on main help sign in
fix: append error tool message when tool call is cancelled (#2492)
2928dcbChris Chen
internal/agent/agent.go+10−4
@@ -364,7 +364,9 @@ func (a *sessionAgent) Run(ctx context.Context, call SessionAgentCall) (*fantasy
364 Finished: false,
364 Finished: false,
365 }
365 }
366 currentAssistant.AddToolCall(toolCall)
366 currentAssistant.AddToolCall(toolCall)
367+ // Use parent ctx instead of genCtx to ensure the update succeeds
368+ // even if the request is canceled mid-stream
367− return a.messages.Update(genCtx, *currentAssistant)
369+ return a.messages.Update(ctx, *currentAssistant)
368 },
370 },
369 OnRetry: func(err *fantasy.ProviderError, delay time.Duration) {
371 OnRetry: func(err *fantasy.ProviderError, delay time.Duration) {
370 // TODO: implement
372 // TODO: implement
@@ -378,11 +380,15 @@ func (a *sessionAgent) Run(ctx context.Context, call SessionAgentCall) (*fantasy
378 Finished: true,
380 Finished: true,
379 }
381 }
380 currentAssistant.AddToolCall(toolCall)
382 currentAssistant.AddToolCall(toolCall)
383+ // Use parent ctx instead of genCtx to ensure the update succeeds
384+ // even if the request is canceled mid-stream
381− return a.messages.Update(genCtx, *currentAssistant)
385+ return a.messages.Update(ctx, *currentAssistant)
382 },
386 },
383 OnToolResult: func(result fantasy.ToolResultContent) error {
387 OnToolResult: func(result fantasy.ToolResultContent) error {
384 toolResult := a.convertToToolResult(result)
388 toolResult := a.convertToToolResult(result)
389+ // Use parent ctx instead of genCtx to ensure the message is created
390+ // even if the request is canceled mid-stream
385− _, createMsgErr := a.messages.Create(genCtx, currentAssistant.SessionID, message.CreateMessageParams{
391+ _, createMsgErr := a.messages.Create(ctx, currentAssistant.SessionID, message.CreateMessageParams{
386 Role: message.Tool,
392 Role: message.Tool,
387 Parts: []message.ContentPart{
393 Parts: []message.ContentPart{
388 toolResult,
394 toolResult,
@@ -485,7 +491,7 @@ func (a *sessionAgent) Run(ctx context.Context, call SessionAgentCall) (*fantasy
485 }
491 }
486 content := "There was an error while executing the tool"
492 content := "There was an error while executing the tool"
487 if isCancelErr {
493 if isCancelErr {
488− content = "Tool execution canceled by user"
494+ content = "Error: user cancelled assistant tool calling"
489 } else if isPermissionErr {
495 } else if isPermissionErr {
490 content = "User denied permission"
496 content = "User denied permission"
491 }
497 }