@enderfga/claw-orchestrator 7.13.0 → 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.
@@ -0,0 +1,409 @@
1
+ /**
2
+ * ACP Session — drives any agent that speaks the Agent Client Protocol on stdio.
3
+ *
4
+ * `acp-server.ts` is the other half: there the orchestrator is the agent. Here
5
+ * it is the client, so one wrapper covers every ACP agent (`kimi acp`,
6
+ * `opencode acp`, a Claude Code ACP adapter, …) with no per-agent parsing. The
7
+ * agent process lives as long as the session; each send is one `session/prompt`.
8
+ *
9
+ * Protocol notes (`@agentclientprotocol/sdk` 1.3.0, protocol v1):
10
+ * - `initialize` → `session/new` (or `session/load` / `session/resume` for a
11
+ * stored session id) → `session/prompt` per send. The prompt's response
12
+ * carries the stop reason; text, tool calls and usage arrive before it as
13
+ * `session/update` notifications.
14
+ * - The client advertises no `fs` or `terminal` capability, so the agent
15
+ * reads, writes and runs commands with its own tools, in its own process.
16
+ * - `session/request_permission` is answered at once from the session's
17
+ * permission mode. Nothing here can put a question to a person, and an
18
+ * unanswered request would hold the turn until it times out.
19
+ */
20
+ import { EventEmitter } from 'node:events';
21
+ import * as fs from 'node:fs';
22
+ import * as path from 'node:path';
23
+ import { Readable, Writable } from 'node:stream';
24
+ import * as acp from '@agentclientprotocol/sdk';
25
+ import { killEngineTree, spawnEngine } from './engine-spawn.js';
26
+ import { resolveAcpAgent } from './engine-presets.js';
27
+ import { resolveAlias } from './models.js';
28
+ import { SESSION_EVENT, MAX_HISTORY_ITEMS, DEFAULT_HISTORY_LIMIT } from './constants.js';
29
+ const DEFAULT_TURN_TIMEOUT_MS = 600_000;
30
+ /** Permission modes under which the agent may act without asking. */
31
+ const ALLOWING_MODES = new Set(['bypassPermissions', 'acceptEdits', 'auto', 'dontAsk']);
32
+ export class PersistentAcpSession extends EventEmitter {
33
+ options;
34
+ agent;
35
+ proc = null;
36
+ conn = null;
37
+ acpSessionId;
38
+ _isReady = false;
39
+ _isPaused = false;
40
+ _isBusy = false;
41
+ _startTime = null;
42
+ _history = [];
43
+ _requests = 0;
44
+ /** The turn in flight: its text so far and how to fail it if the process dies. */
45
+ turnText = '';
46
+ turnFail = null;
47
+ sessionId;
48
+ _stats = {
49
+ turns: 0,
50
+ turnsSucceeded: 0,
51
+ toolCalls: 0,
52
+ toolErrors: 0,
53
+ tokensIn: 0,
54
+ tokensOut: 0,
55
+ cachedTokens: 0,
56
+ costUsd: 0,
57
+ /** True once the agent has reported a cost; the registry estimate is then never used. */
58
+ costReported: false,
59
+ contextUsed: 0,
60
+ contextSize: 0,
61
+ lastActivity: null,
62
+ };
63
+ constructor(config) {
64
+ super();
65
+ const agent = resolveAcpAgent(config.acpAgent);
66
+ if (!agent)
67
+ throw new Error("engine 'acp' needs `acpAgent`: a bundled preset id or an inline config");
68
+ this.agent = agent;
69
+ this.options = { ...config, permissionMode: config.permissionMode || 'bypassPermissions' };
70
+ }
71
+ // ── Property accessors ─────────────────────────────────────────────────
72
+ get pid() {
73
+ return this.proc?.pid ?? undefined;
74
+ }
75
+ get isReady() {
76
+ return this._isReady;
77
+ }
78
+ get isPaused() {
79
+ return this._isPaused;
80
+ }
81
+ get isBusy() {
82
+ return this._isBusy;
83
+ }
84
+ /** The agent's own session id; a later session resumes it. */
85
+ get agentSessionId() {
86
+ return this.acpSessionId;
87
+ }
88
+ // ── Lifecycle ──────────────────────────────────────────────────────────
89
+ async start() {
90
+ const cwd = path.resolve(this.options.cwd || process.cwd());
91
+ if (!fs.existsSync(cwd))
92
+ fs.mkdirSync(cwd, { recursive: true });
93
+ this.options.cwd = cwd;
94
+ const command = (this.agent.commandEnv && process.env[this.agent.commandEnv]) || this.agent.command;
95
+ const proc = spawnEngine(command, this.agent.args ?? [], {
96
+ launcher: this.options.launcher,
97
+ cwd,
98
+ env: { ...process.env, ...this.agent.env },
99
+ stdio: ['pipe', 'pipe', 'pipe'],
100
+ });
101
+ this.proc = proc;
102
+ proc.stderr?.on('data', (d) => this.emit(SESSION_EVENT.LOG, `[acp:${this.agent.name}] ${d.toString()}`));
103
+ const exited = new Promise((_, reject) => {
104
+ proc.once('error', (err) => reject(new Error(`could not start ${command}: ${err.message}`)));
105
+ proc.once('exit', (code, signal) => {
106
+ this._isReady = false;
107
+ const err = new Error(`ACP agent ${this.agent.name} exited (${signal ?? `code ${code}`})`);
108
+ this.turnFail?.(err);
109
+ this.turnFail = null;
110
+ this.conn?.close(err);
111
+ reject(err);
112
+ this.emit(SESSION_EVENT.CLOSE, code ?? 0);
113
+ });
114
+ });
115
+ exited.catch(() => undefined);
116
+ const stream = acp.ndJsonStream(Writable.toWeb(proc.stdin), Readable.toWeb(proc.stdout));
117
+ this.conn = acp
118
+ .client({ name: 'claw-orchestrator' })
119
+ .onRequest(acp.methods.client.session.requestPermission, (ctx) => this._answerPermission(ctx.params))
120
+ .onNotification(acp.methods.client.session.update, (ctx) => this._onUpdate(ctx.params))
121
+ .connect(stream);
122
+ // A closed connection is a dead session, whether or not the exit has been reported yet.
123
+ this.conn.closed.then(() => (this._isReady = false), () => (this._isReady = false));
124
+ const agent = this.conn.agent;
125
+ const init = await Promise.race([
126
+ agent.request(acp.methods.agent.initialize, {
127
+ protocolVersion: acp.PROTOCOL_VERSION,
128
+ clientCapabilities: {},
129
+ clientInfo: { name: 'claw-orchestrator', version: '1' },
130
+ }),
131
+ exited,
132
+ ]);
133
+ const caps = init.agentCapabilities ?? {};
134
+ const resumeId = this.options.resumeSessionId;
135
+ if (resumeId) {
136
+ // A stored id that cannot be honoured is an error, not a fresh session:
137
+ // the caller asked for that conversation, and a new one would silently
138
+ // drop everything it knew.
139
+ if (caps.sessionCapabilities?.resume) {
140
+ await Promise.race([
141
+ agent.request(acp.methods.agent.session.resume, { sessionId: resumeId, cwd, mcpServers: [] }),
142
+ exited,
143
+ ]);
144
+ }
145
+ else if (caps.loadSession) {
146
+ await Promise.race([
147
+ agent.request(acp.methods.agent.session.load, { sessionId: resumeId, cwd, mcpServers: [] }),
148
+ exited,
149
+ ]);
150
+ }
151
+ else {
152
+ this.stop();
153
+ throw new Error(`ACP agent ${this.agent.name} cannot resume a session (no loadSession or resume capability)`);
154
+ }
155
+ // Set only now: `session/load` replays the conversation as updates
156
+ // before it returns, and an update for an id not yet ours is dropped —
157
+ // that history is not this session's work.
158
+ this.acpSessionId = resumeId;
159
+ }
160
+ else {
161
+ const created = await Promise.race([
162
+ agent.request(acp.methods.agent.session.new, { cwd, mcpServers: [] }),
163
+ exited,
164
+ ]);
165
+ this.acpSessionId = created.sessionId;
166
+ }
167
+ this.sessionId = `acp-${this.agent.name}-${Date.now().toString(36)}`;
168
+ this._startTime = new Date().toISOString();
169
+ this._isReady = true;
170
+ this.emit(SESSION_EVENT.READY);
171
+ this.emit(SESSION_EVENT.INIT, { type: 'system', subtype: 'init', session_id: this.sessionId });
172
+ return this;
173
+ }
174
+ stop() {
175
+ this._isReady = false;
176
+ this._isPaused = false;
177
+ if (this.conn && this.acpSessionId && this._isBusy) {
178
+ this.conn.agent.notify(acp.methods.agent.session.cancel, { sessionId: this.acpSessionId }).catch(() => undefined);
179
+ }
180
+ this.conn?.close();
181
+ this.conn = null;
182
+ if (this.proc) {
183
+ killEngineTree(this.proc);
184
+ this.proc = null;
185
+ }
186
+ }
187
+ pause() {
188
+ this._isPaused = true;
189
+ this.emit(SESSION_EVENT.PAUSED, { sessionId: this.sessionId });
190
+ }
191
+ resume() {
192
+ this._isPaused = false;
193
+ this.emit(SESSION_EVENT.RESUMED, { sessionId: this.sessionId });
194
+ }
195
+ // ── send() ─────────────────────────────────────────────────────────────
196
+ async send(message, options = {}) {
197
+ if (!this._isReady || !this.conn || !this.acpSessionId)
198
+ throw new Error('Session not ready. Call start() first.');
199
+ if (this._isBusy)
200
+ throw new Error('A turn is already running on this ACP session');
201
+ const text = typeof message === 'string' ? message : JSON.stringify(message);
202
+ const id = ++this._requests;
203
+ if (!options.waitForComplete) {
204
+ this._turn(text, options).catch((err) => this._emitError(err));
205
+ return { requestId: id, sent: true };
206
+ }
207
+ return this._turn(text, options);
208
+ }
209
+ async _turn(text, options) {
210
+ const conn = this.conn;
211
+ const sessionId = this.acpSessionId;
212
+ this._isBusy = true;
213
+ this.turnText = '';
214
+ const onText = (chunk) => {
215
+ try {
216
+ options.callbacks?.onText?.(chunk);
217
+ }
218
+ catch {
219
+ // A caller's callback failing does not fail the turn.
220
+ }
221
+ };
222
+ this.on(SESSION_EVENT.TEXT, onText);
223
+ let timer;
224
+ try {
225
+ const aborted = new Promise((_, reject) => {
226
+ this.turnFail = reject;
227
+ timer = setTimeout(() => {
228
+ conn.agent.notify(acp.methods.agent.session.cancel, { sessionId }).catch(() => undefined);
229
+ reject(new Error(`Timeout waiting for ACP agent ${this.agent.name} to finish the turn`));
230
+ }, options.timeout || DEFAULT_TURN_TIMEOUT_MS);
231
+ });
232
+ const response = await Promise.race([
233
+ conn.agent.request(acp.methods.agent.session.prompt, { sessionId, prompt: [{ type: 'text', text }] }),
234
+ aborted,
235
+ ]);
236
+ this._absorbUsage(response.usage);
237
+ const ok = response.stopReason === 'end_turn';
238
+ this._stats.turns++;
239
+ if (ok)
240
+ this._stats.turnsSucceeded++;
241
+ this._stats.lastActivity = new Date().toISOString();
242
+ const event = {
243
+ type: 'result',
244
+ subtype: ok ? 'success' : 'error',
245
+ result: this.turnText,
246
+ is_error: !ok,
247
+ stop_reason: response.stopReason,
248
+ session_id: this.sessionId,
249
+ total_cost_usd: this._stats.costUsd,
250
+ };
251
+ this._addHistory({ time: this._stats.lastActivity, type: 'result', event });
252
+ this.emit(SESSION_EVENT.RESULT, event);
253
+ this.emit(SESSION_EVENT.TURN_COMPLETE, event);
254
+ if (!ok)
255
+ throw new Error(`ACP agent ${this.agent.name} stopped the turn: ${response.stopReason}`);
256
+ return { text: this.turnText, event };
257
+ }
258
+ catch (err) {
259
+ if (!(err instanceof Error && err.message.startsWith(`ACP agent ${this.agent.name} stopped`))) {
260
+ this._stats.turns++;
261
+ }
262
+ // The connection usually ends (stdout EOF) before the exit is reported.
263
+ if (err instanceof Error && /connection closed/i.test(err.message)) {
264
+ throw new Error(`ACP agent ${this.agent.name} exited mid-turn`);
265
+ }
266
+ throw err;
267
+ }
268
+ finally {
269
+ clearTimeout(timer);
270
+ this.turnFail = null;
271
+ this._isBusy = false;
272
+ this.removeListener(SESSION_EVENT.TEXT, onText);
273
+ }
274
+ }
275
+ // ── Agent → client ─────────────────────────────────────────────────────
276
+ _answerPermission(params) {
277
+ const allow = ALLOWING_MODES.has(this.options.permissionMode ?? '');
278
+ const kinds = allow ? ['allow_once', 'allow_always'] : ['reject_once', 'reject_always'];
279
+ const option = kinds.map((k) => params.options.find((o) => o.kind === k)).find(Boolean);
280
+ this._addHistory({
281
+ time: new Date().toISOString(),
282
+ type: 'permission',
283
+ event: { tool: params.toolCall.title, answer: option?.kind ?? 'cancelled' },
284
+ });
285
+ return option
286
+ ? { outcome: { outcome: 'selected', optionId: option.optionId } }
287
+ : { outcome: { outcome: 'cancelled' } };
288
+ }
289
+ _onUpdate(params) {
290
+ if (params.sessionId !== this.acpSessionId)
291
+ return;
292
+ const update = params.update;
293
+ this._stats.lastActivity = new Date().toISOString();
294
+ switch (update.sessionUpdate) {
295
+ case 'agent_message_chunk':
296
+ if (update.content.type === 'text') {
297
+ this.turnText += update.content.text;
298
+ this.emit(SESSION_EVENT.TEXT, update.content.text);
299
+ }
300
+ break;
301
+ case 'tool_call':
302
+ this._stats.toolCalls++;
303
+ this.emit(SESSION_EVENT.TOOL_USE, { id: update.toolCallId, name: update.title, input: update.rawInput });
304
+ if (update.status === 'failed')
305
+ this._stats.toolErrors++;
306
+ break;
307
+ case 'tool_call_update':
308
+ if (update.status === 'failed')
309
+ this._stats.toolErrors++;
310
+ if (update.status === 'completed' || update.status === 'failed') {
311
+ this.emit(SESSION_EVENT.TOOL_RESULT, {
312
+ id: update.toolCallId,
313
+ is_error: update.status === 'failed',
314
+ output: update.rawOutput,
315
+ });
316
+ }
317
+ break;
318
+ case 'usage_update':
319
+ this._stats.contextUsed = update.used;
320
+ this._stats.contextSize = update.size;
321
+ if (update.cost && update.cost.currency.toUpperCase() === 'USD') {
322
+ this._stats.costUsd = update.cost.amount;
323
+ this._stats.costReported = true;
324
+ }
325
+ break;
326
+ default:
327
+ break;
328
+ }
329
+ }
330
+ /** `PromptResponse.usage` holds session totals, so it replaces, never adds. */
331
+ _absorbUsage(usage) {
332
+ if (!usage)
333
+ return;
334
+ this._stats.tokensIn = usage.inputTokens;
335
+ this._stats.tokensOut = usage.outputTokens;
336
+ this._stats.cachedTokens = usage.cachedReadTokens ?? 0;
337
+ if (!this._stats.costReported && this.agent.pricing) {
338
+ const p = this.agent.pricing;
339
+ const fresh = Math.max(0, this._stats.tokensIn - this._stats.cachedTokens);
340
+ this._stats.costUsd =
341
+ (fresh * p.input + this._stats.cachedTokens * (p.cached ?? p.input) + this._stats.tokensOut * p.output) /
342
+ 1_000_000;
343
+ }
344
+ }
345
+ // ── ISession surface ───────────────────────────────────────────────────
346
+ getStats() {
347
+ const window = this._stats.contextSize || this.agent.contextWindow || 0;
348
+ return {
349
+ turns: this._stats.turns,
350
+ turnsSucceeded: this._stats.turnsSucceeded,
351
+ toolCalls: this._stats.toolCalls,
352
+ toolErrors: this._stats.toolErrors,
353
+ tokensIn: this._stats.tokensIn,
354
+ tokensOut: this._stats.tokensOut,
355
+ cachedTokens: this._stats.cachedTokens,
356
+ costUsd: Math.round(this._stats.costUsd * 10000) / 10000,
357
+ isReady: this._isReady,
358
+ startTime: this._startTime,
359
+ lastActivity: this._stats.lastActivity,
360
+ contextPercent: window ? Math.min(100, Math.round((this._stats.contextUsed / window) * 100)) : 0,
361
+ retries: 0,
362
+ sessionId: this.sessionId,
363
+ uptime: this._startTime ? Math.round((Date.now() - new Date(this._startTime).getTime()) / 1000) : 0,
364
+ acpSessionId: this.acpSessionId,
365
+ };
366
+ }
367
+ getHistory(limit = DEFAULT_HISTORY_LIMIT) {
368
+ return this._history.slice(-limit);
369
+ }
370
+ getCost() {
371
+ const p = this.agent.pricing;
372
+ return {
373
+ model: this.options.model || this.agent.name,
374
+ tokensIn: this._stats.tokensIn,
375
+ tokensOut: this._stats.tokensOut,
376
+ cachedTokens: this._stats.cachedTokens,
377
+ pricing: { inputPer1M: p?.input ?? 0, outputPer1M: p?.output ?? 0, cachedPer1M: p?.cached },
378
+ breakdown: { inputCost: 0, cachedCost: 0, outputCost: 0 },
379
+ totalUsd: this._stats.costUsd,
380
+ };
381
+ }
382
+ async compact(_summary) {
383
+ const event = { type: 'result', result: 'ACP agents manage their own context' };
384
+ return { text: 'ACP agents manage their own context', event };
385
+ }
386
+ getEffort() {
387
+ return this.options.effort || 'auto';
388
+ }
389
+ setEffort(level) {
390
+ this.options.effort = level;
391
+ }
392
+ resolveModel(alias) {
393
+ return resolveAlias(alias);
394
+ }
395
+ // ── Helpers ────────────────────────────────────────────────────────────
396
+ /** As in codex-app: with no listener, an `'error'` event would throw and take the process down. */
397
+ _emitError(err) {
398
+ if (this.listenerCount(SESSION_EVENT.ERROR) > 0)
399
+ this.emit(SESSION_EVENT.ERROR, err);
400
+ else
401
+ this.emit(SESSION_EVENT.LOG, `[acp:${this.agent.name}] ${err.message}`);
402
+ }
403
+ _addHistory(entry) {
404
+ this._history.push(entry);
405
+ if (this._history.length > MAX_HISTORY_ITEMS)
406
+ this._history.shift();
407
+ }
408
+ }
409
+ //# sourceMappingURL=persistent-acp-session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"persistent-acp-session.js","sourceRoot":"","sources":["../../src/persistent-acp-session.ts"],"names":[],"mappings":"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"}
@@ -136,6 +136,7 @@ import { PersistentGrokSession } from './persistent-grok-session.js';
136
136
  import { PersistentOpencodeSession } from './persistent-opencode-session.js';
137
137
  import { PersistentAgySession } from './persistent-agy-session.js';
138
138
  import { PersistentCustomSession } from './persistent-custom-session.js';
139
+ import { PersistentAcpSession } from './persistent-acp-session.js';
139
140
  import { resolveCustomEngine } from './engine-presets.js';
140
141
  import { EFFORT_LEVELS, ENGINE_TYPES, overrideModelPricing, ENGINE_BINARY_NAMES, } from './types.js';
141
142
  import { resolveAlias, isClaudeModel, lookupModel } from './models.js';
@@ -2676,6 +2677,10 @@ export class SessionManager {
2676
2677
  if (engine === 'codex-app') {
2677
2678
  return session.codexThreadId;
2678
2679
  }
2680
+ // Likewise an ACP session's `sessionId` is ours; the agent resumes its own.
2681
+ if (engine === 'acp') {
2682
+ return session.agentSessionId;
2683
+ }
2679
2684
  return session.sessionId;
2680
2685
  }
2681
2686
  _storedResumeId(engine, id) {
@@ -2687,6 +2692,8 @@ export class SessionManager {
2687
2692
  return id && !/^grok-\d+-/.test(id) ? id : undefined;
2688
2693
  if (engine === 'codex-app')
2689
2694
  return id && !id.startsWith('codex-app-') ? id : undefined;
2695
+ if (engine === 'acp')
2696
+ return id && !id.startsWith('acp-') ? id : undefined;
2690
2697
  return id;
2691
2698
  }
2692
2699
  _listMdFiles(dir) {
@@ -2728,6 +2735,8 @@ export class SessionManager {
2728
2735
  if (!config.customEngine)
2729
2736
  throw new Error('customEngine config is required for engine type "custom"');
2730
2737
  return new PersistentCustomSession(config);
2738
+ case 'acp':
2739
+ return new PersistentAcpSession(config);
2731
2740
  case 'claude':
2732
2741
  default:
2733
2742
  return new PersistentClaudeSession(config, this.pluginConfig.claudeBin);