@enderfga/claw-orchestrator 7.12.1 → 7.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -11
- package/configs/engines/README.md +20 -0
- package/configs/engines/dsh.json +17 -0
- package/configs/engines/kimi-code.json +17 -0
- package/dist/bin/cli.js +123 -34
- package/dist/bin/cli.js.map +1 -1
- package/dist/src/acp-server.js +4 -2
- package/dist/src/acp-server.js.map +1 -1
- package/dist/src/autoloop/dispatcher.d.ts +19 -0
- package/dist/src/autoloop/dispatcher.js +57 -0
- package/dist/src/autoloop/dispatcher.js.map +1 -1
- package/dist/src/autoloop/runner.d.ts +102 -2
- package/dist/src/autoloop/runner.js +367 -44
- package/dist/src/autoloop/runner.js.map +1 -1
- package/dist/src/autoloop/types.d.ts +17 -0
- package/dist/src/autoloop/types.js.map +1 -1
- package/dist/src/dashboard/index.html +79 -73
- package/dist/src/embedded-server.js +35 -7
- package/dist/src/embedded-server.js.map +1 -1
- package/dist/src/engine-presets.d.ts +7 -3
- package/dist/src/engine-presets.js +39 -6
- package/dist/src/engine-presets.js.map +1 -1
- package/dist/src/engine-spawn.d.ts +8 -1
- package/dist/src/engine-spawn.js +13 -3
- package/dist/src/engine-spawn.js.map +1 -1
- package/dist/src/index.js +78 -71
- package/dist/src/index.js.map +1 -1
- package/dist/src/kernel/agent-step.d.ts +3 -0
- package/dist/src/kernel/agent-step.js.map +1 -1
- package/dist/src/kernel/engine.d.ts +5 -2
- package/dist/src/kernel/engine.js +11 -12
- package/dist/src/kernel/engine.js.map +1 -1
- package/dist/src/kernel/nodes/autoloop.d.ts +32 -2
- package/dist/src/kernel/nodes/autoloop.js +122 -15
- package/dist/src/kernel/nodes/autoloop.js.map +1 -1
- package/dist/src/kernel/nodes/goal.d.ts +94 -0
- package/dist/src/kernel/nodes/goal.js +386 -0
- package/dist/src/kernel/nodes/goal.js.map +1 -0
- package/dist/src/kernel/nodes/index.d.ts +2 -1
- package/dist/src/kernel/nodes/index.js +3 -1
- package/dist/src/kernel/nodes/index.js.map +1 -1
- package/dist/src/kernel/templates/index.d.ts +27 -3
- package/dist/src/kernel/templates/index.js +78 -1
- package/dist/src/kernel/templates/index.js.map +1 -1
- package/dist/src/kernel/types.d.ts +41 -2
- package/dist/src/kernel/types.js.map +1 -1
- package/dist/src/persistent-acp-session.d.ts +76 -0
- package/dist/src/persistent-acp-session.js +409 -0
- package/dist/src/persistent-acp-session.js.map +1 -0
- package/dist/src/persistent-agy-session.js +1 -0
- package/dist/src/persistent-agy-session.js.map +1 -1
- package/dist/src/persistent-codex-app-session.d.ts +55 -26
- package/dist/src/persistent-codex-app-session.js +109 -24
- package/dist/src/persistent-codex-app-session.js.map +1 -1
- package/dist/src/persistent-codex-session.js +1 -0
- package/dist/src/persistent-codex-session.js.map +1 -1
- package/dist/src/persistent-cursor-session.js +1 -0
- package/dist/src/persistent-cursor-session.js.map +1 -1
- package/dist/src/persistent-custom-session.js +2 -0
- package/dist/src/persistent-custom-session.js.map +1 -1
- package/dist/src/persistent-gemini-session.js +1 -0
- package/dist/src/persistent-gemini-session.js.map +1 -1
- package/dist/src/persistent-grok-session.js +1 -0
- package/dist/src/persistent-grok-session.js.map +1 -1
- package/dist/src/persistent-opencode-session.js +1 -0
- package/dist/src/persistent-opencode-session.js.map +1 -1
- package/dist/src/persistent-session.js +1 -0
- package/dist/src/persistent-session.js.map +1 -1
- package/dist/src/sanitize.d.ts +10 -0
- package/dist/src/sanitize.js +26 -0
- package/dist/src/sanitize.js.map +1 -1
- package/dist/src/session-manager.d.ts +25 -20
- package/dist/src/session-manager.js +92 -43
- package/dist/src/session-manager.js.map +1 -1
- package/dist/src/types.d.ts +35 -1
- package/dist/src/types.js +2 -0
- package/dist/src/types.js.map +1 -1
- package/openclaw.plugin.json +1 -1
- package/package.json +2 -2
- package/skills/SKILL.md +8 -5
- package/skills/references/acp.md +4 -0
- package/skills/references/autoloop.md +27 -2
- package/skills/references/claude-cli-tracking.md +3 -1
- package/skills/references/cli.md +79 -39
- package/skills/references/dashboard.md +5 -1
- package/skills/references/multi-engine.md +39 -10
- package/skills/references/tools.md +77 -65
- package/skills/references/workflow.md +87 -13
|
@@ -8,57 +8,58 @@ All 78 tools are registered as OpenClaw plugin tools and exposed over MCP by `cl
|
|
|
8
8
|
|
|
9
9
|
Start a persistent coding session with full CLI flag support.
|
|
10
10
|
|
|
11
|
-
| Parameter | Type
|
|
12
|
-
| ------------------------------------ |
|
|
13
|
-
| `name` | string
|
|
14
|
-
| `cwd` | string
|
|
15
|
-
| `engine` | `'claude'` \| `'codex'` \| `'codex-app'` \| `'agy'` \| `'grok'` \| `'opencode'` \| `'custom'` | Engine to use (default: `claude`). `agy` wraps Google Antigravity CLI. `grok` wraps xAI Grok Build and reports its own per-turn cost. `opencode` wraps sst/opencode (pass model as `provider/model`). Use `custom` with `customEngine` for any CLI. (`'gemini'` and `'cursor'` are still accepted for existing callers but are legacy — not version-tracked; use `agy` for Google and `grok` in place of Cursor.)
|
|
16
|
-
| `model` | string
|
|
17
|
-
| `permissionMode` | string
|
|
18
|
-
| `sandboxMode` | `'read-only'` \| `'workspace-write'` \| `'danger-full-access'`
|
|
19
|
-
| `allowedTools` | string[]
|
|
20
|
-
| `disallowedTools` | string[]
|
|
21
|
-
| `maxTurns` | number
|
|
22
|
-
| `maxBudgetUsd` | number
|
|
23
|
-
| `autoCompactPercent` | number
|
|
24
|
-
| `systemPrompt` | string
|
|
25
|
-
| `appendSystemPrompt` | string
|
|
26
|
-
| `agents` | object
|
|
27
|
-
| `agent` | string
|
|
28
|
-
| `bare` | boolean
|
|
29
|
-
| `worktree` | string \| boolean
|
|
30
|
-
| `fallbackModel` | string \| string[]
|
|
31
|
-
| `resumeSessionId` | string
|
|
32
|
-
| `jsonSchema` | string
|
|
33
|
-
| `mcpConfig` | string \| string[]
|
|
34
|
-
| `settings` | string
|
|
35
|
-
| `ultracode` | boolean
|
|
36
|
-
| `noSessionPersistence` | boolean
|
|
37
|
-
| `ignoreUserConfig` | boolean
|
|
38
|
-
| `codexProfile` | string
|
|
39
|
-
| `restricted` | boolean
|
|
40
|
-
| `betas` | string \| string[]
|
|
41
|
-
| `enableAgentTeams` | boolean
|
|
42
|
-
| `enableAutoMode` | boolean
|
|
43
|
-
| `customEngine` | object
|
|
44
|
-
| `
|
|
45
|
-
| `
|
|
46
|
-
| `
|
|
47
|
-
| `
|
|
48
|
-
| `
|
|
49
|
-
| `
|
|
50
|
-
| `
|
|
51
|
-
| `
|
|
52
|
-
| `
|
|
53
|
-
| `
|
|
54
|
-
| `
|
|
55
|
-
| `
|
|
56
|
-
| `
|
|
57
|
-
| `
|
|
58
|
-
| `
|
|
59
|
-
| `
|
|
60
|
-
| `
|
|
61
|
-
| `
|
|
11
|
+
| Parameter | Type | Description |
|
|
12
|
+
| ------------------------------------ | -------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
13
|
+
| `name` | string | Session name (auto-generated if omitted) |
|
|
14
|
+
| `cwd` | string | Working directory |
|
|
15
|
+
| `engine` | `'claude'` \| `'codex'` \| `'codex-app'` \| `'agy'` \| `'grok'` \| `'opencode'` \| `'acp'` \| `'custom'` | Engine to use (default: `claude`). `agy` wraps Google Antigravity CLI. `grok` wraps xAI Grok Build and reports its own per-turn cost. `opencode` wraps sst/opencode (pass model as `provider/model`). `acp` drives any Agent Client Protocol agent named by `acpAgent`. Use `custom` with `customEngine` for any CLI. (`'gemini'` and `'cursor'` are still accepted for existing callers but are legacy — not version-tracked; use `agy` for Google and `grok` in place of Cursor.) |
|
|
16
|
+
| `model` | string | Model alias or full name |
|
|
17
|
+
| `permissionMode` | string | `acceptEdits`, `bypassPermissions`, `plan`, `auto`, `manual`, `dontAsk` (`default` = legacy alias for `manual`) |
|
|
18
|
+
| `sandboxMode` | `'read-only'` \| `'workspace-write'` \| `'danger-full-access'` | Sandbox policy. Codex supports all values. `read-only` is enforced on every other built-in engine too: Claude → plan mode; Antigravity → its plan mode; OpenCode → a generated `clawo-readonly` agent denying `edit`/`bash`. Grok → its OS-enforced `--sandbox read-only` profile (refused for a project under the temp directory, on platforms without Seatbelt or Landlock, and when grok cannot apply it). A `custom` engine must map it via `permissionModes`, or the session refuses to start. Persisted across session resume. |
|
|
19
|
+
| `allowedTools` | string[] | Tools to auto-approve |
|
|
20
|
+
| `disallowedTools` | string[] | Tools to deny |
|
|
21
|
+
| `maxTurns` | number | Max agent loop turns |
|
|
22
|
+
| `maxBudgetUsd` | number | Max API spend (USD). Enforced by the runtime on every engine: once the session's cumulative cost reaches the cap, further sends are refused before the engine is spawned. See [observability.md](observability.md) for the accuracy caveat on engines that estimate token counts. |
|
|
23
|
+
| `autoCompactPercent` | number | Compact the conversation before a send once `contextPercent` reaches this value (1–99). Off by default. For long-lived sessions, where cost grows with context size; survives a server restart. A failed compaction does not block the send. |
|
|
24
|
+
| `systemPrompt` | string | Replace system prompt |
|
|
25
|
+
| `appendSystemPrompt` | string | Append custom instructions to the system prompt. Claude Code and Grok take it natively; Codex, Antigravity and OpenCode have no such flag and receive it at the top of the first message of a conversation |
|
|
26
|
+
| `agents` | object | Custom sub-agents JSON |
|
|
27
|
+
| `agent` | string | Default agent to use |
|
|
28
|
+
| `bare` | boolean | Skip hooks, LSP, auto-memory, CLAUDE.md |
|
|
29
|
+
| `worktree` | string \| boolean | Run in git worktree |
|
|
30
|
+
| `fallbackModel` | string \| string[] | Fallback model(s) when the primary is overloaded; an array is tried in order |
|
|
31
|
+
| `resumeSessionId` | string | Resume existing session by ID |
|
|
32
|
+
| `jsonSchema` | string | JSON Schema for structured output. Claude: `--json-schema` (inline). Codex: `--output-schema` (written to a temp file, requires Codex 0.132+). Other engines ignore it. |
|
|
33
|
+
| `mcpConfig` | string \| string[] | MCP server config file(s) |
|
|
34
|
+
| `settings` | string | Settings.json path or inline JSON |
|
|
35
|
+
| `ultracode` | boolean | Claude only. Enable "ultracode" / dynamic workflows — Claude plans a JS orchestration script per substantive task and fans out to subagents. Injected as the `ultracode:true` settings key (merged into `settings`). The workflow runs in the background: `session_send` returns at launch, and the completion turn is not returned by a later send (see sessions.md). |
|
|
36
|
+
| `noSessionPersistence` | boolean | Do not save session to disk — both the engine's own transcript and this orchestrator's resume registry, so a later start under the same name does not reattach |
|
|
37
|
+
| `ignoreUserConfig` | boolean | Codex only. Run without loading `$CODEX_HOME/config.toml`, so an orchestrated run is decided by what the caller passed rather than by the machine's own Codex config — notably a `model = …` line in that file, which otherwise picks the model while the ledger records this engine's default. Auth still resolves from `CODEX_HOME`. |
|
|
38
|
+
| `codexProfile` | string | Codex only. Named profile from `~/.codex/config.toml`, passed as `codex exec --profile` |
|
|
39
|
+
| `restricted` | boolean | Claude Code only. Restricted mode (`--restricted`): the CLI removes the built-in tools that run commands or code — Bash, PowerShell, the REPL — plus `WebFetch` unless `tools` names them, and ignores user, project and local settings files. Separate from `sandboxMode: 'read-only'`: that maps to plan mode, which holds on its own, while this makes the shell absent rather than refused. It also drops the caller's CLAUDE.md and hooks, so it is never switched on implicitly. |
|
|
40
|
+
| `betas` | string \| string[] | Custom beta headers |
|
|
41
|
+
| `enableAgentTeams` | boolean | Enable experimental agent teams |
|
|
42
|
+
| `enableAutoMode` | boolean | Enable auto permission mode |
|
|
43
|
+
| `customEngine` | object | Custom engine config (required when `engine='custom'`). See [Multi-Engine: Custom Engine](./multi-engine.md#custom-engine-engine-custom). |
|
|
44
|
+
| `acpAgent` | string \| object | The ACP agent (required when `engine='acp'`): a bundled preset id (`kimi-code`, `dsh`), or, from a local caller only, `{ name, command, commandEnv?, args?, env? }`. See [Multi-Engine: ACP agents](./multi-engine.md#acp-agents-engine-acp). |
|
|
45
|
+
| `crossSessionInbound` | string | `accept` / `hold` / `refuse` — policy for peer messages from other Claude Code sessions on this machine (Claude engine). Delivered as a settings key; there is no CLI flag. Without it the CLI holds messages whose two sides run different permission modes, which is the usual orchestrated-session-to-human-terminal case |
|
|
46
|
+
| `includeHookEvents` | boolean | Stream hook lifecycle events (PreToolUse/PostToolUse) as `system` events |
|
|
47
|
+
| `forwardSubagentText` | boolean | Forward subagent text and thinking into the output stream (Claude engine, CLI 2.1.211+). Without it the parent stream stays quiet while a subagent works |
|
|
48
|
+
| `chrome` | boolean | Let the session use the user's Chrome through the Claude in Chrome extension, acting with that browser's sign-ins (Claude engine, `--chrome`). Off by default. Needs Chrome running with the extension and a claude.ai login; survives a server restart |
|
|
49
|
+
| `permissionPromptTool` | string | MCP tool name to delegate permission prompts to (non-interactive use). When omitted, the session runs with `--permission-prompts none`: a prompt nobody could answer is denied rather than left waiting until the turn timeout. |
|
|
50
|
+
| `excludeDynamicSystemPromptSections` | boolean | Move cwd/env/git context from system prompt to user message for better prompt cache hits; auto-enabled with `bare: true` |
|
|
51
|
+
| `enablePromptCaching1H` | boolean | Enable 1-hour prompt cache TTL (vs default 5-min); auto-enabled with `bare: true` |
|
|
52
|
+
| `debug` | string \| string[] | Debug categories to enable (e.g. `"api,mcp"` or `["api", "mcp"]`) |
|
|
53
|
+
| `debugFile` | string | File path to write debug output to |
|
|
54
|
+
| `fromPr` | string | Resume a session linked to a GitHub PR number or URL |
|
|
55
|
+
| `channels` | string \| string[] | MCP channel subscription spec (research preview) |
|
|
56
|
+
| `dangerouslyLoadDevelopmentChannels` | string \| string[] | Development MCP channel subscriptions (research preview) |
|
|
57
|
+
| `forkSubagent` | boolean | Fork subagent for non-interactive sessions (sets `CLAUDE_CODE_FORK_SUBAGENT=1`) |
|
|
58
|
+
| `enableToolSearch` | boolean | Enable Vertex AI tool search (sets `ENABLE_TOOL_SEARCH=1`) |
|
|
59
|
+
| `otelLogUserPrompts` | boolean | OpenTelemetry: log user prompts (sets `OTEL_LOG_USER_PROMPTS=1`) |
|
|
60
|
+
| `otelLogRawApiBodies` | boolean | OpenTelemetry: log raw API request/response bodies (sets `OTEL_LOG_RAW_API_BODIES=1`); debug only |
|
|
61
|
+
| `bedrockServiceTier` | `'default'` \| `'flex'` \| `'priority'` | AWS Bedrock service tier (sets `ANTHROPIC_BEDROCK_SERVICE_TIER`); only effective when routing through Bedrock |
|
|
62
|
+
| `effort` | `'low'` \| `'medium'` \| `'high'` \| `'xhigh'` \| `'max'` \| `'ultra'` \| `'auto'` | Reasoning effort level. Engines do not share one ladder: Claude Code takes up to `max`, Codex adds `ultra`, Grok stops at `xhigh`, Antigravity at `high`, and OpenCode forwards the level to its provider unvalidated. A level above an engine's ceiling clamps rather than being dropped. `high` and above trigger the `ultrathink` prefix on Claude user messages. |
|
|
62
63
|
|
|
63
64
|
### `session_send`
|
|
64
65
|
|
|
@@ -297,38 +298,37 @@ Returns `{ ok, stdout, stderr }`.
|
|
|
297
298
|
|
|
298
299
|
### `codex_goal_set`
|
|
299
300
|
|
|
300
|
-
Set a long-horizon objective.
|
|
301
|
+
Set a long-horizon objective (`thread/goal/set`). Codex then works turn after turn on its own until the goal leaves `active`. **Requires `engine: "codex-app"`.**
|
|
301
302
|
|
|
302
|
-
| Parameter
|
|
303
|
-
|
|
|
304
|
-
| `name`
|
|
305
|
-
| `objective`
|
|
306
|
-
| `
|
|
303
|
+
| Parameter | Type | Required | Notes |
|
|
304
|
+
| ------------- | ------ | -------- | ---------------------------------------------------------------- |
|
|
305
|
+
| `name` | string | yes | |
|
|
306
|
+
| `objective` | string | yes | |
|
|
307
|
+
| `tokenBudget` | number | | Tokens the goal may spend; it stops as `budgetLimited` past this |
|
|
307
308
|
|
|
308
|
-
Returns `{ ok,
|
|
309
|
+
Returns `{ ok, goal }` where `goal` is `{ objective, status, tokenBudget, tokensUsed, timeUsedSeconds, ... }`. `status` is one of `active`, `paused`, `blocked`, `usageLimited`, `budgetLimited`, `complete`.
|
|
309
310
|
|
|
310
311
|
### `codex_goal_get`
|
|
311
312
|
|
|
312
|
-
|
|
313
|
+
Ask the app-server for the goal (`thread/goal/get`). Sends no turn.
|
|
313
314
|
|
|
314
315
|
| Parameter | Type | Required |
|
|
315
316
|
| --------- | ------ | -------- |
|
|
316
317
|
| `name` | string | yes |
|
|
317
318
|
|
|
318
|
-
Returns `{ ok, goal }` (`null` if no goal
|
|
319
|
+
Returns `{ ok, goal }` (`null` if the thread has no goal).
|
|
319
320
|
|
|
320
321
|
### `codex_goal_pause` / `codex_goal_resume` / `codex_goal_clear`
|
|
321
322
|
|
|
322
|
-
|
|
323
|
+
Pause (`status: "paused"`), resume (`status: "active"`, also for a goal stopped by a usage limit) or remove (`thread/goal/clear`) the goal. Requires `engine: "codex-app"`.
|
|
323
324
|
|
|
324
325
|
| Parameter | Type | Required |
|
|
325
326
|
| --------- | ------ | -------- |
|
|
326
327
|
| `name` | string | yes |
|
|
327
|
-
| `timeout` | number | |
|
|
328
328
|
|
|
329
|
-
Returns `{ ok,
|
|
329
|
+
Returns `{ ok, goal }` (`null` after `clear`).
|
|
330
330
|
|
|
331
|
-
|
|
331
|
+
For a goal that has to run unattended for hours, judged by checks the agent did not write, use the `goal` workflow (`workflow_start` with `template: "goal"`, or `clawo goal`) instead of these tools; see [workflow.md](./workflow.md#goal).
|
|
332
332
|
|
|
333
333
|
### Codex app-server RPCs
|
|
334
334
|
|
|
@@ -645,7 +645,11 @@ or smaller values are rejected, and there is deliberately no
|
|
|
645
645
|
Each successful increase appends one migration row to `decisions.jsonl`; the
|
|
646
646
|
original run spec, history, and prior audit bytes are not rewritten. The
|
|
647
647
|
matching live awaiting-resume condition is advanced without replaying the
|
|
648
|
-
timed-out logical dispatch.
|
|
648
|
+
timed-out logical dispatch. A live ordinary or activity-lease pause
|
|
649
|
+
(`pending_dispatch` null) resumes with no timeout fields: the call returns once
|
|
650
|
+
the run is active again, the lease re-arms without moving the hard deadline,
|
|
651
|
+
and Planner chat parked during the pause is then delivered once, in order. A
|
|
652
|
+
no-option resume does not clear a pending send timeout.
|
|
649
653
|
|
|
650
654
|
### `autoloop_chat`
|
|
651
655
|
|
|
@@ -656,6 +660,14 @@ Send a message into the Planner conversation.
|
|
|
656
660
|
| `run_id` | string | yes |
|
|
657
661
|
| `text` | string | yes |
|
|
658
662
|
|
|
663
|
+
The message is accepted only once it is stored in the run checkpoint; otherwise
|
|
664
|
+
the call fails with `autoloop chat could not be persisted` (or a stopping,
|
|
665
|
+
restoring or limit error) and nothing is sent. Accepted chat survives
|
|
666
|
+
`autoloop_stop` and owner loss and is delivered once, in order, after a resume.
|
|
667
|
+
A message that was mid-delivery when the run stopped is not resent; it is
|
|
668
|
+
reported through `unconfirmed_chat` in `autoloop_status` and one notice in chat
|
|
669
|
+
history.
|
|
670
|
+
|
|
659
671
|
### `autoloop_status`
|
|
660
672
|
|
|
661
673
|
Get the current state and push log.
|
|
@@ -46,7 +46,9 @@ its choice is not recorded. A run parked at a `human_gate` parks there again.
|
|
|
46
46
|
Steers survive a restart. They are logged when they arrive and recorded as
|
|
47
47
|
consumed when the node that took them finishes, so on resume every steer no
|
|
48
48
|
finished node consumed is queued again — including one a node was holding when
|
|
49
|
-
it died, which goes to that node's retry.
|
|
49
|
+
it died, which goes to that node's retry. A `goal` node delivers steers into
|
|
50
|
+
the running turn as they arrive, so one delivered before a crash is delivered
|
|
51
|
+
again after the resume.
|
|
50
52
|
|
|
51
53
|
**This makes node execution at-least-once, not exactly-once.** There is no
|
|
52
54
|
idempotency key and no side-effect commit marker, so a node that wrote files and
|
|
@@ -136,17 +138,18 @@ is unrecoverable and reads back as "not found".
|
|
|
136
138
|
|
|
137
139
|
## Node kinds
|
|
138
140
|
|
|
139
|
-
| Kind | Does
|
|
140
|
-
| ------------ |
|
|
141
|
-
| `agent` | One session, one turn
|
|
142
|
-
| `fanout` | N agents in parallel, optional synthesis
|
|
143
|
-
| `council` | The existing council engine, votes recorded as advisory
|
|
144
|
-
| `verifier` | Runs an acceptance contract, writes evidence — see [`verification.md`](./verification.md)
|
|
145
|
-
| `human_gate` | Parks the run until a person answers
|
|
146
|
-
| `router` | Picks the next node from declarative conditions; a backwards route is the loop
|
|
147
|
-
| `subflow` | Runs another workflow as a step and adopts its verdict
|
|
141
|
+
| Kind | Does |
|
|
142
|
+
| ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
143
|
+
| `agent` | One session, one turn |
|
|
144
|
+
| `fanout` | N agents in parallel, optional synthesis |
|
|
145
|
+
| `council` | The existing council engine, votes recorded as advisory |
|
|
146
|
+
| `verifier` | Runs an acceptance contract, writes evidence — see [`verification.md`](./verification.md) |
|
|
147
|
+
| `human_gate` | Parks the run until a person answers |
|
|
148
|
+
| `router` | Picks the next node from declarative conditions; a backwards route is the loop |
|
|
149
|
+
| `subflow` | Runs another workflow as a step and adopts its verdict |
|
|
148
150
|
| `autoloop` | A long-lived Planner / Coder / Reviewer loop; its executor is injected. On the node's first visit (`visits === 1`) the shared fresh-start boundary applies (dirty-worktree refusal + run-local `tasks/<config.runId>/.gitignore`); resume and later visits skip it. |
|
|
149
|
-
| `
|
|
151
|
+
| `goal` | A Codex `/goal` on one `codex-app` thread, run until the goal finishes — see [below](#goal) |
|
|
152
|
+
| `ultraapp_*` | UltraApp's synth and deploy stages; their executors are injected too |
|
|
150
153
|
|
|
151
154
|
Every node takes `retry: { max, backoffMs }`, `timeoutMs`, and
|
|
152
155
|
`onFailure: 'fail' | 'continue'`.
|
|
@@ -258,9 +261,79 @@ test suite would double the most expensive part of the run to learn nothing new.
|
|
|
258
261
|
- **`council`** — one council node, plus the implicit verifier when a contract is
|
|
259
262
|
declared.
|
|
260
263
|
- **`fanout`** — one fan-out node.
|
|
264
|
+
- **`goal`** — a `goal` node → verify → repair on the same thread; `task` is the
|
|
265
|
+
objective. See [below](#goal).
|
|
261
266
|
|
|
262
267
|
These are ordinary specs, not privileged paths.
|
|
263
268
|
|
|
269
|
+
## Goal
|
|
270
|
+
|
|
271
|
+
A `goal` node runs one Codex `/goal` on one `codex-app` thread. Codex's
|
|
272
|
+
app-server runs the goal itself: `thread/goal/set` starts its turn loop, which
|
|
273
|
+
keeps going until the goal is `complete`, out of budget, `blocked`, or stopped
|
|
274
|
+
by a usage limit. The node adds what an unattended run needs around that loop.
|
|
275
|
+
|
|
276
|
+
```jsonc
|
|
277
|
+
{
|
|
278
|
+
"id": "goal",
|
|
279
|
+
"kind": "goal",
|
|
280
|
+
"objective": "Reach the goal described in GOAL.md …",
|
|
281
|
+
"cwd": "/work/task/ws",
|
|
282
|
+
"model": "gpt-6.1-sol", // optional; codex's own default otherwise
|
|
283
|
+
"launcher": ["/work/goal/sandbox/sandbox.sh", "task", "0 1"], // optional argv prefix
|
|
284
|
+
"threadId": "019c…", // optional: start on this existing thread, replacing its goal
|
|
285
|
+
"tokenBudget": 50000000, // optional; the goal ends as budgetLimited past it
|
|
286
|
+
"capacityRetry": { "max": 20, "backoffMs": 60000 }, // default
|
|
287
|
+
"stallMs": 300000, // default 5 min
|
|
288
|
+
"timeoutMs": 86400000, // optional wall-clock budget; no default
|
|
289
|
+
}
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
- **The objective fits Codex's limit.** Codex accepts at most 4,000 characters;
|
|
293
|
+
a longer objective fails the node before a session opens. Put a long brief in
|
|
294
|
+
a file in the working directory and name the file in the objective.
|
|
295
|
+
- **The thread is checkpointed.** Node data holds `threadId`, `status`,
|
|
296
|
+
`tokensUsed`, `timeUsedSeconds`, `resumes`, `lastError`, the agent's last reply
|
|
297
|
+
(`lastMessage`, at most 4,000 characters) and the thread's spend
|
|
298
|
+
(`costUsd`), updated as the goal moves (progress at most every 10 s, status
|
|
299
|
+
changes at once). `workflow_status` and `clawo workflow show` read it while the
|
|
300
|
+
goal runs.
|
|
301
|
+
- **Resume reattaches, it does not restart.** A resumed run hands the stored
|
|
302
|
+
thread id to `thread/resume`; a goal that had not finished continues where it
|
|
303
|
+
was. If the resume lands on a different thread the node fails rather than
|
|
304
|
+
starting the objective over. An app-server that exits mid-goal is reopened on
|
|
305
|
+
the same thread the same way.
|
|
306
|
+
- **Stalls are resumed within a bound.** A goal that is `usageLimited` or
|
|
307
|
+
`paused`, or `active` with no turn running and either no news for `stallMs` or
|
|
308
|
+
an error the server will not retry (`serverOverloaded`, `usageLimitExceeded`,
|
|
309
|
+
`rateLimitExceeded`, a dropped connection), is set back to `active` after a
|
|
310
|
+
backoff that starts at `capacityRetry.backoffMs` and doubles to at most 15 min.
|
|
311
|
+
Every attempt counts before it is made, reopening a dead app-server included;
|
|
312
|
+
past `capacityRetry.max` the node fails.
|
|
313
|
+
- **Repair on the same thread.** Revisited after a red verifier, the node clears
|
|
314
|
+
the finished goal and sets a new objective on the same thread: the failing
|
|
315
|
+
checks first (as diagnostic data, like an agent node's repair brief), then the
|
|
316
|
+
original objective. The agent keeps its context. The original objective is
|
|
317
|
+
always kept whole; when both do not fit in 4,000 characters the checks are cut
|
|
318
|
+
(the full output stays in the run's evidence). A first goal that was never set
|
|
319
|
+
left nothing on its thread, so its revisit starts a new one.
|
|
320
|
+
- **Steering is live.** `workflow_steer` text goes into the running turn through
|
|
321
|
+
`turn/steer`; with no turn running it waits for the next one. Text queued
|
|
322
|
+
before the goal is set is put in front of the objective.
|
|
323
|
+
- **No approval prompts.** Nothing can answer one, so the thread runs with
|
|
324
|
+
`approvalPolicy: "never"` and any request the server sends anyway (approval,
|
|
325
|
+
user input) is answered with an error at once; the sandbox mode is the
|
|
326
|
+
boundary.
|
|
327
|
+
- **Ends.** `complete` succeeds. `budgetLimited` and `blocked` fail with the
|
|
328
|
+
reason. Cancel interrupts the running turn and pauses the goal. Like
|
|
329
|
+
`autoloop`, the node has no default timeout.
|
|
330
|
+
|
|
331
|
+
The `goal` template wraps this in `goal → verify → repair-gate`. The goal node
|
|
332
|
+
continues on failure, so a goal that ran out of budget is still judged. The
|
|
333
|
+
verifier's node timeout is sized from the contract (each check's timeout, at
|
|
334
|
+
least 30 min), so a judge that takes hours is not cut off at the 30-minute node
|
|
335
|
+
default. `maxRepairs` defaults to 1.
|
|
336
|
+
|
|
264
337
|
## The verifier is a terminal barrier
|
|
265
338
|
|
|
266
339
|
A passing verdict only stands while it still describes the tree.
|
|
@@ -299,7 +372,7 @@ success.
|
|
|
299
372
|
|
|
300
373
|
| Action | Tool | HTTP | CLI |
|
|
301
374
|
| ------------- | ------------------ | --------------------------------- | -------------------------------------- |
|
|
302
|
-
| Start | `workflow_start` | `POST /workflow/new` |
|
|
375
|
+
| Start | `workflow_start` | `POST /workflow/new` | `clawo solve` / `fanout` / `goal` |
|
|
303
376
|
| Poll | `workflow_status` | `GET /workflow/<id>/state` | `clawo workflow show <id>` |
|
|
304
377
|
| List | `workflow_list` | `GET /workflow/list` | `clawo workflow list` |
|
|
305
378
|
| Resume | `workflow_resume` | `POST /workflow/<id>/resume` | `clawo workflow resume <id>` |
|
|
@@ -309,7 +382,8 @@ success.
|
|
|
309
382
|
| Evidence | — | `GET /workflow/<id>/evidence` | `clawo verify <id>` |
|
|
310
383
|
| Live events | — | `GET /workflow/<id>/events` (SSE) | — |
|
|
311
384
|
|
|
312
|
-
|
|
385
|
+
In a running `goal` node, steer text goes into the current turn (`turn/steer`).
|
|
386
|
+
Otherwise, steer text is **prepended** to the next agent node's prompt: an instruction that
|
|
313
387
|
arrives while the previous node was running is a correction, and corrections
|
|
314
388
|
belong before the task.
|
|
315
389
|
|