feat(agentloop): add Callbacks struct with OnToolStart to agentloop.Run#228
Conversation
…oolStart Replace the bare `onDelta func(string)` parameter in `agentloop.Run` with a `Callbacks` struct that holds `OnDelta` and `OnToolStart`. The struct is nil-safe by default — unset fields are simply not called. `OnToolStart` fires in `OnToolCall` with the tool name, enabling callers (e.g. WebSocket handlers) to emit tool status events to clients. All existing callers updated to use the new struct.
PR Review: feat(agentloop) — Callbacks struct + OnToolStartSummaryClean, principled refactor. The Important IssuesMissing test for
Suggested addition to the existing tool call test: var toolsStarted []string
result, err := Run(context.Background(), cfg, nil, "run bash", Callbacks{
OnToolStart: func(toolName string) {
toolsStarted = append(toolsStarted, toolName)
},
})
require.NoError(t, err)
assert.Equal(t, []string{"bash"}, toolsStarted)Suggestions
Strengths
VERDICT: LGTM (with suggested test addition)Blocking on nothing. The |
Add TestRun_OnToolStart to lock in the callback contract — catches regressions like passing ToolCallID instead of ToolName or moving the callback to OnToolResult. Also clarify the OnToolStart godoc to note it fires before tool execution (at selection time), not after.
Triage UpdateFixed
VerdictLGTM — no remaining issues. |
Summary
onDelta func(string)parameter inagentloop.Runwith aCallbacksstructCallbackshas two fields:OnDelta func(string)andOnToolStart func(toolName string)OnToolStartfires insideOnToolCallso callers can emit tool status events (e.g. WebSockettool_startevents to iOS clients)cmd/subagent.go,cmd/explore.go, and all tests inpkg/agentloop/loop_test.goWhy Callbacks struct vs individual params
Runalready has 5 params. More callbacks are coming (onToolEnd,onError,onStepComplete) for WebSocket streaming. The struct scales without signature churn and is zero-value safe — callers that don't need new callbacks don't change.Test plan
make test)go build ./...)