fix(chat): reconstruct agent tool-chain from agent_log rows when tool_trace empty (core#2636 follow-up) #2639
Reference in New Issue
Block a user
Delete Branch "feat/2636b-reconstruct-tooltrace-from-agentlog"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
PR #2637 persisted tool_trace end-to-end, but verified live on agents-team: 0/15 agent turns had a tool_trace column — the claude-code runtime emits tool steps as per-tool agent_log rows (the live-feed source), never into the A2A reply metadata. So chains still vanished on reload.
This reconstructs the chain entirely server-side from data already persisted: for each agent turn lacking a tool_trace column but with a duration_ms, it pulls the agent_log tool rows inside the turn's [end-duration, end] window (one batched query per page) and attaches them as the chain. Runtime-agnostic, no runtime release needed. formatTool renders a reconstructed entry as-is.
Tests: windowed reconstruction through full List; formatTool shapes; wire-order mock to 6 cols. messagestore + handlers + chat vitest green; canvas build green.
Refs core#2636.
🤖 Generated with Claude Code
REQUEST_CHANGES on current head
601ac3f164.The overall direction is right: reconstructing from
agent_logis the correct source for claude-code turns when the A2A reply metadata has notool_trace, and doing one bounded page-span query is the right performance shape.Blocker:
reconstructToolTracesFromAgentLogcurrently selects everyagent_logrow with a non-null summary inside the turn window and converts every summary into atoolTraceEntry. The only transformation isstrings.TrimPrefix(summary, "🛠 "); non-tool summaries pass through unchanged and will render under "N tools used" as if they were tools. That is both a correctness issue for the displayed tool chain and a scope issue: chat reload should persist the tool-use chain, not arbitrary live-feed/log summaries that happened during the same time window.Please restrict reconstruction to actual tool rows, e.g. add a query predicate or in-process filter for the tool marker (
summary LIKE '🛠 %'/strings.HasPrefix(strings.TrimSpace(summary), "🛠 ")), and add a regression test with a non-toolagent_logsummary inside the same [end-duration, end] window proving it is excluded while the two tool rows are kept.Secondary status note: current statuses still show Platform/Canvas/all-required in flight and advisory Local Provision red, so this also is not ready for approval on green yet. The implementation CI may settle, but the filtering issue above is independent.
APPROVED on current head
0e0f6c4f6b.Re-review of my prior blocker: fixed.
reconstructToolTracesFromAgentLognow filters at the SQL layer withsummary LIKE $2and passestoolSummaryPrefix+"%"(🛠 %), so non-toolagent_logsummaries in the turn window are not rehydrated as fake tools. The added tests assert the LIKE marker arg through sqlmock, verify only the marker tool row is bucketed, and covertoolNameFromSummarybehavior for marker and non-marker strings.5-axis ack:
tool_traceis empty, while preserving explicittool_tracewhen present.LIMIT 2000, no N+1 query per turn.Status note: targeted implementation checks visible to me are green (Handlers Postgres, E2E Chat, Canvas tabs, secret scan, lint). E2E API still shows running and Local Provision is advisory/red; governance qa/security gates are expected to clear from review.