Skip to content

feat(serve): stream tool input and output in tool events - #488

Merged
emal-avala merged 1 commit into
mainfrom
feat/client-ui-components
Jul 25, 2026
Merged

feat(serve): stream tool input and output in tool events#488
emal-avala merged 1 commit into
mainfrom
feat/client-ui-components

Conversation

@emal-avala

Copy link
Copy Markdown
Member

Summary

The tool events on the serve SSE and WebSocket streams carried only a tool name (plus an error flag), dropping both the arguments and the output. A client could show that "FileEdit ran" — but not which file, and not the diff. Any GUI or API consumer was stuck rendering a bare tool name with no detail.

What changed

  • tool_start now carries input (the tool's arguments), so clients can render a detail line: the bash command, the edited file path, the search pattern, the fetched URL.
  • tool_result now carries content (the tool's output), so clients can render it — notably the unified diff the edit tools already return, which enables inline diff review in a GUI (the counterpart of what the terminal client renders today).
  • Output is capped at 64 KiB with a truncation marker. Events are broadcast to every subscriber and cloned per subscriber, so an unbounded result — a large FileRead, a chatty shell command — would otherwise be copied wholesale into the channel.

Both fields are additive, so existing consumers are unaffected (they simply ignore the new keys).

Verification

  • New tests cover the serialized wire shape (tool_start.input, tool_result.content, diff content surviving serialization) and truncation — including the multi-byte-char boundary case, which would otherwise panic on a naive slice.
  • cargo test (12 pass in this module), cargo clippy --all-targets -- -D warnings, cargo fmt --all -- --check all clean.

Why now

This unblocks rich tool cards + inline diffs in the Flutter client — without it the client has nothing to render. Shipping it separately keeps the protocol change reviewable on its own.

The tool events on the SSE and WebSocket streams carried only a tool name
(and an error flag), dropping both the arguments and the output. A client
could show that "FileEdit ran" but not which file, nor the diff — so any
GUI or API consumer had to render a bare name with no detail.

- tool_start now carries `input` (the tool's arguments), so clients can show
  a detail line: the bash command, the edited path, the search pattern.
- tool_result now carries `content` (the tool's output), so clients can
  render it — notably the unified diff that the edit tools already return.
- Output is capped at 64 KiB with a truncation marker. Events are broadcast
  and cloned per subscriber, so an unbounded result (a large FileRead, a
  chatty command) would otherwise be copied wholesale into the channel.

Both fields are additive, so existing consumers are unaffected. Tests cover
the serialized shape and the truncation, including multi-byte boundaries.
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, add credits to your account and enable them for code reviews in your settings.

@emal-avala
emal-avala merged commit 8fd1439 into main Jul 25, 2026
14 of 15 checks passed
@emal-avala
emal-avala deleted the feat/client-ui-components branch July 25, 2026 05:04
@emal-avala emal-avala mentioned this pull request Jul 25, 2026
8 tasks
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.

1 participant