@enderfga/claw-orchestrator 7.12.0 → 7.13.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 +6 -4
- package/dist/bin/cli.js +66 -6
- package/dist/bin/cli.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 +28 -5
- package/dist/src/embedded-server.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 +58 -69
- 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/models.js +10 -2
- package/dist/src/models.js.map +1 -1
- 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.d.ts +4 -0
- package/dist/src/persistent-grok-session.js +12 -2
- 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 +217 -44
- package/dist/src/session-manager.js.map +1 -1
- package/dist/src/types.d.ts +6 -0
- package/package.json +2 -2
- package/skills/SKILL.md +8 -5
- package/skills/references/autoloop.md +52 -8
- package/skills/references/claude-cli-tracking.md +3 -1
- package/skills/references/cli.md +32 -1
- package/skills/references/dashboard.md +5 -1
- package/skills/references/multi-engine.md +26 -15
- package/skills/references/tools.md +25 -14
- package/skills/references/workflow.md +87 -13
package/skills/SKILL.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: claw-orchestrator
|
|
3
|
-
description: Manage persistent coding sessions across Claude Code, Codex, Antigravity (agy), Grok Build, and OpenCode engines. Use when orchestrating multi-engine coding agents, starting/sending/stopping sessions, running multi-agent council collaborations, cross-session messaging, ultraplan deep planning, ultrareview parallel code review, autoloop autonomous workspace iteration, ultraapp building deployable web apps from a structured Q&A interview, switching models/tools at runtime, exposing the orchestrator's 78 tools as an MCP server to Hermes Agent / Claude Desktop / Cursor / Cline / Continue / Zed / Windsurf / Goose, or running as an Agent Client Protocol (ACP) agent that Zed / JetBrains / Neovim / Emacs / VS Code / dsh can drive directly. Triggers on "start a session", "send to session", "run council", "ultraplan", "ultrareview", "autoloop", "ultraapp", "Forge tab", "build a web app", "one-click app", "AppSpec", "autonomous iteration", "iterate until goal", "auto research", "switch model", "hand off a session", "session handoff", "switch engine", "continue on codex", "continue on claude", "move this session to another engine", "multi-agent coding", "coding session", "session inbox", "grok session", "grok build", "opencode", "mcp server", "clawo-mcp", "hermes mcp", "model context protocol", "ultracode", "dynamic workflow", "fanout", "fan-out", "best-of-N", "steer turn", "interrupt turn", "fork thread", "rollback turns", "acp", "agent client protocol", "clawo acp", "zed agent", "jetbrains agent", "external agent", "dsh subagent", "deepseek harness", "clawo runs", "run ledger", "session cost", "coding-agent token usage", "spend cap", "budget limit", "maxBudgetUsd", "durable workflow", "resume a run", "verify a coding run", "acceptance contract", "evidence bundle", "did the agent's tests actually pass", "protected tests", "agent edited the tests", "human gate", "repair loop", "clawo workflow", "clawo verify", "clawo solve", "clawo fanout", "fix and verify", "solve from the terminal".
|
|
3
|
+
description: Manage persistent coding sessions across Claude Code, Codex, Antigravity (agy), Grok Build, and OpenCode engines. Use when orchestrating multi-engine coding agents, starting/sending/stopping sessions, running multi-agent council collaborations, cross-session messaging, ultraplan deep planning, ultrareview parallel code review, autoloop autonomous workspace iteration, ultraapp building deployable web apps from a structured Q&A interview, switching models/tools at runtime, exposing the orchestrator's 78 tools as an MCP server to Hermes Agent / Claude Desktop / Cursor / Cline / Continue / Zed / Windsurf / Goose, or running as an Agent Client Protocol (ACP) agent that Zed / JetBrains / Neovim / Emacs / VS Code / dsh can drive directly. Triggers on "start a session", "send to session", "run council", "ultraplan", "ultrareview", "autoloop", "ultraapp", "Forge tab", "build a web app", "one-click app", "AppSpec", "autonomous iteration", "iterate until goal", "auto research", "switch model", "hand off a session", "session handoff", "switch engine", "continue on codex", "continue on claude", "move this session to another engine", "multi-agent coding", "coding session", "session inbox", "grok session", "grok build", "opencode", "mcp server", "clawo-mcp", "hermes mcp", "model context protocol", "ultracode", "dynamic workflow", "fanout", "fan-out", "best-of-N", "steer turn", "interrupt turn", "fork thread", "rollback turns", "acp", "agent client protocol", "clawo acp", "zed agent", "jetbrains agent", "external agent", "dsh subagent", "deepseek harness", "clawo runs", "run ledger", "session cost", "coding-agent token usage", "spend cap", "budget limit", "maxBudgetUsd", "durable workflow", "resume a run", "verify a coding run", "acceptance contract", "evidence bundle", "did the agent's tests actually pass", "protected tests", "agent edited the tests", "human gate", "repair loop", "clawo workflow", "clawo verify", "clawo solve", "clawo fanout", "fix and verify", "solve from the terminal", "codex goal", "/goal", "clawo goal", "long-horizon goal", "unattended codex run", "goal node", "run codex in a sandbox", "launcher".
|
|
4
4
|
metadata:
|
|
5
5
|
{
|
|
6
6
|
'openclaw':
|
|
@@ -213,15 +213,18 @@ For setup, the dsh YAML block, and the cancellation/permission limits: see [refe
|
|
|
213
213
|
|
|
214
214
|
## Durable workflows
|
|
215
215
|
|
|
216
|
-
`workflow_start` runs a declarative graph of `agent` / `fanout` / `council` / `
|
|
217
|
-
`human_gate` / `router` / `subflow` / `autoloop` / `ultraapp_synth` /
|
|
216
|
+
`workflow_start` runs a declarative graph of `agent` / `fanout` / `council` / `goal` /
|
|
217
|
+
`verifier` / `human_gate` / `router` / `subflow` / `autoloop` / `ultraapp_synth` /
|
|
218
218
|
`ultraapp_deploy` nodes. Every state transition is checkpointed to
|
|
219
219
|
`~/.claw-orchestrator/wf/<runId>/`, so a run survives a process restart and `workflow_resume`
|
|
220
220
|
picks it up at the node boundary — nodes already succeeded are not re-run, and the one that
|
|
221
221
|
was in flight is retried because a half-finished node left no result to trust.
|
|
222
222
|
|
|
223
|
-
|
|
224
|
-
review), `council`, and `
|
|
223
|
+
Four built-in templates: `solve` (triage → implement → verify → repair-until-green →
|
|
224
|
+
review), `council`, `fanout`, and `goal` (a Codex `/goal` on one `codex-app` thread, run
|
|
225
|
+
unattended for as long as it takes — reattached on resume, resumed after usage limits and
|
|
226
|
+
stalls within a bound, optionally under a sandbox `launcher` — then verify → repair on the
|
|
227
|
+
same thread; `clawo goal` from the terminal). Retry, per-node timeout, cancel, steer, human gates, and
|
|
225
228
|
bounded loops come from the kernel rather than from each mode's own state machine.
|
|
226
229
|
|
|
227
230
|
For node shapes, routing conditions, and the control surfaces:
|
|
@@ -138,6 +138,19 @@ A successful increase appends exactly one `timeout_migration` record to
|
|
|
138
138
|
pending dispatch identity when available. It does not rewrite the original
|
|
139
139
|
stored spec, chat or iteration evidence, or any earlier audit bytes.
|
|
140
140
|
|
|
141
|
+
A live run paused by `pause_loop` or an expired activity lease, with
|
|
142
|
+
`pending_dispatch` null, continues on `autoloopResume()` / `POST /autoloop/<id>/resume`
|
|
143
|
+
with no timeout fields. That resume clears the lease expiry, sets status back
|
|
144
|
+
to `planning` (or `running` once subagents have been spawned), re-arms the
|
|
145
|
+
activity lease from the resume, and leaves the original hard deadline where it
|
|
146
|
+
was. That call returns once the run is active again; Planner chat accepted
|
|
147
|
+
during the pause was parked, not delivered, and is then delivered once, in
|
|
148
|
+
order, by the background drain. If the hard deadline has already passed, the
|
|
149
|
+
same resume terminates the run with `hard_timeout_exceeded` and delivers
|
|
150
|
+
nothing. A no-option resume of an `awaiting_resume` send-timeout pause is still
|
|
151
|
+
a no-op: the pending dispatch, its reason, and the lease suspension stay as
|
|
152
|
+
they are until an explicit timeout increase names that dispatch.
|
|
153
|
+
|
|
141
154
|
## Quick start
|
|
142
155
|
|
|
143
156
|
Over HTTP, against `clawo serve` (default `127.0.0.1:18796`):
|
|
@@ -212,7 +225,7 @@ removes partial files, and suppresses both spawn and directives.
|
|
|
212
225
|
| `notify_user` | `level` ('info' / 'warn' / 'decision' / 'error'), `summary`, `detail?`, `channel?` ('auto' / 'wechat' / 'webchat' / 'both' / 'email') | Push you out-of-band. |
|
|
213
226
|
| `spawn_subagents` | `coder_engine?`, `coder_model?`, `reviewer_engine?`, `reviewer_model?`, `initial_directive?` | Start Coder + Reviewer. Omitted values inherit run defaults. An engine change without a model uses the new engine's default. Once a role session has started, changing its engine/model is rejected. Custom configs cannot be emitted by Planner. Only after explicit user approval. |
|
|
214
227
|
| `send_directive` | `goal`, `constraints?`, `success_criteria?`, `max_attempts?` | Next iter's instruction to Coder. |
|
|
215
|
-
| `pause_loop` | `reason` |
|
|
228
|
+
| `pause_loop` | `reason` | Pause the live run. Planner chat is parked during a pause and is delivered once, in order, on resume. |
|
|
216
229
|
| `resume_loop` | — | Resume after pause. |
|
|
217
230
|
| `terminate` | `reason` | End run. |
|
|
218
231
|
| `update_push_policy` | partial PushPolicy | Mutate notification rules (e.g. when you say "tell me every iter"). |
|
|
@@ -390,7 +403,7 @@ Every JSON artifact in the ledger carries a `schema_version` field (currently
|
|
|
390
403
|
| `GET /autoloop/<id>/events` | SSE: `snapshot` / `message` / `state` / `push` / `iter_done` / `planner_reply` / `planner_error` / `coder_reply` / `reviewer_reply` / `terminated`. For runs that are NOT in this process's memory (terminated, or live in another process), the endpoint emits a single-shot `snapshot` + `terminated` then closes — the dashboard's existing handlers render history without hanging. A run still in memory that has already reached `terminated` or `crashed` gets the same single-shot pair instead of an open stream that would never receive another event. Every such stream sets `retry: 864000000`, so an `EventSource` does not keep reconnecting to a stream that can only end again. |
|
|
391
404
|
| `POST /autoloop/<id>/chat` | **202** `{ ok, queued: true }` — body `{ text }`. Fire-and-forget: the Planner's reply streams back via the `/events` SSE channel as a `planner_reply` event (or `planner_error` on failure); the HTTP response intentionally does NOT wait for it, because first-contact replies routinely exceed reverse-proxy idle limits (e.g. Cloudflare Tunnel cuts at ~100s → 524). 400 on empty text. 404 when the run is not in this process's memory: if the store still holds it, the error says so and names `POST /autoloop/<id>/resume`; an unknown or malformed id is plain `not found`. The MCP `autoloop_chat` tool path keeps the synchronous await-and-return-reply semantics (it runs in-process). |
|
|
392
405
|
| `GET /autoloop/<id>/resume-requirements` | `{ ok, runId, rolesNeedingCustomEngine }` — the roles whose engine was `custom`, so a caller knows which secret references a resume needs. Role names only; nothing sensitive. 404 when there is no such run. |
|
|
393
|
-
| `POST /autoloop/<id>/resume` | `{ ok, state }` — restore the role engine/model choices from the run's spec and re-create dispatcher + runner. For recoverable send timeouts, body fields `send_timeout_ms` and `pending_dispatch_id` apply the increase-only migration described above; `allow_decrease`, lease overrides, and hard-cap overrides are rejected. A custom-engine config is never persisted and is never accepted over HTTP, so a role using `custom` is re-supplied by **reference**: `plannerCustomEngineRef` / `coderCustomEngineRef` / `reviewerCustomEngineRef` name an environment variable `CLAWO_CUSTOM_ENGINE_<NAME>` on the orchestrator host, which the server reads and resolves. The name is not sensitive, the value never crosses the wire, and an unknown name is an error rather than a silent start without credentials. Existing engine-specific conversation resume behavior is reused where supported; `chat.jsonl` remains the visual history fallback. 404 when there is no such run. |
|
|
406
|
+
| `POST /autoloop/<id>/resume` | `{ ok, state }` — for a live ordinary or activity-lease pause (`pending_dispatch` null), an empty timeout body continues that run: the response returns once status is `planning` or `running` again, the lease re-arms, the hard deadline stays put, and parked Planner input is then delivered once, in order. A live `awaiting_resume` pause is unchanged unless the body increases the send timeout. Otherwise restore the role engine/model choices from the run's spec and re-create dispatcher + runner. For recoverable send timeouts, body fields `send_timeout_ms` and `pending_dispatch_id` apply the increase-only migration described above; `allow_decrease`, lease overrides, and hard-cap overrides are rejected. A custom-engine config is never persisted and is never accepted over HTTP, so a role using `custom` is re-supplied by **reference**: `plannerCustomEngineRef` / `coderCustomEngineRef` / `reviewerCustomEngineRef` name an environment variable `CLAWO_CUSTOM_ENGINE_<NAME>` on the orchestrator host, which the server reads and resolves. The name is not sensitive, the value never crosses the wire, and an unknown name is an error rather than a silent start without credentials. Existing engine-specific conversation resume behavior is reused where supported; `chat.jsonl` remains the visual history fallback. 404 when there is no such run. |
|
|
394
407
|
| `POST /autoloop/<id>/delete` | `{ ok }` — stops the loop if still live, deletes the run record from the run store, and purges the role sessions' persisted resume ids so the run cannot be resumed. The ledger directory under `<workspace>/tasks/<run_id>/` is kept on disk. 404 when there is no such run. |
|
|
395
408
|
|
|
396
409
|
The dashboard's 3-pane autoloop view (`/dashboard`) consumes these endpoints:
|
|
@@ -464,13 +477,39 @@ Resume is explicit. `POST /autoloop/<id>/resume` (or
|
|
|
464
477
|
`SessionManager.autoloopResume()`) restarts a run from its stored spec.
|
|
465
478
|
Custom-engine configs are the one thing the spec does not carry (they can hold
|
|
466
479
|
secrets), so a resume must be given them again. Cancelling a run stops all three
|
|
467
|
-
agents, the same as `autoloop_stop`.
|
|
480
|
+
agents, the same as `autoloop_stop`.
|
|
481
|
+
|
|
482
|
+
On a non-fresh boot (resume / revisit), before any Planner session or
|
|
483
|
+
checkpoint publish, the boot reads the run ledger once and restores typed
|
|
484
|
+
`iter` and `metric_history` from the contiguous valid closed prefix of
|
|
485
|
+
`iter/0..K` (each closed entry needs `directive.json` plus a parsed
|
|
486
|
+
`verdict.json` whose `iter` matches and whose `decision` is a supported
|
|
487
|
+
Reviewer decision). Finite verdict metrics are kept in order, capped at
|
|
488
|
+
`MAX_METRIC_HISTORY` (20). The stored checkpoint's `iter` / `metric_history`
|
|
489
|
+
are never progress authority. A fresh start skips that read. When there is no
|
|
490
|
+
valid closed prefix (including missing or open/malformed `iter/0` with a later
|
|
491
|
+
canonical directory present), the reader returns without restore or refusal —
|
|
492
|
+
same Planner-only resume as before. If the highest committed Coder iteration
|
|
468
493
|
has ledger artifacts and no `verdict.json`, and `HEAD` still names that iter,
|
|
469
|
-
resume starts and sends only the Reviewer: one `review_request` for that
|
|
470
|
-
|
|
471
|
-
resume a Coder session, and a historical
|
|
472
|
-
unchanged. An in-flight send is still not
|
|
473
|
-
outbox.
|
|
494
|
+
resume still starts and sends only the Reviewer: one `review_request` for that
|
|
495
|
+
iteration (with rebuilt `prior_metrics`), and the dispatcher persists
|
|
496
|
+
`verdict.json`. It does not create or resume a Coder session, and a historical
|
|
497
|
+
persisted Coder registry row is left unchanged. An in-flight send is still not
|
|
498
|
+
retried, and there is no message outbox. A gap or malformed closed tail after a
|
|
499
|
+
valid prefix refuses the resume with a fixed generic error before any new
|
|
500
|
+
session or effect; ledger text is never echoed into the error.
|
|
501
|
+
|
|
502
|
+
**Accepted chat survives stop and owner loss.** `autoloop_chat` and `POST
|
|
503
|
+
/autoloop/:id/chat` accept a message only once it is in the run's checkpoint;
|
|
504
|
+
otherwise they fail (`autoloop chat could not be persisted`, or a stopping,
|
|
505
|
+
restoring or limit error) and nothing is sent. Up to 1,000 entries and 8 MiB
|
|
506
|
+
can be pending. Chat that was not yet handed to the Planner is delivered once,
|
|
507
|
+
in order, after a resume. Chat that was being delivered when the run stopped is
|
|
508
|
+
not resent: the status gains `unconfirmed_chat` (`count`, `last_at`,
|
|
509
|
+
`history_pending`) and chat history gets one system notice asking to re-send it
|
|
510
|
+
if needed. No further chat is handed over until that notice is recorded; if it
|
|
511
|
+
cannot be written the run pauses with `chat_notice_pending`, and a plain resume
|
|
512
|
+
retries it.
|
|
474
513
|
|
|
475
514
|
## Known limitations
|
|
476
515
|
|
|
@@ -489,6 +528,11 @@ outbox.
|
|
|
489
528
|
process until it is resumed, and a send that was in flight is not retried.
|
|
490
529
|
- **Multi-run / same workspace** races on `git index.lock`. Run separate
|
|
491
530
|
workspaces (or git worktrees) for concurrent runs.
|
|
531
|
+
- **Closed-ledger restore does not rebuild streaks or status.** Only `iter` and
|
|
532
|
+
capped `metric_history` are restored from the closed prefix; `rejectStreak`,
|
|
533
|
+
`regressionStreak`, and run `status` fields are not reconstructed. Prefixless
|
|
534
|
+
corruption, path/symlink size hardening, and fresh `autoloop_start` reuse of a
|
|
535
|
+
retained ledger id remain out of scope.
|
|
492
536
|
|
|
493
537
|
## Related
|
|
494
538
|
|
|
@@ -2,12 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
This document tracks which Claude Code CLI version Claw Orchestrator is currently synced to, and which features have been integrated. Recent rows also record the other engines' versions checked in the same sync.
|
|
4
4
|
|
|
5
|
-
## Currently tracked: **Claude Code CLI 2.1.
|
|
5
|
+
## Currently tracked: **Claude Code CLI 2.1.307** (as of 2026-10-24, plugin v7.13.0)
|
|
6
6
|
|
|
7
7
|
## Sync history
|
|
8
8
|
|
|
9
9
|
| Plugin Version | Claude CLI Version | Date | Notable integrations |
|
|
10
10
|
| ------------------- | ------------------ | ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
11
|
+
| v7.13.0 | 2.1.307 | 2026-10-24 | Codex 0.163.0→0.164.0; the other engines as tracked in v7.12.1. Integrated: Codex 0.164 app-server goal RPCs (`thread/goal/set` / `get` / `clear`, six goal states, `tokenBudget`, `thread/goal/updated`), structured `error` notifications (`codexErrorInfo`, `willRetry`), `turn/steer` during goal turns, and `approvalPolicy` on `thread/start` / `thread/resume`; the `goal` workflow node is built on them. Measured: a goal objective is capped at 4,000 characters, and a thread can be resumed only after its first turn. |
|
|
12
|
+
| v7.12.1 | 2.1.307 | 2026-10-22 | CC 2.1.302→2.1.307, agy 1.4.0→1.4.4, grok 1.0.62→1.0.67; Codex 0.163.0 and OpenCode 1.19.3 unchanged. No flag the wrappers pass changed. grok 1.0.67 makes `grok-4.7` its default and only model: registered (same prices and 500K window as `grok-4.6`), the `grok` alias moved to it, and a session with no `model` is labelled with the model grok reports. grok read-only re-measured on 1.0.67 (direct and shell writes blocked; the subagent probe hit the free-tier limit). OpenCode 2 still beta-only, still refused. |
|
|
11
13
|
| v7.12.0 | 2.1.302 | 2026-10-17 | CC 2.1.296→2.1.302, Codex 0.162.1→0.163.0, agy 1.3.2→1.4.0, grok 1.0.50→1.0.62, OpenCode 1.19.0→1.19.3. No flag the wrappers pass changed. grok read-only re-measured on 1.0.62 (direct, shell and subagent writes blocked; the failed-sandbox warning unchanged). OpenCode 2 still beta-only, still refused. Codex 0.163.0 turns Daybreak (security programme, not a model) on for eligible accounts; billing follows the model codex reports. |
|
|
12
14
|
| v7.11.0 | 2.1.296 | 2026-10-11 | CC 2.1.295→2.1.296, Codex 0.162.0→0.162.1, OpenCode 1.18.35→1.19.0; agy 1.3.2 and grok 1.0.50 unchanged. No flag the wrappers pass changed. OpenCode 1.19.0 offers `opencode upgrade --major` to OpenCode 2 (beta builds `0.0.0-beta-N`, replaces V1): measured on 0.0.0-beta-17823 it drops `step_finish` and `--variant`, and its free tier answers 403 to a custom agent, so the read-only agent is unverifiable — the OpenCode session now refuses a V2 binary at start. |
|
|
13
15
|
| v7.10.0 | 2.1.295 | 2026-10-09 | CC 2.1.292→2.1.295, Codex 0.160.1→0.162.0, agy 1.3.1→1.3.2, grok 1.0.46→1.0.50; OpenCode 1.18.35 unchanged. No flag the wrappers pass changed. Integrated: Claude Haiku 5.5 registered and the `haiku` alias moved to it (`--model haiku` resolves to `claude-haiku-5-5` in 2.1.295); Sonnet 5.5's cache-hit price corrected to 0.05× input. Integrated: grok 1.0.50's `--sandbox read-only` backs Grok's `sandboxMode: 'read-only'`, measured against direct, shell, subagent, resumed-turn and out-of-project writes; a profile grok cannot apply only warns, so the session kills the process on that warning. |
|
package/skills/references/cli.md
CHANGED
|
@@ -238,6 +238,37 @@ engine may appear more than once. With `--wait` the run is followed to the end
|
|
|
238
238
|
and every answer is printed, followed by the synthesis when `--synthesize` was
|
|
239
239
|
given. Checks run after the fan-out, as for `solve`.
|
|
240
240
|
|
|
241
|
+
## `clawo goal`
|
|
242
|
+
|
|
243
|
+
Run a Codex `/goal` on one `codex-app` thread, then have the runtime check the
|
|
244
|
+
result: goal → verify → repair on the same thread. See [workflow.md](./workflow.md#goal).
|
|
245
|
+
|
|
246
|
+
```bash
|
|
247
|
+
clawo goal "<objective>" | --objective-file <file>
|
|
248
|
+
[--check "<command>"]... [--contract <file>] [--check-timeout <minutes>]
|
|
249
|
+
[--launcher <arg>]... [--model <model>] [--effort <level>] [--sandbox <mode>] [--thread <id>]
|
|
250
|
+
[--token-budget N] [--goal-timeout <minutes>] [--max-repairs N]
|
|
251
|
+
[--cwd <dir>] [--wait] [--json]
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
| Option | Default | Notes |
|
|
255
|
+
| ------------------ | ----------------- | ------------------------------------------------------------------------------------------------------------------- |
|
|
256
|
+
| `--objective-file` | — | Read the objective from a file instead of the argument. Codex accepts at most 4,000 characters |
|
|
257
|
+
| `-c, --check` | — | A command check, repeatable, run after the goal. Split on whitespace; quote-needing commands go in `--contract` |
|
|
258
|
+
| `--check-timeout` | 10 | Minutes for each `--check`. The verifier's node timeout is sized from the checks |
|
|
259
|
+
| `--launcher` | — | Run codex under this command, one argv element per flag: `--launcher ./sandbox.sh --launcher task --launcher "0 1"` |
|
|
260
|
+
| `-m, --model` | codex's own | Codex model |
|
|
261
|
+
| `--sandbox` | `workspace-write` | Codex's own sandbox mode. With an outer sandbox as the boundary, `danger-full-access` |
|
|
262
|
+
| `--thread` | — | Start on this existing codex thread: its goal is replaced, its history kept |
|
|
263
|
+
| `--token-budget` | — | The goal stops as `budgetLimited` past this |
|
|
264
|
+
| `--goal-timeout` | none | Wall-clock minutes for one goal pass |
|
|
265
|
+
| `--max-repairs` | `1` | Times a red verdict sends the goal back to the same thread |
|
|
266
|
+
| `-w, --wait` | off | Follow the run; exit `0` only if it completes |
|
|
267
|
+
|
|
268
|
+
`clawo workflow show <runId>` prints the goal's status, tokens, time, resume
|
|
269
|
+
attempts and thread id while it runs; `clawo workflow steer <runId> "<text>"`
|
|
270
|
+
goes into the running turn.
|
|
271
|
+
|
|
241
272
|
## `clawo workflow`
|
|
242
273
|
|
|
243
274
|
```bash
|
|
@@ -245,7 +276,7 @@ clawo workflow list [--state <s>] [--workflow <name>] [--limit N] [--json]
|
|
|
245
276
|
clawo workflow show <runId> [--json]
|
|
246
277
|
clawo workflow resume <runId> # re-attach to a run whose process died
|
|
247
278
|
clawo workflow cancel <runId>
|
|
248
|
-
clawo workflow steer <runId> "<text>" #
|
|
279
|
+
clawo workflow steer <runId> "<text>" # a correction for the next agent node, or into a running goal
|
|
249
280
|
clawo workflow approve <runId> [reject]
|
|
250
281
|
```
|
|
251
282
|
|
|
@@ -120,7 +120,11 @@ that both read the file always agree.
|
|
|
120
120
|
Opening a run whose `status` is `terminated` (because its process has
|
|
121
121
|
exited, or because you're viewing it cross-process) fetches
|
|
122
122
|
`/autoloop/<id>/chat_history`, replays the conversation into the Planner pane,
|
|
123
|
-
and shows a green **Resume run** button in the topbar.
|
|
123
|
+
and shows a green **Resume run** button in the topbar. The same button is shown
|
|
124
|
+
for any live paused run, and it follows later SSE state: a pause adds it, and
|
|
125
|
+
returning to an active status removes it. Timeout fields are included only when
|
|
126
|
+
`pending_dispatch` exists; an ordinary or activity-lease pause resumes with
|
|
127
|
+
an empty timeout body. Clicking it POSTs `/autoloop/<id>/resume`;
|
|
124
128
|
the orchestrator re-attaches the Planner (reusing the persisted Claude
|
|
125
129
|
session ID when available, so Claude's context picks up where it left
|
|
126
130
|
off) and the dashboard reconnects to `/events` for live updates.
|
|
@@ -28,7 +28,7 @@ SessionManager
|
|
|
28
28
|
|
|
29
29
|
### Claude Code (`engine: 'claude'`)
|
|
30
30
|
|
|
31
|
-
Default engine. Long-running subprocess with streaming JSON I/O. Tested with Claude Code CLI **2.1.
|
|
31
|
+
Default engine. Long-running subprocess with streaming JSON I/O. Tested with Claude Code CLI **2.1.307**.
|
|
32
32
|
|
|
33
33
|
- Persistent multi-turn conversations
|
|
34
34
|
- Real-time streaming (text, tool_use, tool_result, system events)
|
|
@@ -62,7 +62,7 @@ await manager.startSession({
|
|
|
62
62
|
|
|
63
63
|
### OpenAI Codex (`engine: 'codex'`)
|
|
64
64
|
|
|
65
|
-
Wraps the `codex exec` subcommand. Each `send()` spawns a new process. Tested with `codex` CLI **0.
|
|
65
|
+
Wraps the `codex exec` subcommand. Each `send()` spawns a new process. Tested with `codex` CLI **0.164.0**.
|
|
66
66
|
|
|
67
67
|
- Non-interactive execution via `codex exec --sandbox workspace-write --skip-git-repo-check --json`
|
|
68
68
|
- Real `usage` from the `turn.completed` JSON event (input, output, cached, reasoning tokens). **These are cumulative over the thread, not per turn**, so they replace the session totals rather than being added to them; subtracting consecutive values gives one turn's prompt
|
|
@@ -102,19 +102,18 @@ await manager.startSession({
|
|
|
102
102
|
|
|
103
103
|
### OpenAI Codex App-Server (`engine: 'codex-app'`)
|
|
104
104
|
|
|
105
|
-
Wraps `codex app-server --listen stdio:// --enable goals` as a long-running JSON-RPC subprocess. **Required for `/goal` long-horizon objective support** — Codex's exec subcommand has no
|
|
105
|
+
Wraps `codex app-server --listen stdio:// --enable goals` as a long-running JSON-RPC subprocess. **Required for `/goal` long-horizon objective support** — Codex's exec subcommand has no goal surface. Tested with `codex` CLI **0.164.0**.
|
|
106
106
|
|
|
107
107
|
- Long-running subprocess; one `codex app-server` per session
|
|
108
108
|
- JSON-RPC 2.0 over stdio with v2 protocol method names (`initialize`, `thread/start`, `turn/start`, ...)
|
|
109
109
|
- Real-time streaming via `item/agentMessage/delta` notifications
|
|
110
110
|
- Cumulative token tracking from `thread/tokenUsage/updated` notifications. The same notification's `last` breakdown and `modelContextWindow` drive `contextPercent`, so it reports live occupancy against the window the server enforces rather than a running total over the model's published window
|
|
111
111
|
- `appendSystemPrompt` is placed at the top of the first message of a new thread (app-server has no system-prompt flag); a resumed thread already carries it
|
|
112
|
-
-
|
|
113
|
-
-
|
|
114
|
-
- v2 RPC tools (Codex 0.137): `codex_interrupt` (`turn/interrupt`), `codex_steer` (`turn/steer
|
|
115
|
-
-
|
|
116
|
-
|
|
117
|
-
> **Feature flag.** `goals` is an experimental Codex feature. The session always passes `--enable goals`; some goal commands may still fail or be ignored by the server.
|
|
112
|
+
- Goals through the typed RPCs `thread/goal/set` / `get` / `clear`: setting an objective starts the server's own turn loop, which runs until the goal is `complete`, `budgetLimited`, `blocked`, `usageLimited` or `paused`. Each change arrives as `thread/goal/updated`. The `codex_goal_*` tools wrap these; the kernel's `goal` node drives them for unattended runs ([workflow.md](./workflow.md#goal))
|
|
113
|
+
- `error` notifications are read as `{ error: { message, codexErrorInfo }, willRetry }`. The session keeps the last one (`lastError`, with `codexErrorInfo` as a name such as `serverOverloaded`) and emits it as `codex:error`; an error notification never throws when nothing listens for errors
|
|
114
|
+
- v2 RPC tools (Codex 0.137): `codex_interrupt` (`turn/interrupt`), `codex_steer` (`turn/steer`, including into a turn the goal loop started), `codex_fork` (`thread/fork`), `codex_rollback` (`thread/rollback`), `codex_models` (`model/list`), `codex_thread_list` (`thread/list`). A `turn/completed` with `status: 'failed'` rejects the turn and increments `toolErrors`.
|
|
115
|
+
- Threads are opened and resumed with `approvalPolicy: "never"`, and a server request the session cannot handle (an approval, a request for user input) gets an error reply at once: nothing here can answer one, and an unanswered request blocks its turn. The sandbox mode is the boundary.
|
|
116
|
+
- Thread resume: starting with `resumeSessionId` loads the existing thread via `thread/resume` instead of `thread/start`. The id the session manager stores and replays (model switch, restart) is the app-server's own thread id. A thread resumed with an active goal continues it on its own.
|
|
118
117
|
|
|
119
118
|
```typescript
|
|
120
119
|
await manager.startSession({
|
|
@@ -123,17 +122,27 @@ await manager.startSession({
|
|
|
123
122
|
model: 'gpt-5.5',
|
|
124
123
|
cwd: '/project',
|
|
125
124
|
});
|
|
126
|
-
|
|
127
|
-
// await manager.codexGoalCommand('codex-goal-task', 'build a tic-tac-toe app');
|
|
125
|
+
await manager.codexGoal('codex-goal-task', { action: 'set', objective: 'build a tic-tac-toe app' });
|
|
128
126
|
// or via the codex_goal_set tool:
|
|
129
127
|
// await tool('codex_goal_set', { name: 'codex-goal-task', objective: 'build a tic-tac-toe app' });
|
|
130
128
|
```
|
|
131
129
|
|
|
130
|
+
### Running an engine under a launcher
|
|
131
|
+
|
|
132
|
+
`SessionConfig.launcher` is an argv prefix the engine binary runs under, for every
|
|
133
|
+
engine: `launcher: ['/opt/task/sandbox.sh', 'task', '0 1']` spawns
|
|
134
|
+
`/opt/task/sandbox.sh task '0 1' codex app-server …`. This is how a caller puts
|
|
135
|
+
the agent inside its own sandbox (bubblewrap, a container entry point, `taskset`)
|
|
136
|
+
without a custom engine. The launcher is the caller's own command, at the same
|
|
137
|
+
trust level as a contract's command check, which the HTTP API also accepts: set
|
|
138
|
+
it through the SessionManager API, `/session/start` or a workflow spec (the `goal`
|
|
139
|
+
node's `launcher`). It is not a parameter of the `session_start` tool.
|
|
140
|
+
|
|
132
141
|
### Google Antigravity (`engine: 'agy'`)
|
|
133
142
|
|
|
134
143
|
Wraps Google's **Antigravity CLI** (`agy`) — the successor to Gemini CLI (consumer
|
|
135
144
|
Gemini CLI tiers stopped serving 2026-06-18). Each `send()` spawns a new process
|
|
136
|
-
in print mode. Tested with `agy` **1.4.
|
|
145
|
+
in print mode. Tested with `agy` **1.4.4**.
|
|
137
146
|
|
|
138
147
|
- One-shot execution per message (no persistent subprocess)
|
|
139
148
|
- **Structured output and real usage** — `--output-format stream-json` emits an
|
|
@@ -218,12 +227,14 @@ await manager.startSession({
|
|
|
218
227
|
### Grok Build (`engine: 'grok'`)
|
|
219
228
|
|
|
220
229
|
Wraps xAI's **Grok Build** CLI. Each `send()` spawns `grok -p <msg> --output-format json`, which
|
|
221
|
-
prints a single JSON object and exits. Tested with `grok` **1.0.
|
|
230
|
+
prints a single JSON object and exits. Tested with `grok` **1.0.67**.
|
|
222
231
|
|
|
223
232
|
- **Cost comes from the engine, not from the price table.** The result object carries
|
|
224
233
|
`total_cost_usd`, and the wrapper writes it straight into the session's spend, so the run ledger
|
|
225
234
|
and the `maxBudgetUsd` gate both read what xAI charged. Other engines multiply tokens by a rate in
|
|
226
|
-
`models.ts`. `grok-4.
|
|
235
|
+
`models.ts`. `grok-4.7` (grok's default since 1.0.67) and `grok-4.6` are still registered, for
|
|
236
|
+
their context window and an indicative breakdown; with no `model` set, the session is labelled with
|
|
237
|
+
the model grok reports under `modelUsage`.
|
|
227
238
|
- **Real conversation continuity**: the `sessionId` from turn 1 is replayed as `--resume <id>`.
|
|
228
239
|
`--continue` is not used — it means "the most recent session for this cwd", which collides
|
|
229
240
|
between concurrent sessions.
|
|
@@ -263,7 +274,7 @@ prints a single JSON object and exits. Tested with `grok` **1.0.62**.
|
|
|
263
274
|
await manager.startSession({
|
|
264
275
|
name: 'grok-task',
|
|
265
276
|
engine: 'grok',
|
|
266
|
-
model: 'grok-4.
|
|
277
|
+
model: 'grok-4.7',
|
|
267
278
|
cwd: '/project',
|
|
268
279
|
});
|
|
269
280
|
```
|
|
@@ -297,38 +297,37 @@ Returns `{ ok, stdout, stderr }`.
|
|
|
297
297
|
|
|
298
298
|
### `codex_goal_set`
|
|
299
299
|
|
|
300
|
-
Set a long-horizon objective.
|
|
300
|
+
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
301
|
|
|
302
|
-
| Parameter
|
|
303
|
-
|
|
|
304
|
-
| `name`
|
|
305
|
-
| `objective`
|
|
306
|
-
| `
|
|
302
|
+
| Parameter | Type | Required | Notes |
|
|
303
|
+
| ------------- | ------ | -------- | ---------------------------------------------------------------- |
|
|
304
|
+
| `name` | string | yes | |
|
|
305
|
+
| `objective` | string | yes | |
|
|
306
|
+
| `tokenBudget` | number | | Tokens the goal may spend; it stops as `budgetLimited` past this |
|
|
307
307
|
|
|
308
|
-
Returns `{ ok,
|
|
308
|
+
Returns `{ ok, goal }` where `goal` is `{ objective, status, tokenBudget, tokensUsed, timeUsedSeconds, ... }`. `status` is one of `active`, `paused`, `blocked`, `usageLimited`, `budgetLimited`, `complete`.
|
|
309
309
|
|
|
310
310
|
### `codex_goal_get`
|
|
311
311
|
|
|
312
|
-
|
|
312
|
+
Ask the app-server for the goal (`thread/goal/get`). Sends no turn.
|
|
313
313
|
|
|
314
314
|
| Parameter | Type | Required |
|
|
315
315
|
| --------- | ------ | -------- |
|
|
316
316
|
| `name` | string | yes |
|
|
317
317
|
|
|
318
|
-
Returns `{ ok, goal }` (`null` if no goal
|
|
318
|
+
Returns `{ ok, goal }` (`null` if the thread has no goal).
|
|
319
319
|
|
|
320
320
|
### `codex_goal_pause` / `codex_goal_resume` / `codex_goal_clear`
|
|
321
321
|
|
|
322
|
-
|
|
322
|
+
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
323
|
|
|
324
324
|
| Parameter | Type | Required |
|
|
325
325
|
| --------- | ------ | -------- |
|
|
326
326
|
| `name` | string | yes |
|
|
327
|
-
| `timeout` | number | |
|
|
328
327
|
|
|
329
|
-
Returns `{ ok,
|
|
328
|
+
Returns `{ ok, goal }` (`null` after `clear`).
|
|
330
329
|
|
|
331
|
-
|
|
330
|
+
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
331
|
|
|
333
332
|
### Codex app-server RPCs
|
|
334
333
|
|
|
@@ -645,7 +644,11 @@ or smaller values are rejected, and there is deliberately no
|
|
|
645
644
|
Each successful increase appends one migration row to `decisions.jsonl`; the
|
|
646
645
|
original run spec, history, and prior audit bytes are not rewritten. The
|
|
647
646
|
matching live awaiting-resume condition is advanced without replaying the
|
|
648
|
-
timed-out logical dispatch.
|
|
647
|
+
timed-out logical dispatch. A live ordinary or activity-lease pause
|
|
648
|
+
(`pending_dispatch` null) resumes with no timeout fields: the call returns once
|
|
649
|
+
the run is active again, the lease re-arms without moving the hard deadline,
|
|
650
|
+
and Planner chat parked during the pause is then delivered once, in order. A
|
|
651
|
+
no-option resume does not clear a pending send timeout.
|
|
649
652
|
|
|
650
653
|
### `autoloop_chat`
|
|
651
654
|
|
|
@@ -656,6 +659,14 @@ Send a message into the Planner conversation.
|
|
|
656
659
|
| `run_id` | string | yes |
|
|
657
660
|
| `text` | string | yes |
|
|
658
661
|
|
|
662
|
+
The message is accepted only once it is stored in the run checkpoint; otherwise
|
|
663
|
+
the call fails with `autoloop chat could not be persisted` (or a stopping,
|
|
664
|
+
restoring or limit error) and nothing is sent. Accepted chat survives
|
|
665
|
+
`autoloop_stop` and owner loss and is delivered once, in order, after a resume.
|
|
666
|
+
A message that was mid-delivery when the run stopped is not resent; it is
|
|
667
|
+
reported through `unconfirmed_chat` in `autoloop_status` and one notice in chat
|
|
668
|
+
history.
|
|
669
|
+
|
|
659
670
|
### `autoloop_status`
|
|
660
671
|
|
|
661
672
|
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
|
|