@@ -9,6 +9,7 @@ package agent
99import (
1010 "context"
1111 "encoding/json"
12+ "errors"
1213 "fmt"
1314 "path/filepath"
1415 "strings"
@@ -666,10 +667,35 @@ func (al *AgentLoop) runLLMIteration(
666667 }
667668
668669 errMsg := strings .ToLower (err .Error ())
669- isContextError := strings .Contains (errMsg , "token" ) ||
670- strings .Contains (errMsg , "context" ) ||
670+
671+ // Check if this is a network/HTTP timeout — not a context window error.
672+ isTimeoutError := errors .Is (err , context .DeadlineExceeded ) ||
673+ strings .Contains (errMsg , "deadline exceeded" ) ||
674+ strings .Contains (errMsg , "client.timeout" ) ||
675+ strings .Contains (errMsg , "timed out" ) ||
676+ strings .Contains (errMsg , "timeout exceeded" )
677+
678+ // Detect real context window / token limit errors, excluding network timeouts.
679+ isContextError := ! isTimeoutError && (strings .Contains (errMsg , "context_length_exceeded" ) ||
680+ strings .Contains (errMsg , "context window" ) ||
681+ strings .Contains (errMsg , "maximum context length" ) ||
682+ strings .Contains (errMsg , "token limit" ) ||
683+ strings .Contains (errMsg , "too many tokens" ) ||
684+ strings .Contains (errMsg , "max_tokens" ) ||
671685 strings .Contains (errMsg , "invalidparameter" ) ||
672- strings .Contains (errMsg , "length" )
686+ strings .Contains (errMsg , "prompt is too long" ) ||
687+ strings .Contains (errMsg , "request too large" ))
688+
689+ if isTimeoutError && retry < maxRetries {
690+ backoff := time .Duration (retry + 1 ) * 5 * time .Second
691+ logger .WarnCF ("agent" , "Timeout error, retrying after backoff" , map [string ]any {
692+ "error" : err .Error (),
693+ "retry" : retry ,
694+ "backoff" : backoff .String (),
695+ })
696+ time .Sleep (backoff )
697+ continue
698+ }
673699
674700 if isContextError && retry < maxRetries {
675701 logger .WarnCF ("agent" , "Context window error detected, attempting compression" , map [string ]any {
0 commit comments