fix(runner): clear failed tool items before governed suspension

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
DottaandPaperclip committed 2026-09-18 22:12:32 -05:00
1 parent 9bae201ea3
commit f20ccfb38a
2 files changed
+11 -3

No files matched your search

@@ -4128,6 +4128,11 @@ describe("native governed waits", () => {
payload: { kind: "dynamicToolCall" },
};
// A failed tool is terminal too, even when its error event omits kind.
// It must not block the later approval tool from parking this run.
await observation.observe({ ...replayedEvent, eventType: "item.started", itemId: "failed-command", payload: { kind: "commandExecution" } }, false);
await observation.observe({ ...replayedEvent, eventType: "item.failed", itemId: "failed-command", payload: { error: "Command exited with status 1" } }, false);
// A usage event must not park while the card-creation response is held.
await observation.observe({ ...replayedEvent, eventType: "item.started", itemId: "approval-tool" }, false);
const usage = { ...replayedEvent, payload: { kind: "usage" } };
@@ -998,9 +998,12 @@ export function createGovernedWaitEventObservation(
observation = null;
const kind = record(event.payload).kind;
const tool = ["dynamicToolCall", "mcpToolCall", "commandExecution"].includes(String(kind));
if (tool && event.itemId) {
if (event.eventType === "item.started") pendingTools.add(event.itemId);
if (event.eventType === "item.completed") pendingTools.delete(event.itemId);
if (event.itemId) {
if (tool && event.eventType === "item.started") pendingTools.add(event.itemId);
// Terminal error events can omit kind; the tracked ID owns cleanup.
if (event.eventType === "item.completed" || event.eventType === "item.failed") {
pendingTools.delete(event.itemId);
}
}
// Usage/model messages can arrive while the tool creating the card is
// still awaiting its response. Parking then interrupts that in-flight