Skip to content

th-d9fa29: talk to your Smooth Operator again — rewire over the SEP WebSocket#249

Merged
brentrager merged 1 commit into
mainfrom
th-d9fa29-sep-ws-rewire
Jul 23, 2026
Merged

th-d9fa29: talk to your Smooth Operator again — rewire over the SEP WebSocket#249
brentrager merged 1 commit into
mainfrom
th-d9fa29-sep-ws-rewire

Conversation

@brentrager

Copy link
Copy Markdown
Contributor

Problem

POST /organizations/{org}/smooth-operator/chat was deleted upstream (SMOODEV-2673, PR #3171) along with the whole run_turn path — it is not coming back. So both surfaces that talk to the org agent were pointed at a dead route and 404'd:

  • ask_business — the MCP tool Claude Desktop / Cursor / VS Code use
  • th api smooth-operator chat — the CLI

Fix

New smooai::smooth_operator_ws::operator_turn drives the supported SEP WebSocket transport:

  1. mint a short-lived ES256 socket token — POST /organizations/{org}/smooth-operator/token
  2. connect wss://smooth-operator.smoo.ai/ws?token=…
  3. create_conversation_session (pass conversationId to resume) → send_message {stream:true}
  4. buffer frames until the terminal eventual_response

Hand-rolled deliberately: the smooth-operator crates are server-side only and ship no Rust client, so this matches the wire shapes in smooth-operator-server's protocol.rs / handler.rs. Adds tokio-tungstenite + futures-util.

Approval model got better

Confirmation is now inline: the socket parks the turn on write_confirmation_required and takes confirm_tool_action on the same connection. So approval is a flag (approve: true / --confirm) instead of a second round-trip. Without it, the destructive action is declined and reported ("I did NOT do this without your approval"), never silently run. The old th api smooth-operator confirm subcommand is retired with an explanation, and the dead REST turn types/helpers are deleted.

Verification — live against production, both surfaces

  • ask_business over MCP → real operator reply + threaded conversation_id.
  • th api smooth-operator chat → round-tripped over the socket.
  • 375 tests pass; clippy clean on all touched files; docs updated (zero remaining references to the dead route).

Unblocks the "talk to your business from Claude Desktop / Cursor / the CLI, authed via th auth login" story end-to-end (epic th-093ce3).

🤖 Generated with Claude Code

…WebSocket

POST /organizations/{org}/smooth-operator/chat was DELETED upstream
(SMOODEV-2673), so ask_business (Claude Desktop/Cursor) and the CLI both 404'd
against a route that is never coming back.

Add smooai::smooth_operator_ws::operator_turn — mint a short-lived ES256 socket
token from api-prime, connect wss://smooth-operator.smoo.ai/ws,
create_conversation_session (resume by conversationId) -> send_message ->
buffer frames until eventual_response. Hand-rolled: the smooth-operator crates
are server-side and ship no Rust client, so this matches the wire shapes in
smooth-operator-server's protocol.rs / handler.rs.

Confirmation is now INLINE — the socket parks the turn on
write_confirmation_required and takes confirm_tool_action on the same
connection. So approval is a flag (ask_business approve=true / chat --confirm)
rather than a second round-trip; without it the action is declined and
surfaced, never silently run. Retires `th api smooth-operator confirm` (now
explains the change) and deletes the dead REST turn types/helpers.

Verified LIVE against production on both surfaces: ask_business returned a real
operator reply + conversation id over MCP, and `th api smooth-operator chat`
round-tripped over the socket. 375 tests pass; clippy clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015ZctFb4oiWoJraHN2db1nX
@changeset-bot

changeset-bot Bot commented Jul 23, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 68294ff

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 Minor

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 enabled auto-merge (squash) July 23, 2026 22:17
@brentrager
brentrager merged commit 0ad504f into main Jul 23, 2026
3 checks passed
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