feat(desktop): mid-turn steer injection and tool-call details in history#3263
feat(desktop): mid-turn steer injection and tool-call details in history#3263JesonChou wants to merge 2 commits into
Conversation
Fix two core desktop features: 1. Model dialogue mid-turn steer: when the model is running, user input is now injected as mid-turn guidance via a steer queue instead of being silently dropped by runGuarded. A runningRef replaces the stale state.running closure in handleSend, and the steer flows through App.Steer -> Controller.Steer -> Agent.Steer into a FIFO queue consumed each iteration of the agent loop, persisted to the session so it remains visible for subsequent API calls. A Steer event confirms delivery to the frontend. 2. History tool-call details: HistoryMessage now carries ToolName, ToolArgs, ToolOutput, ToolID, and ToolTruncated fields mapped from the provider's tool-call records. The history reducer and HistoryPanel's previewMessagesToItems render tool messages as ToolCard items, so switching between saved sessions shows full tool invocation details. Changes: - internal/event/event.go: add Steer event kind - internal/agent/agent.go: add steerQueue, Steer/consumeSteer/ SteerConsumed/clearSteerQueue/steerQueueLen, midTurnSteerPrefix, and steer consumption/peristence in Run loop - internal/control/controller.go: add Steer/SteerConsumed methods - desktop/app.go: add App.Steer, expand HistoryMessage struct with tool fields, map tool messages in historyMessages via toolCallByID - desktop/frontend/src/lib/bridge.ts: add Steer to AppBindings and mock - desktop/frontend/src/lib/types.ts: add steer event kind, tool fields to HistoryMessage - desktop/frontend/src/lib/useController.ts: add steer callback, update history reducer for tool messages - desktop/frontend/src/App.tsx: add runningRef + steer in handleSend - desktop/frontend/src/components/HistoryPanel.tsx: update previewMessagesToItems for tool messages
SivanCola
left a comment
There was a problem hiding this comment.
Requesting changes after reviewing this PR against main-v2.\n\nFindings:\n\n1. is not wired into the desktop/server wire event kind maps. The PR adds the new event kind, but and do not map it, while serializes . That means steer events are emitted with an empty , so the frontend cannot reliably receive the intended event. Please add the wire mappings and a regression test.\n\n2. Steer injection is not tab-scoped. The frontend dispatches the local user bubble to , but routes through . In a multi-tab/background-running scenario, the UI can show the steer message in one tab while the backend injects it into a different active controller. Please add a tab-scoped API, analogous to Submit/Cancel/ApproveForTab, and route the frontend call with the tab id.\n\nThis PR also overlaps with #3286 for history tool details. I would recommend splitting the mid-turn steer feature from the history replay fix, then rebasing on the dedicated history fix once it lands.
|
Correction to my review above: the shell stripped the inline code identifiers from the submitted review body. The exact findings are:
This PR also overlaps with #3286 for history tool details. I would recommend splitting the mid-turn steer feature from the history replay fix, then rebasing on the dedicated history fix once it lands. |
|
感谢大佬意见,我继续修改 |
…osition-aware tool-result pairing - Add Steer event kind (internal/event/event.go) with wire mappings in desktop/wire.go and internal/serve/wire.go, plus regression tests. - Add Agent.steerQueue with Steer / consumeSteer / SteerConsumed / clearSteerQueue / steerQueueLen and mid-turn injection in the Run loop: each queued steer is persisted to the session and emitted as a Steer event so the frontend can confirm delivery. - Add Controller.Steer / SteerConsumed methods that delegate to the current executor. - Add App.Steer / App.SteerForTab with per-tab routing, matching the SubmitForTab / CancelForTab pattern (reviewer feedback esengine#3263). - Add Steer / SteerForTab to the frontend AppBindings, mock, useController steer callback (routed with activeTabId), and runningRef + steer dispatch in App.handleSend. - Expand HistoryMessage with ToolCalls []HistoryToolCall (assistant) and ToolCallID / ToolName (tool result), and add historyMessagesToItems that pairs tool calls with results. - Fix historyMessagesToItems and serve renderHistoryMessages to use position-aware tool-result pairing (collectToolResultsAfter) instead of a global resultByID map, so cross-turn tool-call ID collisions (e.g. synthesized call_0 from gateways that omit IDs) do not shadow later turns' results. Mirrors SanitizeToolPairing's turn-scoped pairing.
Fix two core desktop features:
Model dialogue mid-turn steer: when the model is running, user input is now injected as mid-turn guidance via a steer queue instead of being silently dropped by runGuarded. A runningRef replaces the stale state.running closure in handleSend, and the steer flows through App.Steer -> Controller.Steer -> Agent.Steer into a FIFO queue consumed each iteration of the agent loop, persisted to the session so it remains visible for subsequent API calls. A Steer event confirms delivery to the frontend.
History tool-call details: HistoryMessage now carries ToolName, ToolArgs, ToolOutput, ToolID, and ToolTruncated fields mapped from the provider's tool-call records. The history reducer and HistoryPanel's previewMessagesToItems render tool messages as ToolCard items, so switching between saved sessions shows full tool invocation details.
Changes: