@enderfga/claw-orchestrator 7.2.0 → 7.4.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.
@@ -133,7 +133,7 @@ await manager.startSession({
133
133
 
134
134
  Wraps Google's **Antigravity CLI** (`agy`) — the successor to Gemini CLI (consumer
135
135
  Gemini CLI tiers stopped serving 2026-06-18). Each `send()` spawns a new process
136
- in print mode. Verified against `agy` **1.1.13**.
136
+ in print mode. Adapter behavior is covered through `agy` **1.2.2**.
137
137
 
138
138
  - One-shot execution per message (no persistent subprocess)
139
139
  - **Structured output and real usage** — `--output-format stream-json` emits an
@@ -145,6 +145,18 @@ in print mode. Verified against `agy` **1.1.13**.
145
145
  scrape remains as a fallback for turns that die before emitting `init`. Seed it
146
146
  externally via `resumeSessionId` (bare UUID only); read it back from
147
147
  `getStats().agyConversationId`.
148
+ - **Empty responses fail adapter-wide and remain recoverable**: an exit-0 result
149
+ with a missing, blank, or whitespace-only response rejects instead of becoming
150
+ a successful empty reply, whether the caller is Autoloop, MCP, HTTP, or the
151
+ library API. agy 1.1.26 may do this after plan mode soft-denies a tool
152
+ confirmation. The adapter clears the per-session log before each spawn and
153
+ recognizes only the narrow current-turn `tool_confirmation_manager` marker,
154
+ returning a fixed sanitized diagnosis without exposing native log content. A
155
+ conversation id already emitted by `init` is retained for the caller's next
156
+ send; the failed turn is not retried automatically. On agy 1.2.2 the same
157
+ denial can accompany `status: SUCCESS` and a non-empty reply; the refused tool
158
+ names are emitted as `permission_denials`, which SessionManager exposes as
159
+ `SendResult.permissionDenials` without discarding the reply.
148
160
  - **Reasoning effort**: session `effort` and per-turn `session_send` overrides map
149
161
  to `--effort`. agy accepts `low`, `medium`, and `high`; everything above that
150
162
  (`xhigh`, `max`, `ultra`) clamps to `high`. agy 1.1.25 requires an effort with unsuffixed base
@@ -163,15 +175,21 @@ in print mode. Verified against `agy` **1.1.13**.
163
175
  - Permission modes: `bypassPermissions` → `--dangerously-skip-permissions`,
164
176
  `default` → `--sandbox` (terminal-restricted), and
165
177
  `sandboxMode: 'read-only'` → `--mode plan` (takes precedence). Other modes
166
- run agy's own approval flow, which blocks in headless print mode — use
167
- `bypassPermissions` for autonomous write-enabled work
178
+ run agy's own approval flow, which can block in headless print mode. A caller
179
+ must explicitly choose `bypassPermissions` for a write-enabled session; it is
180
+ not a recovery mechanism. In particular, an Autoloop Planner stays on
181
+ `--mode plan` when its preserved conversation is resumed.
168
182
  - agy enforces its own print timeout (default 5m); the engine derives
169
183
  `--print-timeout` from the send timeout so the wrapper timer decides
170
- - Unknown `--model` slugs do **not** error — agy silently falls back to its
171
- default model. Registered slugs: `gemini-3.5-flash` (alias `agy-flash`),
172
- `gemini-3.1-pro` (alias `agy-pro`); agy also proxies Claude and GPT-OSS
173
- models (`agy models` lists them) which pass through unregistered. The
174
- `agy/` prefix forces Antigravity routing for provider-like model strings
184
+ - Do not rely on an unknown `--model` falling back: current agy versions can
185
+ report `status: ERROR` with no usable response. The adapter rejects result
186
+ errors, non-success statuses, and empty responses. `agy-flash` and the engine
187
+ default resolve to `gemini-3.8-flash`; `agy-pro` resolves to
188
+ `gemini-3.1-pro`. The registry also describes the 3.5/3.6/3.7 Flash API
189
+ families for pricing and routing, but agy's own `agy models` output decides
190
+ which slugs are executable. agy also proxies Claude and GPT-OSS models, which
191
+ pass through unregistered. The `agy/` prefix forces Antigravity routing for
192
+ provider-like model strings.
175
193
  - Consumer auth is a one-time `agy` Google OAuth login (subscription quotas, no
176
194
  per-token billing — registry pricing mirrors Gemini API rates as a value proxy)
177
195
  - Requires `agy` installed: `curl -fsSL https://antigravity.google/cli/install.sh | bash`
@@ -181,7 +199,7 @@ in print mode. Verified against `agy` **1.1.13**.
181
199
  await manager.startSession({
182
200
  name: 'antigravity-task',
183
201
  engine: 'agy',
184
- model: 'gemini-3.5-flash',
202
+ model: 'gemini-3.8-flash',
185
203
  effort: 'high',
186
204
  cwd: '/project',
187
205
  });
@@ -77,6 +77,53 @@ await manager.startSession({
77
77
 
78
78
  > `claude continue/respawn/stop/logs` are not headless subcommands — session continuation is via `resumeSessionId`/`forkSession`. Use the `claude_agents_list` tool (`claude agents --json`) to enumerate Claude Code background agent sessions.
79
79
 
80
+ ### Handing off to another engine
81
+
82
+ `resumeSessionId` and `forkSession` continue a conversation on the engine that holds it. To continue
83
+ it somewhere else — a stuck Claude session into Codex, an expensive model into a cheaper one —
84
+ use `handoffSession` (tool: `session_handoff`):
85
+
86
+ ```typescript
87
+ await manager.handoffSession('refactor', {
88
+ engine: 'codex',
89
+ message: 'Carry on from where we stopped.', // optional: send now and return the reply
90
+ });
91
+ // → new session 'refactor-codex', same cwd; 'refactor' keeps running untouched
92
+ ```
93
+
94
+ **How the conversation travels.** No engine can resume another's session, and each keeps its
95
+ history in its own undocumented on-disk format. So the conversation is replayed as text: a
96
+ `<conversation_history>` block in front of the new session's first message, after which the new
97
+ engine holds it itself. Every turn in it is fenced, so a reply that contains the block's own tags
98
+ cannot close it early and speak as another role. Nothing is written into either engine's session
99
+ store.
100
+
101
+ **What carries across.** What was said: every message sent through `sendMessage` and every reply,
102
+ recorded per session as it happens. The session's own history buffer is not used for this — it is
103
+ capped by event count, and on a long session the opening request is the first thing it loses. The
104
+ new session inherits the source's working directory and its engine-neutral settings (permission and
105
+ sandbox mode, effort, spend cap, system prompts, extra directories). It does not inherit anything
106
+ written for the source engine — its model, tool allowlists in that engine's tool names, resume ids,
107
+ profiles.
108
+
109
+ **What does not.** The source engine's hidden reasoning, which no engine exposes, and the detail of
110
+ tool calls — the new agent sees the replies that described the work, and the workspace itself, which
111
+ the framing tells it to check before relying on anything the history describes.
112
+
113
+ **When it is too long.** Up to `maxChars` (default 240,000 characters, ~60k tokens) the whole
114
+ conversation is sent. Past that, the opening request is kept, the newest turns fill what is left,
115
+ and one line records how many turns in between were left out: the request says what the work is
116
+ for, the newest turns say where it stands, and the middle is what the workspace can answer.
117
+
118
+ **A fork, not a move.** The two sessions go their separate ways. The new one starts from the
119
+ source's record, so handing it off again carries the whole conversation rather than only its own
120
+ part. The history is cleared only after a first send succeeds, so a first turn that fails on the
121
+ new engine does not strand the conversation it was carrying.
122
+
123
+ Verified end to end over MCP against the installed engines: a fact planted in a Claude session was
124
+ recalled by Codex 0.154.0 after a handoff, and again by Claude after a second handoff back, which
125
+ also named Codex as the engine it had taken over from.
126
+
80
127
  ### ultracode (Claude dynamic workflows)
81
128
 
82
129
  Set `ultracode: true` on a Claude `session_start` to have Claude orchestrate a JS workflow per substantive task and fan out to subagents. It is injected as the `ultracode: true` settings key merged into `--settings` (not a `--effort` value — the CLI rejects `--effort ultracode`):
@@ -2,7 +2,7 @@
2
2
 
3
3
  All tools are registered as Claw Orchestrator plugin tools. In standalone mode, they're accessible via the embedded HTTP server.
4
4
 
5
- ## Session Lifecycle (5)
5
+ ## Session Lifecycle (6)
6
6
 
7
7
  ### `session_start`
8
8
 
@@ -77,6 +77,26 @@ when there was at least one. Check it even when `error` is absent: a turn whose
77
77
  denied still ends as a success. See [sessions.md](./sessions.md) on what "succeeded" does and does
78
78
  not mean.
79
79
 
80
+ ### `session_handoff`
81
+
82
+ Continue a session's conversation on another engine — or the same engine with another model. Starts
83
+ a new session in the source's working directory and carries the conversation into it; the source
84
+ keeps running untouched.
85
+
86
+ | Parameter | Type | Required | Description |
87
+ | -------------- | ------ | -------- | --------------------------------------------------------------------------- |
88
+ | `name` | string | yes | The session to hand off from |
89
+ | `engine` | string | yes | Engine for the new session |
90
+ | `model` | string | | Model for the new session (default: the engine's default) |
91
+ | `newName` | string | | Name for the new session (default `<name>-<engine>`) |
92
+ | `message` | string | | Send this now and return the reply; otherwise the history waits for `session_send` |
93
+ | `maxChars` | number | | Cap on the carried history, in characters (default 240000, minimum 4000) |
94
+ | `customEngine` | object | | As in `session_start`, when `engine` is `custom` |
95
+
96
+ Returns `{ ok, name, engine, from: { name, engine }, carried: { turns, omitted, chars }, result? }`.
97
+ `result` is the send result of `message`, when one was given. See [sessions.md](./sessions.md) for
98
+ what carries across, what does not, and what is kept when the conversation is too long to send whole.
99
+
80
100
  ### `session_stop`
81
101
 
82
102
  Graceful shutdown (SIGTERM, then SIGKILL after 3s).