Skip to content

Pearl th-248f33: th code speaks the canonical operator protocol — parity with Big Smooth - #287

Merged
brentrager merged 1 commit into
mainfrom
th-248f33-canonical-client
Jul 27, 2026
Merged

Pearl th-248f33: th code speaks the canonical operator protocol — parity with Big Smooth#287
brentrager merged 1 commit into
mainfrom
th-248f33-canonical-client

Conversation

@brentrager

Copy link
Copy Markdown
Contributor

The problem

th code spoke a protocol whose server no longer exists. It sent TaskStart and waited for a Connected event from smooth-bigsmooth — a crate deleted with the microVM stack (th-f4a801). Big Smooth now hosts smooth-operator's canonical, schema-driven WS, so nothing had spoken th code's dialect in months. Every turn died on "Timed out waiting for Connected event" (surfaced once the 401 was fixed in #281).

The fix — another interface, not another protocol

th code is now a first-class canonical client, exactly like the web SPA (crates/smooth-web/web/src/operator.ts): same daemon, same conversations, same sessions, same tools — just a terminal instead of a browser.

  • create_conversation_session on connect; its reply is the connection signal and carries the session id.
  • send_message per turn; streaming back over stream_token / stream_chunk.

Translation happens at the edge of client.rs, mapping canonical frames onto the TUI's existing internal event vocabulary — so app.rs and render.rs are untouched. That keeps this a focused change instead of a TUI rewrite.

Details taken from the shipped client, not guessed

  • Tool calls and results both nest under rawResponse. operator.ts documents that reading state.toolResult leaves every tool chip stuck "running" forever — I'd have walked straight into it.
  • stream_reasoning is dropped, never merged into the answer stream (th-4d8682, and the persona's no-chain-of-thought rule).
  • Cancel/steer have no canonical verb, so they emit nothing rather than a frame the server would reject — with a test asserting exactly that.

Verification

262 tests green. 8 new ones cover the translation contract (session-reply→connected, non-session immediate_response must not be mistaken for the handshake, token/tool/reasoning mapping, no-invented-verbs). The pre-existing send test asserted the dead bespoke shape and now asserts the canonical one.

End-to-end against the live daemon — a real turn streams a reply:

You:  reply with exactly: PARITY OK
Smooth:  PARITY OK

🤖 Generated with Claude Code

th code sent TaskStart and waited for a bespoke `Connected` event from
smooth-bigsmooth — a crate deleted with the microVM stack. Big Smooth hosts
smooth-operator's canonical schema-driven WS, so every turn timed out.

th code is now a first-class canonical client like the web SPA:
create_conversation_session on connect (its reply IS the connection signal and
carries the session id), send_message per turn, streaming via
stream_token/stream_chunk. Same daemon, conversations, sessions and tools —
different interface.

Translation lives at the edge of client.rs onto the TUI's existing internal
events, so app.rs/render.rs are untouched. Learned from operator.ts rather than
guessed: toolCall AND toolResult both nest under rawResponse (reading
state.toolResult strands every tool on "running"); stream_reasoning is dropped
so chain-of-thought never renders as the answer; cancel/steer have no canonical
verb so they emit nothing instead of a rejected frame.

262 tests green (8 new covering the translation contract; the pre-existing send
test now asserts the canonical shape). Verified end-to-end: a real turn against
the live daemon streams a reply.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TwUg6nyMqXHzFDsibzTKmp
@changeset-bot

changeset-bot Bot commented Jul 27, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: a4aeb1e

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@smooai/smooth Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@brentrager
brentrager merged commit fbf6a71 into main Jul 27, 2026
3 checks passed
@brentrager
brentrager deleted the th-248f33-canonical-client branch July 27, 2026 14:18
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