From dabcbc79831052effc6ce990021feee07d661f7e Mon Sep 17 00:00:00 2001 From: Adam Malczewski Date: Wed, 24 Jun 2026 14:10:03 +0900 Subject: fix(kernel+tool-shell): abort hanging tool calls without bricking the conversation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit kernel: executeToolCall now races tool.execute against the abort signal via Promise.race; on abort resolves (not rejects) with an "Aborted" result so the step completes normally → finishReason "aborted" → turn seals cleanly (done event) → finally clears activeTurns → conversation freed, next message accepted. run-turn strips tool-call chunks from the assistant message on abort (keeps text/thinking) and omits tool-result messages to avoid persisting dangling tool calls that would 400 the provider next turn. tool-shell: realSpawn spawns detached (own process group); on abort AND timeout kills the entire group (process.kill(-pgid, SIGKILL)) and resolves immediately — no child.on("close") dependency, so a grandchild holding the pipes can't stall the spawn promise or leak. Also: ORCHESTRATOR.md migrated to dispatch CLI summon mechanism; .skills summary; bin/sync-env PATH injection; frontend handoff docs. 1453 vitest pass · tsc -b EXIT 0 · biome clean. --- packages/tool-shell/src/shell.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'packages/tool-shell/src/shell.ts') diff --git a/packages/tool-shell/src/shell.ts b/packages/tool-shell/src/shell.ts index d96d73e..cc76bca 100644 --- a/packages/tool-shell/src/shell.ts +++ b/packages/tool-shell/src/shell.ts @@ -12,6 +12,7 @@ export interface ValidatedArgs { export interface SpawnResult { readonly exitCode: number | null; readonly timedOut: boolean; + readonly aborted: boolean; } export type SpawnShell = (params: { @@ -139,7 +140,6 @@ export function createRunShellTool(deps: { }; let spawnResult: SpawnResult; - let aborted = false; try { spawnResult = await deps.spawn({ @@ -154,7 +154,6 @@ export function createRunShellTool(deps: { }); } catch (err: unknown) { if (ctx.signal.aborted) { - aborted = true; return buildResult({ exitCode: null, timedOut: false, @@ -172,7 +171,7 @@ export function createRunShellTool(deps: { return buildResult({ exitCode: spawnResult.exitCode, timedOut: spawnResult.timedOut, - aborted, + aborted: spawnResult.aborted, output, cap, }); -- cgit v1.2.3