Skip to content

Commit 572effc

Browse files
committed
pkg/aflow: retry LLM requests on transient errors
Update #6573
1 parent e2d1759 commit 572effc

File tree

1 file changed

+20
-1
lines changed

1 file changed

+20
-1
lines changed

pkg/aflow/llm_agent.go

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,12 @@
44
package aflow
55

66
import (
7+
"errors"
78
"fmt"
89
"maps"
10+
"net/http"
911
"reflect"
12+
"time"
1013

1114
"github.com/google/syzkaller/pkg/aflow/trajectory"
1215
"google.golang.org/genai"
@@ -155,7 +158,7 @@ func (a *LLMAgent) chat(ctx *Context, cfg *genai.GenerateContentConfig, tools ma
155158
if err := ctx.startSpan(reqSpan); err != nil {
156159
return "", nil, err
157160
}
158-
resp, err := ctx.generateContent(cfg, req)
161+
resp, err := a.generateContent(ctx, cfg, req)
159162
if err != nil {
160163
return "", nil, ctx.finishSpan(reqSpan, err)
161164
}
@@ -271,6 +274,22 @@ func (a *LLMAgent) parseResponse(resp *genai.GenerateContentResponse) (
271274
return
272275
}
273276

277+
func (a *LLMAgent) generateContent(ctx *Context, cfg *genai.GenerateContentConfig,
278+
req []*genai.Content) (*genai.GenerateContentResponse, error) {
279+
backoff := time.Second
280+
for try := 0; ; try++ {
281+
resp, err := ctx.generateContent(cfg, req)
282+
var apiErr genai.APIError
283+
if err != nil && try < 100 && errors.As(err, &apiErr) &&
284+
apiErr.Code == http.StatusServiceUnavailable {
285+
time.Sleep(backoff)
286+
backoff = min(backoff+time.Second, 10*time.Second)
287+
continue
288+
}
289+
return resp, err
290+
}
291+
}
292+
274293
func (a *LLMAgent) verify(vctx *verifyContext) {
275294
vctx.requireNotEmpty(a.Name, "Name", a.Name)
276295
vctx.requireNotEmpty(a.Name, "Reply", a.Reply)

0 commit comments

Comments
 (0)