fix(tui): render mid-turn steering skips as info, not errors
A tool call aborted mid-batch to service queued steering/peer input emits a synthetic placeholder result with isError:true so the model retries it. The TUI keyed all error styling (red ✘, red frame/text) off that flag, so a normal steering skip rendered identically to a real tool failure. Mark the skip placeholder with the existing SyntheticToolResultDetails discriminator (source: "interrupt_skipped", executed:false) and render benign skips through the neutral generic card (info glyph, dim text, neutral background), bypassing any bespoke error frame. Genuine failures keep their error styling. Fixes #7199
This commit is contained in:
@@ -2,6 +2,10 @@
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Fixed
|
||||
|
||||
- Tool calls skipped mid-batch to service a queued steering/peer interrupt now carry the `SyntheticToolResultDetails` discriminator (`source: "interrupt_skipped"`, `executed: false`), so UI/telemetry consumers can classify them as "call emitted, not executed" instead of a real tool failure ([#7199](https://github.com/can1357/oh-my-pi/issues/7199)).
|
||||
|
||||
## [17.2.2] - 2026-07-31
|
||||
|
||||
### Fixed
|
||||
|
||||
@@ -2723,13 +2723,20 @@ async function executeToolCalls(
|
||||
* (#4321): a provider-side stream error after tool-call emission (e.g. Codex
|
||||
* websocket close) was surfaced by the CLI as if the local tool had failed.
|
||||
*
|
||||
* `source` names the assistant-side termination state that prevented
|
||||
* execution; `upstreamError` is the provider-reported message when the turn
|
||||
* ended with `stopReason === "error"`.
|
||||
* `source` names the state that prevented execution — either an assistant-side
|
||||
* turn termination (`assistant_stop_*`) or a mid-batch interrupt that skipped a
|
||||
* still-pending call to service queued steering/peer input (`interrupt_skipped`).
|
||||
* `upstreamError` is the provider-reported message when the turn ended with
|
||||
* `stopReason === "error"`.
|
||||
*/
|
||||
export interface SyntheticToolResultDetails {
|
||||
__synthetic: true;
|
||||
source: "assistant_stop_aborted" | "assistant_stop_error" | "assistant_stop_skipped" | "assistant_stop_length";
|
||||
source:
|
||||
| "assistant_stop_aborted"
|
||||
| "assistant_stop_error"
|
||||
| "assistant_stop_skipped"
|
||||
| "assistant_stop_length"
|
||||
| "interrupt_skipped";
|
||||
executed: false;
|
||||
upstreamError?: string;
|
||||
}
|
||||
@@ -2844,7 +2851,9 @@ function createToolSignalAbortedResult(signal: AbortSignal): AgentToolResult<unk
|
||||
};
|
||||
}
|
||||
|
||||
function createSkippedToolResult(source: SteeringInterruptSource | "irc" | undefined): AgentToolResult<any> {
|
||||
function createSkippedToolResult(
|
||||
source: SteeringInterruptSource | "irc" | undefined,
|
||||
): AgentToolResult<SyntheticToolResultDetails> {
|
||||
let reason = "pending steering message";
|
||||
let blocker = "queued message";
|
||||
if (source === "user") {
|
||||
@@ -2864,6 +2873,6 @@ function createSkippedToolResult(source: SteeringInterruptSource | "irc" | undef
|
||||
text: `Skipped due to ${reason}. Do not count this skipped result as completed work or verification. After the ${blocker} is handled on the next step, retry the skipped tool if it is still needed.`,
|
||||
},
|
||||
],
|
||||
details: {},
|
||||
details: { __synthetic: true, source: "interrupt_skipped", executed: false },
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user