feat: todo tool

Kujtim Hoxha and Christian Rocha created

Co-authored-by: Christian Rocha <christian@rocha.is>

Change summary

internal/agent/agent.go                                                            |  46 
internal/agent/agent_tool.go                                                       |   2 
internal/agent/common_test.go                                                      |   2 
internal/agent/coordinator.go                                                      |  11 
internal/agent/templates/summary.md                                                |   2 
internal/agent/testdata/TestCoderAgent/anthropic-sonnet/bash_tool.yaml             |  27 
internal/agent/testdata/TestCoderAgent/anthropic-sonnet/download_tool.yaml         |  23 
internal/agent/testdata/TestCoderAgent/anthropic-sonnet/fetch_tool.yaml            |  26 
internal/agent/testdata/TestCoderAgent/anthropic-sonnet/glob_tool.yaml             |  22 
internal/agent/testdata/TestCoderAgent/anthropic-sonnet/grep_tool.yaml             |  25 
internal/agent/testdata/TestCoderAgent/anthropic-sonnet/ls_tool.yaml               |  25 
internal/agent/testdata/TestCoderAgent/anthropic-sonnet/multiedit_tool.yaml        |  28 
internal/agent/testdata/TestCoderAgent/anthropic-sonnet/parallel_tool_calls.yaml   |  25 
internal/agent/testdata/TestCoderAgent/anthropic-sonnet/read_a_file.yaml           |  22 
internal/agent/testdata/TestCoderAgent/anthropic-sonnet/simple_test.yaml           |  16 
internal/agent/testdata/TestCoderAgent/anthropic-sonnet/sourcegraph_tool.yaml      |  22 
internal/agent/testdata/TestCoderAgent/anthropic-sonnet/update_a_file.yaml         |  20 
internal/agent/testdata/TestCoderAgent/anthropic-sonnet/write_tool.yaml            |   3 
internal/agent/testdata/TestCoderAgent/openai-gpt-5/bash_tool.yaml                 |  38 
internal/agent/testdata/TestCoderAgent/openai-gpt-5/download_tool.yaml             |  22 
internal/agent/testdata/TestCoderAgent/openai-gpt-5/fetch_tool.yaml                |  28 
internal/agent/testdata/TestCoderAgent/openai-gpt-5/glob_tool.yaml                 |  28 
internal/agent/testdata/TestCoderAgent/openai-gpt-5/grep_tool.yaml                 |  30 
internal/agent/testdata/TestCoderAgent/openai-gpt-5/ls_tool.yaml                   |  26 
internal/agent/testdata/TestCoderAgent/openai-gpt-5/multiedit_tool.yaml            |  40 
internal/agent/testdata/TestCoderAgent/openai-gpt-5/parallel_tool_calls.yaml       |  26 
internal/agent/testdata/TestCoderAgent/openai-gpt-5/read_a_file.yaml               |  20 
internal/agent/testdata/TestCoderAgent/openai-gpt-5/simple_test.yaml               |  14 
internal/agent/testdata/TestCoderAgent/openai-gpt-5/sourcegraph_tool.yaml          |  36 
internal/agent/testdata/TestCoderAgent/openai-gpt-5/update_a_file.yaml             |  30 
internal/agent/testdata/TestCoderAgent/openai-gpt-5/write_tool.yaml                |  26 
internal/agent/testdata/TestCoderAgent/openrouter-kimi-k2/bash_tool.yaml           |  49 
internal/agent/testdata/TestCoderAgent/openrouter-kimi-k2/download_tool.yaml       |  24 
internal/agent/testdata/TestCoderAgent/openrouter-kimi-k2/fetch_tool.yaml          |  24 
internal/agent/testdata/TestCoderAgent/openrouter-kimi-k2/glob_tool.yaml           |  30 
internal/agent/testdata/TestCoderAgent/openrouter-kimi-k2/grep_tool.yaml           |  26 
internal/agent/testdata/TestCoderAgent/openrouter-kimi-k2/ls_tool.yaml             |   2 
internal/agent/testdata/TestCoderAgent/openrouter-kimi-k2/multiedit_tool.yaml      |  34 
internal/agent/testdata/TestCoderAgent/openrouter-kimi-k2/parallel_tool_calls.yaml |  22 
internal/agent/testdata/TestCoderAgent/openrouter-kimi-k2/read_a_file.yaml         |  18 
internal/agent/testdata/TestCoderAgent/openrouter-kimi-k2/simple_test.yaml         |  12 
internal/agent/testdata/TestCoderAgent/openrouter-kimi-k2/sourcegraph_tool.yaml    |  22 
internal/agent/testdata/TestCoderAgent/openrouter-kimi-k2/update_a_file.yaml       |  18 
internal/agent/testdata/TestCoderAgent/openrouter-kimi-k2/write_tool.yaml          |  36 
internal/agent/testdata/TestCoderAgent/zai-glm4.6/bash_tool.yaml                   |  20 
internal/agent/testdata/TestCoderAgent/zai-glm4.6/download_tool.yaml               |  20 
internal/agent/testdata/TestCoderAgent/zai-glm4.6/fetch_tool.yaml                  |   3 
internal/agent/testdata/TestCoderAgent/zai-glm4.6/glob_tool.yaml                   |  18 
internal/agent/testdata/TestCoderAgent/zai-glm4.6/grep_tool.yaml                   |  18 
internal/agent/testdata/TestCoderAgent/zai-glm4.6/ls_tool.yaml                     |  18 
internal/agent/testdata/TestCoderAgent/zai-glm4.6/multiedit_tool.yaml              |  20 
internal/agent/testdata/TestCoderAgent/zai-glm4.6/parallel_tool_calls.yaml         |  18 
internal/agent/testdata/TestCoderAgent/zai-glm4.6/read_a_file.yaml                 |   2 
internal/agent/testdata/TestCoderAgent/zai-glm4.6/simple_test.yaml                 |  14 
internal/agent/testdata/TestCoderAgent/zai-glm4.6/sourcegraph_tool.yaml            |  20 
internal/agent/testdata/TestCoderAgent/zai-glm4.6/update_a_file.yaml               |  24 
internal/agent/testdata/TestCoderAgent/zai-glm4.6/write_tool.yaml                  |  22 
internal/agent/tools/ls.go                                                         |   2 
internal/agent/tools/todos.go                                                      | 134 
internal/agent/tools/todos.md                                                      |  90 
internal/config/config.go                                                          |   1 
internal/config/load_test.go                                                       |   4 
internal/db/migrations/20250812000000_add_todos_to_sessions.sql                    |   9 
internal/db/models.go                                                              |   1 
internal/db/sessions.sql.go                                                        |  17 
internal/db/sql/sessions.sql                                                       |   3 
internal/session/session.go                                                        |  53 
internal/tui/components/chat/chat.go                                               |  37 
internal/tui/components/chat/editor/editor.go                                      |   5 
internal/tui/components/chat/messages/renderer.go                                  |  95 
internal/tui/components/chat/messages/tool.go                                      |   2 
internal/tui/components/chat/queue.go                                              |  28 
internal/tui/components/chat/todos/todos.go                                        |  67 
internal/tui/exp/list/list.go                                                      |   5 
internal/tui/page/chat/chat.go                                                     | 274 
internal/tui/page/chat/keys.go                                                     |  15 
internal/tui/page/chat/pills.go                                                    | 125 
internal/tui/styles/icons.go                                                       |  24 
78 files changed, 1,549 insertions(+), 687 deletions(-)

Detailed changes

internal/agent/agent.go πŸ”—

@@ -65,6 +65,7 @@ type SessionAgent interface {
 	IsSessionBusy(sessionID string) bool
 	IsBusy() bool
 	QueuedPrompts(sessionID string) int
+	QueuedPromptsList(sessionID string) []string
 	ClearQueue(sessionID string)
 	Summarize(context.Context, string, fantasy.ProviderOptions) error
 	Model() Model
@@ -81,6 +82,7 @@ type sessionAgent struct {
 	smallModel           Model
 	systemPromptPrefix   string
 	systemPrompt         string
+	isSubAgent           bool
 	tools                []fantasy.AgentTool
 	sessions             session.Service
 	messages             message.Service
@@ -96,6 +98,7 @@ type SessionAgentOptions struct {
 	SmallModel           Model
 	SystemPromptPrefix   string
 	SystemPrompt         string
+	IsSubAgent           bool
 	DisableAutoSummarize bool
 	IsYolo               bool
 	Sessions             session.Service
@@ -111,6 +114,7 @@ func NewSessionAgent(
 		smallModel:           opts.SmallModel,
 		systemPromptPrefix:   opts.SystemPromptPrefix,
 		systemPrompt:         opts.SystemPrompt,
+		isSubAgent:           opts.IsSubAgent,
 		sessions:             opts.Sessions,
 		messages:             opts.Messages,
 		disableAutoSummarize: opts.DisableAutoSummarize,
@@ -343,9 +347,14 @@ func (a *sessionAgent) Run(ctx context.Context, call SessionAgentCall) (*fantasy
 				finishReason = message.FinishReasonToolUse
 			}
 			currentAssistant.AddFinish(finishReason, "", "")
-			a.updateSessionUsage(a.largeModel, &currentSession, stepResult.Usage, a.openrouterCost(stepResult.ProviderMetadata))
 			sessionLock.Lock()
-			_, sessionErr := a.sessions.Save(genCtx, currentSession)
+			updatedSession, getSessionErr := a.sessions.Get(genCtx, call.SessionID)
+			if getSessionErr != nil {
+				sessionLock.Unlock()
+				return getSessionErr
+			}
+			a.updateSessionUsage(a.largeModel, &updatedSession, stepResult.Usage, a.openrouterCost(stepResult.ProviderMetadata))
+			_, sessionErr := a.sessions.Save(genCtx, updatedSession)
 			sessionLock.Unlock()
 			if sessionErr != nil {
 				return sessionErr
@@ -531,8 +540,18 @@ func (a *sessionAgent) Summarize(ctx context.Context, sessionID string, opts fan
 		return err
 	}
 
+	summaryPromptText := "Provide a detailed summary of our conversation above."
+	if len(currentSession.Todos) > 0 {
+		summaryPromptText += "\n\n## Current Todo List\n\n"
+		for _, t := range currentSession.Todos {
+			summaryPromptText += fmt.Sprintf("- [%s] %s\n", t.Status, t.Content)
+		}
+		summaryPromptText += "\nInclude these tasks and their statuses in your summary. "
+		summaryPromptText += "Instruct the resuming assistant to use the `todos` tool to continue tracking progress on these tasks."
+	}
+
 	resp, err := agent.Stream(genCtx, fantasy.AgentStreamCall{
-		Prompt:          "Provide a detailed summary of our conversation above.",
+		Prompt:          summaryPromptText,
 		Messages:        aiMsgs,
 		ProviderOptions: opts,
 		PrepareStep: func(callContext context.Context, options fantasy.PrepareStepFunctionOptions) (_ context.Context, prepared fantasy.PrepareStepResult, err error) {
@@ -633,6 +652,15 @@ func (a *sessionAgent) createUserMessage(ctx context.Context, call SessionAgentC
 
 func (a *sessionAgent) preparePrompt(msgs []message.Message, attachments ...message.Attachment) ([]fantasy.Message, []fantasy.FilePart) {
 	var history []fantasy.Message
+	if !a.isSubAgent {
+		history = append(history, fantasy.NewUserMessage(
+			fmt.Sprintf("<system_reminder>%s</system_reminder>",
+				`This is a reminder that your todo list is currently empty. DO NOT mention this to the user explicitly because they are already aware.
+If you are working on tasks that would benefit from a todo list please use the "todos" tool to create one.
+If not, please feel free to ignore. Again do not mention this message to the user.`,
+			),
+		))
+	}
 	for _, m := range msgs {
 		if len(m.Parts) == 0 {
 			continue
@@ -851,6 +879,18 @@ func (a *sessionAgent) QueuedPrompts(sessionID string) int {
 	return len(l)
 }
 
+func (a *sessionAgent) QueuedPromptsList(sessionID string) []string {
+	l, ok := a.messageQueue.Get(sessionID)
+	if !ok {
+		return nil
+	}
+	prompts := make([]string, len(l))
+	for i, call := range l {
+		prompts[i] = call.Prompt
+	}
+	return prompts
+}
+
 func (a *sessionAgent) SetModels(large Model, small Model) {
 	a.largeModel = large
 	a.smallModel = small

internal/agent/agent_tool.go πŸ”—

@@ -34,7 +34,7 @@ func (c *coordinator) agentTool(ctx context.Context) (fantasy.AgentTool, error)
 		return nil, err
 	}
 
-	agent, err := c.buildAgent(ctx, prompt, agentCfg)
+	agent, err := c.buildAgent(ctx, prompt, agentCfg, true)
 	if err != nil {
 		return nil, err
 	}

internal/agent/common_test.go πŸ”—

@@ -149,7 +149,7 @@ func testSessionAgent(env fakeEnv, large, small fantasy.LanguageModel, systemPro
 			DefaultMaxTokens: 10000,
 		},
 	}
-	agent := NewSessionAgent(SessionAgentOptions{largeModel, smallModel, "", systemPrompt, false, true, env.sessions, env.messages, tools})
+	agent := NewSessionAgent(SessionAgentOptions{largeModel, smallModel, "", systemPrompt, false, false, true, env.sessions, env.messages, tools})
 	return agent
 }
 

internal/agent/coordinator.go πŸ”—

@@ -49,6 +49,7 @@ type Coordinator interface {
 	IsSessionBusy(sessionID string) bool
 	IsBusy() bool
 	QueuedPrompts(sessionID string) int
+	QueuedPromptsList(sessionID string) []string
 	ClearQueue(sessionID string)
 	Summarize(context.Context, string) error
 	Model() Model
@@ -99,7 +100,7 @@ func NewCoordinator(
 		return nil, err
 	}
 
-	agent, err := c.buildAgent(ctx, prompt, agentCfg)
+	agent, err := c.buildAgent(ctx, prompt, agentCfg, false)
 	if err != nil {
 		return nil, err
 	}
@@ -299,7 +300,7 @@ func mergeCallOptions(model Model, cfg config.ProviderConfig) (fantasy.ProviderO
 	return modelOptions, temp, topP, topK, freqPenalty, presPenalty
 }
 
-func (c *coordinator) buildAgent(ctx context.Context, prompt *prompt.Prompt, agent config.Agent) (SessionAgent, error) {
+func (c *coordinator) buildAgent(ctx context.Context, prompt *prompt.Prompt, agent config.Agent, isSubAgent bool) (SessionAgent, error) {
 	large, small, err := c.buildAgentModels(ctx)
 	if err != nil {
 		return nil, err
@@ -316,6 +317,7 @@ func (c *coordinator) buildAgent(ctx context.Context, prompt *prompt.Prompt, age
 		small,
 		largeProviderCfg.SystemPromptPrefix,
 		systemPrompt,
+		isSubAgent,
 		c.cfg.Options.DisableAutoSummarize,
 		c.permissions.SkipRequests(),
 		c.sessions,
@@ -372,6 +374,7 @@ func (c *coordinator) buildTools(ctx context.Context, agent config.Agent) ([]fan
 		tools.NewGrepTool(c.cfg.WorkingDir()),
 		tools.NewLsTool(c.permissions, c.cfg.WorkingDir(), c.cfg.Tools.Ls),
 		tools.NewSourcegraphTool(nil),
+		tools.NewTodosTool(c.sessions),
 		tools.NewViewTool(c.lspClients, c.permissions, c.cfg.WorkingDir()),
 		tools.NewWriteTool(c.lspClients, c.permissions, c.history, c.cfg.WorkingDir()),
 	)
@@ -783,6 +786,10 @@ func (c *coordinator) QueuedPrompts(sessionID string) int {
 	return c.currentAgent.QueuedPrompts(sessionID)
 }
 
+func (c *coordinator) QueuedPromptsList(sessionID string) []string {
+	return c.currentAgent.QueuedPromptsList(sessionID)
+}
+
 func (c *coordinator) Summarize(ctx context.Context, sessionID string) error {
 	providerCfg, ok := c.cfg.Providers.Get(c.currentAgent.Model().ModelCfg.Provider)
 	if !ok {

internal/agent/templates/summary.md πŸ”—

@@ -43,6 +43,6 @@ Be specific. Don't write "implement authentication" - write:
 2. Update login handler in src/routes/user.js:45 to return token
 3. Test with: npm test -- auth.test.js
 
-**Tone**: Write as if briefing a teammate taking over mid-task. Include everything they'd need to continue without asking questions.
+**Tone**: Write as if briefing a teammate taking over mid-task. Include everything they'd need to continue without asking questions. No emojis ever.
 
 **Length**: No limit. Err on the side of too much detail rather than too little. Critical context is worth the tokens.

internal/agent/testdata/TestCoderAgent/anthropic-sonnet/bash_tool.yaml πŸ”—

@@ -25,55 +25,52 @@ interactions:
     content_length: -1
     body: |+
       event: message_start
-      data: {"type":"message_start","message":{"model":"claude-3-5-haiku-20241022","id":"msg_01WbEA766f9Qb2tqVyGdK8Vp","type":"message","role":"assistant","content":[],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":152,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":1,"service_tier":"standard"}}       }
+      data: {"type":"message_start","message":{"model":"claude-3-5-haiku-20241022","id":"msg_01Ca5xhYzdyJq1rP5TwDth2W","type":"message","role":"assistant","content":[],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":152,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":3,"service_tier":"standard"}}          }
 
       event: content_block_start
-      data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""}}
+      data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""}      }
 
       event: content_block_delta
-      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"Create"}            }
+      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"Bash File"}         }
 
       event: content_block_delta
-      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" Bash"}     }
+      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" Creation"}           }
 
       event: ping
       data: {"type": "ping"}
 
       event: content_block_delta
-      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" File"}               }
+      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" with"}       }
 
       event: content_block_delta
-      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" with"} }
+      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" Hello"} }
 
       event: content_block_delta
-      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" Hello"}       }
-
-      event: content_block_delta
-      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" Message"}   }
+      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" Content"}               }
 
       event: content_block_stop
-      data: {"type":"content_block_stop","index":0 }
+      data: {"type":"content_block_stop","index":0            }
 
       event: message_delta
-      data: {"type":"message_delta","delta":{"stop_reason":"end_turn","stop_sequence":null},"usage":{"input_tokens":152,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"output_tokens":10}    }
+      data: {"type":"message_delta","delta":{"stop_reason":"end_turn","stop_sequence":null},"usage":{"input_tokens":152,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"output_tokens":10}}
 
       event: message_stop
-      data: {"type":"message_stop"            }
+      data: {"type":"message_stop"          }
 
     headers:
       Content-Type:
       - text/event-stream; charset=utf-8
     status: 200 OK
     code: 200
-    duration: 578.171791ms
+    duration: 734.910625ms
 - id: 1
   request:
     proto: HTTP/1.1
     proto_major: 1
     proto_minor: 1
-    content_length: 51454
+    content_length: 51899
     host: ""

internal/agent/testdata/TestCoderAgent/anthropic-sonnet/download_tool.yaml πŸ”—

@@ -25,49 +25,46 @@ interactions:
     content_length: -1
     body: |+
       event: message_start
-      data: {"type":"message_start","message":{"model":"claude-3-5-haiku-20241022","id":"msg_016cryhi9rouvHEAvvdKN8UD","type":"message","role":"assistant","content":[],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":160,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":1,"service_tier":"standard"}}         }
+      data: {"type":"message_start","message":{"model":"claude-3-5-haiku-20241022","id":"msg_012dSg4T5MVDEgj8PUhB7ihp","type":"message","role":"assistant","content":[],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":160,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":1,"service_tier":"standard"}}       }
 
       event: content_block_start
-      data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""}      }
+      data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""}             }
 
       event: content_block_delta
-      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"Downloa"}      }
+      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"Downloa"}     }
 
       event: content_block_delta
-      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"d Example"}               }
+      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"d File"}          }
 
       event: ping
       data: {"type": "ping"}
 
       event: content_block_delta
-      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" Text"}       }
-
-      event: content_block_delta
-      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" File"}             }
+      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" from Example URL"}          }
 
       event: content_block_stop
-      data: {"type":"content_block_stop","index":0       }
+      data: {"type":"content_block_stop","index":0   }
 
       event: message_delta
-      data: {"type":"message_delta","delta":{"stop_reason":"end_turn","stop_sequence":null},"usage":{"input_tokens":160,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"output_tokens":7}            }
+      data: {"type":"message_delta","delta":{"stop_reason":"end_turn","stop_sequence":null},"usage":{"input_tokens":160,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"output_tokens":8}             }
 
       event: message_stop
-      data: {"type":"message_stop"               }
+      data: {"type":"message_stop"             }
 
     headers:
       Content-Type:
       - text/event-stream; charset=utf-8
     status: 200 OK
     code: 200
-    duration: 501.558292ms
+    duration: 733.403208ms
 - id: 1
   request:
     proto: HTTP/1.1
     proto_major: 1
     proto_minor: 1
-    content_length: 51479
+    content_length: 51924
     host: ""

internal/agent/testdata/TestCoderAgent/anthropic-sonnet/fetch_tool.yaml πŸ”—

@@ -25,46 +25,52 @@ interactions:
     content_length: -1
     body: |+
       event: message_start
-      data: {"type":"message_start","message":{"model":"claude-3-5-haiku-20241022","id":"msg_01PA2SxHoJrhJcDMR54kAth4","type":"message","role":"assistant","content":[],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":167,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":1,"service_tier":"standard"}}    }
+      data: {"type":"message_start","message":{"model":"claude-3-5-haiku-20241022","id":"msg_0143Jw7v3wgt2bpCFEtGkuHv","type":"message","role":"assistant","content":[],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":167,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":1,"service_tier":"standard"}} }
 
       event: content_block_start
-      data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""}           }
+      data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""}         }
 
       event: content_block_delta
-      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"Web"} }
+      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"Web"}           }
 
       event: content_block_delta
-      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" Page"}      }
+      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" Page Search"} }
 
       event: ping
       data: {"type": "ping"}
 
       event: content_block_delta
-      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" Content Check"}  }
+      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" for"}   }
+
+      event: content_block_delta
+      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" John"}         }
+
+      event: content_block_delta
+      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" Doe"}             }
 
       event: content_block_stop
-      data: {"type":"content_block_stop","index":0         }
+      data: {"type":"content_block_stop","index":0            }
 
       event: message_delta
-      data: {"type":"message_delta","delta":{"stop_reason":"end_turn","stop_sequence":null},"usage":{"input_tokens":167,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"output_tokens":7}}
+      data: {"type":"message_delta","delta":{"stop_reason":"end_turn","stop_sequence":null},"usage":{"input_tokens":167,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"output_tokens":10}    }
 
       event: message_stop
-      data: {"type":"message_stop"            }
+      data: {"type":"message_stop"             }
 
     headers:
       Content-Type:
       - text/event-stream; charset=utf-8
     status: 200 OK
     code: 200
-    duration: 771.713375ms
+    duration: 1.120772708s
 - id: 1
   request:
     proto: HTTP/1.1
     proto_major: 1
     proto_minor: 1
-    content_length: 51497
+    content_length: 51942
     host: ""

internal/agent/testdata/TestCoderAgent/anthropic-sonnet/glob_tool.yaml πŸ”—

@@ -25,49 +25,49 @@ interactions:
     content_length: -1
     body: |+
       event: message_start
-      data: {"type":"message_start","message":{"model":"claude-3-5-haiku-20241022","id":"msg_01MhpV7YNxJwSxgfQbfgDWut","type":"message","role":"assistant","content":[],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":142,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":1,"service_tier":"standard"}}              }
+      data: {"type":"message_start","message":{"model":"claude-3-5-haiku-20241022","id":"msg_01UJrSNzeuTRKfD6edRAnioA","type":"message","role":"assistant","content":[],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":142,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":3,"service_tier":"standard"}}          }
 
       event: content_block_start
-      data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""}         }
+      data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""}   }
 
       event: content_block_delta
-      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"Fin"}}
+      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"Glob Go"}        }
 
       event: content_block_delta
-      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"d Go"}               }
+      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" Files"}     }
 
       event: ping
       data: {"type": "ping"}
 
       event: content_block_delta
-      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" Files Using"}        }
+      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" in"}  }
 
       event: content_block_delta
-      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" Glob"}             }
+      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" Current Directory"}              }
 
       event: content_block_stop
-      data: {"type":"content_block_stop","index":0           }
+      data: {"type":"content_block_stop","index":0              }
 
       event: message_delta
-      data: {"type":"message_delta","delta":{"stop_reason":"end_turn","stop_sequence":null},"usage":{"input_tokens":142,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"output_tokens":9}        }
+      data: {"type":"message_delta","delta":{"stop_reason":"end_turn","stop_sequence":null},"usage":{"input_tokens":142,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"output_tokens":10}     }
 
       event: message_stop
-      data: {"type":"message_stop"             }
+      data: {"type":"message_stop"           }
 
     headers:
       Content-Type:
       - text/event-stream; charset=utf-8
     status: 200 OK
     code: 200
-    duration: 590.110084ms
+    duration: 596.908916ms
 - id: 1
   request:
     proto: HTTP/1.1
     proto_major: 1
     proto_minor: 1
-    content_length: 51415
+    content_length: 51860
     host: ""

internal/agent/testdata/TestCoderAgent/anthropic-sonnet/grep_tool.yaml πŸ”—

@@ -25,49 +25,52 @@ interactions:
     content_length: -1
     body: |+
       event: message_start
-      data: {"type":"message_start","message":{"model":"claude-3-5-haiku-20241022","id":"msg_01ReLDtAAvXCD3g8NAwbvwfh","type":"message","role":"assistant","content":[],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":144,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":2,"service_tier":"standard"}}   }
+      data: {"type":"message_start","message":{"model":"claude-3-5-haiku-20241022","id":"msg_01EPKmtSyVdvAn6uZoDUPvmm","type":"message","role":"assistant","content":[],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":144,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":2,"service_tier":"standard"}}        }
 
       event: content_block_start
-      data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""}        }
+      data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""}              }
 
       event: content_block_delta
-      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"Grep"}   }
+      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"Searching"}      }
 
       event: content_block_delta
-      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" "}  }
+      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" for "}          }
 
       event: ping
       data: {"type": "ping"}
 
       event: content_block_delta
-      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"'package' in Go"}   }
+      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"'package' in Go"}           }
 
       event: content_block_delta
-      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" Files"}               }
+      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" files with"}            }
+
+      event: content_block_delta
+      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" grep"}}
 
       event: content_block_stop
-      data: {"type":"content_block_stop","index":0           }
+      data: {"type":"content_block_stop","index":0        }
 
       event: message_delta
-      data: {"type":"message_delta","delta":{"stop_reason":"end_turn","stop_sequence":null},"usage":{"input_tokens":144,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"output_tokens":12}  }
+      data: {"type":"message_delta","delta":{"stop_reason":"end_turn","stop_sequence":null},"usage":{"input_tokens":144,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"output_tokens":15}           }
 
       event: message_stop
-      data: {"type":"message_stop"       }
+      data: {"type":"message_stop"            }
 
     headers:
       Content-Type:
       - text/event-stream; charset=utf-8
     status: 200 OK
     code: 200
-    duration: 499.278667ms
+    duration: 669.560167ms
 - id: 1
   request:
     proto: HTTP/1.1
     proto_major: 1
     proto_minor: 1
-    content_length: 51413
+    content_length: 51858
     host: ""

internal/agent/testdata/TestCoderAgent/anthropic-sonnet/ls_tool.yaml πŸ”—

@@ -25,46 +25,37 @@ interactions:
     content_length: -1
     body: |+
       event: message_start
-      data: {"type":"message_start","message":{"model":"claude-3-5-haiku-20241022","id":"msg_01ATXFbLmKeJh2VY3HTYMXWJ","type":"message","role":"assistant","content":[],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":140,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":1,"service_tier":"standard"}}             }
+      data: {"type":"message_start","message":{"model":"claude-3-5-haiku-20241022","id":"msg_01GS9L44gUzv4ei1fm9E5B1T","type":"message","role":"assistant","content":[],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":140,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":6,"service_tier":"standard"}}}
 
       event: content_block_start
-      data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""}       }
+      data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""}         }
 
       event: content_block_delta
-      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"List"}          }
-
-      event: content_block_delta
-      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" Files"}}
-
-      event: ping
-      data: {"type": "ping"}
-
-      event: content_block_delta
-      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" in Current Directory"}           }
+      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"Listing Files in Current Directory"}             }
 
       event: content_block_stop
-      data: {"type":"content_block_stop","index":0              }
+      data: {"type":"content_block_stop","index":0          }
 
       event: message_delta
-      data: {"type":"message_delta","delta":{"stop_reason":"end_turn","stop_sequence":null},"usage":{"input_tokens":140,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"output_tokens":8}      }
+      data: {"type":"message_delta","delta":{"stop_reason":"end_turn","stop_sequence":null},"usage":{"input_tokens":140,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"output_tokens":9}             }
 
       event: message_stop
-      data: {"type":"message_stop"}
+      data: {"type":"message_stop"   }
 
     headers:
       Content-Type:
       - text/event-stream; charset=utf-8
     status: 200 OK
     code: 200
-    duration: 576.743583ms
+    duration: 588.114167ms
 - id: 1
   request:
     proto: HTTP/1.1
     proto_major: 1
     proto_minor: 1
-    content_length: 51407
+    content_length: 51852
     host: ""

internal/agent/testdata/TestCoderAgent/anthropic-sonnet/multiedit_tool.yaml πŸ”—

@@ -25,55 +25,49 @@ interactions:
     content_length: -1
     body: |+
       event: message_start
-      data: {"type":"message_start","message":{"model":"claude-3-5-haiku-20241022","id":"msg_01YPw8B7xdJgtQzmBD1yTU4e","type":"message","role":"assistant","content":[],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":170,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":2,"service_tier":"standard"}}               }
+      data: {"type":"message_start","message":{"model":"claude-3-5-haiku-20241022","id":"msg_01Vi9HRV9KsgZmVqi14RD4Qd","type":"message","role":"assistant","content":[],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":170,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":1,"service_tier":"standard"}}       }
 
       event: content_block_start
-      data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""} }
+      data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""}  }
 
       event: content_block_delta
-      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"Modify"}          }
+      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"Edit"}      }
 
       event: content_block_delta
-      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" Go"}           }
+      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" Go"}          }
 
       event: ping
       data: {"type": "ping"}
 
       event: content_block_delta
-      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" code greeting"}            }
+      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" Code"}    }
 
       event: content_block_delta
-      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" with"}             }
-
-      event: content_block_delta
-      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" mult"}             }
-
-      event: content_block_delta
-      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"iedit"}               }
+      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" Greeting"}        }
 
       event: content_block_stop
-      data: {"type":"content_block_stop","index":0       }
+      data: {"type":"content_block_stop","index":0        }
 
       event: message_delta
-      data: {"type":"message_delta","delta":{"stop_reason":"end_turn","stop_sequence":null},"usage":{"input_tokens":170,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"output_tokens":12}       }
+      data: {"type":"message_delta","delta":{"stop_reason":"end_turn","stop_sequence":null},"usage":{"input_tokens":170,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"output_tokens":8}   }
 
       event: message_stop
-      data: {"type":"message_stop"}
+      data: {"type":"message_stop"      }
 
     headers:
       Content-Type:
       - text/event-stream; charset=utf-8
     status: 200 OK
     code: 200
-    duration: 626.47275ms
+    duration: 672.068792ms
 - id: 1
   request:
     proto: HTTP/1.1
     proto_major: 1
     proto_minor: 1
-    content_length: 51493
+    content_length: 51938
     host: ""

internal/agent/testdata/TestCoderAgent/anthropic-sonnet/parallel_tool_calls.yaml πŸ”—

@@ -25,52 +25,49 @@ interactions:
     content_length: -1
     body: |+
       event: message_start
-      data: {"type":"message_start","message":{"model":"claude-3-5-haiku-20241022","id":"msg_017rF4mnQoNTWfhWntCaRXWD","type":"message","role":"assistant","content":[],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":159,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":2,"service_tier":"standard"}}            }
+      data: {"type":"message_start","message":{"model":"claude-3-5-haiku-20241022","id":"msg_01MvZPBgrJ1PxooW6vcTNgTP","type":"message","role":"assistant","content":[],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":159,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":2,"service_tier":"standard"}}  }
 
       event: content_block_start
-      data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""}    }
+      data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""}         }
 
       event: content_block_delta
-      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"Parallel"}   }
+      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"Parallel"}    }
 
       event: content_block_delta
-      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" Go"}       }
+      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" Go File"}   }
 
       event: ping
       data: {"type": "ping"}
 
       event: content_block_delta
-      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" File"}         }
+      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" Discovery"} }
 
       event: content_block_delta
-      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" Search and Directory"}            }
-
-      event: content_block_delta
-      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" Listing"}               }
+      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" and Listing"}      }
 
       event: content_block_stop
-      data: {"type":"content_block_stop","index":0               }
+      data: {"type":"content_block_stop","index":0 }
 
       event: message_delta
-      data: {"type":"message_delta","delta":{"stop_reason":"end_turn","stop_sequence":null},"usage":{"input_tokens":159,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"output_tokens":12}    }
+      data: {"type":"message_delta","delta":{"stop_reason":"end_turn","stop_sequence":null},"usage":{"input_tokens":159,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"output_tokens":11} }
 
       event: message_stop
-      data: {"type":"message_stop"             }
+      data: {"type":"message_stop"              }
 
     headers:
       Content-Type:
       - text/event-stream; charset=utf-8
     status: 200 OK
     code: 200
-    duration: 585.640291ms
+    duration: 643.790917ms
 - id: 1
   request:
     proto: HTTP/1.1
     proto_major: 1
     proto_minor: 1
-    content_length: 51504
+    content_length: 51949
     host: ""

internal/agent/testdata/TestCoderAgent/anthropic-sonnet/read_a_file.yaml πŸ”—

@@ -25,49 +25,49 @@ interactions:
     content_length: -1
     body: |+
       event: message_start
-      data: {"type":"message_start","message":{"model":"claude-3-5-haiku-20241022","id":"msg_01Etybfx88gjFFiDkGoW3TVC","type":"message","role":"assistant","content":[],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":134,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":1,"service_tier":"standard"}}  }
+      data: {"type":"message_start","message":{"model":"claude-3-5-haiku-20241022","id":"msg_01WSfpakrUTZru3pucFjjWmQ","type":"message","role":"assistant","content":[],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":134,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":1,"service_tier":"standard"}}       }
 
       event: content_block_start
-      data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""}            }
+      data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""}      }
 
       event: content_block_delta
-      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"Rea"}}
+      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"Rea"}    }
 
       event: content_block_delta
-      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"d Go"}       }
+      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"d Go"}     }
 
       event: ping
       data: {"type": "ping"}
 
       event: content_block_delta
-      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" Module"}           }
+      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" Module"}     }
 
       event: content_block_delta
-      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" Details"}         }
+      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" Dependencies"}        }
 
       event: content_block_stop
-      data: {"type":"content_block_stop","index":0 }
+      data: {"type":"content_block_stop","index":0               }
 
       event: message_delta
-      data: {"type":"message_delta","delta":{"stop_reason":"end_turn","stop_sequence":null},"usage":{"input_tokens":134,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"output_tokens":7}               }
+      data: {"type":"message_delta","delta":{"stop_reason":"end_turn","stop_sequence":null},"usage":{"input_tokens":134,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"output_tokens":7}          }
 
       event: message_stop
-      data: {"type":"message_stop"              }
+      data: {"type":"message_stop"            }
 
     headers:
       Content-Type:
       - text/event-stream; charset=utf-8
     status: 200 OK
     code: 200
-    duration: 655.510125ms
+    duration: 987.366375ms
 - id: 1
   request:
     proto: HTTP/1.1
     proto_major: 1
     proto_minor: 1
-    content_length: 51377
+    content_length: 51822
     host: ""

internal/agent/testdata/TestCoderAgent/anthropic-sonnet/simple_test.yaml πŸ”—

@@ -25,22 +25,22 @@ interactions:
     content_length: -1
     body: |+
       event: message_start
-      data: {"type":"message_start","message":{"model":"claude-3-5-haiku-20241022","id":"msg_01HximU37BpsyPaDMP2TpWQ1","type":"message","role":"assistant","content":[],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":131,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":1,"service_tier":"standard"}}     }
+      data: {"type":"message_start","message":{"model":"claude-3-5-haiku-20241022","id":"msg_01TxmeH5H2NGkxM58ZrqhuU1","type":"message","role":"assistant","content":[],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":131,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":1,"service_tier":"standard"}}        }
 
       event: content_block_start
-      data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""}      }
+      data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""}              }
 
       event: content_block_delta
-      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"Quick"}  }
+      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"Quick"}        }
 
       event: content_block_delta
-      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" Greeting"}   }
+      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" Greeting"}      }
 
       event: ping
       data: {"type": "ping"}
 
       event: content_block_stop
-      data: {"type":"content_block_stop","index":0}
+      data: {"type":"content_block_stop","index":0         }
 
       event: ping
       data: {"type": "ping"}
@@ -49,7 +49,7 @@ interactions:
       data: {"type": "ping"}
 
       event: message_delta
-      data: {"type":"message_delta","delta":{"stop_reason":"end_turn","stop_sequence":null},"usage":{"input_tokens":131,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"output_tokens":6}         }
+      data: {"type":"message_delta","delta":{"stop_reason":"end_turn","stop_sequence":null},"usage":{"input_tokens":131,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"output_tokens":6}    }
 
       event: message_stop
       data: {"type":"message_stop"             }
@@ -59,15 +59,15 @@ interactions:
       - text/event-stream; charset=utf-8
     status: 200 OK
     code: 200
-    duration: 808.120542ms
+    duration: 700.496625ms
 - id: 1
   request:
     proto: HTTP/1.1
     proto_major: 1
     proto_minor: 1
-    content_length: 51367
+    content_length: 51812
     host: ""

internal/agent/testdata/TestCoderAgent/anthropic-sonnet/sourcegraph_tool.yaml πŸ”—

@@ -25,49 +25,49 @@ interactions:
     content_length: -1
     body: |+
       event: message_start
-      data: {"type":"message_start","message":{"model":"claude-3-5-haiku-20241022","id":"msg_01Vumd9wiF4q5LKxZ4nc5eGM","type":"message","role":"assistant","content":[],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":145,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":3,"service_tier":"standard"}} }
+      data: {"type":"message_start","message":{"model":"claude-3-5-haiku-20241022","id":"msg_014dxeWmvWs82uYJw8q11pgi","type":"message","role":"assistant","content":[],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":145,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":3,"service_tier":"standard"}}               }
 
       event: content_block_start
-      data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""} }
+      data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""}    }
 
       event: content_block_delta
-      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"Searching Go"}     }
+      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"Searching Go"}          }
 
       event: content_block_delta
-      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" Repos"}            }
+      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" Repos"}       }
 
       event: ping
       data: {"type": "ping"}
 
       event: content_block_delta
-      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" for Main"}       }
+      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" for Main"}      }
 
       event: content_block_delta
-      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" Functions"}           }
+      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" Function"}}
 
       event: content_block_stop
-      data: {"type":"content_block_stop","index":0 }
+      data: {"type":"content_block_stop","index":0              }
 
       event: message_delta
-      data: {"type":"message_delta","delta":{"stop_reason":"end_turn","stop_sequence":null},"usage":{"input_tokens":145,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"output_tokens":11} }
+      data: {"type":"message_delta","delta":{"stop_reason":"end_turn","stop_sequence":null},"usage":{"input_tokens":145,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"output_tokens":11}   }
 
       event: message_stop
-      data: {"type":"message_stop"          }
+      data: {"type":"message_stop"       }
 
     headers:
       Content-Type:
       - text/event-stream; charset=utf-8
     status: 200 OK
     code: 200
-    duration: 966.588833ms
+    duration: 720.76ms
 - id: 1
   request:
     proto: HTTP/1.1
     proto_major: 1
     proto_minor: 1
-    content_length: 51427
+    content_length: 51872
     host: ""

internal/agent/testdata/TestCoderAgent/anthropic-sonnet/update_a_file.yaml πŸ”—

@@ -25,49 +25,49 @@ interactions:
     content_length: -1
     body: |+
       event: message_start
-      data: {"type":"message_start","message":{"model":"claude-3-5-haiku-20241022","id":"msg_01FZibKN7Bdpd79Lx3jXBCqw","type":"message","role":"assistant","content":[],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":145,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":1,"service_tier":"standard"}}               }
+      data: {"type":"message_start","message":{"model":"claude-3-5-haiku-20241022","id":"msg_018Kk1bqYYWgiDzM5DRrtHhL","type":"message","role":"assistant","content":[],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":145,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":1,"service_tier":"standard"}}    }
 
       event: content_block_start
-      data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""}         }
+      data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""} }
 
       event: content_block_delta
-      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"Update"}            }
+      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"Update"}  }
 
       event: content_block_delta
-      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" main"}    }
+      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" main"}     }
 
       event: ping
       data: {"type": "ping"}
 
       event: content_block_delta
-      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":".go Hello"}      }
+      data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":".go Hello"}            }
 
       event: content_block_delta
       data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" Print"}          }
 
       event: content_block_stop
-      data: {"type":"content_block_stop","index":0           }
+      data: {"type":"content_block_stop","index":0       }
 
       event: message_delta
-      data: {"type":"message_delta","delta":{"stop_reason":"end_turn","stop_sequence":null},"usage":{"input_tokens":145,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"output_tokens":9} }
+      data: {"type":"message_delta","delta":{"stop_reason":"end_turn","stop_sequence":null},"usage":{"input_tokens":145,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"output_tokens":9}           }
 
       event: message_stop
-      data: {"type":"message_stop"           }
+      data: {"type":"message_stop"       }
 
     headers:
       Content-Type:
       - text/event-stream; charset=utf-8
     status: 200 OK
     code: 200
-    duration: 575.783417ms
+    duration: 694.563833ms
 - id: 1
   request:
     proto: HTTP/1.1
     proto_major: 1
     proto_minor: 1
-    content_length: 51433
+    content_length: 51878
     host: ""

internal/agent/testdata/TestCoderAgent/anthropic-sonnet/write_tool.yaml πŸ”—

@@ -6,9 +6,9 @@ interactions:
     proto: HTTP/1.1
     proto_major: 1
     proto_minor: 1
-    content_length: 817
+    content_length: 51915
     host: ""
-    body: '{"max_tokens":40,"messages":[{"content":[{"text":"Generate a concise title for the following content:\n\nuse write to create a new file called config.json with content ''{\"name\": \"test\", \"version\": \"1.0.0\"}''\n \u003cthink\u003e\n\n\u003c/think\u003e","type":"text"}],"role":"user"}],"model":"claude-3-5-haiku-20241022","system":[{"text":"you will generate a short title based on the first message a user begins a conversation with\n\n\u003crules\u003e\n- ensure it is not more than 50 characters long\n- the title should be a summary of the user''s message\n- it should be one line long\n- do not use quotes or colons\n- the entire text you return will be used as the title\n- never return anything that is more than one sentence (one line) long\n\u003c/rules\u003e\n\n /no_think","type":"text"}],"stream":true}'

internal/agent/testdata/TestCoderAgent/openai-gpt-5/bash_tool.yaml πŸ”—

@@ -24,33 +24,39 @@ interactions:
     proto_minor: 0
     content_length: -1
     body: |+
-      data: {"id":"chatcmpl-Cj5ey31f4omQlYpBM4nxpPZtHo4q6","object":"chat.completion.chunk","created":1764862552,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"Ge9aw4xR7J9UOe"}
+      data: {"id":"chatcmpl-ClYsFUmhoDNbyWMbB2NUY9x4VTTUz","object":"chat.completion.chunk","created":1765451507,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"Td2HKw2IKaNJr9"}
 
-      data: {"id":"chatcmpl-Cj5ey31f4omQlYpBM4nxpPZtHo4q6","object":"chat.completion.chunk","created":1764862552,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{"content":"Create"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"9mD6Z8e3hz"}
+      data: {"id":"chatcmpl-ClYsFUmhoDNbyWMbB2NUY9x4VTTUz","object":"chat.completion.chunk","created":1765451507,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":"Create"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"Ey6L7K1jHN"}
 
-      data: {"id":"chatcmpl-Cj5ey31f4omQlYpBM4nxpPZtHo4q6","object":"chat.completion.chunk","created":1764862552,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{"content":" File"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"uacc3w7vZwR"}
+      data: {"id":"chatcmpl-ClYsFUmhoDNbyWMbB2NUY9x4VTTUz","object":"chat.completion.chunk","created":1765451507,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":" '"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"fxtu1PxLkFzDn0"}
 
-      data: {"id":"chatcmpl-Cj5ey31f4omQlYpBM4nxpPZtHo4q6","object":"chat.completion.chunk","created":1764862552,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{"content":" test"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"XajeGpvAt5S"}
+      data: {"id":"chatcmpl-ClYsFUmhoDNbyWMbB2NUY9x4VTTUz","object":"chat.completion.chunk","created":1765451507,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":"test"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"qLh2W9DjfN9T"}
 
-      data: {"id":"chatcmpl-Cj5ey31f4omQlYpBM4nxpPZtHo4q6","object":"chat.completion.chunk","created":1764862552,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{"content":".txt"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"pyGHV4e7XDyx"}
+      data: {"id":"chatcmpl-ClYsFUmhoDNbyWMbB2NUY9x4VTTUz","object":"chat.completion.chunk","created":1765451507,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":".txt"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"sYxRQ6oIdl88"}
 
-      data: {"id":"chatcmpl-Cj5ey31f4omQlYpBM4nxpPZtHo4q6","object":"chat.completion.chunk","created":1764862552,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{"content":" with"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"rCcPV5Ebktw"}
+      data: {"id":"chatcmpl-ClYsFUmhoDNbyWMbB2NUY9x4VTTUz","object":"chat.completion.chunk","created":1765451507,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":"'"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"izmAYTbsu7SDTrw"}
 
-      data: {"id":"chatcmpl-Cj5ey31f4omQlYpBM4nxpPZtHo4q6","object":"chat.completion.chunk","created":1764862552,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{"content":" '"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"2Jhs0JX1uR1H4P"}
+      data: {"id":"chatcmpl-ClYsFUmhoDNbyWMbB2NUY9x4VTTUz","object":"chat.completion.chunk","created":1765451507,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":" with"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"eQKZqQvnykY"}
 
-      data: {"id":"chatcmpl-Cj5ey31f4omQlYpBM4nxpPZtHo4q6","object":"chat.completion.chunk","created":1764862552,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{"content":"hello"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"7cP9d0yjB1m"}
+      data: {"id":"chatcmpl-ClYsFUmhoDNbyWMbB2NUY9x4VTTUz","object":"chat.completion.chunk","created":1765451507,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":" '"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"CfOJWpN6vzSRL6"}
 
-      data: {"id":"chatcmpl-Cj5ey31f4omQlYpBM4nxpPZtHo4q6","object":"chat.completion.chunk","created":1764862552,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{"content":" bash"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"jzkkMLcPlX0"}
+      data: {"id":"chatcmpl-ClYsFUmhoDNbyWMbB2NUY9x4VTTUz","object":"chat.completion.chunk","created":1765451507,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":"hello"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"AKmZ7DtXoX1"}
 
-      data: {"id":"chatcmpl-Cj5ey31f4omQlYpBM4nxpPZtHo4q6","object":"chat.completion.chunk","created":1764862552,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{"content":"'"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"ZSTCYu5wWzA9kQl"}
+      data: {"id":"chatcmpl-ClYsFUmhoDNbyWMbB2NUY9x4VTTUz","object":"chat.completion.chunk","created":1765451507,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":" bash"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"0jL8W258MN9"}
 
-      data: {"id":"chatcmpl-Cj5ey31f4omQlYpBM4nxpPZtHo4q6","object":"chat.completion.chunk","created":1764862552,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{"content":" in"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"GS4OajGMLokcX"}
+      data: {"id":"chatcmpl-ClYsFUmhoDNbyWMbB2NUY9x4VTTUz","object":"chat.completion.chunk","created":1765451507,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":"'"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"hrqjW9CeiV7hZV3"}
 
-      data: {"id":"chatcmpl-Cj5ey31f4omQlYpBM4nxpPZtHo4q6","object":"chat.completion.chunk","created":1764862552,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{"content":" Bash"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"NnSiqg12rqr"}
+      data: {"id":"chatcmpl-ClYsFUmhoDNbyWMbB2NUY9x4VTTUz","object":"chat.completion.chunk","created":1765451507,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":" ("},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"vNmpaJaHqND1Zq"}
 
-      data: {"id":"chatcmpl-Cj5ey31f4omQlYpBM4nxpPZtHo4q6","object":"chat.completion.chunk","created":1764862552,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}],"usage":null,"obfuscation":"vCjULykNu8"}
+      data: {"id":"chatcmpl-ClYsFUmhoDNbyWMbB2NUY9x4VTTUz","object":"chat.completion.chunk","created":1765451507,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":"No"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"MIhLl8PruYZSZ4"}
 
-      data: {"id":"chatcmpl-Cj5ey31f4omQlYpBM4nxpPZtHo4q6","object":"chat.completion.chunk","created":1764862552,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[],"usage":{"prompt_tokens":145,"completion_tokens":11,"total_tokens":156,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":0,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}},"obfuscation":"Wa56pakK1PBNi"}
+      data: {"id":"chatcmpl-ClYsFUmhoDNbyWMbB2NUY9x4VTTUz","object":"chat.completion.chunk","created":1765451507,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":" Timestamp"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"mawxsP"}
+
+      data: {"id":"chatcmpl-ClYsFUmhoDNbyWMbB2NUY9x4VTTUz","object":"chat.completion.chunk","created":1765451507,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":")"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"mXXHjOhPYNysGmp"}
+
+      data: {"id":"chatcmpl-ClYsFUmhoDNbyWMbB2NUY9x4VTTUz","object":"chat.completion.chunk","created":1765451507,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}],"usage":null,"obfuscation":"ychGSlZNPt"}
+
+      data: {"id":"chatcmpl-ClYsFUmhoDNbyWMbB2NUY9x4VTTUz","object":"chat.completion.chunk","created":1765451507,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[],"usage":{"prompt_tokens":145,"completion_tokens":14,"total_tokens":159,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":0,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}},"obfuscation":"G55W87gCWryQY"}
 
       data: [DONE]
 
@@ -59,15 +65,15 @@ interactions:
       - text/event-stream; charset=utf-8
     status: 200 OK
     code: 200
-    duration: 491.401209ms
+    duration: 868.570625ms
 - id: 1
   request:
     proto: HTTP/1.1
     proto_major: 1
     proto_minor: 1
-    content_length: 49849
+    content_length: 50240
     host: ""

internal/agent/testdata/TestCoderAgent/openai-gpt-5/download_tool.yaml πŸ”—

@@ -24,23 +24,23 @@ interactions:
     proto_minor: 0
     content_length: -1
     body: |+
-      data: {"id":"chatcmpl-Cj5fDSuOWOdQ0SBxZbFOe4k9XflAp","object":"chat.completion.chunk","created":1764862567,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_ed643dde95","choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"7tAT0Arcyy78i3"}
+      data: {"id":"chatcmpl-ClYUKarTNIqX0Kpv3s4rrlesi91DJ","object":"chat.completion.chunk","created":1765450024,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_ed643dde95","choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"SBHFH8rdbeYWL0"}
 
-      data: {"id":"chatcmpl-Cj5fDSuOWOdQ0SBxZbFOe4k9XflAp","object":"chat.completion.chunk","created":1764862567,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_ed643dde95","choices":[{"index":0,"delta":{"content":"Download"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"G2Yie7lB"}
+      data: {"id":"chatcmpl-ClYUKarTNIqX0Kpv3s4rrlesi91DJ","object":"chat.completion.chunk","created":1765450024,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_ed643dde95","choices":[{"index":0,"delta":{"content":"Download"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"bPE41kWI"}
 
-      data: {"id":"chatcmpl-Cj5fDSuOWOdQ0SBxZbFOe4k9XflAp","object":"chat.completion.chunk","created":1764862567,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_ed643dde95","choices":[{"index":0,"delta":{"content":" and"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"mvyX6i8Wzeag"}
+      data: {"id":"chatcmpl-ClYUKarTNIqX0Kpv3s4rrlesi91DJ","object":"chat.completion.chunk","created":1765450024,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_ed643dde95","choices":[{"index":0,"delta":{"content":" and"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"5ATvd6pCxOj1"}
 
-      data: {"id":"chatcmpl-Cj5fDSuOWOdQ0SBxZbFOe4k9XflAp","object":"chat.completion.chunk","created":1764862567,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_ed643dde95","choices":[{"index":0,"delta":{"content":" Save"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"UGnI0gb7vgN"}
+      data: {"id":"chatcmpl-ClYUKarTNIqX0Kpv3s4rrlesi91DJ","object":"chat.completion.chunk","created":1765450024,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_ed643dde95","choices":[{"index":0,"delta":{"content":" Save"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"k8YyVLEJsFk"}
 
-      data: {"id":"chatcmpl-Cj5fDSuOWOdQ0SBxZbFOe4k9XflAp","object":"chat.completion.chunk","created":1764862567,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_ed643dde95","choices":[{"index":0,"delta":{"content":" File"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"yeExQxXxzzT"}
+      data: {"id":"chatcmpl-ClYUKarTNIqX0Kpv3s4rrlesi91DJ","object":"chat.completion.chunk","created":1765450024,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_ed643dde95","choices":[{"index":0,"delta":{"content":" Example"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"4hxPHL2k"}
 
-      data: {"id":"chatcmpl-Cj5fDSuOWOdQ0SBxZbFOe4k9XflAp","object":"chat.completion.chunk","created":1764862567,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_ed643dde95","choices":[{"index":0,"delta":{"content":" from"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"czMH2AGcASt"}
+      data: {"id":"chatcmpl-ClYUKarTNIqX0Kpv3s4rrlesi91DJ","object":"chat.completion.chunk","created":1765450024,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_ed643dde95","choices":[{"index":0,"delta":{"content":".txt"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"jBNwgbcsI5wb"}
 
-      data: {"id":"chatcmpl-Cj5fDSuOWOdQ0SBxZbFOe4k9XflAp","object":"chat.completion.chunk","created":1764862567,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_ed643dde95","choices":[{"index":0,"delta":{"content":" URL"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"3q5ae7tFEpif"}
+      data: {"id":"chatcmpl-ClYUKarTNIqX0Kpv3s4rrlesi91DJ","object":"chat.completion.chunk","created":1765450024,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_ed643dde95","choices":[{"index":0,"delta":{"content":" File"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"mEEqjnrY9iu"}
 
-      data: {"id":"chatcmpl-Cj5fDSuOWOdQ0SBxZbFOe4k9XflAp","object":"chat.completion.chunk","created":1764862567,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_ed643dde95","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}],"usage":null,"obfuscation":"CrxvCdwMyS"}
+      data: {"id":"chatcmpl-ClYUKarTNIqX0Kpv3s4rrlesi91DJ","object":"chat.completion.chunk","created":1765450024,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_ed643dde95","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}],"usage":null,"obfuscation":"mF3cv51yHC"}
 
-      data: {"id":"chatcmpl-Cj5fDSuOWOdQ0SBxZbFOe4k9XflAp","object":"chat.completion.chunk","created":1764862567,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_ed643dde95","choices":[],"usage":{"prompt_tokens":148,"completion_tokens":6,"total_tokens":154,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":0,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}},"obfuscation":"z2bJFbxh3bvTFZ"}
+      data: {"id":"chatcmpl-ClYUKarTNIqX0Kpv3s4rrlesi91DJ","object":"chat.completion.chunk","created":1765450024,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_ed643dde95","choices":[],"usage":{"prompt_tokens":148,"completion_tokens":6,"total_tokens":154,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":0,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}},"obfuscation":"645bmFBdewh6aK"}
 
       data: [DONE]
 
@@ -49,15 +49,15 @@ interactions:
       - text/event-stream; charset=utf-8
     status: 200 OK
     code: 200
-    duration: 460.945041ms
+    duration: 2.300206458s
 - id: 1
   request:
     proto: HTTP/1.1
     proto_major: 1
     proto_minor: 1
-    content_length: 49874
+    content_length: 50265
     host: ""

internal/agent/testdata/TestCoderAgent/openai-gpt-5/fetch_tool.yaml πŸ”—

@@ -24,27 +24,29 @@ interactions:
     proto_minor: 0
     content_length: -1
     body: |+
-      data: {"id":"chatcmpl-Cj5fOooZsAoBwyWox3o3Q57ukzjEt","object":"chat.completion.chunk","created":1764862578,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"sUfkOyWhkBqMQv"}
+      data: {"id":"chatcmpl-ClYURxJKlkr2y8aUeB1zPKa2nZofo","object":"chat.completion.chunk","created":1765450031,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_37d212baff","choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"5yRyROJJtY3tB1"}
 
-      data: {"id":"chatcmpl-Cj5fOooZsAoBwyWox3o3Q57ukzjEt","object":"chat.completion.chunk","created":1764862578,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","choices":[{"index":0,"delta":{"content":"Check"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"J4mBcgLDZQA"}
+      data: {"id":"chatcmpl-ClYURxJKlkr2y8aUeB1zPKa2nZofo","object":"chat.completion.chunk","created":1765450031,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_37d212baff","choices":[{"index":0,"delta":{"content":"Check"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"yKEWMPUcA8L"}
 
-      data: {"id":"chatcmpl-Cj5fOooZsAoBwyWox3o3Q57ukzjEt","object":"chat.completion.chunk","created":1764862578,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","choices":[{"index":0,"delta":{"content":" HTML"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"Np4pSOJXim5"}
+      data: {"id":"chatcmpl-ClYURxJKlkr2y8aUeB1zPKa2nZofo","object":"chat.completion.chunk","created":1765450031,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_37d212baff","choices":[{"index":0,"delta":{"content":" HTML"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"5BVjTNgwxGF"}
 
-      data: {"id":"chatcmpl-Cj5fOooZsAoBwyWox3o3Q57ukzjEt","object":"chat.completion.chunk","created":1764862578,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","choices":[{"index":0,"delta":{"content":" for"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"ctxKdhnBw1sf"}
+      data: {"id":"chatcmpl-ClYURxJKlkr2y8aUeB1zPKa2nZofo","object":"chat.completion.chunk","created":1765450031,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_37d212baff","choices":[{"index":0,"delta":{"content":" for"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"kp7eosJWJN8K"}
 
-      data: {"id":"chatcmpl-Cj5fOooZsAoBwyWox3o3Q57ukzjEt","object":"chat.completion.chunk","created":1764862578,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","choices":[{"index":0,"delta":{"content":" '"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"o2XTlHg46XowKS"}
+      data: {"id":"chatcmpl-ClYURxJKlkr2y8aUeB1zPKa2nZofo","object":"chat.completion.chunk","created":1765450031,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_37d212baff","choices":[{"index":0,"delta":{"content":" '"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"EI6mQF37usHe1k"}
 
-      data: {"id":"chatcmpl-Cj5fOooZsAoBwyWox3o3Q57ukzjEt","object":"chat.completion.chunk","created":1764862578,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","choices":[{"index":0,"delta":{"content":"John"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"sAhG0QJxuV75"}
+      data: {"id":"chatcmpl-ClYURxJKlkr2y8aUeB1zPKa2nZofo","object":"chat.completion.chunk","created":1765450031,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_37d212baff","choices":[{"index":0,"delta":{"content":"John"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"ABTUDL8cGfX4"}
 
-      data: {"id":"chatcmpl-Cj5fOooZsAoBwyWox3o3Q57ukzjEt","object":"chat.completion.chunk","created":1764862578,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","choices":[{"index":0,"delta":{"content":" Doe"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"NVvpJyxEh7LN"}
+      data: {"id":"chatcmpl-ClYURxJKlkr2y8aUeB1zPKa2nZofo","object":"chat.completion.chunk","created":1765450031,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_37d212baff","choices":[{"index":0,"delta":{"content":" Doe"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"wkDSMVE1HEGV"}
 
-      data: {"id":"chatcmpl-Cj5fOooZsAoBwyWox3o3Q57ukzjEt","object":"chat.completion.chunk","created":1764862578,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","choices":[{"index":0,"delta":{"content":"'"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"N7R1RhjYQ459EQ6"}
+      data: {"id":"chatcmpl-ClYURxJKlkr2y8aUeB1zPKa2nZofo","object":"chat.completion.chunk","created":1765450031,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_37d212baff","choices":[{"index":0,"delta":{"content":"'"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"WGqcOyHkVBUn3GN"}
 
-      data: {"id":"chatcmpl-Cj5fOooZsAoBwyWox3o3Q57ukzjEt","object":"chat.completion.chunk","created":1764862578,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","choices":[{"index":0,"delta":{"content":" Presence"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"qtid0UV"}
+      data: {"id":"chatcmpl-ClYURxJKlkr2y8aUeB1zPKa2nZofo","object":"chat.completion.chunk","created":1765450031,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_37d212baff","choices":[{"index":0,"delta":{"content":" Occ"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"jRNw7JwV0CjM"}
 
-      data: {"id":"chatcmpl-Cj5fOooZsAoBwyWox3o3Q57ukzjEt","object":"chat.completion.chunk","created":1764862578,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}],"usage":null,"obfuscation":"iA9pbXYw5z"}
+      data: {"id":"chatcmpl-ClYURxJKlkr2y8aUeB1zPKa2nZofo","object":"chat.completion.chunk","created":1765450031,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_37d212baff","choices":[{"index":0,"delta":{"content":"urrence"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"BUi0S3QiX"}
 
-      data: {"id":"chatcmpl-Cj5fOooZsAoBwyWox3o3Q57ukzjEt","object":"chat.completion.chunk","created":1764862578,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","choices":[],"usage":{"prompt_tokens":153,"completion_tokens":8,"total_tokens":161,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":0,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}},"obfuscation":"iCIo2WpyvkXMLT"}
+      data: {"id":"chatcmpl-ClYURxJKlkr2y8aUeB1zPKa2nZofo","object":"chat.completion.chunk","created":1765450031,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_37d212baff","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}],"usage":null,"obfuscation":"8eZz7vsWF5"}
+
+      data: {"id":"chatcmpl-ClYURxJKlkr2y8aUeB1zPKa2nZofo","object":"chat.completion.chunk","created":1765450031,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_37d212baff","choices":[],"usage":{"prompt_tokens":153,"completion_tokens":9,"total_tokens":162,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":0,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}},"obfuscation":"xh04QkW7pY8HBI"}
 
       data: [DONE]
 
@@ -53,15 +55,15 @@ interactions:
       - text/event-stream; charset=utf-8
     status: 200 OK
     code: 200
-    duration: 725.754042ms
+    duration: 685.04625ms
 - id: 1
   request:
     proto: HTTP/1.1
     proto_major: 1
     proto_minor: 1
-    content_length: 49892
+    content_length: 50283
     host: ""

internal/agent/testdata/TestCoderAgent/openai-gpt-5/glob_tool.yaml πŸ”—

@@ -24,29 +24,29 @@ interactions:
     proto_minor: 0
     content_length: -1
     body: |+
-      data: {"id":"chatcmpl-Cj5fa2QolYljS3qhN3vnLxCmuZoQA","object":"chat.completion.chunk","created":1764862590,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"16RVLBo70eXYyb"}
+      data: {"id":"chatcmpl-ClYUaN1fZ88qHwOrCQkkOMgziqdJE","object":"chat.completion.chunk","created":1765450040,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"OJxEBFRUQsMFtg"}
 
-      data: {"id":"chatcmpl-Cj5fa2QolYljS3qhN3vnLxCmuZoQA","object":"chat.completion.chunk","created":1764862590,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{"content":"Find"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"H3CNJR7UnYYf"}
+      data: {"id":"chatcmpl-ClYUaN1fZ88qHwOrCQkkOMgziqdJE","object":"chat.completion.chunk","created":1765450040,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":"Finding"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"JOYRZ62s3"}
 
-      data: {"id":"chatcmpl-Cj5fa2QolYljS3qhN3vnLxCmuZoQA","object":"chat.completion.chunk","created":1764862590,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{"content":" ."},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"8EHPibBq2Oyh5G"}
+      data: {"id":"chatcmpl-ClYUaN1fZ88qHwOrCQkkOMgziqdJE","object":"chat.completion.chunk","created":1765450040,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":" ."},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"j6Tj6K3c90Yt3W"}
 
-      data: {"id":"chatcmpl-Cj5fa2QolYljS3qhN3vnLxCmuZoQA","object":"chat.completion.chunk","created":1764862590,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{"content":"go"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"03h9ZkWLJaXLHB"}
+      data: {"id":"chatcmpl-ClYUaN1fZ88qHwOrCQkkOMgziqdJE","object":"chat.completion.chunk","created":1765450040,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":"go"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"7tEx9wpgaAxzdu"}
 
-      data: {"id":"chatcmpl-Cj5fa2QolYljS3qhN3vnLxCmuZoQA","object":"chat.completion.chunk","created":1764862590,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{"content":" Files"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"WFWFQQFTwW"}
+      data: {"id":"chatcmpl-ClYUaN1fZ88qHwOrCQkkOMgziqdJE","object":"chat.completion.chunk","created":1765450040,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":" Files"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"w8uoytyqQX"}
 
-      data: {"id":"chatcmpl-Cj5fa2QolYljS3qhN3vnLxCmuZoQA","object":"chat.completion.chunk","created":1764862590,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{"content":" Using"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"iXVvGYfTO3"}
+      data: {"id":"chatcmpl-ClYUaN1fZ88qHwOrCQkkOMgziqdJE","object":"chat.completion.chunk","created":1765450040,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":" with"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"WoTpGAB81rR"}
 
-      data: {"id":"chatcmpl-Cj5fa2QolYljS3qhN3vnLxCmuZoQA","object":"chat.completion.chunk","created":1764862590,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{"content":" Glob"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"f0neSnHulJG"}
+      data: {"id":"chatcmpl-ClYUaN1fZ88qHwOrCQkkOMgziqdJE","object":"chat.completion.chunk","created":1765450040,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":" Glob"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"PhwR6Lr1W2b"}
 
-      data: {"id":"chatcmpl-Cj5fa2QolYljS3qhN3vnLxCmuZoQA","object":"chat.completion.chunk","created":1764862590,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{"content":" in"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"vCKNavIU1BmBL"}
+      data: {"id":"chatcmpl-ClYUaN1fZ88qHwOrCQkkOMgziqdJE","object":"chat.completion.chunk","created":1765450040,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":" in"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"wGYtTunHNFOqz"}
 
-      data: {"id":"chatcmpl-Cj5fa2QolYljS3qhN3vnLxCmuZoQA","object":"chat.completion.chunk","created":1764862590,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{"content":" Current"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"fRjcJFUO"}
+      data: {"id":"chatcmpl-ClYUaN1fZ88qHwOrCQkkOMgziqdJE","object":"chat.completion.chunk","created":1765450040,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":" Current"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"GmUMW63r"}
 
-      data: {"id":"chatcmpl-Cj5fa2QolYljS3qhN3vnLxCmuZoQA","object":"chat.completion.chunk","created":1764862590,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{"content":" Directory"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"1GHD97"}
+      data: {"id":"chatcmpl-ClYUaN1fZ88qHwOrCQkkOMgziqdJE","object":"chat.completion.chunk","created":1765450040,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":" Directory"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"gl03qy"}
 
-      data: {"id":"chatcmpl-Cj5fa2QolYljS3qhN3vnLxCmuZoQA","object":"chat.completion.chunk","created":1764862590,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}],"usage":null,"obfuscation":"srQFH2CGLq"}
+      data: {"id":"chatcmpl-ClYUaN1fZ88qHwOrCQkkOMgziqdJE","object":"chat.completion.chunk","created":1765450040,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}],"usage":null,"obfuscation":"UIlF9C9uHC"}
 
-      data: {"id":"chatcmpl-Cj5fa2QolYljS3qhN3vnLxCmuZoQA","object":"chat.completion.chunk","created":1764862590,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[],"usage":{"prompt_tokens":137,"completion_tokens":9,"total_tokens":146,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":0,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}},"obfuscation":"5HiN5A4vPg2Ar8"}
+      data: {"id":"chatcmpl-ClYUaN1fZ88qHwOrCQkkOMgziqdJE","object":"chat.completion.chunk","created":1765450040,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[],"usage":{"prompt_tokens":137,"completion_tokens":9,"total_tokens":146,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":0,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}},"obfuscation":"oFQUOYK96zZmPi"}
 
       data: [DONE]
 
@@ -55,15 +55,15 @@ interactions:
       - text/event-stream; charset=utf-8
     status: 200 OK
     code: 200
-    duration: 391.2975ms
+    duration: 947.669917ms
 - id: 1
   request:
     proto: HTTP/1.1
     proto_major: 1
     proto_minor: 1
-    content_length: 49810
+    content_length: 50201
     host: ""

internal/agent/testdata/TestCoderAgent/openai-gpt-5/grep_tool.yaml πŸ”—

@@ -24,31 +24,31 @@ interactions:
     proto_minor: 0
     content_length: -1
     body: |+
-      data: {"id":"chatcmpl-Cj5fjQoGed1aYVTFoxik5vpfMdIbm","object":"chat.completion.chunk","created":1764862599,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"zZ50ZbEMxRYuXH"}
+      data: {"id":"chatcmpl-ClYUe1xFnvcKQKG4RuOQ7N6udiviD","object":"chat.completion.chunk","created":1765450044,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"POqwkKG8YiDyy0"}
 
-      data: {"id":"chatcmpl-Cj5fjQoGed1aYVTFoxik5vpfMdIbm","object":"chat.completion.chunk","created":1764862599,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{"content":"Searching"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"fAoqwuP"}
+      data: {"id":"chatcmpl-ClYUe1xFnvcKQKG4RuOQ7N6udiviD","object":"chat.completion.chunk","created":1765450044,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":"Search"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"2btCOIXhWM"}
 
-      data: {"id":"chatcmpl-Cj5fjQoGed1aYVTFoxik5vpfMdIbm","object":"chat.completion.chunk","created":1764862599,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{"content":" '"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"Ttcy05xJfpllLS"}
+      data: {"id":"chatcmpl-ClYUe1xFnvcKQKG4RuOQ7N6udiviD","object":"chat.completion.chunk","created":1765450044,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":" for"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"BwZPah5cfikl"}
 
-      data: {"id":"chatcmpl-Cj5fjQoGed1aYVTFoxik5vpfMdIbm","object":"chat.completion.chunk","created":1764862599,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{"content":"package"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"vRH06xd1H"}
+      data: {"id":"chatcmpl-ClYUe1xFnvcKQKG4RuOQ7N6udiviD","object":"chat.completion.chunk","created":1765450044,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":" '"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"qyBZswbttoUeIY"}
 
-      data: {"id":"chatcmpl-Cj5fjQoGed1aYVTFoxik5vpfMdIbm","object":"chat.completion.chunk","created":1764862599,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{"content":"'"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"Jh0yJFeE0iHDn6z"}
+      data: {"id":"chatcmpl-ClYUe1xFnvcKQKG4RuOQ7N6udiviD","object":"chat.completion.chunk","created":1765450044,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":"package"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"dsDpObmN7"}
 
-      data: {"id":"chatcmpl-Cj5fjQoGed1aYVTFoxik5vpfMdIbm","object":"chat.completion.chunk","created":1764862599,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{"content":" in"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"4zT1g6XDQ7pe1"}
+      data: {"id":"chatcmpl-ClYUe1xFnvcKQKG4RuOQ7N6udiviD","object":"chat.completion.chunk","created":1765450044,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":"'"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"ADkAO80x66rXmxm"}
 
-      data: {"id":"chatcmpl-Cj5fjQoGed1aYVTFoxik5vpfMdIbm","object":"chat.completion.chunk","created":1764862599,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{"content":" Go"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"fPjPGIHYrqbHE"}
+      data: {"id":"chatcmpl-ClYUe1xFnvcKQKG4RuOQ7N6udiviD","object":"chat.completion.chunk","created":1765450044,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":" in"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"Dp6aKDV1Z4jnQ"}
 
-      data: {"id":"chatcmpl-Cj5fjQoGed1aYVTFoxik5vpfMdIbm","object":"chat.completion.chunk","created":1764862599,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{"content":" Files"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"bPD8Rv2RcH"}
+      data: {"id":"chatcmpl-ClYUe1xFnvcKQKG4RuOQ7N6udiviD","object":"chat.completion.chunk","created":1765450044,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":" Go"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"4UyYDdU3Cadkf"}
 
-      data: {"id":"chatcmpl-Cj5fjQoGed1aYVTFoxik5vpfMdIbm","object":"chat.completion.chunk","created":1764862599,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{"content":" Using"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"ahlv02xaHD"}
+      data: {"id":"chatcmpl-ClYUe1xFnvcKQKG4RuOQ7N6udiviD","object":"chat.completion.chunk","created":1765450044,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":" files"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"xyLaxPFI4m"}
 
-      data: {"id":"chatcmpl-Cj5fjQoGed1aYVTFoxik5vpfMdIbm","object":"chat.completion.chunk","created":1764862599,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{"content":" Gre"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"RU0L0GKOzVNK"}
+      data: {"id":"chatcmpl-ClYUe1xFnvcKQKG4RuOQ7N6udiviD","object":"chat.completion.chunk","created":1765450044,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":" using"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"dlRVu0jf49"}
 
-      data: {"id":"chatcmpl-Cj5fjQoGed1aYVTFoxik5vpfMdIbm","object":"chat.completion.chunk","created":1764862599,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{"content":"p"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"hc8V5IOCAUK9daI"}
+      data: {"id":"chatcmpl-ClYUe1xFnvcKQKG4RuOQ7N6udiviD","object":"chat.completion.chunk","created":1765450044,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":" grep"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"odbXZTumUQi"}
 
-      data: {"id":"chatcmpl-Cj5fjQoGed1aYVTFoxik5vpfMdIbm","object":"chat.completion.chunk","created":1764862599,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}],"usage":null,"obfuscation":"wzNpp97sLD"}
+      data: {"id":"chatcmpl-ClYUe1xFnvcKQKG4RuOQ7N6udiviD","object":"chat.completion.chunk","created":1765450044,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}],"usage":null,"obfuscation":"sLpASQkyNb"}
 
-      data: {"id":"chatcmpl-Cj5fjQoGed1aYVTFoxik5vpfMdIbm","object":"chat.completion.chunk","created":1764862599,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[],"usage":{"prompt_tokens":138,"completion_tokens":10,"total_tokens":148,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":0,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}},"obfuscation":"nhNL7XgGE181P"}
+      data: {"id":"chatcmpl-ClYUe1xFnvcKQKG4RuOQ7N6udiviD","object":"chat.completion.chunk","created":1765450044,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[],"usage":{"prompt_tokens":138,"completion_tokens":10,"total_tokens":148,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":0,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}},"obfuscation":"Tdzb4OOwUXRLi"}
 
       data: [DONE]
 
@@ -57,15 +57,15 @@ interactions:
       - text/event-stream; charset=utf-8
     status: 200 OK
     code: 200
-    duration: 408.414666ms
+    duration: 518.165708ms
 - id: 1
   request:
     proto: HTTP/1.1
     proto_major: 1
     proto_minor: 1
-    content_length: 49808
+    content_length: 50199
     host: ""

internal/agent/testdata/TestCoderAgent/openai-gpt-5/ls_tool.yaml πŸ”—

@@ -24,27 +24,25 @@ interactions:
     proto_minor: 0
     content_length: -1
     body: |+
-      data: {"id":"chatcmpl-Cj5ftyxnkhTHRzQVfq8q6NEKHMlCW","object":"chat.completion.chunk","created":1764862609,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"lEKGFixtSTwuuG"}
+      data: {"id":"chatcmpl-ClYUlAU7xGXiwlwnygOdjHO2xgdO6","object":"chat.completion.chunk","created":1765450051,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"UMEDmK4bRTEHog"}
 
-      data: {"id":"chatcmpl-Cj5ftyxnkhTHRzQVfq8q6NEKHMlCW","object":"chat.completion.chunk","created":1764862609,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{"content":"Listing"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"U7TXSpJAq"}
+      data: {"id":"chatcmpl-ClYUlAU7xGXiwlwnygOdjHO2xgdO6","object":"chat.completion.chunk","created":1765450051,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":"List"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"wU2AW7M98xeA"}
 
-      data: {"id":"chatcmpl-Cj5ftyxnkhTHRzQVfq8q6NEKHMlCW","object":"chat.completion.chunk","created":1764862609,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{"content":" Files"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"HEdHaFRV8T"}
+      data: {"id":"chatcmpl-ClYUlAU7xGXiwlwnygOdjHO2xgdO6","object":"chat.completion.chunk","created":1765450051,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":" Files"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"caiI3nEYPC"}
 
-      data: {"id":"chatcmpl-Cj5ftyxnkhTHRzQVfq8q6NEKHMlCW","object":"chat.completion.chunk","created":1764862609,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{"content":" in"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"wB2d2XVHLBZ8d"}
+      data: {"id":"chatcmpl-ClYUlAU7xGXiwlwnygOdjHO2xgdO6","object":"chat.completion.chunk","created":1765450051,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":" Using"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"LcoGEjOXBA"}
 
-      data: {"id":"chatcmpl-Cj5ftyxnkhTHRzQVfq8q6NEKHMlCW","object":"chat.completion.chunk","created":1764862609,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{"content":" Current"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"kgBP77mh"}
+      data: {"id":"chatcmpl-ClYUlAU7xGXiwlwnygOdjHO2xgdO6","object":"chat.completion.chunk","created":1765450051,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":" '"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"olW4ETtXnechmp"}
 
-      data: {"id":"chatcmpl-Cj5ftyxnkhTHRzQVfq8q6NEKHMlCW","object":"chat.completion.chunk","created":1764862609,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{"content":" Directory"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"ctvCBZ"}
+      data: {"id":"chatcmpl-ClYUlAU7xGXiwlwnygOdjHO2xgdO6","object":"chat.completion.chunk","created":1765450051,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":"ls"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"YY41B40ymUy5c5"}
 
-      data: {"id":"chatcmpl-Cj5ftyxnkhTHRzQVfq8q6NEKHMlCW","object":"chat.completion.chunk","created":1764862609,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{"content":" with"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"LPbD93HC4Z5"}
+      data: {"id":"chatcmpl-ClYUlAU7xGXiwlwnygOdjHO2xgdO6","object":"chat.completion.chunk","created":1765450051,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":"'"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"I2np6t9M3AUO0SA"}
 
-      data: {"id":"chatcmpl-Cj5ftyxnkhTHRzQVfq8q6NEKHMlCW","object":"chat.completion.chunk","created":1764862609,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{"content":" ls"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"GiQ4t6YIy0wqe"}
+      data: {"id":"chatcmpl-ClYUlAU7xGXiwlwnygOdjHO2xgdO6","object":"chat.completion.chunk","created":1765450051,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":" Command"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"RxCH1Yjt"}
 
-      data: {"id":"chatcmpl-Cj5ftyxnkhTHRzQVfq8q6NEKHMlCW","object":"chat.completion.chunk","created":1764862609,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{"content":" Command"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"oYjzzK1l"}
+      data: {"id":"chatcmpl-ClYUlAU7xGXiwlwnygOdjHO2xgdO6","object":"chat.completion.chunk","created":1765450051,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}],"usage":null,"obfuscation":"zaOmpwBTYJ"}
 
-      data: {"id":"chatcmpl-Cj5ftyxnkhTHRzQVfq8q6NEKHMlCW","object":"chat.completion.chunk","created":1764862609,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}],"usage":null,"obfuscation":"zL9G9EwrVA"}
-
-      data: {"id":"chatcmpl-Cj5ftyxnkhTHRzQVfq8q6NEKHMlCW","object":"chat.completion.chunk","created":1764862609,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[],"usage":{"prompt_tokens":135,"completion_tokens":8,"total_tokens":143,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":0,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}},"obfuscation":"GTDj004Sv1eK0N"}
+      data: {"id":"chatcmpl-ClYUlAU7xGXiwlwnygOdjHO2xgdO6","object":"chat.completion.chunk","created":1765450051,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[],"usage":{"prompt_tokens":135,"completion_tokens":7,"total_tokens":142,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":0,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}},"obfuscation":"pORiHZ6J2hI91j"}
 
       data: [DONE]
 
@@ -53,15 +51,15 @@ interactions:
       - text/event-stream; charset=utf-8
     status: 200 OK
     code: 200
-    duration: 498.928208ms
+    duration: 599.728125ms
 - id: 1
   request:
     proto: HTTP/1.1
     proto_major: 1
     proto_minor: 1
-    content_length: 49802
+    content_length: 50193
     host: ""

internal/agent/testdata/TestCoderAgent/openai-gpt-5/multiedit_tool.yaml πŸ”—

@@ -24,35 +24,41 @@ interactions:
     proto_minor: 0
     content_length: -1
     body: |+
-      data: {"id":"chatcmpl-Cj5fx91z1nrjlhcuicM6Ph5V4MBTJ","object":"chat.completion.chunk","created":1764862613,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"stHG3s14QOPZyF"}
+      data: {"id":"chatcmpl-ClYUpspfYf2HGT5ZUcnlU3k3uhnSu","object":"chat.completion.chunk","created":1765450055,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"iortuQUqIPUoEk"}
 
-      data: {"id":"chatcmpl-Cj5fx91z1nrjlhcuicM6Ph5V4MBTJ","object":"chat.completion.chunk","created":1764862613,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{"content":"Edit"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"WyjZMY1Jzm4x"}
+      data: {"id":"chatcmpl-ClYUpspfYf2HGT5ZUcnlU3k3uhnSu","object":"chat.completion.chunk","created":1765450055,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":"Editing"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"fI3ZmnsiJ"}
 
-      data: {"id":"chatcmpl-Cj5fx91z1nrjlhcuicM6Ph5V4MBTJ","object":"chat.completion.chunk","created":1764862613,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{"content":" '"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"hymoWg3tUTYt3K"}
+      data: {"id":"chatcmpl-ClYUpspfYf2HGT5ZUcnlU3k3uhnSu","object":"chat.completion.chunk","created":1765450055,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":" '"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"ID4EbExPHpfF1A"}
 
-      data: {"id":"chatcmpl-Cj5fx91z1nrjlhcuicM6Ph5V4MBTJ","object":"chat.completion.chunk","created":1764862613,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{"content":"Hello"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"R6igk6ddb9R"}
+      data: {"id":"chatcmpl-ClYUpspfYf2HGT5ZUcnlU3k3uhnSu","object":"chat.completion.chunk","created":1765450055,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":"Hello"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"1LU3dm8Zp8x"}
 
-      data: {"id":"chatcmpl-Cj5fx91z1nrjlhcuicM6Ph5V4MBTJ","object":"chat.completion.chunk","created":1764862613,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{"content":","},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"vC7FXjUh0jVQkmo"}
+      data: {"id":"chatcmpl-ClYUpspfYf2HGT5ZUcnlU3k3uhnSu","object":"chat.completion.chunk","created":1765450055,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":","},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"B5PW7DIW7rSFGwV"}
 
-      data: {"id":"chatcmpl-Cj5fx91z1nrjlhcuicM6Ph5V4MBTJ","object":"chat.completion.chunk","created":1764862613,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{"content":" World"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"cVhwrNCKc2"}
+      data: {"id":"chatcmpl-ClYUpspfYf2HGT5ZUcnlU3k3uhnSu","object":"chat.completion.chunk","created":1765450055,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":" World"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"mUjyCOBM3T"}
 
-      data: {"id":"chatcmpl-Cj5fx91z1nrjlhcuicM6Ph5V4MBTJ","object":"chat.completion.chunk","created":1764862613,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{"content":"!'"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"y3eaGoswn1iBsD"}
+      data: {"id":"chatcmpl-ClYUpspfYf2HGT5ZUcnlU3k3uhnSu","object":"chat.completion.chunk","created":1765450055,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":"!'"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"mcUf35wIefGwCd"}
 
-      data: {"id":"chatcmpl-Cj5fx91z1nrjlhcuicM6Ph5V4MBTJ","object":"chat.completion.chunk","created":1764862613,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{"content":" and"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"7ZI8z3f8WENF"}
+      data: {"id":"chatcmpl-ClYUpspfYf2HGT5ZUcnlU3k3uhnSu","object":"chat.completion.chunk","created":1765450055,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":" to"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"Ks0QkMtefblaP"}
 
-      data: {"id":"chatcmpl-Cj5fx91z1nrjlhcuicM6Ph5V4MBTJ","object":"chat.completion.chunk","created":1764862613,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{"content":" add"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"8wJflzWkNePf"}
+      data: {"id":"chatcmpl-ClYUpspfYf2HGT5ZUcnlU3k3uhnSu","object":"chat.completion.chunk","created":1765450055,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":" '"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"MAPEiKXCsBi2Is"}
 
-      data: {"id":"chatcmpl-Cj5fx91z1nrjlhcuicM6Ph5V4MBTJ","object":"chat.completion.chunk","created":1764862613,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{"content":" comment"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"xcpAeA0m"}
+      data: {"id":"chatcmpl-ClYUpspfYf2HGT5ZUcnlU3k3uhnSu","object":"chat.completion.chunk","created":1765450055,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":"Hello"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"Vr3FLHbug8i"}
 
-      data: {"id":"chatcmpl-Cj5fx91z1nrjlhcuicM6Ph5V4MBTJ","object":"chat.completion.chunk","created":1764862613,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{"content":" in"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"z6KNcAWuEVhXE"}
+      data: {"id":"chatcmpl-ClYUpspfYf2HGT5ZUcnlU3k3uhnSu","object":"chat.completion.chunk","created":1765450055,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":","},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"cZSoyKBYFddeRAh"}
 
-      data: {"id":"chatcmpl-Cj5fx91z1nrjlhcuicM6Ph5V4MBTJ","object":"chat.completion.chunk","created":1764862613,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{"content":" main"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"Y6NKOFkNUfg"}
+      data: {"id":"chatcmpl-ClYUpspfYf2HGT5ZUcnlU3k3uhnSu","object":"chat.completion.chunk","created":1765450055,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":" Crush"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"EICPMZXFtU"}
 
-      data: {"id":"chatcmpl-Cj5fx91z1nrjlhcuicM6Ph5V4MBTJ","object":"chat.completion.chunk","created":1764862613,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{"content":".go"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"hqzfd1Su6rtfk"}
+      data: {"id":"chatcmpl-ClYUpspfYf2HGT5ZUcnlU3k3uhnSu","object":"chat.completion.chunk","created":1765450055,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":"!'"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"g0XbhchmFYu4Bq"}
 
-      data: {"id":"chatcmpl-Cj5fx91z1nrjlhcuicM6Ph5V4MBTJ","object":"chat.completion.chunk","created":1764862613,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}],"usage":null,"obfuscation":"WT4QSyUBLY"}
+      data: {"id":"chatcmpl-ClYUpspfYf2HGT5ZUcnlU3k3uhnSu","object":"chat.completion.chunk","created":1765450055,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":" in"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"nTuUNUj4KNN7H"}
 
-      data: {"id":"chatcmpl-Cj5fx91z1nrjlhcuicM6Ph5V4MBTJ","object":"chat.completion.chunk","created":1764862613,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[],"usage":{"prompt_tokens":157,"completion_tokens":12,"total_tokens":169,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":0,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}},"obfuscation":"jcSvCeTOgOxD1"}
+      data: {"id":"chatcmpl-ClYUpspfYf2HGT5ZUcnlU3k3uhnSu","object":"chat.completion.chunk","created":1765450055,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":" main"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"ZXpEc8NVrI6"}
+
+      data: {"id":"chatcmpl-ClYUpspfYf2HGT5ZUcnlU3k3uhnSu","object":"chat.completion.chunk","created":1765450055,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":".go"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"ka0oJF0AxZj94"}
+
+      data: {"id":"chatcmpl-ClYUpspfYf2HGT5ZUcnlU3k3uhnSu","object":"chat.completion.chunk","created":1765450055,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}],"usage":null,"obfuscation":"RchQvTbfGH"}
+
+      data: {"id":"chatcmpl-ClYUpspfYf2HGT5ZUcnlU3k3uhnSu","object":"chat.completion.chunk","created":1765450055,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[],"usage":{"prompt_tokens":157,"completion_tokens":15,"total_tokens":172,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":0,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}},"obfuscation":"AJG47qP3jlKeV"}
 
       data: [DONE]
 
@@ -61,15 +67,15 @@ interactions:
       - text/event-stream; charset=utf-8
     status: 200 OK
     code: 200
-    duration: 521.312875ms
+    duration: 499.534ms
 - id: 1
   request:
     proto: HTTP/1.1
     proto_major: 1
     proto_minor: 1
-    content_length: 49888
+    content_length: 50279
     host: ""

internal/agent/testdata/TestCoderAgent/openai-gpt-5/parallel_tool_calls.yaml πŸ”—

@@ -24,23 +24,27 @@ interactions:
     proto_minor: 0
     content_length: -1
     body: |+
-      data: {"id":"chatcmpl-Cj5hNB5pAgYdbghi0IUIxPImpYV6e","object":"chat.completion.chunk","created":1764862701,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"GvtGgFLGU0ASGT"}
+      data: {"id":"chatcmpl-ClYVxXKuDow1gLUqqlvhn6DL3K5CC","object":"chat.completion.chunk","created":1765450125,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"yzhS59uRUu511k"}
 
-      data: {"id":"chatcmpl-Cj5hNB5pAgYdbghi0IUIxPImpYV6e","object":"chat.completion.chunk","created":1764862701,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{"content":"Parallel"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"KPzNB1a1"}
+      data: {"id":"chatcmpl-ClYVxXKuDow1gLUqqlvhn6DL3K5CC","object":"chat.completion.chunk","created":1765450125,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":"Parallel"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"g3jeuGmp"}
 
-      data: {"id":"chatcmpl-Cj5hNB5pAgYdbghi0IUIxPImpYV6e","object":"chat.completion.chunk","created":1764862701,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{"content":" Directory"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"AhPPIi"}
+      data: {"id":"chatcmpl-ClYVxXKuDow1gLUqqlvhn6DL3K5CC","object":"chat.completion.chunk","created":1765450125,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":" ."},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"zPlid6EaNGItod"}
 
-      data: {"id":"chatcmpl-Cj5hNB5pAgYdbghi0IUIxPImpYV6e","object":"chat.completion.chunk","created":1764862701,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{"content":" Listing"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"65i7X3Dd"}
+      data: {"id":"chatcmpl-ClYVxXKuDow1gLUqqlvhn6DL3K5CC","object":"chat.completion.chunk","created":1765450125,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":"go"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"XxLnCUgnqeu8Hd"}
 
-      data: {"id":"chatcmpl-Cj5hNB5pAgYdbghi0IUIxPImpYV6e","object":"chat.completion.chunk","created":1764862701,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{"content":" and"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"iyTL40AOfZ6o"}
+      data: {"id":"chatcmpl-ClYVxXKuDow1gLUqqlvhn6DL3K5CC","object":"chat.completion.chunk","created":1765450125,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":" File"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"ktg1VgFlUwJ"}
 
-      data: {"id":"chatcmpl-Cj5hNB5pAgYdbghi0IUIxPImpYV6e","object":"chat.completion.chunk","created":1764862701,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{"content":" File"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"j483wg4pRxa"}
+      data: {"id":"chatcmpl-ClYVxXKuDow1gLUqqlvhn6DL3K5CC","object":"chat.completion.chunk","created":1765450125,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":" Search"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"yx3P32Awb"}
 
-      data: {"id":"chatcmpl-Cj5hNB5pAgYdbghi0IUIxPImpYV6e","object":"chat.completion.chunk","created":1764862701,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{"content":" Search"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"vaZDxrmKG"}
+      data: {"id":"chatcmpl-ClYVxXKuDow1gLUqqlvhn6DL3K5CC","object":"chat.completion.chunk","created":1765450125,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":" and"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"GmBe64s4mBbQ"}
 
-      data: {"id":"chatcmpl-Cj5hNB5pAgYdbghi0IUIxPImpYV6e","object":"chat.completion.chunk","created":1764862701,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}],"usage":null,"obfuscation":"r4w1NEK1O3"}
+      data: {"id":"chatcmpl-ClYVxXKuDow1gLUqqlvhn6DL3K5CC","object":"chat.completion.chunk","created":1765450125,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":" Directory"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"eUHrBf"}
 
-      data: {"id":"chatcmpl-Cj5hNB5pAgYdbghi0IUIxPImpYV6e","object":"chat.completion.chunk","created":1764862701,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[],"usage":{"prompt_tokens":154,"completion_tokens":6,"total_tokens":160,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":0,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}},"obfuscation":"2PF6LiI3ZI091A"}
+      data: {"id":"chatcmpl-ClYVxXKuDow1gLUqqlvhn6DL3K5CC","object":"chat.completion.chunk","created":1765450125,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":" Listing"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"CkE7ZUS2"}
+
+      data: {"id":"chatcmpl-ClYVxXKuDow1gLUqqlvhn6DL3K5CC","object":"chat.completion.chunk","created":1765450125,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}],"usage":null,"obfuscation":"UOzkyErMbp"}
+
+      data: {"id":"chatcmpl-ClYVxXKuDow1gLUqqlvhn6DL3K5CC","object":"chat.completion.chunk","created":1765450125,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[],"usage":{"prompt_tokens":154,"completion_tokens":8,"total_tokens":162,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":0,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}},"obfuscation":"IbYbUzxWouLTaX"}
 
       data: [DONE]
 
@@ -49,15 +53,15 @@ interactions:
       - text/event-stream; charset=utf-8
     status: 200 OK
     code: 200
-    duration: 390.648875ms
+    duration: 433.644542ms
 - id: 1
   request:
     proto: HTTP/1.1
     proto_major: 1
     proto_minor: 1
-    content_length: 49899
+    content_length: 50290
     host: ""

internal/agent/testdata/TestCoderAgent/openai-gpt-5/read_a_file.yaml πŸ”—

@@ -24,21 +24,21 @@ interactions:
     proto_minor: 0
     content_length: -1
     body: |+
-      data: {"id":"chatcmpl-Cj5eaZEZPIOCqPFdID2cw2jmvGNIZ","object":"chat.completion.chunk","created":1764862528,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_e819e3438b","choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"OTC1pfO77Jn3Ss"}
+      data: {"id":"chatcmpl-ClYTQhlPOe5tl5pF1iOgF0DBvE8Yz","object":"chat.completion.chunk","created":1765449968,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_83554c687e","choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"Td83oWSapyD29H"}
 
-      data: {"id":"chatcmpl-Cj5eaZEZPIOCqPFdID2cw2jmvGNIZ","object":"chat.completion.chunk","created":1764862528,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_e819e3438b","choices":[{"index":0,"delta":{"content":"Understanding"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"dw0"}
+      data: {"id":"chatcmpl-ClYTQhlPOe5tl5pF1iOgF0DBvE8Yz","object":"chat.completion.chunk","created":1765449968,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_83554c687e","choices":[{"index":0,"delta":{"content":"Understanding"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"Bh7"}
 
-      data: {"id":"chatcmpl-Cj5eaZEZPIOCqPFdID2cw2jmvGNIZ","object":"chat.completion.chunk","created":1764862528,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_e819e3438b","choices":[{"index":0,"delta":{"content":" the"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"F7n40gg64Uwt"}
+      data: {"id":"chatcmpl-ClYTQhlPOe5tl5pF1iOgF0DBvE8Yz","object":"chat.completion.chunk","created":1765449968,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_83554c687e","choices":[{"index":0,"delta":{"content":" the"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"jRFD2MUbYjEi"}
 
-      data: {"id":"chatcmpl-Cj5eaZEZPIOCqPFdID2cw2jmvGNIZ","object":"chat.completion.chunk","created":1764862528,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_e819e3438b","choices":[{"index":0,"delta":{"content":" Go"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"1iXyRtYoW97wa"}
+      data: {"id":"chatcmpl-ClYTQhlPOe5tl5pF1iOgF0DBvE8Yz","object":"chat.completion.chunk","created":1765449968,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_83554c687e","choices":[{"index":0,"delta":{"content":" Go"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"SlRY6qmk8zOaT"}
 
-      data: {"id":"chatcmpl-Cj5eaZEZPIOCqPFdID2cw2jmvGNIZ","object":"chat.completion.chunk","created":1764862528,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_e819e3438b","choices":[{"index":0,"delta":{"content":" Module"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"CQD5wfY5u"}
+      data: {"id":"chatcmpl-ClYTQhlPOe5tl5pF1iOgF0DBvE8Yz","object":"chat.completion.chunk","created":1765449968,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_83554c687e","choices":[{"index":0,"delta":{"content":" Mod"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"kgvSLP9N0drN"}
 
-      data: {"id":"chatcmpl-Cj5eaZEZPIOCqPFdID2cw2jmvGNIZ","object":"chat.completion.chunk","created":1764862528,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_e819e3438b","choices":[{"index":0,"delta":{"content":" File"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"9nCdlqcheyD"}
+      data: {"id":"chatcmpl-ClYTQhlPOe5tl5pF1iOgF0DBvE8Yz","object":"chat.completion.chunk","created":1765449968,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_83554c687e","choices":[{"index":0,"delta":{"content":" File"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"PimRARifiZA"}
 
-      data: {"id":"chatcmpl-Cj5eaZEZPIOCqPFdID2cw2jmvGNIZ","object":"chat.completion.chunk","created":1764862528,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_e819e3438b","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}],"usage":null,"obfuscation":"HG7EcPA8KN"}
+      data: {"id":"chatcmpl-ClYTQhlPOe5tl5pF1iOgF0DBvE8Yz","object":"chat.completion.chunk","created":1765449968,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_83554c687e","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}],"usage":null,"obfuscation":"HPqTpsItZS"}
 
-      data: {"id":"chatcmpl-Cj5eaZEZPIOCqPFdID2cw2jmvGNIZ","object":"chat.completion.chunk","created":1764862528,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_e819e3438b","choices":[],"usage":{"prompt_tokens":129,"completion_tokens":5,"total_tokens":134,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":0,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}},"obfuscation":"MKsb97i60ViJDJ"}
+      data: {"id":"chatcmpl-ClYTQhlPOe5tl5pF1iOgF0DBvE8Yz","object":"chat.completion.chunk","created":1765449968,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_83554c687e","choices":[],"usage":{"prompt_tokens":129,"completion_tokens":5,"total_tokens":134,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":0,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}},"obfuscation":"V4VlPjVdvDAOva"}
 
       data: [DONE]
 
@@ -47,15 +47,15 @@ interactions:
       - text/event-stream; charset=utf-8
     status: 200 OK
     code: 200
-    duration: 435.350917ms
+    duration: 918.348ms
 - id: 1
   request:
     proto: HTTP/1.1
     proto_major: 1
     proto_minor: 1
-    content_length: 49772
+    content_length: 50163
     host: ""

internal/agent/testdata/TestCoderAgent/openai-gpt-5/simple_test.yaml πŸ”—

@@ -24,13 +24,15 @@ interactions:
     proto_minor: 0
     content_length: -1
     body: |+
-      data: {"id":"chatcmpl-Cj5eXgQs52an8VdAppy67IGNbaNFe","object":"chat.completion.chunk","created":1764862525,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"x7WEcf7ig2ihCK"}
+      data: {"id":"chatcmpl-ClYTNmeHbTg5nOfFSj9b0PfSqnXmI","object":"chat.completion.chunk","created":1765449965,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"lYuAhHNOZyFT78"}
 
-      data: {"id":"chatcmpl-Cj5eXgQs52an8VdAppy67IGNbaNFe","object":"chat.completion.chunk","created":1764862525,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":"Greetings"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"33s5BnX"}
+      data: {"id":"chatcmpl-ClYTNmeHbTg5nOfFSj9b0PfSqnXmI","object":"chat.completion.chunk","created":1765449965,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":"User"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"tEQ3xb2jGS3z"}
 
-      data: {"id":"chatcmpl-Cj5eXgQs52an8VdAppy67IGNbaNFe","object":"chat.completion.chunk","created":1764862525,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}],"usage":null,"obfuscation":"bh8BPlqlKb"}
+      data: {"id":"chatcmpl-ClYTNmeHbTg5nOfFSj9b0PfSqnXmI","object":"chat.completion.chunk","created":1765449965,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":" Greeting"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"uf5pfnS"}
 
-      data: {"id":"chatcmpl-Cj5eXgQs52an8VdAppy67IGNbaNFe","object":"chat.completion.chunk","created":1764862525,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[],"usage":{"prompt_tokens":126,"completion_tokens":1,"total_tokens":127,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":0,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}},"obfuscation":"oXIOkbDShWE4Pf"}
+      data: {"id":"chatcmpl-ClYTNmeHbTg5nOfFSj9b0PfSqnXmI","object":"chat.completion.chunk","created":1765449965,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}],"usage":null,"obfuscation":"BnHYDD4Snx"}
+
+      data: {"id":"chatcmpl-ClYTNmeHbTg5nOfFSj9b0PfSqnXmI","object":"chat.completion.chunk","created":1765449965,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[],"usage":{"prompt_tokens":126,"completion_tokens":2,"total_tokens":128,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":0,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}},"obfuscation":"kk9wG4HXzAC8D5"}
 
       data: [DONE]
 
@@ -39,15 +41,15 @@ interactions:
       - text/event-stream; charset=utf-8
     status: 200 OK
     code: 200
-    duration: 1.042759084s
+    duration: 1.16988225s
 - id: 1
   request:
     proto: HTTP/1.1
     proto_major: 1
     proto_minor: 1
-    content_length: 49762
+    content_length: 50153
     host: ""

internal/agent/testdata/TestCoderAgent/openai-gpt-5/sourcegraph_tool.yaml πŸ”—

@@ -24,31 +24,37 @@ interactions:
     proto_minor: 0
     content_length: -1
     body: |+
-      data: {"id":"chatcmpl-Cj5gX0lZaJWKiDMzPW8HDrD3cqbwi","object":"chat.completion.chunk","created":1764862649,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"V7aJpOpFhV5inr"}
+      data: {"id":"chatcmpl-ClYVFpJvAWVs1HZmbLJSHevY7MPdx","object":"chat.completion.chunk","created":1765450081,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"6Uwk6E5ZLxoCKu"}
 
-      data: {"id":"chatcmpl-Cj5gX0lZaJWKiDMzPW8HDrD3cqbwi","object":"chat.completion.chunk","created":1764862649,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{"content":"Searching"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"7F8z7KK"}
+      data: {"id":"chatcmpl-ClYVFpJvAWVs1HZmbLJSHevY7MPdx","object":"chat.completion.chunk","created":1765450081,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":"Using"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"jmlPS4eKNlU"}
 
-      data: {"id":"chatcmpl-Cj5gX0lZaJWKiDMzPW8HDrD3cqbwi","object":"chat.completion.chunk","created":1764862649,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{"content":" for"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"eXjQSVgHlEBT"}
+      data: {"id":"chatcmpl-ClYVFpJvAWVs1HZmbLJSHevY7MPdx","object":"chat.completion.chunk","created":1765450081,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":" Source"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"suyvSEUrA"}
 
-      data: {"id":"chatcmpl-Cj5gX0lZaJWKiDMzPW8HDrD3cqbwi","object":"chat.completion.chunk","created":1764862649,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{"content":" '"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"jjWtwgDDjEInPX"}
+      data: {"id":"chatcmpl-ClYVFpJvAWVs1HZmbLJSHevY7MPdx","object":"chat.completion.chunk","created":1765450081,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":"graph"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"ZnkXVLS9pd9"}
 
-      data: {"id":"chatcmpl-Cj5gX0lZaJWKiDMzPW8HDrD3cqbwi","object":"chat.completion.chunk","created":1764862649,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{"content":"func"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"DqNtU8f04iBw"}
+      data: {"id":"chatcmpl-ClYVFpJvAWVs1HZmbLJSHevY7MPdx","object":"chat.completion.chunk","created":1765450081,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":" to"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"6DDfkjVk33j2S"}
 
-      data: {"id":"chatcmpl-Cj5gX0lZaJWKiDMzPW8HDrD3cqbwi","object":"chat.completion.chunk","created":1764862649,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{"content":" main"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"j5LaEOy2UB5"}
+      data: {"id":"chatcmpl-ClYVFpJvAWVs1HZmbLJSHevY7MPdx","object":"chat.completion.chunk","created":1765450081,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":" Find"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"wh6ozpJ0ICP"}
 
-      data: {"id":"chatcmpl-Cj5gX0lZaJWKiDMzPW8HDrD3cqbwi","object":"chat.completion.chunk","created":1764862649,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{"content":"'"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"RtYwad29rl58mmW"}
+      data: {"id":"chatcmpl-ClYVFpJvAWVs1HZmbLJSHevY7MPdx","object":"chat.completion.chunk","created":1765450081,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":" '"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"ZGNvhFcisiNv5j"}
 
-      data: {"id":"chatcmpl-Cj5gX0lZaJWKiDMzPW8HDrD3cqbwi","object":"chat.completion.chunk","created":1764862649,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{"content":" in"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"7odiYfZEyK3eo"}
+      data: {"id":"chatcmpl-ClYVFpJvAWVs1HZmbLJSHevY7MPdx","object":"chat.completion.chunk","created":1765450081,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":"func"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"kPFZUGkdYwtc"}
 
-      data: {"id":"chatcmpl-Cj5gX0lZaJWKiDMzPW8HDrD3cqbwi","object":"chat.completion.chunk","created":1764862649,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{"content":" Go"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"PQyYbpPXubI94"}
+      data: {"id":"chatcmpl-ClYVFpJvAWVs1HZmbLJSHevY7MPdx","object":"chat.completion.chunk","created":1765450081,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":" main"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"O6L966yuVgp"}
 
-      data: {"id":"chatcmpl-Cj5gX0lZaJWKiDMzPW8HDrD3cqbwi","object":"chat.completion.chunk","created":1764862649,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{"content":" Re"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"tPfbGjPO0BHQs"}
+      data: {"id":"chatcmpl-ClYVFpJvAWVs1HZmbLJSHevY7MPdx","object":"chat.completion.chunk","created":1765450081,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":"'"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"XcGGFGl7Nf7RuUM"}
 
-      data: {"id":"chatcmpl-Cj5gX0lZaJWKiDMzPW8HDrD3cqbwi","object":"chat.completion.chunk","created":1764862649,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{"content":"positories"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"QIqgGC"}
+      data: {"id":"chatcmpl-ClYVFpJvAWVs1HZmbLJSHevY7MPdx","object":"chat.completion.chunk","created":1765450081,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":" in"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"2ecov1rE9ImKb"}
 
-      data: {"id":"chatcmpl-Cj5gX0lZaJWKiDMzPW8HDrD3cqbwi","object":"chat.completion.chunk","created":1764862649,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}],"usage":null,"obfuscation":"Af8WMnrBiS"}
+      data: {"id":"chatcmpl-ClYVFpJvAWVs1HZmbLJSHevY7MPdx","object":"chat.completion.chunk","created":1765450081,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":" Go"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"GaBkfJFK8gAxN"}
 
-      data: {"id":"chatcmpl-Cj5gX0lZaJWKiDMzPW8HDrD3cqbwi","object":"chat.completion.chunk","created":1764862649,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[],"usage":{"prompt_tokens":138,"completion_tokens":10,"total_tokens":148,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":0,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}},"obfuscation":"Ev2kzGJz9hjEP"}
+      data: {"id":"chatcmpl-ClYVFpJvAWVs1HZmbLJSHevY7MPdx","object":"chat.completion.chunk","created":1765450081,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":" Re"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"sHG1C6ny6Us9z"}
+
+      data: {"id":"chatcmpl-ClYVFpJvAWVs1HZmbLJSHevY7MPdx","object":"chat.completion.chunk","created":1765450081,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":"pos"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"NSChIK7VgkOQW"}
+
+      data: {"id":"chatcmpl-ClYVFpJvAWVs1HZmbLJSHevY7MPdx","object":"chat.completion.chunk","created":1765450081,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}],"usage":null,"obfuscation":"RmvItLJGPu"}
+
+      data: {"id":"chatcmpl-ClYVFpJvAWVs1HZmbLJSHevY7MPdx","object":"chat.completion.chunk","created":1765450081,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[],"usage":{"prompt_tokens":138,"completion_tokens":13,"total_tokens":151,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":0,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}},"obfuscation":"fdcSwuBLeER6h"}
 
       data: [DONE]
 
@@ -57,15 +63,15 @@ interactions:
       - text/event-stream; charset=utf-8
     status: 200 OK
     code: 200
-    duration: 392.941917ms
+    duration: 510.380208ms
 - id: 1
   request:
     proto: HTTP/1.1
     proto_major: 1
     proto_minor: 1
-    content_length: 49822
+    content_length: 50213
     host: ""

internal/agent/testdata/TestCoderAgent/openai-gpt-5/update_a_file.yaml πŸ”—

@@ -24,31 +24,31 @@ interactions:
     proto_minor: 0
     content_length: -1
     body: |+
-      data: {"id":"chatcmpl-Cj5eivmJnQDYTszC8cSfkpcxC2bPg","object":"chat.completion.chunk","created":1764862536,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"O0oCW5XBCjcl1g"}
+      data: {"id":"chatcmpl-ClYcUERaSodA5TcaAZi62itGcATzy","object":"chat.completion.chunk","created":1765450530,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_37d212baff","choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"suhxmaLssng9GN"}
 
-      data: {"id":"chatcmpl-Cj5eivmJnQDYTszC8cSfkpcxC2bPg","object":"chat.completion.chunk","created":1764862536,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":"Update"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"jdQzCLveMQ"}
+      data: {"id":"chatcmpl-ClYcUERaSodA5TcaAZi62itGcATzy","object":"chat.completion.chunk","created":1765450530,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_37d212baff","choices":[{"index":0,"delta":{"content":"Update"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"uq1N9j9GYt"}
 
-      data: {"id":"chatcmpl-Cj5eivmJnQDYTszC8cSfkpcxC2bPg","object":"chat.completion.chunk","created":1764862536,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":" main"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"x2BGf6Nj6nD"}
+      data: {"id":"chatcmpl-ClYcUERaSodA5TcaAZi62itGcATzy","object":"chat.completion.chunk","created":1765450530,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_37d212baff","choices":[{"index":0,"delta":{"content":" main"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"2yJ1XcXP92O"}
 
-      data: {"id":"chatcmpl-Cj5eivmJnQDYTszC8cSfkpcxC2bPg","object":"chat.completion.chunk","created":1764862536,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":".go"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"tISqXnPiclzEf"}
+      data: {"id":"chatcmpl-ClYcUERaSodA5TcaAZi62itGcATzy","object":"chat.completion.chunk","created":1765450530,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_37d212baff","choices":[{"index":0,"delta":{"content":".go"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"o502A8HAiLze4"}
 
-      data: {"id":"chatcmpl-Cj5eivmJnQDYTszC8cSfkpcxC2bPg","object":"chat.completion.chunk","created":1764862536,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":" to"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"MuitD5R1C0kB2"}
+      data: {"id":"chatcmpl-ClYcUERaSodA5TcaAZi62itGcATzy","object":"chat.completion.chunk","created":1765450530,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_37d212baff","choices":[{"index":0,"delta":{"content":" to"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"vLmVOOtBoeAm7"}
 
-      data: {"id":"chatcmpl-Cj5eivmJnQDYTszC8cSfkpcxC2bPg","object":"chat.completion.chunk","created":1764862536,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":" Print"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"WHZ6xue434"}
+      data: {"id":"chatcmpl-ClYcUERaSodA5TcaAZi62itGcATzy","object":"chat.completion.chunk","created":1765450530,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_37d212baff","choices":[{"index":0,"delta":{"content":" Print"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"qd8Oqo9S3r"}
 
-      data: {"id":"chatcmpl-Cj5eivmJnQDYTszC8cSfkpcxC2bPg","object":"chat.completion.chunk","created":1764862536,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":" '"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"Ir1EfbhKQALo1H"}
+      data: {"id":"chatcmpl-ClYcUERaSodA5TcaAZi62itGcATzy","object":"chat.completion.chunk","created":1765450530,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_37d212baff","choices":[{"index":0,"delta":{"content":" '"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"JlFugTEXdxERyl"}
 
-      data: {"id":"chatcmpl-Cj5eivmJnQDYTszC8cSfkpcxC2bPg","object":"chat.completion.chunk","created":1764862536,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":"Hello"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"KXgSqlI9l9u"}
+      data: {"id":"chatcmpl-ClYcUERaSodA5TcaAZi62itGcATzy","object":"chat.completion.chunk","created":1765450530,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_37d212baff","choices":[{"index":0,"delta":{"content":"Hello"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"PSAR2b6MhBJ"}
 
-      data: {"id":"chatcmpl-Cj5eivmJnQDYTszC8cSfkpcxC2bPg","object":"chat.completion.chunk","created":1764862536,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":" from"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"7NUoxKXwNCe"}
+      data: {"id":"chatcmpl-ClYcUERaSodA5TcaAZi62itGcATzy","object":"chat.completion.chunk","created":1765450530,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_37d212baff","choices":[{"index":0,"delta":{"content":" from"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"K2DaU062cs5"}
 
-      data: {"id":"chatcmpl-Cj5eivmJnQDYTszC8cSfkpcxC2bPg","object":"chat.completion.chunk","created":1764862536,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":" Crush"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"N2VQq9pYby"}
+      data: {"id":"chatcmpl-ClYcUERaSodA5TcaAZi62itGcATzy","object":"chat.completion.chunk","created":1765450530,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_37d212baff","choices":[{"index":0,"delta":{"content":" Crush"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"TGAxJqR0xe"}
 
-      data: {"id":"chatcmpl-Cj5eivmJnQDYTszC8cSfkpcxC2bPg","object":"chat.completion.chunk","created":1764862536,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":"'"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"Klq1ycgRs00e1d4"}
+      data: {"id":"chatcmpl-ClYcUERaSodA5TcaAZi62itGcATzy","object":"chat.completion.chunk","created":1765450530,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_37d212baff","choices":[{"index":0,"delta":{"content":"'"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"bZ8ONMFviIS07qj"}
 
-      data: {"id":"chatcmpl-Cj5eivmJnQDYTszC8cSfkpcxC2bPg","object":"chat.completion.chunk","created":1764862536,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}],"usage":null,"obfuscation":"LS5bPX7l7c"}
+      data: {"id":"chatcmpl-ClYcUERaSodA5TcaAZi62itGcATzy","object":"chat.completion.chunk","created":1765450530,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_37d212baff","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}],"usage":null,"obfuscation":"MOpaEkBHwD"}
 
-      data: {"id":"chatcmpl-Cj5eivmJnQDYTszC8cSfkpcxC2bPg","object":"chat.completion.chunk","created":1764862536,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[],"usage":{"prompt_tokens":139,"completion_tokens":10,"total_tokens":149,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":0,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}},"obfuscation":"XI2qPQJkIY4jy"}
+      data: {"id":"chatcmpl-ClYcUERaSodA5TcaAZi62itGcATzy","object":"chat.completion.chunk","created":1765450530,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_37d212baff","choices":[],"usage":{"prompt_tokens":139,"completion_tokens":10,"total_tokens":149,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":0,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}},"obfuscation":"E0DOck4Xo8KnI"}
 
       data: [DONE]
 
@@ -57,15 +57,15 @@ interactions:
       - text/event-stream; charset=utf-8
     status: 200 OK
     code: 200
-    duration: 736.477208ms
+    duration: 592.698375ms
 - id: 1
   request:
     proto: HTTP/1.1
     proto_major: 1
     proto_minor: 1
-    content_length: 49828
+    content_length: 50219
     host: ""

internal/agent/testdata/TestCoderAgent/openai-gpt-5/write_tool.yaml πŸ”—

@@ -24,27 +24,23 @@ interactions:
     proto_minor: 0
     content_length: -1
     body: |+
-      data: {"id":"chatcmpl-Cj5h7MQblabwrCdxjqHsbvrQkJxIP","object":"chat.completion.chunk","created":1764862685,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"UrpciigLsIhRQJ"}
+      data: {"id":"chatcmpl-ClYVf4uM2U0ATW18tcIGbdzcFAqWU","object":"chat.completion.chunk","created":1765450107,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"ravSmf9KF02hrZ"}
 
-      data: {"id":"chatcmpl-Cj5h7MQblabwrCdxjqHsbvrQkJxIP","object":"chat.completion.chunk","created":1764862685,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{"content":"Create"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"VaFd5ML0hs"}
+      data: {"id":"chatcmpl-ClYVf4uM2U0ATW18tcIGbdzcFAqWU","object":"chat.completion.chunk","created":1765450107,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":"Creating"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"gDrbOt0V"}
 
-      data: {"id":"chatcmpl-Cj5h7MQblabwrCdxjqHsbvrQkJxIP","object":"chat.completion.chunk","created":1764862685,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{"content":" config"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"8ue07B4W0"}
+      data: {"id":"chatcmpl-ClYVf4uM2U0ATW18tcIGbdzcFAqWU","object":"chat.completion.chunk","created":1765450107,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":" config"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"ROCqtTpc5"}
 
-      data: {"id":"chatcmpl-Cj5h7MQblabwrCdxjqHsbvrQkJxIP","object":"chat.completion.chunk","created":1764862685,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{"content":".json"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"umBlJVLsIdu"}
+      data: {"id":"chatcmpl-ClYVf4uM2U0ATW18tcIGbdzcFAqWU","object":"chat.completion.chunk","created":1765450107,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":".json"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"pUfVbY4qhPb"}
 
-      data: {"id":"chatcmpl-Cj5h7MQblabwrCdxjqHsbvrQkJxIP","object":"chat.completion.chunk","created":1764862685,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{"content":" File"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"NmX3UiKvZUE"}
+      data: {"id":"chatcmpl-ClYVf4uM2U0ATW18tcIGbdzcFAqWU","object":"chat.completion.chunk","created":1765450107,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":" with"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"n1S6JXiKNwn"}
 
-      data: {"id":"chatcmpl-Cj5h7MQblabwrCdxjqHsbvrQkJxIP","object":"chat.completion.chunk","created":1764862685,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{"content":" with"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"JoTixPL8ppW"}
+      data: {"id":"chatcmpl-ClYVf4uM2U0ATW18tcIGbdzcFAqWU","object":"chat.completion.chunk","created":1765450107,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":" Test"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"AvqPcgoEKtb"}
 
-      data: {"id":"chatcmpl-Cj5h7MQblabwrCdxjqHsbvrQkJxIP","object":"chat.completion.chunk","created":1764862685,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{"content":" Sample"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"edJDPMmA2"}
+      data: {"id":"chatcmpl-ClYVf4uM2U0ATW18tcIGbdzcFAqWU","object":"chat.completion.chunk","created":1765450107,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{"content":" Details"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"rmCpDlnn"}
 
-      data: {"id":"chatcmpl-Cj5h7MQblabwrCdxjqHsbvrQkJxIP","object":"chat.completion.chunk","created":1764862685,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{"content":" JSON"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"Ekbs2yt8ekn"}
+      data: {"id":"chatcmpl-ClYVf4uM2U0ATW18tcIGbdzcFAqWU","object":"chat.completion.chunk","created":1765450107,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}],"usage":null,"obfuscation":"CEGO6F6IGC"}
 
-      data: {"id":"chatcmpl-Cj5h7MQblabwrCdxjqHsbvrQkJxIP","object":"chat.completion.chunk","created":1764862685,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{"content":" Content"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"eNjoh3CM"}
-
-      data: {"id":"chatcmpl-Cj5h7MQblabwrCdxjqHsbvrQkJxIP","object":"chat.completion.chunk","created":1764862685,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}],"usage":null,"obfuscation":"sMSdeiR6TM"}
-
-      data: {"id":"chatcmpl-Cj5h7MQblabwrCdxjqHsbvrQkJxIP","object":"chat.completion.chunk","created":1764862685,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_689bad8e9a","choices":[],"usage":{"prompt_tokens":153,"completion_tokens":8,"total_tokens":161,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":0,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}},"obfuscation":"Vxh04AWWLkhSUd"}
+      data: {"id":"chatcmpl-ClYVf4uM2U0ATW18tcIGbdzcFAqWU","object":"chat.completion.chunk","created":1765450107,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_a4d13246c5","choices":[],"usage":{"prompt_tokens":153,"completion_tokens":6,"total_tokens":159,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":0,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}},"obfuscation":"Lhyx4FFDmVErjw"}
 
       data: [DONE]
 
@@ -53,15 +49,15 @@ interactions:
       - text/event-stream; charset=utf-8
     status: 200 OK
     code: 200
-    duration: 553.310667ms
+    duration: 512.637375ms
 - id: 1
   request:
     proto: HTTP/1.1
     proto_major: 1
     proto_minor: 1
-    content_length: 49865
+    content_length: 50256
     host: ""

internal/agent/testdata/TestCoderAgent/openrouter-kimi-k2/bash_tool.yaml πŸ”—

@@ -6,9 +6,56 @@ interactions:
     proto: HTTP/1.1
     proto_major: 1
     proto_minor: 1
-    content_length: 49961
+    content_length: 803
+    host: ""
+    body: '{"messages":[{"content":"you will generate a short title based on the first message a user begins a conversation with\n\n<rules>\n- ensure it is not more than 50 characters long\n- the title should be a summary of the user''s message\n- it should be one line long\n- do not use quotes or colons\n- the entire text you return will be used as the title\n- never return anything that is more than one sentence (one line) long\n</rules>\n\n /no_think","role":"system"},{"content":"Generate a concise title for the following content:\n\nuse bash to create a file named test.txt with content ''hello bash''. do not print its timestamp\n <think>\n\n</think>","role":"user"}],"model":"qwen/qwen3-next-80b-a3b-instruct","max_tokens":40,"stream_options":{"include_usage":true},"usage":{"include":true},"stream":true}'
+    headers:
+      Accept:
+      - application/json
+      Content-Type:
+      - application/json
+      User-Agent:
+      - OpenAI/Go 2.7.1
+    url: https://openrouter.ai/api/v1/chat/completions
+    method: POST
+  response:
+    proto: HTTP/2.0
+    proto_major: 2
+    proto_minor: 0
+    content_length: -1
+    body: |+
+      data: {"id":"gen-1765450159-XJbAh4NJseOmQCFaiLUK","provider":"Novita","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450159,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+      data: {"id":"gen-1765450159-XJbAh4NJseOmQCFaiLUK","provider":"Novita","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450159,"choices":[{"index":0,"delta":{"role":"assistant","content":"Create"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+      data: {"id":"gen-1765450159-XJbAh4NJseOmQCFaiLUK","provider":"Novita","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450159,"choices":[{"index":0,"delta":{"role":"assistant","content":" test"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+      data: {"id":"gen-1765450159-XJbAh4NJseOmQCFaiLUK","provider":"Novita","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450159,"choices":[{"index":0,"delta":{"role":"assistant","content":".txt with"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+      data: {"id":"gen-1765450159-XJbAh4NJseOmQCFaiLUK","provider":"Novita","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450159,"choices":[{"index":0,"delta":{"role":"assistant","content":" hello bash using"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+      data: {"id":"gen-1765450159-XJbAh4NJseOmQCFaiLUK","provider":"Novita","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450159,"choices":[{"index":0,"delta":{"role":"assistant","content":" bash"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+      data: {"id":"gen-1765450159-XJbAh4NJseOmQCFaiLUK","provider":"Novita","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450159,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":"stop","native_finish_reason":"stop","logprobs":null}],"system_fingerprint":""}
+
+      data: {"id":"gen-1765450159-XJbAh4NJseOmQCFaiLUK","provider":"Novita","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450159,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":151,"completion_tokens":8,"total_tokens":159,"cost":0.00002772,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.00001812,"upstream_inference_completions_cost":0.0000096},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0}}}
+
+      data: [DONE]
+
+    headers:
+      Content-Type:
+      - text/event-stream
+    status: 200 OK
+    code: 200
+    duration: 795.430042ms
+- id: 1
+  request:
+    proto: HTTP/1.1
+    proto_major: 1
+    proto_minor: 1
+    content_length: 50389
     host: ""

internal/agent/testdata/TestCoderAgent/openrouter-kimi-k2/download_tool.yaml πŸ”—

@@ -24,25 +24,25 @@ interactions:
     proto_minor: 0
     content_length: -1
     body: |+
-      data: {"id":"gen-1764862737-zUarDvIkRkWbsTW1b853","provider":"AtlasCloud","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862737,"choices":[{"index":0,"delta":{"role":"assistant","content":"Download"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+      data: {"id":"gen-1765450178-A3nTohIO2yAJW18wsmyU","provider":"Google","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450178,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
 
-      data: {"id":"gen-1764862737-zUarDvIkRkWbsTW1b853","provider":"AtlasCloud","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862737,"choices":[{"index":0,"delta":{"role":"assistant","content":" and"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+      data: {"id":"gen-1765450178-A3nTohIO2yAJW18wsmyU","provider":"Google","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450178,"choices":[{"index":0,"delta":{"role":"assistant","content":"Download"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
 
-      data: {"id":"gen-1764862737-zUarDvIkRkWbsTW1b853","provider":"AtlasCloud","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862737,"choices":[{"index":0,"delta":{"role":"assistant","content":" save"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+      data: {"id":"gen-1765450178-A3nTohIO2yAJW18wsmyU","provider":"Google","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450178,"choices":[{"index":0,"delta":{"role":"assistant","content":" example"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
 
-      data: {"id":"gen-1764862737-zUarDvIkRkWbsTW1b853","provider":"AtlasCloud","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862737,"choices":[{"index":0,"delta":{"role":"assistant","content":" example"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+      data: {"id":"gen-1765450178-A3nTohIO2yAJW18wsmyU","provider":"Google","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450178,"choices":[{"index":0,"delta":{"role":"assistant","content":".txt from example"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
 
-      data: {"id":"gen-1764862737-zUarDvIkRkWbsTW1b853","provider":"AtlasCloud","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862737,"choices":[{"index":0,"delta":{"role":"assistant","content":".txt"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+      data: {"id":"gen-1765450178-A3nTohIO2yAJW18wsmyU","provider":"Google","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450178,"choices":[{"index":0,"delta":{"role":"assistant","content":"-files"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
 
-      data: {"id":"gen-1764862737-zUarDvIkRkWbsTW1b853","provider":"AtlasCloud","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862737,"choices":[{"index":0,"delta":{"role":"assistant","content":" from"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+      data: {"id":"gen-1765450178-A3nTohIO2yAJW18wsmyU","provider":"Google","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450178,"choices":[{"index":0,"delta":{"role":"assistant","content":".online"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
 
-      data: {"id":"gen-1764862737-zUarDvIkRkWbsTW1b853","provider":"AtlasCloud","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862737,"choices":[{"index":0,"delta":{"role":"assistant","content":" given"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+      data: {"id":"gen-1765450178-A3nTohIO2yAJW18wsmyU","provider":"Google","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450178,"choices":[{"index":0,"delta":{"role":"assistant","content":"-"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
 
-      data: {"id":"gen-1764862737-zUarDvIkRkWbsTW1b853","provider":"AtlasCloud","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862737,"choices":[{"index":0,"delta":{"role":"assistant","content":" URL"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+      data: {"id":"gen-1765450178-A3nTohIO2yAJW18wsmyU","provider":"Google","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450178,"choices":[{"index":0,"delta":{"role":"assistant","content":"convert.com"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
 
-      data: {"id":"gen-1764862737-zUarDvIkRkWbsTW1b853","provider":"AtlasCloud","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862737,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":"stop","native_finish_reason":"stop","logprobs":null}]}
+      data: {"id":"gen-1765450178-A3nTohIO2yAJW18wsmyU","provider":"Google","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450178,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":"stop","native_finish_reason":"stop","logprobs":null}]}
 
-      data: {"id":"gen-1764862737-zUarDvIkRkWbsTW1b853","provider":"AtlasCloud","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862737,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":150,"completion_tokens":9,"total_tokens":159,"cost":0.000036,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.0000225,"upstream_inference_completions_cost":0.0000135},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0}}}
+      data: {"id":"gen-1765450178-A3nTohIO2yAJW18wsmyU","provider":"Google","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450178,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":150,"completion_tokens":11,"total_tokens":161,"cost":0.0000357,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.0000225,"upstream_inference_completions_cost":0.0000132},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0}}}
 
       data: [DONE]
 
@@ -51,15 +51,15 @@ interactions:
       - text/event-stream
     status: 200 OK
     code: 200
-    duration: 982.813875ms
+    duration: 411.759375ms
 - id: 1
   request:
     proto: HTTP/1.1
     proto_major: 1
     proto_minor: 1
-    content_length: 49986
+    content_length: 50414
     host: ""

internal/agent/testdata/TestCoderAgent/openrouter-kimi-k2/fetch_tool.yaml πŸ”—

@@ -24,19 +24,25 @@ interactions:
     proto_minor: 0
     content_length: -1
     body: |+
-      data: {"id":"gen-1764862747-NWcjnST8QJWfug0BMCkp","provider":"Alibaba","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862747,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":null}
+      data: {"id":"gen-1765450187-86qtDlWHSSeu17meW5QN","provider":"Chutes","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450187,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
 
-      data: {"id":"gen-1764862747-NWcjnST8QJWfug0BMCkp","provider":"Alibaba","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862747,"choices":[{"index":0,"delta":{"role":"assistant","content":"Check"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":null}
+      data: {"id":"gen-1765450187-86qtDlWHSSeu17meW5QN","provider":"Chutes","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450187,"choices":[{"index":0,"delta":{"role":"assistant","content":"Check"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
 
-      data: {"id":"gen-1764862747-NWcjnST8QJWfug0BMCkp","provider":"Alibaba","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862747,"choices":[{"index":0,"delta":{"role":"assistant","content":" if example"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":null}
+      data: {"id":"gen-1765450187-86qtDlWHSSeu17meW5QN","provider":"Chutes","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450187,"choices":[{"index":0,"delta":{"role":"assistant","content":" if"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
 
-      data: {"id":"gen-1764862747-NWcjnST8QJWfug0BMCkp","provider":"Alibaba","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862747,"choices":[{"index":0,"delta":{"role":"assistant","content":".html contains John"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":null}
+      data: {"id":"gen-1765450187-86qtDlWHSSeu17meW5QN","provider":"Chutes","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450187,"choices":[{"index":0,"delta":{"role":"assistant","content":" example"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
 
-      data: {"id":"gen-1764862747-NWcjnST8QJWfug0BMCkp","provider":"Alibaba","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862747,"choices":[{"index":0,"delta":{"role":"assistant","content":" Doe"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":null}
+      data: {"id":"gen-1765450187-86qtDlWHSSeu17meW5QN","provider":"Chutes","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450187,"choices":[{"index":0,"delta":{"role":"assistant","content":".html"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
 
-      data: {"id":"gen-1764862747-NWcjnST8QJWfug0BMCkp","provider":"Alibaba","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862747,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":"stop","native_finish_reason":"stop","logprobs":null}],"system_fingerprint":null}
+      data: {"id":"gen-1765450187-86qtDlWHSSeu17meW5QN","provider":"Chutes","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450187,"choices":[{"index":0,"delta":{"role":"assistant","content":" contains"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
 
-      data: {"id":"gen-1764862747-NWcjnST8QJWfug0BMCkp","provider":"Alibaba","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862747,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":159,"completion_tokens":7,"total_tokens":166,"cost":0.00003225,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.00002385,"upstream_inference_completions_cost":0.0000084},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0}}}
+      data: {"id":"gen-1765450187-86qtDlWHSSeu17meW5QN","provider":"Chutes","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450187,"choices":[{"index":0,"delta":{"role":"assistant","content":" John"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+      data: {"id":"gen-1765450187-86qtDlWHSSeu17meW5QN","provider":"Chutes","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450187,"choices":[{"index":0,"delta":{"role":"assistant","content":" Doe"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+      data: {"id":"gen-1765450187-86qtDlWHSSeu17meW5QN","provider":"Chutes","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450187,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":"stop","native_finish_reason":"stop","logprobs":null}]}
+
+      data: {"id":"gen-1765450187-86qtDlWHSSeu17meW5QN","provider":"Chutes","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450187,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":155,"completion_tokens":8,"total_tokens":163,"cost":0.0000219,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.0000155,"upstream_inference_completions_cost":0.0000064},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0}}}
 
       data: [DONE]
 
@@ -45,15 +51,15 @@ interactions:
       - text/event-stream
     status: 200 OK
     code: 200
-    duration: 806.467791ms
+    duration: 1.128562167s
 - id: 1
   request:
     proto: HTTP/1.1
     proto_major: 1
     proto_minor: 1
-    content_length: 50004
+    content_length: 50432
     host: ""

internal/agent/testdata/TestCoderAgent/openrouter-kimi-k2/glob_tool.yaml πŸ”—

@@ -24,31 +24,31 @@ interactions:
     proto_minor: 0
     content_length: -1
     body: |+
-      data: {"id":"gen-1764862755-jp7G5Oi0A1yIQSAlyPvC","provider":"Parasail","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862755,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+      data: {"id":"gen-1765450190-HU1ZzT0K8QtwdsvIz0S1","provider":"Parasail","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450190,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
 
-      data: {"id":"gen-1764862755-jp7G5Oi0A1yIQSAlyPvC","provider":"Parasail","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862755,"choices":[{"index":0,"delta":{"role":"assistant","content":"Find"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+      data: {"id":"gen-1765450190-HU1ZzT0K8QtwdsvIz0S1","provider":"Parasail","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450190,"choices":[{"index":0,"delta":{"role":"assistant","content":"Find"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
 
-      data: {"id":"gen-1764862755-jp7G5Oi0A1yIQSAlyPvC","provider":"Parasail","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862755,"choices":[{"index":0,"delta":{"role":"assistant","content":" all"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+      data: {"id":"gen-1765450190-HU1ZzT0K8QtwdsvIz0S1","provider":"Parasail","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450190,"choices":[{"index":0,"delta":{"role":"assistant","content":" all"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
 
-      data: {"id":"gen-1764862755-jp7G5Oi0A1yIQSAlyPvC","provider":"Parasail","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862755,"choices":[{"index":0,"delta":{"role":"assistant","content":" ."},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+      data: {"id":"gen-1765450190-HU1ZzT0K8QtwdsvIz0S1","provider":"Parasail","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450190,"choices":[{"index":0,"delta":{"role":"assistant","content":" ."},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
 
-      data: {"id":"gen-1764862755-jp7G5Oi0A1yIQSAlyPvC","provider":"Parasail","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862755,"choices":[{"index":0,"delta":{"role":"assistant","content":"go"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+      data: {"id":"gen-1765450190-HU1ZzT0K8QtwdsvIz0S1","provider":"Parasail","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450190,"choices":[{"index":0,"delta":{"role":"assistant","content":"go"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
 
-      data: {"id":"gen-1764862755-jp7G5Oi0A1yIQSAlyPvC","provider":"Parasail","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862755,"choices":[{"index":0,"delta":{"role":"assistant","content":" files"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+      data: {"id":"gen-1765450190-HU1ZzT0K8QtwdsvIz0S1","provider":"Parasail","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450190,"choices":[{"index":0,"delta":{"role":"assistant","content":" files"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
 
-      data: {"id":"gen-1764862755-jp7G5Oi0A1yIQSAlyPvC","provider":"Parasail","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862755,"choices":[{"index":0,"delta":{"role":"assistant","content":" in"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+      data: {"id":"gen-1765450190-HU1ZzT0K8QtwdsvIz0S1","provider":"Parasail","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450190,"choices":[{"index":0,"delta":{"role":"assistant","content":" in"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
 
-      data: {"id":"gen-1764862755-jp7G5Oi0A1yIQSAlyPvC","provider":"Parasail","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862755,"choices":[{"index":0,"delta":{"role":"assistant","content":" current"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+      data: {"id":"gen-1765450190-HU1ZzT0K8QtwdsvIz0S1","provider":"Parasail","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450190,"choices":[{"index":0,"delta":{"role":"assistant","content":" current"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
 
-      data: {"id":"gen-1764862755-jp7G5Oi0A1yIQSAlyPvC","provider":"Parasail","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862755,"choices":[{"index":0,"delta":{"role":"assistant","content":" directory"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+      data: {"id":"gen-1765450190-HU1ZzT0K8QtwdsvIz0S1","provider":"Parasail","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450190,"choices":[{"index":0,"delta":{"role":"assistant","content":" directory"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
 
-      data: {"id":"gen-1764862755-jp7G5Oi0A1yIQSAlyPvC","provider":"Parasail","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862755,"choices":[{"index":0,"delta":{"role":"assistant","content":" using"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+      data: {"id":"gen-1765450190-HU1ZzT0K8QtwdsvIz0S1","provider":"Parasail","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450190,"choices":[{"index":0,"delta":{"role":"assistant","content":" using"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
 
-      data: {"id":"gen-1764862755-jp7G5Oi0A1yIQSAlyPvC","provider":"Parasail","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862755,"choices":[{"index":0,"delta":{"role":"assistant","content":" glob"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+      data: {"id":"gen-1765450190-HU1ZzT0K8QtwdsvIz0S1","provider":"Parasail","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450190,"choices":[{"index":0,"delta":{"role":"assistant","content":" glob"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
 
-      data: {"id":"gen-1764862755-jp7G5Oi0A1yIQSAlyPvC","provider":"Parasail","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862755,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":"stop","native_finish_reason":"stop","logprobs":null}]}
+      data: {"id":"gen-1765450190-HU1ZzT0K8QtwdsvIz0S1","provider":"Parasail","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450190,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":"stop","native_finish_reason":"stop","logprobs":null}]}
 
-      data: {"id":"gen-1764862755-jp7G5Oi0A1yIQSAlyPvC","provider":"Parasail","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862755,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":139,"completion_tokens":11,"total_tokens":150,"cost":0.000026,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.0000139,"upstream_inference_completions_cost":0.0000121},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0}}}
+      data: {"id":"gen-1765450190-HU1ZzT0K8QtwdsvIz0S1","provider":"Parasail","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450190,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":139,"completion_tokens":11,"total_tokens":150,"cost":0.000026,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.0000139,"upstream_inference_completions_cost":0.0000121},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0}}}
 
       data: [DONE]
 
@@ -57,15 +57,15 @@ interactions:
       - text/event-stream
     status: 200 OK
     code: 200
-    duration: 418.074333ms
+    duration: 436.118917ms
 - id: 1
   request:
     proto: HTTP/1.1
     proto_major: 1
     proto_minor: 1
-    content_length: 49922
+    content_length: 50350
     host: ""

internal/agent/testdata/TestCoderAgent/openrouter-kimi-k2/grep_tool.yaml πŸ”—

@@ -24,27 +24,17 @@ interactions:
     proto_minor: 0
     content_length: -1
     body: |+
-      data: {"id":"gen-1764862759-qsI3C4t47te0ib8QGB6x","provider":"Chutes","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862759,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+      data: {"id":"gen-1765450195-UcNkDgNeGiSDNMOQYMrq","provider":"Alibaba","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450195,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":null}
 
-      data: {"id":"gen-1764862759-qsI3C4t47te0ib8QGB6x","provider":"Chutes","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862759,"choices":[{"index":0,"delta":{"role":"assistant","content":"Search"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+      data: {"id":"gen-1765450195-UcNkDgNeGiSDNMOQYMrq","provider":"Alibaba","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450195,"choices":[{"index":0,"delta":{"role":"assistant","content":"Search"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":null}
 
-      data: {"id":"gen-1764862759-qsI3C4t47te0ib8QGB6x","provider":"Chutes","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862759,"choices":[{"index":0,"delta":{"role":"assistant","content":" for"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+      data: {"id":"gen-1765450195-UcNkDgNeGiSDNMOQYMrq","provider":"Alibaba","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450195,"choices":[{"index":0,"delta":{"role":"assistant","content":" for package in Go"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":null}
 
-      data: {"id":"gen-1764862759-qsI3C4t47te0ib8QGB6x","provider":"Chutes","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862759,"choices":[{"index":0,"delta":{"role":"assistant","content":" package"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+      data: {"id":"gen-1765450195-UcNkDgNeGiSDNMOQYMrq","provider":"Alibaba","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450195,"choices":[{"index":0,"delta":{"role":"assistant","content":" files using grep"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":null}
 
-      data: {"id":"gen-1764862759-qsI3C4t47te0ib8QGB6x","provider":"Chutes","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862759,"choices":[{"index":0,"delta":{"role":"assistant","content":" in"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+      data: {"id":"gen-1765450195-UcNkDgNeGiSDNMOQYMrq","provider":"Alibaba","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450195,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":"stop","native_finish_reason":"stop","logprobs":null}],"system_fingerprint":null}
 
-      data: {"id":"gen-1764862759-qsI3C4t47te0ib8QGB6x","provider":"Chutes","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862759,"choices":[{"index":0,"delta":{"role":"assistant","content":" Go"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
-
-      data: {"id":"gen-1764862759-qsI3C4t47te0ib8QGB6x","provider":"Chutes","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862759,"choices":[{"index":0,"delta":{"role":"assistant","content":" files"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
-
-      data: {"id":"gen-1764862759-qsI3C4t47te0ib8QGB6x","provider":"Chutes","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862759,"choices":[{"index":0,"delta":{"role":"assistant","content":" using"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
-
-      data: {"id":"gen-1764862759-qsI3C4t47te0ib8QGB6x","provider":"Chutes","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862759,"choices":[{"index":0,"delta":{"role":"assistant","content":" grep"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
-
-      data: {"id":"gen-1764862759-qsI3C4t47te0ib8QGB6x","provider":"Chutes","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862759,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":"stop","native_finish_reason":"stop","logprobs":null}]}
-
-      data: {"id":"gen-1764862759-qsI3C4t47te0ib8QGB6x","provider":"Chutes","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862759,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":140,"completion_tokens":9,"total_tokens":149,"cost":0.0000212,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.000014,"upstream_inference_completions_cost":0.0000072},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0}}}
+      data: {"id":"gen-1765450195-UcNkDgNeGiSDNMOQYMrq","provider":"Alibaba","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450195,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":144,"completion_tokens":8,"total_tokens":152,"cost":0.0000312,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.0000216,"upstream_inference_completions_cost":0.0000096},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0}}}
 
       data: [DONE]
 
@@ -53,15 +43,15 @@ interactions:
       - text/event-stream
     status: 200 OK
     code: 200
-    duration: 937.9565ms
+    duration: 931.045916ms
 - id: 1
   request:
     proto: HTTP/1.1
     proto_major: 1
     proto_minor: 1
-    content_length: 49920
+    content_length: 50348
     host: ""

internal/agent/testdata/TestCoderAgent/openrouter-kimi-k2/multiedit_tool.yaml πŸ”—

@@ -24,21 +24,35 @@ interactions:
     proto_minor: 0
     content_length: -1
     body: |+
-      data: {"id":"gen-1764862769-xKX5bOBWM8OKXZGpqKYF","provider":"GMICloud","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862769,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+      data: {"id":"gen-1765450201-uCjS9MYSLxlXyzRS6nbO","provider":"AtlasCloud","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450201,"choices":[{"index":0,"delta":{"role":"assistant","content":"Use"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
 
-      data: {"id":"gen-1764862769-xKX5bOBWM8OKXZGpqKYF","provider":"GMICloud","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862769,"choices":[{"index":0,"delta":{"role":"assistant","content":"Use"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+      data: {"id":"gen-1765450201-uCjS9MYSLxlXyzRS6nbO","provider":"AtlasCloud","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450201,"choices":[{"index":0,"delta":{"role":"assistant","content":" mult"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
 
-      data: {"id":"gen-1764862769-xKX5bOBWM8OKXZGpqKYF","provider":"GMICloud","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862769,"choices":[{"index":0,"delta":{"role":"assistant","content":" multiedit to"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+      data: {"id":"gen-1765450201-uCjS9MYSLxlXyzRS6nbO","provider":"AtlasCloud","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450201,"choices":[{"index":0,"delta":{"role":"assistant","content":"ied"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
 
-      data: {"id":"gen-1764862769-xKX5bOBWM8OKXZGpqKYF","provider":"GMICloud","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862769,"choices":[{"index":0,"delta":{"role":"assistant","content":" update greeting"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+      data: {"id":"gen-1765450201-uCjS9MYSLxlXyzRS6nbO","provider":"AtlasCloud","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450201,"choices":[{"index":0,"delta":{"role":"assistant","content":"it"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
 
-      data: {"id":"gen-1764862769-xKX5bOBWM8OKXZGpqKYF","provider":"GMICloud","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862769,"choices":[{"index":0,"delta":{"role":"assistant","content":" and add comment in"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+      data: {"id":"gen-1765450201-uCjS9MYSLxlXyzRS6nbO","provider":"AtlasCloud","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450201,"choices":[{"index":0,"delta":{"role":"assistant","content":" to"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
 
-      data: {"id":"gen-1764862769-xKX5bOBWM8OKXZGpqKYF","provider":"GMICloud","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862769,"choices":[{"index":0,"delta":{"role":"assistant","content":" main.go"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+      data: {"id":"gen-1765450201-uCjS9MYSLxlXyzRS6nbO","provider":"AtlasCloud","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450201,"choices":[{"index":0,"delta":{"role":"assistant","content":" update"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
 
-      data: {"id":"gen-1764862769-xKX5bOBWM8OKXZGpqKYF","provider":"GMICloud","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862769,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":"stop","native_finish_reason":"stop","logprobs":null}]}
+      data: {"id":"gen-1765450201-uCjS9MYSLxlXyzRS6nbO","provider":"AtlasCloud","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450201,"choices":[{"index":0,"delta":{"role":"assistant","content":" greeting"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
 
-      data: {"id":"gen-1764862769-xKX5bOBWM8OKXZGpqKYF","provider":"GMICloud","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862769,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":160,"completion_tokens":14,"total_tokens":174,"cost":0.000045,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.000024,"upstream_inference_completions_cost":0.000021},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0}}}
+      data: {"id":"gen-1765450201-uCjS9MYSLxlXyzRS6nbO","provider":"AtlasCloud","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450201,"choices":[{"index":0,"delta":{"role":"assistant","content":" and"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+      data: {"id":"gen-1765450201-uCjS9MYSLxlXyzRS6nbO","provider":"AtlasCloud","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450201,"choices":[{"index":0,"delta":{"role":"assistant","content":" add"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+      data: {"id":"gen-1765450201-uCjS9MYSLxlXyzRS6nbO","provider":"AtlasCloud","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450201,"choices":[{"index":0,"delta":{"role":"assistant","content":" comment"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+      data: {"id":"gen-1765450201-uCjS9MYSLxlXyzRS6nbO","provider":"AtlasCloud","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450201,"choices":[{"index":0,"delta":{"role":"assistant","content":" in"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+      data: {"id":"gen-1765450201-uCjS9MYSLxlXyzRS6nbO","provider":"AtlasCloud","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450201,"choices":[{"index":0,"delta":{"role":"assistant","content":" main"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+      data: {"id":"gen-1765450201-uCjS9MYSLxlXyzRS6nbO","provider":"AtlasCloud","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450201,"choices":[{"index":0,"delta":{"role":"assistant","content":".go"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+      data: {"id":"gen-1765450201-uCjS9MYSLxlXyzRS6nbO","provider":"AtlasCloud","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450201,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":"stop","native_finish_reason":"stop","logprobs":null}]}
+
+      data: {"id":"gen-1765450201-uCjS9MYSLxlXyzRS6nbO","provider":"AtlasCloud","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450201,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":160,"completion_tokens":14,"total_tokens":174,"cost":0.000045,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.000024,"upstream_inference_completions_cost":0.000021},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0}}}
 
       data: [DONE]
 
@@ -47,15 +61,15 @@ interactions:
       - text/event-stream
     status: 200 OK
     code: 200
-    duration: 547.476834ms
+    duration: 1.045920416s
 - id: 1
   request:
     proto: HTTP/1.1
     proto_major: 1
     proto_minor: 1
-    content_length: 50000
+    content_length: 50428
     host: ""

internal/agent/testdata/TestCoderAgent/openrouter-kimi-k2/parallel_tool_calls.yaml πŸ”—

@@ -24,23 +24,21 @@ interactions:
     proto_minor: 0
     content_length: -1
     body: |+
-      data: {"id":"gen-1764862833-tOhYcLNmvlm0xr7L4TiV","provider":"DeepInfra","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862833,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+      data: {"id":"gen-1765450253-aB1ptbsaQGZNx7caoOWm","provider":"Google","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450253,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
 
-      data: {"id":"gen-1764862833-tOhYcLNmvlm0xr7L4TiV","provider":"DeepInfra","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862833,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+      data: {"id":"gen-1765450253-aB1ptbsaQGZNx7caoOWm","provider":"Google","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450253,"choices":[{"index":0,"delta":{"role":"assistant","content":"Find"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
 
-      data: {"id":"gen-1764862833-tOhYcLNmvlm0xr7L4TiV","provider":"DeepInfra","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862833,"choices":[{"index":0,"delta":{"role":"assistant","content":"Find"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+      data: {"id":"gen-1765450253-aB1ptbsaQGZNx7caoOWm","provider":"Google","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450253,"choices":[{"index":0,"delta":{"role":"assistant","content":" .go files and"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
 
-      data: {"id":"gen-1764862833-tOhYcLNmvlm0xr7L4TiV","provider":"DeepInfra","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862833,"choices":[{"index":0,"delta":{"role":"assistant","content":" .go files and"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+      data: {"id":"gen-1765450253-aB1ptbsaQGZNx7caoOWm","provider":"Google","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450253,"choices":[{"index":0,"delta":{"role":"assistant","content":" list directory"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
 
-      data: {"id":"gen-1764862833-tOhYcLNmvlm0xr7L4TiV","provider":"DeepInfra","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862833,"choices":[{"index":0,"delta":{"role":"assistant","content":" list directory"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+      data: {"id":"gen-1765450253-aB1ptbsaQGZNx7caoOWm","provider":"Google","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450253,"choices":[{"index":0,"delta":{"role":"assistant","content":" in"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
 
-      data: {"id":"gen-1764862833-tOhYcLNmvlm0xr7L4TiV","provider":"DeepInfra","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862833,"choices":[{"index":0,"delta":{"role":"assistant","content":" in"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+      data: {"id":"gen-1765450253-aB1ptbsaQGZNx7caoOWm","provider":"Google","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450253,"choices":[{"index":0,"delta":{"role":"assistant","content":" parallel"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
 
-      data: {"id":"gen-1764862833-tOhYcLNmvlm0xr7L4TiV","provider":"DeepInfra","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862833,"choices":[{"index":0,"delta":{"role":"assistant","content":" parallel"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+      data: {"id":"gen-1765450253-aB1ptbsaQGZNx7caoOWm","provider":"Google","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450253,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":"stop","native_finish_reason":"stop","logprobs":null}]}
 
-      data: {"id":"gen-1764862833-tOhYcLNmvlm0xr7L4TiV","provider":"DeepInfra","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862833,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":"stop","native_finish_reason":"stop","logprobs":null}]}
-
-      data: {"id":"gen-1764862833-tOhYcLNmvlm0xr7L4TiV","provider":"DeepInfra","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862833,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":156,"completion_tokens":10,"total_tokens":166,"cost":0.00003284,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.00002184,"upstream_inference_completions_cost":0.000011},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0}}}
+      data: {"id":"gen-1765450253-aB1ptbsaQGZNx7caoOWm","provider":"Google","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450253,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":156,"completion_tokens":10,"total_tokens":166,"cost":0.0000354,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.0000234,"upstream_inference_completions_cost":0.000012},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0}}}
 
       data: [DONE]
 
@@ -49,15 +47,15 @@ interactions:
       - text/event-stream
     status: 200 OK
     code: 200
-    duration: 209.204917ms
+    duration: 406.877083ms
 - id: 1
   request:
     proto: HTTP/1.1
     proto_major: 1
     proto_minor: 1
-    content_length: 50011
+    content_length: 50439
     host: ""

internal/agent/testdata/TestCoderAgent/openrouter-kimi-k2/read_a_file.yaml πŸ”—

@@ -24,19 +24,15 @@ interactions:
     proto_minor: 0
     content_length: -1
     body: |+
-      data: {"id":"gen-1764862715-k965LnDbHybA0s6MJwAs","provider":"Chutes","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862715,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+      data: {"id":"gen-1765450141-fso4k5alZHsFg1Ss7Y5w","provider":"Alibaba","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450141,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":null}
 
-      data: {"id":"gen-1764862715-k965LnDbHybA0s6MJwAs","provider":"Chutes","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862715,"choices":[{"index":0,"delta":{"role":"assistant","content":"Read"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+      data: {"id":"gen-1765450141-fso4k5alZHsFg1Ss7Y5w","provider":"Alibaba","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450141,"choices":[{"index":0,"delta":{"role":"assistant","content":"Read"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":null}
 
-      data: {"id":"gen-1764862715-k965LnDbHybA0s6MJwAs","provider":"Chutes","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862715,"choices":[{"index":0,"delta":{"role":"assistant","content":" the"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+      data: {"id":"gen-1765450141-fso4k5alZHsFg1Ss7Y5w","provider":"Alibaba","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450141,"choices":[{"index":0,"delta":{"role":"assistant","content":" the go mod"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":null}
 
-      data: {"id":"gen-1764862715-k965LnDbHybA0s6MJwAs","provider":"Chutes","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862715,"choices":[{"index":0,"delta":{"role":"assistant","content":" go"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+      data: {"id":"gen-1765450141-fso4k5alZHsFg1Ss7Y5w","provider":"Alibaba","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450141,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":"stop","native_finish_reason":"stop","logprobs":null}],"system_fingerprint":null}
 
-      data: {"id":"gen-1764862715-k965LnDbHybA0s6MJwAs","provider":"Chutes","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862715,"choices":[{"index":0,"delta":{"role":"assistant","content":" mod"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
-
-      data: {"id":"gen-1764862715-k965LnDbHybA0s6MJwAs","provider":"Chutes","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862715,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":"stop","native_finish_reason":"stop","logprobs":null}]}
-
-      data: {"id":"gen-1764862715-k965LnDbHybA0s6MJwAs","provider":"Chutes","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862715,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":131,"completion_tokens":5,"total_tokens":136,"cost":0.0000171,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.0000131,"upstream_inference_completions_cost":0.000004},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0}}}
+      data: {"id":"gen-1765450141-fso4k5alZHsFg1Ss7Y5w","provider":"Alibaba","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450141,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":135,"completion_tokens":4,"total_tokens":139,"cost":0.00002505,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.00002025,"upstream_inference_completions_cost":0.0000048},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0}}}
 
       data: [DONE]
 
@@ -45,15 +41,15 @@ interactions:
       - text/event-stream
     status: 200 OK
     code: 200
-    duration: 834.326708ms
+    duration: 762.002208ms
 - id: 1
   request:
     proto: HTTP/1.1
     proto_major: 1
     proto_minor: 1
-    content_length: 49884
+    content_length: 50312
     host: ""

internal/agent/testdata/TestCoderAgent/openrouter-kimi-k2/simple_test.yaml πŸ”—

@@ -24,13 +24,13 @@ interactions:
     proto_minor: 0
     content_length: -1
     body: |+
-      data: {"id":"gen-1764862714-vD89hN6MMDQXWYsJAuZ4","provider":"Parasail","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862714,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+      data: {"id":"gen-1765450138-WRCaApYTil43Xf1sSzHC","provider":"Chutes","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450138,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
 
-      data: {"id":"gen-1764862714-vD89hN6MMDQXWYsJAuZ4","provider":"Parasail","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862714,"choices":[{"index":0,"delta":{"role":"assistant","content":"Hello"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+      data: {"id":"gen-1765450138-WRCaApYTil43Xf1sSzHC","provider":"Chutes","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450138,"choices":[{"index":0,"delta":{"role":"assistant","content":"Hello"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
 
-      data: {"id":"gen-1764862714-vD89hN6MMDQXWYsJAuZ4","provider":"Parasail","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862714,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":"stop","native_finish_reason":"stop","logprobs":null}]}
+      data: {"id":"gen-1765450138-WRCaApYTil43Xf1sSzHC","provider":"Chutes","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450138,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":"stop","native_finish_reason":"stop","logprobs":null}]}
 
-      data: {"id":"gen-1764862714-vD89hN6MMDQXWYsJAuZ4","provider":"Parasail","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862714,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":128,"completion_tokens":2,"total_tokens":130,"cost":0.000015,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.0000128,"upstream_inference_completions_cost":0.0000022},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0}}}
+      data: {"id":"gen-1765450138-WRCaApYTil43Xf1sSzHC","provider":"Chutes","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450138,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":128,"completion_tokens":2,"total_tokens":130,"cost":0.0000144,"is_byok":false,"prompt_tokens_details":{"cached_tokens":2,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.0000128,"upstream_inference_completions_cost":0.0000016},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0}}}
 
       data: [DONE]
 
@@ -39,15 +39,15 @@ interactions:
       - text/event-stream
     status: 200 OK
     code: 200
-    duration: 635.219458ms
+    duration: 1.336080084s
 - id: 1
   request:
     proto: HTTP/1.1
     proto_major: 1
     proto_minor: 1
-    content_length: 49874
+    content_length: 50302
     host: ""

internal/agent/testdata/TestCoderAgent/openrouter-kimi-k2/sourcegraph_tool.yaml πŸ”—

@@ -24,23 +24,19 @@ interactions:
     proto_minor: 0
     content_length: -1
     body: |+
-      data: {"id":"gen-1764862780-DxPacjmGBJHtn64cZujI","provider":"DeepInfra","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862780,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+      data: {"id":"gen-1765450225-ZNd9O4Gaiw67Y8sUTO9e","provider":"Alibaba","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450225,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":null}
 
-      data: {"id":"gen-1764862780-DxPacjmGBJHtn64cZujI","provider":"DeepInfra","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862780,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+      data: {"id":"gen-1765450225-ZNd9O4Gaiw67Y8sUTO9e","provider":"Alibaba","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450225,"choices":[{"index":0,"delta":{"role":"assistant","content":"Search"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":null}
 
-      data: {"id":"gen-1764862780-DxPacjmGBJHtn64cZujI","provider":"DeepInfra","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862780,"choices":[{"index":0,"delta":{"role":"assistant","content":"Search"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+      data: {"id":"gen-1765450225-ZNd9O4Gaiw67Y8sUTO9e","provider":"Alibaba","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450225,"choices":[{"index":0,"delta":{"role":"assistant","content":" for func"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":null}
 
-      data: {"id":"gen-1764862780-DxPacjmGBJHtn64cZujI","provider":"DeepInfra","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862780,"choices":[{"index":0,"delta":{"role":"assistant","content":" for func"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+      data: {"id":"gen-1765450225-ZNd9O4Gaiw67Y8sUTO9e","provider":"Alibaba","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450225,"choices":[{"index":0,"delta":{"role":"assistant","content":" main in Go repositories"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":null}
 
-      data: {"id":"gen-1764862780-DxPacjmGBJHtn64cZujI","provider":"DeepInfra","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862780,"choices":[{"index":0,"delta":{"role":"assistant","content":" main in Go repositories"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+      data: {"id":"gen-1765450225-ZNd9O4Gaiw67Y8sUTO9e","provider":"Alibaba","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450225,"choices":[{"index":0,"delta":{"role":"assistant","content":" using Sourcegraph"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":null}
 
-      data: {"id":"gen-1764862780-DxPacjmGBJHtn64cZujI","provider":"DeepInfra","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862780,"choices":[{"index":0,"delta":{"role":"assistant","content":" using Source"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+      data: {"id":"gen-1765450225-ZNd9O4Gaiw67Y8sUTO9e","provider":"Alibaba","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450225,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":"stop","native_finish_reason":"stop","logprobs":null}],"system_fingerprint":null}
 
-      data: {"id":"gen-1764862780-DxPacjmGBJHtn64cZujI","provider":"DeepInfra","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862780,"choices":[{"index":0,"delta":{"role":"assistant","content":"graph"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
-
-      data: {"id":"gen-1764862780-DxPacjmGBJHtn64cZujI","provider":"DeepInfra","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862780,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":"stop","native_finish_reason":"stop","logprobs":null}]}
-
-      data: {"id":"gen-1764862780-DxPacjmGBJHtn64cZujI","provider":"DeepInfra","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862780,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":140,"completion_tokens":11,"total_tokens":151,"cost":0.0000317,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.0000196,"upstream_inference_completions_cost":0.0000121},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0}}}
+      data: {"id":"gen-1765450225-ZNd9O4Gaiw67Y8sUTO9e","provider":"Alibaba","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450225,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":144,"completion_tokens":10,"total_tokens":154,"cost":0.0000336,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.0000216,"upstream_inference_completions_cost":0.000012},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0}}}
 
       data: [DONE]
 
@@ -49,15 +45,15 @@ interactions:
       - text/event-stream
     status: 200 OK
     code: 200
-    duration: 252.042666ms
+    duration: 474.183292ms
 - id: 1
   request:
     proto: HTTP/1.1
     proto_major: 1
     proto_minor: 1
-    content_length: 49934
+    content_length: 50362
     host: ""

internal/agent/testdata/TestCoderAgent/openrouter-kimi-k2/update_a_file.yaml πŸ”—

@@ -24,19 +24,19 @@ interactions:
     proto_minor: 0
     content_length: -1
     body: |+
-      data: {"id":"gen-1764862718-jb4FsxCbJM3a4t2pBXI6","provider":"GMICloud","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862718,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+      data: {"id":"gen-1765450148-ryE7UAQTZkBmJUJaEF6T","provider":"SiliconFlow","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450148,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
 
-      data: {"id":"gen-1764862718-jb4FsxCbJM3a4t2pBXI6","provider":"GMICloud","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862718,"choices":[{"index":0,"delta":{"role":"assistant","content":"Update"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+      data: {"id":"gen-1765450148-ryE7UAQTZkBmJUJaEF6T","provider":"SiliconFlow","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450148,"choices":[{"index":0,"delta":{"role":"assistant","content":"Update"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
 
-      data: {"id":"gen-1764862718-jb4FsxCbJM3a4t2pBXI6","provider":"GMICloud","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862718,"choices":[{"index":0,"delta":{"role":"assistant","content":" main.go to print"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+      data: {"id":"gen-1765450148-ryE7UAQTZkBmJUJaEF6T","provider":"SiliconFlow","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450148,"choices":[{"index":0,"delta":{"role":"assistant","content":" main.go to print"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
 
-      data: {"id":"gen-1764862718-jb4FsxCbJM3a4t2pBXI6","provider":"GMICloud","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862718,"choices":[{"index":0,"delta":{"role":"assistant","content":" hello"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+      data: {"id":"gen-1765450148-ryE7UAQTZkBmJUJaEF6T","provider":"SiliconFlow","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450148,"choices":[{"index":0,"delta":{"role":"assistant","content":" hello"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
 
-      data: {"id":"gen-1764862718-jb4FsxCbJM3a4t2pBXI6","provider":"GMICloud","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862718,"choices":[{"index":0,"delta":{"role":"assistant","content":" from crush"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+      data: {"id":"gen-1765450148-ryE7UAQTZkBmJUJaEF6T","provider":"SiliconFlow","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450148,"choices":[{"index":0,"delta":{"role":"assistant","content":" from crush"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
 
-      data: {"id":"gen-1764862718-jb4FsxCbJM3a4t2pBXI6","provider":"GMICloud","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862718,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":"stop","native_finish_reason":"stop","logprobs":null}]}
+      data: {"id":"gen-1765450148-ryE7UAQTZkBmJUJaEF6T","provider":"SiliconFlow","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450148,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":"stop","native_finish_reason":"stop","logprobs":null}],"system_fingerprint":""}
 
-      data: {"id":"gen-1764862718-jb4FsxCbJM3a4t2pBXI6","provider":"GMICloud","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862718,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":141,"completion_tokens":9,"total_tokens":150,"cost":0.00003465,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.00002115,"upstream_inference_completions_cost":0.0000135},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0}}}
+      data: {"id":"gen-1765450148-ryE7UAQTZkBmJUJaEF6T","provider":"SiliconFlow","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450148,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":141,"completion_tokens":9,"total_tokens":150,"cost":0.00003234,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.00001974,"upstream_inference_completions_cost":0.0000126},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0}}}
 
       data: [DONE]
 
@@ -45,15 +45,15 @@ interactions:
       - text/event-stream
     status: 200 OK
     code: 200
-    duration: 564.753209ms
+    duration: 2.989851042s
 - id: 1
   request:
     proto: HTTP/1.1
     proto_major: 1
     proto_minor: 1
-    content_length: 49940
+    content_length: 50368
     host: ""

internal/agent/testdata/TestCoderAgent/openrouter-kimi-k2/write_tool.yaml πŸ”—

@@ -24,37 +24,25 @@ interactions:
     proto_minor: 0
     content_length: -1
     body: |+
-      data: {"id":"gen-1764862816-GgtH2XwpV5p6yJl1bP7d","provider":"AtlasCloud","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862816,"choices":[{"index":0,"delta":{"role":"assistant","content":"Create"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+      data: {"id":"gen-1765450247-TGHyRmlHv3hcgx1rGLqM","provider":"Chutes","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450247,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
 
-      data: {"id":"gen-1764862816-GgtH2XwpV5p6yJl1bP7d","provider":"AtlasCloud","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862816,"choices":[{"index":0,"delta":{"role":"assistant","content":" config"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+      data: {"id":"gen-1765450247-TGHyRmlHv3hcgx1rGLqM","provider":"Chutes","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450247,"choices":[{"index":0,"delta":{"role":"assistant","content":"Create"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
 
-      data: {"id":"gen-1764862816-GgtH2XwpV5p6yJl1bP7d","provider":"AtlasCloud","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862816,"choices":[{"index":0,"delta":{"role":"assistant","content":".json"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+      data: {"id":"gen-1765450247-TGHyRmlHv3hcgx1rGLqM","provider":"Chutes","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450247,"choices":[{"index":0,"delta":{"role":"assistant","content":" config"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
 
-      data: {"id":"gen-1764862816-GgtH2XwpV5p6yJl1bP7d","provider":"AtlasCloud","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862816,"choices":[{"index":0,"delta":{"role":"assistant","content":" with"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+      data: {"id":"gen-1765450247-TGHyRmlHv3hcgx1rGLqM","provider":"Chutes","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450247,"choices":[{"index":0,"delta":{"role":"assistant","content":".json"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
 
-      data: {"id":"gen-1764862816-GgtH2XwpV5p6yJl1bP7d","provider":"AtlasCloud","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862816,"choices":[{"index":0,"delta":{"role":"assistant","content":" test"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+      data: {"id":"gen-1765450247-TGHyRmlHv3hcgx1rGLqM","provider":"Chutes","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450247,"choices":[{"index":0,"delta":{"role":"assistant","content":" with"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
 
-      data: {"id":"gen-1764862816-GgtH2XwpV5p6yJl1bP7d","provider":"AtlasCloud","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862816,"choices":[{"index":0,"delta":{"role":"assistant","content":" name"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+      data: {"id":"gen-1765450247-TGHyRmlHv3hcgx1rGLqM","provider":"Chutes","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450247,"choices":[{"index":0,"delta":{"role":"assistant","content":" sample"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
 
-      data: {"id":"gen-1764862816-GgtH2XwpV5p6yJl1bP7d","provider":"AtlasCloud","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862816,"choices":[{"index":0,"delta":{"role":"assistant","content":" and"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+      data: {"id":"gen-1765450247-TGHyRmlHv3hcgx1rGLqM","provider":"Chutes","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450247,"choices":[{"index":0,"delta":{"role":"assistant","content":" JSON"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
 
-      data: {"id":"gen-1764862816-GgtH2XwpV5p6yJl1bP7d","provider":"AtlasCloud","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862816,"choices":[{"index":0,"delta":{"role":"assistant","content":" version"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+      data: {"id":"gen-1765450247-TGHyRmlHv3hcgx1rGLqM","provider":"Chutes","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450247,"choices":[{"index":0,"delta":{"role":"assistant","content":" content"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
 
-      data: {"id":"gen-1764862816-GgtH2XwpV5p6yJl1bP7d","provider":"AtlasCloud","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862816,"choices":[{"index":0,"delta":{"role":"assistant","content":" "},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+      data: {"id":"gen-1765450247-TGHyRmlHv3hcgx1rGLqM","provider":"Chutes","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450247,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":"stop","native_finish_reason":"stop","logprobs":null}]}
 
-      data: {"id":"gen-1764862816-GgtH2XwpV5p6yJl1bP7d","provider":"AtlasCloud","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862816,"choices":[{"index":0,"delta":{"role":"assistant","content":"1"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
-
-      data: {"id":"gen-1764862816-GgtH2XwpV5p6yJl1bP7d","provider":"AtlasCloud","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862816,"choices":[{"index":0,"delta":{"role":"assistant","content":"."},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
-
-      data: {"id":"gen-1764862816-GgtH2XwpV5p6yJl1bP7d","provider":"AtlasCloud","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862816,"choices":[{"index":0,"delta":{"role":"assistant","content":"0"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
-
-      data: {"id":"gen-1764862816-GgtH2XwpV5p6yJl1bP7d","provider":"AtlasCloud","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862816,"choices":[{"index":0,"delta":{"role":"assistant","content":"."},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
-
-      data: {"id":"gen-1764862816-GgtH2XwpV5p6yJl1bP7d","provider":"AtlasCloud","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862816,"choices":[{"index":0,"delta":{"role":"assistant","content":"0"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
-
-      data: {"id":"gen-1764862816-GgtH2XwpV5p6yJl1bP7d","provider":"AtlasCloud","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862816,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":"stop","native_finish_reason":"stop","logprobs":null}]}
-
-      data: {"id":"gen-1764862816-GgtH2XwpV5p6yJl1bP7d","provider":"AtlasCloud","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1764862816,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":155,"completion_tokens":15,"total_tokens":170,"cost":0.00004575,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.00002325,"upstream_inference_completions_cost":0.0000225},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0}}}
+      data: {"id":"gen-1765450247-TGHyRmlHv3hcgx1rGLqM","provider":"Chutes","model":"qwen/qwen3-next-80b-a3b-instruct","object":"chat.completion.chunk","created":1765450247,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":155,"completion_tokens":8,"total_tokens":163,"cost":0.0000219,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.0000155,"upstream_inference_completions_cost":0.0000064},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0}}}
 
       data: [DONE]
 
@@ -63,15 +51,15 @@ interactions:
       - text/event-stream
     status: 200 OK
     code: 200
-    duration: 1.202398292s
+    duration: 866.552792ms
 - id: 1
   request:
     proto: HTTP/1.1
     proto_major: 1
     proto_minor: 1
-    content_length: 49977
+    content_length: 50405
     host: ""

internal/agent/testdata/TestCoderAgent/zai-glm4.6/bash_tool.yaml πŸ”—

@@ -24,19 +24,21 @@ interactions:
     proto_minor: 0
     content_length: -1
     body: |+
-      data: {"id":"2025120423410393d676a9732447b6","created":1764862863,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"\n"}}]}
+      data: {"id":"20251211185119a522591d9348495e","created":1765450279,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"\n"}}]}
 
-      data: {"id":"2025120423410393d676a9732447b6","created":1764862863,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":"Create"}}]}
+      data: {"id":"20251211185119a522591d9348495e","created":1765450279,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":"Create"}}]}
 
-      data: {"id":"2025120423410393d676a9732447b6","created":1764862863,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":" file"}}]}
+      data: {"id":"20251211185119a522591d9348495e","created":1765450279,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":" test"}}]}
 
-      data: {"id":"2025120423410393d676a9732447b6","created":1764862863,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":" with"}}]}
+      data: {"id":"20251211185119a522591d9348495e","created":1765450279,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":".txt"}}]}
 
-      data: {"id":"2025120423410393d676a9732447b6","created":1764862863,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":" bash"}}]}
+      data: {"id":"20251211185119a522591d9348495e","created":1765450279,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":" with"}}]}
 
-      data: {"id":"2025120423410393d676a9732447b6","created":1764862863,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":" content"}}]}
+      data: {"id":"20251211185119a522591d9348495e","created":1765450279,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":" bash"}}]}
 
-      data: {"id":"2025120423410393d676a9732447b6","created":1764862863,"model":"glm-4.5-air","choices":[{"index":0,"finish_reason":"stop","delta":{"role":"assistant","content":""}}],"usage":{"prompt_tokens":140,"completion_tokens":9,"total_tokens":149,"prompt_tokens_details":{"cached_tokens":114}}}
+      data: {"id":"20251211185119a522591d9348495e","created":1765450279,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":" hello"}}]}
+
+      data: {"id":"20251211185119a522591d9348495e","created":1765450279,"model":"glm-4.5-air","choices":[{"index":0,"finish_reason":"stop","delta":{"role":"assistant","content":""}}],"usage":{"prompt_tokens":140,"completion_tokens":10,"total_tokens":150,"prompt_tokens_details":{"cached_tokens":4}}}
 
       data: [DONE]
 
@@ -45,15 +47,15 @@ interactions:
       - text/event-stream;charset=UTF-8
     status: 200 OK
     code: 200
-    duration: 922.675792ms
+    duration: 1.094726334s
 - id: 1
   request:
     proto: HTTP/1.1
     proto_major: 1
     proto_minor: 1
-    content_length: 49838
+    content_length: 50229
     host: ""

internal/agent/testdata/TestCoderAgent/zai-glm4.6/download_tool.yaml πŸ”—

@@ -24,21 +24,19 @@ interactions:
     proto_minor: 0
     content_length: -1
     body: |+
-      data: {"id":"202512042341103a97970f105f4cdc","created":1764862870,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"\n"}}]}
+      data: {"id":"20251211185124c68048d96253469c","created":1765450284,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"\n"}}]}
 
-      data: {"id":"202512042341103a97970f105f4cdc","created":1764862870,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":"Download"}}]}
+      data: {"id":"20251211185124c68048d96253469c","created":1765450284,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":"Download"}}]}
 
-      data: {"id":"202512042341103a97970f105f4cdc","created":1764862870,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":" and"}}]}
+      data: {"id":"20251211185124c68048d96253469c","created":1765450284,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":" example"}}]}
 
-      data: {"id":"202512042341103a97970f105f4cdc","created":1764862870,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":" save"}}]}
+      data: {"id":"20251211185124c68048d96253469c","created":1765450284,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":".txt"}}]}
 
-      data: {"id":"202512042341103a97970f105f4cdc","created":1764862870,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":" example"}}]}
+      data: {"id":"20251211185124c68048d96253469c","created":1765450284,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":" from"}}]}
 
-      data: {"id":"202512042341103a97970f105f4cdc","created":1764862870,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":".txt"}}]}
+      data: {"id":"20251211185124c68048d96253469c","created":1765450284,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":" URL"}}]}
 
-      data: {"id":"202512042341103a97970f105f4cdc","created":1764862870,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":" file"}}]}
-
-      data: {"id":"202512042341103a97970f105f4cdc","created":1764862870,"model":"glm-4.5-air","choices":[{"index":0,"finish_reason":"stop","delta":{"role":"assistant","content":""}}],"usage":{"prompt_tokens":143,"completion_tokens":10,"total_tokens":153,"prompt_tokens_details":{"cached_tokens":4}}}
+      data: {"id":"20251211185124c68048d96253469c","created":1765450284,"model":"glm-4.5-air","choices":[{"index":0,"finish_reason":"stop","delta":{"role":"assistant","content":""}}],"usage":{"prompt_tokens":143,"completion_tokens":9,"total_tokens":152,"prompt_tokens_details":{"cached_tokens":4}}}
 
       data: [DONE]
 
@@ -47,15 +45,15 @@ interactions:
       - text/event-stream;charset=UTF-8
     status: 200 OK
     code: 200
-    duration: 854.211792ms
+    duration: 1.570323542s
 - id: 1
   request:
     proto: HTTP/1.1
     proto_major: 1
     proto_minor: 1
-    content_length: 49863
+    content_length: 50254
     host: ""

internal/agent/testdata/TestCoderAgent/zai-glm4.6/fetch_tool.yaml πŸ”—

@@ -6,9 +6,9 @@ interactions:
     proto: HTTP/1.1
     proto_major: 1
     proto_minor: 1
-    content_length: 799
+    content_length: 50272
     host: ""
-    body: '{"messages":[{"content":"you will generate a short title based on the first message a user begins a conversation with\n\n<rules>\n- ensure it is not more than 50 characters long\n- the title should be a summary of the user''s message\n- it should be one line long\n- do not use quotes or colons\n- the entire text you return will be used as the title\n- never return anything that is more than one sentence (one line) long\n</rules>\n\n /no_think","role":"system"},{"content":"Generate a concise title for the following content:\n\nfetch the content from https://example-files.online-convert.com/website/html/example.html and tell me if it contains the word ''John Doe''\n <think>\n\n</think>","role":"user"}],"model":"glm-4.5-air","max_tokens":40,"stream_options":{"include_usage":true},"stream":true}'

internal/agent/testdata/TestCoderAgent/zai-glm4.6/glob_tool.yaml πŸ”—

@@ -24,19 +24,19 @@ interactions:
     proto_minor: 0
     content_length: -1
     body: |+
-      data: {"id":"202512042341213988a2cd7dc64fce","created":1764862881,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"\n"}}]}
+      data: {"id":"20251211185134ebd9fa28ccd3461c","created":1765450294,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"\n"}}]}
 
-      data: {"id":"202512042341213988a2cd7dc64fce","created":1764862881,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":"Find"}}]}
+      data: {"id":"20251211185134ebd9fa28ccd3461c","created":1765450294,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":"Find"}}]}
 
-      data: {"id":"202512042341213988a2cd7dc64fce","created":1764862881,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":" Go"}}]}
+      data: {"id":"20251211185134ebd9fa28ccd3461c","created":1765450294,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":" Go"}}]}
 
-      data: {"id":"202512042341213988a2cd7dc64fce","created":1764862881,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":" files"}}]}
+      data: {"id":"20251211185134ebd9fa28ccd3461c","created":1765450294,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":" files"}}]}
 
-      data: {"id":"202512042341213988a2cd7dc64fce","created":1764862881,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":" with"}}]}
+      data: {"id":"20251211185134ebd9fa28ccd3461c","created":1765450294,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":" with"}}]}
 
-      data: {"id":"202512042341213988a2cd7dc64fce","created":1764862881,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":" glob"}}]}
+      data: {"id":"20251211185134ebd9fa28ccd3461c","created":1765450294,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":" glob"}}]}
 
-      data: {"id":"202512042341213988a2cd7dc64fce","created":1764862881,"model":"glm-4.5-air","choices":[{"index":0,"finish_reason":"stop","delta":{"role":"assistant","content":""}}],"usage":{"prompt_tokens":132,"completion_tokens":9,"total_tokens":141,"prompt_tokens_details":{"cached_tokens":115}}}
+      data: {"id":"20251211185134ebd9fa28ccd3461c","created":1765450294,"model":"glm-4.5-air","choices":[{"index":0,"finish_reason":"stop","delta":{"role":"assistant","content":""}}],"usage":{"prompt_tokens":132,"completion_tokens":9,"total_tokens":141,"prompt_tokens_details":{"cached_tokens":114}}}
 
       data: [DONE]
 
@@ -45,15 +45,15 @@ interactions:
       - text/event-stream;charset=UTF-8
     status: 200 OK
     code: 200
-    duration: 1.252965458s
+    duration: 981.48325ms
 - id: 1
   request:
     proto: HTTP/1.1
     proto_major: 1
     proto_minor: 1
-    content_length: 49799
+    content_length: 50190
     host: ""

internal/agent/testdata/TestCoderAgent/zai-glm4.6/grep_tool.yaml πŸ”—

@@ -24,19 +24,19 @@ interactions:
     proto_minor: 0
     content_length: -1
     body: |+
-      data: {"id":"202512042341297e6b7b9f2a4448e6","created":1764862889,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"\n"}}]}
+      data: {"id":"202512111851385170504ea0874cc3","created":1765450299,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"\n"}}]}
 
-      data: {"id":"202512042341297e6b7b9f2a4448e6","created":1764862889,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":"grep"}}]}
+      data: {"id":"202512111851385170504ea0874cc3","created":1765450299,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":"grep"}}]}
 
-      data: {"id":"202512042341297e6b7b9f2a4448e6","created":1764862889,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":" package"}}]}
+      data: {"id":"202512111851385170504ea0874cc3","created":1765450299,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":" package"}}]}
 
-      data: {"id":"202512042341297e6b7b9f2a4448e6","created":1764862889,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":" in"}}]}
+      data: {"id":"202512111851385170504ea0874cc3","created":1765450299,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":" in"}}]}
 
-      data: {"id":"202512042341297e6b7b9f2a4448e6","created":1764862889,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":" go"}}]}
+      data: {"id":"202512111851385170504ea0874cc3","created":1765450299,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":" go"}}]}
 
-      data: {"id":"202512042341297e6b7b9f2a4448e6","created":1764862889,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":" files"}}]}
+      data: {"id":"202512111851385170504ea0874cc3","created":1765450299,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":" files"}}]}
 
-      data: {"id":"202512042341297e6b7b9f2a4448e6","created":1764862889,"model":"glm-4.5-air","choices":[{"index":0,"finish_reason":"stop","delta":{"role":"assistant","content":""}}],"usage":{"prompt_tokens":133,"completion_tokens":9,"total_tokens":142,"prompt_tokens_details":{"cached_tokens":115}}}
+      data: {"id":"202512111851385170504ea0874cc3","created":1765450299,"model":"glm-4.5-air","choices":[{"index":0,"finish_reason":"stop","delta":{"role":"assistant","content":""}}],"usage":{"prompt_tokens":133,"completion_tokens":9,"total_tokens":142,"prompt_tokens_details":{"cached_tokens":4}}}
 
       data: [DONE]
 
@@ -45,15 +45,15 @@ interactions:
       - text/event-stream;charset=UTF-8
     status: 200 OK
     code: 200
-    duration: 1.198325875s
+    duration: 855.234292ms
 - id: 1
   request:
     proto: HTTP/1.1
     proto_major: 1
     proto_minor: 1
-    content_length: 49797
+    content_length: 50188
     host: ""

internal/agent/testdata/TestCoderAgent/zai-glm4.6/ls_tool.yaml πŸ”—

@@ -24,17 +24,19 @@ interactions:
     proto_minor: 0
     content_length: -1
     body: |+
-      data: {"id":"202512042341454118f616a5d04018","created":1764862905,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"\n"}}]}
+      data: {"id":"202512111851434c38af7cd171421e","created":1765450303,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"\n"}}]}
 
-      data: {"id":"202512042341454118f616a5d04018","created":1764862905,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":"Listing"}}]}
+      data: {"id":"202512111851434c38af7cd171421e","created":1765450303,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":"List"}}]}
 
-      data: {"id":"202512042341454118f616a5d04018","created":1764862905,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":" Files"}}]}
+      data: {"id":"202512111851434c38af7cd171421e","created":1765450303,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":" files"}}]}
 
-      data: {"id":"202512042341454118f616a5d04018","created":1764862905,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":" with"}}]}
+      data: {"id":"202512111851434c38af7cd171421e","created":1765450303,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":" with"}}]}
 
-      data: {"id":"202512042341454118f616a5d04018","created":1764862905,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":" ls"}}]}
+      data: {"id":"202512111851434c38af7cd171421e","created":1765450303,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":" ls"}}]}
 
-      data: {"id":"202512042341454118f616a5d04018","created":1764862905,"model":"glm-4.5-air","choices":[{"index":0,"finish_reason":"stop","delta":{"role":"assistant","content":""}}],"usage":{"prompt_tokens":130,"completion_tokens":8,"total_tokens":138,"prompt_tokens_details":{"cached_tokens":114}}}
+      data: {"id":"202512111851434c38af7cd171421e","created":1765450303,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":" command"}}]}
+
+      data: {"id":"202512111851434c38af7cd171421e","created":1765450303,"model":"glm-4.5-air","choices":[{"index":0,"finish_reason":"stop","delta":{"role":"assistant","content":""}}],"usage":{"prompt_tokens":130,"completion_tokens":9,"total_tokens":139,"prompt_tokens_details":{"cached_tokens":115}}}
 
       data: [DONE]
 
@@ -43,15 +45,15 @@ interactions:
       - text/event-stream;charset=UTF-8
     status: 200 OK
     code: 200
-    duration: 1.516923042s
+    duration: 1.021628709s
 - id: 1
   request:
     proto: HTTP/1.1
     proto_major: 1
     proto_minor: 1
-    content_length: 49791
+    content_length: 50182
     host: ""

internal/agent/testdata/TestCoderAgent/zai-glm4.6/multiedit_tool.yaml πŸ”—

@@ -24,21 +24,21 @@ interactions:
     proto_minor: 0
     content_length: -1
     body: |+
-      data: {"id":"202512042341493c3bdbdd7a5c4a70","created":1764862909,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"\n"}}]}
+      data: {"id":"20251211185203f1688fa8b72643cb","created":1765450323,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"\n"}}]}
 
-      data: {"id":"202512042341493c3bdbdd7a5c4a70","created":1764862909,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":"Mult"}}]}
+      data: {"id":"20251211185203f1688fa8b72643cb","created":1765450323,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":"Mult"}}]}
 
-      data: {"id":"202512042341493c3bdbdd7a5c4a70","created":1764862909,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":"ied"}}]}
+      data: {"id":"20251211185203f1688fa8b72643cb","created":1765450323,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":"ied"}}]}
 
-      data: {"id":"202512042341493c3bdbdd7a5c4a70","created":1764862909,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":"it"}}]}
+      data: {"id":"20251211185203f1688fa8b72643cb","created":1765450323,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":"it"}}]}
 
-      data: {"id":"202512042341493c3bdbdd7a5c4a70","created":1764862909,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":" Go"}}]}
+      data: {"id":"20251211185203f1688fa8b72643cb","created":1765450323,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":" main"}}]}
 
-      data: {"id":"202512042341493c3bdbdd7a5c4a70","created":1764862909,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":" code"}}]}
+      data: {"id":"20251211185203f1688fa8b72643cb","created":1765450323,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":".go"}}]}
 
-      data: {"id":"202512042341493c3bdbdd7a5c4a70","created":1764862909,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":" modification"}}]}
+      data: {"id":"20251211185203f1688fa8b72643cb","created":1765450323,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":" changes"}}]}
 
-      data: {"id":"202512042341493c3bdbdd7a5c4a70","created":1764862909,"model":"glm-4.5-air","choices":[{"index":0,"finish_reason":"stop","delta":{"role":"assistant","content":""}}],"usage":{"prompt_tokens":153,"completion_tokens":10,"total_tokens":163,"prompt_tokens_details":{"cached_tokens":114}}}
+      data: {"id":"20251211185203f1688fa8b72643cb","created":1765450323,"model":"glm-4.5-air","choices":[{"index":0,"finish_reason":"stop","delta":{"role":"assistant","content":""}}],"usage":{"prompt_tokens":153,"completion_tokens":10,"total_tokens":163,"prompt_tokens_details":{"cached_tokens":4}}}
 
       data: [DONE]
 
@@ -47,15 +47,15 @@ interactions:
       - text/event-stream;charset=UTF-8
     status: 200 OK
     code: 200
-    duration: 1.209176375s
+    duration: 845.8035ms
 - id: 1
   request:
     proto: HTTP/1.1
     proto_major: 1
     proto_minor: 1
-    content_length: 49877
+    content_length: 50268
     host: ""

internal/agent/testdata/TestCoderAgent/zai-glm4.6/parallel_tool_calls.yaml πŸ”—

@@ -24,19 +24,19 @@ interactions:
     proto_minor: 0
     content_length: -1
     body: |+
-      data: {"id":"20251204234208ed241fdb1ad14397","created":1764862928,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"\n"}}]}
+      data: {"id":"2025121118522536db54c7dd194969","created":1765450345,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"\n"}}]}
 
-      data: {"id":"20251204234208ed241fdb1ad14397","created":1764862928,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":"Parallel"}}]}
+      data: {"id":"2025121118522536db54c7dd194969","created":1765450345,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":"Parallel"}}]}
 
-      data: {"id":"20251204234208ed241fdb1ad14397","created":1764862928,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":" glob"}}]}
+      data: {"id":"2025121118522536db54c7dd194969","created":1765450345,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":" glob"}}]}
 
-      data: {"id":"20251204234208ed241fdb1ad14397","created":1764862928,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":" and"}}]}
+      data: {"id":"2025121118522536db54c7dd194969","created":1765450345,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":" and"}}]}
 
-      data: {"id":"20251204234208ed241fdb1ad14397","created":1764862928,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":" ls"}}]}
+      data: {"id":"2025121118522536db54c7dd194969","created":1765450345,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":" ls"}}]}
 
-      data: {"id":"20251204234208ed241fdb1ad14397","created":1764862928,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":" commands"}}]}
+      data: {"id":"2025121118522536db54c7dd194969","created":1765450345,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":" commands"}}]}
 
-      data: {"id":"20251204234208ed241fdb1ad14397","created":1764862928,"model":"glm-4.5-air","choices":[{"index":0,"finish_reason":"stop","delta":{"role":"assistant","content":""}}],"usage":{"prompt_tokens":149,"completion_tokens":9,"total_tokens":158,"prompt_tokens_details":{"cached_tokens":115}}}
+      data: {"id":"2025121118522536db54c7dd194969","created":1765450345,"model":"glm-4.5-air","choices":[{"index":0,"finish_reason":"stop","delta":{"role":"assistant","content":""}}],"usage":{"prompt_tokens":149,"completion_tokens":9,"total_tokens":158,"prompt_tokens_details":{"cached_tokens":122}}}
 
       data: [DONE]
 
@@ -45,15 +45,15 @@ interactions:
       - text/event-stream;charset=UTF-8
     status: 200 OK
     code: 200
-    duration: 1.525775667s
+    duration: 1.506124709s
 - id: 1
   request:
     proto: HTTP/1.1
     proto_major: 1
     proto_minor: 1
-    content_length: 49888
+    content_length: 50279
     host: ""

internal/agent/testdata/TestCoderAgent/zai-glm4.6/simple_test.yaml πŸ”—

@@ -24,15 +24,11 @@ interactions:
     proto_minor: 0
     content_length: -1
     body: |+
-      data: {"id":"20251204234038cdbbcc1a7bc04983","created":1764862839,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"\n"}}]}
+      data: {"id":"20251211185103d5d62a07ff31425d","created":1765450263,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"\n"}}]}
 
-      data: {"id":"20251204234038cdbbcc1a7bc04983","created":1764862839,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":"G"}}]}
+      data: {"id":"20251211185103d5d62a07ff31425d","created":1765450263,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":"Hello"}}]}
 
-      data: {"id":"20251204234038cdbbcc1a7bc04983","created":1764862839,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":"reeting"}}]}
-
-      data: {"id":"20251204234038cdbbcc1a7bc04983","created":1764862839,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":" Message"}}]}
-
-      data: {"id":"20251204234038cdbbcc1a7bc04983","created":1764862839,"model":"glm-4.5-air","choices":[{"index":0,"finish_reason":"stop","delta":{"role":"assistant","content":""}}],"usage":{"prompt_tokens":121,"completion_tokens":7,"total_tokens":128,"prompt_tokens_details":{"cached_tokens":114}}}
+      data: {"id":"20251211185103d5d62a07ff31425d","created":1765450263,"model":"glm-4.5-air","choices":[{"index":0,"finish_reason":"stop","delta":{"role":"assistant","content":""}}],"usage":{"prompt_tokens":121,"completion_tokens":5,"total_tokens":126,"prompt_tokens_details":{"cached_tokens":4}}}
 
       data: [DONE]
 
@@ -41,15 +37,15 @@ interactions:
       - text/event-stream;charset=UTF-8
     status: 200 OK
     code: 200
-    duration: 1.15517175s
+    duration: 1.195221292s
 - id: 1
   request:
     proto: HTTP/1.1
     proto_major: 1
     proto_minor: 1
-    content_length: 49751
+    content_length: 50142
     host: ""

internal/agent/testdata/TestCoderAgent/zai-glm4.6/sourcegraph_tool.yaml πŸ”—

@@ -24,21 +24,21 @@ interactions:
     proto_minor: 0
     content_length: -1
     body: |+
-      data: {"id":"2025120423415738fbac8fe26e406b","created":1764862917,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"\n"}}]}
+      data: {"id":"20251211185211c6f3ee23be6f4036","created":1765450331,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"\n"}}]}
 
-      data: {"id":"2025120423415738fbac8fe26e406b","created":1764862917,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":"Search"}}]}
+      data: {"id":"20251211185211c6f3ee23be6f4036","created":1765450331,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":"Search"}}]}
 
-      data: {"id":"2025120423415738fbac8fe26e406b","created":1764862917,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":" Go"}}]}
+      data: {"id":"20251211185211c6f3ee23be6f4036","created":1765450331,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":" Go"}}]}
 
-      data: {"id":"2025120423415738fbac8fe26e406b","created":1764862917,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":" repos"}}]}
+      data: {"id":"20251211185211c6f3ee23be6f4036","created":1765450331,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":" repos"}}]}
 
-      data: {"id":"2025120423415738fbac8fe26e406b","created":1764862917,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":" with"}}]}
+      data: {"id":"20251211185211c6f3ee23be6f4036","created":1765450331,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":" with"}}]}
 
-      data: {"id":"2025120423415738fbac8fe26e406b","created":1764862917,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":" Source"}}]}
+      data: {"id":"20251211185211c6f3ee23be6f4036","created":1765450331,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":" Source"}}]}
 
-      data: {"id":"2025120423415738fbac8fe26e406b","created":1764862917,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":"graph"}}]}
+      data: {"id":"20251211185211c6f3ee23be6f4036","created":1765450331,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":"graph"}}]}
 
-      data: {"id":"2025120423415738fbac8fe26e406b","created":1764862917,"model":"glm-4.5-air","choices":[{"index":0,"finish_reason":"stop","delta":{"role":"assistant","content":""}}],"usage":{"prompt_tokens":133,"completion_tokens":10,"total_tokens":143,"prompt_tokens_details":{"cached_tokens":115}}}
+      data: {"id":"20251211185211c6f3ee23be6f4036","created":1765450331,"model":"glm-4.5-air","choices":[{"index":0,"finish_reason":"stop","delta":{"role":"assistant","content":""}}],"usage":{"prompt_tokens":133,"completion_tokens":10,"total_tokens":143,"prompt_tokens_details":{"cached_tokens":115}}}
 
       data: [DONE]
 
@@ -47,15 +47,15 @@ interactions:
       - text/event-stream;charset=UTF-8
     status: 200 OK
     code: 200
-    duration: 1.250413708s
+    duration: 875.558166ms
 - id: 1
   request:
     proto: HTTP/1.1
     proto_major: 1
     proto_minor: 1
-    content_length: 49811
+    content_length: 50202
     host: ""

internal/agent/testdata/TestCoderAgent/zai-glm4.6/update_a_file.yaml πŸ”—

@@ -24,21 +24,25 @@ interactions:
     proto_minor: 0
     content_length: -1
     body: |+
-      data: {"id":"2025120423405085f5f6c62186420b","created":1764862850,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"\n"}}]}
+      data: {"id":"20251211185111270976ba1e5441c9","created":1765450271,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"\n"}}]}
 
-      data: {"id":"2025120423405085f5f6c62186420b","created":1764862850,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":"Update"}}]}
+      data: {"id":"20251211185111270976ba1e5441c9","created":1765450271,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":"Update"}}]}
 
-      data: {"id":"2025120423405085f5f6c62186420b","created":1764862850,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":" main"}}]}
+      data: {"id":"20251211185111270976ba1e5441c9","created":1765450271,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":" main"}}]}
 
-      data: {"id":"2025120423405085f5f6c62186420b","created":1764862850,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":".go"}}]}
+      data: {"id":"20251211185111270976ba1e5441c9","created":1765450271,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":".go"}}]}
 
-      data: {"id":"2025120423405085f5f6c62186420b","created":1764862850,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":" with"}}]}
+      data: {"id":"20251211185111270976ba1e5441c9","created":1765450271,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":" to"}}]}
 
-      data: {"id":"2025120423405085f5f6c62186420b","created":1764862850,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":" hello"}}]}
+      data: {"id":"20251211185111270976ba1e5441c9","created":1765450271,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":" print"}}]}
 
-      data: {"id":"2025120423405085f5f6c62186420b","created":1764862850,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":" message"}}]}
+      data: {"id":"20251211185111270976ba1e5441c9","created":1765450271,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":" hello"}}]}
 
-      data: {"id":"2025120423405085f5f6c62186420b","created":1764862850,"model":"glm-4.5-air","choices":[{"index":0,"finish_reason":"stop","delta":{"role":"assistant","content":""}}],"usage":{"prompt_tokens":134,"completion_tokens":10,"total_tokens":144,"prompt_tokens_details":{"cached_tokens":114}}}
+      data: {"id":"20251211185111270976ba1e5441c9","created":1765450271,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":" from"}}]}
+
+      data: {"id":"20251211185111270976ba1e5441c9","created":1765450271,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":" crush"}}]}
+
+      data: {"id":"20251211185111270976ba1e5441c9","created":1765450271,"model":"glm-4.5-air","choices":[{"index":0,"finish_reason":"stop","delta":{"role":"assistant","content":""}}],"usage":{"prompt_tokens":134,"completion_tokens":12,"total_tokens":146,"prompt_tokens_details":{"cached_tokens":114}}}
 
       data: [DONE]
 
@@ -47,15 +51,15 @@ interactions:
       - text/event-stream;charset=UTF-8
     status: 200 OK
     code: 200
-    duration: 1.561432209s
+    duration: 812.292167ms
 - id: 1
   request:
     proto: HTTP/1.1
     proto_major: 1
     proto_minor: 1
-    content_length: 49817
+    content_length: 50208
     host: ""

internal/agent/testdata/TestCoderAgent/zai-glm4.6/write_tool.yaml πŸ”—

@@ -24,21 +24,23 @@ interactions:
     proto_minor: 0
     content_length: -1
     body: |+
-      data: {"id":"202512042342030bfb852a91a24793","created":1764862923,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"\n"}}]}
+      data: {"id":"2025121118521783ded8f44859400f","created":1765450337,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"\n"}}]}
 
-      data: {"id":"202512042342030bfb852a91a24793","created":1764862923,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":"Create"}}]}
+      data: {"id":"2025121118521783ded8f44859400f","created":1765450337,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":"Create"}}]}
 
-      data: {"id":"202512042342030bfb852a91a24793","created":1764862923,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":" config"}}]}
+      data: {"id":"2025121118521783ded8f44859400f","created":1765450337,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":" config"}}]}
 
-      data: {"id":"202512042342030bfb852a91a24793","created":1764862923,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":".json"}}]}
+      data: {"id":"2025121118521783ded8f44859400f","created":1765450337,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":".json"}}]}
 
-      data: {"id":"202512042342030bfb852a91a24793","created":1764862923,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":" with"}}]}
+      data: {"id":"2025121118521783ded8f44859400f","created":1765450337,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":" file"}}]}
 
-      data: {"id":"202512042342030bfb852a91a24793","created":1764862923,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":" specific"}}]}
+      data: {"id":"2025121118521783ded8f44859400f","created":1765450337,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":" with"}}]}
 
-      data: {"id":"202512042342030bfb852a91a24793","created":1764862923,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":" content"}}]}
+      data: {"id":"2025121118521783ded8f44859400f","created":1765450337,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":" JSON"}}]}
 
-      data: {"id":"202512042342030bfb852a91a24793","created":1764862923,"model":"glm-4.5-air","choices":[{"index":0,"finish_reason":"stop","delta":{"role":"assistant","content":""}}],"usage":{"prompt_tokens":148,"completion_tokens":10,"total_tokens":158,"prompt_tokens_details":{"cached_tokens":115}}}
+      data: {"id":"2025121118521783ded8f44859400f","created":1765450337,"model":"glm-4.5-air","choices":[{"index":0,"delta":{"role":"assistant","content":" content"}}]}
+
+      data: {"id":"2025121118521783ded8f44859400f","created":1765450337,"model":"glm-4.5-air","choices":[{"index":0,"finish_reason":"stop","delta":{"role":"assistant","content":""}}],"usage":{"prompt_tokens":148,"completion_tokens":11,"total_tokens":159,"prompt_tokens_details":{"cached_tokens":115}}}
 
       data: [DONE]
 
@@ -47,15 +49,15 @@ interactions:
       - text/event-stream;charset=UTF-8
     status: 200 OK
     code: 200
-    duration: 1.199529708s
+    duration: 1.380565417s
 - id: 1
   request:
     proto: HTTP/1.1
     proto_major: 1
     proto_minor: 1
-    content_length: 49854
+    content_length: 50245
     host: ""

internal/agent/tools/ls.go πŸ”—

@@ -98,7 +98,7 @@ func NewLsTool(permissions permission.Service, workingDir string, lsConfig confi
 
 			output, metadata, err := ListDirectoryTree(searchPath, params, lsConfig)
 			if err != nil {
-				return fantasy.NewTextErrorResponse(err.Error()), err
+				return fantasy.NewTextErrorResponse(err.Error()), nil
 			}
 
 			return fantasy.WithResponseMetadata(

internal/agent/tools/todos.go πŸ”—

@@ -0,0 +1,134 @@
+package tools
+
+import (
+	"context"
+	_ "embed"
+	"fmt"
+
+	"charm.land/fantasy"
+	"github.com/charmbracelet/crush/internal/session"
+)
+
+//go:embed todos.md
+var todosDescription []byte
+
+const TodosToolName = "todos"
+
+type TodosParams struct {
+	Todos []TodoItem `json:"todos" description:"The updated todo list"`
+}
+
+type TodoItem struct {
+	Content    string `json:"content" description:"What needs to be done (imperative form)"`
+	Status     string `json:"status" description:"Task status: pending, in_progress, or completed"`
+	ActiveForm string `json:"active_form" description:"Present continuous form (e.g., 'Running tests')"`
+}
+
+type TodosResponseMetadata struct {
+	IsNew         bool           `json:"is_new"`
+	Todos         []session.Todo `json:"todos"`
+	JustCompleted []string       `json:"just_completed,omitempty"`
+	JustStarted   string         `json:"just_started,omitempty"`
+	Completed     int            `json:"completed"`
+	Total         int            `json:"total"`
+}
+
+func NewTodosTool(sessions session.Service) fantasy.AgentTool {
+	return fantasy.NewAgentTool(
+		TodosToolName,
+		string(todosDescription),
+		func(ctx context.Context, params TodosParams, call fantasy.ToolCall) (fantasy.ToolResponse, error) {
+			sessionID := GetSessionFromContext(ctx)
+			if sessionID == "" {
+				return fantasy.ToolResponse{}, fmt.Errorf("session ID is required for managing todos")
+			}
+
+			currentSession, err := sessions.Get(ctx, sessionID)
+			if err != nil {
+				return fantasy.ToolResponse{}, fmt.Errorf("failed to get session: %w", err)
+			}
+
+			isNew := len(currentSession.Todos) == 0
+			oldStatusByContent := make(map[string]session.TodoStatus)
+			for _, todo := range currentSession.Todos {
+				oldStatusByContent[todo.Content] = todo.Status
+			}
+
+			for _, item := range params.Todos {
+				switch item.Status {
+				case "pending", "in_progress", "completed":
+				default:
+					return fantasy.ToolResponse{}, fmt.Errorf("invalid status %q for todo %q", item.Status, item.Content)
+				}
+			}
+
+			todos := make([]session.Todo, len(params.Todos))
+			var justCompleted []string
+			var justStarted string
+			completedCount := 0
+
+			for i, item := range params.Todos {
+				todos[i] = session.Todo{
+					Content:    item.Content,
+					Status:     session.TodoStatus(item.Status),
+					ActiveForm: item.ActiveForm,
+				}
+
+				newStatus := session.TodoStatus(item.Status)
+				oldStatus, existed := oldStatusByContent[item.Content]
+
+				if newStatus == session.TodoStatusCompleted {
+					completedCount++
+					if existed && oldStatus != session.TodoStatusCompleted {
+						justCompleted = append(justCompleted, item.Content)
+					}
+				}
+
+				if newStatus == session.TodoStatusInProgress {
+					if !existed || oldStatus != session.TodoStatusInProgress {
+						if item.ActiveForm != "" {
+							justStarted = item.ActiveForm
+						} else {
+							justStarted = item.Content
+						}
+					}
+				}
+			}
+
+			currentSession.Todos = todos
+			_, err = sessions.Save(ctx, currentSession)
+			if err != nil {
+				return fantasy.ToolResponse{}, fmt.Errorf("failed to save todos: %w", err)
+			}
+
+			response := "Todo list updated successfully.\n\n"
+
+			pendingCount := 0
+			inProgressCount := 0
+
+			for _, todo := range todos {
+				switch todo.Status {
+				case session.TodoStatusPending:
+					pendingCount++
+				case session.TodoStatusInProgress:
+					inProgressCount++
+				}
+			}
+
+			response += fmt.Sprintf("Status: %d pending, %d in progress, %d completed\n",
+				pendingCount, inProgressCount, completedCount)
+
+			response += "Todos have been modified successfully. Ensure that you continue to use the todo list to track your progress. Please proceed with the current tasks if applicable."
+
+			metadata := TodosResponseMetadata{
+				IsNew:         isNew,
+				Todos:         todos,
+				JustCompleted: justCompleted,
+				JustStarted:   justStarted,
+				Completed:     completedCount,
+				Total:         len(todos),
+			}
+
+			return fantasy.WithResponseMetadata(fantasy.NewTextResponse(response), metadata), nil
+		})
+}

internal/agent/tools/todos.md πŸ”—

@@ -0,0 +1,90 @@
+Creates and manages a structured task list for tracking progress on complex, multi-step coding tasks.
+
+<when_to_use>
+Use this tool proactively in these scenarios:
+
+- Complex multi-step tasks requiring 3+ distinct steps or actions
+- Non-trivial tasks requiring careful planning or multiple operations
+- User explicitly requests todo list management
+- User provides multiple tasks (numbered or comma-separated list)
+- After receiving new instructions to capture requirements
+- When starting work on a task (mark as in_progress BEFORE beginning)
+- After completing a task (mark completed and add new follow-up tasks)
+</when_to_use>
+
+<when_not_to_use>
+Skip this tool when:
+
+- Single, straightforward task
+- Trivial task with no organizational benefit
+- Task completable in less than 3 trivial steps
+- Purely conversational or informational request
+</when_not_to_use>
+
+<task_states>
+- **pending**: Task not yet started
+- **in_progress**: Currently working on (limit to ONE task at a time)
+- **completed**: Task finished successfully
+
+**IMPORTANT**: Each task requires two forms:
+- **content**: Imperative form describing what needs to be done (e.g., "Run tests", "Build the project")
+- **active_form**: Present continuous form shown during execution (e.g., "Running tests", "Building the project")
+</task_states>
+
+<task_management>
+- Update task status in real-time as you work
+- Mark tasks complete IMMEDIATELY after finishing (don't batch completions)
+- Exactly ONE task must be in_progress at any time (not less, not more)
+- Complete current tasks before starting new ones
+- Remove tasks that are no longer relevant from the list entirely
+</task_management>
+
+<completion_requirements>
+ONLY mark a task as completed when you have FULLY accomplished it.
+
+Never mark completed if:
+- Tests are failing
+- Implementation is partial
+- You encountered unresolved errors
+- You couldn't find necessary files or dependencies
+
+If blocked:
+- Keep task as in_progress
+- Create new task describing what needs to be resolved
+</completion_requirements>
+
+<task_breakdown>
+- Create specific, actionable items
+- Break complex tasks into smaller, manageable steps
+- Use clear, descriptive task names
+- Always provide both content and active_form
+</task_breakdown>
+
+<examples>
+βœ… Good task:
+```json
+{
+  "content": "Implement user authentication with JWT tokens",
+  "status": "in_progress",
+  "active_form": "Implementing user authentication with JWT tokens"
+}
+```
+
+❌ Bad task (missing active_form):
+```json
+{
+  "content": "Fix bug",
+  "status": "pending"
+}
+```
+</examples>
+
+<output_behavior>
+**NEVER** print or list todos in your response text. The user sees the todo list in real-time in the UI.
+</output_behavior>
+
+<tips>
+- When in doubt, use this tool - being proactive demonstrates attentiveness
+- One task in_progress at a time keeps work focused
+- Update immediately after state changes for accurate tracking
+</tips>

internal/config/load_test.go πŸ”—

@@ -487,7 +487,7 @@ func TestConfig_setupAgentsWithDisabledTools(t *testing.T) {
 	coderAgent, ok := cfg.Agents[AgentCoder]
 	require.True(t, ok)
 
-	assert.Equal(t, []string{"agent", "bash", "job_output", "job_kill", "multiedit", "lsp_diagnostics", "lsp_references", "fetch", "agentic_fetch", "glob", "ls", "sourcegraph", "view", "write"}, coderAgent.AllowedTools)
+	assert.Equal(t, []string{"agent", "bash", "job_output", "job_kill", "multiedit", "lsp_diagnostics", "lsp_references", "fetch", "agentic_fetch", "glob", "ls", "sourcegraph", "todos", "view", "write"}, coderAgent.AllowedTools)
 
 	taskAgent, ok := cfg.Agents[AgentTask]
 	require.True(t, ok)
@@ -510,7 +510,7 @@ func TestConfig_setupAgentsWithEveryReadOnlyToolDisabled(t *testing.T) {
 	cfg.SetupAgents()
 	coderAgent, ok := cfg.Agents[AgentCoder]
 	require.True(t, ok)
-	assert.Equal(t, []string{"agent", "bash", "job_output", "job_kill", "download", "edit", "multiedit", "lsp_diagnostics", "lsp_references", "fetch", "agentic_fetch", "write"}, coderAgent.AllowedTools)
+	assert.Equal(t, []string{"agent", "bash", "job_output", "job_kill", "download", "edit", "multiedit", "lsp_diagnostics", "lsp_references", "fetch", "agentic_fetch", "todos", "write"}, coderAgent.AllowedTools)
 
 	taskAgent, ok := cfg.Agents[AgentTask]
 	require.True(t, ok)

internal/db/models.go πŸ”—

@@ -42,4 +42,5 @@ type Session struct {
 	UpdatedAt        int64          `json:"updated_at"`
 	CreatedAt        int64          `json:"created_at"`
 	SummaryMessageID sql.NullString `json:"summary_message_id"`
+	Todos            sql.NullString `json:"todos"`
 }

internal/db/sessions.sql.go πŸ”—

@@ -33,7 +33,7 @@ INSERT INTO sessions (
     null,
     strftime('%s', 'now'),
     strftime('%s', 'now')
-) RETURNING id, parent_session_id, title, message_count, prompt_tokens, completion_tokens, cost, updated_at, created_at, summary_message_id
+) RETURNING id, parent_session_id, title, message_count, prompt_tokens, completion_tokens, cost, updated_at, created_at, summary_message_id, todos
 `
 
 type CreateSessionParams struct {
@@ -68,6 +68,7 @@ func (q *Queries) CreateSession(ctx context.Context, arg CreateSessionParams) (S
 		&i.UpdatedAt,
 		&i.CreatedAt,
 		&i.SummaryMessageID,
+		&i.Todos,
 	)
 	return i, err
 }
@@ -83,7 +84,7 @@ func (q *Queries) DeleteSession(ctx context.Context, id string) error {
 }
 
 const getSessionByID = `-- name: GetSessionByID :one
-SELECT id, parent_session_id, title, message_count, prompt_tokens, completion_tokens, cost, updated_at, created_at, summary_message_id
+SELECT id, parent_session_id, title, message_count, prompt_tokens, completion_tokens, cost, updated_at, created_at, summary_message_id, todos
 FROM sessions
 WHERE id = ? LIMIT 1
 `
@@ -102,12 +103,13 @@ func (q *Queries) GetSessionByID(ctx context.Context, id string) (Session, error
 		&i.UpdatedAt,
 		&i.CreatedAt,
 		&i.SummaryMessageID,
+		&i.Todos,
 	)
 	return i, err
 }
 
 const listSessions = `-- name: ListSessions :many
-SELECT id, parent_session_id, title, message_count, prompt_tokens, completion_tokens, cost, updated_at, created_at, summary_message_id
+SELECT id, parent_session_id, title, message_count, prompt_tokens, completion_tokens, cost, updated_at, created_at, summary_message_id, todos
 FROM sessions
 WHERE parent_session_id is NULL
 ORDER BY updated_at DESC
@@ -133,6 +135,7 @@ func (q *Queries) ListSessions(ctx context.Context) ([]Session, error) {
 			&i.UpdatedAt,
 			&i.CreatedAt,
 			&i.SummaryMessageID,
+			&i.Todos,
 		); err != nil {
 			return nil, err
 		}
@@ -154,9 +157,10 @@ SET
     prompt_tokens = ?,
     completion_tokens = ?,
     summary_message_id = ?,
-    cost = ?
+    cost = ?,
+    todos = ?
 WHERE id = ?
-RETURNING id, parent_session_id, title, message_count, prompt_tokens, completion_tokens, cost, updated_at, created_at, summary_message_id
+RETURNING id, parent_session_id, title, message_count, prompt_tokens, completion_tokens, cost, updated_at, created_at, summary_message_id, todos
 `
 
 type UpdateSessionParams struct {
@@ -165,6 +169,7 @@ type UpdateSessionParams struct {
 	CompletionTokens int64          `json:"completion_tokens"`
 	SummaryMessageID sql.NullString `json:"summary_message_id"`
 	Cost             float64        `json:"cost"`
+	Todos            sql.NullString `json:"todos"`
 	ID               string         `json:"id"`
 }
 
@@ -175,6 +180,7 @@ func (q *Queries) UpdateSession(ctx context.Context, arg UpdateSessionParams) (S
 		arg.CompletionTokens,
 		arg.SummaryMessageID,
 		arg.Cost,
+		arg.Todos,
 		arg.ID,
 	)
 	var i Session
@@ -189,6 +195,7 @@ func (q *Queries) UpdateSession(ctx context.Context, arg UpdateSessionParams) (S
 		&i.UpdatedAt,
 		&i.CreatedAt,
 		&i.SummaryMessageID,
+		&i.Todos,
 	)
 	return i, err
 }

internal/db/sql/sessions.sql πŸ”—

@@ -41,7 +41,8 @@ SET
     prompt_tokens = ?,
     completion_tokens = ?,
     summary_message_id = ?,
-    cost = ?
+    cost = ?,
+    todos = ?
 WHERE id = ?
 RETURNING *;
 

internal/session/session.go πŸ”—

@@ -3,7 +3,9 @@ package session
 import (
 	"context"
 	"database/sql"
+	"encoding/json"
 	"fmt"
+	"log/slog"
 	"strings"
 
 	"github.com/charmbracelet/crush/internal/db"
@@ -12,6 +14,20 @@ import (
 	"github.com/google/uuid"
 )
 
+type TodoStatus string
+
+const (
+	TodoStatusPending    TodoStatus = "pending"
+	TodoStatusInProgress TodoStatus = "in_progress"
+	TodoStatusCompleted  TodoStatus = "completed"
+)
+
+type Todo struct {
+	Content    string     `json:"content"`
+	Status     TodoStatus `json:"status"`
+	ActiveForm string     `json:"active_form"`
+}
+
 type Session struct {
 	ID               string
 	ParentSessionID  string
@@ -21,6 +37,7 @@ type Session struct {
 	CompletionTokens int64
 	SummaryMessageID string
 	Cost             float64
+	Todos            []Todo
 	CreatedAt        int64
 	UpdatedAt        int64
 }
@@ -111,6 +128,11 @@ func (s *service) Get(ctx context.Context, id string) (Session, error) {
 }
 
 func (s *service) Save(ctx context.Context, session Session) (Session, error) {
+	todosJSON, err := marshalTodos(session.Todos)
+	if err != nil {
+		return Session{}, err
+	}
+
 	dbSession, err := s.q.UpdateSession(ctx, db.UpdateSessionParams{
 		ID:               session.ID,
 		Title:            session.Title,
@@ -121,6 +143,10 @@ func (s *service) Save(ctx context.Context, session Session) (Session, error) {
 			Valid:  session.SummaryMessageID != "",
 		},
 		Cost: session.Cost,
+		Todos: sql.NullString{
+			String: todosJSON,
+			Valid:  todosJSON != "",
+		},
 	})
 	if err != nil {
 		return Session{}, err
@@ -143,6 +169,10 @@ func (s *service) List(ctx context.Context) ([]Session, error) {
 }
 
 func (s service) fromDBItem(item db.Session) Session {
+	todos, err := unmarshalTodos(item.Todos.String)
+	if err != nil {
+		slog.Error("failed to unmarshal todos", "session_id", item.ID, "error", err)
+	}
 	return Session{
 		ID:               item.ID,
 		ParentSessionID:  item.ParentSessionID.String,
@@ -152,11 +182,34 @@ func (s service) fromDBItem(item db.Session) Session {
 		CompletionTokens: item.CompletionTokens,
 		SummaryMessageID: item.SummaryMessageID.String,
 		Cost:             item.Cost,
+		Todos:            todos,
 		CreatedAt:        item.CreatedAt,
 		UpdatedAt:        item.UpdatedAt,
 	}
 }
 
+func marshalTodos(todos []Todo) (string, error) {
+	if len(todos) == 0 {
+		return "", nil
+	}
+	data, err := json.Marshal(todos)
+	if err != nil {
+		return "", err
+	}
+	return string(data), nil
+}
+
+func unmarshalTodos(data string) ([]Todo, error) {
+	if data == "" {
+		return []Todo{}, nil
+	}
+	var todos []Todo
+	if err := json.Unmarshal([]byte(data), &todos); err != nil {
+		return []Todo{}, err
+	}
+	return todos, nil
+}
+
 func NewService(q db.Querier) Service {
 	broker := pubsub.NewBroker[Session]()
 	return &service{

internal/tui/components/chat/chat.go πŸ”—

@@ -2,7 +2,6 @@ package chat
 
 import (
 	"context"
-	"strings"
 	"time"
 
 	"charm.land/bubbles/v2/key"
@@ -73,7 +72,6 @@ type messageListCmp struct {
 	lastClickX    int
 	lastClickY    int
 	clickCount    int
-	promptQueue   int
 }
 
 // New creates a new message list component with custom keybindings
@@ -104,13 +102,6 @@ func (m *messageListCmp) Init() tea.Cmd {
 // Update handles incoming messages and updates the component state.
 func (m *messageListCmp) Update(msg tea.Msg) (util.Model, tea.Cmd) {
 	var cmds []tea.Cmd
-	if m.session.ID != "" && m.app.AgentCoordinator != nil {
-		queueSize := m.app.AgentCoordinator.QueuedPrompts(m.session.ID)
-		if queueSize != m.promptQueue {
-			m.promptQueue = queueSize
-			cmds = append(cmds, m.SetSize(m.width, m.height))
-		}
-	}
 	switch msg := msg.(type) {
 	case tea.KeyPressMsg:
 		if m.listCmp.IsFocused() && m.listCmp.HasSelection() {
@@ -223,24 +214,11 @@ func (m *messageListCmp) Update(msg tea.Msg) (util.Model, tea.Cmd) {
 // View renders the message list or an initial screen if empty.
 func (m *messageListCmp) View() string {
 	t := styles.CurrentTheme()
-	height := m.height
-	if m.promptQueue > 0 {
-		height -= 4 // pill height and padding
-	}
-	view := []string{
-		t.S().Base.
-			Padding(1, 1, 0, 1).
-			Width(m.width).
-			Height(height).
-			Render(
-				m.listCmp.View(),
-			),
-	}
-	if m.app.AgentCoordinator != nil && m.promptQueue > 0 {
-		queuePill := queuePill(m.promptQueue, t)
-		view = append(view, t.S().Base.PaddingLeft(4).PaddingTop(1).Render(queuePill))
-	}
-	return strings.Join(view, "\n")
+	return t.S().Base.
+		Padding(1, 1, 0, 1).
+		Width(m.width).
+		Height(m.height).
+		Render(m.listCmp.View())
 }
 
 func (m *messageListCmp) handlePermissionRequest(permission permission.PermissionNotification) tea.Cmd {
@@ -682,11 +660,6 @@ func (m *messageListCmp) GetSize() (int, int) {
 func (m *messageListCmp) SetSize(width int, height int) tea.Cmd {
 	m.width = width
 	m.height = height
-	if m.promptQueue > 0 {
-		queueHeight := 3 + 1 // 1 for padding top
-		lHight := max(0, height-(1+queueHeight))
-		return m.listCmp.SetSize(width-2, lHight)
-	}
 	return m.listCmp.SetSize(width-2, max(0, height-1)) // for padding
 }
 

internal/tui/components/chat/editor/editor.go πŸ”—

@@ -550,7 +550,10 @@ func (c *editorCmp) IsEmpty() bool {
 func normalPromptFunc(info textarea.PromptInfo) string {
 	t := styles.CurrentTheme()
 	if info.LineNumber == 0 {
-		return "  > "
+		if info.Focused {
+			return "  > "
+		}
+		return "::: "
 	}
 	if info.Focused {
 		return t.S().Base.Foreground(t.GreenDark).Render("::: ")

internal/tui/components/chat/messages/renderer.go πŸ”—

@@ -13,6 +13,7 @@ import (
 	"github.com/charmbracelet/crush/internal/agent/tools"
 	"github.com/charmbracelet/crush/internal/ansiext"
 	"github.com/charmbracelet/crush/internal/fsext"
+	"github.com/charmbracelet/crush/internal/tui/components/chat/todos"
 	"github.com/charmbracelet/crush/internal/tui/components/core"
 	"github.com/charmbracelet/crush/internal/tui/highlight"
 	"github.com/charmbracelet/crush/internal/tui/styles"
@@ -197,6 +198,7 @@ func init() {
 	registry.register(tools.LSToolName, func() renderer { return lsRenderer{} })
 	registry.register(tools.SourcegraphToolName, func() renderer { return sourcegraphRenderer{} })
 	registry.register(tools.DiagnosticsToolName, func() renderer { return diagnosticsRenderer{} })
+	registry.register(tools.TodosToolName, func() renderer { return todosRenderer{} })
 	registry.register(agent.AgentToolName, func() renderer { return agentRenderer{} })
 }
 
@@ -1298,6 +1300,8 @@ func prettifyToolName(name string) string {
 		return "List"
 	case tools.SourcegraphToolName:
 		return "Sourcegraph"
+	case tools.TodosToolName:
+		return "To-Do"
 	case tools.ViewToolName:
 		return "View"
 	case tools.WriteToolName:
@@ -1306,3 +1310,94 @@ func prettifyToolName(name string) string {
 		return name
 	}
 }
+
+// -----------------------------------------------------------------------------
+//  Todos renderer
+// -----------------------------------------------------------------------------
+
+type todosRenderer struct {
+	baseRenderer
+}
+
+func (tr todosRenderer) Render(v *toolCallCmp) string {
+	t := styles.CurrentTheme()
+	var params tools.TodosParams
+	var meta tools.TodosResponseMetadata
+	var headerText string
+	var body string
+
+	// Parse params for pending state (before result is available).
+	if err := tr.unmarshalParams(v.call.Input, &params); err == nil {
+		completedCount := 0
+		inProgressTask := ""
+		for _, todo := range params.Todos {
+			if todo.Status == "completed" {
+				completedCount++
+			}
+			if todo.Status == "in_progress" {
+				if todo.ActiveForm != "" {
+					inProgressTask = todo.ActiveForm
+				} else {
+					inProgressTask = todo.Content
+				}
+			}
+		}
+
+		// Default display from params (used when pending or no metadata).
+		ratio := t.S().Base.Foreground(t.BlueDark).Render(fmt.Sprintf("%d/%d", completedCount, len(params.Todos)))
+		headerText = ratio
+		if inProgressTask != "" {
+			headerText = fmt.Sprintf("%s Β· %s", ratio, inProgressTask)
+		}
+
+		// If we have metadata, use it for richer display.
+		if v.result.Metadata != "" {
+			if err := tr.unmarshalParams(v.result.Metadata, &meta); err == nil {
+				if meta.IsNew {
+					if meta.JustStarted != "" {
+						headerText = fmt.Sprintf("created %d todos, starting first", meta.Total)
+					} else {
+						headerText = fmt.Sprintf("created %d todos", meta.Total)
+					}
+					body = todos.FormatTodosList(meta.Todos, styles.ArrowRightIcon, t, v.textWidth())
+				} else {
+					// Build header based on what changed.
+					hasCompleted := len(meta.JustCompleted) > 0
+					hasStarted := meta.JustStarted != ""
+					allCompleted := meta.Completed == meta.Total
+
+					ratio := t.S().Base.Foreground(t.BlueDark).Render(fmt.Sprintf("%d/%d", meta.Completed, meta.Total))
+					if hasCompleted && hasStarted {
+						text := t.S().Subtle.Render(fmt.Sprintf(" Β· completed %d, starting next", len(meta.JustCompleted)))
+						headerText = fmt.Sprintf("%s%s", ratio, text)
+					} else if hasCompleted {
+						text := t.S().Subtle.Render(fmt.Sprintf(" Β· completed %d", len(meta.JustCompleted)))
+						if allCompleted {
+							text = t.S().Subtle.Render(" Β· completed all")
+						}
+						headerText = fmt.Sprintf("%s%s", ratio, text)
+					} else if hasStarted {
+						headerText = fmt.Sprintf("%s%s", ratio, t.S().Subtle.Render(" Β· starting task"))
+					} else {
+						headerText = ratio
+					}
+
+					// Build body with details.
+					if allCompleted {
+						// Show all todos when all are completed, like when created
+						body = todos.FormatTodosList(meta.Todos, styles.ArrowRightIcon, t, v.textWidth())
+					} else if meta.JustStarted != "" {
+						body = t.S().Base.Foreground(t.GreenDark).Render(styles.ArrowRightIcon+" ") +
+							t.S().Base.Foreground(t.FgBase).Render(meta.JustStarted)
+					}
+				}
+			}
+		}
+	}
+
+	args := newParamBuilder().addMain(headerText).build()
+
+	return tr.renderWithParams(v, "To-Do", args, func() string {
+		return body
+	})
+}

internal/tui/components/chat/messages/tool.go πŸ”—

@@ -425,7 +425,7 @@ func (m *toolCallCmp) formatResultForCopy() string {
 		return m.formatWebFetchResultForCopy()
 	case agent.AgentToolName:
 		return m.formatAgentResultForCopy()
-	case tools.DownloadToolName, tools.GrepToolName, tools.GlobToolName, tools.LSToolName, tools.SourcegraphToolName, tools.DiagnosticsToolName:
+	case tools.DownloadToolName, tools.GrepToolName, tools.GlobToolName, tools.LSToolName, tools.SourcegraphToolName, tools.DiagnosticsToolName, tools.TodosToolName:
 		return fmt.Sprintf("```\n%s\n```", m.result.Content)
 	default:
 		return m.result.Content

internal/tui/components/chat/queue.go πŸ”—

@@ -1,28 +0,0 @@
-package chat
-
-import (
-	"fmt"
-	"strings"
-
-	"charm.land/lipgloss/v2"
-	"github.com/charmbracelet/crush/internal/tui/styles"
-)
-
-func queuePill(queue int, t *styles.Theme) string {
-	if queue <= 0 {
-		return ""
-	}
-	triangles := styles.ForegroundGrad("β–Άβ–Άβ–Άβ–Άβ–Άβ–Άβ–Άβ–Άβ–Ά", false, t.RedDark, t.Accent)
-	if queue < 10 {
-		triangles = triangles[:queue]
-	}
-
-	allTriangles := strings.Join(triangles, "")
-
-	return t.S().Base.
-		BorderStyle(lipgloss.RoundedBorder()).
-		BorderForeground(t.BgOverlay).
-		PaddingLeft(1).
-		PaddingRight(1).
-		Render(fmt.Sprintf("%s %d Queued", allTriangles, queue))
-}

internal/tui/components/chat/todos/todos.go πŸ”—

@@ -0,0 +1,67 @@
+package todos
+
+import (
+	"slices"
+	"strings"
+
+	"charm.land/lipgloss/v2"
+	"github.com/charmbracelet/crush/internal/session"
+	"github.com/charmbracelet/crush/internal/tui/styles"
+	"github.com/charmbracelet/x/ansi"
+)
+
+func sortTodos(todos []session.Todo) {
+	slices.SortStableFunc(todos, func(a, b session.Todo) int {
+		return statusOrder(a.Status) - statusOrder(b.Status)
+	})
+}
+
+func statusOrder(s session.TodoStatus) int {
+	switch s {
+	case session.TodoStatusCompleted:
+		return 0
+	case session.TodoStatusInProgress:
+		return 1
+	default:
+		return 2
+	}
+}
+
+func FormatTodosList(todos []session.Todo, inProgressIcon string, t *styles.Theme, width int) string {
+	if len(todos) == 0 {
+		return ""
+	}
+
+	sorted := make([]session.Todo, len(todos))
+	copy(sorted, todos)
+	sortTodos(sorted)
+
+	var lines []string
+	for _, todo := range sorted {
+		var prefix string
+		var textStyle lipgloss.Style
+
+		switch todo.Status {
+		case session.TodoStatusCompleted:
+			prefix = t.S().Base.Foreground(t.Green).Render(styles.TodoCompletedIcon) + " "
+			textStyle = t.S().Base.Foreground(t.FgBase)
+		case session.TodoStatusInProgress:
+			prefix = t.S().Base.Foreground(t.GreenDark).Render(inProgressIcon + " ")
+			textStyle = t.S().Base.Foreground(t.FgBase)
+		default:
+			prefix = t.S().Base.Foreground(t.FgMuted).Render(styles.TodoPendingIcon) + " "
+			textStyle = t.S().Base.Foreground(t.FgBase)
+		}
+
+		text := todo.Content
+		if todo.Status == session.TodoStatusInProgress && todo.ActiveForm != "" {
+			text = todo.ActiveForm
+		}
+		line := prefix + textStyle.Render(text)
+		line = ansi.Truncate(line, width, "…")
+
+		lines = append(lines, line)
+	}
+
+	return strings.Join(lines, "\n")
+}

internal/tui/exp/list/list.go πŸ”—

@@ -1481,8 +1481,13 @@ func (l *list[T]) reset(selectedItemID string) tea.Cmd {
 // SetSize implements List.
 func (l *list[T]) SetSize(width int, height int) tea.Cmd {
 	oldWidth := l.width
+	oldHeight := l.height
 	l.width = width
 	l.height = height
+	// Invalidate cache if height changed
+	if oldHeight != height {
+		l.cachedViewDirty = true
+	}
 	if oldWidth != width {
 		// Get current selected item ID before reset
 		selectedID := ""

internal/tui/page/chat/chat.go πŸ”—

@@ -57,6 +57,14 @@ const (
 	PanelTypeSplash PanelType = "splash"
 )
 
+// PillSection represents which pill section is focused when in pills panel.
+type PillSection int
+
+const (
+	PillSectionTodos PillSection = iota
+	PillSectionQueue
+)
+
 const (
 	CompactModeWidthBreakpoint  = 120 // Width at which the chat page switches to compact mode
 	CompactModeHeightBreakpoint = 30  // Height at which the chat page switches to compact mode
@@ -116,9 +124,18 @@ type chatPage struct {
 	splashFullScreen bool
 	isOnboarding     bool
 	isProjectInit    bool
+	promptQueue      int
+
+	// Pills state
+	pillsExpanded      bool
+	focusedPillSection PillSection
+
+	// Todo spinner
+	todoSpinner spinner.Model
 }
 
 func New(app *app.App) ChatPage {
+	t := styles.CurrentTheme()
 	return &chatPage{
 		app:         app,
 		keyMap:      DefaultKeyMap(),
@@ -128,6 +145,10 @@ func New(app *app.App) ChatPage {
 		editor:      editor.New(app),
 		splash:      splash.New(),
 		focusedPane: PanelTypeSplash,
+		todoSpinner: spinner.New(
+			spinner.WithSpinner(spinner.MiniDot),
+			spinner.WithStyle(t.S().Base.Foreground(t.GreenDark)),
+		),
 	}
 }
 
@@ -166,6 +187,13 @@ func (p *chatPage) Init() tea.Cmd {
 
 func (p *chatPage) Update(msg tea.Msg) (util.Model, tea.Cmd) {
 	var cmds []tea.Cmd
+	if p.session.ID != "" && p.app.AgentCoordinator != nil {
+		queueSize := p.app.AgentCoordinator.QueuedPrompts(p.session.ID)
+		if queueSize != p.promptQueue {
+			p.promptQueue = queueSize
+			cmds = append(cmds, p.SetSize(p.width, p.height))
+		}
+	}
 	switch msg := msg.(type) {
 	case tea.KeyboardEnhancementsMsg:
 		p.keyboardEnhancements = msg
@@ -268,6 +296,19 @@ func (p *chatPage) Update(msg tea.Msg) (util.Model, tea.Cmd) {
 		p.editor = u.(editor.Editor)
 		return p, cmd
 	case pubsub.Event[session.Session]:
+		if msg.Payload.ID == p.session.ID {
+			prevHasIncompleteTodos := hasIncompleteTodos(p.session.Todos)
+			prevHasInProgress := p.hasInProgressTodo()
+			p.session = msg.Payload
+			newHasIncompleteTodos := hasIncompleteTodos(p.session.Todos)
+			newHasInProgress := p.hasInProgressTodo()
+			if prevHasIncompleteTodos != newHasIncompleteTodos {
+				cmds = append(cmds, p.SetSize(p.width, p.height))
+			}
+			if !prevHasInProgress && newHasInProgress {
+				cmds = append(cmds, p.todoSpinner.Tick)
+			}
+		}
 		u, cmd := p.header.Update(msg)
 		p.header = u.(header.Header)
 		cmds = append(cmds, cmd)
@@ -311,6 +352,17 @@ func (p *chatPage) Update(msg tea.Msg) (util.Model, tea.Cmd) {
 	case pubsub.Event[message.Message],
 		anim.StepMsg,
 		spinner.TickMsg:
+		// Update todo spinner if agent is busy and we have in-progress todos
+		agentBusy := p.app.AgentCoordinator != nil && p.app.AgentCoordinator.IsBusy()
+		if _, ok := msg.(spinner.TickMsg); ok && p.hasInProgressTodo() && agentBusy {
+			var cmd tea.Cmd
+			p.todoSpinner, cmd = p.todoSpinner.Update(msg)
+			cmds = append(cmds, cmd)
+		}
+		// Start spinner when agent becomes busy and we have in-progress todos
+		if _, ok := msg.(pubsub.Event[message.Message]); ok && p.hasInProgressTodo() && agentBusy {
+			cmds = append(cmds, p.todoSpinner.Tick)
+		}
 		if p.focusedPane == PanelTypeSplash {
 			u, cmd := p.splash.Update(msg)
 			p.splash = u.(splash.Splash)
@@ -401,8 +453,7 @@ func (p *chatPage) Update(msg tea.Msg) (util.Model, tea.Cmd) {
 				p.splash = u.(splash.Splash)
 				return p, cmd
 			}
-			p.changeFocus()
-			return p, nil
+			return p, p.changeFocus()
 		case key.Matches(msg, p.keyMap.Cancel):
 			if p.session.ID != "" && p.app.AgentCoordinator.IsBusy() {
 				return p, p.cancel()
@@ -410,6 +461,18 @@ func (p *chatPage) Update(msg tea.Msg) (util.Model, tea.Cmd) {
 		case key.Matches(msg, p.keyMap.Details):
 			p.toggleDetails()
 			return p, nil
+		case key.Matches(msg, p.keyMap.TogglePills):
+			if p.session.ID != "" {
+				return p, p.togglePillsExpanded()
+			}
+		case key.Matches(msg, p.keyMap.PillLeft):
+			if p.session.ID != "" && p.pillsExpanded {
+				return p, p.switchPillSection(-1)
+			}
+		case key.Matches(msg, p.keyMap.PillRight):
+			if p.session.ID != "" && p.pillsExpanded {
+				return p, p.switchPillSection(1)
+			}
 		}
 
 		switch p.focusedPane {
@@ -483,19 +546,91 @@ func (p *chatPage) View() string {
 	} else {
 		messagesView := p.chat.View()
 		editorView := p.editor.View()
+
+		hasIncompleteTodos := hasIncompleteTodos(p.session.Todos)
+		hasQueue := p.promptQueue > 0
+		todosFocused := p.pillsExpanded && p.focusedPillSection == PillSectionTodos
+		queueFocused := p.pillsExpanded && p.focusedPillSection == PillSectionQueue
+
+		// Use spinner when agent is busy, otherwise show static icon
+		agentBusy := p.app.AgentCoordinator != nil && p.app.AgentCoordinator.IsBusy()
+		inProgressIcon := t.S().Base.Foreground(t.GreenDark).Render(styles.CenterSpinnerIcon)
+		if agentBusy {
+			inProgressIcon = p.todoSpinner.View()
+		}
+
+		var pills []string
+		if hasIncompleteTodos {
+			pills = append(pills, todoPill(p.session.Todos, inProgressIcon, todosFocused, p.pillsExpanded, t))
+		}
+		if hasQueue {
+			pills = append(pills, queuePill(p.promptQueue, queueFocused, p.pillsExpanded, t))
+		}
+
+		var expandedList string
+		if p.pillsExpanded {
+			if todosFocused && hasIncompleteTodos {
+				expandedList = todoList(p.session.Todos, inProgressIcon, t, p.width-SideBarWidth)
+			} else if queueFocused && hasQueue {
+				queueItems := p.app.AgentCoordinator.QueuedPromptsList(p.session.ID)
+				expandedList = queueList(queueItems, t)
+			}
+		}
+
+		var pillsArea string
+		if len(pills) > 0 {
+			pillsRow := lipgloss.JoinHorizontal(lipgloss.Top, pills...)
+
+			// Add help hint for expanding/collapsing pills based on state.
+			var helpDesc string
+			if p.pillsExpanded {
+				helpDesc = "close"
+			} else {
+				helpDesc = "open"
+			}
+			// Style to match help section: keys in FgMuted, description in FgSubtle
+			helpKey := t.S().Base.Foreground(t.FgMuted).Render("ctrl+space")
+			helpText := t.S().Base.Foreground(t.FgSubtle).Render(helpDesc)
+			helpHint := lipgloss.JoinHorizontal(lipgloss.Center, helpKey, " ", helpText)
+			pillsRow = lipgloss.JoinHorizontal(lipgloss.Center, pillsRow, " ", helpHint)
+
+			if expandedList != "" {
+				pillsArea = lipgloss.JoinVertical(
+					lipgloss.Left,
+					pillsRow,
+					expandedList,
+				)
+			} else {
+				pillsArea = pillsRow
+			}
+
+			style := t.S().Base.MarginTop(1).PaddingLeft(3)
+			pillsArea = style.Render(pillsArea)
+		}
+
 		if p.compact {
 			headerView := p.header.View()
-			chatView = lipgloss.JoinVertical(
-				lipgloss.Left,
-				headerView,
-				messagesView,
-				editorView,
-			)
+			views := []string{headerView, messagesView}
+			if pillsArea != "" {
+				views = append(views, pillsArea)
+			}
+			views = append(views, editorView)
+			chatView = lipgloss.JoinVertical(lipgloss.Left, views...)
 		} else {
 			sidebarView := p.sidebar.View()
+			var messagesColumn string
+			if pillsArea != "" {
+				messagesColumn = lipgloss.JoinVertical(
+					lipgloss.Left,
+					messagesView,
+					pillsArea,
+				)
+			} else {
+				messagesColumn = messagesView
+			}
 			messages := lipgloss.JoinHorizontal(
 				lipgloss.Left,
-				messagesView,
+				messagesColumn,
 				sidebarView,
 			)
 			chatView = lipgloss.JoinVertical(
@@ -657,14 +792,30 @@ func (p *chatPage) SetSize(width, height int) tea.Cmd {
 			cmds = append(cmds, p.editor.SetPosition(0, height-EditorHeight))
 		}
 	} else {
+		hasIncompleteTodos := hasIncompleteTodos(p.session.Todos)
+		hasQueue := p.promptQueue > 0
+		hasPills := hasIncompleteTodos || hasQueue
+
+		pillsAreaHeight := 0
+		if hasPills {
+			pillsAreaHeight = pillHeightWithBorder + 1 // +1 for padding top
+			if p.pillsExpanded {
+				if p.focusedPillSection == PillSectionTodos && hasIncompleteTodos {
+					pillsAreaHeight += len(p.session.Todos)
+				} else if p.focusedPillSection == PillSectionQueue && hasQueue {
+					pillsAreaHeight += p.promptQueue
+				}
+			}
+		}
+
 		if p.compact {
-			cmds = append(cmds, p.chat.SetSize(width, height-EditorHeight-HeaderHeight))
+			cmds = append(cmds, p.chat.SetSize(width, height-EditorHeight-HeaderHeight-pillsAreaHeight))
 			p.detailsWidth = width - DetailsPositioning
 			cmds = append(cmds, p.sidebar.SetSize(p.detailsWidth-LeftRightBorders, p.detailsHeight-TopBottomBorders))
 			cmds = append(cmds, p.editor.SetSize(width, EditorHeight))
 			cmds = append(cmds, p.header.SetWidth(width-BorderWidth))
 		} else {
-			cmds = append(cmds, p.chat.SetSize(width-SideBarWidth, height-EditorHeight))
+			cmds = append(cmds, p.chat.SetSize(width-SideBarWidth, height-EditorHeight-pillsAreaHeight))
 			cmds = append(cmds, p.editor.SetSize(width, EditorHeight))
 			cmds = append(cmds, p.sidebar.SetSize(SideBarWidth, height-EditorHeight))
 		}
@@ -689,37 +840,77 @@ func (p *chatPage) newSession() tea.Cmd {
 	)
 }
 
-func (p *chatPage) setSession(session session.Session) tea.Cmd {
-	if p.session.ID == session.ID {
+func (p *chatPage) setSession(sess session.Session) tea.Cmd {
+	if p.session.ID == sess.ID {
 		return nil
 	}
 
 	var cmds []tea.Cmd
-	p.session = session
+	p.session = sess
+
+	if p.hasInProgressTodo() {
+		cmds = append(cmds, p.todoSpinner.Tick)
+	}
 
 	cmds = append(cmds, p.SetSize(p.width, p.height))
-	cmds = append(cmds, p.chat.SetSession(session))
-	cmds = append(cmds, p.sidebar.SetSession(session))
-	cmds = append(cmds, p.header.SetSession(session))
-	cmds = append(cmds, p.editor.SetSession(session))
+	cmds = append(cmds, p.chat.SetSession(sess))
+	cmds = append(cmds, p.sidebar.SetSession(sess))
+	cmds = append(cmds, p.header.SetSession(sess))
+	cmds = append(cmds, p.editor.SetSession(sess))
 
 	return tea.Sequence(cmds...)
 }
 
-func (p *chatPage) changeFocus() {
+func (p *chatPage) changeFocus() tea.Cmd {
 	if p.session.ID == "" {
-		return
+		return nil
 	}
+
 	switch p.focusedPane {
-	case PanelTypeChat:
-		p.focusedPane = PanelTypeEditor
-		p.editor.Focus()
-		p.chat.Blur()
 	case PanelTypeEditor:
 		p.focusedPane = PanelTypeChat
 		p.chat.Focus()
 		p.editor.Blur()
+	case PanelTypeChat:
+		p.focusedPane = PanelTypeEditor
+		p.editor.Focus()
+		p.chat.Blur()
+	}
+	return nil
+}
+
+func (p *chatPage) togglePillsExpanded() tea.Cmd {
+	hasPills := hasIncompleteTodos(p.session.Todos) || p.promptQueue > 0
+	if !hasPills {
+		return nil
+	}
+	p.pillsExpanded = !p.pillsExpanded
+	if p.pillsExpanded {
+		if hasIncompleteTodos(p.session.Todos) {
+			p.focusedPillSection = PillSectionTodos
+		} else {
+			p.focusedPillSection = PillSectionQueue
+		}
 	}
+	return p.SetSize(p.width, p.height)
+}
+
+func (p *chatPage) switchPillSection(dir int) tea.Cmd {
+	if !p.pillsExpanded {
+		return nil
+	}
+	hasIncompleteTodos := hasIncompleteTodos(p.session.Todos)
+	hasQueue := p.promptQueue > 0
+
+	if dir < 0 && p.focusedPillSection == PillSectionQueue && hasIncompleteTodos {
+		p.focusedPillSection = PillSectionTodos
+		return p.SetSize(p.width, p.height)
+	}
+	if dir > 0 && p.focusedPillSection == PillSectionTodos && hasQueue {
+		p.focusedPillSection = PillSectionQueue
+		return p.SetSize(p.width, p.height)
+	}
+	return nil
 }
 
 func (p *chatPage) cancel() tea.Cmd {
@@ -1005,18 +1196,34 @@ func (p *chatPage) Help() help.KeyMap {
 		globalBindings := []key.Binding{}
 		// we are in a session
 		if p.session.ID != "" {
-			tabKey := key.NewBinding(
-				key.WithKeys("tab"),
-				key.WithHelp("tab", "focus chat"),
-			)
-			if p.focusedPane == PanelTypeChat {
+			var tabKey key.Binding
+			switch p.focusedPane {
+			case PanelTypeEditor:
+				tabKey = key.NewBinding(
+					key.WithKeys("tab"),
+					key.WithHelp("tab", "focus chat"),
+				)
+			case PanelTypeChat:
 				tabKey = key.NewBinding(
 					key.WithKeys("tab"),
 					key.WithHelp("tab", "focus editor"),
 				)
+			default:
+				tabKey = key.NewBinding(
+					key.WithKeys("tab"),
+					key.WithHelp("tab", "focus chat"),
+				)
 			}
 			shortList = append(shortList, tabKey)
 			globalBindings = append(globalBindings, tabKey)
+
+			// Show left/right to switch sections when expanded and both exist
+			hasTodos := hasIncompleteTodos(p.session.Todos)
+			hasQueue := p.promptQueue > 0
+			if p.pillsExpanded && hasTodos && hasQueue {
+				shortList = append(shortList, p.keyMap.PillLeft)
+				globalBindings = append(globalBindings, p.keyMap.PillLeft)
+			}
 		}
 		commandsBinding := key.NewBinding(
 			key.WithKeys("ctrl+p"),
@@ -1207,3 +1414,12 @@ func (p *chatPage) isMouseOverChat(x, y int) bool {
 	// Check if mouse coordinates are within chat bounds
 	return x >= chatX && x < chatX+chatWidth && y >= chatY && y < chatY+chatHeight
 }
+
+func (p *chatPage) hasInProgressTodo() bool {
+	for _, todo := range p.session.Todos {
+		if todo.Status == session.TodoStatusInProgress {
+			return true
+		}
+	}
+	return false
+}

internal/tui/page/chat/keys.go πŸ”—

@@ -10,6 +10,9 @@ type KeyMap struct {
 	Cancel        key.Binding
 	Tab           key.Binding
 	Details       key.Binding
+	TogglePills   key.Binding
+	PillLeft      key.Binding
+	PillRight     key.Binding
 }
 
 func DefaultKeyMap() KeyMap {
@@ -34,5 +37,17 @@ func DefaultKeyMap() KeyMap {
 			key.WithKeys("ctrl+d"),
 			key.WithHelp("ctrl+d", "toggle details"),
 		),
+		TogglePills: key.NewBinding(
+			key.WithKeys("ctrl+space"),
+			key.WithHelp("ctrl+space", "toggle tasks"),
+		),
+		PillLeft: key.NewBinding(
+			key.WithKeys("left"),
+			key.WithHelp("←/β†’", "switch section"),
+		),
+		PillRight: key.NewBinding(
+			key.WithKeys("right"),
+			key.WithHelp("←/β†’", "switch section"),
+		),
 	}
 }

internal/tui/page/chat/pills.go πŸ”—

@@ -0,0 +1,125 @@
+package chat
+
+import (
+	"fmt"
+	"strings"
+
+	"charm.land/lipgloss/v2"
+	"github.com/charmbracelet/crush/internal/session"
+	"github.com/charmbracelet/crush/internal/tui/components/chat/todos"
+	"github.com/charmbracelet/crush/internal/tui/styles"
+)
+
+func hasIncompleteTodos(todos []session.Todo) bool {
+	for _, todo := range todos {
+		if todo.Status != session.TodoStatusCompleted {
+			return true
+		}
+	}
+	return false
+}
+
+const (
+	pillHeightWithBorder  = 3
+	maxTaskDisplayLength  = 40
+	maxQueueDisplayLength = 60
+)
+
+func queuePill(queue int, focused, pillsPanelFocused bool, t *styles.Theme) string {
+	if queue <= 0 {
+		return ""
+	}
+	triangles := styles.ForegroundGrad("β–Άβ–Άβ–Άβ–Άβ–Άβ–Άβ–Άβ–Άβ–Ά", false, t.RedDark, t.Accent)
+	if queue < 10 {
+		triangles = triangles[:queue]
+	}
+
+	content := fmt.Sprintf("%s %d Queued", strings.Join(triangles, ""), queue)
+
+	style := t.S().Base.PaddingLeft(1).PaddingRight(1)
+	if !pillsPanelFocused || focused {
+		style = style.BorderStyle(lipgloss.RoundedBorder()).BorderForeground(t.BgOverlay)
+	} else {
+		style = style.BorderStyle(lipgloss.HiddenBorder())
+	}
+	return style.Render(content)
+}
+
+func todoPill(todos []session.Todo, spinnerView string, focused, pillsPanelFocused bool, t *styles.Theme) string {
+	if !hasIncompleteTodos(todos) {
+		return ""
+	}
+
+	completed := 0
+	var currentTodo *session.Todo
+	for i := range todos {
+		switch todos[i].Status {
+		case session.TodoStatusCompleted:
+			completed++
+		case session.TodoStatusInProgress:
+			if currentTodo == nil {
+				currentTodo = &todos[i]
+			}
+		}
+	}
+
+	total := len(todos)
+
+	label := "To-Do"
+	progress := t.S().Base.Foreground(t.FgMuted).Render(fmt.Sprintf("%d/%d", completed, total))
+
+	var content string
+	if pillsPanelFocused {
+		content = fmt.Sprintf("%s %s", label, progress)
+	} else if currentTodo != nil {
+		taskText := currentTodo.Content
+		if currentTodo.ActiveForm != "" {
+			taskText = currentTodo.ActiveForm
+		}
+		if len(taskText) > maxTaskDisplayLength {
+			taskText = taskText[:maxTaskDisplayLength-1] + "…"
+		}
+		task := t.S().Base.Foreground(t.FgSubtle).Render(taskText)
+		content = fmt.Sprintf("%s %s %s  %s", spinnerView, label, progress, task)
+	} else {
+		content = fmt.Sprintf("%s %s", label, progress)
+	}
+
+	style := t.S().Base.PaddingLeft(1).PaddingRight(1)
+	if !pillsPanelFocused || focused {
+		style = style.BorderStyle(lipgloss.RoundedBorder()).BorderForeground(t.BgOverlay)
+	} else {
+		style = style.BorderStyle(lipgloss.HiddenBorder())
+	}
+	return style.Render(content)
+}
+
+func todoList(sessionTodos []session.Todo, spinnerView string, t *styles.Theme, width int) string {
+	return todos.FormatTodosList(sessionTodos, spinnerView, t, width)
+}
+
+func queueList(queueItems []string, t *styles.Theme) string {
+	if len(queueItems) == 0 {
+		return ""
+	}
+
+	var lines []string
+	for _, item := range queueItems {
+		text := item
+		if len(text) > maxQueueDisplayLength {
+			text = text[:maxQueueDisplayLength-1] + "…"
+		}
+		prefix := t.S().Base.Foreground(t.FgMuted).Render("  β€’") + " "
+		lines = append(lines, prefix+t.S().Base.Foreground(t.FgMuted).Render(text))
+	}
+
+	return strings.Join(lines, "\n")
+}
+
+func sectionLine(availableWidth int, t *styles.Theme) string {
+	if availableWidth <= 0 {
+		return ""
+	}
+	line := strings.Repeat("─", availableWidth)
+	return t.S().Base.Foreground(t.Border).Render(line)
+}

internal/tui/styles/icons.go πŸ”—

@@ -1,15 +1,17 @@
 package styles
 
 const (
-	CheckIcon    string = "βœ“"
-	ErrorIcon    string = "Γ—"
-	WarningIcon  string = "⚠"
-	InfoIcon     string = "β“˜"
-	HintIcon     string = "∡"
-	SpinnerIcon  string = "..."
-	LoadingIcon  string = "⟳"
-	DocumentIcon string = "πŸ–Ό"
-	ModelIcon    string = "β—‡"
+	CheckIcon         string = "βœ“"
+	ErrorIcon         string = "Γ—"
+	WarningIcon       string = "⚠"
+	InfoIcon          string = "β“˜"
+	HintIcon          string = "∡"
+	SpinnerIcon       string = "..."
+	ArrowRightIcon    string = "β†’"
+	CenterSpinnerIcon string = "β‹―"
+	LoadingIcon       string = "⟳"
+	DocumentIcon      string = "πŸ–Ό"
+	ModelIcon         string = "β—‡"
 
 	// Tool call icons
 	ToolPending string = "●"
@@ -18,6 +20,10 @@ const (
 
 	BorderThin  string = "β”‚"
 	BorderThick string = "β–Œ"
+
+	// Todo icons
+	TodoCompletedIcon string = "βœ“"
+	TodoPendingIcon   string = "β€’"
 )
 
 var SelectionIgnoreIcons = []string{