Skip to content

fix(frontend/sdk): show every tool call the same way, live and after reload - #5932

Merged
mmabrouk merged 3 commits into
release/v0.112.0from
fix/transcript-parity
Aug 11, 2026
Merged

fix(frontend/sdk): show every tool call the same way, live and after reload#5932
mmabrouk merged 3 commits into
release/v0.112.0from
fix/transcript-parity

Conversation

@mmabrouk

Copy link
Copy Markdown
Member

Context

The same tool call looked different depending on when you looked at it. A commit approval card rendered as a clean "what is changing" view while the turn streamed, then a background refresh rebuilt the chat from the saved records and the same card degraded to a raw JSON blob. The cause: the chat has two builders (one for the live stream, one for the saved records), and they drifted apart with no test forcing them to agree. Found and diagnosed on 2026-08-11, sessions 3d99d178 and f60bc4f8 on the dev stack. This PR stacks on #5919; its base will move to the release branch when that PR merges.

Changes

Four fixes, each making the two builders agree, plus the tests that keep them agreeing.

  1. Replay unwraps the transport envelope. Saved records store a tool call's input as {tool, server, arguments: {...}}. The cards read the bare arguments. Both replay copies now unwrap conservatively (only when every sibling of arguments is a string envelope key), so a replayed commit card finds workflow_revision at the top level and renders the real diff view instead of JSON.

  2. The live stream shows the bare arguments too (Python SDK). Ordinary tool calls streamed the envelope, and a gated call could show the bare form first and the envelope moments later. The SDK's stream adapter now unwraps with the same rule, so live and reload show the same input, always.

Before (live, ordinary MCP call):

{"tool": "discover_tools", "server": "agenta-tools", "arguments": {"query": "telegram"}}

After (live and reload):

{"query": "telegram"}
  1. Replayed approval cards use the resolved tool name. Replay kept the raw wire name, so a reloaded card said "Mcp.agenta tools.commit revision" where live said "Commit revision". Worse, the raw name slipped past the guard that keeps platform operations ungrantable: a replayed card could offer "Always allow" for commit_revision and store a permission key the runner can never match. Both copies now resolve the name the same way the live stream does; live and replayed cards produce the same name, the same grant eligibility, and the same permission key end to end.

  2. Golden parity tests from real sessions. Three real sessions (commits, schedules, forms, connects, both interaction-row generations) are captured as fixtures, together with the actual output of the live builder over the same events. New suites assert: the two replay copies stay identical outside three documented, individually-pinned divergences; every replayed part carries the exact shape each card component reads (each assertion cites the component line it protects); and replayed parts equal live parts for the same records. Any future drift between the builders is a red build, not a UI surprise.

Also: the secret scanner config allowlists exactly the uuid-shaped interaction tokens inside the new fixtures (they are join keys, not credentials), verified against the gitleaks version CI pins; planted real-key shapes in the same files are still caught.

Tests

  • Both replay suites extended (unwrapping, resolved names); the new parity suites: builder copy-parity, per-card shape contracts, live-versus-replay equality; the permission-key chain test (card name to stored grant to runner matcher).
  • Python SDK: 17 new stream-adapter tests; full agents suite 878 passed. ruff clean under CI's pinned version.
  • web/oss AgentChatSlice: 30 files, 334 passed. tsc, eslint, prettier clean.

What to QA

  • Open an old codex session (for example the Arabic-poetry agent). The commit approval card shows the description and the config diff, and it stays that way after a reload. No raw {tool, server, arguments} JSON anywhere.
  • Run a new agent turn with a tool call and compare the tool row live versus after a reload: identical input both times.
  • Regression: approve a tool call live; the approval card and its "Always allow" options look and behave as before.

@vercel

vercel Bot commented Aug 11, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
agenta-documentation Error Error Aug 11, 2026 11:14am

Request Review

@dosubot dosubot Bot added size:XL This PR changes 500-999 lines, ignoring generated files. frontend python Pull requests that update Python code tests labels Aug 11, 2026
@coderabbitai

coderabbitai Bot commented Aug 11, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

🗂️ Base branches to auto review (1)
  • release/.*

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: c9b0f58b-9105-4818-8428-358928866478

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@mmabrouk

Copy link
Copy Markdown
Member Author

Added a second commit: fix(runner) for the empty codex tool outputs. The runner only knew how to read text results; codex reports results as objects, so 100% of codex tool outputs and error messages stored and streamed empty. The runner now reads the object shapes (verified against the pinned codex bridge source), with 10 new unit tests on a path that had none. Proven live on the dev stack with the real payload shapes; a failed call now shows its actual error text. Claude and pi paths are untouched.

@github-actions

github-actions Bot commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Railway Preview Environment

Status Destroyed (PR closed)

Updated at 2026-08-11T11:31:30.719Z

@mmabrouk
mmabrouk requested a review from ardaerzin August 11, 2026 10:58

@mmabrouk mmabrouk left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@mmabrouk mmabrouk added the lgtm This PR has been approved by a maintainer label Aug 11, 2026
@mmabrouk
mmabrouk force-pushed the fix/transcript-parity branch from 2dbce76 to 9d072e1 Compare August 11, 2026 11:14
@mmabrouk
mmabrouk changed the base branch from feat/interaction-card-lifecycle to release/v0.112.0 August 11, 2026 11:25
@mmabrouk
mmabrouk merged commit fefbb8b into release/v0.112.0 Aug 11, 2026
66 of 69 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

frontend lgtm This PR has been approved by a maintainer python Pull requests that update Python code size:XL This PR changes 500-999 lines, ignoring generated files. tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant