Skip to content

Commit 5c6fad8

Browse files
committed
fix: allow retrying of failed runs
Signed-off-by: Donnie Adams <donnie@acorn.io>
1 parent 8452bda commit 5c6fad8

File tree

4 files changed

+64
-16
lines changed

4 files changed

+64
-16
lines changed

client.go

-2
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,6 @@ func (c *client) Evaluate(ctx context.Context, opts Options, tools ...fmt.String
119119
state: Creating,
120120
opts: opts,
121121
content: concatTools(tools),
122-
chatState: opts.ChatState,
123122
}).NextChat(ctx, opts.Input)
124123
}
125124

@@ -130,7 +129,6 @@ func (c *client) Run(ctx context.Context, toolPath string, opts Options) (*Run,
130129
state: Creating,
131130
opts: opts,
132131
toolPath: toolPath,
133-
chatState: opts.ChatState,
134132
}).NextChat(ctx, opts.Input)
135133
}
136134

opts.go

+10-9
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,14 @@ package gptscript
22

33
// Options represents options for the gptscript tool or file.
44
type Options struct {
5-
Confirm bool `json:"confirm"`
6-
Input string `json:"input"`
7-
DisableCache bool `json:"disableCache"`
8-
CacheDir string `json:"cacheDir"`
9-
SubTool string `json:"subTool"`
10-
Workspace string `json:"workspace"`
11-
ChatState string `json:"chatState"`
12-
IncludeEvents bool `json:"includeEvents"`
13-
Prompt bool `json:"prompt"`
5+
Confirm bool `json:"confirm"`
6+
Input string `json:"input"`
7+
DisableCache bool `json:"disableCache"`
8+
CacheDir string `json:"cacheDir"`
9+
SubTool string `json:"subTool"`
10+
Workspace string `json:"workspace"`
11+
ChatState string `json:"chatState"`
12+
IncludeEvents bool `json:"includeEvents"`
13+
Prompt bool `json:"prompt"`
14+
Env []string `json:"env"`
1415
}

run.go

+12-5
Original file line numberDiff line numberDiff line change
@@ -106,22 +106,24 @@ func (r *Run) ChatState() string {
106106
// NextChat will pass input and create the next run in a chat.
107107
// The new Run will be returned.
108108
func (r *Run) NextChat(ctx context.Context, input string) (*Run, error) {
109-
if r.state != Creating && r.state != Continue {
110-
return nil, fmt.Errorf("run must be in creating or continue state not %q", r.state)
109+
if r.state != Creating && r.state != Continue && r.state != Error {
110+
return nil, fmt.Errorf("run must be in creating, continue, or error state not %q", r.state)
111111
}
112112

113113
run := &Run{
114114
url: r.url,
115115
requestPath: r.requestPath,
116116
state: Creating,
117-
chatState: r.chatState,
118117
toolPath: r.toolPath,
119118
content: r.content,
120119
opts: r.opts,
121120
}
121+
122122
run.opts.Input = input
123-
if run.chatState != "" {
124-
run.opts.ChatState = run.chatState
123+
if r.chatState != "" && r.state != Error {
124+
// If the previous run errored, then don't update the chat state.
125+
// opts.ChatState will be the last chat state where an error did not occur.
126+
run.opts.ChatState = r.chatState
125127
}
126128

127129
var payload any
@@ -287,6 +289,11 @@ func (r *Run) request(ctx context.Context, payload any) (err error) {
287289
return
288290
}
289291

292+
if event.Run != nil && event.Run.Type == EventTypeRunFinish && event.Run.Error != "" {
293+
r.state = Error
294+
r.err = fmt.Errorf(event.Run.Error)
295+
}
296+
290297
if r.opts.IncludeEvents {
291298
r.events <- event
292299
}

run_test.go

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package gptscript
2+
3+
import (
4+
"context"
5+
"testing"
6+
)
7+
8+
func TestRestartingErrorRun(t *testing.T) {
9+
tool := &ToolDef{
10+
Context: []string{"my-context"},
11+
Instructions: "Say hello",
12+
}
13+
contextTool := &ToolDef{
14+
Name: "my-context",
15+
Args: map[string]string{
16+
"code": "The exit code to use",
17+
},
18+
Instructions: "#!/usr/bin/env python3\nimport os\nimport sys\nsys.exit(int(os.environ['EXIT_CODE']))",
19+
}
20+
21+
run, err := c.Evaluate(context.Background(), Options{DisableCache: true, Env: []string{"EXIT_CODE=1"}}, tool, contextTool)
22+
if err != nil {
23+
t.Errorf("Error executing tool: %v", err)
24+
}
25+
26+
// Wait for the run to complete
27+
_, err = run.Text()
28+
if err == nil {
29+
t.Fatalf("no error returned from run")
30+
}
31+
32+
run.opts.Env = []string{"EXIT_CODE=0"}
33+
run, err = run.NextChat(context.Background(), "")
34+
if err != nil {
35+
t.Errorf("Error executing next run: %v", err)
36+
}
37+
38+
_, err = run.Text()
39+
if err != nil {
40+
t.Errorf("executing run with input of 0 should not fail: %v", err)
41+
}
42+
}

0 commit comments

Comments
 (0)