acpx 0.19.3 → 0.19.4

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.
Files changed (40) hide show
  1. package/dist/{agent-registry-DWnqUICY.js → agent-registry-kHdpsK9F.js} +16 -5
  2. package/dist/agent-registry-kHdpsK9F.js.map +1 -0
  3. package/dist/agent-registry.d.ts.map +1 -1
  4. package/dist/agent-registry.js +1 -1
  5. package/dist/{cli-C1uofM8S.js → cli-DCtHeMEi.js} +34 -46
  6. package/dist/cli-DCtHeMEi.js.map +1 -0
  7. package/dist/cli.js +11 -10
  8. package/dist/cli.js.map +1 -1
  9. package/dist/{client-CdG6nVDG.d.ts → client-DqCXdF0Q.d.ts} +3 -16
  10. package/dist/client-DqCXdF0Q.d.ts.map +1 -0
  11. package/dist/{flows-hz_Pfsp-.js → flows--1zpaEh9.js} +34 -14
  12. package/dist/flows--1zpaEh9.js.map +1 -0
  13. package/dist/flows.d.ts +1 -1
  14. package/dist/flows.js +1 -1
  15. package/dist/{invocation-options-DbZzMvKM.js → invocation-options-CvkenzCc.js} +6 -12
  16. package/dist/invocation-options-CvkenzCc.js.map +1 -0
  17. package/dist/{ipc-BW06Pbb8.js → ipc-D7zT86b9.js} +94 -20
  18. package/dist/ipc-D7zT86b9.js.map +1 -0
  19. package/dist/{output-BjeeG-cj.js → output-lylSoEBd.js} +12 -4
  20. package/dist/output-lylSoEBd.js.map +1 -0
  21. package/dist/{queue-owner-runtime-Dhr4gxNE.js → queue-owner-runtime-C0wIYowh.js} +314 -154
  22. package/dist/queue-owner-runtime-C0wIYowh.js.map +1 -0
  23. package/dist/runtime.d.ts +17 -2
  24. package/dist/runtime.d.ts.map +1 -1
  25. package/dist/runtime.js +32 -9
  26. package/dist/runtime.js.map +1 -1
  27. package/dist/{session-watch-CgfkUKLA.js → session-watch-DPOwDRf8.js} +4 -4
  28. package/dist/{session-watch-CgfkUKLA.js.map → session-watch-DPOwDRf8.js.map} +1 -1
  29. package/dist/{watch-BGdqBiNX.js → watch-H7rNOJtv.js} +2 -2
  30. package/dist/{watch-BGdqBiNX.js.map → watch-H7rNOJtv.js.map} +1 -1
  31. package/package.json +9 -8
  32. package/skills/acpx/SKILL.md +6 -1
  33. package/dist/agent-registry-DWnqUICY.js.map +0 -1
  34. package/dist/cli-C1uofM8S.js.map +0 -1
  35. package/dist/client-CdG6nVDG.d.ts.map +0 -1
  36. package/dist/flows-hz_Pfsp-.js.map +0 -1
  37. package/dist/invocation-options-DbZzMvKM.js.map +0 -1
  38. package/dist/ipc-BW06Pbb8.js.map +0 -1
  39. package/dist/output-BjeeG-cj.js.map +0 -1
  40. package/dist/queue-owner-runtime-Dhr4gxNE.js.map +0 -1
@@ -1,5 +1,5 @@
1
- import { $ as resetPerfMetrics, Bt as GeminiAcpStartupTimeoutError, C as textPrompt, Ct as normalizeOutputError, F as normalizeName, Ft as AgentSpawnError, G as SESSION_JOURNAL_SCHEMA, Gt as SessionModeReplayError, Ht as PermissionPromptUnavailableError, It as AgentStartupError, Jt as SessionResumeRequiredError, K as SessionJournalReader, Kt as SessionModelReplayError, L as readSessionRecord, Lt as AuthPolicyError, M as isoNow$1, Nt as AcpxOperationalError, O as absolutePath, Pt as AgentDisconnectedError, Q as measurePerf, R as resolveSessionRecord, Rt as ClaudeAcpSessionCreateTimeoutError, S as promptToDisplayText, St as isRetryablePromptError, T as lockOwnerPid, Tt as isAcpResourceNotFoundError, U as extractAgentSessionId, Ut as QueueConnectionError, Vt as PermissionDeniedError, W as normalizeAgentSessionId, Wt as SessionConfigOptionReplayError, X as getPerfMetricsSnapshot, Y as formatPerfMetric, Yt as UnsupportedPromptContentError, Z as incrementPerfCounter, _ as ProcessDescendants, a as trySetModelOnRunningOwner, at as isSessionUpdateNotification, bt as formatErrorMessage, d as releaseQueueOwnerLease, dt as sessionBaseDir, et as setPerfGauge, f as terminateProcess, ft as sessionEventActivePath, g as QueueLeaseGuardSettlementError, h as waitMs$1, i as trySetModeOnRunningOwner, it as isAcpMessageObject, j as findSessionByDirectoryWalk, k as findGitRepositoryRoot, m as tryAcquireQueueOwnerLease, mt as sessionEventSegmentPath, n as tryCloseSessionOnRunningOwner, o as trySubmitToRunningOwner, p as terminateQueueOwnerForSession, pt as sessionEventLockPath, r as trySetConfigOptionOnRunningOwner, rt as isAcpJsonRpcMessage, s as SessionQueueOwner, t as tryCancelOnRunningOwner, tt as startPerfTimer, u as refreshQueueOwnerLease, ut as defaultSessionEventLog, vt as isProcessAlive, w as createLockOwner, wt as extractAcpError, xt as isAcpQueryClosedBeforeResponseError, y as getUnsupportedPromptContentMessage, z as writeSessionRecord, zt as CopilotAcpUnsupportedError } from "./ipc-BW06Pbb8.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-DWnqUICY.js";
1
+ import { $ as resetPerfMetrics, Bt as GeminiAcpStartupTimeoutError, C as textPrompt, Ct as normalizeOutputError, F as normalizeName, Ft as AgentSpawnError, G as SESSION_JOURNAL_SCHEMA, Gt as SessionModeReplayError, Ht as PermissionPromptUnavailableError, It as AgentStartupError, Jt as SessionResumeRequiredError, K as SessionJournalReader, Kt as SessionModelReplayError, L as readSessionRecord, Lt as AuthPolicyError, M as isoNow$1, Nt as AcpxOperationalError, O as absolutePath, Pt as AgentDisconnectedError, Q as measurePerf, R as resolveSessionRecord, Rt as ClaudeAcpSessionCreateTimeoutError, S as promptToDisplayText, St as isRetryablePromptError, T as lockOwnerPid, Tt as isAcpResourceNotFoundError, U as extractAgentSessionId, Ut as QueueConnectionError, Vt as PermissionDeniedError, W as normalizeAgentSessionId, Wt as SessionConfigOptionReplayError, X as getPerfMetricsSnapshot, Y as formatPerfMetric, Yt as UnsupportedPromptContentError, Z as incrementPerfCounter, _ as ProcessDescendants, a as trySetModelOnRunningOwner, at as isSessionUpdateNotification, bt as formatErrorMessage, d as releaseQueueOwnerLease, dt as sessionBaseDir, et as setPerfGauge, f as terminateProcess, ft as sessionEventActivePath, g as QueueLeaseGuardSettlementError, h as waitMs$1, i as trySetModeOnRunningOwner, it as isAcpMessageObject, j as findSessionByDirectoryWalk, k as findGitRepositoryRoot, m as tryAcquireQueueOwnerLease, mt as sessionEventSegmentPath, n as tryCloseSessionOnRunningOwner, o as trySubmitToRunningOwner, p as terminateQueueOwnerForSession, pt as sessionEventLockPath, r as trySetConfigOptionOnRunningOwner, rt as isAcpJsonRpcMessage, s as SessionQueueOwner, t as tryCancelOnRunningOwner, tt as startPerfTimer, u as refreshQueueOwnerLease, ut as defaultSessionEventLog, vt as isProcessAlive, w as createLockOwner, wt as extractAcpError, xt as isAcpQueryClosedBeforeResponseError, y as getUnsupportedPromptContentMessage, z as writeSessionRecord, zt as CopilotAcpUnsupportedError } from "./ipc-D7zT86b9.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";
@@ -606,6 +606,18 @@ function sliceReadWindow(content, line, limit) {
606
606
  }
607
607
  //#endregion
608
608
  //#region src/permission-prompt.ts
609
+ function visiblePromptText(value) {
610
+ let rendered = "";
611
+ for (const character of value) {
612
+ const codePoint = character.codePointAt(0);
613
+ if (codePoint !== void 0 && (codePoint <= 31 || codePoint >= 127 && codePoint <= 159)) {
614
+ rendered += `\\x${codePoint.toString(16).padStart(2, "0")}`;
615
+ continue;
616
+ }
617
+ rendered += character;
618
+ }
619
+ return rendered;
620
+ }
609
621
  let promptQueue = Promise.resolve();
610
622
  async function promptForPermission(options) {
611
623
  options.signal?.throwIfAborted();
@@ -624,6 +636,10 @@ async function promptForPermission(options) {
624
636
  signal.removeEventListener("abort", onAbort);
625
637
  }
626
638
  }
639
+ function promptForDisplay(prompt) {
640
+ if (prompt.startsWith("\n")) return `\n${visiblePromptText(prompt.slice(1))}`;
641
+ return visiblePromptText(prompt);
642
+ }
627
643
  async function askPermission(options) {
628
644
  options.signal?.throwIfAborted();
629
645
  if (!canPrompt()) return false;
@@ -640,7 +656,7 @@ async function askPermission(options) {
640
656
  rl.once("close", onClose);
641
657
  });
642
658
  try {
643
- const answer = await Promise.race([rl.question(options.prompt, { signal }), closed]);
659
+ const answer = await Promise.race([rl.question(promptForDisplay(options.prompt), { signal }), closed]);
644
660
  options.signal?.throwIfAborted();
645
661
  const normalized = answer?.trim().toLowerCase();
646
662
  return normalized === "y" || normalized === "yes";
@@ -654,8 +670,8 @@ function canPrompt() {
654
670
  return process.stdin.isTTY && process.stderr.isTTY && !process.stdin.readableEnded && !process.stdin.destroyed;
655
671
  }
656
672
  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`);
673
+ if (options.header) process.stderr.write(`\n${visiblePromptText(options.header)}\n`);
674
+ if (options.details && options.details.trim().length > 0) process.stderr.write(`${options.details.split("\n").map(visiblePromptText).join("\n")}\n`);
659
675
  }
660
676
  //#endregion
661
677
  //#region src/filesystem.ts
@@ -1330,7 +1346,12 @@ function buildAgentEnvironment(authCredentials, sessionEnv, agentProcessEnv) {
1330
1346
  function assignSessionEnv(env, key, value) {
1331
1347
  const normalizedKey = protectedEnvKey(key);
1332
1348
  for (const existingKey of Object.keys(env)) if (protectedEnvKey(existingKey) === normalizedKey) delete env[existingKey];
1333
- env[key] = value;
1349
+ Object.defineProperty(env, key, {
1350
+ value,
1351
+ writable: true,
1352
+ enumerable: true,
1353
+ configurable: true
1354
+ });
1334
1355
  }
1335
1356
  function addAuthCredentialEnvKeys(protectedKeys, methodId, credential) {
1336
1357
  if (typeof credential !== "string" || credential.trim().length === 0) return;
@@ -1516,34 +1537,7 @@ function captureCommandProbeOutput(child, timeoutMs, retire) {
1516
1537
  };
1517
1538
  }
1518
1539
  //#endregion
1519
- //#region src/acp/model-support.ts
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
- }
1540
+ //#region src/acp/model-config-state.ts
1547
1541
  function asRecord$2(value) {
1548
1542
  if (!value || typeof value !== "object" || Array.isArray(value)) return;
1549
1543
  return value;
@@ -1602,6 +1596,35 @@ function modelStateFromConfigOptions(configOptions) {
1602
1596
  }
1603
1597
  return selected;
1604
1598
  }
1599
+ //#endregion
1600
+ //#region src/acp/model-support.ts
1601
+ const REQUESTED_MODEL_UNSUPPORTED_ERROR_CODE = "ACP_MODEL_UNSUPPORTED";
1602
+ const REQUESTED_MODEL_UNSUPPORTED_REASONS = ["missing-capability", "unadvertised-model"];
1603
+ var RequestedModelUnsupportedError = class extends Error {
1604
+ code = REQUESTED_MODEL_UNSUPPORTED_ERROR_CODE;
1605
+ reason;
1606
+ ambiguous;
1607
+ constructor(message, reason, details) {
1608
+ super(message);
1609
+ this.name = "RequestedModelUnsupportedError";
1610
+ this.reason = reason;
1611
+ if (details?.ambiguous) this.ambiguous = true;
1612
+ }
1613
+ };
1614
+ function isRequestedModelUnsupportedReason(value) {
1615
+ return typeof value === "string" && REQUESTED_MODEL_UNSUPPORTED_REASONS.includes(value);
1616
+ }
1617
+ function isRequestedModelUnsupportedError(value) {
1618
+ if (value instanceof RequestedModelUnsupportedError) return true;
1619
+ if (!value || typeof value !== "object") return false;
1620
+ const candidate = value;
1621
+ return candidate.name === "RequestedModelUnsupportedError" && candidate.code === "ACP_MODEL_UNSUPPORTED" && isRequestedModelUnsupportedReason(candidate.reason);
1622
+ }
1623
+ function supportsLegacyClaudeCodeModelMetadata(agentCommand) {
1624
+ if (!agentCommand) return false;
1625
+ const { command, args } = splitCommandLine(agentCommand);
1626
+ return isClaudeAcpCommand(command, args);
1627
+ }
1605
1628
  function modelStateFromLegacyResponse(response) {
1606
1629
  if (!response || typeof response !== "object") return;
1607
1630
  const models = response.models;
@@ -1633,6 +1656,16 @@ function resolveRequestedModelId(params) {
1633
1656
  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
1657
  return candidates.length === 1 ? candidates[0] : params.requestedModel;
1635
1658
  }
1659
+ function resolveRequestedConfigOption(params) {
1660
+ const modelConfigId = params.models?.configId;
1661
+ return {
1662
+ modelConfigId,
1663
+ resolvedValue: modelConfigId === params.configId ? resolveRequestedModelId({
1664
+ ...params,
1665
+ requestedModel: params.value
1666
+ }) : params.value
1667
+ };
1668
+ }
1636
1669
  function isCursorAcpCommandForModelAlias(agentCommand) {
1637
1670
  if (!agentCommand) return false;
1638
1671
  const { command, args } = splitCommandLine(agentCommand);
@@ -2242,7 +2275,7 @@ async function spawnTerminalProcess(params, defaultCwd, authority) {
2242
2275
  }
2243
2276
  async function spawnAndWait(spawnCommand, params, defaultCwd, authority) {
2244
2277
  const spawnOptions = buildTerminalSpawnOptions(spawnCommand.command, params.cwd ?? defaultCwd, params.env);
2245
- if (spawnCommand.killProcessGroup || process.platform !== "win32") spawnOptions.detached = true;
2278
+ if (process.platform !== "win32") spawnOptions.detached = true;
2246
2279
  assertControlAuthority(authority);
2247
2280
  const proc = spawn(spawnCommand.command, spawnCommand.args, spawnOptions);
2248
2281
  await waitForSpawn(proc);
@@ -2406,7 +2439,14 @@ function hasResponseField(response, field) {
2406
2439
  }
2407
2440
  function normalizeResponseConfigOptions(response) {
2408
2441
  if (!response || !("configOptions" in response)) return;
2409
- return response.configOptions ?? [];
2442
+ return Array.isArray(response.configOptions) ? response.configOptions : void 0;
2443
+ }
2444
+ function normalizeConfigOptionAcknowledgement(response) {
2445
+ if (!response || typeof response !== "object" || Array.isArray(response)) return {};
2446
+ if (Array.isArray(response.configOptions)) return response;
2447
+ const acknowledgement = { ...response };
2448
+ delete acknowledgement.configOptions;
2449
+ return acknowledgement;
2410
2450
  }
2411
2451
  function toReconnectedSessionResult(response) {
2412
2452
  const configOptions = normalizeResponseConfigOptions(response);
@@ -2417,7 +2457,7 @@ function toReconnectedSessionResult(response) {
2417
2457
  configOptions,
2418
2458
  response
2419
2459
  }),
2420
- configOptionsPresent: hasResponseField(response, "configOptions"),
2460
+ configOptionsPresent: configOptions !== void 0,
2421
2461
  legacyModelMetadataPresent: hasResponseField(response, "models")
2422
2462
  };
2423
2463
  }
@@ -2971,7 +3011,7 @@ var AcpClient = class {
2971
3011
  agentSessionId: extractAgentSessionId(result._meta),
2972
3012
  configOptions,
2973
3013
  models,
2974
- configOptionsPresent: hasResponseField(result, "configOptions"),
3014
+ configOptionsPresent: configOptions !== void 0,
2975
3015
  legacyModelMetadataPresent: hasResponseField(result, "models")
2976
3016
  };
2977
3017
  }
@@ -3128,11 +3168,11 @@ var AcpClient = class {
3128
3168
  assertControlAuthority(authority);
3129
3169
  const resolvedValue = models?.configId === configId ? this.resolveSessionModelId(value, models) : value;
3130
3170
  const connection = this.getConnection();
3131
- return await this.runConnectionRequest(() => connection.agent.request(methods.agent.session.setConfigOption, {
3171
+ return normalizeConfigOptionAcknowledgement(await this.runConnectionRequest(() => connection.agent.request(methods.agent.session.setConfigOption, {
3132
3172
  sessionId,
3133
3173
  configId,
3134
3174
  value: resolvedValue
3135
- }), authority, (error) => maybeWrapSessionControlError("session/set_config_option", error, `for "${configId}"="${value}"`));
3175
+ }), authority, (error) => maybeWrapSessionControlError("session/set_config_option", error, `for "${configId}"="${value}"`)));
3136
3176
  }
3137
3177
  async setSessionModel(sessionId, modelId, models, authority) {
3138
3178
  assertControlAuthority(authority);
@@ -3154,11 +3194,11 @@ var AcpClient = class {
3154
3194
  }
3155
3195
  async setSessionModelThroughConfig(sessionId, modelId, configId, authority) {
3156
3196
  const connection = this.getConnection();
3157
- return await this.runConnectionRequest(() => connection.agent.request(methods.agent.session.setConfigOption, {
3197
+ return normalizeConfigOptionAcknowledgement(await this.runConnectionRequest(() => connection.agent.request(methods.agent.session.setConfigOption, {
3158
3198
  sessionId,
3159
3199
  configId,
3160
3200
  value: modelId
3161
- }), authority, (error) => this.throwSessionModelError("session/set_config_option", modelId, error));
3201
+ }), authority, (error) => this.throwSessionModelError("session/set_config_option", modelId, error)));
3162
3202
  }
3163
3203
  async setSessionModelThroughLegacyMethod(sessionId, modelId, authority) {
3164
3204
  const connection = this.getConnection();
@@ -3925,6 +3965,7 @@ function removeModelConfigOptions(state) {
3925
3965
  state.config_options = state.config_options.filter((option) => option.category !== "model" && option.id !== "model");
3926
3966
  }
3927
3967
  function applyConfigOptionsModelState(state, configOptions) {
3968
+ if (!Array.isArray(configOptions)) return;
3928
3969
  const previousConfigModels = modelStateFromConfigOptions(state.config_options);
3929
3970
  const preservesLegacyControl = state.model_control === "legacy_set_model" || state.model_control === void 0 && previousConfigModels === void 0 && legacyModelState(state) !== void 0;
3930
3971
  state.config_options = structuredClone(configOptions);
@@ -3934,14 +3975,9 @@ function applyConfigOptionsModelState(state, configOptions) {
3934
3975
  else clearAdvertisedModelState(state);
3935
3976
  }
3936
3977
  //#endregion
3937
- //#region src/session/conversation-model.ts
3938
- const MAX_RUNTIME_MESSAGES = 200;
3939
- const MAX_RUNTIME_AGENT_TEXT_CHARS = 8e3;
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();
3978
+ //#region src/session/conversation-reducer.ts
3979
+ function resolveUserMessageId(value) {
3980
+ return typeof value === "string" ? value : value();
3945
3981
  }
3946
3982
  function deepClone(value) {
3947
3983
  try {
@@ -4012,9 +4048,6 @@ function resourceToUserContent(content) {
4012
4048
  content: content.resource.uri
4013
4049
  } };
4014
4050
  }
4015
- function nextUserMessageId() {
4016
- return randomUUID();
4017
- }
4018
4051
  function isUserMessage(message) {
4019
4052
  return typeof message === "object" && message !== null && hasOwn(message, "User");
4020
4053
  }
@@ -4046,7 +4079,7 @@ function ensureAgentMessage(conversation) {
4046
4079
  function appendAgentText(agent, text) {
4047
4080
  const last = agent.content.at(-1);
4048
4081
  if (last && isAgentTextContent(last)) {
4049
- last.Text = trimRuntimeText(`${last.Text}${text}`, MAX_RUNTIME_AGENT_TEXT_CHARS);
4082
+ last.Text = `${last.Text}${text}`;
4050
4083
  return;
4051
4084
  }
4052
4085
  const next = { Text: text };
@@ -4055,7 +4088,7 @@ function appendAgentText(agent, text) {
4055
4088
  function appendAgentThinking(agent, text) {
4056
4089
  const last = agent.content.at(-1);
4057
4090
  if (last && isAgentThinkingContent(last)) {
4058
- last.Thinking.text = trimRuntimeText(`${last.Thinking.text}${text}`, MAX_RUNTIME_THINKING_CHARS);
4091
+ last.Thinking.text = `${last.Thinking.text}${text}`;
4059
4092
  return;
4060
4093
  }
4061
4094
  const next = { Thinking: {
@@ -4064,13 +4097,6 @@ function appendAgentThinking(agent, text) {
4064
4097
  } };
4065
4098
  agent.content.push(next);
4066
4099
  }
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
4100
  function statusIndicatesComplete(status) {
4075
4101
  if (typeof status !== "string") return false;
4076
4102
  const normalized = status.toLowerCase();
@@ -4082,18 +4108,18 @@ function statusIndicatesError(status) {
4082
4108
  return normalized.includes("fail") || normalized.includes("error");
4083
4109
  }
4084
4110
  function toToolResultContent(value) {
4085
- if (typeof value === "string") return { Text: trimRuntimeText(value, MAX_RUNTIME_TOOL_IO_CHARS) };
4111
+ if (typeof value === "string") return { Text: value };
4086
4112
  if (value != null) try {
4087
- return { Text: trimRuntimeText(JSON.stringify(value), MAX_RUNTIME_TOOL_IO_CHARS) };
4113
+ return { Text: JSON.stringify(value) ?? "[Unserializable value]" };
4088
4114
  } catch {
4089
4115
  return { Text: "[Unserializable value]" };
4090
4116
  }
4091
4117
  return { Text: "" };
4092
4118
  }
4093
4119
  function toRawInput(value) {
4094
- if (typeof value === "string") return trimRuntimeText(value, MAX_RUNTIME_TOOL_IO_CHARS);
4120
+ if (typeof value === "string") return value;
4095
4121
  try {
4096
- return trimRuntimeText(JSON.stringify(value ?? {}), MAX_RUNTIME_TOOL_IO_CHARS);
4122
+ return JSON.stringify(value ?? {}) ?? "[Unserializable input]";
4097
4123
  } catch {
4098
4124
  return value == null ? "" : "[Unserializable input]";
4099
4125
  }
@@ -4138,11 +4164,13 @@ function existingToolResultValues(existing) {
4138
4164
  };
4139
4165
  }
4140
4166
  function applyToolCallUpdate(agent, update) {
4167
+ const contentCount = agent.content.length;
4141
4168
  const tool = ensureToolUseContent(agent, update.toolCallId);
4142
4169
  applyToolIdentityUpdate(tool, update);
4143
4170
  applyToolInputUpdate(tool, update);
4144
4171
  applyToolStatusUpdate(tool, update);
4145
4172
  applyToolResultUpdate(agent, tool, update);
4173
+ return agent.content.length !== contentCount || hasOwn(update, "rawInput") || hasToolResultPatch(update);
4146
4174
  }
4147
4175
  function applyToolIdentityUpdate(tool, update) {
4148
4176
  if (hasOwn(update, "title")) tool.name = normalizeAgentName(update.title) ?? tool.name ?? "tool_call";
@@ -4245,7 +4273,7 @@ function lastUserMessageId(conversation) {
4245
4273
  if (message && isUserMessage(message)) return message.User.id;
4246
4274
  }
4247
4275
  }
4248
- function createSessionConversation(timestamp = isoNow()) {
4276
+ function createConversation(timestamp) {
4249
4277
  return {
4250
4278
  title: null,
4251
4279
  messages: [],
@@ -4255,8 +4283,7 @@ function createSessionConversation(timestamp = isoNow()) {
4255
4283
  request_token_usage: {}
4256
4284
  };
4257
4285
  }
4258
- function cloneSessionConversation(conversation) {
4259
- if (!conversation) return createSessionConversation();
4286
+ function cloneConversation(conversation) {
4260
4287
  return {
4261
4288
  title: conversation.title,
4262
4289
  messages: deepClone(conversation.messages ?? []),
@@ -4297,57 +4324,47 @@ function cloneSessionOptions(options) {
4297
4324
  function cloneSystemPromptOption(option) {
4298
4325
  return typeof option === "string" ? option : { append: option.append };
4299
4326
  }
4300
- function recordPromptSubmission(conversation, prompt, timestamp = isoNow(), messageId) {
4327
+ function reducePromptSubmission(conversation, prompt, timestamp, messageId) {
4301
4328
  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();
4329
+ if (userContent.length === 0) return { messageIndex: void 0 };
4304
4330
  conversation.messages.push({ User: {
4305
- id: promptMessageId,
4306
- content: userContent.map((content) => {
4307
- if ("Text" in content) return { Text: trimRuntimeText(content.Text, MAX_RUNTIME_AGENT_TEXT_CHARS) };
4308
- return content;
4309
- })
4331
+ id: resolveUserMessageId(messageId),
4332
+ content: userContent
4310
4333
  } });
4311
4334
  updateConversationTimestamp(conversation, timestamp);
4312
- trimConversationForRuntime(conversation);
4313
- return promptMessageId;
4335
+ return { messageIndex: conversation.messages.length - 1 };
4314
4336
  }
4315
- function recordSessionUpdate(conversation, state, notification, timestamp = isoNow(), userMessageId) {
4337
+ function reduceSessionUpdate(conversation, state, notification, timestamp, userMessageId) {
4316
4338
  const acpx = ensureAcpxState$1(state);
4317
- const update = notification.update;
4318
- applySessionUpdate(conversation, acpx, update, userMessageId);
4339
+ const messageIndex = applySessionUpdate(conversation, acpx, notification.update, userMessageId);
4319
4340
  updateConversationTimestamp(conversation, timestamp);
4320
- trimConversationForRuntime(conversation);
4321
- return acpx;
4341
+ return {
4342
+ acpx,
4343
+ messageIndex
4344
+ };
4322
4345
  }
4323
- function recordPromptResponseUsage(conversation, usage, promptMessageId, timestamp = isoNow()) {
4346
+ function reducePromptResponseUsage(conversation, usage, promptMessageId, timestamp) {
4324
4347
  const tokenUsage = sourceToTokenUsage(usage);
4325
4348
  if (!tokenUsage) return false;
4326
4349
  applyTokenUsage(conversation, tokenUsage, promptMessageId);
4327
4350
  updateConversationTimestamp(conversation, timestamp);
4328
- trimConversationForRuntime(conversation);
4329
4351
  return true;
4330
4352
  }
4331
4353
  function applySessionUpdate(conversation, acpx, update, userMessageId) {
4332
- const handler = SESSION_UPDATE_HANDLERS[update.sessionUpdate];
4333
- handler?.(conversation, acpx, update, userMessageId);
4354
+ return (Object.hasOwn(SESSION_UPDATE_HANDLERS, update.sessionUpdate) ? SESSION_UPDATE_HANDLERS[update.sessionUpdate] : void 0)?.(conversation, acpx, update, userMessageId);
4334
4355
  }
4335
4356
  const SESSION_UPDATE_HANDLERS = {
4336
4357
  user_message_chunk: (conversation, _acpx, update, userMessageId) => {
4337
- if (update.sessionUpdate === "user_message_chunk") appendUserMessageChunk(conversation, update.content, userMessageId);
4358
+ if (update.sessionUpdate === "user_message_chunk") return appendUserMessageChunk(conversation, update.content, userMessageId);
4338
4359
  },
4339
4360
  agent_message_chunk: (conversation, _acpx, update) => {
4340
- if (update.sessionUpdate === "agent_message_chunk") appendAgentMessageChunk(conversation, update.content, appendAgentText);
4361
+ if (update.sessionUpdate === "agent_message_chunk") return appendAgentMessageChunk(conversation, update.content, appendAgentText);
4341
4362
  },
4342
4363
  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);
4364
+ if (update.sessionUpdate === "agent_thought_chunk") return appendAgentMessageChunk(conversation, update.content, appendAgentThinking);
4350
4365
  },
4366
+ tool_call: applyToolUpdate,
4367
+ tool_call_update: applyToolUpdate,
4351
4368
  usage_update: (conversation, _acpx, update) => {
4352
4369
  if (update.sessionUpdate === "usage_update") applyUsageUpdate(conversation, update);
4353
4370
  },
@@ -4364,17 +4381,24 @@ const SESSION_UPDATE_HANDLERS = {
4364
4381
  if (update.sessionUpdate === "config_option_update") applyConfigOptionsModelState(acpx, deepClone(update.configOptions));
4365
4382
  }
4366
4383
  };
4384
+ function applyToolUpdate(conversation, _acpx, update) {
4385
+ if (update.sessionUpdate !== "tool_call" && update.sessionUpdate !== "tool_call_update") return;
4386
+ return applyToolCallUpdate(ensureAgentMessage(conversation), update) ? conversation.messages.length - 1 : void 0;
4387
+ }
4367
4388
  function appendUserMessageChunk(conversation, content, messageId) {
4368
4389
  const userContent = contentToUserContent(content);
4369
4390
  if (!userContent) return;
4370
4391
  conversation.messages.push({ User: {
4371
- id: messageId ?? nextUserMessageId(),
4392
+ id: resolveUserMessageId(messageId),
4372
4393
  content: [userContent]
4373
4394
  } });
4395
+ return conversation.messages.length - 1;
4374
4396
  }
4375
4397
  function appendAgentMessageChunk(conversation, content, append) {
4376
4398
  const text = extractText(content);
4377
- if (text) append(ensureAgentMessage(conversation), text);
4399
+ if (!text) return;
4400
+ append(ensureAgentMessage(conversation), text);
4401
+ return conversation.messages.length - 1;
4378
4402
  }
4379
4403
  function applyUsageUpdate(conversation, update) {
4380
4404
  const usage = usageToTokenUsage(update);
@@ -4386,17 +4410,30 @@ function applyUsageUpdate(conversation, update) {
4386
4410
  function applyTokenUsage(conversation, usage, promptMessageId) {
4387
4411
  conversation.cumulative_token_usage = usage;
4388
4412
  const userId = promptMessageId ?? lastUserMessageId(conversation);
4389
- if (userId) conversation.request_token_usage[userId] = usage;
4413
+ if (userId) Object.defineProperty(conversation.request_token_usage, userId, {
4414
+ value: usage,
4415
+ writable: true,
4416
+ enumerable: true,
4417
+ configurable: true
4418
+ });
4390
4419
  }
4391
4420
  function applySessionInfoUpdate(conversation, update) {
4392
4421
  if (hasOwn(update, "title")) conversation.title = update.title ?? null;
4393
4422
  if (hasOwn(update, "updatedAt")) conversation.updated_at = update.updatedAt ?? conversation.updated_at;
4394
4423
  }
4395
- function recordClientOperation(conversation, state, _operation, timestamp = isoNow()) {
4396
- const acpx = ensureAcpxState$1(state);
4397
- updateConversationTimestamp(conversation, timestamp);
4398
- trimConversationForRuntime(conversation);
4399
- return acpx;
4424
+ //#endregion
4425
+ //#region src/session/conversation-retention.ts
4426
+ const MAX_RUNTIME_MESSAGES = 200;
4427
+ const MAX_RUNTIME_AGENT_TEXT_CHARS = 8e3;
4428
+ const MAX_RUNTIME_THINKING_CHARS = 4e3;
4429
+ const MAX_RUNTIME_TOOL_IO_CHARS = 4e3;
4430
+ const MAX_RUNTIME_REQUEST_TOKEN_USAGE = 100;
4431
+ function trimRuntimeText(value, maxChars) {
4432
+ if (value.length <= maxChars) return value;
4433
+ let end = Math.max(0, maxChars - 3);
4434
+ const last = value.charCodeAt(end - 1);
4435
+ if (last >= 55296 && last <= 56319) end -= 1;
4436
+ return `${value.slice(0, end)}...`;
4400
4437
  }
4401
4438
  function trimConversationForRuntime(conversation) {
4402
4439
  if (conversation.messages.length > MAX_RUNTIME_MESSAGES) conversation.messages = conversation.messages.slice(-200);
@@ -4431,6 +4468,39 @@ function trimRuntimeToolResult(result) {
4431
4468
  if (typeof result.output === "string") result.output = trimRuntimeText(result.output, MAX_RUNTIME_TOOL_IO_CHARS);
4432
4469
  }
4433
4470
  //#endregion
4471
+ //#region src/session/conversation-model.ts
4472
+ function isoNow() {
4473
+ return (/* @__PURE__ */ new Date()).toISOString();
4474
+ }
4475
+ function createSessionConversation(timestamp = isoNow()) {
4476
+ return createConversation(timestamp);
4477
+ }
4478
+ function cloneSessionConversation(conversation) {
4479
+ return conversation ? cloneConversation(conversation) : createSessionConversation();
4480
+ }
4481
+ function recordPromptSubmission(conversation, prompt, timestamp = isoNow(), messageId) {
4482
+ let promptMessageId = messageId;
4483
+ if (reducePromptSubmission(conversation, prompt, timestamp, () => promptMessageId ??= randomUUID()).messageIndex === void 0) return;
4484
+ trimConversationForRuntime(conversation);
4485
+ return promptMessageId;
4486
+ }
4487
+ function recordSessionUpdate(conversation, state, notification, timestamp = isoNow(), userMessageId) {
4488
+ const { acpx } = reduceSessionUpdate(conversation, state, notification, timestamp, userMessageId ?? randomUUID);
4489
+ trimConversationForRuntime(conversation);
4490
+ return acpx;
4491
+ }
4492
+ function recordPromptResponseUsage(conversation, usage, promptMessageId, timestamp = isoNow()) {
4493
+ if (!reducePromptResponseUsage(conversation, usage, promptMessageId, timestamp)) return false;
4494
+ trimConversationForRuntime(conversation);
4495
+ return true;
4496
+ }
4497
+ function recordClientOperation(conversation, state, _operation, timestamp = isoNow()) {
4498
+ const acpx = state ?? {};
4499
+ conversation.updated_at = timestamp;
4500
+ trimConversationForRuntime(conversation);
4501
+ return acpx;
4502
+ }
4503
+ //#endregion
4434
4504
  //#region src/runtime/engine/lifecycle.ts
4435
4505
  function createInitialSessionRecord(params) {
4436
4506
  const now = (/* @__PURE__ */ new Date()).toISOString();
@@ -4553,19 +4623,27 @@ function storedEnvRecord(value) {
4553
4623
  const result = {};
4554
4624
  for (const [key, raw] of entries) {
4555
4625
  if (typeof raw !== "string") continue;
4556
- result[key] = raw;
4626
+ Object.defineProperty(result, key, {
4627
+ value: raw,
4628
+ writable: true,
4629
+ enumerable: true,
4630
+ configurable: true
4631
+ });
4557
4632
  }
4558
4633
  return Object.keys(result).length > 0 ? result : void 0;
4559
4634
  }
4560
4635
  function normalizeSystemPromptOption(value) {
4561
- const prompt = nonEmptyString(value);
4636
+ const prompt = nonEmptyPromptText(value);
4562
4637
  if (prompt !== void 0) return prompt;
4563
4638
  const append = appendedSystemPrompt(value);
4564
4639
  return append === void 0 ? void 0 : { append };
4565
4640
  }
4566
4641
  function appendedSystemPrompt(value) {
4567
4642
  if (typeof value !== "object" || value === null || Array.isArray(value)) return;
4568
- return nonEmptyString(value.append);
4643
+ return nonEmptyPromptText(value.append);
4644
+ }
4645
+ function nonEmptyPromptText(value) {
4646
+ return typeof value === "string" && value.length > 0 ? value : void 0;
4569
4647
  }
4570
4648
  function storedAllowedTools(value) {
4571
4649
  return Array.isArray(value) && value.every((item) => typeof item === "string") ? [...value] : void 0;
@@ -4638,13 +4716,19 @@ async function applyRequestedModelIfAdvertised(params) {
4638
4716
  });
4639
4717
  if (warning) params.onWarning?.(warning);
4640
4718
  if (!params.models) return { applied: false };
4641
- if (params.models.currentModelId === requestedModel) return {
4719
+ const resolvedModelId = resolveRequestedModelId({
4720
+ ...params,
4721
+ requestedModel
4722
+ });
4723
+ if (params.models.currentModelId === resolvedModelId) return {
4642
4724
  applied: true,
4643
- modelId: requestedModel
4725
+ modelId: requestedModel,
4726
+ resolvedModelId
4644
4727
  };
4645
4728
  return {
4646
4729
  applied: true,
4647
4730
  modelId: requestedModel,
4731
+ resolvedModelId,
4648
4732
  response: await withTimeout(params.client.setSessionModel(params.sessionId, requestedModel, params.models, params.authority), params.timeoutMs)
4649
4733
  };
4650
4734
  }
@@ -4657,17 +4741,18 @@ function applyConfigOptionsToState(state, configOptions) {
4657
4741
  }
4658
4742
  function applyConfigOptionsToRecord(record, result) {
4659
4743
  const configOptions = result?.configOptions;
4660
- if (!configOptions) return;
4744
+ if (!Array.isArray(configOptions)) return;
4661
4745
  record.acpx = applyConfigOptionsToState(record.acpx, configOptions);
4662
4746
  }
4663
4747
  function applyInitialModelSelection(record, originalModels, modelApplication) {
4664
4748
  applyConfigOptionsToRecord(record, modelApplication.response);
4665
- syncAdvertisedModelState(record, modelApplication.response?.configOptions !== void 0 ? modelStateFromConfigOptions(modelApplication.response.configOptions) : originalModels);
4666
- if (modelApplication.applied) record.acpx = applyModelSelection(record.acpx, modelApplication.modelId, modelApplication.response);
4749
+ const configOptions = modelApplication.response?.configOptions;
4750
+ syncAdvertisedModelState(record, Array.isArray(configOptions) ? modelStateFromConfigOptions(configOptions) : originalModels);
4751
+ if (modelApplication.applied) record.acpx = applyModelSelection(record.acpx, modelApplication.modelId, modelApplication.response, modelApplication.resolvedModelId);
4667
4752
  }
4668
4753
  function applyAcceptedConfigOptions(state, response, selection) {
4669
4754
  const next = cloneSessionAcpxState(state) ?? {};
4670
- if (response?.configOptions === void 0) {
4755
+ if (!Array.isArray(response?.configOptions)) {
4671
4756
  const option = next.config_options?.find((entry) => entry.id === selection.configId);
4672
4757
  if (option) option.currentValue = selection.value;
4673
4758
  return next;
@@ -4683,22 +4768,25 @@ function reconcileDesiredConfigOptions(state, configOptions) {
4683
4768
  if (desiredEntries.length > 0) state.desired_config_options = Object.fromEntries(desiredEntries);
4684
4769
  else delete state.desired_config_options;
4685
4770
  }
4686
- function applyModelSelection(state, modelId, response) {
4771
+ function applyModelSelection(state, modelId, response, resolvedModelId = modelId) {
4687
4772
  const modelConfigId = advertisedModelState(state)?.configId;
4688
4773
  const next = applyAcceptedConfigOptions(state, response, {
4689
4774
  configId: modelConfigId,
4690
- value: modelId
4775
+ value: resolvedModelId
4691
4776
  });
4692
4777
  next.session_options = {
4693
4778
  ...next.session_options,
4694
4779
  model: modelId
4695
4780
  };
4696
- next.current_model_id = currentModelIdFromSetModelResponse(response, modelId);
4781
+ next.current_model_id = currentModelIdFromSetModelResponse(response, resolvedModelId);
4697
4782
  clearDesiredConfigOption(next, modelConfigId ?? advertisedModelState(next)?.configId);
4698
4783
  return next;
4699
4784
  }
4700
- function applyConfigOptionSelection(state, configId, value, response, modelConfigId = advertisedModelState(state)?.configId) {
4701
- if (configId === modelConfigId || configId === modelStateFromConfigOptions(response.configOptions)?.configId) return applyModelSelection(state, value, response);
4785
+ function isModelConfigSelection(configId, response, modelConfigId) {
4786
+ return configId === modelConfigId || configId === modelStateFromConfigOptions(response?.configOptions)?.configId;
4787
+ }
4788
+ function applyConfigOptionSelection(state, configId, value, response, modelConfigId = advertisedModelState(state)?.configId, resolvedValue = value) {
4789
+ if (isModelConfigSelection(configId, response, modelConfigId)) return applyModelSelection(state, value, response, resolvedValue);
4702
4790
  const next = cloneSessionAcpxState(state) ?? {};
4703
4791
  next.desired_config_options = {
4704
4792
  ...next.desired_config_options,
@@ -4806,9 +4894,14 @@ async function replayDesiredModel(params) {
4806
4894
  context: "replay"
4807
4895
  }), params.suppressWarnings);
4808
4896
  if (!params.models) return { replayed: false };
4897
+ const resolvedModelId = resolveRequestedModelId({
4898
+ requestedModel: params.desiredModelId,
4899
+ models: params.models,
4900
+ agentCommand: params.record.agentCommand
4901
+ });
4809
4902
  const response = await withTimeout(params.client.setSessionModel(params.sessionId, params.desiredModelId, params.models, params.replay.authority), params.timeoutMs);
4810
4903
  params.replay.acknowledged = true;
4811
- params.record.acpx = applyModelSelection(params.record.acpx, params.desiredModelId, response);
4904
+ params.record.acpx = applyModelSelection(params.record.acpx, params.desiredModelId, response, resolvedModelId);
4812
4905
  const models = advertisedModelState(params.record.acpx);
4813
4906
  if (params.verbose) process.stderr.write(`[acpx] replayed desired model ${params.desiredModelId} on ACP session ${params.sessionId} (previous ${params.previousSessionId})\n`);
4814
4907
  return {
@@ -4834,9 +4927,16 @@ async function replayDesiredConfigOptions(params) {
4834
4927
  for (const [configId, value] of Object.entries(params.desiredConfigOptions)) {
4835
4928
  if (configId === replacingKey || acceptedConfigOptions && !acceptsSavedConfigValue(acceptedConfigOptions.find((option) => option.id === configId), value)) continue;
4836
4929
  try {
4837
- const response = await withTimeout(params.client.setSessionConfigOption(params.sessionId, configId, value, advertisedModelState(params.record.acpx), params.replay.authority), params.timeoutMs);
4930
+ const models = advertisedModelState(params.record.acpx);
4931
+ const { modelConfigId, resolvedValue } = resolveRequestedConfigOption({
4932
+ configId,
4933
+ value,
4934
+ models,
4935
+ agentCommand: params.record.agentCommand
4936
+ });
4937
+ const response = await withTimeout(params.client.setSessionConfigOption(params.sessionId, configId, value, models, params.replay.authority), params.timeoutMs);
4838
4938
  params.replay.acknowledged = true;
4839
- params.record.acpx = applyConfigOptionSelection(params.record.acpx, configId, value, response);
4939
+ params.record.acpx = applyConfigOptionSelection(params.record.acpx, configId, value, response, modelConfigId, resolvedValue);
4840
4940
  acceptedConfigOptions = params.record.acpx.config_options;
4841
4941
  result = {
4842
4942
  replayed: true,
@@ -5289,8 +5389,13 @@ async function runSessionSetModelDirect(options) {
5289
5389
  replacingConfigOption: { key: "model" }
5290
5390
  }, async ({ client, sessionId, record }) => {
5291
5391
  const models = advertisedModelState(record.acpx);
5392
+ const resolvedModelId = resolveRequestedModelId({
5393
+ requestedModel: options.modelId,
5394
+ models,
5395
+ agentCommand: record.agentCommand
5396
+ });
5292
5397
  const response = await withTimeout(client.setSessionModel(sessionId, options.modelId, models), options.timeoutMs);
5293
- record.acpx = applyModelSelection(record.acpx, options.modelId, response);
5398
+ record.acpx = applyModelSelection(record.acpx, options.modelId, response, resolvedModelId);
5294
5399
  return response;
5295
5400
  }));
5296
5401
  return {
@@ -5304,8 +5409,14 @@ async function runSessionSetConfigOptionDirect(options) {
5304
5409
  replacingConfigOption: { key: options.configId }
5305
5410
  }, async ({ client, sessionId, record }) => {
5306
5411
  const models = advertisedModelState(record.acpx);
5412
+ const { modelConfigId, resolvedValue } = resolveRequestedConfigOption({
5413
+ configId: options.configId,
5414
+ value: options.value,
5415
+ models,
5416
+ agentCommand: record.agentCommand
5417
+ });
5307
5418
  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, models?.configId);
5419
+ record.acpx = applyConfigOptionSelection(record.acpx, options.configId, options.value, response, modelConfigId, resolvedValue);
5309
5420
  return response;
5310
5421
  }));
5311
5422
  return {
@@ -5451,7 +5562,11 @@ async function setSessionModelOnOwner(options) {
5451
5562
  if (!submittedToOwner) return;
5452
5563
  const record = await resolveSessionRecord(options.sessionId);
5453
5564
  if (!submittedToOwner.persistsControlState) {
5454
- record.acpx = applyModelSelection(record.acpx, options.modelId, submittedToOwner.value.response);
5565
+ record.acpx = applyModelSelection(record.acpx, options.modelId, submittedToOwner.value.response, resolveRequestedModelId({
5566
+ requestedModel: options.modelId,
5567
+ models: advertisedModelState(record.acpx),
5568
+ agentCommand: record.agentCommand
5569
+ }));
5455
5570
  await writeSessionRecord(record);
5456
5571
  }
5457
5572
  return {
@@ -5482,7 +5597,14 @@ async function setSessionConfigOptionOnOwner(options) {
5482
5597
  if (!ownerResponse) return;
5483
5598
  const record = await resolveSessionRecord(options.sessionId);
5484
5599
  if (!ownerResponse.persistsControlState) {
5485
- record.acpx = applyConfigOptionSelection(record.acpx, options.configId, options.value, ownerResponse.value);
5600
+ const models = advertisedModelState(record.acpx);
5601
+ const { modelConfigId, resolvedValue } = resolveRequestedConfigOption({
5602
+ configId: options.configId,
5603
+ value: options.value,
5604
+ models,
5605
+ agentCommand: record.agentCommand
5606
+ });
5607
+ record.acpx = applyConfigOptionSelection(record.acpx, options.configId, options.value, ownerResponse.value, modelConfigId, resolvedValue);
5486
5608
  await writeSessionRecord(record);
5487
5609
  }
5488
5610
  return {
@@ -5600,7 +5722,7 @@ async function closeSession(sessionId) {
5600
5722
  }
5601
5723
  //#endregion
5602
5724
  //#region src/session/execution/session-management.ts
5603
- async function createSessionRecordWithClient(client, options) {
5725
+ async function createSessionRecordWithClient(client, options, resumedRecordId) {
5604
5726
  const cwd = absolutePath(options.cwd);
5605
5727
  await withTimeout(client.start({ signal: options.signal }), options.timeoutMs);
5606
5728
  assertControlAuthority({ signal: options.signal });
@@ -5610,7 +5732,7 @@ async function createSessionRecordWithClient(client, options) {
5610
5732
  const lifecycle = client.getAgentLifecycleSnapshot();
5611
5733
  const record = {
5612
5734
  ...createInitialSessionRecord({
5613
- recordId: sessionId,
5735
+ recordId: resumedRecordId ?? randomUUID(),
5614
5736
  sessionId,
5615
5737
  agentSessionId,
5616
5738
  agentCommand: options.agentCommand,
@@ -5681,11 +5803,17 @@ async function resumeSessionRecordWithClient(client, options, cwd) {
5681
5803
  }
5682
5804
  async function createSessionWithClient(options) {
5683
5805
  assertControlAuthority({ signal: options.signal });
5806
+ let resumedRecordId;
5684
5807
  if (options.resumeSessionId) {
5685
5808
  const resumedRecord = await readSessionRecord(options.resumeSessionId);
5686
5809
  assertControlAuthority({ signal: options.signal });
5687
- if (resumedRecord && !resumedRecord.closed && resumedRecord.agentCommand === options.agentCommand) {
5688
- await closeSession(resumedRecord.acpxRecordId);
5810
+ if (resumedRecord && resumedRecord.agentCommand === options.agentCommand) {
5811
+ resumedRecordId = resumedRecord.acpxRecordId;
5812
+ if (!resumedRecord.closed) await closeSession(resumedRecord.acpxRecordId);
5813
+ options = {
5814
+ ...options,
5815
+ resumeSessionId: resumedRecord.acpSessionId
5816
+ };
5689
5817
  assertControlAuthority({ signal: options.signal });
5690
5818
  }
5691
5819
  }
@@ -5708,7 +5836,7 @@ async function createSessionWithClient(options) {
5708
5836
  try {
5709
5837
  const create = async () => {
5710
5838
  assertControlAuthority({ signal: options.signal });
5711
- const record = await createSessionRecordWithClient(client, options);
5839
+ const record = await createSessionRecordWithClient(client, options, resumedRecordId);
5712
5840
  assertControlAuthority({ signal: options.signal });
5713
5841
  return record;
5714
5842
  };
@@ -6190,14 +6318,25 @@ function createOwnedSessionControls(options) {
6190
6318
  },
6191
6319
  setSessionModel: async (modelId, deadline) => {
6192
6320
  const models = advertisedModelState(options.record.acpx);
6321
+ const resolvedModelId = resolveRequestedModelId({
6322
+ requestedModel: modelId,
6323
+ models,
6324
+ agentCommand: options.record.agentCommand
6325
+ });
6193
6326
  return await acceptControl(options, (authority) => options.client.setSessionModel(options.sessionId(), modelId, models, authority), (response) => {
6194
- options.record.acpx = applyModelSelection(options.record.acpx, modelId, response);
6327
+ options.record.acpx = applyModelSelection(options.record.acpx, modelId, response, resolvedModelId);
6195
6328
  }, deadline);
6196
6329
  },
6197
6330
  setSessionConfigOption: async (configId, value, deadline) => {
6198
6331
  const models = advertisedModelState(options.record.acpx);
6332
+ const { modelConfigId, resolvedValue } = resolveRequestedConfigOption({
6333
+ configId,
6334
+ value,
6335
+ models,
6336
+ agentCommand: options.record.agentCommand
6337
+ });
6199
6338
  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, models?.configId);
6339
+ options.record.acpx = applyConfigOptionSelection(options.record.acpx, configId, value, response, modelConfigId, resolvedValue);
6201
6340
  }, deadline);
6202
6341
  }
6203
6342
  };
@@ -6693,7 +6832,7 @@ async function applyPromptModelIfAdvertised(params) {
6693
6832
  authority: { signal: params.signal },
6694
6833
  onWarning: params.suppressWarnings ? void 0 : (message) => process.stderr.write(`[acpx] warning: ${message}\n`)
6695
6834
  });
6696
- if (result.applied) params.record.acpx = applyModelSelection(params.record.acpx, requestedModel, result.response);
6835
+ if (result.applied) params.record.acpx = applyModelSelection(params.record.acpx, requestedModel, result.response, result.resolvedModelId);
6697
6836
  }
6698
6837
  function jsonRpcIdKey(message) {
6699
6838
  if (!("id" in message)) return;
@@ -7245,8 +7384,10 @@ async function runOwnedSessionPrompt(options) {
7245
7384
  record.lastUsedAt = now;
7246
7385
  record.closed = false;
7247
7386
  record.closedAt = void 0;
7248
- record.protocolVersion = client.initializeResult?.protocolVersion;
7249
- record.agentCapabilities = client.initializeResult?.agentCapabilities;
7387
+ if (client.initializeResult) {
7388
+ record.protocolVersion = client.initializeResult.protocolVersion;
7389
+ record.agentCapabilities = client.initializeResult.agentCapabilities;
7390
+ }
7250
7391
  applyConversation(record, conversation);
7251
7392
  applyLifecycleSnapshotToRecord(record, client.getAgentLifecycleSnapshot());
7252
7393
  stopTotalTimer();
@@ -7256,15 +7397,20 @@ async function runOwnedSessionPrompt(options) {
7256
7397
  options.ownedSignal?.throwIfAborted();
7257
7398
  const { sessionId: activeSessionId, resumed, loadError } = await connectForPrompt();
7258
7399
  options.ownedSignal?.throwIfAborted();
7259
- await applyPromptModelIfAdvertised({
7260
- client,
7261
- sessionId: activeSessionId,
7262
- requestedModel: options.sessionOptions?.model,
7263
- record,
7264
- timeoutMs: options.timeoutMs,
7265
- suppressWarnings: options.suppressSdkConsoleErrors,
7266
- signal: options.ownedSignal
7267
- });
7400
+ try {
7401
+ await applyPromptModelIfAdvertised({
7402
+ client,
7403
+ sessionId: activeSessionId,
7404
+ requestedModel: options.sessionOptions?.model,
7405
+ record,
7406
+ timeoutMs: options.timeoutMs,
7407
+ suppressWarnings: options.suppressSdkConsoleErrors,
7408
+ signal: options.ownedSignal
7409
+ });
7410
+ } catch (error) {
7411
+ if (error instanceof TimeoutError) closeClientOnExit = true;
7412
+ throw error;
7413
+ }
7268
7414
  options.ownedSignal?.throwIfAborted();
7269
7415
  output.setContext({ sessionId: record.acpxRecordId });
7270
7416
  await liveCheckpoint.checkpoint();
@@ -7357,6 +7503,7 @@ async function runOnce(options, control) {
7357
7503
  let promptTurnActive = false;
7358
7504
  let promptTurnHadSideEffects = false;
7359
7505
  let controlState = {};
7506
+ let sawOwnedModelConfig = false;
7360
7507
  const acpErrors = new AcpErrorTracker();
7361
7508
  const client = new AcpClient({
7362
7509
  agentCommand: options.agentCommand,
@@ -7377,7 +7524,10 @@ async function runOnce(options, control) {
7377
7524
  acpErrors.observe(output, direction, message);
7378
7525
  },
7379
7526
  onSessionUpdate: (notification) => {
7380
- if (notification.update.sessionUpdate === "config_option_update") controlState = applyConfigOptionsToState(controlState, notification.update.configOptions);
7527
+ if (notification.update.sessionUpdate === "config_option_update" && client.hasReusableSession(notification.sessionId)) {
7528
+ controlState = applyConfigOptionsToState(controlState, notification.update.configOptions);
7529
+ sawOwnedModelConfig ||= controlState.model_control === "config_option";
7530
+ }
7381
7531
  if (promptTurnActive) promptTurnHadSideEffects = true;
7382
7532
  options.onSessionUpdate?.(notification);
7383
7533
  },
@@ -7393,6 +7543,11 @@ async function runOnce(options, control) {
7393
7543
  });
7394
7544
  const permissionStatsBefore = client.getPermissionStats();
7395
7545
  const closeOwnedClient = ownDirectClient(client, control?.signal);
7546
+ const initializeControlState = (createdSession) => {
7547
+ const configOptions = controlState.config_options ?? createdSession.configOptions ?? [];
7548
+ if (createdSession.models && !sawOwnedModelConfig) applyAdvertisedModelState(controlState, createdSession.models);
7549
+ controlState = applyConfigOptionsToState(controlState, configOptions);
7550
+ };
7396
7551
  const runExecPromptAttempt = async (sessionId) => {
7397
7552
  assertControlAuthority(authority);
7398
7553
  acpErrors.reset();
@@ -7425,23 +7580,28 @@ async function runOnce(options, control) {
7425
7580
  });
7426
7581
  assertControlAuthority(authority);
7427
7582
  const sessionId = createdSession.sessionId;
7428
- if (createdSession.models) applyAdvertisedModelState(controlState, createdSession.models);
7429
- controlState = applyConfigOptionsToState(controlState, createdSession.configOptions ?? []);
7583
+ initializeControlState(createdSession);
7430
7584
  const modelApplication = await applyRequestedModelIfAdvertised({
7431
7585
  client,
7432
7586
  sessionId,
7433
7587
  requestedModel: options.sessionOptions?.model,
7434
- models: createdSession.models,
7588
+ models: advertisedModelState(controlState),
7435
7589
  agentCommand: options.agentCommand,
7436
7590
  timeoutMs: options.timeoutMs,
7437
7591
  authority,
7438
7592
  onWarning: options.suppressSdkConsoleErrors ? void 0 : (message) => process.stderr.write(`[acpx] warning: ${message}\n`)
7439
7593
  });
7440
- if (modelApplication.applied) controlState = applyModelSelection(controlState, modelApplication.modelId, modelApplication.response);
7594
+ if (modelApplication.applied) controlState = applyModelSelection(controlState, modelApplication.modelId, modelApplication.response, modelApplication.resolvedModelId);
7441
7595
  for (const configOption of options.configOptions ?? []) {
7442
7596
  assertControlAuthority(authority);
7443
- const response = await withTimeout(client.setSessionConfigOption(sessionId, configOption.configId, configOption.value, advertisedModelState(controlState), authority), options.timeoutMs);
7444
- controlState = applyConfigOptionSelection(controlState, configOption.configId, configOption.value, response);
7597
+ const models = advertisedModelState(controlState);
7598
+ const { modelConfigId, resolvedValue } = resolveRequestedConfigOption({
7599
+ ...configOption,
7600
+ models,
7601
+ agentCommand: options.agentCommand
7602
+ });
7603
+ const response = await withTimeout(client.setSessionConfigOption(sessionId, configOption.configId, configOption.value, models, authority), options.timeoutMs);
7604
+ controlState = applyConfigOptionSelection(controlState, configOption.configId, configOption.value, response, modelConfigId, resolvedValue);
7445
7605
  }
7446
7606
  assertControlAuthority(authority);
7447
7607
  output.setContext({ sessionId });
@@ -7917,6 +8077,6 @@ async function sendSession(options) {
7917
8077
  }
7918
8078
  const queueOwnerRuntimeTestInternals = { queueOwnerExitIsFatal };
7919
8079
  //#endregion
7920
- export { isRequestedModelUnsupportedError as $, applyInitialModelSelection as A, reconcileAgentSessionId as B, setSessionModeOnOwner as C, connectAndLoadSession as D, withConnectedSession as E, persistSessionOptions as F, recordPromptSubmission as G, cloneSessionConversation as H, sessionOptionsFromRecord as I, advertisedModelState as J, recordSessionUpdate 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, createSessionConversation as U, cloneSessionAcpxState as V, recordClientOperation as W, REQUESTED_MODEL_UNSUPPORTED_ERROR_CODE as X, AcpClient as Y, REQUESTED_MODEL_UNSUPPORTED_REASONS as Z, cancelSessionPrompt as _, runQueuedTask as a, acquireSessionScope as at, setSessionConfigOption as b, LiveSessionCheckpoint as c, InterruptedError as ct, flushPerfMetricsCapture as d, withInterrupt as dt, getAcpxVersion as et, installPerfMetricsCapture as f, withTimeout as ft, listAgentSessions as g, ensureSession as h, runOnce as i, acquireSessionImport as it, applyModelSelection as j, applyConfigOptionsToRecord as k, runPromptTurn as l, TimeoutError as lt, createSessionWithClient as m, runSessionQueueOwner as n, DEFAULT_QUEUE_OWNER_TTL_MS as nt, sendSessionDirect as o, listSessionEvents as ot, createSession as p, trimConversationForRuntime as q, sendSession as r, normalizeQueueOwnerTtlMs as rt, DISCARD_OUTPUT_FORMATTER as s, isLegacyZedCodexAcpInvocation as st, queueOwnerRuntimeTestInternals as t, permissionModeSatisfies as tt, buildQueueOwnerArgOverride as u, assertControlAuthority as ut, closeSession as v, setSessionModel as w, setSessionConfigOptionOnOwner as x, sessionControlTestInternals as y, createInitialSessionRecord as z };
8080
+ 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
8081
 
7922
- //# sourceMappingURL=queue-owner-runtime-Dhr4gxNE.js.map
8082
+ //# sourceMappingURL=queue-owner-runtime-C0wIYowh.js.map