acpx 0.19.3 → 0.19.5
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/dist/{agent-registry-DWnqUICY.js → agent-registry-kHdpsK9F.js} +16 -5
- package/dist/agent-registry-kHdpsK9F.js.map +1 -0
- package/dist/agent-registry.d.ts.map +1 -1
- package/dist/agent-registry.js +1 -1
- package/dist/{cli-C1uofM8S.js → cli-CQtZNbI4.js} +34 -46
- package/dist/cli-CQtZNbI4.js.map +1 -0
- package/dist/cli.d.ts +1 -1
- package/dist/cli.js +12 -11
- package/dist/cli.js.map +1 -1
- package/dist/{client-CdG6nVDG.d.ts → client-zT_kgYGW.d.ts} +4 -17
- package/dist/client-zT_kgYGW.d.ts.map +1 -0
- package/dist/{flows-hz_Pfsp-.js → flows-Clk_mTYy.js} +34 -14
- package/dist/flows-Clk_mTYy.js.map +1 -0
- package/dist/flows.d.ts +2 -2
- package/dist/flows.js +1 -1
- package/dist/{invocation-options-DbZzMvKM.js → invocation-options-iM1Cc2A1.js} +6 -12
- package/dist/invocation-options-iM1Cc2A1.js.map +1 -0
- package/dist/{ipc-BW06Pbb8.js → ipc-C96eDxkW.js} +188 -33
- package/dist/ipc-C96eDxkW.js.map +1 -0
- package/dist/{output-BjeeG-cj.js → output-DnEPVCtT.js} +80 -12
- package/dist/output-DnEPVCtT.js.map +1 -0
- package/dist/{queue-owner-runtime-Dhr4gxNE.js → queue-owner-runtime-DoijBCvt.js} +376 -174
- package/dist/queue-owner-runtime-DoijBCvt.js.map +1 -0
- package/dist/runtime.d.ts +18 -3
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +34 -9
- package/dist/runtime.js.map +1 -1
- package/dist/{session-options-X7LhX9BF.d.ts → session-options-CkcvthCv.d.ts} +2 -1
- package/dist/{session-options-X7LhX9BF.d.ts.map → session-options-CkcvthCv.d.ts.map} +1 -1
- package/dist/{session-watch-CgfkUKLA.js → session-watch-2CKSvPIS.js} +4 -4
- package/dist/{session-watch-CgfkUKLA.js.map → session-watch-2CKSvPIS.js.map} +1 -1
- package/dist/{watch-BGdqBiNX.js → watch-pnPd9LCw.js} +2 -2
- package/dist/{watch-BGdqBiNX.js.map → watch-pnPd9LCw.js.map} +1 -1
- package/package.json +7 -7
- package/skills/acpx/SKILL.md +8 -1
- package/dist/agent-registry-DWnqUICY.js.map +0 -1
- package/dist/cli-C1uofM8S.js.map +0 -1
- package/dist/client-CdG6nVDG.d.ts.map +0 -1
- package/dist/flows-hz_Pfsp-.js.map +0 -1
- package/dist/invocation-options-DbZzMvKM.js.map +0 -1
- package/dist/ipc-BW06Pbb8.js.map +0 -1
- package/dist/output-BjeeG-cj.js.map +0 -1
- package/dist/queue-owner-runtime-Dhr4gxNE.js.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { $ as
|
|
2
|
-
import { A as requireAgentStdio, C as PROCESS_HELPER_TIMEOUT_MS, D as isoNow$2, E as isChildProcessRunning, F as waitForChildExit, I as waitForSpawn, M as resolveAgentSessionCwd, N as runTimedExecFile, P as splitCommandLine, T as basenameToken, _ as buildSpawnCommandOptions, b as readWindowsEnvValue, f as resolveBuiltInAgentLaunch, g as buildAgentSpawnCommand, j as resolveAgentCommandParts, v as buildTerminalShellSpawnCommand, w as asAbsoluteCwd, x as resolveWindowsExecutablePath, y as buildTerminalSpawnCommand } from "./agent-registry-
|
|
1
|
+
import { $ as measurePerf, $t as UnsupportedPromptContentError, Bt as AgentStartupError, C as textPrompt, Dt as normalizeOutputError, Et as isRetryablePromptError, F as normalizeName, G as normalizeAgentSessionId, Gt as PermissionDeniedError, H as canonicalAgentCommand, Ht as ClaudeAcpSessionCreateTimeoutError, Jt as SessionConfigOptionReplayError, K as SESSION_JOURNAL_SCHEMA, Kt as PermissionPromptUnavailableError, L as readSessionRecord, Lt as AcpxOperationalError, M as isoNow$1, O as absolutePath, Ot as extractAcpError, Q as incrementPerfCounter, Qt as SessionResumeRequiredError, R as resolveSessionRecord, Rt as AgentDisconnectedError, S as promptToDisplayText, St as isProcessAlive, T as lockOwnerPid, Tt as isAcpQueryClosedBeforeResponseError, Ut as CopilotAcpUnsupportedError, Vt as AuthPolicyError, W as extractAgentSessionId, Wt as GeminiAcpStartupTimeoutError, X as formatPerfMetric, Xt as SessionModelReplayError, Yt as SessionModeReplayError, Z as getPerfMetricsSnapshot, _ as ProcessDescendants, _t as sessionEventLockPath, a as trySetModelOnRunningOwner, at as isAcpMessageObject, d as releaseQueueOwnerLease, et as resetPerfMetrics, f as terminateProcess, ft as defaultSessionEventLog, g as QueueLeaseGuardSettlementError, gt as sessionEventActivePath, h as waitMs$1, ht as sessionBaseDir, i as trySetModeOnRunningOwner, it as isAcpJsonRpcMessage, j as findSessionByDirectoryWalk, k as findGitRepositoryRoot, kt as isAcpResourceNotFoundError, m as tryAcquireQueueOwnerLease, mt as retainedEventMaxSegments, n as tryCloseSessionOnRunningOwner, nt as startPerfTimer, o as trySubmitToRunningOwner, ot as isSessionUpdateNotification, p as terminateQueueOwnerForSession, pt as existingEventSegmentIndices, q as SessionJournalReader, qt as QueueConnectionError, r as trySetConfigOptionOnRunningOwner, s as SessionQueueOwner, t as tryCancelOnRunningOwner, tt as setPerfGauge, u as refreshQueueOwnerLease, vt as sessionEventSegmentPath, w as createLockOwner, wt as formatErrorMessage, y as getUnsupportedPromptContentMessage, z as writeSessionRecord, zt as AgentSpawnError } from "./ipc-C96eDxkW.js";
|
|
2
|
+
import { A as requireAgentStdio, C as PROCESS_HELPER_TIMEOUT_MS, D as isoNow$2, E as isChildProcessRunning, F as waitForChildExit, I as waitForSpawn, M as resolveAgentSessionCwd, N as runTimedExecFile, P as splitCommandLine, T as basenameToken, _ as buildSpawnCommandOptions, b as readWindowsEnvValue, f as resolveBuiltInAgentLaunch, g as buildAgentSpawnCommand, j as resolveAgentCommandParts, v as buildTerminalShellSpawnCommand, w as asAbsoluteCwd, x as resolveWindowsExecutablePath, y as buildTerminalSpawnCommand } from "./agent-registry-kHdpsK9F.js";
|
|
3
3
|
import fs, { readFileSync, realpathSync } from "node:fs";
|
|
4
4
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
5
5
|
import path from "node:path";
|
|
@@ -112,8 +112,8 @@ async function pathExists(filePath) {
|
|
|
112
112
|
}
|
|
113
113
|
}
|
|
114
114
|
async function countExistingSegments(sessionId, maxSegments) {
|
|
115
|
-
|
|
116
|
-
|
|
115
|
+
const limit = retainedEventMaxSegments(maxSegments);
|
|
116
|
+
let count = (await existingEventSegmentIndices(sessionId)).filter((index) => index <= limit).length;
|
|
117
117
|
if (await pathExists(sessionEventActivePath(sessionId))) count += 1;
|
|
118
118
|
return count;
|
|
119
119
|
}
|
|
@@ -124,22 +124,36 @@ async function resolveInitialSegmentCount(record, maxSegments) {
|
|
|
124
124
|
async function resolveSessionMaxSegments(sessionId) {
|
|
125
125
|
try {
|
|
126
126
|
const configured = (await resolveSessionRecord(sessionId)).eventLog.max_segments;
|
|
127
|
-
|
|
127
|
+
const retained = retainedEventMaxSegments(configured);
|
|
128
|
+
if (retained > 0) return retained;
|
|
128
129
|
} catch {}
|
|
129
130
|
return 5;
|
|
130
131
|
}
|
|
131
132
|
async function rotateSegments(sessionId, maxSegments) {
|
|
132
|
-
const
|
|
133
|
-
|
|
134
|
-
await
|
|
133
|
+
const limit = retainedEventMaxSegments(maxSegments);
|
|
134
|
+
if (limit < 1) return;
|
|
135
|
+
await discardOverflowSegment(sessionId, limit);
|
|
136
|
+
await shiftRetainedSegments(sessionId, limit);
|
|
137
|
+
await promoteActiveSegment(sessionId);
|
|
138
|
+
}
|
|
139
|
+
async function discardOverflowSegment(sessionId, limit) {
|
|
140
|
+
if (!(await existingEventSegmentIndices(sessionId)).includes(limit)) return;
|
|
141
|
+
await fs$1.unlink(sessionEventSegmentPath(sessionId, limit)).catch((error) => {
|
|
135
142
|
if (error.code !== "ENOENT") throw error;
|
|
136
143
|
});
|
|
137
|
-
|
|
144
|
+
}
|
|
145
|
+
async function shiftRetainedSegments(sessionId, limit) {
|
|
146
|
+
const movable = (await existingEventSegmentIndices(sessionId)).filter((index) => index < limit).toSorted((left, right) => right - left);
|
|
147
|
+
for (const segment of movable) {
|
|
138
148
|
const from = sessionEventSegmentPath(sessionId, segment);
|
|
139
|
-
const to = sessionEventSegmentPath(sessionId, segment + 1);
|
|
140
149
|
if (!await pathExists(from)) continue;
|
|
141
|
-
|
|
150
|
+
const next = segment + 1;
|
|
151
|
+
if (!Number.isSafeInteger(next)) throw new Error("Session journal segment index exceeds its supported range");
|
|
152
|
+
await fs$1.rename(from, sessionEventSegmentPath(sessionId, next));
|
|
142
153
|
}
|
|
154
|
+
}
|
|
155
|
+
async function promoteActiveSegment(sessionId) {
|
|
156
|
+
const active = sessionEventActivePath(sessionId);
|
|
143
157
|
if (await pathExists(active)) await fs$1.rename(active, sessionEventSegmentPath(sessionId, 1));
|
|
144
158
|
}
|
|
145
159
|
var SessionEventWriter = class SessionEventWriter {
|
|
@@ -174,7 +188,7 @@ var SessionEventWriter = class SessionEventWriter {
|
|
|
174
188
|
}
|
|
175
189
|
static async open(record, options = {}) {
|
|
176
190
|
const maxSegmentBytes = options.maxSegmentBytes ?? record.eventLog.max_segment_bytes ?? 67108864;
|
|
177
|
-
const maxSegments = options.maxSegments ?? record.eventLog.max_segments ?? 5;
|
|
191
|
+
const maxSegments = retainedEventMaxSegments(options.maxSegments ?? record.eventLog.max_segments ?? 5);
|
|
178
192
|
const activePath = sessionEventActivePath(record.acpxRecordId);
|
|
179
193
|
const tail = await new SessionJournalReader({
|
|
180
194
|
...record,
|
|
@@ -339,7 +353,7 @@ var SessionEventWriter = class SessionEventWriter {
|
|
|
339
353
|
}
|
|
340
354
|
};
|
|
341
355
|
async function listSessionEvents(sessionId, maxSegments) {
|
|
342
|
-
maxSegments
|
|
356
|
+
maxSegments = retainedEventMaxSegments(maxSegments ?? await resolveSessionMaxSegments(sessionId));
|
|
343
357
|
return await new SessionJournalReader({
|
|
344
358
|
acpxRecordId: sessionId,
|
|
345
359
|
eventLog: { max_segments: maxSegments }
|
|
@@ -558,7 +572,7 @@ async function acquireSessionTurn(recordId, signal) {
|
|
|
558
572
|
}
|
|
559
573
|
async function acquireSessionScope(scope, signal) {
|
|
560
574
|
return await acquireSessionTurn(`ensure:${createHash("sha256").update(JSON.stringify([
|
|
561
|
-
scope.agentCommand,
|
|
575
|
+
canonicalAgentCommand(scope.agentCommand),
|
|
562
576
|
scope.cwd,
|
|
563
577
|
scope.name
|
|
564
578
|
])).digest("hex")}`, signal);
|
|
@@ -606,6 +620,18 @@ function sliceReadWindow(content, line, limit) {
|
|
|
606
620
|
}
|
|
607
621
|
//#endregion
|
|
608
622
|
//#region src/permission-prompt.ts
|
|
623
|
+
function visiblePromptText(value) {
|
|
624
|
+
let rendered = "";
|
|
625
|
+
for (const character of value) {
|
|
626
|
+
const codePoint = character.codePointAt(0);
|
|
627
|
+
if (codePoint !== void 0 && (codePoint <= 31 || codePoint >= 127 && codePoint <= 159)) {
|
|
628
|
+
rendered += `\\x${codePoint.toString(16).padStart(2, "0")}`;
|
|
629
|
+
continue;
|
|
630
|
+
}
|
|
631
|
+
rendered += character;
|
|
632
|
+
}
|
|
633
|
+
return rendered;
|
|
634
|
+
}
|
|
609
635
|
let promptQueue = Promise.resolve();
|
|
610
636
|
async function promptForPermission(options) {
|
|
611
637
|
options.signal?.throwIfAborted();
|
|
@@ -624,6 +650,10 @@ async function promptForPermission(options) {
|
|
|
624
650
|
signal.removeEventListener("abort", onAbort);
|
|
625
651
|
}
|
|
626
652
|
}
|
|
653
|
+
function promptForDisplay(prompt) {
|
|
654
|
+
if (prompt.startsWith("\n")) return `\n${visiblePromptText(prompt.slice(1))}`;
|
|
655
|
+
return visiblePromptText(prompt);
|
|
656
|
+
}
|
|
627
657
|
async function askPermission(options) {
|
|
628
658
|
options.signal?.throwIfAborted();
|
|
629
659
|
if (!canPrompt()) return false;
|
|
@@ -640,7 +670,7 @@ async function askPermission(options) {
|
|
|
640
670
|
rl.once("close", onClose);
|
|
641
671
|
});
|
|
642
672
|
try {
|
|
643
|
-
const answer = await Promise.race([rl.question(options.prompt, { signal }), closed]);
|
|
673
|
+
const answer = await Promise.race([rl.question(promptForDisplay(options.prompt), { signal }), closed]);
|
|
644
674
|
options.signal?.throwIfAborted();
|
|
645
675
|
const normalized = answer?.trim().toLowerCase();
|
|
646
676
|
return normalized === "y" || normalized === "yes";
|
|
@@ -654,8 +684,8 @@ function canPrompt() {
|
|
|
654
684
|
return process.stdin.isTTY && process.stderr.isTTY && !process.stdin.readableEnded && !process.stdin.destroyed;
|
|
655
685
|
}
|
|
656
686
|
function writePromptDetails(options) {
|
|
657
|
-
if (options.header) process.stderr.write(`\n${options.header}\n`);
|
|
658
|
-
if (options.details && options.details.trim().length > 0) process.stderr.write(`${options.details}\n`);
|
|
687
|
+
if (options.header) process.stderr.write(`\n${visiblePromptText(options.header)}\n`);
|
|
688
|
+
if (options.details && options.details.trim().length > 0) process.stderr.write(`${options.details.split("\n").map(visiblePromptText).join("\n")}\n`);
|
|
659
689
|
}
|
|
660
690
|
//#endregion
|
|
661
691
|
//#region src/filesystem.ts
|
|
@@ -1330,7 +1360,12 @@ function buildAgentEnvironment(authCredentials, sessionEnv, agentProcessEnv) {
|
|
|
1330
1360
|
function assignSessionEnv(env, key, value) {
|
|
1331
1361
|
const normalizedKey = protectedEnvKey(key);
|
|
1332
1362
|
for (const existingKey of Object.keys(env)) if (protectedEnvKey(existingKey) === normalizedKey) delete env[existingKey];
|
|
1333
|
-
env
|
|
1363
|
+
Object.defineProperty(env, key, {
|
|
1364
|
+
value,
|
|
1365
|
+
writable: true,
|
|
1366
|
+
enumerable: true,
|
|
1367
|
+
configurable: true
|
|
1368
|
+
});
|
|
1334
1369
|
}
|
|
1335
1370
|
function addAuthCredentialEnvKeys(protectedKeys, methodId, credential) {
|
|
1336
1371
|
if (typeof credential !== "string" || credential.trim().length === 0) return;
|
|
@@ -1516,34 +1551,7 @@ function captureCommandProbeOutput(child, timeoutMs, retire) {
|
|
|
1516
1551
|
};
|
|
1517
1552
|
}
|
|
1518
1553
|
//#endregion
|
|
1519
|
-
//#region src/acp/model-
|
|
1520
|
-
const REQUESTED_MODEL_UNSUPPORTED_ERROR_CODE = "ACP_MODEL_UNSUPPORTED";
|
|
1521
|
-
const REQUESTED_MODEL_UNSUPPORTED_REASONS = ["missing-capability", "unadvertised-model"];
|
|
1522
|
-
var RequestedModelUnsupportedError = class extends Error {
|
|
1523
|
-
code = REQUESTED_MODEL_UNSUPPORTED_ERROR_CODE;
|
|
1524
|
-
reason;
|
|
1525
|
-
ambiguous;
|
|
1526
|
-
constructor(message, reason, details) {
|
|
1527
|
-
super(message);
|
|
1528
|
-
this.name = "RequestedModelUnsupportedError";
|
|
1529
|
-
this.reason = reason;
|
|
1530
|
-
if (details?.ambiguous) this.ambiguous = true;
|
|
1531
|
-
}
|
|
1532
|
-
};
|
|
1533
|
-
function isRequestedModelUnsupportedReason(value) {
|
|
1534
|
-
return typeof value === "string" && REQUESTED_MODEL_UNSUPPORTED_REASONS.includes(value);
|
|
1535
|
-
}
|
|
1536
|
-
function isRequestedModelUnsupportedError(value) {
|
|
1537
|
-
if (value instanceof RequestedModelUnsupportedError) return true;
|
|
1538
|
-
if (!value || typeof value !== "object") return false;
|
|
1539
|
-
const candidate = value;
|
|
1540
|
-
return candidate.name === "RequestedModelUnsupportedError" && candidate.code === "ACP_MODEL_UNSUPPORTED" && isRequestedModelUnsupportedReason(candidate.reason);
|
|
1541
|
-
}
|
|
1542
|
-
function supportsLegacyClaudeCodeModelMetadata(agentCommand) {
|
|
1543
|
-
if (!agentCommand) return false;
|
|
1544
|
-
const { command, args } = splitCommandLine(agentCommand);
|
|
1545
|
-
return isClaudeAcpCommand(command, args);
|
|
1546
|
-
}
|
|
1554
|
+
//#region src/acp/model-config-state.ts
|
|
1547
1555
|
function asRecord$2(value) {
|
|
1548
1556
|
if (!value || typeof value !== "object" || Array.isArray(value)) return;
|
|
1549
1557
|
return value;
|
|
@@ -1602,6 +1610,35 @@ function modelStateFromConfigOptions(configOptions) {
|
|
|
1602
1610
|
}
|
|
1603
1611
|
return selected;
|
|
1604
1612
|
}
|
|
1613
|
+
//#endregion
|
|
1614
|
+
//#region src/acp/model-support.ts
|
|
1615
|
+
const REQUESTED_MODEL_UNSUPPORTED_ERROR_CODE = "ACP_MODEL_UNSUPPORTED";
|
|
1616
|
+
const REQUESTED_MODEL_UNSUPPORTED_REASONS = ["missing-capability", "unadvertised-model"];
|
|
1617
|
+
var RequestedModelUnsupportedError = class extends Error {
|
|
1618
|
+
code = REQUESTED_MODEL_UNSUPPORTED_ERROR_CODE;
|
|
1619
|
+
reason;
|
|
1620
|
+
ambiguous;
|
|
1621
|
+
constructor(message, reason, details) {
|
|
1622
|
+
super(message);
|
|
1623
|
+
this.name = "RequestedModelUnsupportedError";
|
|
1624
|
+
this.reason = reason;
|
|
1625
|
+
if (details?.ambiguous) this.ambiguous = true;
|
|
1626
|
+
}
|
|
1627
|
+
};
|
|
1628
|
+
function isRequestedModelUnsupportedReason(value) {
|
|
1629
|
+
return typeof value === "string" && REQUESTED_MODEL_UNSUPPORTED_REASONS.includes(value);
|
|
1630
|
+
}
|
|
1631
|
+
function isRequestedModelUnsupportedError(value) {
|
|
1632
|
+
if (value instanceof RequestedModelUnsupportedError) return true;
|
|
1633
|
+
if (!value || typeof value !== "object") return false;
|
|
1634
|
+
const candidate = value;
|
|
1635
|
+
return candidate.name === "RequestedModelUnsupportedError" && candidate.code === "ACP_MODEL_UNSUPPORTED" && isRequestedModelUnsupportedReason(candidate.reason);
|
|
1636
|
+
}
|
|
1637
|
+
function supportsLegacyClaudeCodeModelMetadata(agentCommand) {
|
|
1638
|
+
if (!agentCommand) return false;
|
|
1639
|
+
const { command, args } = splitCommandLine(agentCommand);
|
|
1640
|
+
return isClaudeAcpCommand(command, args);
|
|
1641
|
+
}
|
|
1605
1642
|
function modelStateFromLegacyResponse(response) {
|
|
1606
1643
|
if (!response || typeof response !== "object") return;
|
|
1607
1644
|
const models = response.models;
|
|
@@ -1633,6 +1670,16 @@ function resolveRequestedModelId(params) {
|
|
|
1633
1670
|
if (candidates.length > 1) throw new RequestedModelUnsupportedError(`Cannot select model "${params.requestedModel}": multiple advertised Cursor models match (${candidates.join(", ")}). Use an exact advertised model ID.`, "unadvertised-model", { ambiguous: true });
|
|
1634
1671
|
return candidates.length === 1 ? candidates[0] : params.requestedModel;
|
|
1635
1672
|
}
|
|
1673
|
+
function resolveRequestedConfigOption(params) {
|
|
1674
|
+
const modelConfigId = params.models?.configId;
|
|
1675
|
+
return {
|
|
1676
|
+
modelConfigId,
|
|
1677
|
+
resolvedValue: modelConfigId === params.configId ? resolveRequestedModelId({
|
|
1678
|
+
...params,
|
|
1679
|
+
requestedModel: params.value
|
|
1680
|
+
}) : params.value
|
|
1681
|
+
};
|
|
1682
|
+
}
|
|
1636
1683
|
function isCursorAcpCommandForModelAlias(agentCommand) {
|
|
1637
1684
|
if (!agentCommand) return false;
|
|
1638
1685
|
const { command, args } = splitCommandLine(agentCommand);
|
|
@@ -2242,7 +2289,7 @@ async function spawnTerminalProcess(params, defaultCwd, authority) {
|
|
|
2242
2289
|
}
|
|
2243
2290
|
async function spawnAndWait(spawnCommand, params, defaultCwd, authority) {
|
|
2244
2291
|
const spawnOptions = buildTerminalSpawnOptions(spawnCommand.command, params.cwd ?? defaultCwd, params.env);
|
|
2245
|
-
if (
|
|
2292
|
+
if (process.platform !== "win32") spawnOptions.detached = true;
|
|
2246
2293
|
assertControlAuthority(authority);
|
|
2247
2294
|
const proc = spawn(spawnCommand.command, spawnCommand.args, spawnOptions);
|
|
2248
2295
|
await waitForSpawn(proc);
|
|
@@ -2406,7 +2453,14 @@ function hasResponseField(response, field) {
|
|
|
2406
2453
|
}
|
|
2407
2454
|
function normalizeResponseConfigOptions(response) {
|
|
2408
2455
|
if (!response || !("configOptions" in response)) return;
|
|
2409
|
-
return response.configOptions
|
|
2456
|
+
return Array.isArray(response.configOptions) ? response.configOptions : void 0;
|
|
2457
|
+
}
|
|
2458
|
+
function normalizeConfigOptionAcknowledgement(response) {
|
|
2459
|
+
if (!response || typeof response !== "object" || Array.isArray(response)) return {};
|
|
2460
|
+
if (Array.isArray(response.configOptions)) return response;
|
|
2461
|
+
const acknowledgement = { ...response };
|
|
2462
|
+
delete acknowledgement.configOptions;
|
|
2463
|
+
return acknowledgement;
|
|
2410
2464
|
}
|
|
2411
2465
|
function toReconnectedSessionResult(response) {
|
|
2412
2466
|
const configOptions = normalizeResponseConfigOptions(response);
|
|
@@ -2417,7 +2471,7 @@ function toReconnectedSessionResult(response) {
|
|
|
2417
2471
|
configOptions,
|
|
2418
2472
|
response
|
|
2419
2473
|
}),
|
|
2420
|
-
configOptionsPresent:
|
|
2474
|
+
configOptionsPresent: configOptions !== void 0,
|
|
2421
2475
|
legacyModelMetadataPresent: hasResponseField(response, "models")
|
|
2422
2476
|
};
|
|
2423
2477
|
}
|
|
@@ -2971,7 +3025,7 @@ var AcpClient = class {
|
|
|
2971
3025
|
agentSessionId: extractAgentSessionId(result._meta),
|
|
2972
3026
|
configOptions,
|
|
2973
3027
|
models,
|
|
2974
|
-
configOptionsPresent:
|
|
3028
|
+
configOptionsPresent: configOptions !== void 0,
|
|
2975
3029
|
legacyModelMetadataPresent: hasResponseField(result, "models")
|
|
2976
3030
|
};
|
|
2977
3031
|
}
|
|
@@ -3128,11 +3182,11 @@ var AcpClient = class {
|
|
|
3128
3182
|
assertControlAuthority(authority);
|
|
3129
3183
|
const resolvedValue = models?.configId === configId ? this.resolveSessionModelId(value, models) : value;
|
|
3130
3184
|
const connection = this.getConnection();
|
|
3131
|
-
return await this.runConnectionRequest(() => connection.agent.request(methods.agent.session.setConfigOption, {
|
|
3185
|
+
return normalizeConfigOptionAcknowledgement(await this.runConnectionRequest(() => connection.agent.request(methods.agent.session.setConfigOption, {
|
|
3132
3186
|
sessionId,
|
|
3133
3187
|
configId,
|
|
3134
3188
|
value: resolvedValue
|
|
3135
|
-
}), authority, (error) => maybeWrapSessionControlError("session/set_config_option", error, `for "${configId}"="${value}"`));
|
|
3189
|
+
}), authority, (error) => maybeWrapSessionControlError("session/set_config_option", error, `for "${configId}"="${value}"`)));
|
|
3136
3190
|
}
|
|
3137
3191
|
async setSessionModel(sessionId, modelId, models, authority) {
|
|
3138
3192
|
assertControlAuthority(authority);
|
|
@@ -3154,11 +3208,11 @@ var AcpClient = class {
|
|
|
3154
3208
|
}
|
|
3155
3209
|
async setSessionModelThroughConfig(sessionId, modelId, configId, authority) {
|
|
3156
3210
|
const connection = this.getConnection();
|
|
3157
|
-
return await this.runConnectionRequest(() => connection.agent.request(methods.agent.session.setConfigOption, {
|
|
3211
|
+
return normalizeConfigOptionAcknowledgement(await this.runConnectionRequest(() => connection.agent.request(methods.agent.session.setConfigOption, {
|
|
3158
3212
|
sessionId,
|
|
3159
3213
|
configId,
|
|
3160
3214
|
value: modelId
|
|
3161
|
-
}), authority, (error) => this.throwSessionModelError("session/set_config_option", modelId, error));
|
|
3215
|
+
}), authority, (error) => this.throwSessionModelError("session/set_config_option", modelId, error)));
|
|
3162
3216
|
}
|
|
3163
3217
|
async setSessionModelThroughLegacyMethod(sessionId, modelId, authority) {
|
|
3164
3218
|
const connection = this.getConnection();
|
|
@@ -3925,6 +3979,7 @@ function removeModelConfigOptions(state) {
|
|
|
3925
3979
|
state.config_options = state.config_options.filter((option) => option.category !== "model" && option.id !== "model");
|
|
3926
3980
|
}
|
|
3927
3981
|
function applyConfigOptionsModelState(state, configOptions) {
|
|
3982
|
+
if (!Array.isArray(configOptions)) return;
|
|
3928
3983
|
const previousConfigModels = modelStateFromConfigOptions(state.config_options);
|
|
3929
3984
|
const preservesLegacyControl = state.model_control === "legacy_set_model" || state.model_control === void 0 && previousConfigModels === void 0 && legacyModelState(state) !== void 0;
|
|
3930
3985
|
state.config_options = structuredClone(configOptions);
|
|
@@ -3934,14 +3989,9 @@ function applyConfigOptionsModelState(state, configOptions) {
|
|
|
3934
3989
|
else clearAdvertisedModelState(state);
|
|
3935
3990
|
}
|
|
3936
3991
|
//#endregion
|
|
3937
|
-
//#region src/session/conversation-
|
|
3938
|
-
|
|
3939
|
-
|
|
3940
|
-
const MAX_RUNTIME_THINKING_CHARS = 4e3;
|
|
3941
|
-
const MAX_RUNTIME_TOOL_IO_CHARS = 4e3;
|
|
3942
|
-
const MAX_RUNTIME_REQUEST_TOKEN_USAGE = 100;
|
|
3943
|
-
function isoNow() {
|
|
3944
|
-
return (/* @__PURE__ */ new Date()).toISOString();
|
|
3992
|
+
//#region src/session/conversation-reducer.ts
|
|
3993
|
+
function resolveUserMessageId(value) {
|
|
3994
|
+
return typeof value === "string" ? value : value();
|
|
3945
3995
|
}
|
|
3946
3996
|
function deepClone(value) {
|
|
3947
3997
|
try {
|
|
@@ -4012,9 +4062,6 @@ function resourceToUserContent(content) {
|
|
|
4012
4062
|
content: content.resource.uri
|
|
4013
4063
|
} };
|
|
4014
4064
|
}
|
|
4015
|
-
function nextUserMessageId() {
|
|
4016
|
-
return randomUUID();
|
|
4017
|
-
}
|
|
4018
4065
|
function isUserMessage(message) {
|
|
4019
4066
|
return typeof message === "object" && message !== null && hasOwn(message, "User");
|
|
4020
4067
|
}
|
|
@@ -4046,7 +4093,7 @@ function ensureAgentMessage(conversation) {
|
|
|
4046
4093
|
function appendAgentText(agent, text) {
|
|
4047
4094
|
const last = agent.content.at(-1);
|
|
4048
4095
|
if (last && isAgentTextContent(last)) {
|
|
4049
|
-
last.Text =
|
|
4096
|
+
last.Text = `${last.Text}${text}`;
|
|
4050
4097
|
return;
|
|
4051
4098
|
}
|
|
4052
4099
|
const next = { Text: text };
|
|
@@ -4055,7 +4102,7 @@ function appendAgentText(agent, text) {
|
|
|
4055
4102
|
function appendAgentThinking(agent, text) {
|
|
4056
4103
|
const last = agent.content.at(-1);
|
|
4057
4104
|
if (last && isAgentThinkingContent(last)) {
|
|
4058
|
-
last.Thinking.text =
|
|
4105
|
+
last.Thinking.text = `${last.Thinking.text}${text}`;
|
|
4059
4106
|
return;
|
|
4060
4107
|
}
|
|
4061
4108
|
const next = { Thinking: {
|
|
@@ -4064,13 +4111,6 @@ function appendAgentThinking(agent, text) {
|
|
|
4064
4111
|
} };
|
|
4065
4112
|
agent.content.push(next);
|
|
4066
4113
|
}
|
|
4067
|
-
function trimRuntimeText(value, maxChars) {
|
|
4068
|
-
if (value.length <= maxChars) return value;
|
|
4069
|
-
let end = Math.max(0, maxChars - 3);
|
|
4070
|
-
const last = value.charCodeAt(end - 1);
|
|
4071
|
-
if (last >= 55296 && last <= 56319) end -= 1;
|
|
4072
|
-
return `${value.slice(0, end)}...`;
|
|
4073
|
-
}
|
|
4074
4114
|
function statusIndicatesComplete(status) {
|
|
4075
4115
|
if (typeof status !== "string") return false;
|
|
4076
4116
|
const normalized = status.toLowerCase();
|
|
@@ -4082,18 +4122,18 @@ function statusIndicatesError(status) {
|
|
|
4082
4122
|
return normalized.includes("fail") || normalized.includes("error");
|
|
4083
4123
|
}
|
|
4084
4124
|
function toToolResultContent(value) {
|
|
4085
|
-
if (typeof value === "string") return { Text:
|
|
4125
|
+
if (typeof value === "string") return { Text: value };
|
|
4086
4126
|
if (value != null) try {
|
|
4087
|
-
return { Text:
|
|
4127
|
+
return { Text: JSON.stringify(value) ?? "[Unserializable value]" };
|
|
4088
4128
|
} catch {
|
|
4089
4129
|
return { Text: "[Unserializable value]" };
|
|
4090
4130
|
}
|
|
4091
4131
|
return { Text: "" };
|
|
4092
4132
|
}
|
|
4093
4133
|
function toRawInput(value) {
|
|
4094
|
-
if (typeof value === "string") return
|
|
4134
|
+
if (typeof value === "string") return value;
|
|
4095
4135
|
try {
|
|
4096
|
-
return
|
|
4136
|
+
return JSON.stringify(value ?? {}) ?? "[Unserializable input]";
|
|
4097
4137
|
} catch {
|
|
4098
4138
|
return value == null ? "" : "[Unserializable input]";
|
|
4099
4139
|
}
|
|
@@ -4138,11 +4178,13 @@ function existingToolResultValues(existing) {
|
|
|
4138
4178
|
};
|
|
4139
4179
|
}
|
|
4140
4180
|
function applyToolCallUpdate(agent, update) {
|
|
4181
|
+
const contentCount = agent.content.length;
|
|
4141
4182
|
const tool = ensureToolUseContent(agent, update.toolCallId);
|
|
4142
4183
|
applyToolIdentityUpdate(tool, update);
|
|
4143
4184
|
applyToolInputUpdate(tool, update);
|
|
4144
4185
|
applyToolStatusUpdate(tool, update);
|
|
4145
4186
|
applyToolResultUpdate(agent, tool, update);
|
|
4187
|
+
return agent.content.length !== contentCount || hasOwn(update, "rawInput") || hasToolResultPatch(update);
|
|
4146
4188
|
}
|
|
4147
4189
|
function applyToolIdentityUpdate(tool, update) {
|
|
4148
4190
|
if (hasOwn(update, "title")) tool.name = normalizeAgentName(update.title) ?? tool.name ?? "tool_call";
|
|
@@ -4245,7 +4287,7 @@ function lastUserMessageId(conversation) {
|
|
|
4245
4287
|
if (message && isUserMessage(message)) return message.User.id;
|
|
4246
4288
|
}
|
|
4247
4289
|
}
|
|
4248
|
-
function
|
|
4290
|
+
function createConversation(timestamp) {
|
|
4249
4291
|
return {
|
|
4250
4292
|
title: null,
|
|
4251
4293
|
messages: [],
|
|
@@ -4255,8 +4297,7 @@ function createSessionConversation(timestamp = isoNow()) {
|
|
|
4255
4297
|
request_token_usage: {}
|
|
4256
4298
|
};
|
|
4257
4299
|
}
|
|
4258
|
-
function
|
|
4259
|
-
if (!conversation) return createSessionConversation();
|
|
4300
|
+
function cloneConversation(conversation) {
|
|
4260
4301
|
return {
|
|
4261
4302
|
title: conversation.title,
|
|
4262
4303
|
messages: deepClone(conversation.messages ?? []),
|
|
@@ -4272,6 +4313,7 @@ function cloneUsageCost(cost) {
|
|
|
4272
4313
|
function cloneSessionAcpxState(state) {
|
|
4273
4314
|
if (!state) return;
|
|
4274
4315
|
return {
|
|
4316
|
+
...state.session_origin ? { session_origin: state.session_origin } : {},
|
|
4275
4317
|
current_mode_id: state.current_mode_id,
|
|
4276
4318
|
desired_mode_id: state.desired_mode_id,
|
|
4277
4319
|
desired_config_options: state.desired_config_options ? { ...state.desired_config_options } : void 0,
|
|
@@ -4297,57 +4339,47 @@ function cloneSessionOptions(options) {
|
|
|
4297
4339
|
function cloneSystemPromptOption(option) {
|
|
4298
4340
|
return typeof option === "string" ? option : { append: option.append };
|
|
4299
4341
|
}
|
|
4300
|
-
function
|
|
4342
|
+
function reducePromptSubmission(conversation, prompt, timestamp, messageId) {
|
|
4301
4343
|
const userContent = (typeof prompt === "string" ? textPrompt(prompt) : prompt).map((content) => contentToUserContent(content)).filter((content) => content !== void 0);
|
|
4302
|
-
if (userContent.length === 0) return;
|
|
4303
|
-
const promptMessageId = messageId ?? nextUserMessageId();
|
|
4344
|
+
if (userContent.length === 0) return { messageIndex: void 0 };
|
|
4304
4345
|
conversation.messages.push({ User: {
|
|
4305
|
-
id:
|
|
4306
|
-
content: userContent
|
|
4307
|
-
if ("Text" in content) return { Text: trimRuntimeText(content.Text, MAX_RUNTIME_AGENT_TEXT_CHARS) };
|
|
4308
|
-
return content;
|
|
4309
|
-
})
|
|
4346
|
+
id: resolveUserMessageId(messageId),
|
|
4347
|
+
content: userContent
|
|
4310
4348
|
} });
|
|
4311
4349
|
updateConversationTimestamp(conversation, timestamp);
|
|
4312
|
-
|
|
4313
|
-
return promptMessageId;
|
|
4350
|
+
return { messageIndex: conversation.messages.length - 1 };
|
|
4314
4351
|
}
|
|
4315
|
-
function
|
|
4352
|
+
function reduceSessionUpdate(conversation, state, notification, timestamp, userMessageId) {
|
|
4316
4353
|
const acpx = ensureAcpxState$1(state);
|
|
4317
|
-
const
|
|
4318
|
-
applySessionUpdate(conversation, acpx, update, userMessageId);
|
|
4354
|
+
const messageIndex = applySessionUpdate(conversation, acpx, notification.update, userMessageId);
|
|
4319
4355
|
updateConversationTimestamp(conversation, timestamp);
|
|
4320
|
-
|
|
4321
|
-
|
|
4356
|
+
return {
|
|
4357
|
+
acpx,
|
|
4358
|
+
messageIndex
|
|
4359
|
+
};
|
|
4322
4360
|
}
|
|
4323
|
-
function
|
|
4361
|
+
function reducePromptResponseUsage(conversation, usage, promptMessageId, timestamp) {
|
|
4324
4362
|
const tokenUsage = sourceToTokenUsage(usage);
|
|
4325
4363
|
if (!tokenUsage) return false;
|
|
4326
4364
|
applyTokenUsage(conversation, tokenUsage, promptMessageId);
|
|
4327
4365
|
updateConversationTimestamp(conversation, timestamp);
|
|
4328
|
-
trimConversationForRuntime(conversation);
|
|
4329
4366
|
return true;
|
|
4330
4367
|
}
|
|
4331
4368
|
function applySessionUpdate(conversation, acpx, update, userMessageId) {
|
|
4332
|
-
|
|
4333
|
-
handler?.(conversation, acpx, update, userMessageId);
|
|
4369
|
+
return (Object.hasOwn(SESSION_UPDATE_HANDLERS, update.sessionUpdate) ? SESSION_UPDATE_HANDLERS[update.sessionUpdate] : void 0)?.(conversation, acpx, update, userMessageId);
|
|
4334
4370
|
}
|
|
4335
4371
|
const SESSION_UPDATE_HANDLERS = {
|
|
4336
4372
|
user_message_chunk: (conversation, _acpx, update, userMessageId) => {
|
|
4337
|
-
if (update.sessionUpdate === "user_message_chunk") appendUserMessageChunk(conversation, update.content, userMessageId);
|
|
4373
|
+
if (update.sessionUpdate === "user_message_chunk") return appendUserMessageChunk(conversation, update.content, userMessageId);
|
|
4338
4374
|
},
|
|
4339
4375
|
agent_message_chunk: (conversation, _acpx, update) => {
|
|
4340
|
-
if (update.sessionUpdate === "agent_message_chunk") appendAgentMessageChunk(conversation, update.content, appendAgentText);
|
|
4376
|
+
if (update.sessionUpdate === "agent_message_chunk") return appendAgentMessageChunk(conversation, update.content, appendAgentText);
|
|
4341
4377
|
},
|
|
4342
4378
|
agent_thought_chunk: (conversation, _acpx, update) => {
|
|
4343
|
-
if (update.sessionUpdate === "agent_thought_chunk") appendAgentMessageChunk(conversation, update.content, appendAgentThinking);
|
|
4344
|
-
},
|
|
4345
|
-
tool_call: (conversation, _acpx, update) => {
|
|
4346
|
-
if (update.sessionUpdate === "tool_call" || update.sessionUpdate === "tool_call_update") applyToolCallUpdate(ensureAgentMessage(conversation), update);
|
|
4347
|
-
},
|
|
4348
|
-
tool_call_update: (conversation, _acpx, update) => {
|
|
4349
|
-
if (update.sessionUpdate === "tool_call" || update.sessionUpdate === "tool_call_update") applyToolCallUpdate(ensureAgentMessage(conversation), update);
|
|
4379
|
+
if (update.sessionUpdate === "agent_thought_chunk") return appendAgentMessageChunk(conversation, update.content, appendAgentThinking);
|
|
4350
4380
|
},
|
|
4381
|
+
tool_call: applyToolUpdate,
|
|
4382
|
+
tool_call_update: applyToolUpdate,
|
|
4351
4383
|
usage_update: (conversation, _acpx, update) => {
|
|
4352
4384
|
if (update.sessionUpdate === "usage_update") applyUsageUpdate(conversation, update);
|
|
4353
4385
|
},
|
|
@@ -4364,17 +4396,24 @@ const SESSION_UPDATE_HANDLERS = {
|
|
|
4364
4396
|
if (update.sessionUpdate === "config_option_update") applyConfigOptionsModelState(acpx, deepClone(update.configOptions));
|
|
4365
4397
|
}
|
|
4366
4398
|
};
|
|
4399
|
+
function applyToolUpdate(conversation, _acpx, update) {
|
|
4400
|
+
if (update.sessionUpdate !== "tool_call" && update.sessionUpdate !== "tool_call_update") return;
|
|
4401
|
+
return applyToolCallUpdate(ensureAgentMessage(conversation), update) ? conversation.messages.length - 1 : void 0;
|
|
4402
|
+
}
|
|
4367
4403
|
function appendUserMessageChunk(conversation, content, messageId) {
|
|
4368
4404
|
const userContent = contentToUserContent(content);
|
|
4369
4405
|
if (!userContent) return;
|
|
4370
4406
|
conversation.messages.push({ User: {
|
|
4371
|
-
id: messageId
|
|
4407
|
+
id: resolveUserMessageId(messageId),
|
|
4372
4408
|
content: [userContent]
|
|
4373
4409
|
} });
|
|
4410
|
+
return conversation.messages.length - 1;
|
|
4374
4411
|
}
|
|
4375
4412
|
function appendAgentMessageChunk(conversation, content, append) {
|
|
4376
4413
|
const text = extractText(content);
|
|
4377
|
-
if (text)
|
|
4414
|
+
if (!text) return;
|
|
4415
|
+
append(ensureAgentMessage(conversation), text);
|
|
4416
|
+
return conversation.messages.length - 1;
|
|
4378
4417
|
}
|
|
4379
4418
|
function applyUsageUpdate(conversation, update) {
|
|
4380
4419
|
const usage = usageToTokenUsage(update);
|
|
@@ -4386,17 +4425,30 @@ function applyUsageUpdate(conversation, update) {
|
|
|
4386
4425
|
function applyTokenUsage(conversation, usage, promptMessageId) {
|
|
4387
4426
|
conversation.cumulative_token_usage = usage;
|
|
4388
4427
|
const userId = promptMessageId ?? lastUserMessageId(conversation);
|
|
4389
|
-
if (userId) conversation.request_token_usage
|
|
4428
|
+
if (userId) Object.defineProperty(conversation.request_token_usage, userId, {
|
|
4429
|
+
value: usage,
|
|
4430
|
+
writable: true,
|
|
4431
|
+
enumerable: true,
|
|
4432
|
+
configurable: true
|
|
4433
|
+
});
|
|
4390
4434
|
}
|
|
4391
4435
|
function applySessionInfoUpdate(conversation, update) {
|
|
4392
4436
|
if (hasOwn(update, "title")) conversation.title = update.title ?? null;
|
|
4393
4437
|
if (hasOwn(update, "updatedAt")) conversation.updated_at = update.updatedAt ?? conversation.updated_at;
|
|
4394
4438
|
}
|
|
4395
|
-
|
|
4396
|
-
|
|
4397
|
-
|
|
4398
|
-
|
|
4399
|
-
|
|
4439
|
+
//#endregion
|
|
4440
|
+
//#region src/session/conversation-retention.ts
|
|
4441
|
+
const MAX_RUNTIME_MESSAGES = 200;
|
|
4442
|
+
const MAX_RUNTIME_AGENT_TEXT_CHARS = 8e3;
|
|
4443
|
+
const MAX_RUNTIME_THINKING_CHARS = 4e3;
|
|
4444
|
+
const MAX_RUNTIME_TOOL_IO_CHARS = 4e3;
|
|
4445
|
+
const MAX_RUNTIME_REQUEST_TOKEN_USAGE = 100;
|
|
4446
|
+
function trimRuntimeText(value, maxChars) {
|
|
4447
|
+
if (value.length <= maxChars) return value;
|
|
4448
|
+
let end = Math.max(0, maxChars - 3);
|
|
4449
|
+
const last = value.charCodeAt(end - 1);
|
|
4450
|
+
if (last >= 55296 && last <= 56319) end -= 1;
|
|
4451
|
+
return `${value.slice(0, end)}...`;
|
|
4400
4452
|
}
|
|
4401
4453
|
function trimConversationForRuntime(conversation) {
|
|
4402
4454
|
if (conversation.messages.length > MAX_RUNTIME_MESSAGES) conversation.messages = conversation.messages.slice(-200);
|
|
@@ -4431,6 +4483,39 @@ function trimRuntimeToolResult(result) {
|
|
|
4431
4483
|
if (typeof result.output === "string") result.output = trimRuntimeText(result.output, MAX_RUNTIME_TOOL_IO_CHARS);
|
|
4432
4484
|
}
|
|
4433
4485
|
//#endregion
|
|
4486
|
+
//#region src/session/conversation-model.ts
|
|
4487
|
+
function isoNow() {
|
|
4488
|
+
return (/* @__PURE__ */ new Date()).toISOString();
|
|
4489
|
+
}
|
|
4490
|
+
function createSessionConversation(timestamp = isoNow()) {
|
|
4491
|
+
return createConversation(timestamp);
|
|
4492
|
+
}
|
|
4493
|
+
function cloneSessionConversation(conversation) {
|
|
4494
|
+
return conversation ? cloneConversation(conversation) : createSessionConversation();
|
|
4495
|
+
}
|
|
4496
|
+
function recordPromptSubmission(conversation, prompt, timestamp = isoNow(), messageId) {
|
|
4497
|
+
let promptMessageId = messageId;
|
|
4498
|
+
if (reducePromptSubmission(conversation, prompt, timestamp, () => promptMessageId ??= randomUUID()).messageIndex === void 0) return;
|
|
4499
|
+
trimConversationForRuntime(conversation);
|
|
4500
|
+
return promptMessageId;
|
|
4501
|
+
}
|
|
4502
|
+
function recordSessionUpdate(conversation, state, notification, timestamp = isoNow(), userMessageId) {
|
|
4503
|
+
const { acpx } = reduceSessionUpdate(conversation, state, notification, timestamp, userMessageId ?? randomUUID);
|
|
4504
|
+
trimConversationForRuntime(conversation);
|
|
4505
|
+
return acpx;
|
|
4506
|
+
}
|
|
4507
|
+
function recordPromptResponseUsage(conversation, usage, promptMessageId, timestamp = isoNow()) {
|
|
4508
|
+
if (!reducePromptResponseUsage(conversation, usage, promptMessageId, timestamp)) return false;
|
|
4509
|
+
trimConversationForRuntime(conversation);
|
|
4510
|
+
return true;
|
|
4511
|
+
}
|
|
4512
|
+
function recordClientOperation(conversation, state, _operation, timestamp = isoNow()) {
|
|
4513
|
+
const acpx = state ?? {};
|
|
4514
|
+
conversation.updated_at = timestamp;
|
|
4515
|
+
trimConversationForRuntime(conversation);
|
|
4516
|
+
return acpx;
|
|
4517
|
+
}
|
|
4518
|
+
//#endregion
|
|
4434
4519
|
//#region src/runtime/engine/lifecycle.ts
|
|
4435
4520
|
function createInitialSessionRecord(params) {
|
|
4436
4521
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -4450,7 +4535,7 @@ function createInitialSessionRecord(params) {
|
|
|
4450
4535
|
closed: false,
|
|
4451
4536
|
closedAt: void 0,
|
|
4452
4537
|
...createSessionConversation(now),
|
|
4453
|
-
acpx: {}
|
|
4538
|
+
acpx: params.sessionOrigin ? { session_origin: params.sessionOrigin } : {}
|
|
4454
4539
|
};
|
|
4455
4540
|
}
|
|
4456
4541
|
function applyLifecycleSnapshotToRecord(record, snapshot) {
|
|
@@ -4477,6 +4562,17 @@ function reconcileAgentSessionId(record, agentSessionId) {
|
|
|
4477
4562
|
function sessionHasAgentMessages(recordOrConversation) {
|
|
4478
4563
|
return recordOrConversation.messages.some((message) => typeof message === "object" && message !== null && "Agent" in message);
|
|
4479
4564
|
}
|
|
4565
|
+
function sessionHasAtMostOneUserMessage(recordOrConversation) {
|
|
4566
|
+
let userMessageCount = 0;
|
|
4567
|
+
for (const message of recordOrConversation.messages) if (typeof message === "object" && message !== null && "User" in message) {
|
|
4568
|
+
userMessageCount += 1;
|
|
4569
|
+
if (userMessageCount > 1) return false;
|
|
4570
|
+
}
|
|
4571
|
+
return true;
|
|
4572
|
+
}
|
|
4573
|
+
function sessionHasUserMessages(recordOrConversation) {
|
|
4574
|
+
return recordOrConversation.messages.some((message) => typeof message === "object" && message !== null && "User" in message);
|
|
4575
|
+
}
|
|
4480
4576
|
function applyConversation(record, conversation) {
|
|
4481
4577
|
record.title = conversation.title;
|
|
4482
4578
|
record.updated_at = conversation.updated_at;
|
|
@@ -4553,19 +4649,27 @@ function storedEnvRecord(value) {
|
|
|
4553
4649
|
const result = {};
|
|
4554
4650
|
for (const [key, raw] of entries) {
|
|
4555
4651
|
if (typeof raw !== "string") continue;
|
|
4556
|
-
result
|
|
4652
|
+
Object.defineProperty(result, key, {
|
|
4653
|
+
value: raw,
|
|
4654
|
+
writable: true,
|
|
4655
|
+
enumerable: true,
|
|
4656
|
+
configurable: true
|
|
4657
|
+
});
|
|
4557
4658
|
}
|
|
4558
4659
|
return Object.keys(result).length > 0 ? result : void 0;
|
|
4559
4660
|
}
|
|
4560
4661
|
function normalizeSystemPromptOption(value) {
|
|
4561
|
-
const prompt =
|
|
4662
|
+
const prompt = nonEmptyPromptText(value);
|
|
4562
4663
|
if (prompt !== void 0) return prompt;
|
|
4563
4664
|
const append = appendedSystemPrompt(value);
|
|
4564
4665
|
return append === void 0 ? void 0 : { append };
|
|
4565
4666
|
}
|
|
4566
4667
|
function appendedSystemPrompt(value) {
|
|
4567
4668
|
if (typeof value !== "object" || value === null || Array.isArray(value)) return;
|
|
4568
|
-
return
|
|
4669
|
+
return nonEmptyPromptText(value.append);
|
|
4670
|
+
}
|
|
4671
|
+
function nonEmptyPromptText(value) {
|
|
4672
|
+
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
4569
4673
|
}
|
|
4570
4674
|
function storedAllowedTools(value) {
|
|
4571
4675
|
return Array.isArray(value) && value.every((item) => typeof item === "string") ? [...value] : void 0;
|
|
@@ -4638,13 +4742,19 @@ async function applyRequestedModelIfAdvertised(params) {
|
|
|
4638
4742
|
});
|
|
4639
4743
|
if (warning) params.onWarning?.(warning);
|
|
4640
4744
|
if (!params.models) return { applied: false };
|
|
4641
|
-
|
|
4745
|
+
const resolvedModelId = resolveRequestedModelId({
|
|
4746
|
+
...params,
|
|
4747
|
+
requestedModel
|
|
4748
|
+
});
|
|
4749
|
+
if (params.models.currentModelId === resolvedModelId) return {
|
|
4642
4750
|
applied: true,
|
|
4643
|
-
modelId: requestedModel
|
|
4751
|
+
modelId: requestedModel,
|
|
4752
|
+
resolvedModelId
|
|
4644
4753
|
};
|
|
4645
4754
|
return {
|
|
4646
4755
|
applied: true,
|
|
4647
4756
|
modelId: requestedModel,
|
|
4757
|
+
resolvedModelId,
|
|
4648
4758
|
response: await withTimeout(params.client.setSessionModel(params.sessionId, requestedModel, params.models, params.authority), params.timeoutMs)
|
|
4649
4759
|
};
|
|
4650
4760
|
}
|
|
@@ -4657,17 +4767,18 @@ function applyConfigOptionsToState(state, configOptions) {
|
|
|
4657
4767
|
}
|
|
4658
4768
|
function applyConfigOptionsToRecord(record, result) {
|
|
4659
4769
|
const configOptions = result?.configOptions;
|
|
4660
|
-
if (!configOptions) return;
|
|
4770
|
+
if (!Array.isArray(configOptions)) return;
|
|
4661
4771
|
record.acpx = applyConfigOptionsToState(record.acpx, configOptions);
|
|
4662
4772
|
}
|
|
4663
4773
|
function applyInitialModelSelection(record, originalModels, modelApplication) {
|
|
4664
4774
|
applyConfigOptionsToRecord(record, modelApplication.response);
|
|
4665
|
-
|
|
4666
|
-
|
|
4775
|
+
const configOptions = modelApplication.response?.configOptions;
|
|
4776
|
+
syncAdvertisedModelState(record, Array.isArray(configOptions) ? modelStateFromConfigOptions(configOptions) : originalModels);
|
|
4777
|
+
if (modelApplication.applied) record.acpx = applyModelSelection(record.acpx, modelApplication.modelId, modelApplication.response, modelApplication.resolvedModelId);
|
|
4667
4778
|
}
|
|
4668
4779
|
function applyAcceptedConfigOptions(state, response, selection) {
|
|
4669
4780
|
const next = cloneSessionAcpxState(state) ?? {};
|
|
4670
|
-
if (response?.configOptions
|
|
4781
|
+
if (!Array.isArray(response?.configOptions)) {
|
|
4671
4782
|
const option = next.config_options?.find((entry) => entry.id === selection.configId);
|
|
4672
4783
|
if (option) option.currentValue = selection.value;
|
|
4673
4784
|
return next;
|
|
@@ -4683,22 +4794,25 @@ function reconcileDesiredConfigOptions(state, configOptions) {
|
|
|
4683
4794
|
if (desiredEntries.length > 0) state.desired_config_options = Object.fromEntries(desiredEntries);
|
|
4684
4795
|
else delete state.desired_config_options;
|
|
4685
4796
|
}
|
|
4686
|
-
function applyModelSelection(state, modelId, response) {
|
|
4797
|
+
function applyModelSelection(state, modelId, response, resolvedModelId = modelId) {
|
|
4687
4798
|
const modelConfigId = advertisedModelState(state)?.configId;
|
|
4688
4799
|
const next = applyAcceptedConfigOptions(state, response, {
|
|
4689
4800
|
configId: modelConfigId,
|
|
4690
|
-
value:
|
|
4801
|
+
value: resolvedModelId
|
|
4691
4802
|
});
|
|
4692
4803
|
next.session_options = {
|
|
4693
4804
|
...next.session_options,
|
|
4694
4805
|
model: modelId
|
|
4695
4806
|
};
|
|
4696
|
-
next.current_model_id = currentModelIdFromSetModelResponse(response,
|
|
4807
|
+
next.current_model_id = currentModelIdFromSetModelResponse(response, resolvedModelId);
|
|
4697
4808
|
clearDesiredConfigOption(next, modelConfigId ?? advertisedModelState(next)?.configId);
|
|
4698
4809
|
return next;
|
|
4699
4810
|
}
|
|
4700
|
-
function
|
|
4701
|
-
|
|
4811
|
+
function isModelConfigSelection(configId, response, modelConfigId) {
|
|
4812
|
+
return configId === modelConfigId || configId === modelStateFromConfigOptions(response?.configOptions)?.configId;
|
|
4813
|
+
}
|
|
4814
|
+
function applyConfigOptionSelection(state, configId, value, response, modelConfigId = advertisedModelState(state)?.configId, resolvedValue = value) {
|
|
4815
|
+
if (isModelConfigSelection(configId, response, modelConfigId)) return applyModelSelection(state, value, response, resolvedValue);
|
|
4702
4816
|
const next = cloneSessionAcpxState(state) ?? {};
|
|
4703
4817
|
next.desired_config_options = {
|
|
4704
4818
|
...next.desired_config_options,
|
|
@@ -4806,9 +4920,14 @@ async function replayDesiredModel(params) {
|
|
|
4806
4920
|
context: "replay"
|
|
4807
4921
|
}), params.suppressWarnings);
|
|
4808
4922
|
if (!params.models) return { replayed: false };
|
|
4923
|
+
const resolvedModelId = resolveRequestedModelId({
|
|
4924
|
+
requestedModel: params.desiredModelId,
|
|
4925
|
+
models: params.models,
|
|
4926
|
+
agentCommand: params.record.agentCommand
|
|
4927
|
+
});
|
|
4809
4928
|
const response = await withTimeout(params.client.setSessionModel(params.sessionId, params.desiredModelId, params.models, params.replay.authority), params.timeoutMs);
|
|
4810
4929
|
params.replay.acknowledged = true;
|
|
4811
|
-
params.record.acpx = applyModelSelection(params.record.acpx, params.desiredModelId, response);
|
|
4930
|
+
params.record.acpx = applyModelSelection(params.record.acpx, params.desiredModelId, response, resolvedModelId);
|
|
4812
4931
|
const models = advertisedModelState(params.record.acpx);
|
|
4813
4932
|
if (params.verbose) process.stderr.write(`[acpx] replayed desired model ${params.desiredModelId} on ACP session ${params.sessionId} (previous ${params.previousSessionId})\n`);
|
|
4814
4933
|
return {
|
|
@@ -4834,9 +4953,16 @@ async function replayDesiredConfigOptions(params) {
|
|
|
4834
4953
|
for (const [configId, value] of Object.entries(params.desiredConfigOptions)) {
|
|
4835
4954
|
if (configId === replacingKey || acceptedConfigOptions && !acceptsSavedConfigValue(acceptedConfigOptions.find((option) => option.id === configId), value)) continue;
|
|
4836
4955
|
try {
|
|
4837
|
-
const
|
|
4956
|
+
const models = advertisedModelState(params.record.acpx);
|
|
4957
|
+
const { modelConfigId, resolvedValue } = resolveRequestedConfigOption({
|
|
4958
|
+
configId,
|
|
4959
|
+
value,
|
|
4960
|
+
models,
|
|
4961
|
+
agentCommand: params.record.agentCommand
|
|
4962
|
+
});
|
|
4963
|
+
const response = await withTimeout(params.client.setSessionConfigOption(params.sessionId, configId, value, models, params.replay.authority), params.timeoutMs);
|
|
4838
4964
|
params.replay.acknowledged = true;
|
|
4839
|
-
params.record.acpx = applyConfigOptionSelection(params.record.acpx, configId, value, response);
|
|
4965
|
+
params.record.acpx = applyConfigOptionSelection(params.record.acpx, configId, value, response, modelConfigId, resolvedValue);
|
|
4840
4966
|
acceptedConfigOptions = params.record.acpx.config_options;
|
|
4841
4967
|
result = {
|
|
4842
4968
|
replayed: true,
|
|
@@ -4885,7 +5011,8 @@ async function connectAndLoadSession(options) {
|
|
|
4885
5011
|
reusingLoadedSession,
|
|
4886
5012
|
sameSessionOnly,
|
|
4887
5013
|
timeoutMs: options.timeoutMs,
|
|
4888
|
-
authority: options.authority
|
|
5014
|
+
authority: options.authority,
|
|
5015
|
+
promptRecorded: options.promptRecorded
|
|
4889
5016
|
});
|
|
4890
5017
|
const { resumed, loadError, sessionId, createdFreshSession, pendingAgentSessionId, sessionModels } = loadState;
|
|
4891
5018
|
applyReconnectedModelState(record, sessionModels, loadState.configOptionsPresent, loadState.legacyModelMetadataPresent, createdFreshSession);
|
|
@@ -5084,19 +5211,32 @@ function rethrowCancelledLoad(error, authority) {
|
|
|
5084
5211
|
}
|
|
5085
5212
|
async function recoverRuntimeSessionLoadFailure(params, error) {
|
|
5086
5213
|
const loadError = formatErrorMessage(error);
|
|
5087
|
-
if (params
|
|
5088
|
-
|
|
5089
|
-
|
|
5090
|
-
|
|
5091
|
-
|
|
5092
|
-
|
|
5214
|
+
if (!canRecoverLoadWithFreshSession(params, error)) {
|
|
5215
|
+
if (params.sameSessionOnly) throw makeSessionResumeRequiredError({
|
|
5216
|
+
record: params.record,
|
|
5217
|
+
reason: loadError,
|
|
5218
|
+
cause: error
|
|
5219
|
+
});
|
|
5220
|
+
throw error;
|
|
5221
|
+
}
|
|
5093
5222
|
return {
|
|
5094
5223
|
...await createFreshRuntimeSession(params.client, params.record, params.timeoutMs, params.authority),
|
|
5095
5224
|
loadError
|
|
5096
5225
|
};
|
|
5097
5226
|
}
|
|
5227
|
+
function canRecoverLoadWithFreshSession(params, error) {
|
|
5228
|
+
if (!params.sameSessionOnly) return shouldFallbackToNewSession(error, params.record);
|
|
5229
|
+
return isUnpromptedNewSession(params.record, params.promptRecorded) && extractAcpError(error)?.code === -32603;
|
|
5230
|
+
}
|
|
5231
|
+
function isUnpromptedNewSession(record, promptRecorded = false) {
|
|
5232
|
+
return record.acpx?.session_origin === "new" && !record.importedFrom && !sessionHasAgentMessages(record) && !record.messages.includes("Resume") && (promptRecorded ? sessionHasAtMostOneUserMessage(record) : !sessionHasUserMessages(record));
|
|
5233
|
+
}
|
|
5098
5234
|
async function createFreshRuntimeSession(client, record, timeoutMs, authority) {
|
|
5099
5235
|
const createdSession = await withTimeout(client.createSession(record.cwd, authority), timeoutMs);
|
|
5236
|
+
record.acpx = {
|
|
5237
|
+
...record.acpx,
|
|
5238
|
+
session_origin: "new"
|
|
5239
|
+
};
|
|
5100
5240
|
applyConfigOptionsToRecord(record, createdSession);
|
|
5101
5241
|
return {
|
|
5102
5242
|
sessionId: createdSession.sessionId,
|
|
@@ -5289,8 +5429,13 @@ async function runSessionSetModelDirect(options) {
|
|
|
5289
5429
|
replacingConfigOption: { key: "model" }
|
|
5290
5430
|
}, async ({ client, sessionId, record }) => {
|
|
5291
5431
|
const models = advertisedModelState(record.acpx);
|
|
5432
|
+
const resolvedModelId = resolveRequestedModelId({
|
|
5433
|
+
requestedModel: options.modelId,
|
|
5434
|
+
models,
|
|
5435
|
+
agentCommand: record.agentCommand
|
|
5436
|
+
});
|
|
5292
5437
|
const response = await withTimeout(client.setSessionModel(sessionId, options.modelId, models), options.timeoutMs);
|
|
5293
|
-
record.acpx = applyModelSelection(record.acpx, options.modelId, response);
|
|
5438
|
+
record.acpx = applyModelSelection(record.acpx, options.modelId, response, resolvedModelId);
|
|
5294
5439
|
return response;
|
|
5295
5440
|
}));
|
|
5296
5441
|
return {
|
|
@@ -5304,8 +5449,14 @@ async function runSessionSetConfigOptionDirect(options) {
|
|
|
5304
5449
|
replacingConfigOption: { key: options.configId }
|
|
5305
5450
|
}, async ({ client, sessionId, record }) => {
|
|
5306
5451
|
const models = advertisedModelState(record.acpx);
|
|
5452
|
+
const { modelConfigId, resolvedValue } = resolveRequestedConfigOption({
|
|
5453
|
+
configId: options.configId,
|
|
5454
|
+
value: options.value,
|
|
5455
|
+
models,
|
|
5456
|
+
agentCommand: record.agentCommand
|
|
5457
|
+
});
|
|
5307
5458
|
const response = await withTimeout(client.setSessionConfigOption(sessionId, options.configId, options.value, models), options.timeoutMs);
|
|
5308
|
-
record.acpx = applyConfigOptionSelection(record.acpx, options.configId, options.value, response,
|
|
5459
|
+
record.acpx = applyConfigOptionSelection(record.acpx, options.configId, options.value, response, modelConfigId, resolvedValue);
|
|
5309
5460
|
return response;
|
|
5310
5461
|
}));
|
|
5311
5462
|
return {
|
|
@@ -5451,7 +5602,11 @@ async function setSessionModelOnOwner(options) {
|
|
|
5451
5602
|
if (!submittedToOwner) return;
|
|
5452
5603
|
const record = await resolveSessionRecord(options.sessionId);
|
|
5453
5604
|
if (!submittedToOwner.persistsControlState) {
|
|
5454
|
-
record.acpx = applyModelSelection(record.acpx, options.modelId, submittedToOwner.value.response
|
|
5605
|
+
record.acpx = applyModelSelection(record.acpx, options.modelId, submittedToOwner.value.response, resolveRequestedModelId({
|
|
5606
|
+
requestedModel: options.modelId,
|
|
5607
|
+
models: advertisedModelState(record.acpx),
|
|
5608
|
+
agentCommand: record.agentCommand
|
|
5609
|
+
}));
|
|
5455
5610
|
await writeSessionRecord(record);
|
|
5456
5611
|
}
|
|
5457
5612
|
return {
|
|
@@ -5482,7 +5637,14 @@ async function setSessionConfigOptionOnOwner(options) {
|
|
|
5482
5637
|
if (!ownerResponse) return;
|
|
5483
5638
|
const record = await resolveSessionRecord(options.sessionId);
|
|
5484
5639
|
if (!ownerResponse.persistsControlState) {
|
|
5485
|
-
|
|
5640
|
+
const models = advertisedModelState(record.acpx);
|
|
5641
|
+
const { modelConfigId, resolvedValue } = resolveRequestedConfigOption({
|
|
5642
|
+
configId: options.configId,
|
|
5643
|
+
value: options.value,
|
|
5644
|
+
models,
|
|
5645
|
+
agentCommand: record.agentCommand
|
|
5646
|
+
});
|
|
5647
|
+
record.acpx = applyConfigOptionSelection(record.acpx, options.configId, options.value, ownerResponse.value, modelConfigId, resolvedValue);
|
|
5486
5648
|
await writeSessionRecord(record);
|
|
5487
5649
|
}
|
|
5488
5650
|
return {
|
|
@@ -5600,7 +5762,7 @@ async function closeSession(sessionId) {
|
|
|
5600
5762
|
}
|
|
5601
5763
|
//#endregion
|
|
5602
5764
|
//#region src/session/execution/session-management.ts
|
|
5603
|
-
async function createSessionRecordWithClient(client, options) {
|
|
5765
|
+
async function createSessionRecordWithClient(client, options, resumedRecordId) {
|
|
5604
5766
|
const cwd = absolutePath(options.cwd);
|
|
5605
5767
|
await withTimeout(client.start({ signal: options.signal }), options.timeoutMs);
|
|
5606
5768
|
assertControlAuthority({ signal: options.signal });
|
|
@@ -5610,9 +5772,10 @@ async function createSessionRecordWithClient(client, options) {
|
|
|
5610
5772
|
const lifecycle = client.getAgentLifecycleSnapshot();
|
|
5611
5773
|
const record = {
|
|
5612
5774
|
...createInitialSessionRecord({
|
|
5613
|
-
recordId:
|
|
5775
|
+
recordId: resumedRecordId ?? randomUUID(),
|
|
5614
5776
|
sessionId,
|
|
5615
5777
|
agentSessionId,
|
|
5778
|
+
sessionOrigin: options.resumeSessionId ? "resume" : "new",
|
|
5616
5779
|
agentCommand: options.agentCommand,
|
|
5617
5780
|
agentArgv: options.agentArgv,
|
|
5618
5781
|
cwd,
|
|
@@ -5681,11 +5844,17 @@ async function resumeSessionRecordWithClient(client, options, cwd) {
|
|
|
5681
5844
|
}
|
|
5682
5845
|
async function createSessionWithClient(options) {
|
|
5683
5846
|
assertControlAuthority({ signal: options.signal });
|
|
5847
|
+
let resumedRecordId;
|
|
5684
5848
|
if (options.resumeSessionId) {
|
|
5685
5849
|
const resumedRecord = await readSessionRecord(options.resumeSessionId);
|
|
5686
5850
|
assertControlAuthority({ signal: options.signal });
|
|
5687
|
-
if (resumedRecord &&
|
|
5688
|
-
|
|
5851
|
+
if (resumedRecord && resumedRecord.agentCommand === options.agentCommand) {
|
|
5852
|
+
resumedRecordId = resumedRecord.acpxRecordId;
|
|
5853
|
+
if (!resumedRecord.closed) await closeSession(resumedRecord.acpxRecordId);
|
|
5854
|
+
options = {
|
|
5855
|
+
...options,
|
|
5856
|
+
resumeSessionId: resumedRecord.acpSessionId
|
|
5857
|
+
};
|
|
5689
5858
|
assertControlAuthority({ signal: options.signal });
|
|
5690
5859
|
}
|
|
5691
5860
|
}
|
|
@@ -5708,7 +5877,7 @@ async function createSessionWithClient(options) {
|
|
|
5708
5877
|
try {
|
|
5709
5878
|
const create = async () => {
|
|
5710
5879
|
assertControlAuthority({ signal: options.signal });
|
|
5711
|
-
const record = await createSessionRecordWithClient(client, options);
|
|
5880
|
+
const record = await createSessionRecordWithClient(client, options, resumedRecordId);
|
|
5712
5881
|
assertControlAuthority({ signal: options.signal });
|
|
5713
5882
|
return record;
|
|
5714
5883
|
};
|
|
@@ -6190,14 +6359,25 @@ function createOwnedSessionControls(options) {
|
|
|
6190
6359
|
},
|
|
6191
6360
|
setSessionModel: async (modelId, deadline) => {
|
|
6192
6361
|
const models = advertisedModelState(options.record.acpx);
|
|
6362
|
+
const resolvedModelId = resolveRequestedModelId({
|
|
6363
|
+
requestedModel: modelId,
|
|
6364
|
+
models,
|
|
6365
|
+
agentCommand: options.record.agentCommand
|
|
6366
|
+
});
|
|
6193
6367
|
return await acceptControl(options, (authority) => options.client.setSessionModel(options.sessionId(), modelId, models, authority), (response) => {
|
|
6194
|
-
options.record.acpx = applyModelSelection(options.record.acpx, modelId, response);
|
|
6368
|
+
options.record.acpx = applyModelSelection(options.record.acpx, modelId, response, resolvedModelId);
|
|
6195
6369
|
}, deadline);
|
|
6196
6370
|
},
|
|
6197
6371
|
setSessionConfigOption: async (configId, value, deadline) => {
|
|
6198
6372
|
const models = advertisedModelState(options.record.acpx);
|
|
6373
|
+
const { modelConfigId, resolvedValue } = resolveRequestedConfigOption({
|
|
6374
|
+
configId,
|
|
6375
|
+
value,
|
|
6376
|
+
models,
|
|
6377
|
+
agentCommand: options.record.agentCommand
|
|
6378
|
+
});
|
|
6199
6379
|
return await acceptControl(options, (authority) => options.client.setSessionConfigOption(options.sessionId(), configId, value, models, authority), (response) => {
|
|
6200
|
-
options.record.acpx = applyConfigOptionSelection(options.record.acpx, configId, value, response,
|
|
6380
|
+
options.record.acpx = applyConfigOptionSelection(options.record.acpx, configId, value, response, modelConfigId, resolvedValue);
|
|
6201
6381
|
}, deadline);
|
|
6202
6382
|
}
|
|
6203
6383
|
};
|
|
@@ -6693,7 +6873,7 @@ async function applyPromptModelIfAdvertised(params) {
|
|
|
6693
6873
|
authority: { signal: params.signal },
|
|
6694
6874
|
onWarning: params.suppressWarnings ? void 0 : (message) => process.stderr.write(`[acpx] warning: ${message}\n`)
|
|
6695
6875
|
});
|
|
6696
|
-
if (result.applied) params.record.acpx = applyModelSelection(params.record.acpx, requestedModel, result.response);
|
|
6876
|
+
if (result.applied) params.record.acpx = applyModelSelection(params.record.acpx, requestedModel, result.response, result.resolvedModelId);
|
|
6697
6877
|
}
|
|
6698
6878
|
function jsonRpcIdKey(message) {
|
|
6699
6879
|
if (!("id" in message)) return;
|
|
@@ -7145,6 +7325,7 @@ async function runOwnedSessionPrompt(options) {
|
|
|
7145
7325
|
timeoutMs: options.timeoutMs,
|
|
7146
7326
|
verbose: options.verbose,
|
|
7147
7327
|
suppressWarnings: options.suppressSdkConsoleErrors,
|
|
7328
|
+
promptRecorded: true,
|
|
7148
7329
|
activeController,
|
|
7149
7330
|
authority: { signal: options.ownedSignal },
|
|
7150
7331
|
onClientAvailable: (controller) => {
|
|
@@ -7245,8 +7426,10 @@ async function runOwnedSessionPrompt(options) {
|
|
|
7245
7426
|
record.lastUsedAt = now;
|
|
7246
7427
|
record.closed = false;
|
|
7247
7428
|
record.closedAt = void 0;
|
|
7248
|
-
|
|
7249
|
-
|
|
7429
|
+
if (client.initializeResult) {
|
|
7430
|
+
record.protocolVersion = client.initializeResult.protocolVersion;
|
|
7431
|
+
record.agentCapabilities = client.initializeResult.agentCapabilities;
|
|
7432
|
+
}
|
|
7250
7433
|
applyConversation(record, conversation);
|
|
7251
7434
|
applyLifecycleSnapshotToRecord(record, client.getAgentLifecycleSnapshot());
|
|
7252
7435
|
stopTotalTimer();
|
|
@@ -7256,15 +7439,20 @@ async function runOwnedSessionPrompt(options) {
|
|
|
7256
7439
|
options.ownedSignal?.throwIfAborted();
|
|
7257
7440
|
const { sessionId: activeSessionId, resumed, loadError } = await connectForPrompt();
|
|
7258
7441
|
options.ownedSignal?.throwIfAborted();
|
|
7259
|
-
|
|
7260
|
-
|
|
7261
|
-
|
|
7262
|
-
|
|
7263
|
-
|
|
7264
|
-
|
|
7265
|
-
|
|
7266
|
-
|
|
7267
|
-
|
|
7442
|
+
try {
|
|
7443
|
+
await applyPromptModelIfAdvertised({
|
|
7444
|
+
client,
|
|
7445
|
+
sessionId: activeSessionId,
|
|
7446
|
+
requestedModel: options.sessionOptions?.model,
|
|
7447
|
+
record,
|
|
7448
|
+
timeoutMs: options.timeoutMs,
|
|
7449
|
+
suppressWarnings: options.suppressSdkConsoleErrors,
|
|
7450
|
+
signal: options.ownedSignal
|
|
7451
|
+
});
|
|
7452
|
+
} catch (error) {
|
|
7453
|
+
if (error instanceof TimeoutError) closeClientOnExit = true;
|
|
7454
|
+
throw error;
|
|
7455
|
+
}
|
|
7268
7456
|
options.ownedSignal?.throwIfAborted();
|
|
7269
7457
|
output.setContext({ sessionId: record.acpxRecordId });
|
|
7270
7458
|
await liveCheckpoint.checkpoint();
|
|
@@ -7357,6 +7545,7 @@ async function runOnce(options, control) {
|
|
|
7357
7545
|
let promptTurnActive = false;
|
|
7358
7546
|
let promptTurnHadSideEffects = false;
|
|
7359
7547
|
let controlState = {};
|
|
7548
|
+
let sawOwnedModelConfig = false;
|
|
7360
7549
|
const acpErrors = new AcpErrorTracker();
|
|
7361
7550
|
const client = new AcpClient({
|
|
7362
7551
|
agentCommand: options.agentCommand,
|
|
@@ -7377,7 +7566,10 @@ async function runOnce(options, control) {
|
|
|
7377
7566
|
acpErrors.observe(output, direction, message);
|
|
7378
7567
|
},
|
|
7379
7568
|
onSessionUpdate: (notification) => {
|
|
7380
|
-
if (notification.update.sessionUpdate === "config_option_update"
|
|
7569
|
+
if (notification.update.sessionUpdate === "config_option_update" && client.hasReusableSession(notification.sessionId)) {
|
|
7570
|
+
controlState = applyConfigOptionsToState(controlState, notification.update.configOptions);
|
|
7571
|
+
sawOwnedModelConfig ||= controlState.model_control === "config_option";
|
|
7572
|
+
}
|
|
7381
7573
|
if (promptTurnActive) promptTurnHadSideEffects = true;
|
|
7382
7574
|
options.onSessionUpdate?.(notification);
|
|
7383
7575
|
},
|
|
@@ -7393,6 +7585,11 @@ async function runOnce(options, control) {
|
|
|
7393
7585
|
});
|
|
7394
7586
|
const permissionStatsBefore = client.getPermissionStats();
|
|
7395
7587
|
const closeOwnedClient = ownDirectClient(client, control?.signal);
|
|
7588
|
+
const initializeControlState = (createdSession) => {
|
|
7589
|
+
const configOptions = controlState.config_options ?? createdSession.configOptions ?? [];
|
|
7590
|
+
if (createdSession.models && !sawOwnedModelConfig) applyAdvertisedModelState(controlState, createdSession.models);
|
|
7591
|
+
controlState = applyConfigOptionsToState(controlState, configOptions);
|
|
7592
|
+
};
|
|
7396
7593
|
const runExecPromptAttempt = async (sessionId) => {
|
|
7397
7594
|
assertControlAuthority(authority);
|
|
7398
7595
|
acpErrors.reset();
|
|
@@ -7425,23 +7622,28 @@ async function runOnce(options, control) {
|
|
|
7425
7622
|
});
|
|
7426
7623
|
assertControlAuthority(authority);
|
|
7427
7624
|
const sessionId = createdSession.sessionId;
|
|
7428
|
-
|
|
7429
|
-
controlState = applyConfigOptionsToState(controlState, createdSession.configOptions ?? []);
|
|
7625
|
+
initializeControlState(createdSession);
|
|
7430
7626
|
const modelApplication = await applyRequestedModelIfAdvertised({
|
|
7431
7627
|
client,
|
|
7432
7628
|
sessionId,
|
|
7433
7629
|
requestedModel: options.sessionOptions?.model,
|
|
7434
|
-
models:
|
|
7630
|
+
models: advertisedModelState(controlState),
|
|
7435
7631
|
agentCommand: options.agentCommand,
|
|
7436
7632
|
timeoutMs: options.timeoutMs,
|
|
7437
7633
|
authority,
|
|
7438
7634
|
onWarning: options.suppressSdkConsoleErrors ? void 0 : (message) => process.stderr.write(`[acpx] warning: ${message}\n`)
|
|
7439
7635
|
});
|
|
7440
|
-
if (modelApplication.applied) controlState = applyModelSelection(controlState, modelApplication.modelId, modelApplication.response);
|
|
7636
|
+
if (modelApplication.applied) controlState = applyModelSelection(controlState, modelApplication.modelId, modelApplication.response, modelApplication.resolvedModelId);
|
|
7441
7637
|
for (const configOption of options.configOptions ?? []) {
|
|
7442
7638
|
assertControlAuthority(authority);
|
|
7443
|
-
const
|
|
7444
|
-
|
|
7639
|
+
const models = advertisedModelState(controlState);
|
|
7640
|
+
const { modelConfigId, resolvedValue } = resolveRequestedConfigOption({
|
|
7641
|
+
...configOption,
|
|
7642
|
+
models,
|
|
7643
|
+
agentCommand: options.agentCommand
|
|
7644
|
+
});
|
|
7645
|
+
const response = await withTimeout(client.setSessionConfigOption(sessionId, configOption.configId, configOption.value, models, authority), options.timeoutMs);
|
|
7646
|
+
controlState = applyConfigOptionSelection(controlState, configOption.configId, configOption.value, response, modelConfigId, resolvedValue);
|
|
7445
7647
|
}
|
|
7446
7648
|
assertControlAuthority(authority);
|
|
7447
7649
|
output.setContext({ sessionId });
|
|
@@ -7917,6 +8119,6 @@ async function sendSession(options) {
|
|
|
7917
8119
|
}
|
|
7918
8120
|
const queueOwnerRuntimeTestInternals = { queueOwnerExitIsFatal };
|
|
7919
8121
|
//#endregion
|
|
7920
|
-
export { isRequestedModelUnsupportedError as $, applyInitialModelSelection as A, reconcileAgentSessionId as B, setSessionModeOnOwner as C, connectAndLoadSession as D, withConnectedSession as E, persistSessionOptions as F,
|
|
8122
|
+
export { isRequestedModelUnsupportedError as $, applyInitialModelSelection as A, reconcileAgentSessionId as B, setSessionModeOnOwner as C, connectAndLoadSession as D, withConnectedSession as E, persistSessionOptions as F, recordSessionUpdate as G, createSessionConversation as H, sessionOptionsFromRecord as I, advertisedModelState as J, trimConversationForRuntime as K, applyConversation as L, applyRequestedModelIfAdvertised as M, setDesiredModeId as N, applyConfigOptionSelection as O, normalizeSessionOptionShape as P, RequestedModelUnsupportedError as Q, applyLifecycleSnapshotToRecord as R, setSessionMode as S, setSessionModelOnOwner as T, recordClientOperation as U, cloneSessionConversation as V, recordPromptSubmission as W, REQUESTED_MODEL_UNSUPPORTED_ERROR_CODE as X, AcpClient as Y, REQUESTED_MODEL_UNSUPPORTED_REASONS as Z, cancelSessionPrompt as _, runQueuedTask as a, normalizeQueueOwnerTtlMs as at, setSessionConfigOption as b, LiveSessionCheckpoint as c, listSessionEvents as ct, flushPerfMetricsCapture as d, TimeoutError as dt, resolveRequestedConfigOption as et, installPerfMetricsCapture as f, assertControlAuthority as ft, listAgentSessions as g, ensureSession as h, runOnce as i, DEFAULT_QUEUE_OWNER_TTL_MS as it, applyModelSelection as j, applyConfigOptionsToRecord as k, runPromptTurn as l, isLegacyZedCodexAcpInvocation as lt, createSessionWithClient as m, withTimeout as mt, runSessionQueueOwner as n, getAcpxVersion as nt, sendSessionDirect as o, acquireSessionImport as ot, createSession as p, withInterrupt as pt, cloneSessionAcpxState as q, sendSession as r, permissionModeSatisfies as rt, DISCARD_OUTPUT_FORMATTER as s, acquireSessionScope as st, queueOwnerRuntimeTestInternals as t, resolveRequestedModelId as tt, buildQueueOwnerArgOverride as u, InterruptedError as ut, closeSession as v, setSessionModel as w, setSessionConfigOptionOnOwner as x, sessionControlTestInternals as y, createInitialSessionRecord as z };
|
|
7921
8123
|
|
|
7922
|
-
//# sourceMappingURL=queue-owner-runtime-
|
|
8124
|
+
//# sourceMappingURL=queue-owner-runtime-DoijBCvt.js.map
|