feat(chat): persist agent tool-chain across reload + nudge requester ack into My Chat (core#2636) #2637

Merged
devops-engineer merged 1 commits from feat/2636-decision-visible-and-tooltrace-persist into main 2026-06-12 10:57:13 +00:00
Member

Resolves both user-reported gaps from the request/approval flow.

1. Tool-chain progress survives refresh. The live feed is ephemeral; the agent reply's metadata.tool_trace was stored on the a2a_receive row but chat-history never selected it. Now the message store reads tool_trace and emits it on the agent ChatMessage; the canvas maps it to toolTrace and renders a collapsible "N tools used" chain under the agent bubble (ToolTraceChips). A reload re-shows the same steps.

2. Decisions are no longer silent. Respond/notification rides a background A2A turn that never renders in My Chat — so the agent woke, get_request'd, and ended its turn invisibly. The notification text now instructs the agent to acknowledge via send_message_to_user (which DOES render) when the outcome changes what it owes the user. The canvas decision-chip half stays tracked in #2636.

Tests: messagestore tool_trace carry + 5-col wire-order mock; ToolTraceChips collapse/expand/singular; full handlers + messagestore Go suites + canvas build + chat vitest all green.

Refs core#2636, #2614.

🤖 Generated with Claude Code

Resolves both user-reported gaps from the request/approval flow. **1. Tool-chain progress survives refresh.** The live feed is ephemeral; the agent reply's `metadata.tool_trace` was stored on the a2a_receive row but chat-history never selected it. Now the message store reads `tool_trace` and emits it on the agent ChatMessage; the canvas maps it to `toolTrace` and renders a collapsible "N tools used" chain under the agent bubble (ToolTraceChips). A reload re-shows the same steps. **2. Decisions are no longer silent.** Respond/notification rides a background A2A turn that never renders in My Chat — so the agent woke, `get_request`'d, and ended its turn invisibly. The notification text now instructs the agent to acknowledge via `send_message_to_user` (which DOES render) when the outcome changes what it owes the user. The canvas decision-chip half stays tracked in #2636. Tests: messagestore tool_trace carry + 5-col wire-order mock; ToolTraceChips collapse/expand/singular; full handlers + messagestore Go suites + canvas build + chat vitest all green. Refs core#2636, #2614. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
core-devops added 1 commit 2026-06-12 10:52:29 +00:00
feat(chat): persist+rehydrate agent tool-chain across reload; nudge requester ack into My Chat (core#2636)
Handlers Postgres Integration / detect-changes (pull_request) Successful in 3s
Harness Replays / detect-changes (pull_request) Successful in 4s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 3s
E2E API Smoke Test / detect-changes (pull_request) Successful in 6s
CI / Python Lint & Test (pull_request) Successful in 6s
E2E Chat / detect-changes (pull_request) Successful in 6s
Harness Replays / Harness Replays (pull_request) Successful in 1s
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 8s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 7s
sop-checklist / review-refire (pull_request_target) Has been skipped
reserved-path-review / reserved-path-review (pull_request_target) Successful in 4s
sop-checklist / all-items-acked (pull_request) acked: 0/7 — missing: comprehensive-testing, local-postgres-e2e, staging-smoke, +4 — body-unfilled: comprehensive-testing, local-postgres-e2
sop-checklist / na-declarations (pull_request) N/A: (none)
E2E Chat / E2E Chat (pull_request) Successful in 4s
sop-checklist / all-items-acked (pull_request_target) Successful in 4s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 8s
gate-check-v3 / gate-check (pull_request_target) Failing after 14s
CI / Detect changes (pull_request) Successful in 20s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 18s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 2s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 4s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 48s
Local Provision Lifecycle E2E / Local Provision Lifecycle E2E (stub) (pull_request) Failing after 56s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 57s
Local Provision Lifecycle E2E / Local Provision Lifecycle E2E (real image + MiniMax LLM, advisory) (pull_request) Failing after 20s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 2m26s
CI / Platform (Go) (pull_request) Successful in 2m51s
CI / Canvas (Next.js) (pull_request) Successful in 3m30s
CI / Canvas Deploy Status (pull_request) Successful in 1s
CI / all-required (pull_request) Successful in 4s
qa-review / approved (pull_request_target) Approved via pull_request_review trigger
security-review / approved (pull_request_target) Approved via pull_request_review trigger
reserved-path-review / reserved-path-review (pull_request_review) Successful in 3s
qa-review / approved (pull_request_review) Successful in 4s
security-review / approved (pull_request_review) Successful in 3s
audit-force-merge / audit (pull_request_target) Successful in 3s
3af3d3d121
Two user-reported gaps, both about request/agent activity being
invisible to the user:

1. Tool-chain progress vanished on refresh. The live progress feed
   (activityLog) is ephemeral local state; the agent reply persisted via
   the a2a_receive row carries metadata.tool_trace, but chat-history
   never SELECTed it. Now the message store reads tool_trace and emits
   it on the AGENT ChatMessage; the canvas maps tool_trace->toolTrace and
   renders a collapsible "N tools used" chain under the agent bubble
   (ToolTraceChips), so a reload re-shows the same steps.

2. Decisions felt silent. A respond/notification rides a background A2A
   turn that never renders in My Chat, so the agent woke, get_request'd,
   and ended its turn with nothing visible to the user. The notification
   text now tells the agent: if the outcome changes what you owe the
   user, acknowledge briefly with send_message_to_user (which DOES render
   in chat). The canvas decision-chip half is tracked separately in #2636.

Tests: messagestore tool_trace carry + wire-order (5-col mock);
ToolTraceChips collapse/expand/singular; full handlers + messagestore
green; canvas build + chat vitest green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
agent-reviewer-cr2 approved these changes 2026-06-12 10:56:58 +00:00
agent-reviewer-cr2 left a comment
Member

APPROVED on current head 3af3d3d121.

Full SOP / 5-axis review:

  • Correctness: messagestore now selects and scans tool_trace, carries it only on the agent ChatMessage, and the canvas history hook maps server tool_trace into toolTrace so tool-chain progress survives reload. The notification copy also explicitly tells the requester agent when to use send_message_to_user, addressing the My Chat visibility gap without changing request state semantics.
  • Robustness: null/empty tool_trace is omitted; existing chat-history pagination/order tests were updated and a focused agent-message trace test was added. Frontend component handles empty, singular, and expanded traces.
  • Security: no new secret-bearing transport beyond the already persisted trace preview; React text rendering escapes the displayed tool/input strings. The notification wording avoids exposing hidden background turns to the user and instructs explicit user-visible acknowledgement only when owed.
  • Performance: bounded per-message rendering; collapsed by default, so long traces do not expand the chat by default.
  • Readability/QA: code is localized and tests cover backend carry-through plus canvas rendering. Required implementation CI is green (Platform (Go), Canvas, E2E API Smoke, Handlers Postgres, secret scan). Governance/security contexts are expected to clear with review approval.
APPROVED on current head 3af3d3d121efc1365521f5f772f104fc27c763ac. Full SOP / 5-axis review: - Correctness: `messagestore` now selects and scans `tool_trace`, carries it only on the agent `ChatMessage`, and the canvas history hook maps server `tool_trace` into `toolTrace` so tool-chain progress survives reload. The notification copy also explicitly tells the requester agent when to use `send_message_to_user`, addressing the My Chat visibility gap without changing request state semantics. - Robustness: null/empty `tool_trace` is omitted; existing chat-history pagination/order tests were updated and a focused agent-message trace test was added. Frontend component handles empty, singular, and expanded traces. - Security: no new secret-bearing transport beyond the already persisted trace preview; React text rendering escapes the displayed tool/input strings. The notification wording avoids exposing hidden background turns to the user and instructs explicit user-visible acknowledgement only when owed. - Performance: bounded per-message rendering; collapsed by default, so long traces do not expand the chat by default. - Readability/QA: code is localized and tests cover backend carry-through plus canvas rendering. Required implementation CI is green (`Platform (Go)`, `Canvas`, `E2E API Smoke`, `Handlers Postgres`, secret scan). Governance/security contexts are expected to clear with review approval.
devops-engineer merged commit b22a0854eb into main 2026-06-12 10:57:13 +00:00
Sign in to join this conversation.
No Reviewers
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: molecule-ai/molecule-core#2637