acpx 0.5.3 → 0.6.1
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 +12 -4
- package/dist/{cli-ChWsO-bb.js → cli-Ddxpnz9X.js} +4 -4
- package/dist/{cli-ChWsO-bb.js.map → cli-Ddxpnz9X.js.map} +1 -1
- package/dist/cli.d.ts +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +147 -75
- package/dist/cli.js.map +1 -1
- package/dist/{client-D-4_aZf2.d.ts → client-2fTFutRH.d.ts} +4 -2
- package/dist/client-2fTFutRH.d.ts.map +1 -0
- package/dist/{flags-ceSqz2T6.js → flags-yXzUm7Aq.js} +25 -6
- package/dist/flags-yXzUm7Aq.js.map +1 -0
- package/dist/{flows-_KmnuUXd.js → flows-CDsfbaA2.js} +13 -6
- package/dist/flows-CDsfbaA2.js.map +1 -0
- package/dist/flows.d.ts +2 -8
- package/dist/flows.d.ts.map +1 -1
- package/dist/flows.js +1 -1
- package/dist/{ipc-BM335WFg.js → ipc-BruTG5Fb.js} +50 -19
- package/dist/ipc-BruTG5Fb.js.map +1 -0
- package/dist/{output-C4QhjpM6.js → output-DmHvT8vm.js} +141 -12
- package/dist/output-DmHvT8vm.js.map +1 -0
- package/dist/{perf-metrics-D0um6IR6.js → perf-metrics-C2pXfxvR.js} +12 -2
- package/dist/perf-metrics-C2pXfxvR.js.map +1 -0
- package/dist/{prompt-turn-CXMtXBl-.js → prompt-turn-BY5SwU1F.js} +256 -80
- package/dist/prompt-turn-BY5SwU1F.js.map +1 -0
- package/dist/{render-Br-kVPK_.js → render-yqwtaOX4.js} +35 -3
- package/dist/{render-Br-kVPK_.js.map → render-yqwtaOX4.js.map} +1 -1
- package/dist/runtime.d.ts +84 -10
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +425 -190
- package/dist/runtime.js.map +1 -1
- package/dist/{session-BtwAKtJ3.js → session-BwgaPK8-.js} +119 -81
- package/dist/session-BwgaPK8-.js.map +1 -0
- package/dist/session-options-pCbHn_n7.d.ts +13 -0
- package/dist/session-options-pCbHn_n7.d.ts.map +1 -0
- package/dist/{types-yxf-gcOE.d.ts → types-CVBeQyi3.d.ts} +9 -1
- package/dist/types-CVBeQyi3.d.ts.map +1 -0
- package/package.json +21 -21
- package/skills/acpx/SKILL.md +9 -4
- package/dist/client-D-4_aZf2.d.ts.map +0 -1
- package/dist/flags-ceSqz2T6.js.map +0 -1
- package/dist/flows-_KmnuUXd.js.map +0 -1
- package/dist/ipc-BM335WFg.js.map +0 -1
- package/dist/output-C4QhjpM6.js.map +0 -1
- package/dist/perf-metrics-D0um6IR6.js.map +0 -1
- package/dist/prompt-turn-CXMtXBl-.js.map +0 -1
- package/dist/session-BtwAKtJ3.js.map +0 -1
- package/dist/types-yxf-gcOE.d.ts.map +0 -1
package/dist/runtime.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { C as isAcpResourceNotFoundError, S as extractAcpError, g as textPrompt, x as normalizeOutputError } from "./perf-metrics-
|
|
2
|
-
import {
|
|
1
|
+
import { C as isAcpResourceNotFoundError, S as extractAcpError, g as textPrompt, x as normalizeOutputError } from "./perf-metrics-C2pXfxvR.js";
|
|
2
|
+
import { I as parseSessionRecord, J as withTimeout, Q as resolveAgentCommand, R as defaultSessionEventLog, S as AcpClient, U as assertPersistedKeyPolicy, W as serializeSessionRecordForDisk, X as listBuiltInAgents, Y as DEFAULT_AGENT_NAME, _ as createSessionConversation, a as connectAndLoadSession, b as recordSessionUpdate, c as reconcileAgentSessionId, d as setDesiredConfigOption, f as setDesiredModeId, g as cloneSessionConversation, h as cloneSessionAcpxState, n as withConnectedSession, o as applyConversation, s as applyLifecycleSnapshotToRecord, t as runPromptTurn, v as recordClientOperation, x as trimConversationForRuntime, y as recordPromptSubmission } from "./prompt-turn-BY5SwU1F.js";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import fs from "node:fs/promises";
|
|
5
5
|
import { randomUUID } from "node:crypto";
|
|
@@ -31,9 +31,6 @@ function asString(value) {
|
|
|
31
31
|
function asOptionalString(value) {
|
|
32
32
|
return asTrimmedString(value) || void 0;
|
|
33
33
|
}
|
|
34
|
-
function asOptionalBoolean(value) {
|
|
35
|
-
return typeof value === "boolean" ? value : void 0;
|
|
36
|
-
}
|
|
37
34
|
function deriveAgentFromSessionKey(sessionKey, fallbackAgent) {
|
|
38
35
|
const match = sessionKey.match(/^agent:([^:]+):/i);
|
|
39
36
|
return (match?.[1] ? asTrimmedString(match[1]) : "") || fallbackAgent;
|
|
@@ -133,13 +130,54 @@ function createTextDeltaEvent(params) {
|
|
|
133
130
|
...params.tag ? { tag: params.tag } : {}
|
|
134
131
|
};
|
|
135
132
|
}
|
|
133
|
+
function readFirstString(record, keys) {
|
|
134
|
+
for (const key of keys) {
|
|
135
|
+
const value = asOptionalString(record[key]);
|
|
136
|
+
if (value) return value;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
function readFirstStringArray(record, keys) {
|
|
140
|
+
for (const key of keys) {
|
|
141
|
+
const value = record[key];
|
|
142
|
+
if (!Array.isArray(value)) continue;
|
|
143
|
+
const entries = value.map((entry) => asOptionalString(entry)).filter((entry) => entry !== void 0);
|
|
144
|
+
if (entries.length > 0) return entries;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
function summarizeToolInput(rawInput) {
|
|
148
|
+
if (rawInput == null) return;
|
|
149
|
+
if (typeof rawInput === "string" || typeof rawInput === "number" || typeof rawInput === "boolean") return String(rawInput);
|
|
150
|
+
if (!isRecord(rawInput)) return;
|
|
151
|
+
const command = readFirstString(rawInput, [
|
|
152
|
+
"command",
|
|
153
|
+
"cmd",
|
|
154
|
+
"program"
|
|
155
|
+
]);
|
|
156
|
+
const args = readFirstStringArray(rawInput, ["args", "arguments"]);
|
|
157
|
+
if (command) return [command, ...args ?? []].join(" ");
|
|
158
|
+
return readFirstString(rawInput, [
|
|
159
|
+
"path",
|
|
160
|
+
"file",
|
|
161
|
+
"filePath",
|
|
162
|
+
"filepath",
|
|
163
|
+
"target",
|
|
164
|
+
"uri",
|
|
165
|
+
"url",
|
|
166
|
+
"query",
|
|
167
|
+
"pattern",
|
|
168
|
+
"text",
|
|
169
|
+
"search"
|
|
170
|
+
]);
|
|
171
|
+
}
|
|
136
172
|
function createToolCallEvent(params) {
|
|
137
173
|
const title = asTrimmedString(params.payload.title) || "tool call";
|
|
138
174
|
const status = asTrimmedString(params.payload.status);
|
|
175
|
+
const inputSummary = summarizeToolInput(params.payload.rawInput);
|
|
139
176
|
const toolCallId = asOptionalString(params.payload.toolCallId);
|
|
177
|
+
const summaryText = status ? `${title} (${status})` : title;
|
|
140
178
|
return {
|
|
141
179
|
type: "tool_call",
|
|
142
|
-
text:
|
|
180
|
+
text: inputSummary ? `${summaryText}: ${inputSummary}` : summaryText,
|
|
143
181
|
tag: params.tag,
|
|
144
182
|
...toolCallId ? { toolCallId } : {},
|
|
145
183
|
...status ? { status } : {},
|
|
@@ -236,16 +274,8 @@ function parsePromptEventLine(line) {
|
|
|
236
274
|
...tag ? { tag } : {}
|
|
237
275
|
};
|
|
238
276
|
}
|
|
239
|
-
case "done":
|
|
240
|
-
|
|
241
|
-
stopReason: asOptionalString(payload.stopReason)
|
|
242
|
-
};
|
|
243
|
-
case "error": return {
|
|
244
|
-
type: "error",
|
|
245
|
-
message: asTrimmedString(payload.message) || "acpx runtime error",
|
|
246
|
-
code: asOptionalString(payload.code),
|
|
247
|
-
retryable: asOptionalBoolean(payload.retryable)
|
|
248
|
-
};
|
|
277
|
+
case "done":
|
|
278
|
+
case "error": return null;
|
|
249
279
|
default: return null;
|
|
250
280
|
}
|
|
251
281
|
}
|
|
@@ -272,6 +302,12 @@ function createDeferred() {
|
|
|
272
302
|
reject
|
|
273
303
|
};
|
|
274
304
|
}
|
|
305
|
+
function applyConfigOptionsToRecord(record, configOptions) {
|
|
306
|
+
if (!configOptions) return;
|
|
307
|
+
const acpxState = cloneSessionAcpxState(record.acpx) ?? {};
|
|
308
|
+
acpxState.config_options = structuredClone(configOptions);
|
|
309
|
+
record.acpx = acpxState;
|
|
310
|
+
}
|
|
275
311
|
var AsyncEventQueue = class {
|
|
276
312
|
items = [];
|
|
277
313
|
waits = [];
|
|
@@ -290,6 +326,9 @@ var AsyncEventQueue = class {
|
|
|
290
326
|
this.closed = true;
|
|
291
327
|
for (const waiter of this.waits.splice(0)) waiter.resolve(null);
|
|
292
328
|
}
|
|
329
|
+
clear() {
|
|
330
|
+
this.items.length = 0;
|
|
331
|
+
}
|
|
293
332
|
async next() {
|
|
294
333
|
if (this.items.length > 0) return this.items.shift() ?? null;
|
|
295
334
|
if (this.closed) return null;
|
|
@@ -360,6 +399,18 @@ function createRecordId(sessionKey, mode) {
|
|
|
360
399
|
function resumePolicyForSessionMode(mode) {
|
|
361
400
|
return mode === "persistent" ? "same-session-only" : "allow-new";
|
|
362
401
|
}
|
|
402
|
+
function legacyTerminalEventFromTurnResult(result) {
|
|
403
|
+
if (result.status === "failed") return {
|
|
404
|
+
type: "error",
|
|
405
|
+
message: result.error.message,
|
|
406
|
+
...result.error.code ? { code: result.error.code } : {},
|
|
407
|
+
...result.error.retryable === void 0 ? {} : { retryable: result.error.retryable }
|
|
408
|
+
};
|
|
409
|
+
return {
|
|
410
|
+
type: "done",
|
|
411
|
+
...result.stopReason ? { stopReason: result.stopReason } : {}
|
|
412
|
+
};
|
|
413
|
+
}
|
|
363
414
|
function statusSummary(record) {
|
|
364
415
|
return [
|
|
365
416
|
`session=${record.acpxRecordId}`,
|
|
@@ -372,6 +423,7 @@ function statusSummary(record) {
|
|
|
372
423
|
var AcpRuntimeManager = class {
|
|
373
424
|
activeControllers = /* @__PURE__ */ new Map();
|
|
374
425
|
pendingPersistentClients = /* @__PURE__ */ new Map();
|
|
426
|
+
closingActiveRecords = /* @__PURE__ */ new Set();
|
|
375
427
|
constructor(options, deps = {}) {
|
|
376
428
|
this.options = options;
|
|
377
429
|
this.deps = deps;
|
|
@@ -379,6 +431,79 @@ var AcpRuntimeManager = class {
|
|
|
379
431
|
createClient(options) {
|
|
380
432
|
return this.deps.clientFactory?.(options) ?? new AcpClient(options);
|
|
381
433
|
}
|
|
434
|
+
async readPendingPersistentClient(record, options) {
|
|
435
|
+
const pendingClient = this.pendingPersistentClients.get(record.acpxRecordId);
|
|
436
|
+
if (!pendingClient) return;
|
|
437
|
+
if (!pendingClient.hasReusableSession(record.acpSessionId)) {
|
|
438
|
+
this.pendingPersistentClients.delete(record.acpxRecordId);
|
|
439
|
+
await pendingClient.close().catch(() => {});
|
|
440
|
+
return;
|
|
441
|
+
}
|
|
442
|
+
if (options.consume) this.pendingPersistentClients.delete(record.acpxRecordId);
|
|
443
|
+
return pendingClient;
|
|
444
|
+
}
|
|
445
|
+
async closePendingPersistentClient(recordId) {
|
|
446
|
+
const pendingClient = this.pendingPersistentClients.get(recordId);
|
|
447
|
+
if (!pendingClient) return;
|
|
448
|
+
this.pendingPersistentClients.delete(recordId);
|
|
449
|
+
await pendingClient.close().catch(() => {});
|
|
450
|
+
}
|
|
451
|
+
async refreshClosedState(record) {
|
|
452
|
+
if (!this.closingActiveRecords.has(record.acpxRecordId)) return record.closed === true;
|
|
453
|
+
const latest = await this.options.sessionStore.load(record.acpxRecordId).catch(() => void 0);
|
|
454
|
+
record.closed = true;
|
|
455
|
+
record.closedAt = latest?.closedAt ?? record.closedAt ?? isoNow();
|
|
456
|
+
if (latest?.acpx) record.acpx = {
|
|
457
|
+
...record.acpx,
|
|
458
|
+
...latest.acpx
|
|
459
|
+
};
|
|
460
|
+
return true;
|
|
461
|
+
}
|
|
462
|
+
async retainPersistentClientAfterTurn(input) {
|
|
463
|
+
const { record, client } = input;
|
|
464
|
+
if (!!record.acpxRecordId.includes(":oneshot:") || record.closed || !client.hasReusableSession(record.acpSessionId)) return false;
|
|
465
|
+
const previousClient = this.pendingPersistentClients.get(record.acpxRecordId);
|
|
466
|
+
this.pendingPersistentClients.set(record.acpxRecordId, client);
|
|
467
|
+
if (previousClient && previousClient !== client) await previousClient.close().catch(() => {});
|
|
468
|
+
return true;
|
|
469
|
+
}
|
|
470
|
+
async withRuntimeControlSession(record, sessionMode, run) {
|
|
471
|
+
const pendingClient = await this.readPendingPersistentClient(record, { consume: false });
|
|
472
|
+
if (pendingClient) {
|
|
473
|
+
const value = await run({
|
|
474
|
+
client: pendingClient,
|
|
475
|
+
sessionId: record.acpSessionId,
|
|
476
|
+
record
|
|
477
|
+
});
|
|
478
|
+
record.lastUsedAt = isoNow();
|
|
479
|
+
record.closed = false;
|
|
480
|
+
record.closedAt = void 0;
|
|
481
|
+
record.protocolVersion = pendingClient.initializeResult?.protocolVersion;
|
|
482
|
+
record.agentCapabilities = pendingClient.initializeResult?.agentCapabilities;
|
|
483
|
+
applyLifecycleSnapshotToRecord(record, pendingClient.getAgentLifecycleSnapshot());
|
|
484
|
+
return {
|
|
485
|
+
value,
|
|
486
|
+
record
|
|
487
|
+
};
|
|
488
|
+
}
|
|
489
|
+
const result = await withConnectedSession({
|
|
490
|
+
sessionRecordId: record.acpxRecordId,
|
|
491
|
+
loadRecord: async (sessionRecordId) => await this.requireRecord(sessionRecordId),
|
|
492
|
+
saveRecord: async (connectedRecord) => await this.options.sessionStore.save(connectedRecord),
|
|
493
|
+
createClient: (options) => this.createClient(options),
|
|
494
|
+
mcpServers: [...this.options.mcpServers ?? []],
|
|
495
|
+
permissionMode: this.options.permissionMode,
|
|
496
|
+
nonInteractivePermissions: this.options.nonInteractivePermissions,
|
|
497
|
+
verbose: this.options.verbose,
|
|
498
|
+
timeoutMs: this.options.timeoutMs,
|
|
499
|
+
resumePolicy: resumePolicyForSessionMode(sessionMode),
|
|
500
|
+
run
|
|
501
|
+
});
|
|
502
|
+
return {
|
|
503
|
+
value: result.value,
|
|
504
|
+
record: result.record
|
|
505
|
+
};
|
|
506
|
+
}
|
|
382
507
|
async ensureSession(input) {
|
|
383
508
|
const cwd = path.resolve(input.cwd?.trim() || this.options.cwd);
|
|
384
509
|
const agentCommand = this.options.agentRegistry.resolve(input.agent);
|
|
@@ -390,6 +515,7 @@ var AcpRuntimeManager = class {
|
|
|
390
515
|
})) {
|
|
391
516
|
existing.closed = false;
|
|
392
517
|
existing.closedAt = void 0;
|
|
518
|
+
this.closingActiveRecords.delete(existing.acpxRecordId);
|
|
393
519
|
await this.options.sessionStore.save(existing);
|
|
394
520
|
return existing;
|
|
395
521
|
}
|
|
@@ -423,6 +549,7 @@ var AcpRuntimeManager = class {
|
|
|
423
549
|
cwd,
|
|
424
550
|
agentSessionId
|
|
425
551
|
});
|
|
552
|
+
this.closingActiveRecords.delete(record.acpxRecordId);
|
|
426
553
|
record.protocolVersion = client.initializeResult?.protocolVersion;
|
|
427
554
|
record.agentCapabilities = client.initializeResult?.agentCapabilities;
|
|
428
555
|
applyLifecycleSnapshotToRecord(record, client.getAgentLifecycleSnapshot());
|
|
@@ -438,86 +565,143 @@ var AcpRuntimeManager = class {
|
|
|
438
565
|
if (!keepClientOpen) await client.close();
|
|
439
566
|
}
|
|
440
567
|
}
|
|
441
|
-
|
|
442
|
-
const record = await this.requireRecord(input.handle.acpxRecordId ?? input.handle.sessionKey);
|
|
443
|
-
const conversation = cloneSessionConversation(record);
|
|
444
|
-
let acpxState = cloneSessionAcpxState(record.acpx);
|
|
568
|
+
startTurn(input) {
|
|
445
569
|
const promptInput = toPromptInput(input.text, input.attachments);
|
|
446
|
-
const promptMessageId = recordPromptSubmission(conversation, promptInput, isoNow());
|
|
447
|
-
trimConversationForRuntime(conversation);
|
|
448
570
|
const queue = new AsyncEventQueue();
|
|
449
|
-
|
|
450
|
-
if (pendingClient) {
|
|
451
|
-
this.pendingPersistentClients.delete(record.acpxRecordId);
|
|
452
|
-
if (!pendingClient.hasReusableSession(record.acpSessionId)) {
|
|
453
|
-
await pendingClient.close().catch(() => {});
|
|
454
|
-
pendingClient = void 0;
|
|
455
|
-
}
|
|
456
|
-
}
|
|
457
|
-
const client = pendingClient ?? this.createClient({
|
|
458
|
-
agentCommand: record.agentCommand,
|
|
459
|
-
cwd: record.cwd,
|
|
460
|
-
mcpServers: [...this.options.mcpServers ?? []],
|
|
461
|
-
permissionMode: this.options.permissionMode,
|
|
462
|
-
nonInteractivePermissions: this.options.nonInteractivePermissions,
|
|
463
|
-
verbose: this.options.verbose
|
|
464
|
-
});
|
|
465
|
-
let activeSessionId = record.acpSessionId;
|
|
466
|
-
let sawDone = false;
|
|
467
|
-
let pendingCancel = false;
|
|
468
|
-
let turnActive = true;
|
|
571
|
+
const result = createDeferred();
|
|
469
572
|
const sessionReady = createDeferred();
|
|
470
573
|
sessionReady.promise.catch(() => {});
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
574
|
+
let resultSettled = false;
|
|
575
|
+
let pendingCancel = false;
|
|
576
|
+
let turnActive = true;
|
|
577
|
+
let streamClosed = false;
|
|
578
|
+
let activeController = null;
|
|
579
|
+
const settleResult = (next) => {
|
|
580
|
+
if (resultSettled) return;
|
|
581
|
+
resultSettled = true;
|
|
582
|
+
result.resolve(next);
|
|
476
583
|
};
|
|
477
|
-
const
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
pendingCancel = true;
|
|
483
|
-
return true;
|
|
484
|
-
},
|
|
485
|
-
setSessionMode: async (modeId) => {
|
|
486
|
-
if (!client.hasActivePrompt()) await sessionReady.promise;
|
|
487
|
-
await client.setSessionMode(activeSessionId, modeId);
|
|
488
|
-
},
|
|
489
|
-
setSessionModel: async (modelId) => {
|
|
490
|
-
if (!client.hasActivePrompt()) await sessionReady.promise;
|
|
491
|
-
await client.setSessionModel(activeSessionId, modelId);
|
|
492
|
-
},
|
|
493
|
-
setSessionConfigOption: async (configId, value) => {
|
|
494
|
-
if (!client.hasActivePrompt()) await sessionReady.promise;
|
|
495
|
-
return await client.setSessionConfigOption(activeSessionId, configId, value);
|
|
496
|
-
}
|
|
584
|
+
const closeStream = () => {
|
|
585
|
+
if (streamClosed) return;
|
|
586
|
+
streamClosed = true;
|
|
587
|
+
queue.clear();
|
|
588
|
+
queue.close();
|
|
497
589
|
};
|
|
498
|
-
const
|
|
499
|
-
|
|
500
|
-
if (!
|
|
501
|
-
|
|
502
|
-
|
|
590
|
+
const requestCancel = async () => {
|
|
591
|
+
if (activeController) return await activeController.requestCancelActivePrompt();
|
|
592
|
+
if (!turnActive) return false;
|
|
593
|
+
pendingCancel = true;
|
|
594
|
+
return true;
|
|
503
595
|
};
|
|
504
596
|
const abortHandler = () => {
|
|
505
|
-
|
|
597
|
+
requestCancel();
|
|
506
598
|
};
|
|
507
599
|
if (input.signal) {
|
|
508
600
|
if (input.signal.aborted) {
|
|
509
|
-
|
|
510
|
-
|
|
601
|
+
closeStream();
|
|
602
|
+
settleResult({
|
|
603
|
+
status: "cancelled",
|
|
604
|
+
stopReason: "cancelled"
|
|
605
|
+
});
|
|
606
|
+
return {
|
|
607
|
+
requestId: input.requestId,
|
|
608
|
+
events: queue.iterate(),
|
|
609
|
+
result: result.promise,
|
|
610
|
+
cancel: async () => {},
|
|
611
|
+
closeStream: async () => {}
|
|
612
|
+
};
|
|
511
613
|
}
|
|
512
614
|
input.signal.addEventListener("abort", abortHandler, { once: true });
|
|
513
615
|
}
|
|
514
|
-
this.activeControllers.set(record.acpxRecordId, activeController);
|
|
515
616
|
(async () => {
|
|
617
|
+
let record = null;
|
|
618
|
+
let conversation = null;
|
|
619
|
+
let acpxState;
|
|
620
|
+
let client = null;
|
|
516
621
|
try {
|
|
517
|
-
|
|
622
|
+
record = await this.requireRecord(input.handle.acpxRecordId ?? input.handle.sessionKey);
|
|
623
|
+
conversation = cloneSessionConversation(record);
|
|
624
|
+
acpxState = cloneSessionAcpxState(record.acpx);
|
|
625
|
+
const promptStartedAt = isoNow();
|
|
626
|
+
const promptMessageId = recordPromptSubmission(conversation, promptInput, promptStartedAt);
|
|
627
|
+
trimConversationForRuntime(conversation);
|
|
628
|
+
record.lastPromptAt = promptStartedAt;
|
|
629
|
+
record.lastUsedAt = promptStartedAt;
|
|
630
|
+
record.acpx = acpxState;
|
|
631
|
+
applyConversation(record, conversation);
|
|
632
|
+
await this.options.sessionStore.save(record);
|
|
633
|
+
const pendingClient = await this.readPendingPersistentClient(record, { consume: true });
|
|
634
|
+
client = pendingClient ?? this.createClient({
|
|
635
|
+
agentCommand: record.agentCommand,
|
|
636
|
+
cwd: record.cwd,
|
|
637
|
+
mcpServers: [...this.options.mcpServers ?? []],
|
|
638
|
+
permissionMode: this.options.permissionMode,
|
|
639
|
+
nonInteractivePermissions: this.options.nonInteractivePermissions,
|
|
640
|
+
verbose: this.options.verbose
|
|
641
|
+
});
|
|
642
|
+
const runtimeClient = client;
|
|
643
|
+
const runtimeConversation = conversation;
|
|
644
|
+
const runtimeRecord = record;
|
|
645
|
+
let activeSessionId = record.acpSessionId;
|
|
646
|
+
const applyPendingCancel = async () => {
|
|
647
|
+
if (!pendingCancel || !runtimeClient.hasActivePrompt()) return false;
|
|
648
|
+
const cancelled = await runtimeClient.requestCancelActivePrompt();
|
|
649
|
+
if (cancelled) pendingCancel = false;
|
|
650
|
+
return cancelled;
|
|
651
|
+
};
|
|
652
|
+
activeController = {
|
|
653
|
+
hasActivePrompt: () => runtimeClient.hasActivePrompt(),
|
|
654
|
+
requestCancelActivePrompt: async () => {
|
|
655
|
+
if (runtimeClient.hasActivePrompt()) return await runtimeClient.requestCancelActivePrompt();
|
|
656
|
+
if (!turnActive) return false;
|
|
657
|
+
pendingCancel = true;
|
|
658
|
+
return true;
|
|
659
|
+
},
|
|
660
|
+
setSessionMode: async (modeId) => {
|
|
661
|
+
if (!runtimeClient.hasActivePrompt()) await sessionReady.promise;
|
|
662
|
+
await runtimeClient.setSessionMode(activeSessionId, modeId);
|
|
663
|
+
const nextState = cloneSessionAcpxState(acpxState) ?? {};
|
|
664
|
+
nextState.desired_mode_id = modeId;
|
|
665
|
+
acpxState = nextState;
|
|
666
|
+
},
|
|
667
|
+
setSessionModel: async (modelId) => {
|
|
668
|
+
if (!runtimeClient.hasActivePrompt()) await sessionReady.promise;
|
|
669
|
+
await runtimeClient.setSessionModel(activeSessionId, modelId);
|
|
670
|
+
},
|
|
671
|
+
setSessionConfigOption: async (configId, value) => {
|
|
672
|
+
if (!runtimeClient.hasActivePrompt()) await sessionReady.promise;
|
|
673
|
+
const response = await runtimeClient.setSessionConfigOption(activeSessionId, configId, value);
|
|
674
|
+
if (response?.configOptions) {
|
|
675
|
+
const nextState = cloneSessionAcpxState(acpxState) ?? {};
|
|
676
|
+
nextState.config_options = structuredClone(response.configOptions);
|
|
677
|
+
acpxState = nextState;
|
|
678
|
+
}
|
|
679
|
+
if (configId === "mode") {
|
|
680
|
+
const nextState = cloneSessionAcpxState(acpxState) ?? {};
|
|
681
|
+
nextState.desired_mode_id = value;
|
|
682
|
+
acpxState = nextState;
|
|
683
|
+
} else if (configId !== "model") {
|
|
684
|
+
const nextState = cloneSessionAcpxState(acpxState) ?? {};
|
|
685
|
+
nextState.desired_config_options = {
|
|
686
|
+
...nextState.desired_config_options,
|
|
687
|
+
[configId]: value
|
|
688
|
+
};
|
|
689
|
+
acpxState = nextState;
|
|
690
|
+
}
|
|
691
|
+
return response;
|
|
692
|
+
}
|
|
693
|
+
};
|
|
694
|
+
const emitParsed = (payload) => {
|
|
695
|
+
if (streamClosed) return;
|
|
696
|
+
const parsed = parsePromptEventLine(JSON.stringify(payload));
|
|
697
|
+
if (!parsed) return;
|
|
698
|
+
queue.push(parsed);
|
|
699
|
+
};
|
|
700
|
+
this.activeControllers.set(runtimeRecord.acpxRecordId, activeController);
|
|
701
|
+
runtimeClient.setEventHandlers({
|
|
518
702
|
onSessionUpdate: (notification) => {
|
|
519
|
-
acpxState = recordSessionUpdate(
|
|
520
|
-
trimConversationForRuntime(
|
|
703
|
+
acpxState = recordSessionUpdate(runtimeConversation, acpxState, notification);
|
|
704
|
+
trimConversationForRuntime(runtimeConversation);
|
|
521
705
|
emitParsed({
|
|
522
706
|
jsonrpc: "2.0",
|
|
523
707
|
method: "session/update",
|
|
@@ -525,8 +709,8 @@ var AcpRuntimeManager = class {
|
|
|
525
709
|
});
|
|
526
710
|
},
|
|
527
711
|
onClientOperation: (operation) => {
|
|
528
|
-
acpxState = recordClientOperation(
|
|
529
|
-
trimConversationForRuntime(
|
|
712
|
+
acpxState = recordClientOperation(runtimeConversation, acpxState, operation);
|
|
713
|
+
trimConversationForRuntime(runtimeConversation);
|
|
530
714
|
emitParsed({
|
|
531
715
|
type: "client_operation",
|
|
532
716
|
...operation
|
|
@@ -538,13 +722,14 @@ var AcpRuntimeManager = class {
|
|
|
538
722
|
resumed: false,
|
|
539
723
|
loadError: void 0
|
|
540
724
|
} : await connectAndLoadSession({
|
|
541
|
-
client,
|
|
542
|
-
record,
|
|
725
|
+
client: runtimeClient,
|
|
726
|
+
record: runtimeRecord,
|
|
543
727
|
resumePolicy: resumePolicyForSessionMode(input.sessionMode),
|
|
544
728
|
timeoutMs: this.options.timeoutMs,
|
|
545
729
|
activeController,
|
|
546
730
|
onClientAvailable: (controller) => {
|
|
547
|
-
|
|
731
|
+
activeController = controller;
|
|
732
|
+
this.activeControllers.set(runtimeRecord.acpxRecordId, controller);
|
|
548
733
|
},
|
|
549
734
|
onConnectedRecord: (connectedRecord) => {
|
|
550
735
|
connectedRecord.lastPromptAt = isoNow();
|
|
@@ -554,68 +739,96 @@ var AcpRuntimeManager = class {
|
|
|
554
739
|
}
|
|
555
740
|
});
|
|
556
741
|
sessionReady.resolve();
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
742
|
+
runtimeRecord.lastRequestId = input.requestId;
|
|
743
|
+
runtimeRecord.lastPromptAt = isoNow();
|
|
744
|
+
runtimeRecord.closed = false;
|
|
745
|
+
runtimeRecord.closedAt = void 0;
|
|
746
|
+
runtimeRecord.lastUsedAt = isoNow();
|
|
562
747
|
if (resumed || loadError) emitParsed({
|
|
563
748
|
type: "status",
|
|
564
749
|
text: loadError ? `load fallback: ${loadError}` : "session resumed"
|
|
565
750
|
});
|
|
566
751
|
if (pendingCancel || input.signal?.aborted) {
|
|
567
752
|
pendingCancel = false;
|
|
568
|
-
|
|
569
|
-
|
|
753
|
+
settleResult({
|
|
754
|
+
status: "cancelled",
|
|
570
755
|
stopReason: "cancelled"
|
|
571
756
|
});
|
|
572
757
|
return;
|
|
573
758
|
}
|
|
574
759
|
await applyPendingCancel();
|
|
575
760
|
const response = await runPromptTurn({
|
|
576
|
-
client,
|
|
761
|
+
client: runtimeClient,
|
|
577
762
|
sessionId,
|
|
578
763
|
prompt: promptInput,
|
|
579
764
|
timeoutMs: input.timeoutMs ?? this.options.timeoutMs,
|
|
580
|
-
conversation,
|
|
765
|
+
conversation: runtimeConversation,
|
|
581
766
|
promptMessageId
|
|
582
767
|
});
|
|
583
|
-
|
|
584
|
-
reconcileAgentSessionId(
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
applyConversation(
|
|
589
|
-
applyLifecycleSnapshotToRecord(
|
|
590
|
-
await this.options.sessionStore.save(
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
stopReason: response.stopReason
|
|
768
|
+
runtimeRecord.acpSessionId = activeSessionId;
|
|
769
|
+
reconcileAgentSessionId(runtimeRecord, runtimeRecord.agentSessionId);
|
|
770
|
+
runtimeRecord.protocolVersion = runtimeClient.initializeResult?.protocolVersion;
|
|
771
|
+
runtimeRecord.agentCapabilities = runtimeClient.initializeResult?.agentCapabilities;
|
|
772
|
+
runtimeRecord.acpx = acpxState;
|
|
773
|
+
applyConversation(runtimeRecord, runtimeConversation);
|
|
774
|
+
applyLifecycleSnapshotToRecord(runtimeRecord, runtimeClient.getAgentLifecycleSnapshot());
|
|
775
|
+
await this.options.sessionStore.save(runtimeRecord);
|
|
776
|
+
settleResult({
|
|
777
|
+
status: response.stopReason === "cancelled" ? "cancelled" : "completed",
|
|
778
|
+
...response.stopReason ? { stopReason: response.stopReason } : {}
|
|
594
779
|
});
|
|
595
780
|
} catch (error) {
|
|
596
781
|
sessionReady.reject(error);
|
|
597
782
|
const normalized = normalizeOutputError(error, { origin: "runtime" });
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
783
|
+
settleResult({
|
|
784
|
+
status: "failed",
|
|
785
|
+
error: {
|
|
786
|
+
message: normalized.message,
|
|
787
|
+
...normalized.code ? { code: normalized.code } : {},
|
|
788
|
+
...normalized.retryable !== void 0 ? { retryable: normalized.retryable } : {}
|
|
789
|
+
}
|
|
603
790
|
});
|
|
604
791
|
} finally {
|
|
605
792
|
turnActive = false;
|
|
606
793
|
if (input.signal) input.signal.removeEventListener("abort", abortHandler);
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
794
|
+
client?.clearEventHandlers();
|
|
795
|
+
let pooled = false;
|
|
796
|
+
if (record && conversation) {
|
|
797
|
+
applyLifecycleSnapshotToRecord(record, client?.getAgentLifecycleSnapshot() ?? { running: false });
|
|
798
|
+
record.acpx = acpxState;
|
|
799
|
+
applyConversation(record, conversation);
|
|
800
|
+
record.lastUsedAt = isoNow();
|
|
801
|
+
const closed = await this.refreshClosedState(record);
|
|
802
|
+
await this.options.sessionStore.save(record).catch(() => {});
|
|
803
|
+
if (!closed && client) pooled = await this.retainPersistentClientAfterTurn({
|
|
804
|
+
record,
|
|
805
|
+
client
|
|
806
|
+
});
|
|
807
|
+
}
|
|
808
|
+
if (!pooled) await client?.close().catch(() => {});
|
|
809
|
+
if (record) {
|
|
810
|
+
this.activeControllers.delete(record.acpxRecordId);
|
|
811
|
+
this.closingActiveRecords.delete(record.acpxRecordId);
|
|
812
|
+
}
|
|
615
813
|
queue.close();
|
|
616
814
|
}
|
|
617
815
|
})();
|
|
618
|
-
|
|
816
|
+
return {
|
|
817
|
+
requestId: input.requestId,
|
|
818
|
+
events: queue.iterate(),
|
|
819
|
+
result: result.promise,
|
|
820
|
+
cancel: async () => {
|
|
821
|
+
await requestCancel();
|
|
822
|
+
},
|
|
823
|
+
closeStream: async () => {
|
|
824
|
+
closeStream();
|
|
825
|
+
}
|
|
826
|
+
};
|
|
827
|
+
}
|
|
828
|
+
async *runTurn(input) {
|
|
829
|
+
const turn = this.startTurn(input);
|
|
830
|
+
yield* turn.events;
|
|
831
|
+
yield legacyTerminalEventFromTurnResult(await turn.result);
|
|
619
832
|
}
|
|
620
833
|
async getStatus(handle) {
|
|
621
834
|
const record = await this.requireRecord(handle.acpxRecordId ?? handle.sessionKey);
|
|
@@ -627,7 +840,8 @@ var AcpRuntimeManager = class {
|
|
|
627
840
|
details: {
|
|
628
841
|
cwd: record.cwd,
|
|
629
842
|
lastUsedAt: record.lastUsedAt,
|
|
630
|
-
closed: record.closed === true
|
|
843
|
+
closed: record.closed === true,
|
|
844
|
+
...record.acpx?.config_options !== void 0 ? { configOptions: structuredClone(record.acpx.config_options) } : {}
|
|
631
845
|
}
|
|
632
846
|
};
|
|
633
847
|
}
|
|
@@ -636,20 +850,8 @@ var AcpRuntimeManager = class {
|
|
|
636
850
|
const controller = this.activeControllers.get(record.acpxRecordId);
|
|
637
851
|
let targetRecord = record;
|
|
638
852
|
if (controller) await controller.setSessionMode(mode);
|
|
639
|
-
else targetRecord = (await
|
|
640
|
-
|
|
641
|
-
loadRecord: async (sessionRecordId) => await this.requireRecord(sessionRecordId),
|
|
642
|
-
saveRecord: async (connectedRecord) => await this.options.sessionStore.save(connectedRecord),
|
|
643
|
-
createClient: (options) => this.createClient(options),
|
|
644
|
-
mcpServers: [...this.options.mcpServers ?? []],
|
|
645
|
-
permissionMode: this.options.permissionMode,
|
|
646
|
-
nonInteractivePermissions: this.options.nonInteractivePermissions,
|
|
647
|
-
verbose: this.options.verbose,
|
|
648
|
-
timeoutMs: this.options.timeoutMs,
|
|
649
|
-
resumePolicy: resumePolicyForSessionMode(sessionMode),
|
|
650
|
-
run: async ({ client, sessionId }) => {
|
|
651
|
-
await client.setSessionMode(sessionId, mode);
|
|
652
|
-
}
|
|
853
|
+
else targetRecord = (await this.withRuntimeControlSession(record, sessionMode, async ({ client, sessionId }) => {
|
|
854
|
+
await client.setSessionMode(sessionId, mode);
|
|
653
855
|
})).record;
|
|
654
856
|
setDesiredModeId(targetRecord, mode);
|
|
655
857
|
await this.options.sessionStore.save(targetRecord);
|
|
@@ -658,24 +860,16 @@ var AcpRuntimeManager = class {
|
|
|
658
860
|
const record = await this.requireRecord(handle.acpxRecordId ?? handle.sessionKey);
|
|
659
861
|
const controller = this.activeControllers.get(record.acpxRecordId);
|
|
660
862
|
let targetRecord = record;
|
|
661
|
-
if (controller)
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
permissionMode: this.options.permissionMode,
|
|
669
|
-
nonInteractivePermissions: this.options.nonInteractivePermissions,
|
|
670
|
-
verbose: this.options.verbose,
|
|
671
|
-
timeoutMs: this.options.timeoutMs,
|
|
672
|
-
resumePolicy: resumePolicyForSessionMode(sessionMode),
|
|
673
|
-
run: async ({ client, sessionId, record: connectedRecord }) => {
|
|
674
|
-
await client.setSessionConfigOption(sessionId, key, value);
|
|
675
|
-
if (key === "mode") setDesiredModeId(connectedRecord, value);
|
|
676
|
-
}
|
|
863
|
+
if (controller) {
|
|
864
|
+
const response = await controller.setSessionConfigOption(key, value);
|
|
865
|
+
applyConfigOptionsToRecord(targetRecord, response?.configOptions);
|
|
866
|
+
} else targetRecord = (await this.withRuntimeControlSession(record, sessionMode, async ({ client, sessionId, record: connectedRecord }) => {
|
|
867
|
+
applyConfigOptionsToRecord(connectedRecord, (await client.setSessionConfigOption(sessionId, key, value))?.configOptions);
|
|
868
|
+
if (key === "mode") setDesiredModeId(connectedRecord, value);
|
|
869
|
+
else setDesiredConfigOption(connectedRecord, key, value);
|
|
677
870
|
})).record;
|
|
678
871
|
if (key === "mode") setDesiredModeId(targetRecord, value);
|
|
872
|
+
else setDesiredConfigOption(targetRecord, key, value);
|
|
679
873
|
await this.options.sessionStore.save(targetRecord);
|
|
680
874
|
}
|
|
681
875
|
async cancel(handle) {
|
|
@@ -683,6 +877,7 @@ var AcpRuntimeManager = class {
|
|
|
683
877
|
}
|
|
684
878
|
async close(handle, options = {}) {
|
|
685
879
|
const record = await this.requireRecord(handle.acpxRecordId ?? handle.sessionKey);
|
|
880
|
+
if (this.activeControllers.has(record.acpxRecordId)) this.closingActiveRecords.add(record.acpxRecordId);
|
|
686
881
|
await this.cancel(handle);
|
|
687
882
|
if (options.discardPersistentState) {
|
|
688
883
|
await this.closeBackendSession(record);
|
|
@@ -690,17 +885,14 @@ var AcpRuntimeManager = class {
|
|
|
690
885
|
...record.acpx,
|
|
691
886
|
reset_on_next_ensure: true
|
|
692
887
|
};
|
|
693
|
-
}
|
|
888
|
+
} else await this.closePendingPersistentClient(record.acpxRecordId);
|
|
694
889
|
record.closed = true;
|
|
695
890
|
record.closedAt = isoNow();
|
|
696
891
|
await this.options.sessionStore.save(record);
|
|
697
892
|
}
|
|
698
893
|
async closeBackendSession(record) {
|
|
699
|
-
const pendingClient = this.
|
|
700
|
-
|
|
701
|
-
const reusablePendingClient = pendingClient?.hasReusableSession(record.acpSessionId) === true ? pendingClient : void 0;
|
|
702
|
-
if (pendingClient && !reusablePendingClient) await pendingClient.close().catch(() => {});
|
|
703
|
-
const client = reusablePendingClient ?? this.createClient({
|
|
894
|
+
const pendingClient = await this.readPendingPersistentClient(record, { consume: true });
|
|
895
|
+
const client = pendingClient ?? this.createClient({
|
|
704
896
|
agentCommand: record.agentCommand,
|
|
705
897
|
cwd: record.cwd,
|
|
706
898
|
mcpServers: [...this.options.mcpServers ?? []],
|
|
@@ -709,7 +901,7 @@ var AcpRuntimeManager = class {
|
|
|
709
901
|
verbose: this.options.verbose
|
|
710
902
|
});
|
|
711
903
|
try {
|
|
712
|
-
if (!
|
|
904
|
+
if (!pendingClient) await withTimeout(client.start(), this.options.timeoutMs);
|
|
713
905
|
if (!client.supportsCloseSession()) throw new AcpRuntimeError("ACP_BACKEND_UNSUPPORTED_CONTROL", `Agent does not support session/close for ${record.acpxRecordId}.`);
|
|
714
906
|
await withTimeout(client.closeSession(record.acpSessionId), this.options.timeoutMs);
|
|
715
907
|
} catch (error) {
|
|
@@ -807,6 +999,28 @@ function writeHandleState(handle, state) {
|
|
|
807
999
|
}
|
|
808
1000
|
//#endregion
|
|
809
1001
|
//#region src/runtime/public/probe.ts
|
|
1002
|
+
function formatRuntimeDetail(value) {
|
|
1003
|
+
if (value instanceof Error) return value.message || value.name;
|
|
1004
|
+
if (typeof value === "string") return value;
|
|
1005
|
+
if (value == null || typeof value === "number" || typeof value === "boolean" || typeof value === "bigint" || typeof value === "symbol") return String(value);
|
|
1006
|
+
if (typeof value === "function") return value.name ? `[Function ${value.name}]` : "[Function]";
|
|
1007
|
+
const seen = /* @__PURE__ */ new WeakSet();
|
|
1008
|
+
try {
|
|
1009
|
+
return JSON.stringify(value, (_key, nested) => {
|
|
1010
|
+
if (nested instanceof Error) return nested.message || nested.name;
|
|
1011
|
+
if (nested && typeof nested === "object") {
|
|
1012
|
+
if (seen.has(nested)) return "[Circular]";
|
|
1013
|
+
seen.add(nested);
|
|
1014
|
+
}
|
|
1015
|
+
return nested;
|
|
1016
|
+
}) ?? "undefined";
|
|
1017
|
+
} catch {
|
|
1018
|
+
return "unserializable object";
|
|
1019
|
+
}
|
|
1020
|
+
}
|
|
1021
|
+
function normalizeRuntimeDetails(details) {
|
|
1022
|
+
return details?.map((detail) => formatRuntimeDetail(detail));
|
|
1023
|
+
}
|
|
810
1024
|
async function probeRuntime(options, deps = {}) {
|
|
811
1025
|
const agentName = options.probeAgent?.trim() || "codex";
|
|
812
1026
|
const agentCommand = options.agentRegistry.resolve(agentName);
|
|
@@ -845,7 +1059,7 @@ async function probeRuntime(options, deps = {}) {
|
|
|
845
1059
|
`agent=${agentName}`,
|
|
846
1060
|
`command=${agentCommand}`,
|
|
847
1061
|
`cwd=${options.cwd}`,
|
|
848
|
-
|
|
1062
|
+
formatRuntimeDetail(error)
|
|
849
1063
|
]
|
|
850
1064
|
};
|
|
851
1065
|
} finally {
|
|
@@ -882,7 +1096,8 @@ var AcpxRuntime = class {
|
|
|
882
1096
|
return this.healthy;
|
|
883
1097
|
}
|
|
884
1098
|
async probeAvailability() {
|
|
885
|
-
|
|
1099
|
+
const report = await this.runProbe();
|
|
1100
|
+
this.healthy = report.ok;
|
|
886
1101
|
}
|
|
887
1102
|
async doctor() {
|
|
888
1103
|
const report = await this.runProbe();
|
|
@@ -891,7 +1106,7 @@ var AcpxRuntime = class {
|
|
|
891
1106
|
ok: report.ok,
|
|
892
1107
|
code: report.ok ? void 0 : "ACP_BACKEND_UNAVAILABLE",
|
|
893
1108
|
message: report.message,
|
|
894
|
-
details: report.details
|
|
1109
|
+
details: normalizeRuntimeDetails(report.details)
|
|
895
1110
|
};
|
|
896
1111
|
}
|
|
897
1112
|
async ensureSession(input) {
|
|
@@ -926,13 +1141,38 @@ var AcpxRuntime = class {
|
|
|
926
1141
|
});
|
|
927
1142
|
return handle;
|
|
928
1143
|
}
|
|
1144
|
+
startTurn(input) {
|
|
1145
|
+
const { handle, state } = this.resolveManagerHandle(input.handle);
|
|
1146
|
+
const turnPromise = this.getManager().then((manager) => manager.startTurn({
|
|
1147
|
+
handle,
|
|
1148
|
+
text: input.text,
|
|
1149
|
+
attachments: input.attachments,
|
|
1150
|
+
mode: input.mode,
|
|
1151
|
+
sessionMode: state.mode,
|
|
1152
|
+
requestId: input.requestId,
|
|
1153
|
+
timeoutMs: input.timeoutMs,
|
|
1154
|
+
signal: input.signal
|
|
1155
|
+
}));
|
|
1156
|
+
return {
|
|
1157
|
+
requestId: input.requestId,
|
|
1158
|
+
events: { async *[Symbol.asyncIterator]() {
|
|
1159
|
+
yield* (await turnPromise).events;
|
|
1160
|
+
} },
|
|
1161
|
+
get result() {
|
|
1162
|
+
return turnPromise.then((turn) => turn.result);
|
|
1163
|
+
},
|
|
1164
|
+
cancel(inputArgs) {
|
|
1165
|
+
return turnPromise.then((turn) => turn.cancel(inputArgs));
|
|
1166
|
+
},
|
|
1167
|
+
closeStream(inputArgs) {
|
|
1168
|
+
return turnPromise.then((turn) => turn.closeStream(inputArgs));
|
|
1169
|
+
}
|
|
1170
|
+
};
|
|
1171
|
+
}
|
|
929
1172
|
async *runTurn(input) {
|
|
930
|
-
const state = this.
|
|
1173
|
+
const { handle, state } = this.resolveManagerHandle(input.handle);
|
|
931
1174
|
yield* (await this.getManager()).runTurn({
|
|
932
|
-
handle
|
|
933
|
-
...input.handle,
|
|
934
|
-
acpxRecordId: state.acpxRecordId ?? input.handle.acpxRecordId ?? input.handle.sessionKey
|
|
935
|
-
},
|
|
1175
|
+
handle,
|
|
936
1176
|
text: input.text,
|
|
937
1177
|
attachments: input.attachments,
|
|
938
1178
|
mode: input.mode,
|
|
@@ -942,43 +1182,28 @@ var AcpxRuntime = class {
|
|
|
942
1182
|
signal: input.signal
|
|
943
1183
|
});
|
|
944
1184
|
}
|
|
945
|
-
getCapabilities() {
|
|
1185
|
+
getCapabilities(_input) {
|
|
946
1186
|
return ACPX_CAPABILITIES;
|
|
947
1187
|
}
|
|
948
1188
|
async getStatus(input) {
|
|
949
|
-
const
|
|
950
|
-
return await (await this.getManager()).getStatus(
|
|
951
|
-
...input.handle,
|
|
952
|
-
acpxRecordId: state.acpxRecordId ?? input.handle.acpxRecordId ?? input.handle.sessionKey
|
|
953
|
-
});
|
|
1189
|
+
const { handle } = this.resolveManagerHandle(input.handle);
|
|
1190
|
+
return await (await this.getManager()).getStatus(handle);
|
|
954
1191
|
}
|
|
955
1192
|
async setMode(input) {
|
|
956
|
-
const state = this.
|
|
957
|
-
await (await this.getManager()).setMode(
|
|
958
|
-
...input.handle,
|
|
959
|
-
acpxRecordId: state.acpxRecordId ?? input.handle.acpxRecordId ?? input.handle.sessionKey
|
|
960
|
-
}, input.mode, state.mode);
|
|
1193
|
+
const { handle, state } = this.resolveManagerHandle(input.handle);
|
|
1194
|
+
await (await this.getManager()).setMode(handle, input.mode, state.mode);
|
|
961
1195
|
}
|
|
962
1196
|
async setConfigOption(input) {
|
|
963
|
-
const state = this.
|
|
964
|
-
await (await this.getManager()).setConfigOption(
|
|
965
|
-
...input.handle,
|
|
966
|
-
acpxRecordId: state.acpxRecordId ?? input.handle.acpxRecordId ?? input.handle.sessionKey
|
|
967
|
-
}, input.key, input.value, state.mode);
|
|
1197
|
+
const { handle, state } = this.resolveManagerHandle(input.handle);
|
|
1198
|
+
await (await this.getManager()).setConfigOption(handle, input.key, input.value, state.mode);
|
|
968
1199
|
}
|
|
969
1200
|
async cancel(input) {
|
|
970
|
-
const
|
|
971
|
-
await (await this.getManager()).cancel(
|
|
972
|
-
...input.handle,
|
|
973
|
-
acpxRecordId: state.acpxRecordId ?? input.handle.acpxRecordId ?? input.handle.sessionKey
|
|
974
|
-
});
|
|
1201
|
+
const { handle } = this.resolveManagerHandle(input.handle);
|
|
1202
|
+
await (await this.getManager()).cancel(handle);
|
|
975
1203
|
}
|
|
976
1204
|
async close(input) {
|
|
977
|
-
const
|
|
978
|
-
await (await this.getManager()).close({
|
|
979
|
-
...input.handle,
|
|
980
|
-
acpxRecordId: state.acpxRecordId ?? input.handle.acpxRecordId ?? input.handle.sessionKey
|
|
981
|
-
}, { discardPersistentState: input.discardPersistentState });
|
|
1205
|
+
const { handle } = this.resolveManagerHandle(input.handle);
|
|
1206
|
+
await (await this.getManager()).close(handle, { discardPersistentState: input.discardPersistentState });
|
|
982
1207
|
}
|
|
983
1208
|
async getManager() {
|
|
984
1209
|
if (this.manager) return this.manager;
|
|
@@ -991,6 +1216,16 @@ var AcpxRuntime = class {
|
|
|
991
1216
|
async runProbe() {
|
|
992
1217
|
return await (this.testOptions?.probeRunner?.(this.options) ?? probeRuntime(this.options));
|
|
993
1218
|
}
|
|
1219
|
+
resolveManagerHandle(handle) {
|
|
1220
|
+
const state = this.resolveHandleState(handle);
|
|
1221
|
+
return {
|
|
1222
|
+
handle: {
|
|
1223
|
+
...handle,
|
|
1224
|
+
acpxRecordId: state.acpxRecordId ?? handle.acpxRecordId ?? handle.sessionKey
|
|
1225
|
+
},
|
|
1226
|
+
state
|
|
1227
|
+
};
|
|
1228
|
+
}
|
|
994
1229
|
resolveHandleState(handle) {
|
|
995
1230
|
const decoded = decodeAcpxRuntimeHandleState(handle.runtimeSessionName);
|
|
996
1231
|
if (decoded) return {
|