Skip to content
Content
Agent

codeact

**Navigation**: [Agents package rules](../AGENTS.md) → **CodeAct Execution**

From plugin
nodetool
63614 skills14 agents

Claude Code

$ npx -y skills add nodetool-ai/nodetool --agent claude-code

Agent definition

codeact.md

CodeAct Execution (`src/codeact/`)

**Navigation**: [Agents package rules](../AGENTS.md) → **CodeAct Execution**

Paths are relative to `packages/agents/` unless they name another package.

The action space of the step loop, and the only one. Each step acts by writing JavaScript that runs in the QuickJS sandbox with the toolbelt exposed as imports from `@nodetool-ai/sandbox-nodetool/<namespace>`, `finish(result)` for host-validated completion, and memory (`nodetool.memory.*`) for results a later action or turn needs — there is no cross-action variable bag. The prompt tells the model to record each generate/speak result (an `asset://` uri) with `nodetool.memory.save` and reuse it; local variables die with the action, and `return` is the observation only. A step action runs with no guest `fetch` and no secret scope: network and secrets are reached only through the gated capabilities, the same rule the chat session's actions run under. Design and the research it follows (CodeAct, ICML 2024): docs/codeact-design.md.

  • `CodeActExecutor` keeps the message contract, memory writes, and failure

semantics the step loop has always had — consumers work unchanged. Bridged tool calls surface as `tool_call_update` events (ids `codeact_<n>`).

  • A bridged call whose result carries an `error` string throws in the guest

(`extractErrorPayload` in `tool-api.ts`). A `missing_pack` refusal is no exception: it throws `missing_pack: <pack and install step>`, and a guest that wants to continue catches it.

  • The core set goes top level. Every NodeTool tool that mirrors a Claude Agent

SDK built-in (`CORE_TOOL_NAMES` in `@nodetool-ai/runtime` — the file set, `glob`/`grep`, `web_search`, `browser`/`http_request`/`download_file`, `todo_write`, `run_subtask`) is offered to the provider as an ordinary tool next to `execute_code`, for every provider. Those are the shapes models are trained on, so a tool call beats a sandbox round trip that only forwards one. They stay on the belt — `nodetool.web`, `nodetool.agents` and hand-written fan-out call them from code — but the prompt documents them once, under "Direct tools", instead of as a catalog signature. `splitCoreTools` / `buildCoreProviderTools` in `src/codeact/tool-api.ts`.

  • Discovery goes top level with it. `DISCOVERY_TOOL_NAMES` (`find_model`,

`list_models`, `list_provider_models`, `search_nodes`, `get_node_info`, `list_nodes`) answers which providers, models and node types this install has — one question with one answer, and a wrong answer is a hallucinated model id that fails at generation time, after the run was paid for. The two sets stay apart because only the core set has SDK built-ins behind it: `DIRECT_TOOL_NAMES` is their union and is what the four offer sites read (`splitCoreTools`, the CLI turn, the websocket runner, and the MCP mount), while `SDK_NATIVE_TOOL_REPLACEMENTS` still reads `CORE_TOOL_NAMES` alone. `nodetool.models.pick` and `nodetool.nodes.search` are unchanged — the belt keeps every tool, so an action still composes them.

  • The MCP mount subtracts. It offers `DIRECT_TOOL_NAMES` **minus every key of

`SDK_NATIVE_TOOL_REPLACEMENTS`**, because an MCP client (Claude Code, ChatGPT) *is* the host agent that table describes: offering NodeTool's workspace-scoped `read_file` beside the client's own would put two tools of one name and two different roots in front of one model. What survives has no host equivalent — discovery, the server-side reach that runs behind NodeTool's SSRF guard and secrets (`download_file`, `list_directory`), and `run_subtask`, whose child gets the NodeTool belt rather than the client's. `browser`, `http_request` and `todo_write` are also left off the mount (`MCP_SANDBOX_ONLY_TOOL_NAMES`) and stay reachable inside an action. It is a `belt.filter`, so a session missing an injected dependency (no node registry, say) advertises no node tools instead of a tool that cannot run. Before this the mount registered only `execute_code` and `view_image`: everything was still reachable as an import inside an action, but every discovery question cost a sandbox round trip, which is the tax the direct set exists to remove.

  • On `claude_agent_sdk` the built-in wins outright. The provider drops every

tool `SDK_NATIVE_TOOL_REPLACEMENTS` maps (`read_file`→`Read`, `write_file`→`Write`, `edit_file`→`Edit`, `glob`→`Glob`, `grep`→`Grep`, `web_search`→`WebSearch`) from its MCP toolset and lets the SDK's own tool serve the call. The path-scoped five are substituted only when the caller passes a `workspaceDir`, which becomes the session `cwd` — without it the SDK would resolve paths outside the run's workspace, so NodeTool's contained versions stay. `list_directory`, `browser`, `http_request`, `download_file` and `run_subtask` are never substituted: no built-in covers what they do (`Task` would hand the child SDK tools, not the NodeTool belt). Neither is `todo_write`: `TodoWrite` keeps the list inside the SDK session, and the chat's task list is drawn from the `todo_update` that NodeTool's version posts. See `packages/runtime/src/providers/core-tools.ts`.

  • Progressive disclosure: resident tools (`CODEACT_RESIDENT_TOOL_NAMES` —

the search family incl. `web_search`/`search_nodes`/`run_search`/ `asset_search`/`grep`/`glob`, the Claude-agent file set (`read_file`/`write_file`/`edit_file`/`list_directory`), browser, HTTP, memory, `run_subtask`) are documented in full; past `CODEACT_DEFER_THRESHOLD` tools, the rest is name-only in the prompt and discovered in-sandbox with `await nodetool.searchTools("query")` (ToolSearch grammar). All tools stay callable either way. Discovery lives on the object model and nowhere else: the bare `searchTools()` global is gone, because a model that knows `nodetool.*` looked for it there and burned two rounds finding out it was elsewhere.

  • Imports are discoverable too: `nodetool.packs.list()` reports every in
Read more
@nodetool-ai
Ships withnodetool

Open-source AI film studio · agent + node workflows Direct AI films, shot by shot. Start with one sentence. The agent writes the story, draws a still for every shot, and cuts the clips on a timeline.

6361 skill14 agents
Get the whole plugin

Stars on GitHub

Momentum

stars in total
636
Star history of nodetool-ai/nodetool on GitHub, a chart by star-history.com

Other agents on nodetool.

MUTATION_TESTING

MUTATION_TESTING

Agent

The agent package's pure, deterministic core (the chat permission gate, the control-tool plumbing, JSON extraction, and the…

cli

cli

Agent

**Navigation**: [Agents package rules](../AGENTS.md) → **Running Agents from CLI**

More agents from other plugins.

prompt-manager

prompt-manager

Agent

Agent for managing AI prompts on prompts.chat - search, save, improve, and organize your prompt library.

@gh-f@gh-fInstall Agent
humanize-diagnostician

humanize-diagnostician

Agent

정밀(strict) 모드 1단계 진단 에이전트. 글 전체를 한 번에 보고 "가장 지배적인 AI 티 패턴 3~6개"를 taxonomy ID와 함께 진단한다. 불안정한 span 열거(0↔18개로 요동) 대신 "무엇이 이 글을…

@epoko77-ai@epoko77-aiInstall Agent
blog-cluster-curator
Auto-invoked

blog-cluster-curator

Agent

Topic Clusters curator for the Claude Blog Brain. Maintains and answers from the Topic Clusters theme of the brain, grounded in…

@agricidaniel@agricidanielInstall Agent

Questions about codeact.

Which coding agents can use codeact?
codeact installs in Claude Code and Cursor: each loads subagents from .claude/agents, so copy the file there. Flowy's auto-invocation runs in Claude Code only.