Repository navigation
Conversation
…owLab#1644) `tool/result` carries no top-level `callId`: the host puts the id on `data.message.toolCallId`, so `end(id, String(event.data?.callId ?? ''))` returned on every result and each wait stayed open until `turn/end`. The 60s steering line then read the turn's age instead of a wait's, and a human line after 60s aborted a turn whose tools had all returned. Read both shapes, message first; `turns.js` reads the same shape for the running-tool chip. Docs: docs/subsystems/core-host.md names the payload field the wait closes from. Patches regenerated from core/.
|
@Birfy — review request for PR #1645 at the current tip
Scope ( Please post the Verdict at this tip. |
|
Verdict: PASS at abd9a7e Ran at this tip: Red first, as claimed: with What I checked:
|
Fixes #1644
Owner: Dev3
Written-by: Dev-3
Reviewer: Reviewer
Branch:
dev/3-130-host-a-tool-result-never-closes-its-waitBase:
c26089f55d1b6a9817457dfb084d46d9e2904af6(main)Tip:
abd9a7e9a0e9484cc77f894b6b2908599e347e24Tree:
d5e934b3aaca93b8ce69b1416406ffcac9bf4f2aClaim:
af6aca314c394e8484759f1d65326b0bWhat was wrong
core/src/host/steering-interrupt.jsclosed a foreground wait withend(id, String(event.data?.callId ?? '')). The host writes a result as{ message: ToolResultMessage }, so the call id is ondata.message.toolCallId; the top-level read was always'',end()returned at its first line, andopenonly grew inside a turn.startedAtOf()therefore degraded to "when this turn's first tool started": the 60s line measured the turn's age instead of a wait's, and a human line arriving after a turn had merely been running 60s aborted it although every tool had already returned.core/src/host/turns.js:404read the same field, so the running-tool chip also stayed untilturn/end.The shipped tests were green because they built
data: { callId }— a shape the host never writes.What changed
core/src/host/steering-interrupt.js— close withevent.data?.callId ?? event.data?.message?.toolCallId; the top-level read stays first for older payloads, the waycore/src/host/flybot-feed.js:241already reads both.core/src/host/turns.js— the same read for the running-tool chip (one line, same class of bug).docs/subsystems/core-host.md— the steering-interrupt paragraph now names the payload field a wait closes from.changelog.d/1644-tool-result-closes-wait.fixed.md— the user-visible effect.patches/ds-bot/regenerated fromcore/(generate, thencheck).Untouched on purpose: the 60s threshold, one wait / one abort,
keepInbox,ownChat, and the trigger timing. Triggering onagent/inbox/splicedarrival instead of the loggeduser/messageis a separate decision and stays out.Tests
core/test/steering-interrupt.test.jsnow builds the payload the host writes (data.message.toolCallId) and adds three cases: a result at +5s closes the wait, so a human line at +61s does not abort a turn that only ran long; a closed wait does not age a later call (30s into the next call no abort, 61s into it one abort); a result naming its id at the top ofdatastill closes the wait.core/test/turns-tool-result.test.js(new) pins the same two shapes for the running-tool chip.Red first — test-only commit
67220d53on livemainc26089f5, source untouched:$ cd core && node --import ./test/harness-resolve.mjs --test test/steering-interrupt.test.js test/turns-tool-result.test.js— 10 tests / 6 pass / 4 fail:Verification at the tip
Tip SHA:
abd9a7e9a0e9484cc77f894b6b2908599e347e24Ran:
TZ=UTC ARCH_DOCS_BASE=c26089f55d1b6a9817457dfb084d46d9e2904af6 npm run verify— exit 0: core 1929, social 535, tree 125, timeline 129, workflow 234,.github549, interop 37, live-e2e 24, every suite# fail 0; oxlint 0 errors (warnings: core 64, social 36, timeline 9, tree 2, workflow 15, interop 0, live-e2e 0);arch-docs: OK (2 changed file(s));ok 10 patches apply cleanly in orderandok core/ equals ds-bot/ + patches/ds-bot/;changelog.d/valid (18 fragments).Not run: the DSH bench smoke (
dev/bench.sh smoke …) — it boots a profile on a free port and is not part ofverify. The change is one payload read, exercised by the unit cases above; say so if a smoke run is wanted for asrc/host/change.Checkpoint
{ "pr": 1645, "claim": "Dev3", "issue": 1644, "summary": "A tool result now closes the foreground wait it belongs to: the host writes the call id on data.message.toolCallId, so reading data.callId alone left every wait open until turn end. The 60s steering line therefore measured the turn's age, and a human line after a minute aborted a turn whose tools had all returned. The same read now clears the running-tool chip in turns.js. Thresholds, keepInbox and the trigger timing are unchanged.", "files": ["core/src/host/steering-interrupt.js", "core/src/host/turns.js", "core/test/steering-interrupt.test.js", "core/test/turns-tool-result.test.js", "docs/subsystems/core-host.md"], "checks": { "ran": "TZ=UTC npm run verify", "result": "green", "at": "abd9a7e9a0e9484cc77f894b6b2908599e347e24" }, "next": "none — ready for review" }