Skip to content

Fix nameless live tool rows and prepare v1.0.13 - #151

Merged
shaohaozhi286 merged 2 commits into
masterfrom
claude/live-tool-rows-release-v1.0.13-20261020
Oct 19, 2026
Merged

shaohaozhi286 merged 2 commits into
masterfrom
claude/live-tool-rows-release-v1.0.13-20261020

Conversation

@shaohaozhi286

Copy link
Copy Markdown
Collaborator

Problem

During a running turn the Web transcript (seen on a colleague's phone) occasionally showed a run of rows labelled only Tool; expanding one showed the result but 请求未记录(旧记录未保存工具调用参数) for the request. The rows fixed themselves after the turn finished, when the completed-turn self-heal reloaded history.

Root cause

Besides tool_start / tool_end, every tool call is mirrored on the wire by two display-only message events, tool_call and tool_result. They carried no call id, and their message id was a content hash. As a result:

  1. The client had to guess which tool row each one belonged to, by tool name and position across the whole transcript.
  2. Two calls with identical content (the same git status, the same output) had the same id, so the live reducer merged the second into the first.
  3. When switching into a running session (REST history plus event-ring replay), replayed tool_call rows were de-duplicated against history by content. Replayed tool_result rows were not, because history stores them as role tool. They were appended as a run of nameless rows.

Reproduced with a node script against sessionTranscript.js + transcriptProjection.js before the fix.

Changes

  • Daemon: tool_call / tool_result rows now carry metadata.tool_call_id, tool_index and tool_name, matching tool_start. Their id includes the call id, so it is distinct per call. Documented in docs/daemon-api.md.
  • Web: live tool rows are never merged by message id. Replayed rows are de-duplicated against history by call id, on both the WS-reconnect path and the REST catch-up path.
  • Fallback: if a result in the current turn still has no request (for example, it was lost in a reconnect gap), the row shows its tool name right away. After 600 ms one REST tail fetch inserts the persisted assistant.tool_calls request before it. Each call id is tried once, and the timer is not reset by streaming updates.
  • Version bumped to 1.0.13 (CMakeLists.txt, vcpkg.json).

Verification

  • node src/lib/runTests.js (web): 3281 passed, rebased on current master
  • vite build + check-regex-compat: OK
  • New tests: web/src/lib/sessionTranscriptToolRows.test.js (5 cases) and AgentLoopToolLifecycleEvents.PseudoToolRowsCarryCallIdentity
  • Changed C++ translation units compile (-fsyntax-only). The full local acecode_unit_tests run was still building when this PR was opened; CI on this PR covers it.

🤖 Generated with Claude Code

tmoonlight and others added 2 commits October 20, 2026 01:13
During a running turn the Web transcript could show a run of rows labelled
only "Tool" whose detail had a result but "请求未记录" for the request; they
fixed themselves once the completed-turn self-heal reloaded history.

Each tool call is mirrored on the wire by display-only tool_call /
tool_result message events. They carried no call id and a content-hash
message id, so the client had to guess their owner by global name and order,
merged repeated calls with identical content (the same git status, the same
output) into one item, and when switching into a running session appended
replayed tool_result rows that history already held.

- Daemon: tool_call / tool_result rows carry metadata tool_call_id,
  tool_index and tool_name, and their id includes the call id.
- Web: live tool rows are never merged by message id; replayed rows are
  de-duplicated against history by call id (WS replay and REST catch-up).
- Fallback: a current-turn result whose request never arrived shows its tool
  name, and a REST tail fetch inserts the persisted request before it.

Tests: web/src/lib/sessionTranscriptToolRows.test.js,
AgentLoopToolLifecycleEvents.PseudoToolRowsCarryCallIdentity.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@shaohaozhi286
shaohaozhi286 merged commit 60c6bee into master Oct 19, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants