Skip to content

Commit f7e2bda

Browse files
committed
Add error-check workflow and page error handling
Introduced an `error-check` workflow to handle specific runtime errors and respond appropriately. Enhanced the `Page` struct with an `Error` channel and `alive` state for better lifecycle management and error propagation. Updated `NewRunnerManager` to support an initialization flag, ensuring specific workflows like `error-check` are conditionally executed.
1 parent d1c2c99 commit f7e2bda

File tree

9 files changed

+94
-43
lines changed

9 files changed

+94
-43
lines changed

internal/adapter/gemini-aistudio.go

Lines changed: 43 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -24,41 +24,54 @@ func (g *GeminiAIStudioAdapter) HandleResponse(responseBuffer []byte, done bool)
2424
arrToolCalls := make([]string, 0)
2525
input := string(responseBuffer)
2626
matches := re.FindAllString(input, -1)
27-
for _, match := range matches {
28-
value := gjson.Get(match, "0.0")
29-
if value.IsArray() {
30-
arr := value.Array()
31-
if len(arr) == 2 {
32-
body = body + arr[1].String()
33-
} else if len(arr) == 11 && arr[1].Type == gjson.Null && arr[10].Type == gjson.JSON {
34-
if !arr[10].IsArray() {
35-
continue
36-
}
37-
arrayToolCalls := arr[10].Array()
38-
funcName := arrayToolCalls[0].String()
39-
argumentsStr := arrayToolCalls[1].String()
40-
params := g.parseToolCallParams(argumentsStr)
27+
if len(matches) > 0 {
28+
29+
for _, match := range matches {
30+
value := gjson.Get(match, "0.0")
31+
if value.IsArray() {
32+
arr := value.Array()
33+
if len(arr) == 2 {
34+
body = body + arr[1].String()
35+
} else if len(arr) == 11 && arr[1].Type == gjson.Null && arr[10].Type == gjson.JSON {
36+
if !arr[10].IsArray() {
37+
continue
38+
}
39+
arrayToolCalls := arr[10].Array()
40+
funcName := arrayToolCalls[0].String()
41+
argumentsStr := arrayToolCalls[1].String()
42+
params := g.parseToolCallParams(argumentsStr)
4143

42-
toolCallsTemplate := `{"id":"","index":0,"type":"function","function":{"name":"","arguments":""}}`
43-
tcs, _ := sjson.Set(toolCallsTemplate, "function.name", funcName)
44-
tcs, _ = sjson.Set(tcs, "function.arguments", params)
45-
arrToolCalls = append(arrToolCalls, tcs)
46-
} else if len(arr) > 2 {
47-
think = think + arr[1].String()
44+
toolCallsTemplate := `{"id":"","index":0,"type":"function","function":{"name":"","arguments":""}}`
45+
tcs, _ := sjson.Set(toolCallsTemplate, "function.name", funcName)
46+
tcs, _ = sjson.Set(tcs, "function.arguments", params)
47+
arrToolCalls = append(arrToolCalls, tcs)
48+
} else if len(arr) > 2 {
49+
think = think + arr[1].String()
50+
}
4851
}
4952
}
50-
}
51-
if len(arrToolCalls) > 0 {
52-
toolCalls = "[" + strings.Join(arrToolCalls, ",") + "]"
53-
}
53+
if len(arrToolCalls) > 0 {
54+
toolCalls = "[" + strings.Join(arrToolCalls, ",") + "]"
55+
}
5456

55-
result := &AdapterResponse{
56-
Content: body,
57-
ReasoningContent: think,
58-
ToolCalls: toolCalls,
59-
Done: done,
57+
result := &AdapterResponse{
58+
Content: body,
59+
ReasoningContent: think,
60+
ToolCalls: toolCalls,
61+
Done: done,
62+
}
63+
return result, nil
64+
} else {
65+
// [,[8,"You exceeded your current quota, please check your plan and billing details. For more information on this error, head to: https://ai.google.dev/gemini-api/docs/rate-limits.",[
66+
67+
result := &AdapterResponse{
68+
Content: body,
69+
ReasoningContent: think,
70+
ToolCalls: toolCalls,
71+
Done: false,
72+
}
73+
return result, nil
6074
}
61-
return result, nil
6275
}
6376

6477
func (g *GeminiAIStudioAdapter) parseToolCallParams(argumentsStr string) string {

internal/api/handlers.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ func (h *APIHandlers) ChatCompletions(c *gin.Context) {
270270

271271
func (h *APIHandlers) handleContextCanceled(instanceIndex int) {
272272
page := h.pages[h.appConfig.Instance[instanceIndex].Name]
273-
r, err := runner.NewRunnerManager(h.appConfig.Instance[instanceIndex], page, h.debug)
273+
r, err := runner.NewRunnerManager(h.appConfig.Instance[instanceIndex], page, h.debug, false)
274274
if err != nil {
275275
log.Error(err)
276276
return
@@ -506,7 +506,7 @@ func (h *APIHandlers) AuthUpload(c *gin.Context) {
506506
page.Close()
507507

508508
pageLoaded := func() {
509-
r, errNewRunnerManager := runner.NewRunnerManager(*instanceConfig, page, h.appConfig.Debug) // Pass pageCtx
509+
r, errNewRunnerManager := runner.NewRunnerManager(*instanceConfig, page, h.appConfig.Debug, false) // Pass pageCtx
510510
if errNewRunnerManager != nil {
511511
log.Error(errNewRunnerManager)
512512
}

internal/api/processor.go

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ func (cp *ChatProcessor) processNonStreamingTask(appConfigInstance config.AppCon
7171
streamChan := make(chan string, 100)
7272

7373
page := cp.pages[appConfigInstance.Name]
74-
r, errNewRunnerManager := runner.NewRunnerManager(appConfigInstance, page, cp.debug)
74+
r, errNewRunnerManager := runner.NewRunnerManager(appConfigInstance, page, cp.debug, false)
7575
go func() {
7676
if errNewRunnerManager != nil {
7777
log.Debug(errNewRunnerManager)
@@ -93,8 +93,11 @@ func (cp *ChatProcessor) processNonStreamingTask(appConfigInstance config.AppCon
9393
defer close(streamChan)
9494
for !done {
9595
select {
96+
case pageError := <-page.Error:
97+
streamChan <- fmt.Sprintf(`{"error": "%v"}`, pageError)
98+
return
9699
case err := <-errChannel:
97-
streamChan <- fmt.Sprintf(`{"error": %v}`, err)
100+
streamChan <- fmt.Sprintf(`{"error": "%v"}`, err)
98101
return
99102
case <-ctx.Done():
100103
return
@@ -161,7 +164,7 @@ func (cp *ChatProcessor) processStreamingTask(appConfigInstance config.AppConfig
161164
errChannel := make(chan error)
162165

163166
page := cp.pages[appConfigInstance.Name]
164-
r, errNewRunnerManager := runner.NewRunnerManager(appConfigInstance, page, cp.debug)
167+
r, errNewRunnerManager := runner.NewRunnerManager(appConfigInstance, page, cp.debug, false)
165168
go func() {
166169
if errNewRunnerManager != nil {
167170
log.Debug(errNewRunnerManager)
@@ -197,8 +200,11 @@ func (cp *ChatProcessor) processStreamingTask(appConfigInstance config.AppConfig
197200
var done bool
198201
for !done {
199202
select {
203+
case pageError := <-page.Error:
204+
streamChan <- fmt.Sprintf(`{"error": "%v"}`, pageError)
205+
return
200206
case err := <-errChannel:
201-
streamChan <- fmt.Sprintf(`{"error": %v}`, err)
207+
streamChan <- fmt.Sprintf(`{"error": "%v"}`, err)
202208
return
203209
case <-ctx.Done():
204210
return

internal/browser/chrome/page.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ type Page struct {
3030
adapterName string
3131
RequestMutex sync.Mutex
3232
URL string
33+
alive bool
34+
Error chan error
3335
}
3436

3537
func NewPage(manager *Manager, adapterName string, url string, authFilePath string, pageLoaded func(), sniffURLs ...[]string) (*Page, error) {
@@ -182,6 +184,8 @@ func NewPage(manager *Manager, adapterName string, url string, authFilePath stri
182184
queue: queue,
183185
adapterName: adapterName,
184186
URL: url,
187+
alive: true,
188+
Error: make(chan error),
185189
}, nil
186190
}
187191

@@ -254,7 +258,12 @@ func (p *Page) GetLocalStorages() (map[string]string, error) {
254258
return localStorage, nil
255259
}
256260

261+
func (p *Page) Alive() bool {
262+
return p.alive
263+
}
264+
257265
func (p *Page) Close() {
266+
p.alive = false
258267
p.cancel()
259268
}
260269

internal/config/config.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ type AppConfigRunner struct {
2929
Init string `yaml:"init"`
3030
ChatCompletions string `yaml:"chat_completions"`
3131
ContextCanceled string `yaml:"context_canceled"`
32+
ErrorCheck string `yaml:"error_check,omitempty"`
3233
}
3334
type AppConfigInstance struct {
3435
Name string `yaml:"name"`

internal/method/sniff.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,7 @@ func (m *Method) ResponseData(page *chrome.Page, channel chan *adapter.AdapterRe
1818
return false, fmt.Errorf("not finish yet")
1919
}
2020
}
21+
22+
func (m *Method) ResponseError(page *chrome.Page, err string) {
23+
page.Error <- fmt.Errorf(err)
24+
}

internal/runner/manager.go

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ type RunnerManager struct {
3232
abort bool
3333
}
3434

35-
func NewRunnerManager(appConfigInstance config.AppConfigInstance, page *chrome.Page, debug bool, results ...map[string]RunnerResult) (*RunnerManager, error) {
35+
func NewRunnerManager(appConfigInstance config.AppConfigInstance, page *chrome.Page, debug bool, isInitRunner bool, results ...map[string]RunnerResult) (*RunnerManager, error) {
3636
if len(results) == 0 {
3737
results = []map[string]RunnerResult{make(map[string]RunnerResult)}
3838
}
@@ -50,6 +50,22 @@ func NewRunnerManager(appConfigInstance config.AppConfigInstance, page *chrome.P
5050
if err != nil {
5151
return nil, err
5252
}
53+
54+
if isInitRunner {
55+
if _, hasKey := runner.configs["error_check"]; hasKey {
56+
runner.SetVariable("PAGE", page, "ptr")
57+
go func() {
58+
for page.Alive() {
59+
time.Sleep(1 * time.Second)
60+
err = runner.Run("error_check")
61+
if err != nil {
62+
log.Debugf("error_check failed: %v", err)
63+
}
64+
}
65+
}()
66+
}
67+
}
68+
5369
runner.SetVariable("TextFilePromptMinSize", appConfigInstance.TextFilePromptMinSize, "int")
5470
return runner, nil
5571
}
@@ -147,6 +163,8 @@ func (rm *RunnerManager) LoadConfigurations() error {
147163
name = "chat_completions"
148164
case rm.appConfigInstance.Runner.ContextCanceled:
149165
name = "context_canceled"
166+
case rm.appConfigInstance.Runner.ErrorCheck:
167+
name = "error_check"
150168
}
151169

152170
log.Debugf("Loading configuration file: %s -> %s", name, filePath)
@@ -222,7 +240,7 @@ outLoop:
222240
}
223241

224242
if workflows[executeIndex].Action == "DoRunner" {
225-
r, err := NewRunnerManager(rm.appConfigInstance, rm.page, rm.debug, rm.results)
243+
r, err := NewRunnerManager(rm.appConfigInstance, rm.page, rm.debug, false, rm.results)
226244
if err != nil {
227245
log.Error(err)
228246
return err
@@ -510,7 +528,7 @@ func (rm *RunnerManager) executeMethod(obj any, methodName string, params []inte
510528
input := strings.TrimSpace(reflect.ValueOf(params[i-1]).String())
511529
if len(input) > 2 && input[0] == '#' && input[len(input)-1] == '#' {
512530
if input == "#NEW_RUNNER#" {
513-
newRm, _ := NewRunnerManager(rm.appConfigInstance, rm.page, rm.debug, rm.results)
531+
newRm, _ := NewRunnerManager(rm.appConfigInstance, rm.page, rm.debug, false, rm.results)
514532
args[paramIndex] = reflect.ValueOf(newRm)
515533
} else {
516534
input = input[1 : len(input)-1]

main.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ func main() {
151151
log.Debugf("Creating a new page...")
152152

153153
pageLoaded := func() {
154-
r, errNewRunnerManager := runner.NewRunnerManager(cfg.Instance[i], pages[cfg.Instance[i].Name], cfg.Debug) // Pass pageCtx
154+
r, errNewRunnerManager := runner.NewRunnerManager(cfg.Instance[i], pages[cfg.Instance[i].Name], cfg.Debug, true) // Pass pageCtx
155155
if errNewRunnerManager != nil {
156156
log.Error(errNewRunnerManager)
157157
}
@@ -207,7 +207,7 @@ func main() {
207207
log.Debugf("Creating a new page...")
208208

209209
pageLoaded := func() {
210-
r, errNewRunnerManager := runner.NewRunnerManager(cfg.Instance[i], pages[cfg.Instance[i].Name], cfg.Debug) // Pass pageCtx
210+
r, errNewRunnerManager := runner.NewRunnerManager(cfg.Instance[i], pages[cfg.Instance[i].Name], cfg.Debug, true) // Pass pageCtx
211211
if errNewRunnerManager != nil {
212212
log.Error(errNewRunnerManager)
213213
}
@@ -235,7 +235,7 @@ func main() {
235235

236236
pages[cfg.Instance[i].Name] = page // Store pageCtx
237237

238-
r, errNewRunnerManager := runner.NewRunnerManager(cfg.Instance[i], page, cfg.Debug) // Pass pageCtx
238+
r, errNewRunnerManager := runner.NewRunnerManager(cfg.Instance[i], page, cfg.Debug, true) // Pass pageCtx
239239
if errNewRunnerManager != nil {
240240
log.Error(errNewRunnerManager)
241241
}

runner

0 commit comments

Comments
 (0)