feat(chat): run chat turns in CodeAct mode with a JS graph object model - #4766
Merged
Merged
Conversation
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
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
Collaborator
Author
|
CI is red from a GitHub Actions outage, not the diff: every failed job (both on the original head and on the 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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Two connected changes, closing the "chat/websocket toolbelt" follow-up from
docs/codeact-design.md:The chat websocket honors the CodeAct setting. When
NODETOOL_AGENT_EXECUTION_MODE(the existing Settings entry) resolves tocodeact, a plain chat turn presents a singleexecute_codeprovider tool instead of the toolbelt. The model acts by writing sandboxed JavaScript over the same tools (tools.<name>()), with astateobject persisting across the turn's actions and in-sandboxsearchTools()replacing the ToolSearch deferral machinery.view_imagestays 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).Workflow graph and node editing happens on a JS object model. When the belt carries the
ui_*workflow document tools, code actions getopenWorkflow(workflowId): synchronous mutators (addNode,connect,node(id).set/.setTitle/.moveTo/.remove,removeNode,removeEdge) edit a local mirror and queue ops, andawait wf.commit()replays the queue through the same bridgedui_*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.ts—createChatCodeActSession: a chat toolbelt mixes server tools with client (ui_*) tools that exist server-side only as schemas, so instead ofbuildToolBridgethe session bridges everytools.<name>()call to the chat runner's ownexecuteToolrouter — permission gating, ToolBridge client round-trips, and asset materialization stay where they are.packages/agents/src/codeact/graph-model.ts— theopenWorkflow()guest prelude and its prompt section.packages/agents/src/codeact/{tool-api,prompt}.ts— signature rendering andbuildCodeActSystemPromptgeneralized to schema-shaped tools (ToolSignatureSource), plus a"chat"prompt variant (nofinish(); 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_coderouted into the session,sequentialToolsfor codeact turns.docs/codeact-design.md, andpackages/agents/CLAUDE.mdupdated.Testing
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,statepersistence,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/agentssuite: 140 files / 2090 tests pass.packages/websocketsuite: 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