@@ -1555,6 +1555,7 @@ mod tests {
15551555 extra_headers : vec ! [ ] ,
15561556 thinking : None ,
15571557 disable_cache_control : false ,
1558+ policy : Default :: default ( ) ,
15581559 } ,
15591560 std:: path:: PathBuf :: from ( "/tmp" ) ,
15601561 ) ;
@@ -1950,6 +1951,52 @@ mod tests {
19501951 assert_eq ! ( result, "ok" ) ;
19511952 }
19521953
1954+ #[ tokio:: test]
1955+ async fn test_retry_on_header_timeout ( ) {
1956+ // HeaderTimeout is the new non-API error class added for bench-runner's
1957+ // 15s header-arrival timeout. Like ChunkTimeout it must take the
1958+ // retryable fall-through arm — otherwise a stalled-headers re-send never
1959+ // fires and the run dies on the first attempt.
1960+ let mock = MockLlm :: new ( vec ! [
1961+ Err ( AgentError :: HeaderTimeout ( 15_000 ) ) ,
1962+ Ok ( text_response( "recovered" ) ) ,
1963+ ] ) ;
1964+ let ( mut agent, _rx) = make_agent ( mock, ToolRegistry :: new ( ) , None ) ;
1965+ agent. config . retry_config . max_retries = 3 ;
1966+
1967+ let result = agent. run ( ChatMessage :: user ( "test" ) ) . await . unwrap ( ) . unwrap_done ( ) ;
1968+ assert_eq ! ( result, "recovered" , "HeaderTimeout must be retryable" ) ;
1969+ }
1970+
1971+ #[ test]
1972+ fn test_llm_policy_values ( ) {
1973+ let app = crate :: llm:: LlmPolicy :: default ( ) ;
1974+ assert ! ( !app. http1_only) ;
1975+ assert ! ( !app. no_pool) ;
1976+ assert_eq ! ( app. header_timeout_ms, None ) ;
1977+
1978+ let bench = crate :: llm:: LlmPolicy :: bench ( ) ;
1979+ assert ! ( bench. http1_only) ;
1980+ assert ! ( bench. no_pool) ;
1981+ assert_eq ! ( bench. header_timeout_ms, Some ( 15_000 ) ) ;
1982+ }
1983+
1984+ #[ tokio:: test]
1985+ async fn test_retry_on_chunk_timeout_nonapi_error ( ) {
1986+ // ChunkTimeout takes the SAME fall-through arm in call_llm_with_retry as
1987+ // HttpError (mid-stream decode). If this retries, the non-API error path
1988+ // re-sends; if it doesn't, the decode-bypass bug is in the classification.
1989+ let mock = MockLlm :: new ( vec ! [
1990+ Err ( AgentError :: ChunkTimeout ( 60 ) ) ,
1991+ Ok ( text_response( "recovered" ) ) ,
1992+ ] ) ;
1993+ let ( mut agent, _rx) = make_agent ( mock, ToolRegistry :: new ( ) , None ) ;
1994+ agent. config . retry_config . max_retries = 3 ;
1995+
1996+ let result = agent. run ( ChatMessage :: user ( "test" ) ) . await . unwrap ( ) . unwrap_done ( ) ;
1997+ assert_eq ! ( result, "recovered" , "non-API error (ChunkTimeout) must re-send" ) ;
1998+ }
1999+
19532000 #[ tokio:: test]
19542001 async fn test_no_retry_on_401 ( ) {
19552002 let mock = MockLlm :: new ( vec ! [ Err ( AgentError :: LlmApiError {
@@ -2297,6 +2344,7 @@ mod tests {
22972344 extra_headers : vec ! [ ] ,
22982345 thinking : None ,
22992346 disable_cache_control : false ,
2347+ policy : Default :: default ( ) ,
23002348 } ,
23012349 std:: path:: PathBuf :: from ( "/tmp" ) ,
23022350 ) ;
@@ -2362,6 +2410,7 @@ mod tests {
23622410 extra_headers : vec ! [ ] ,
23632411 thinking : None ,
23642412 disable_cache_control : false ,
2413+ policy : Default :: default ( ) ,
23652414 } ,
23662415 std:: path:: PathBuf :: from ( "/tmp" ) ,
23672416 ) ;
@@ -2427,6 +2476,7 @@ mod tests {
24272476 extra_headers : vec ! [ ] ,
24282477 thinking : None ,
24292478 disable_cache_control : false ,
2479+ policy : Default :: default ( ) ,
24302480 } ,
24312481 std:: path:: PathBuf :: from ( "/tmp" ) ,
24322482 ) ;
@@ -2521,6 +2571,7 @@ mod tests {
25212571 extra_headers : vec ! [ ] ,
25222572 thinking : None ,
25232573 disable_cache_control : false ,
2574+ policy : Default :: default ( ) ,
25242575 } ,
25252576 std:: path:: PathBuf :: from ( "/tmp" ) ,
25262577 ) ;
@@ -2617,6 +2668,7 @@ mod tests {
26172668 extra_headers : vec ! [ ] ,
26182669 thinking : None ,
26192670 disable_cache_control : false ,
2671+ policy : Default :: default ( ) ,
26202672 } ,
26212673 std:: path:: PathBuf :: from ( "/tmp" ) ,
26222674 ) ;
@@ -2699,6 +2751,7 @@ mod tests {
26992751 extra_headers : vec ! [ ] ,
27002752 thinking : None ,
27012753 disable_cache_control : false ,
2754+ policy : Default :: default ( ) ,
27022755 } ,
27032756 std:: path:: PathBuf :: from ( "/tmp" ) ,
27042757 ) ;
@@ -2773,6 +2826,7 @@ mod tests {
27732826 extra_headers : vec ! [ ] ,
27742827 thinking : None ,
27752828 disable_cache_control : false ,
2829+ policy : Default :: default ( ) ,
27762830 } ,
27772831 work_dir. path ( ) . to_path_buf ( ) ,
27782832 ) ;
@@ -3022,6 +3076,7 @@ mod tests {
30223076 extra_headers : vec ! [ ] ,
30233077 thinking : None ,
30243078 disable_cache_control : false ,
3079+ policy : Default :: default ( ) ,
30253080 } ,
30263081 tmp. path ( ) . to_path_buf ( ) ,
30273082 ) ;
@@ -3089,6 +3144,7 @@ mod tests {
30893144 extra_headers : vec ! [ ] ,
30903145 thinking : None ,
30913146 disable_cache_control : false ,
3147+ policy : Default :: default ( ) ,
30923148 } ,
30933149 tmp. path ( ) . to_path_buf ( ) ,
30943150 ) ;
@@ -3164,6 +3220,7 @@ mod tests {
31643220 extra_headers : vec ! [ ] ,
31653221 thinking : None ,
31663222 disable_cache_control : false ,
3223+ policy : Default :: default ( ) ,
31673224 } ,
31683225 tmp. path ( ) . to_path_buf ( ) ,
31693226 ) ;
@@ -3230,6 +3287,7 @@ mod tests {
32303287 extra_headers : vec ! [ ] ,
32313288 thinking : None ,
32323289 disable_cache_control : false ,
3290+ policy : Default :: default ( ) ,
32333291 } ,
32343292 tmp. path ( ) . to_path_buf ( ) ,
32353293 ) ;
@@ -3298,6 +3356,7 @@ mod tests {
32983356 extra_headers : vec ! [ ] ,
32993357 thinking : None ,
33003358 disable_cache_control : false ,
3359+ policy : Default :: default ( ) ,
33013360 } ,
33023361 tmp. path ( ) . to_path_buf ( ) ,
33033362 ) ;
@@ -3372,6 +3431,7 @@ mod tests {
33723431 extra_headers : vec ! [ ] ,
33733432 thinking : None ,
33743433 disable_cache_control : false ,
3434+ policy : Default :: default ( ) ,
33753435 } ,
33763436 tmp. path ( ) . to_path_buf ( ) ,
33773437 ) ;
@@ -3590,6 +3650,7 @@ mod tests {
35903650 extra_headers : vec ! [ ] ,
35913651 thinking : None ,
35923652 disable_cache_control : false ,
3653+ policy : Default :: default ( ) ,
35933654 } ,
35943655 tmp. path ( ) . to_path_buf ( ) ,
35953656 ) ;
@@ -3675,6 +3736,7 @@ mod tests {
36753736 extra_headers : vec ! [ ] ,
36763737 thinking : None ,
36773738 disable_cache_control : false ,
3739+ policy : Default :: default ( ) ,
36783740 } ,
36793741 tmp. path ( ) . to_path_buf ( ) ,
36803742 ) ;
@@ -3730,6 +3792,7 @@ mod tests {
37303792 extra_headers : vec ! [ ] ,
37313793 thinking : None ,
37323794 disable_cache_control : false ,
3795+ policy : Default :: default ( ) ,
37333796 } ,
37343797 tmp. path ( ) . to_path_buf ( ) ,
37353798 ) ;
@@ -3792,6 +3855,7 @@ mod tests {
37923855 extra_headers : vec ! [ ] ,
37933856 thinking : None ,
37943857 disable_cache_control : false ,
3858+ policy : Default :: default ( ) ,
37953859 } ,
37963860 std:: path:: PathBuf :: from ( "/tmp" ) ,
37973861 ) ;
0 commit comments