Skip to content

feat(chat): run chat turns in CodeAct mode with a JS graph object model - #4766

Merged
georgi merged 2 commits into
mainfrom
claude/websocket-codeact-workflow-editing-7nqsxb
Aug 6, 2026
Merged

feat(chat): run chat turns in CodeAct mode with a JS graph object model#4766
georgi merged 2 commits into
mainfrom
claude/websocket-codeact-workflow-editing-7nqsxb

Conversation

@georgi

@georgi georgi commented Aug 6, 2026

Copy link
Copy Markdown
Collaborator

What

Two connected changes, closing the "chat/websocket toolbelt" follow-up from docs/codeact-design.md:

  1. The chat websocket honors the CodeAct setting. When NODETOOL_AGENT_EXECUTION_MODE (the existing Settings entry) resolves to codeact, a plain chat turn presents a single execute_code provider tool instead of the toolbelt. The model acts by writing sandboxed JavaScript over the same tools (tools.<name>()), with a state object persisting across the turn's actions and in-sandbox searchTools() replacing the ToolSearch deferral machinery. view_image stays a direct provider tool — it is the one channel that puts pixels into model context, which cannot ride the JSON observation envelope. Default mode is unchanged (tools).

  2. Workflow graph and node editing happens on a JS object model. When the belt carries the ui_* workflow document tools, code actions get openWorkflow(workflowId): synchronous mutators (addNode, connect, node(id).set/.setTitle/.moveTo/.remove, removeNode, removeEdge) edit a local mirror and queue ops, and await wf.commit() replays the queue through the same bridged ui_* tools — so client/server routing, validation, and live-editor sync are untouched, and one code action builds a whole graph. A failed commit names the failing op and keeps it (plus later ops) queued for retry; removing a never-committed node cancels its queued ops instead of issuing a delete.

How

  • packages/agents/src/codeact/chat-codeact.tscreateChatCodeActSession: a chat toolbelt mixes server tools with client (ui_*) tools that exist server-side only as schemas, so instead of buildToolBridge the session bridges every tools.<name>() call to the chat runner's own executeTool router — permission gating, ToolBridge client round-trips, and asset materialization stay where they are.
  • packages/agents/src/codeact/graph-model.ts — the openWorkflow() guest prelude and its prompt section.
  • packages/agents/src/codeact/{tool-api,prompt}.ts — signature rendering and buildCodeActSystemPrompt generalized to schema-shaped tools (ToolSignatureSource), plus a "chat" prompt variant (no finish(); asking the user is allowed; a plain assistant message ends the turn).
  • packages/websocket/src/unified-websocket-runner.ts — mode resolution at toolbelt assembly, session creation once the processing context exists (prompt section lands before the system message is materialized; the tool router is late-bound), execute_code routed into the session, sequentialTools for codeact turns.
  • Settings description, docs/codeact-design.md, and packages/agents/CLAUDE.md updated.

Testing

  • New packages/agents/tests/chat-codeact.test.ts (11 tests, real QuickJS sandbox, fake router, no network): tool bridging + call ids, {error} payloads thrown in-guest, state persistence, finish() chat guidance, searchTools() hits, prompt-section content, and the graph model — queued-op replay order/args, commit-failure retry semantics, uncommitted-node cancellation, existing-graph mirror reads.
  • packages/agents suite: 140 files / 2090 tests pass. packages/websocket suite: 191 files / 2216 tests pass. npm run build:packages: all 59 packages build. Web + electron typecheck clean (mobile typecheck fails only on uninstalled Expo deps in this sandbox, pre-existing). Lint findings on touched packages are all pre-existing lines.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Cw9JB24wa34eZJ4qsCT1SZ


Generated by Claude Code

When the agent execution mode setting is 'codeact', the chat websocket
runner now presents a single execute_code tool instead of the toolbelt:
the model acts by writing sandboxed JavaScript over the same tools, with
per-turn state, in-sandbox searchTools() discovery (replacing the
ToolSearch deferral machinery), and view_image kept as a direct provider
tool since pixels cannot ride the JSON observation envelope.

The adapter is createChatCodeActSession (packages/agents): unlike the
step executor's buildToolBridge it routes every tools.<name>() call
through the chat runner's own executeTool, so permission gating, client
(ui_*) round-trips over the ToolBridge, and asset materialization stay
where they are.

Workflow graph and node editing happens through a JS object model: when
the belt carries the ui_* document tools, actions get openWorkflow(),
whose synchronous mutators (addNode/connect/set/setTitle/moveTo/remove)
edit a local mirror and queue ops that commit() replays through the same
ui_* contract — one code action builds a whole graph, and a failed
commit names the failing op and keeps the queue for a retry.

Also generalizes the codeact signature renderer and system prompt to
schema-shaped tools and adds a 'chat' prompt variant (no finish(),
asking the user is allowed).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Cw9JB24wa34eZJ4qsCT1SZ
@georgi
georgi enabled auto-merge (squash) August 6, 2026 16:20
…resolving actions)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Cw9JB24wa34eZJ4qsCT1SZ

georgi commented Aug 6, 2026

Copy link
Copy Markdown
Collaborator Author

CI is red from a GitHub Actions outage, not the diff: every failed job (both on the original head and on the 7868fc2 re-trigger) died during runner setup with Failed to resolve action download info. Error: Service Unavailable — no project code ran. The outage was still active as of 16:28 UTC.

My token can't re-run failed jobs (403), so I'll push a re-trigger once the outage clears. Anyone with Actions write access can get there sooner via Re-run failed jobs on the E2E run and the Test run. Local verification of the branch is green: agents (2090 tests) and websocket (2216 tests) suites, all 59 packages build, web + electron typecheck.


Generated by Claude Code

@georgi
georgi merged commit d833ff7 into main Aug 6, 2026
5 of 17 checks passed
@georgi
georgi deleted the claude/websocket-codeact-workflow-editing-7nqsxb branch August 6, 2026 22:21
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.

2 participants