@moxt-ai/mobius 0.0.359 → 0.0.360

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 (103) hide show
  1. package/dist/cli.js +935 -490
  2. package/dist/cli.js.map +4 -4
  3. package/dist/engine/acp/adapter/agent-initialization.d.ts +2 -2
  4. package/dist/engine/acp/adapter/agent-initialization.d.ts.map +1 -1
  5. package/dist/engine/acp/adapter/agent-initialization.js.map +1 -1
  6. package/dist/engine/acp/adapter/claude/adapter.d.ts +21 -4
  7. package/dist/engine/acp/adapter/claude/adapter.d.ts.map +1 -1
  8. package/dist/engine/acp/adapter/claude/adapter.js +52 -15
  9. package/dist/engine/acp/adapter/claude/adapter.js.map +1 -1
  10. package/dist/engine/acp/adapter/codex/adapter.d.ts +22 -5
  11. package/dist/engine/acp/adapter/codex/adapter.d.ts.map +1 -1
  12. package/dist/engine/acp/adapter/codex/adapter.js +70 -20
  13. package/dist/engine/acp/adapter/codex/adapter.js.map +1 -1
  14. package/dist/engine/acp/adapter/configuration-changes.d.ts +25 -0
  15. package/dist/engine/acp/adapter/configuration-changes.d.ts.map +1 -0
  16. package/dist/engine/acp/adapter/configuration-changes.js +47 -0
  17. package/dist/engine/acp/adapter/configuration-changes.js.map +1 -0
  18. package/dist/engine/acp/adapter/execution-connections.d.ts +26 -0
  19. package/dist/engine/acp/adapter/execution-connections.d.ts.map +1 -0
  20. package/dist/engine/acp/adapter/{live-sessions.js → execution-connections.js} +92 -24
  21. package/dist/engine/acp/adapter/execution-connections.js.map +1 -0
  22. package/dist/engine/acp/adapter/lifecycle-output.d.ts +10 -0
  23. package/dist/engine/acp/adapter/lifecycle-output.d.ts.map +1 -0
  24. package/dist/engine/acp/adapter/lifecycle-output.js +26 -0
  25. package/dist/engine/acp/adapter/lifecycle-output.js.map +1 -0
  26. package/dist/engine/acp/adapter/native-session-lookup.d.ts +2 -2
  27. package/dist/engine/acp/adapter/native-session-lookup.d.ts.map +1 -1
  28. package/dist/engine/acp/adapter/native-session-lookup.js +4 -4
  29. package/dist/engine/acp/adapter/native-session-lookup.js.map +1 -1
  30. package/dist/engine/acp/adapter/pi/adapter.d.ts +21 -4
  31. package/dist/engine/acp/adapter/pi/adapter.d.ts.map +1 -1
  32. package/dist/engine/acp/adapter/pi/adapter.js +52 -15
  33. package/dist/engine/acp/adapter/pi/adapter.js.map +1 -1
  34. package/dist/engine/acp/adapter/query-processes.d.ts +6 -5
  35. package/dist/engine/acp/adapter/query-processes.d.ts.map +1 -1
  36. package/dist/engine/acp/adapter/query-processes.js +36 -36
  37. package/dist/engine/acp/adapter/query-processes.js.map +1 -1
  38. package/dist/engine/acp/adapter/query-scope.d.ts +8 -0
  39. package/dist/engine/acp/adapter/query-scope.d.ts.map +1 -0
  40. package/dist/engine/acp/adapter/query-scope.js +16 -0
  41. package/dist/engine/acp/adapter/query-scope.js.map +1 -0
  42. package/dist/engine/acp/adapter/query-session.d.ts +3 -4
  43. package/dist/engine/acp/adapter/query-session.d.ts.map +1 -1
  44. package/dist/engine/acp/adapter/query-session.js +26 -31
  45. package/dist/engine/acp/adapter/query-session.js.map +1 -1
  46. package/dist/engine/acp/adapter/session-events.d.ts +34 -6
  47. package/dist/engine/acp/adapter/session-events.d.ts.map +1 -1
  48. package/dist/engine/acp/adapter/session-events.js +95 -3
  49. package/dist/engine/acp/adapter/session-events.js.map +1 -1
  50. package/dist/engine/acp/content/content-externalizer.d.ts +1 -0
  51. package/dist/engine/acp/content/content-externalizer.d.ts.map +1 -1
  52. package/dist/engine/acp/content/content-externalizer.js.map +1 -1
  53. package/dist/engine/acp/native-history/preview-contract.d.ts +73 -16
  54. package/dist/engine/acp/native-history/preview-contract.d.ts.map +1 -1
  55. package/dist/engine/acp/protocol/session-config-protocol.d.ts +1 -0
  56. package/dist/engine/acp/protocol/session-config-protocol.d.ts.map +1 -1
  57. package/dist/engine/acp/protocol/session-config-protocol.js +1 -1
  58. package/dist/engine/acp/protocol/session-config-protocol.js.map +1 -1
  59. package/dist/engine/agent/runtime-agents.d.ts +4 -1
  60. package/dist/engine/agent/runtime-agents.d.ts.map +1 -1
  61. package/dist/engine/agent/runtime-agents.js +6 -4
  62. package/dist/engine/agent/runtime-agents.js.map +1 -1
  63. package/dist/engine/runtime/run.d.ts.map +1 -1
  64. package/dist/engine/runtime/run.js +6 -2
  65. package/dist/engine/runtime/run.js.map +1 -1
  66. package/dist/engine/session/api/session-api.d.ts +3 -0
  67. package/dist/engine/session/api/session-api.d.ts.map +1 -1
  68. package/dist/engine/session/api/session-api.js.map +1 -1
  69. package/dist/engine/session/live/agent-session-restore.d.ts +6 -16
  70. package/dist/engine/session/live/agent-session-restore.d.ts.map +1 -1
  71. package/dist/engine/session/live/agent-session.d.ts +7 -14
  72. package/dist/engine/session/live/agent-session.d.ts.map +1 -1
  73. package/dist/engine/session/live/agent-session.js +108 -87
  74. package/dist/engine/session/live/agent-session.js.map +1 -1
  75. package/dist/engine/session/live/session-restore.d.ts.map +1 -1
  76. package/dist/engine/session/live/session-restore.js +12 -35
  77. package/dist/engine/session/live/session-restore.js.map +1 -1
  78. package/dist/engine/session/manager/session-manager.d.ts.map +1 -1
  79. package/dist/engine/session/manager/session-manager.js +13 -5
  80. package/dist/engine/session/manager/session-manager.js.map +1 -1
  81. package/dist/engine/session/native/native-query.d.ts +5 -0
  82. package/dist/engine/session/native/native-query.d.ts.map +1 -0
  83. package/dist/engine/session/native/native-query.js +14 -0
  84. package/dist/engine/session/native/native-query.js.map +1 -0
  85. package/dist/engine/session/native/native-session-browser.d.ts.map +1 -1
  86. package/dist/engine/session/native/native-session-browser.js +27 -16
  87. package/dist/engine/session/native/native-session-browser.js.map +1 -1
  88. package/dist/engine/session/process/retained-agent-processes.d.ts +10 -10
  89. package/dist/engine/session/process/retained-agent-processes.d.ts.map +1 -1
  90. package/dist/engine/session/process/retained-agent-processes.js.map +1 -1
  91. package/dist/engine/session/prompt/execute-prompt.d.ts.map +1 -1
  92. package/dist/engine/session/prompt/execute-prompt.js +4 -1
  93. package/dist/engine/session/prompt/execute-prompt.js.map +1 -1
  94. package/dist/engine/util/branded-type.d.ts +4 -0
  95. package/dist/engine/util/branded-type.d.ts.map +1 -0
  96. package/dist/engine/util/branded-type.js +2 -0
  97. package/dist/engine/util/branded-type.js.map +1 -0
  98. package/dist/engine.js +874 -471
  99. package/dist/engine.js.map +4 -4
  100. package/package.json +1 -1
  101. package/dist/engine/acp/adapter/live-sessions.d.ts +0 -26
  102. package/dist/engine/acp/adapter/live-sessions.d.ts.map +0 -1
  103. package/dist/engine/acp/adapter/live-sessions.js.map +0 -1
package/dist/engine.js CHANGED
@@ -75873,9 +75873,25 @@ async function runCleanup(...actions) {
75873
75873
  }
75874
75874
  }
75875
75875
 
75876
- // src/engine/acp/adapter/live-sessions.ts
75876
+ // src/engine/acp/protocol/native-session.ts
75877
+ var path6 = external_exports.string().min(1).max(2048).refine((value) => !value.includes("\0"));
75878
+ var title = external_exports.string().transform((value) => value.slice(0, 500));
75879
+ var nativeSessionIdSchema = external_exports.string().regex(/^[a-zA-Z0-9][a-zA-Z0-9._:-]{0,255}$/);
75880
+ var nativeSessionInfoSchema = external_exports.object({
75881
+ sessionId: nativeSessionIdSchema,
75882
+ cwd: path6,
75883
+ additionalDirectories: external_exports.array(path6).max(16).default([]).readonly(),
75884
+ title: title.nullish(),
75885
+ updatedAt: external_exports.iso.datetime({ offset: true }).nullish()
75886
+ }).readonly();
75887
+ var nativeSessionPageSchema = external_exports.object({
75888
+ sessions: external_exports.array(nativeSessionInfoSchema).max(500).readonly(),
75889
+ nextCursor: external_exports.string().min(1).max(4096).nullish()
75890
+ }).readonly();
75891
+
75892
+ // src/engine/acp/adapter/execution-connections.ts
75877
75893
  import { isAbsolute as isAbsolute14, resolve as resolve13 } from "node:path";
75878
- import { methods as methods10 } from "@agentclientprotocol/sdk";
75894
+ import { methods as methods11 } from "@agentclientprotocol/sdk";
75879
75895
 
75880
75896
  // src/engine/acp/client/prompt-content.ts
75881
75897
  function validatePromptContent(options, capabilities) {
@@ -75933,22 +75949,6 @@ function buildPromptContent(options, capabilities) {
75933
75949
  return prompt;
75934
75950
  }
75935
75951
 
75936
- // src/engine/acp/protocol/native-session.ts
75937
- var path6 = external_exports.string().min(1).max(2048).refine((value) => !value.includes("\0"));
75938
- var title = external_exports.string().transform((value) => value.slice(0, 500));
75939
- var nativeSessionIdSchema = external_exports.string().regex(/^[a-zA-Z0-9][a-zA-Z0-9._:-]{0,255}$/);
75940
- var nativeSessionInfoSchema = external_exports.object({
75941
- sessionId: nativeSessionIdSchema,
75942
- cwd: path6,
75943
- additionalDirectories: external_exports.array(path6).max(16).default([]).readonly(),
75944
- title: title.nullish(),
75945
- updatedAt: external_exports.iso.datetime({ offset: true }).nullish()
75946
- }).readonly();
75947
- var nativeSessionPageSchema = external_exports.object({
75948
- sessions: external_exports.array(nativeSessionInfoSchema).max(500).readonly(),
75949
- nextCursor: external_exports.string().min(1).max(4096).nullish()
75950
- }).readonly();
75951
-
75952
75952
  // src/engine/acp/protocol/session-config-protocol.ts
75953
75953
  import { methods as methods9 } from "@agentclientprotocol/sdk";
75954
75954
  var MAXIMUM_CONFIG_OPTIONS = 100;
@@ -76261,6 +76261,101 @@ var AgentUpdateStream = class {
76261
76261
  };
76262
76262
  };
76263
76263
 
76264
+ // src/engine/acp/adapter/agent-initialization.ts
76265
+ import { methods as methods10, PROTOCOL_VERSION as PROTOCOL_VERSION3 } from "@agentclientprotocol/sdk";
76266
+ var RetryableAcpInitializationError = class extends AcpExecutionError {
76267
+ constructor(cause) {
76268
+ super("ACP agent initialization failed", { cause });
76269
+ this.name = "RetryableAcpInitializationError";
76270
+ }
76271
+ };
76272
+ async function validateAgentRuntime(agent, signal) {
76273
+ signal.throwIfAborted();
76274
+ const unchanged = await Promise.all(agent.runtimeExecutables.map((identity2) => revalidateExecutable(identity2)));
76275
+ signal.throwIfAborted();
76276
+ if (unchanged.some((result) => !result)) {
76277
+ throw new AcpExecutionError(
76278
+ "The local Agent runtime changed; restart Mobius before starting a new conversation",
76279
+ {},
76280
+ "agent_runtime_changed"
76281
+ );
76282
+ }
76283
+ }
76284
+ async function initializeAgentConnection(connection, agentId, verifiedVersion, signal) {
76285
+ await connection.race(connection.initialize(signal), "The Agent runtime exited during initialization", signal).catch((cause) => {
76286
+ signal.throwIfAborted();
76287
+ throw new RetryableAcpInitializationError(cause);
76288
+ });
76289
+ const initialized = await connection.race(
76290
+ connection.connection.agent.request(
76291
+ methods10.agent.initialize,
76292
+ {
76293
+ clientCapabilities: {
76294
+ elicitation: { form: {}, url: {} },
76295
+ plan: {},
76296
+ session: { compaction: {}, configOptions: { boolean: {} } }
76297
+ },
76298
+ clientInfo: { name: "mobius", version: "0.0.3" },
76299
+ protocolVersion: PROTOCOL_VERSION3
76300
+ },
76301
+ { cancellationSignal: signal }
76302
+ ),
76303
+ "ACP agent exited during initialization",
76304
+ signal
76305
+ ).catch((cause) => {
76306
+ signal.throwIfAborted();
76307
+ throw new RetryableAcpInitializationError(cause);
76308
+ });
76309
+ if (initialized.protocolVersion !== PROTOCOL_VERSION3) {
76310
+ throw new AcpExecutionError(
76311
+ "ACP agent selected an unsupported protocol version",
76312
+ {},
76313
+ "unsupported_acp_protocol"
76314
+ );
76315
+ }
76316
+ return {
76317
+ capabilities: normalizeAcpCapabilities(initialized),
76318
+ agentName: truncate(initialized.agentInfo?.title ?? initialized.agentInfo?.name ?? agentId, 255),
76319
+ agentVersion: truncate(
76320
+ verifiedVersion.length > 0 ? verifiedVersion : initialized.agentInfo?.version ?? "",
76321
+ 128
76322
+ )
76323
+ };
76324
+ }
76325
+
76326
+ // src/engine/acp/adapter/configuration-changes.ts
76327
+ function recordConfigurationOptions(changes, options) {
76328
+ const modes = options.filter((option) => option.category === "mode");
76329
+ const selection = modes.length > 0 ? { kind: "unchanged" } : changes.kind === "mode" ? { kind: "selected", modeId: changes.modeId } : changes.kind === "replacement" ? changes.selection : { kind: "unchanged" };
76330
+ return {
76331
+ kind: "replacement",
76332
+ options,
76333
+ modes: modes.length > 0 ? modes : changes.kind === "replacement" ? changes.modes : [],
76334
+ selection
76335
+ };
76336
+ }
76337
+ function recordConfigurationMode(changes, modeId) {
76338
+ return changes.kind === "replacement" ? { ...changes, selection: { kind: "selected", modeId } } : { kind: "mode", modeId };
76339
+ }
76340
+ function applyConfigurationMode(options, modeId) {
76341
+ return options.map((option) => option.category === "mode" ? { ...option, currentValue: modeId } : option);
76342
+ }
76343
+ function applyConfigurationChanges(base, changes) {
76344
+ switch (changes.kind) {
76345
+ case "unchanged":
76346
+ return base;
76347
+ case "mode":
76348
+ return applyConfigurationMode(base, changes.modeId);
76349
+ case "replacement": {
76350
+ const options = changes.options.some((option) => option.category === "mode") ? changes.options : [
76351
+ ...changes.modes.length > 0 ? changes.modes : base.filter((option) => option.category === "mode"),
76352
+ ...changes.options
76353
+ ].slice(0, MAXIMUM_CONFIG_OPTIONS);
76354
+ return changes.selection.kind === "selected" ? applyConfigurationMode(options, changes.selection.modeId) : options;
76355
+ }
76356
+ }
76357
+ }
76358
+
76264
76359
  // src/engine/acp/adapter/session-events.ts
76265
76360
  var AdapterSessionConnection = class {
76266
76361
  #connection;
@@ -76270,19 +76365,24 @@ var AdapterSessionConnection = class {
76270
76365
  #updates;
76271
76366
  #lifetime = new AbortController();
76272
76367
  #onClosed;
76368
+ #agent;
76369
+ #state = { kind: "uninitialized" };
76370
+ #initialization = {
76371
+ kind: "not-started"
76372
+ };
76273
76373
  events;
76274
76374
  constructor(options, externalizer, normalizeEvent, onClosed = () => void 0) {
76375
+ this.#agent = options.agent;
76275
76376
  this.#onClosed = onClosed;
76276
76377
  this.#onBackgroundActivity = options.onBackgroundActivity ?? (() => {
76277
76378
  });
76278
- const protocol = sessionConfigProtocolForAgent(options.agent.id);
76279
76379
  this.#updates = new AgentUpdateStream(async (notification) => {
76280
76380
  this.#lifetime.signal.throwIfAborted();
76281
76381
  if (notification.sessionId !== this.#updates.sessionId()) {
76282
76382
  throw new AcpExecutionError("ACP agent referenced an unknown session", {}, "invalid_agent_session");
76283
76383
  }
76284
76384
  const signal = AbortSignal.any([this.#lifetime.signal, AbortSignal.timeout(3e4)]);
76285
- const externalized = await externalizer.update(options.sessionId(), notification.update, signal);
76385
+ const externalized = options.externalizeUpdate === void 0 ? await externalizer.update(notification.sessionId, notification.update, signal) : await options.externalizeUpdate(notification.update, signal);
76286
76386
  signal.throwIfAborted();
76287
76387
  const update = externalized.agent;
76288
76388
  for (const eventUpdate of externalized.events) {
@@ -76308,13 +76408,15 @@ var AdapterSessionConnection = class {
76308
76408
  };
76309
76409
  break;
76310
76410
  case "config_option_update":
76411
+ this.#applyConfigurationUpdate(update.configOptions);
76311
76412
  event = {
76312
76413
  kind: "configuration",
76313
76414
  payload,
76314
- configOptions: protocol.normalizeUpdate(options.configOptions(), update.configOptions)
76415
+ configOptions: this.snapshot().configOptions
76315
76416
  };
76316
76417
  break;
76317
76418
  case "current_mode_update":
76419
+ this.#applyModeUpdate(update.currentModeId);
76318
76420
  event = { kind: "mode", payload, modeId: update.currentModeId };
76319
76421
  break;
76320
76422
  case "session_info_update": {
@@ -76386,10 +76488,92 @@ var AdapterSessionConnection = class {
76386
76488
  get termination() {
76387
76489
  return this.#connection.termination;
76388
76490
  }
76491
+ #ready = () => {
76492
+ const state = this.#state;
76493
+ if (state.kind !== "ready") {
76494
+ throw new AcpExecutionError(
76495
+ "The Agent session is not initialized or has closed",
76496
+ {},
76497
+ "invalid_agent_session"
76498
+ );
76499
+ }
76500
+ return state;
76501
+ };
76502
+ snapshot = () => this.#ready().snapshot;
76503
+ beginStateChange = () => {
76504
+ const state = this.#ready();
76505
+ if (state.operation.kind !== "idle") {
76506
+ throw new AcpExecutionError("Another session configuration operation is running", {}, "session_busy");
76507
+ }
76508
+ this.#state = { ...state, operation: { kind: "pending", changes: { kind: "unchanged" } } };
76509
+ };
76510
+ cancelStateChange = () => {
76511
+ if (this.#state.kind === "ready") {
76512
+ this.#state = { ...this.#state, operation: { kind: "idle" } };
76513
+ }
76514
+ };
76515
+ commitConfiguration = (options) => {
76516
+ const state = this.#ready();
76517
+ if (state.operation.kind !== "pending") {
76518
+ throw new AcpExecutionError("No session configuration operation is running", {}, "invalid_agent_session");
76519
+ }
76520
+ const configOptions = applyConfigurationChanges(options, state.operation.changes);
76521
+ this.#state = { ...state, snapshot: { ...state.snapshot, configOptions }, operation: { kind: "idle" } };
76522
+ return configOptions;
76523
+ };
76524
+ commitLifecycle = (response) => {
76525
+ const state = this.#ready();
76526
+ const capabilities = restrictAcpSessionCapabilities(state.snapshot.capabilities, response);
76527
+ this.commitConfiguration(sessionConfigProtocolForAgent(this.#agent.id).normalizeLifecycle(response));
76528
+ this.#state = { ...this.#ready(), snapshot: { capabilities, configOptions: this.snapshot().configOptions } };
76529
+ return this.snapshot();
76530
+ };
76531
+ #applyConfigurationUpdate = (value) => {
76532
+ const state = this.#ready();
76533
+ const protocol = sessionConfigProtocolForAgent(this.#agent.id);
76534
+ const configOptions = protocol.normalizeUpdate(state.snapshot.configOptions, value);
76535
+ const operation = state.operation.kind === "pending" ? {
76536
+ kind: "pending",
76537
+ changes: recordConfigurationOptions(state.operation.changes, protocol.normalizeUpdate([], value))
76538
+ } : state.operation;
76539
+ this.#state = { ...state, snapshot: { ...state.snapshot, configOptions }, operation };
76540
+ };
76541
+ #applyModeUpdate = (modeId) => {
76542
+ const state = this.#ready();
76543
+ const operation = state.operation.kind === "pending" ? { kind: "pending", changes: recordConfigurationMode(state.operation.changes, modeId) } : state.operation;
76544
+ this.#state = {
76545
+ ...state,
76546
+ snapshot: {
76547
+ ...state.snapshot,
76548
+ configOptions: applyConfigurationMode(state.snapshot.configOptions, modeId)
76549
+ },
76550
+ operation
76551
+ };
76552
+ };
76389
76553
  initialize = (signal) => this.#connection.initialize(signal);
76554
+ initializeAgent = (signal) => {
76555
+ if (this.#initialization.kind === "not-started") {
76556
+ this.#initialization = {
76557
+ kind: "started",
76558
+ result: initializeAgentConnection(this, this.#agent.id, this.#agent.agentVersion, signal).then(
76559
+ (agent) => {
76560
+ this.#lifetime.signal.throwIfAborted();
76561
+ this.#state = {
76562
+ kind: "ready",
76563
+ snapshot: { capabilities: agent.capabilities, configOptions: [] },
76564
+ operation: { kind: "idle" }
76565
+ };
76566
+ return agent;
76567
+ }
76568
+ )
76569
+ };
76570
+ }
76571
+ return this.#initialization.result;
76572
+ };
76390
76573
  agentSettingsModelEffort = () => this.#connection.agentSettingsModelEffort();
76391
76574
  race = (operation, exitMessage, signal) => this.#connection.race(operation, exitMessage, signal);
76392
76575
  closeProcess = async () => {
76576
+ this.#state = { kind: "closed" };
76393
76577
  this.#lifetime.abort(new DOMException("The adapter event subscription closed", "AbortError"));
76394
76578
  try {
76395
76579
  await this.#connection.closeProcess();
@@ -76435,14 +76619,14 @@ var AcpSessionConnector = class {
76435
76619
  };
76436
76620
  };
76437
76621
 
76438
- // src/engine/acp/adapter/live-sessions.ts
76622
+ // src/engine/acp/adapter/execution-connections.ts
76439
76623
  var absolutePathSchema = external_exports.string().min(1).refine(isAbsolute14);
76440
76624
  var targetSchema = external_exports.object({
76441
76625
  nativeSessionId: nativeSessionIdSchema,
76442
76626
  cwd: absolutePathSchema,
76443
76627
  additionalDirectories: external_exports.array(absolutePathSchema)
76444
76628
  });
76445
- var AcpLiveSessions = class {
76629
+ var AcpExecutionConnections = class {
76446
76630
  #sessions = /* @__PURE__ */ new Set();
76447
76631
  #externalizer;
76448
76632
  #normalizeEvent;
@@ -76450,16 +76634,72 @@ var AcpLiveSessions = class {
76450
76634
  this.#externalizer = externalizer;
76451
76635
  this.#normalizeEvent = normalizeEvent;
76452
76636
  }
76453
- connectSession = (scope) => {
76637
+ acquire = (params) => {
76638
+ params.signal.throwIfAborted();
76639
+ const existing = [...this.#sessions].find(
76640
+ ({ subscriber }) => subscriber.onSessionEvent === params.onSessionEvent
76641
+ );
76642
+ if (existing !== void 0) {
76643
+ if (existing.scope.agent !== params.scope.agent || existing.scope.cwd !== params.scope.cwd || !arraysEqual(existing.scope.additionalDirectories, params.scope.additionalDirectories)) {
76644
+ throw new AcpExecutionError(
76645
+ "The agent or workspace cannot change after a conversation has started",
76646
+ {},
76647
+ "session_identity_mismatch"
76648
+ );
76649
+ }
76650
+ return existing;
76651
+ }
76454
76652
  const connection = new AdapterSessionConnection(
76455
- scope,
76653
+ {
76654
+ agent: params.scope.agent,
76655
+ cwd: params.scope.cwd,
76656
+ ...params.scope.externalizeUpdate === void 0 ? {} : { externalizeUpdate: params.scope.externalizeUpdate },
76657
+ onEvent: (event) => params.onSessionEvent(connection.events.sessionId(), event),
76658
+ ...params.onBackgroundActivity === void 0 ? {} : { onBackgroundActivity: params.onBackgroundActivity },
76659
+ interactions: params.interactions
76660
+ },
76456
76661
  this.#externalizer,
76457
76662
  this.#normalizeEvent,
76458
76663
  () => this.#sessions.delete(session)
76459
76664
  );
76460
- const session = { connection, scope };
76665
+ const session = { connection, scope: params.scope, subscriber: params };
76461
76666
  this.#sessions.add(session);
76462
- return connection;
76667
+ return session;
76668
+ };
76669
+ /** Resource scope only: the concrete adapter supplies the protocol operation. */
76670
+ withConnection = async (params, operation) => {
76671
+ const signal = AbortSignal.any([params.signal, AbortSignal.timeout(6e4)]);
76672
+ signal.throwIfAborted();
76673
+ const session = this.acquire(params);
76674
+ const wasBound = session.connection.events.sessionId().length > 0;
76675
+ try {
76676
+ await session.connection.initializeAgent(signal);
76677
+ session.connection.beginStateChange();
76678
+ try {
76679
+ const result = await operation(session, signal);
76680
+ signal.throwIfAborted();
76681
+ return result;
76682
+ } catch (cause) {
76683
+ session.connection.cancelStateChange();
76684
+ throw cause;
76685
+ }
76686
+ } catch (cause) {
76687
+ if (!wasBound) {
76688
+ await session.connection.closeProcess();
76689
+ }
76690
+ throw cause;
76691
+ }
76692
+ };
76693
+ bind = (session, nativeSessionId) => {
76694
+ const existing = this.#find({
76695
+ nativeSessionId,
76696
+ cwd: session.scope.cwd,
76697
+ additionalDirectories: session.scope.additionalDirectories
76698
+ });
76699
+ if (existing !== void 0 && existing !== session) {
76700
+ throw new AcpExecutionError("Another writer is using this native session", {}, "session_busy");
76701
+ }
76702
+ session.connection.events.select(nativeSessionId);
76463
76703
  };
76464
76704
  #find = (target) => {
76465
76705
  const decoded = targetSchema.safeParse(target);
@@ -76488,12 +76728,12 @@ var AcpLiveSessions = class {
76488
76728
  }
76489
76729
  return session;
76490
76730
  };
76491
- cancel = async (target, signal) => {
76731
+ cancel = async ({ signal, ...target }) => {
76492
76732
  const bounded = AbortSignal.any([signal, AbortSignal.timeout(3e4)]);
76493
76733
  bounded.throwIfAborted();
76494
76734
  const { connection } = this.#resolve(target);
76495
76735
  await connection.race(
76496
- connection.connection.agent.notify(methods10.agent.session.cancel, {
76736
+ connection.connection.agent.notify(methods11.agent.session.cancel, {
76497
76737
  sessionId: connection.events.sessionId()
76498
76738
  }),
76499
76739
  "ACP agent exited while cancelling a prompt",
@@ -76501,19 +76741,19 @@ var AcpLiveSessions = class {
76501
76741
  );
76502
76742
  return "retained";
76503
76743
  };
76504
- closeSession = async (target, signal) => {
76744
+ closeSession = async ({ signal, ...target }) => {
76505
76745
  const session = this.#find(target);
76506
76746
  if (session === void 0) {
76507
76747
  signal.throwIfAborted();
76508
76748
  return;
76509
76749
  }
76510
- const { connection, scope } = session;
76750
+ const { connection } = session;
76511
76751
  try {
76512
76752
  signal.throwIfAborted();
76513
- if (scope.capabilities().closeSession) {
76753
+ if (connection.snapshot().capabilities.closeSession) {
76514
76754
  try {
76515
76755
  await connection.connection.agent.request(
76516
- methods10.agent.session.close,
76756
+ methods11.agent.session.close,
76517
76757
  { sessionId: connection.events.sessionId() },
76518
76758
  { cancellationSignal: AbortSignal.any([signal, AbortSignal.timeout(1e3)]) }
76519
76759
  );
@@ -76526,13 +76766,20 @@ var AcpLiveSessions = class {
76526
76766
  }
76527
76767
  signal.throwIfAborted();
76528
76768
  };
76529
- prompt = async (target, content, signal) => {
76769
+ releaseSession = async ({ signal, ...target }) => {
76770
+ const session = this.#find(target);
76771
+ if (session !== void 0) {
76772
+ await session.connection.closeProcess();
76773
+ }
76774
+ signal.throwIfAborted();
76775
+ };
76776
+ prompt = async ({ content, signal, ...target }) => {
76530
76777
  signal.throwIfAborted();
76531
- const { connection, scope } = this.#resolve(target);
76532
- const prompt = buildPromptContent(content, scope.capabilities());
76778
+ const { connection } = this.#resolve(target);
76779
+ const prompt = buildPromptContent(content, connection.snapshot().capabilities);
76533
76780
  const response = await connection.race(
76534
76781
  connection.connection.agent.request(
76535
- methods10.agent.session.prompt,
76782
+ methods11.agent.session.prompt,
76536
76783
  { prompt, sessionId: target.nativeSessionId },
76537
76784
  { cancellationSignal: signal }
76538
76785
  ),
@@ -76559,10 +76806,10 @@ var AcpLiveSessions = class {
76559
76806
  );
76560
76807
  }
76561
76808
  };
76562
- steer = async (target, content, signal) => {
76809
+ steer = async ({ content, signal, ...target }) => {
76563
76810
  signal.throwIfAborted();
76564
- const { connection, scope } = this.#resolve(target);
76565
- if (!scope.capabilities().steering) {
76811
+ const { connection } = this.#resolve(target);
76812
+ if (!connection.snapshot().capabilities.steering) {
76566
76813
  throw new AcpExecutionError(
76567
76814
  "The selected agent does not support mid-turn steering",
76568
76815
  {},
@@ -76574,7 +76821,7 @@ var AcpLiveSessions = class {
76574
76821
  "_session/steering",
76575
76822
  {
76576
76823
  _meta: { steering: { idleBehavior: "promptRequired" } },
76577
- prompt: buildPromptContent(content, scope.capabilities()),
76824
+ prompt: buildPromptContent(content, connection.snapshot().capabilities),
76578
76825
  sessionId: target.nativeSessionId
76579
76826
  },
76580
76827
  { cancellationSignal: signal }
@@ -76604,14 +76851,14 @@ var AcpLiveSessions = class {
76604
76851
  "acp_invalid_steering_response"
76605
76852
  );
76606
76853
  };
76607
- renameSession = async (target, title2, signal) => {
76854
+ renameSession = async ({ title: title2, signal, ...target }) => {
76608
76855
  signal.throwIfAborted();
76609
- const { connection, scope } = this.#resolve(target);
76856
+ const { connection } = this.#resolve(target);
76610
76857
  const normalized = truncate(title2, 500);
76611
76858
  if (normalized.length === 0) {
76612
76859
  throw new AcpExecutionError("The Session title cannot be empty", {}, "invalid_session_title");
76613
76860
  }
76614
- if (!scope.capabilities().renameSession) {
76861
+ if (!connection.snapshot().capabilities.renameSession) {
76615
76862
  return { nativeRenameApplied: false };
76616
76863
  }
76617
76864
  try {
@@ -76637,10 +76884,14 @@ var AcpLiveSessions = class {
76637
76884
  }
76638
76885
  return { nativeRenameApplied: true };
76639
76886
  };
76640
- configureSession = async (target, selection, signal) => {
76887
+ configureSession = async ({
76888
+ selection,
76889
+ signal,
76890
+ ...target
76891
+ }) => {
76641
76892
  signal.throwIfAborted();
76642
76893
  const { connection, scope } = this.#resolve(target);
76643
- const current = scope.configOptions();
76894
+ const current = connection.snapshot().configOptions;
76644
76895
  const existing = current.find((option) => option.id === selection.configId);
76645
76896
  if (existing === void 0 || existing.type !== selection.type || existing.type === "select" && existing.values.length < 2) {
76646
76897
  throw new AcpExecutionError(
@@ -76656,6 +76907,7 @@ var AcpLiveSessions = class {
76656
76907
  existing.values.map((entry) => entry.value)
76657
76908
  );
76658
76909
  }
76910
+ connection.beginStateChange();
76659
76911
  try {
76660
76912
  const configured = await sessionConfigProtocolForAgent(scope.agent.id).configure(
76661
76913
  current,
@@ -76683,8 +76935,9 @@ var AcpLiveSessions = class {
76683
76935
  );
76684
76936
  }
76685
76937
  await connection.events.drained();
76686
- return configured;
76938
+ return connection.commitConfiguration(configured);
76687
76939
  } catch (error62) {
76940
+ connection.cancelStateChange();
76688
76941
  if (error62 instanceof SessionConfigProtocolError) {
76689
76942
  throw new AcpExecutionError(error62.message, { cause: error62 }, error62.code);
76690
76943
  }
@@ -76703,6 +76956,38 @@ var AcpLiveSessions = class {
76703
76956
  };
76704
76957
  };
76705
76958
 
76959
+ // src/engine/acp/adapter/lifecycle-output.ts
76960
+ function sessionWorkspace(scope) {
76961
+ return { cwd: scope.cwd, additionalDirectories: [...scope.additionalDirectories], mcpServers: [] };
76962
+ }
76963
+ function createdNativeSessionId(response) {
76964
+ const decoded = external_exports.object({ sessionId: nativeSessionIdSchema }).safeParse(response);
76965
+ if (!decoded.success) {
76966
+ throw new AcpExecutionError(
76967
+ "The Agent returned an invalid native session",
76968
+ { cause: decoded.error },
76969
+ "invalid_native_session_response"
76970
+ );
76971
+ }
76972
+ return decoded.data.sessionId;
76973
+ }
76974
+ async function normalizeOpenedSession(session, nativeSessionId, response, signal) {
76975
+ await session.connection.race(
76976
+ session.connection.events.drained(),
76977
+ "ACP agent exited while opening a session",
76978
+ signal
76979
+ );
76980
+ signal.throwIfAborted();
76981
+ const initialized = await session.connection.initializeAgent(signal);
76982
+ return {
76983
+ nativeSessionId,
76984
+ agentName: initialized.agentName,
76985
+ agentVersion: initialized.agentVersion,
76986
+ agentSettingsModelEffort: session.connection.agentSettingsModelEffort(),
76987
+ ...session.connection.commitLifecycle(response)
76988
+ };
76989
+ }
76990
+
76706
76991
  // src/engine/acp/adapter/native-session-lookup.ts
76707
76992
  var lookupSchema = external_exports.object({
76708
76993
  nativeSessionId: nativeSessionIdSchema,
@@ -76711,7 +76996,7 @@ var lookupSchema = external_exports.object({
76711
76996
  maximumEntries: external_exports.number().int().positive().nullable()
76712
76997
  })
76713
76998
  });
76714
- async function findNativeSession(list, cwd, nativeSessionId, budget, signal) {
76999
+ async function findNativeSession(list, query, nativeSessionId, budget) {
76715
77000
  const decoded = lookupSchema.safeParse({ nativeSessionId, budget });
76716
77001
  if (!decoded.success) {
76717
77002
  throw new AcpExecutionError(
@@ -76725,9 +77010,9 @@ async function findNativeSession(list, cwd, nativeSessionId, budget, signal) {
76725
77010
  let inspected = 0;
76726
77011
  const visited = /* @__PURE__ */ new Set();
76727
77012
  for (let pageNumber = 0; pageNumber < limits.maximumPages; pageNumber += 1) {
76728
- signal.throwIfAborted();
76729
- const page = await list(cwd, cursor, signal);
76730
- signal.throwIfAborted();
77013
+ query.signal.throwIfAborted();
77014
+ const page = await list({ query, cursor });
77015
+ query.signal.throwIfAborted();
76731
77016
  inspected += page.sessions.length;
76732
77017
  const found = page.sessions.find((session) => session.sessionId === decoded.data.nativeSessionId);
76733
77018
  if (found !== void 0) {
@@ -76749,9 +77034,6 @@ async function findNativeSession(list, cwd, nativeSessionId, budget, signal) {
76749
77034
  throw new AcpExecutionError("The native session was not found", {}, "native_session_not_found");
76750
77035
  }
76751
77036
 
76752
- // src/engine/acp/adapter/query-processes.ts
76753
- import { randomUUID as randomUUID14 } from "node:crypto";
76754
-
76755
77037
  // src/engine/session/history/session-event-store.ts
76756
77038
  import { randomUUID as randomUUID13 } from "node:crypto";
76757
77039
 
@@ -77393,112 +77675,53 @@ var RetainedAgentProcesses = class {
77393
77675
  };
77394
77676
  };
77395
77677
 
77396
- // src/engine/acp/adapter/query-session.ts
77397
- import { methods as methods12 } from "@agentclientprotocol/sdk";
77398
-
77399
- // src/engine/acp/adapter/agent-initialization.ts
77400
- import { methods as methods11, PROTOCOL_VERSION as PROTOCOL_VERSION3 } from "@agentclientprotocol/sdk";
77401
- var RetryableAcpInitializationError = class extends AcpExecutionError {
77402
- constructor(cause) {
77403
- super("ACP agent initialization failed", { cause });
77404
- this.name = "RetryableAcpInitializationError";
77405
- }
77406
- };
77407
- async function validateAgentRuntime(agent, signal) {
77408
- signal.throwIfAborted();
77409
- const unchanged = await Promise.all(agent.runtimeExecutables.map((identity2) => revalidateExecutable(identity2)));
77410
- signal.throwIfAborted();
77411
- if (unchanged.some((result) => !result)) {
77412
- throw new AcpExecutionError(
77413
- "The local Agent runtime changed; restart Mobius before starting a new conversation",
77414
- {},
77415
- "agent_runtime_changed"
77416
- );
77417
- }
77678
+ // src/engine/acp/adapter/query-scope.ts
77679
+ var queryKeySchema = external_exports.string().brand();
77680
+ var previewKeySchema = external_exports.string().brand();
77681
+ function nativeSessionQueryKey(query) {
77682
+ return queryKeySchema.parse(
77683
+ JSON.stringify([
77684
+ query.agent.id,
77685
+ query.cwd,
77686
+ query.additionalDirectories,
77687
+ Object.entries(query.agent.environment).sort(([left], [right]) => left.localeCompare(right))
77688
+ ])
77689
+ );
77418
77690
  }
77419
- async function initializeAgentConnection(connection, agentId, verifiedVersion, signal) {
77420
- await connection.race(connection.initialize(signal), "The Agent runtime exited during initialization", signal).catch((cause) => {
77421
- signal.throwIfAborted();
77422
- throw new RetryableAcpInitializationError(cause);
77423
- });
77424
- const initialized = await connection.race(
77425
- connection.connection.agent.request(
77426
- methods11.agent.initialize,
77427
- {
77428
- clientCapabilities: {
77429
- elicitation: { form: {}, url: {} },
77430
- plan: {},
77431
- session: { compaction: {}, configOptions: { boolean: {} } }
77432
- },
77433
- clientInfo: { name: "mobius", version: "0.0.3" },
77434
- protocolVersion: PROTOCOL_VERSION3
77435
- },
77436
- { cancellationSignal: signal }
77437
- ),
77438
- "ACP agent exited during initialization",
77439
- signal
77440
- ).catch((cause) => {
77441
- signal.throwIfAborted();
77442
- throw new RetryableAcpInitializationError(cause);
77443
- });
77444
- if (initialized.protocolVersion !== PROTOCOL_VERSION3) {
77445
- throw new AcpExecutionError(
77446
- "ACP agent selected an unsupported protocol version",
77447
- {},
77448
- "unsupported_acp_protocol"
77449
- );
77450
- }
77451
- return {
77452
- capabilities: normalizeAcpCapabilities(initialized),
77453
- agentName: truncate(initialized.agentInfo?.title ?? initialized.agentInfo?.name ?? agentId, 255),
77454
- agentVersion: truncate(
77455
- verifiedVersion.length > 0 ? verifiedVersion : initialized.agentInfo?.version ?? "",
77456
- 128
77457
- )
77458
- };
77691
+ function nativeSessionPreviewKey(queryKey, nativeSessionId) {
77692
+ return previewKeySchema.parse(JSON.stringify([queryKey, nativeSessionId]));
77459
77693
  }
77460
77694
 
77461
77695
  // src/engine/acp/adapter/query-session.ts
77696
+ import { methods as methods12 } from "@agentclientprotocol/sdk";
77462
77697
  var AcpQuerySession = class _AcpQuerySession {
77463
- #cwd;
77464
- #sessionId;
77698
+ #options;
77465
77699
  #events;
77466
77700
  #connection;
77467
77701
  #lifecycle = { kind: "open" };
77468
- #capabilities = unsupportedSessionCapabilities();
77469
- #configOptions = [];
77470
- constructor(agent, cwd, sessionId, events, connector) {
77471
- this.#cwd = cwd;
77472
- this.#sessionId = sessionId;
77702
+ #eventScope = crypto.randomUUID();
77703
+ constructor(options, events, connector) {
77704
+ this.#options = options;
77473
77705
  this.#events = events;
77474
77706
  this.#connection = connector.connectQuerySession({
77475
- agent,
77476
- cwd,
77477
- sessionId: () => sessionId,
77478
- configOptions: () => this.#configOptions,
77707
+ agent: options.agent,
77708
+ cwd: options.cwd,
77709
+ ...options.externalizeUpdate === void 0 ? {} : { externalizeUpdate: options.externalizeUpdate },
77479
77710
  onEvent: async (event) => {
77480
- this.#events.append(sessionId, { type: "acp", payload: event.payload });
77481
- if (event.kind === "configuration") {
77482
- this.#configOptions = event.configOptions;
77483
- }
77711
+ this.#events.append(this.#eventScope, { type: "acp", payload: event.payload });
77484
77712
  }
77485
77713
  });
77486
77714
  void this.#connection.termination.then(() => {
77487
77715
  this.#lifecycle = { kind: "terminated" };
77488
77716
  });
77489
77717
  }
77490
- static start = async (agent, cwd, sessionId, events, connector, signal) => {
77718
+ static start = async (options, events, connector) => {
77719
+ const { agent, signal } = options;
77491
77720
  for (let attempt = 1; attempt <= 2; attempt += 1) {
77492
77721
  await validateAgentRuntime(agent, signal);
77493
- const runtime = new _AcpQuerySession(agent, cwd, sessionId, events, connector);
77722
+ const runtime = new _AcpQuerySession(options, events, connector);
77494
77723
  try {
77495
- const initialized = await initializeAgentConnection(
77496
- runtime.#connection,
77497
- agent.id,
77498
- agent.agentVersion,
77499
- signal
77500
- );
77501
- runtime.#capabilities = initialized.capabilities;
77724
+ await runtime.#connection.initializeAgent(options.signal);
77502
77725
  return runtime;
77503
77726
  } catch (error62) {
77504
77727
  await runtime.closeProcess();
@@ -77515,7 +77738,7 @@ var AcpQuerySession = class _AcpQuerySession {
77515
77738
  }
77516
77739
  throw new AcpExecutionError("ACP agent initialization failed");
77517
77740
  };
77518
- capabilities = () => this.#capabilities;
77741
+ capabilities = () => this.#connection.snapshot().capabilities;
77519
77742
  hasTerminated = () => {
77520
77743
  switch (this.#lifecycle.kind) {
77521
77744
  case "open":
@@ -77529,7 +77752,7 @@ var AcpQuerySession = class _AcpQuerySession {
77529
77752
  }
77530
77753
  };
77531
77754
  listNativeSessions = async (cursor, signal) => {
77532
- if (!this.#capabilities.listSessions) {
77755
+ if (!this.capabilities().listSessions) {
77533
77756
  throw new AcpExecutionError(
77534
77757
  "This Agent does not support native session listing",
77535
77758
  {},
@@ -77553,22 +77776,24 @@ var AcpQuerySession = class _AcpQuerySession {
77553
77776
  }
77554
77777
  return decoded.data;
77555
77778
  };
77556
- previewEvents = async (nativeSessionId, eventLimit, additionalDirectories, signal) => {
77557
- if (!this.#capabilities.loadSession) {
77779
+ previewEvents = async (nativeSessionId, eventLimit, signal) => {
77780
+ if (!this.capabilities().loadSession) {
77558
77781
  throw new AcpExecutionError(
77559
77782
  "This Agent restores context but does not provide message history.",
77560
77783
  {},
77561
77784
  "native_history_unsupported"
77562
77785
  );
77563
77786
  }
77564
- this.#events.reset(this.#sessionId);
77787
+ this.#eventScope = nativeSessionId;
77788
+ this.#events.reset(nativeSessionId);
77565
77789
  this.#connection.events.select(nativeSessionId);
77566
- await this.#connection.race(
77790
+ this.#connection.beginStateChange();
77791
+ const response = await this.#connection.race(
77567
77792
  this.#connection.connection.agent.request(
77568
77793
  methods12.agent.session.load,
77569
77794
  {
77570
- additionalDirectories: [...additionalDirectories],
77571
- cwd: this.#cwd,
77795
+ additionalDirectories: [...this.#options.additionalDirectories],
77796
+ cwd: this.#options.cwd,
77572
77797
  mcpServers: [],
77573
77798
  sessionId: nativeSessionId
77574
77799
  },
@@ -77579,10 +77804,11 @@ var AcpQuerySession = class _AcpQuerySession {
77579
77804
  );
77580
77805
  await this.#connection.events.drained();
77581
77806
  signal.throwIfAborted();
77582
- return this.#events.page(this.#sessionId, eventLimit, null);
77807
+ this.#connection.commitLifecycle(response);
77808
+ return this.#events.page(nativeSessionId, eventLimit, null);
77583
77809
  };
77584
77810
  closeProcess = async () => await this.#connection.closeProcess();
77585
- discardEvents = () => this.#events.remove(this.#sessionId);
77811
+ discardEvents = () => this.#events.remove(this.#eventScope);
77586
77812
  };
77587
77813
 
77588
77814
  // src/engine/acp/adapter/query-processes.ts
@@ -77601,45 +77827,46 @@ var AgentQueryProcesses = class {
77601
77827
  refreshAgent = (agent) => {
77602
77828
  this.#agent = agent;
77603
77829
  };
77604
- retire = async (readers, cwd, runtime) => {
77605
- readers.detach(cwd, runtime);
77830
+ retire = async (readers, key, runtime) => {
77831
+ readers.detach(key, runtime);
77606
77832
  try {
77607
77833
  await this.#processes.retire(runtime, () => runtime.closeProcess());
77608
77834
  } finally {
77609
77835
  runtime.discardEvents();
77610
77836
  }
77611
77837
  };
77612
- async #ensure(agent, readers, cwd, signal) {
77613
- signal.throwIfAborted();
77614
- const pending = readers.pending(cwd);
77838
+ async #ensure(readers, query) {
77839
+ query.signal.throwIfAborted();
77840
+ const key = nativeSessionQueryKey(query);
77841
+ const pending = readers.pending(key);
77615
77842
  if (pending !== void 0) {
77616
- return await waitForSharedOperation(pending, signal);
77843
+ return await waitForSharedOperation(pending, query.signal);
77617
77844
  }
77618
- const existing = readers.get(cwd);
77845
+ const existing = readers.get(key);
77619
77846
  if (existing !== void 0 && !existing.hasTerminated()) {
77620
- readers.touch(cwd, existing);
77847
+ readers.touch(key, existing);
77621
77848
  return existing;
77622
77849
  }
77623
- return await readers.prepare(cwd, async () => {
77850
+ return await readers.prepare(key, async () => {
77624
77851
  if (existing !== void 0) {
77625
- await this.retire(readers, cwd, existing);
77852
+ await this.retire(readers, key, existing);
77626
77853
  }
77627
- const readerId = randomUUID14();
77628
77854
  const runtime = await this.#processes.startRetained(
77629
- signal,
77630
- () => AcpQuerySession.start(agent, cwd, readerId, this.#store, this.#connector, signal),
77855
+ query.signal,
77856
+ () => AcpQuerySession.start(query, this.#store, this.#connector),
77631
77857
  {
77632
- isBusy: () => readers.isBusy(cwd),
77633
- retire: (runtime2) => this.retire(readers, cwd, runtime2),
77634
- retireIdle: (runtime2) => this.retire(readers, cwd, runtime2)
77858
+ isBusy: () => readers.isBusy(key),
77859
+ retire: (runtime2) => this.retire(readers, key, runtime2),
77860
+ retireIdle: (runtime2) => this.retire(readers, key, runtime2)
77635
77861
  }
77636
77862
  );
77637
- readers.retain(cwd, runtime);
77863
+ readers.retain(key, runtime);
77638
77864
  return runtime;
77639
77865
  });
77640
77866
  }
77641
- #use = async (cwd, signal, operation) => {
77867
+ #use = async (query, operation) => {
77642
77868
  const agent = this.#agent;
77869
+ const scoped = { ...query, agent };
77643
77870
  let readers = this.#processesByAgent.get(agent);
77644
77871
  if (readers === void 0) {
77645
77872
  readers = new RetainedAgentProcesses({
@@ -77649,35 +77876,38 @@ var AgentQueryProcesses = class {
77649
77876
  this.#processesByAgent.set(agent, readers);
77650
77877
  }
77651
77878
  const current = readers;
77652
- return await current.use(cwd, async () => await operation(await this.#ensure(agent, current, cwd, signal)));
77879
+ return await current.use(
77880
+ nativeSessionQueryKey(scoped),
77881
+ async () => await operation(await this.#ensure(current, scoped))
77882
+ );
77653
77883
  };
77654
- capabilities = async (cwd, signal) => await this.#use(cwd, signal, async (runtime) => runtime.capabilities());
77655
- listNativeSessions = async (cwd, cursor, signal) => await this.#use(cwd, signal, async (runtime) => await runtime.listNativeSessions(cursor, signal));
77656
- previewSessionEvents = async (cwd, additionalDirectories, request, signal) => {
77657
- signal.throwIfAborted();
77658
- const agent = this.#agent;
77659
- const { nativeSessionId, eventLimit, cursor, sessionId } = request;
77884
+ capabilities = async (query) => await this.#use(query, async (runtime) => runtime.capabilities());
77885
+ listNativeSessions = async (query, cursor) => await this.#use(query, async (runtime) => await runtime.listNativeSessions(cursor, query.signal));
77886
+ previewSessionEvents = async (query, request) => {
77887
+ query.signal.throwIfAborted();
77888
+ const scoped = { ...query, agent: this.#agent };
77889
+ const { nativeSessionId, eventLimit, cursor } = request;
77890
+ const key = nativeSessionPreviewKey(nativeSessionQueryKey(scoped), nativeSessionId);
77660
77891
  if (cursor !== null) {
77661
- const preview = this.#eventPreviewsBySession.get(sessionId);
77892
+ const preview = this.#eventPreviewsBySession.get(key);
77662
77893
  if (preview === void 0 || preview.nativeSessionId !== nativeSessionId) {
77663
77894
  throw new Error("The native event cursor is invalid");
77664
77895
  }
77665
- return preview.store.page(sessionId, eventLimit, cursor);
77896
+ return preview.store.page(nativeSessionId, eventLimit, cursor);
77666
77897
  }
77667
77898
  const store = new MemorySessionEventStore();
77668
- const previous = this.#eventPreviewsBySession.get(sessionId);
77669
- previous?.store.close();
77670
- this.#eventPreviewsBySession.set(sessionId, { nativeSessionId, store });
77899
+ this.#eventPreviewsBySession.get(key)?.store.close();
77900
+ this.#eventPreviewsBySession.set(key, { nativeSessionId, store });
77671
77901
  try {
77672
77902
  return await this.#processes.runTransient(
77673
- signal,
77674
- async () => await AcpQuerySession.start(agent, cwd, sessionId, store, this.#connector, signal),
77675
- async (runtime) => await runtime.previewEvents(nativeSessionId, eventLimit, additionalDirectories, signal),
77676
- async (runtime) => await runtime.closeProcess()
77903
+ query.signal,
77904
+ () => AcpQuerySession.start(scoped, store, this.#connector),
77905
+ (runtime) => runtime.previewEvents(nativeSessionId, eventLimit, query.signal),
77906
+ (runtime) => runtime.closeProcess()
77677
77907
  );
77678
77908
  } catch (error62) {
77679
- if (this.#eventPreviewsBySession.get(sessionId)?.store === store) {
77680
- this.#eventPreviewsBySession.delete(sessionId);
77909
+ if (this.#eventPreviewsBySession.get(key)?.store === store) {
77910
+ this.#eventPreviewsBySession.delete(key);
77681
77911
  }
77682
77912
  store.close();
77683
77913
  throw error62;
@@ -77686,7 +77916,7 @@ var AgentQueryProcesses = class {
77686
77916
  close = async () => {
77687
77917
  await Promise.all(
77688
77918
  [...this.#processesByAgent.values()].flatMap(
77689
- (readers) => readers.entries().map(async ([cwd, runtime]) => await this.retire(readers, cwd, runtime))
77919
+ (readers) => readers.entries().map(async ([key, runtime]) => await this.retire(readers, key, runtime))
77690
77920
  )
77691
77921
  );
77692
77922
  this.#processesByAgent.clear();
@@ -77699,35 +77929,99 @@ var AgentQueryProcesses = class {
77699
77929
  };
77700
77930
 
77701
77931
  // src/engine/acp/adapter/claude/adapter.ts
77932
+ import { methods as methods13 } from "@agentclientprotocol/sdk";
77702
77933
  var ClaudeAdapter = class {
77703
77934
  #queryProcesses;
77704
77935
  #connector;
77705
- #liveSessions;
77936
+ #executionConnections;
77706
77937
  constructor(agent, dependencies) {
77707
77938
  this.#connector = new AcpSessionConnector(dependencies.contentExternalizer);
77708
- this.#liveSessions = new AcpLiveSessions(dependencies.contentExternalizer);
77939
+ this.#executionConnections = new AcpExecutionConnections(dependencies.contentExternalizer);
77709
77940
  this.#queryProcesses = new AgentQueryProcesses(agent, dependencies.processes, this.#connector);
77710
77941
  }
77711
77942
  refreshAgent = (agent) => this.#queryProcesses.refreshAgent(agent);
77712
- getCapabilities = (cwd, signal) => this.#queryProcesses.capabilities(cwd, signal);
77713
- connectSession = (options) => this.#liveSessions.connectSession(options);
77714
- cancel = (...args) => this.#liveSessions.cancel(...args);
77715
- closeSession = (...args) => this.#liveSessions.closeSession(...args);
77716
- prompt = (...args) => this.#liveSessions.prompt(...args);
77717
- steer = (...args) => this.#liveSessions.steer(...args);
77718
- renameSession = (...args) => this.#liveSessions.renameSession(...args);
77719
- configureSession = (...args) => this.#liveSessions.configureSession(...args);
77720
- listSessions = (cwd, cursor, signal) => this.#queryProcesses.listNativeSessions(cwd, cursor, signal);
77721
- findSession = (cwd, nativeSessionId, budget, signal) => findNativeSession(this.listSessions, cwd, nativeSessionId, budget, signal);
77722
- readSessionHistory = (cwd, additionalDirectories, request, signal) => this.#queryProcesses.previewSessionEvents(cwd, additionalDirectories, request, signal);
77943
+ getCapabilities = async (query) => await this.#queryProcesses.capabilities(query);
77944
+ createSession = (params) => this.#executionConnections.withConnection(params, async (execution, signal) => {
77945
+ const { connection } = execution;
77946
+ const response = await connection.race(
77947
+ connection.connection.agent.request(methods13.agent.session.new, sessionWorkspace(params.scope), {
77948
+ cancellationSignal: signal
77949
+ }),
77950
+ "ACP agent exited while starting a session",
77951
+ signal
77952
+ );
77953
+ const nativeSessionId = createdNativeSessionId(response);
77954
+ this.#executionConnections.bind(execution, nativeSessionId);
77955
+ return normalizeOpenedSession(execution, nativeSessionId, response, signal);
77956
+ });
77957
+ forkSession = (params) => this.#executionConnections.withConnection(params, async (execution, signal) => {
77958
+ const { connection } = execution;
77959
+ const response = await connection.race(
77960
+ connection.connection.agent.request(
77961
+ methods13.agent.session.fork,
77962
+ {
77963
+ ...sessionWorkspace(params.scope),
77964
+ sessionId: nativeSessionIdSchema.parse(params.sourceNativeSessionId)
77965
+ },
77966
+ { cancellationSignal: signal }
77967
+ ),
77968
+ "ACP agent exited while forking a session",
77969
+ signal
77970
+ );
77971
+ const nativeSessionId = createdNativeSessionId(response);
77972
+ this.#executionConnections.bind(execution, nativeSessionId);
77973
+ return normalizeOpenedSession(execution, nativeSessionId, response, signal);
77974
+ });
77975
+ openSession = (params) => this.#executionConnections.withConnection(params, async (execution, signal) => {
77976
+ const { connection } = execution;
77977
+ const nativeSessionId = nativeSessionIdSchema.parse(params.nativeSessionId);
77978
+ this.#executionConnections.bind(execution, nativeSessionId);
77979
+ const response = await connection.race(
77980
+ connection.connection.agent.request(
77981
+ methods13.agent.session.resume,
77982
+ { ...sessionWorkspace(params.scope), sessionId: nativeSessionId },
77983
+ { cancellationSignal: signal }
77984
+ ),
77985
+ "ACP agent exited while resuming a session",
77986
+ signal
77987
+ );
77988
+ return normalizeOpenedSession(execution, nativeSessionId, response, signal);
77989
+ });
77990
+ openSessionWithReplay = (params) => this.#executionConnections.withConnection(params, async (execution, signal) => {
77991
+ const { connection } = execution;
77992
+ const nativeSessionId = nativeSessionIdSchema.parse(params.nativeSessionId);
77993
+ this.#executionConnections.bind(execution, nativeSessionId);
77994
+ const response = await connection.race(
77995
+ connection.connection.agent.request(
77996
+ methods13.agent.session.load,
77997
+ { ...sessionWorkspace(params.scope), sessionId: nativeSessionId },
77998
+ { cancellationSignal: signal }
77999
+ ),
78000
+ "ACP agent exited while loading a session",
78001
+ signal
78002
+ );
78003
+ await connection.race(connection.events.drained(), "ACP agent exited while loading a session", signal);
78004
+ return normalizeOpenedSession(execution, nativeSessionId, response, signal);
78005
+ });
78006
+ cancel = (...args) => this.#executionConnections.cancel(...args);
78007
+ closeSession = (...args) => this.#executionConnections.closeSession(...args);
78008
+ releaseSession = (params) => this.#executionConnections.releaseSession(params);
78009
+ prompt = (...args) => this.#executionConnections.prompt(...args);
78010
+ steer = (...args) => this.#executionConnections.steer(...args);
78011
+ renameSession = (...args) => this.#executionConnections.renameSession(...args);
78012
+ configureSession = (...args) => this.#executionConnections.configureSession(...args);
78013
+ listSessions = async ({ query, cursor }) => await this.#queryProcesses.listNativeSessions(query, cursor);
78014
+ findSession = ({ query, nativeSessionId, budget }) => findNativeSession(this.listSessions, query, nativeSessionId, budget);
78015
+ readSessionHistory = async ({ query, request }) => await this.#queryProcesses.previewSessionEvents(query, request);
77723
78016
  close = async () => await runCleanup(
77724
78017
  () => this.#queryProcesses.close(),
77725
- () => this.#liveSessions.close()
78018
+ () => this.#executionConnections.close()
77726
78019
  );
77727
78020
  };
77728
78021
 
77729
78022
  // src/engine/acp/adapter/codex/adapter.ts
77730
78023
  import { createHash as createHash5 } from "node:crypto";
78024
+ import { methods as methods14 } from "@agentclientprotocol/sdk";
77731
78025
 
77732
78026
  // src/engine/storage/session/temporary-session-event-cache.ts
77733
78027
  import { mkdtempSync, rmSync as rmSync2 } from "node:fs";
@@ -83027,7 +83321,7 @@ var CodexAdapter = class {
83027
83321
  #agent;
83028
83322
  #queryProcesses;
83029
83323
  #connector;
83030
- #liveSessions;
83324
+ #executionConnections;
83031
83325
  #dependencies;
83032
83326
  #contentExternalizer;
83033
83327
  #previewCache = null;
@@ -83043,37 +83337,112 @@ var CodexAdapter = class {
83043
83337
  }
83044
83338
  };
83045
83339
  this.#connector = new AcpSessionConnector(this.#contentExternalizer, fitCodexToolEvent);
83046
- this.#liveSessions = new AcpLiveSessions(this.#contentExternalizer, fitCodexToolEvent);
83340
+ this.#executionConnections = new AcpExecutionConnections(this.#contentExternalizer, fitCodexToolEvent);
83047
83341
  this.#queryProcesses = new AgentQueryProcesses(agent, dependencies.processes, this.#connector);
83048
83342
  }
83049
83343
  refreshAgent = (agent) => {
83050
83344
  this.#agent = agent;
83051
83345
  this.#queryProcesses.refreshAgent(agent);
83052
83346
  };
83053
- getCapabilities = (cwd, signal) => this.#queryProcesses.capabilities(cwd, signal);
83054
- connectSession = (options) => this.#liveSessions.connectSession(options);
83055
- cancel = async (target, signal) => {
83056
- await this.#liveSessions.closeSession(target, signal);
83347
+ getCapabilities = async (query) => await this.#queryProcesses.capabilities(query);
83348
+ #executionParams = (params) => {
83349
+ const externalize = params.scope.externalizeUpdate;
83350
+ return externalize === void 0 ? params : {
83351
+ ...params,
83352
+ scope: {
83353
+ ...params.scope,
83354
+ externalizeUpdate: (update, signal) => externalize(prepareCodexToolUpdate(update), signal)
83355
+ }
83356
+ };
83357
+ };
83358
+ createSession = (params) => this.#executionConnections.withConnection(this.#executionParams(params), async (execution, signal) => {
83359
+ const { connection } = execution;
83360
+ const response = await connection.race(
83361
+ connection.connection.agent.request(methods14.agent.session.new, sessionWorkspace(params.scope), {
83362
+ cancellationSignal: signal
83363
+ }),
83364
+ "ACP agent exited while starting a session",
83365
+ signal
83366
+ );
83367
+ const nativeSessionId = createdNativeSessionId(response);
83368
+ this.#executionConnections.bind(execution, nativeSessionId);
83369
+ return normalizeOpenedSession(execution, nativeSessionId, response, signal);
83370
+ });
83371
+ forkSession = (params) => this.#executionConnections.withConnection(this.#executionParams(params), async (execution, signal) => {
83372
+ const { connection } = execution;
83373
+ const response = await connection.race(
83374
+ connection.connection.agent.request(
83375
+ methods14.agent.session.fork,
83376
+ {
83377
+ ...sessionWorkspace(params.scope),
83378
+ sessionId: nativeSessionIdSchema.parse(params.sourceNativeSessionId)
83379
+ },
83380
+ { cancellationSignal: signal }
83381
+ ),
83382
+ "ACP agent exited while forking a session",
83383
+ signal
83384
+ );
83385
+ const nativeSessionId = createdNativeSessionId(response);
83386
+ this.#executionConnections.bind(execution, nativeSessionId);
83387
+ return normalizeOpenedSession(execution, nativeSessionId, response, signal);
83388
+ });
83389
+ openSession = (params) => this.#executionConnections.withConnection(this.#executionParams(params), async (execution, signal) => {
83390
+ const { connection } = execution;
83391
+ const nativeSessionId = nativeSessionIdSchema.parse(params.nativeSessionId);
83392
+ this.#executionConnections.bind(execution, nativeSessionId);
83393
+ const response = await connection.race(
83394
+ connection.connection.agent.request(
83395
+ methods14.agent.session.resume,
83396
+ { ...sessionWorkspace(params.scope), sessionId: nativeSessionId },
83397
+ { cancellationSignal: signal }
83398
+ ),
83399
+ "ACP agent exited while resuming a session",
83400
+ signal
83401
+ );
83402
+ return normalizeOpenedSession(execution, nativeSessionId, response, signal);
83403
+ });
83404
+ openSessionWithReplay = (params) => this.#executionConnections.withConnection(this.#executionParams(params), async (execution, signal) => {
83405
+ const { connection } = execution;
83406
+ const nativeSessionId = nativeSessionIdSchema.parse(params.nativeSessionId);
83407
+ this.#executionConnections.bind(execution, nativeSessionId);
83408
+ const response = await connection.race(
83409
+ connection.connection.agent.request(
83410
+ methods14.agent.session.load,
83411
+ { ...sessionWorkspace(params.scope), sessionId: nativeSessionId },
83412
+ { cancellationSignal: signal }
83413
+ ),
83414
+ "ACP agent exited while loading a session",
83415
+ signal
83416
+ );
83417
+ await connection.race(connection.events.drained(), "ACP agent exited while loading a session", signal);
83418
+ return normalizeOpenedSession(execution, nativeSessionId, response, signal);
83419
+ });
83420
+ cancel = async (params) => {
83421
+ await this.#executionConnections.closeSession(params);
83057
83422
  return "closed";
83058
83423
  };
83059
- closeSession = (...args) => this.#liveSessions.closeSession(...args);
83060
- prompt = (...args) => this.#liveSessions.prompt(...args);
83061
- steer = (...args) => this.#liveSessions.steer(...args);
83062
- renameSession = (...args) => this.#liveSessions.renameSession(...args);
83063
- configureSession = (...args) => this.#liveSessions.configureSession(...args);
83064
- listSessions = (cwd, cursor, signal) => this.#queryProcesses.listNativeSessions(cwd, cursor, signal);
83065
- findSession = (cwd, nativeSessionId, budget, signal) => findNativeSession(this.listSessions, cwd, nativeSessionId, budget, signal);
83424
+ closeSession = (...args) => this.#executionConnections.closeSession(...args);
83425
+ releaseSession = (params) => this.#executionConnections.releaseSession(params);
83426
+ prompt = (...args) => this.#executionConnections.prompt(...args);
83427
+ steer = (...args) => this.#executionConnections.steer(...args);
83428
+ renameSession = (...args) => this.#executionConnections.renameSession(...args);
83429
+ configureSession = (...args) => this.#executionConnections.configureSession(...args);
83430
+ listSessions = async ({ query, cursor }) => await this.#queryProcesses.listNativeSessions(query, cursor);
83431
+ findSession = ({ query, nativeSessionId, budget }) => findNativeSession(this.listSessions, query, nativeSessionId, budget);
83066
83432
  close = async () => {
83067
83433
  await runCleanup(
83068
83434
  () => this.#queryProcesses.close(),
83069
- () => this.#liveSessions.close(),
83435
+ () => this.#executionConnections.close(),
83070
83436
  () => this.#previewCache?.close()
83071
83437
  );
83072
83438
  };
83073
- readSessionHistory = async (cwd, _additionalDirectories, request, cancellation) => {
83074
- const agent = this.#agent;
83075
- const signal = AbortSignal.any([cancellation, AbortSignal.timeout(6e4)]);
83076
- const { sessionId } = request;
83439
+ readSessionHistory = async ({
83440
+ query,
83441
+ request
83442
+ }) => {
83443
+ const { agent, cwd } = query;
83444
+ const signal = AbortSignal.any([query.signal, AbortSignal.timeout(6e4)]);
83445
+ const sessionId = request.nativeSessionId;
83077
83446
  signal.throwIfAborted();
83078
83447
  nativeSessionIdSchema.parse(request.nativeSessionId);
83079
83448
  if (agent.id !== "codex") {
@@ -83124,7 +83493,7 @@ var CodexAdapter = class {
83124
83493
  client2,
83125
83494
  request.nativeSessionId,
83126
83495
  async (update) => {
83127
- const externalized = await this.#contentExternalizer.update(sessionId, update, signal);
83496
+ const externalized = query.externalizeUpdate === void 0 ? await this.#contentExternalizer.update(sessionId, update, signal) : await query.externalizeUpdate(prepareCodexToolUpdate(update), signal);
83128
83497
  for (const event of externalized.events) {
83129
83498
  events.push({
83130
83499
  type: "acp",
@@ -83144,30 +83513,93 @@ var CodexAdapter = class {
83144
83513
  };
83145
83514
 
83146
83515
  // src/engine/acp/adapter/pi/adapter.ts
83516
+ import { methods as methods15 } from "@agentclientprotocol/sdk";
83147
83517
  var PiAdapter = class {
83148
83518
  #queryProcesses;
83149
83519
  #connector;
83150
- #liveSessions;
83520
+ #executionConnections;
83151
83521
  constructor(agent, dependencies) {
83152
83522
  this.#connector = new AcpSessionConnector(dependencies.contentExternalizer);
83153
- this.#liveSessions = new AcpLiveSessions(dependencies.contentExternalizer);
83523
+ this.#executionConnections = new AcpExecutionConnections(dependencies.contentExternalizer);
83154
83524
  this.#queryProcesses = new AgentQueryProcesses(agent, dependencies.processes, this.#connector);
83155
83525
  }
83156
83526
  refreshAgent = (agent) => this.#queryProcesses.refreshAgent(agent);
83157
- getCapabilities = (cwd, signal) => this.#queryProcesses.capabilities(cwd, signal);
83158
- connectSession = (options) => this.#liveSessions.connectSession(options);
83159
- cancel = (...args) => this.#liveSessions.cancel(...args);
83160
- closeSession = (...args) => this.#liveSessions.closeSession(...args);
83161
- prompt = (...args) => this.#liveSessions.prompt(...args);
83162
- steer = (...args) => this.#liveSessions.steer(...args);
83163
- renameSession = (...args) => this.#liveSessions.renameSession(...args);
83164
- configureSession = (...args) => this.#liveSessions.configureSession(...args);
83165
- listSessions = (cwd, cursor, signal) => this.#queryProcesses.listNativeSessions(cwd, cursor, signal);
83166
- findSession = (cwd, nativeSessionId, budget, signal) => findNativeSession(this.listSessions, cwd, nativeSessionId, budget, signal);
83167
- readSessionHistory = (cwd, additionalDirectories, request, signal) => this.#queryProcesses.previewSessionEvents(cwd, additionalDirectories, request, signal);
83527
+ getCapabilities = async (query) => await this.#queryProcesses.capabilities(query);
83528
+ createSession = (params) => this.#executionConnections.withConnection(params, async (execution, signal) => {
83529
+ const { connection } = execution;
83530
+ const response = await connection.race(
83531
+ connection.connection.agent.request(methods15.agent.session.new, sessionWorkspace(params.scope), {
83532
+ cancellationSignal: signal
83533
+ }),
83534
+ "ACP agent exited while starting a session",
83535
+ signal
83536
+ );
83537
+ const nativeSessionId = createdNativeSessionId(response);
83538
+ this.#executionConnections.bind(execution, nativeSessionId);
83539
+ return normalizeOpenedSession(execution, nativeSessionId, response, signal);
83540
+ });
83541
+ forkSession = (params) => this.#executionConnections.withConnection(params, async (execution, signal) => {
83542
+ const { connection } = execution;
83543
+ const response = await connection.race(
83544
+ connection.connection.agent.request(
83545
+ methods15.agent.session.fork,
83546
+ {
83547
+ ...sessionWorkspace(params.scope),
83548
+ sessionId: nativeSessionIdSchema.parse(params.sourceNativeSessionId)
83549
+ },
83550
+ { cancellationSignal: signal }
83551
+ ),
83552
+ "ACP agent exited while forking a session",
83553
+ signal
83554
+ );
83555
+ const nativeSessionId = createdNativeSessionId(response);
83556
+ this.#executionConnections.bind(execution, nativeSessionId);
83557
+ return normalizeOpenedSession(execution, nativeSessionId, response, signal);
83558
+ });
83559
+ openSession = (params) => this.#executionConnections.withConnection(params, async (execution, signal) => {
83560
+ const { connection } = execution;
83561
+ const nativeSessionId = nativeSessionIdSchema.parse(params.nativeSessionId);
83562
+ this.#executionConnections.bind(execution, nativeSessionId);
83563
+ const response = await connection.race(
83564
+ connection.connection.agent.request(
83565
+ methods15.agent.session.resume,
83566
+ { ...sessionWorkspace(params.scope), sessionId: nativeSessionId },
83567
+ { cancellationSignal: signal }
83568
+ ),
83569
+ "ACP agent exited while resuming a session",
83570
+ signal
83571
+ );
83572
+ return normalizeOpenedSession(execution, nativeSessionId, response, signal);
83573
+ });
83574
+ openSessionWithReplay = (params) => this.#executionConnections.withConnection(params, async (execution, signal) => {
83575
+ const { connection } = execution;
83576
+ const nativeSessionId = nativeSessionIdSchema.parse(params.nativeSessionId);
83577
+ this.#executionConnections.bind(execution, nativeSessionId);
83578
+ const response = await connection.race(
83579
+ connection.connection.agent.request(
83580
+ methods15.agent.session.load,
83581
+ { ...sessionWorkspace(params.scope), sessionId: nativeSessionId },
83582
+ { cancellationSignal: signal }
83583
+ ),
83584
+ "ACP agent exited while loading a session",
83585
+ signal
83586
+ );
83587
+ await connection.race(connection.events.drained(), "ACP agent exited while loading a session", signal);
83588
+ return normalizeOpenedSession(execution, nativeSessionId, response, signal);
83589
+ });
83590
+ cancel = (...args) => this.#executionConnections.cancel(...args);
83591
+ closeSession = (...args) => this.#executionConnections.closeSession(...args);
83592
+ releaseSession = (params) => this.#executionConnections.releaseSession(params);
83593
+ prompt = (...args) => this.#executionConnections.prompt(...args);
83594
+ steer = (...args) => this.#executionConnections.steer(...args);
83595
+ renameSession = (...args) => this.#executionConnections.renameSession(...args);
83596
+ configureSession = (...args) => this.#executionConnections.configureSession(...args);
83597
+ listSessions = async ({ query, cursor }) => await this.#queryProcesses.listNativeSessions(query, cursor);
83598
+ findSession = ({ query, nativeSessionId, budget }) => findNativeSession(this.listSessions, query, nativeSessionId, budget);
83599
+ readSessionHistory = async ({ query, request }) => await this.#queryProcesses.previewSessionEvents(query, request);
83168
83600
  close = async () => await runCleanup(
83169
83601
  () => this.#queryProcesses.close(),
83170
- () => this.#liveSessions.close()
83602
+ () => this.#executionConnections.close()
83171
83603
  );
83172
83604
  };
83173
83605
 
@@ -83465,10 +83897,12 @@ var AcpContentExternalizer = class {
83465
83897
 
83466
83898
  // src/engine/agent/runtime-agents.ts
83467
83899
  function createRuntimeAdapterRegistry(adapters, processes, externalize, linkedResources) {
83468
- return new AdapterRegistry(adapters, {
83469
- processes,
83470
- contentExternalizer: new AcpContentExternalizer(externalize, linkedResources)
83471
- });
83900
+ const contentExternalizer = new AcpContentExternalizer(externalize, linkedResources);
83901
+ const externalizeSessionUpdate = (sessionId, update, signal) => contentExternalizer.update(sessionId, update, signal);
83902
+ return {
83903
+ adapters: new AdapterRegistry(adapters, { processes, contentExternalizer }),
83904
+ externalizeSessionUpdate
83905
+ };
83472
83906
  }
83473
83907
  var RuntimeAgentDependencies = class {
83474
83908
  agents;
@@ -84567,9 +85001,6 @@ var unmeasuredOperationMetrics = Object.freeze({
84567
85001
  snapshot: () => Object.freeze([])
84568
85002
  });
84569
85003
 
84570
- // src/engine/session/live/agent-session.ts
84571
- import { methods as methods14 } from "@agentclientprotocol/sdk";
84572
-
84573
85004
  // ../mobius-sdk/src/conversation-title.ts
84574
85005
  var CONVERSATION_TITLE_CHARACTER_LIMIT = 42;
84575
85006
  function conversationTitleFromText(text2) {
@@ -85408,7 +85839,6 @@ var RunningAgentTurn = class extends AgentTurnState {
85408
85839
  };
85409
85840
 
85410
85841
  // src/engine/session/live/session-restore.ts
85411
- import { methods as methods13 } from "@agentclientprotocol/sdk";
85412
85842
  function hasMethodNotFoundCode(cause) {
85413
85843
  const visited = /* @__PURE__ */ new Set();
85414
85844
  let current = cause;
@@ -85426,7 +85856,6 @@ async function restoreSession(session, signal, recovery, origin) {
85426
85856
  if (origin !== void 0) {
85427
85857
  session.setSessionTitle(origin.title);
85428
85858
  }
85429
- await session.initializeAgent(signal);
85430
85859
  let stored = session.metrics.measureSync(
85431
85860
  "session-state-read",
85432
85861
  () => origin?.kind === "import" ? new FoundStoredSession(
@@ -85446,7 +85875,7 @@ async function restoreSession(session, signal, recovery, origin) {
85446
85875
  stored = session.metrics.measureSync("session-state-read", () => session.store.read(session.sessionId));
85447
85876
  }
85448
85877
  const forkSource = origin?.kind === "fork" ? session.store.findNative(session.agentId, origin.nativeSessionId)[0] : void 0;
85449
- let lifecycleResponse;
85878
+ let opened;
85450
85879
  if (origin?.kind === "fork") {
85451
85880
  if (!session.capabilities.unstableForkSession) {
85452
85881
  throw new AcpExecutionError(
@@ -85464,22 +85893,9 @@ async function restoreSession(session, signal, recovery, origin) {
85464
85893
  }
85465
85894
  const forked = await session.metrics.measure(
85466
85895
  "session-fork",
85467
- async () => await session.race(
85468
- session.agentRequest(
85469
- methods13.agent.session.fork,
85470
- {
85471
- sessionId: nativeSessionIdSchema.parse(origin.nativeSessionId),
85472
- cwd: session.cwd,
85473
- additionalDirectories: [...session.additionalDirectories],
85474
- mcpServers: []
85475
- },
85476
- { cancellationSignal: signal }
85477
- ),
85478
- "ACP agent exited while forking a session",
85479
- signal
85480
- )
85896
+ async () => await session.forkSession(origin.nativeSessionId, signal)
85481
85897
  );
85482
- session.selectNativeSession(forked.sessionId);
85898
+ session.selectNativeSession(forked.nativeSessionId);
85483
85899
  if (session.nativeSessionId() === origin.nativeSessionId || session.store.findNative(session.agentId, session.nativeSessionId()).length > 0) {
85484
85900
  throw new AcpExecutionError(
85485
85901
  "The Agent did not create an independent fork",
@@ -85492,7 +85908,7 @@ async function restoreSession(session, signal, recovery, origin) {
85492
85908
  if (recovery.kind === "execution-only") {
85493
85909
  session.startExecutionOnlyCapture();
85494
85910
  }
85495
- lifecycleResponse = forked;
85911
+ opened = forked;
85496
85912
  } else if (stored instanceof FoundStoredSession && stored.session.agentId === session.agentId && stored.session.cwd === session.cwd && arraysEqual(stored.session.additionalDirectories, session.additionalDirectories)) {
85497
85913
  session.selectNativeSession(stored.session.nativeSessionId);
85498
85914
  session.setPrompted(stored.session.prompted);
@@ -85506,29 +85922,13 @@ async function restoreSession(session, signal, recovery, origin) {
85506
85922
  "native_history_unsupported"
85507
85923
  );
85508
85924
  }
85509
- lifecycleResponse = await session.metrics.measure(
85925
+ opened = await session.metrics.measure(
85510
85926
  "session-load",
85511
- async () => (await session.loadSession(signal, "ACP agent exited while loading a session")).response
85927
+ async () => await session.openSessionWithReplay(signal)
85512
85928
  );
85513
85929
  } else if (recovery.kind === "execution-only") {
85514
85930
  try {
85515
- lifecycleResponse = await session.metrics.measure(
85516
- "session-resume",
85517
- async () => await session.race(
85518
- session.agentRequest(
85519
- methods13.agent.session.resume,
85520
- {
85521
- additionalDirectories: [...session.additionalDirectories],
85522
- cwd: session.cwd,
85523
- mcpServers: [],
85524
- sessionId: session.nativeSessionId()
85525
- },
85526
- { cancellationSignal: signal }
85527
- ),
85528
- "ACP agent exited while resuming a session",
85529
- signal
85530
- )
85531
- );
85931
+ opened = await session.metrics.measure("session-resume", async () => await session.openSession(signal));
85532
85932
  } catch (cause) {
85533
85933
  signal.throwIfAborted();
85534
85934
  if (cause instanceof AcpExecutionError && !hasMethodNotFoundCode(cause)) {
@@ -85542,27 +85942,11 @@ async function restoreSession(session, signal, recovery, origin) {
85542
85942
  }
85543
85943
  session.startExecutionOnlyCapture();
85544
85944
  } else if (session.capabilities.resumeSession) {
85545
- lifecycleResponse = await session.metrics.measure(
85546
- "session-resume",
85547
- async () => await session.race(
85548
- session.agentRequest(
85549
- methods13.agent.session.resume,
85550
- {
85551
- additionalDirectories: [...session.additionalDirectories],
85552
- cwd: session.cwd,
85553
- mcpServers: [],
85554
- sessionId: session.nativeSessionId()
85555
- },
85556
- { cancellationSignal: signal }
85557
- ),
85558
- "ACP agent exited while resuming a session",
85559
- signal
85560
- )
85561
- );
85945
+ opened = await session.metrics.measure("session-resume", async () => await session.openSession(signal));
85562
85946
  } else if (session.capabilities.loadSession) {
85563
- lifecycleResponse = await session.metrics.measure(
85947
+ opened = await session.metrics.measure(
85564
85948
  "session-load",
85565
- async () => (await session.loadSession(signal, "ACP agent exited while loading a session")).response
85949
+ async () => await session.openSessionWithReplay(signal)
85566
85950
  );
85567
85951
  } else {
85568
85952
  throw new AcpExecutionError(
@@ -85582,37 +85966,20 @@ async function restoreSession(session, signal, recovery, origin) {
85582
85966
  }
85583
85967
  session.store.remove(session.sessionId);
85584
85968
  }
85585
- const created = await session.metrics.measure(
85586
- "session-new",
85587
- async () => await session.race(
85588
- session.agentRequest(
85589
- methods13.agent.session.new,
85590
- {
85591
- additionalDirectories: [...session.additionalDirectories],
85592
- cwd: session.cwd,
85593
- mcpServers: []
85594
- },
85595
- { cancellationSignal: signal }
85596
- ),
85597
- "ACP agent exited while starting a session",
85598
- signal
85599
- )
85600
- );
85601
- session.selectNativeSession(created.sessionId);
85969
+ const created = await session.metrics.measure("session-new", async () => await session.createSession(signal));
85970
+ session.selectNativeSession(created.nativeSessionId);
85602
85971
  session.setNativeHistoryOwnership({ kind: "fresh-session" });
85603
85972
  if (recovery.kind === "execution-only") {
85604
85973
  session.startExecutionOnlyCapture();
85605
85974
  }
85606
- lifecycleResponse = created;
85975
+ opened = created;
85607
85976
  }
85608
- session.restrictSessionCapabilities(lifecycleResponse);
85609
- session.setConfigOptions(session.sessionConfigProtocol.normalizeLifecycle(lifecycleResponse));
85977
+ session.applySessionOpened(opened);
85610
85978
  if (forkSource !== void 0) {
85611
85979
  await session.restoreStoredConfigurations(forkSource, signal, "fork");
85612
85980
  } else if (stored instanceof FoundStoredSession && session.restored) {
85613
85981
  await session.restoreStoredConfigurations(stored.session, signal);
85614
85982
  }
85615
- await session.drained();
85616
85983
  signal.throwIfAborted();
85617
85984
  session.writeStoredSession(
85618
85985
  stored instanceof FoundStoredSession && session.restored ? stored.session.updatedAt : (/* @__PURE__ */ new Date()).toISOString()
@@ -85644,14 +86011,20 @@ var AgentSession = class _AgentSession {
85644
86011
  get sessionId() {
85645
86012
  return this.#mobiusSessionId;
85646
86013
  }
85647
- get sessionConfigProtocol() {
85648
- return this.#sessionConfigProtocol;
85649
- }
85650
86014
  get store() {
85651
86015
  return this.#store;
85652
86016
  }
85653
- hasBackgroundActivity = () => this.#connection.hasBackgroundActivity();
85654
- #connection;
86017
+ hasBackgroundActivity = () => this.#backgroundActivity !== "none";
86018
+ #backgroundActivity = "none";
86019
+ #modelEffort = null;
86020
+ #scope;
86021
+ #subscriber;
86022
+ #nativeIdentity = {
86023
+ kind: "unbound"
86024
+ };
86025
+ get #nativeSessionId() {
86026
+ return this.#nativeIdentity.kind === "bound" ? this.#nativeIdentity.nativeSessionId : "";
86027
+ }
85655
86028
  #adapter;
85656
86029
  #additionalDirectories;
85657
86030
  #agentId;
@@ -85660,11 +86033,8 @@ var AgentSession = class _AgentSession {
85660
86033
  #getObserver;
85661
86034
  #interactions;
85662
86035
  #mobiusSessionId;
85663
- #updates;
85664
86036
  #metrics;
85665
- #sessionConfigProtocol;
85666
86037
  #store;
85667
- #verifiedAgentVersion;
85668
86038
  #agentName = "";
85669
86039
  #agentVersion = "";
85670
86040
  #capabilities = unsupportedSessionCapabilities();
@@ -85680,7 +86050,7 @@ var AgentSession = class _AgentSession {
85680
86050
  #sessionTitle = null;
85681
86051
  #sessionUpdatedAt = "";
85682
86052
  #turn = new IdleAgentTurn();
85683
- constructor(agent, cwd, additionalDirectories, mobiusSessionId, getObserver, store, metrics, adapter) {
86053
+ constructor(agent, cwd, additionalDirectories, mobiusSessionId, getObserver, store, metrics, adapter, externalize) {
85684
86054
  this.#additionalDirectories = [...additionalDirectories];
85685
86055
  this.#adapter = adapter;
85686
86056
  this.#agentId = agent.id;
@@ -85689,9 +86059,7 @@ var AgentSession = class _AgentSession {
85689
86059
  this.#environment = agent.environment;
85690
86060
  this.#mobiusSessionId = mobiusSessionId;
85691
86061
  this.#metrics = metrics;
85692
- this.#sessionConfigProtocol = sessionConfigProtocolForAgent(agent.id);
85693
86062
  this.#store = store;
85694
- this.#verifiedAgentVersion = agent.agentVersion;
85695
86063
  this.#getObserver = getObserver;
85696
86064
  this.#interactions = new SessionInteractions({
85697
86065
  cwd: () => this.#cwd,
@@ -85702,25 +86070,31 @@ var AgentSession = class _AgentSession {
85702
86070
  observer: getObserver,
85703
86071
  recordSessionEvent: this.recordLifecycleEvent
85704
86072
  });
85705
- const scope = {
86073
+ this.#scope = {
85706
86074
  agent,
85707
86075
  cwd,
85708
- sessionId: () => this.#mobiusSessionId,
85709
- configOptions: () => this.#configOptions,
85710
- onEvent: this.#processEvent
85711
- };
85712
- this.#connection = this.#adapter.connectSession({
85713
- ...scope,
85714
86076
  additionalDirectories: this.#additionalDirectories,
85715
- capabilities: () => this.#capabilities,
85716
- onBackgroundActivity: (activity) => this.#getObserver().onBackgroundActivity?.(this, activity),
86077
+ ...externalize === void 0 ? {} : { externalizeUpdate: (update, signal) => externalize(this.#mobiusSessionId, update, signal) }
86078
+ };
86079
+ this.#subscriber = {
86080
+ onSessionEvent: async (nativeSessionId, event) => {
86081
+ if (this.#nativeSessionId.length === 0) {
86082
+ this.selectNativeSession(nativeSessionId);
86083
+ } else {
86084
+ this.assertNativeSession(nativeSessionId);
86085
+ }
86086
+ await this.#processEvent(event);
86087
+ },
86088
+ onBackgroundActivity: (activity) => {
86089
+ this.#backgroundActivity = activity;
86090
+ this.#getObserver().onBackgroundActivity?.(this, activity);
86091
+ },
85717
86092
  interactions: {
85718
86093
  onPermission: this.#interactions.onPermission,
85719
86094
  onElicitation: this.#interactions.onElicitation,
85720
86095
  onElicitationComplete: this.#interactions.onElicitationComplete
85721
86096
  }
85722
- });
85723
- this.#updates = this.#connection.events;
86097
+ };
85724
86098
  }
85725
86099
  static async #start(options, getObserver, store, initialize, metrics, adapter) {
85726
86100
  for (let attempt = 1; attempt <= 2; attempt += 1) {
@@ -85738,7 +86112,8 @@ var AgentSession = class _AgentSession {
85738
86112
  getObserver,
85739
86113
  store,
85740
86114
  metrics,
85741
- adapter
86115
+ adapter,
86116
+ options.externalizeSessionUpdate
85742
86117
  )
85743
86118
  );
85744
86119
  try {
@@ -85761,11 +86136,14 @@ var AgentSession = class _AgentSession {
85761
86136
  }
85762
86137
  throw new AcpExecutionError("ACP agent initialization failed");
85763
86138
  }
85764
- static start = async (options, recovery, getObserver, store, metrics, adapter) => await _AgentSession.#start(
86139
+ static start = async (options, recovery, getObserver, store, metrics, adapter, capabilities = unsupportedSessionCapabilities()) => await _AgentSession.#start(
85765
86140
  options,
85766
86141
  getObserver,
85767
86142
  store,
85768
- async (runtime) => await runtime.initialize(options.signal, recovery, options.origin),
86143
+ async (runtime) => {
86144
+ runtime.#capabilities = capabilities;
86145
+ await runtime.initialize(options.signal, recovery, options.origin);
86146
+ },
85769
86147
  metrics,
85770
86148
  adapter
85771
86149
  );
@@ -85778,7 +86156,7 @@ var AgentSession = class _AgentSession {
85778
86156
  new StoredSession(
85779
86157
  this.#mobiusSessionId,
85780
86158
  this.#agentId,
85781
- this.#updates.sessionId(),
86159
+ this.#nativeSessionId,
85782
86160
  this.#cwd,
85783
86161
  this.#additionalDirectories,
85784
86162
  this.#prompted,
@@ -85800,9 +86178,9 @@ var AgentSession = class _AgentSession {
85800
86178
  if (normalized.length === 0) {
85801
86179
  throw new AcpExecutionError("The Session title cannot be empty", {}, "invalid_session_title");
85802
86180
  }
85803
- const nativeSessionId = this.#updates.sessionId();
86181
+ const nativeSessionId = this.#nativeSessionId;
85804
86182
  if (nativeSessionId.length > 0) {
85805
- await this.#adapter.renameSession(this.#target(), normalized, signal);
86183
+ await this.#adapter.renameSession({ ...this.#target(), title: normalized, signal });
85806
86184
  }
85807
86185
  const updatedAt = (/* @__PURE__ */ new Date()).toISOString();
85808
86186
  await this.#processEvent({
@@ -85817,7 +86195,7 @@ var AgentSession = class _AgentSession {
85817
86195
  };
85818
86196
  #captureSelectedConfigurationValues = () => {
85819
86197
  this.#sessionConfigurations.capture(this.#configOptions);
85820
- if (this.#updates.sessionId().length > 0) {
86198
+ if (this.#nativeSessionId.length > 0) {
85821
86199
  this.writeStoredSession((/* @__PURE__ */ new Date()).toISOString());
85822
86200
  }
85823
86201
  };
@@ -85847,8 +86225,12 @@ var AgentSession = class _AgentSession {
85847
86225
  }
85848
86226
  }
85849
86227
  };
85850
- restrictSessionCapabilities = (response) => {
85851
- this.#capabilities = restrictAcpSessionCapabilities(this.#capabilities, response);
86228
+ applySessionOpened = (opened) => {
86229
+ this.#agentName = opened.agentName;
86230
+ this.#agentVersion = opened.agentVersion;
86231
+ this.#modelEffort = opened.agentSettingsModelEffort;
86232
+ this.#capabilities = opened.capabilities;
86233
+ this.setConfigOptions(opened.configOptions);
85852
86234
  };
85853
86235
  prepared = () => new PreparedSession(
85854
86236
  this.#agentName,
@@ -85868,7 +86250,7 @@ var AgentSession = class _AgentSession {
85868
86250
  "native_history_unsupported"
85869
86251
  );
85870
86252
  }
85871
- await this.#completedHistory(signal, "ACP agent exited while loading history");
86253
+ await this.#completedHistory(signal);
85872
86254
  };
85873
86255
  /** Starts live event capture without asking the native Agent to replay its persisted history. */
85874
86256
  startExecutionOnlyCapture = () => {
@@ -85888,26 +86270,33 @@ var AgentSession = class _AgentSession {
85888
86270
  "native_history_unsupported"
85889
86271
  );
85890
86272
  }
85891
- const history = await this.#completedHistory(signal, "ACP agent exited while loading history");
86273
+ const history = await this.#completedHistory(signal);
85892
86274
  return history.eventPage(eventLimit, cursor);
85893
86275
  };
85894
- async #completedHistory(signal, exitMessage) {
86276
+ async #completedHistory(signal) {
85895
86277
  if (!this.#prompted && this.#nativeHistoryOwnership.kind === "fresh-session") {
85896
86278
  if (this.#sessionLoad.kind === "not-requested") {
85897
86279
  this.#store.events.reset(this.#mobiusSessionId);
85898
86280
  this.#sessionLoad = {
85899
86281
  history: new HistoryReplayCapture(this.#store.events, this.#mobiusSessionId),
85900
86282
  kind: "loaded",
85901
- response: {}
86283
+ opened: {
86284
+ nativeSessionId: this.nativeSessionId(),
86285
+ capabilities: this.#capabilities,
86286
+ configOptions: [],
86287
+ agentName: this.#agentName,
86288
+ agentVersion: this.#agentVersion,
86289
+ agentSettingsModelEffort: this.#modelEffort
86290
+ }
85902
86291
  };
85903
86292
  }
85904
86293
  if (this.#sessionLoad.kind === "loaded") {
85905
86294
  return this.#sessionLoad.history;
85906
86295
  }
85907
86296
  }
85908
- return (await this.#loadSession(signal, exitMessage)).history;
86297
+ return (await this.#loadSession(signal)).history;
85909
86298
  }
85910
- async #loadSession(signal, exitMessage) {
86299
+ async #loadSession(signal) {
85911
86300
  if (this.#sessionLoad.kind === "loaded") {
85912
86301
  return this.#sessionLoad;
85913
86302
  }
@@ -85918,24 +86307,13 @@ var AgentSession = class _AgentSession {
85918
86307
  const history = new HistoryReplayCapture(this.#store.events, this.#mobiusSessionId);
85919
86308
  const completion = Promise.resolve().then(async () => {
85920
86309
  try {
85921
- const response = await this.race(
85922
- this.#connection.connection.agent.request(
85923
- methods14.agent.session.load,
85924
- {
85925
- additionalDirectories: [...this.#additionalDirectories],
85926
- cwd: this.#cwd,
85927
- mcpServers: [],
85928
- sessionId: this.#updates.sessionId()
85929
- },
85930
- { cancellationSignal: signal }
85931
- ),
85932
- exitMessage,
85933
- signal
85934
- );
85935
- await this.#updates.drained();
86310
+ const opened = await this.#adapter.openSessionWithReplay({
86311
+ ...this.#sessionParams(signal),
86312
+ nativeSessionId: this.nativeSessionId()
86313
+ });
85936
86314
  signal.throwIfAborted();
85937
- this.restrictSessionCapabilities(response);
85938
- const loaded = { history, kind: "loaded", response };
86315
+ this.#capabilities = opened.capabilities;
86316
+ const loaded = { history, kind: "loaded", opened };
85939
86317
  this.#sessionLoad = loaded;
85940
86318
  return loaded;
85941
86319
  } catch (cause) {
@@ -85946,24 +86324,10 @@ var AgentSession = class _AgentSession {
85946
86324
  this.#sessionLoad = { completion, history, kind: "capturing" };
85947
86325
  return await completion;
85948
86326
  }
85949
- async #initializeAgent(signal) {
85950
- await this.#metrics.measure("agent-initialize", async () => await this.#initializeAgentOperation(signal));
85951
- }
85952
- async #initializeAgentOperation(signal) {
85953
- const initialized = await initializeAgentConnection(
85954
- this.#connection,
85955
- this.#agentId,
85956
- this.#verifiedAgentVersion,
85957
- signal
85958
- );
85959
- this.#capabilities = initialized.capabilities;
85960
- this.#agentName = initialized.agentName;
85961
- this.#agentVersion = initialized.agentVersion;
85962
- }
85963
86327
  initialize = async (signal, recovery, origin) => await restoreSession(this, signal, recovery, origin);
85964
- nativeSessionId = () => this.#updates.sessionId();
86328
+ nativeSessionId = () => this.#nativeSessionId;
85965
86329
  adoptNativeSessionId = (sessionId) => {
85966
- if (this.#prompted || this.#updates.sessionId() !== sessionId) {
86330
+ if (this.#prompted || this.#nativeSessionId !== sessionId) {
85967
86331
  throw new AcpExecutionError("The new native Session cannot be adopted", {}, "session_identity_mismatch");
85968
86332
  }
85969
86333
  const previousSessionId = this.#mobiusSessionId;
@@ -85985,7 +86349,7 @@ var AgentSession = class _AgentSession {
85985
86349
  };
85986
86350
  #applyConfiguration = async (selection, signal) => {
85987
86351
  const configRevision = this.#configRevision;
85988
- const configured = await this.#adapter.configureSession(this.#target(), selection, signal);
86352
+ const configured = await this.#adapter.configureSession({ ...this.#target(), selection, signal });
85989
86353
  if (this.#configRevision === configRevision) {
85990
86354
  this.#configOptions = configured;
85991
86355
  this.#configRevision = crypto.randomUUID();
@@ -86032,7 +86396,7 @@ var AgentSession = class _AgentSession {
86032
86396
  await this.emitConfigUpdate();
86033
86397
  };
86034
86398
  #target = () => ({
86035
- nativeSessionId: this.#updates.sessionId(),
86399
+ nativeSessionId: this.#nativeSessionId,
86036
86400
  cwd: this.#cwd,
86037
86401
  additionalDirectories: this.#additionalDirectories
86038
86402
  });
@@ -86044,11 +86408,18 @@ var AgentSession = class _AgentSession {
86044
86408
  this.#sessionLoad = {
86045
86409
  kind: "loaded",
86046
86410
  history: new HistoryReplayCapture(this.#store.events, this.#mobiusSessionId),
86047
- response: {}
86411
+ opened: {
86412
+ nativeSessionId: this.nativeSessionId(),
86413
+ capabilities: this.#capabilities,
86414
+ configOptions: [],
86415
+ agentName: this.#agentName,
86416
+ agentVersion: this.#agentVersion,
86417
+ agentSettingsModelEffort: this.#modelEffort
86418
+ }
86048
86419
  };
86049
86420
  }
86050
86421
  if (this.#capabilities.loadSession && this.#sessionLoad.kind !== "execution-only") {
86051
- await this.#completedHistory(options.signal, "ACP agent exited while loading history before a prompt");
86422
+ await this.#completedHistory(options.signal);
86052
86423
  }
86053
86424
  validatePromptContent(options, this.#capabilities);
86054
86425
  if (this.#sessionTitle === null || this.#sessionTitle.length === 0) {
@@ -86082,7 +86453,7 @@ var AgentSession = class _AgentSession {
86082
86453
  });
86083
86454
  }
86084
86455
  try {
86085
- const result = await this.#adapter.prompt(this.#target(), options, options.signal);
86456
+ const result = await this.#adapter.prompt({ ...this.#target(), content: options, signal: options.signal });
86086
86457
  this.writeStoredSession((/* @__PURE__ */ new Date()).toISOString());
86087
86458
  if (lifecycle !== void 0) {
86088
86459
  await this.recordLifecycleEvent({
@@ -86153,7 +86524,7 @@ var AgentSession = class _AgentSession {
86153
86524
  });
86154
86525
  }
86155
86526
  try {
86156
- const outcome = await this.#adapter.steer(this.#target(), options, options.signal);
86527
+ const outcome = await this.#adapter.steer({ ...this.#target(), content: options, signal: options.signal });
86157
86528
  if (lifecycle !== void 0) {
86158
86529
  await this.recordLifecycleEvent({
86159
86530
  payload: {
@@ -86187,7 +86558,7 @@ var AgentSession = class _AgentSession {
86187
86558
  await this.#interactions.cancelPendingInteractions();
86188
86559
  signal.throwIfAborted();
86189
86560
  if (this.#turn.running) {
86190
- return await this.#adapter.cancel(this.#target(), signal);
86561
+ return await this.#adapter.cancel({ ...this.#target(), signal });
86191
86562
  }
86192
86563
  return "retained";
86193
86564
  };
@@ -86212,7 +86583,14 @@ var AgentSession = class _AgentSession {
86212
86583
  await this.#getObserver().onSessionEvent?.(liveEvent2);
86213
86584
  };
86214
86585
  selectNativeSession = (sessionId) => {
86215
- this.#updates.select(sessionId);
86586
+ if (this.#nativeSessionId.length > 0 && this.#nativeSessionId !== sessionId) {
86587
+ throw new AcpExecutionError(
86588
+ "ACP agent attempted to replace the selected session",
86589
+ {},
86590
+ "invalid_agent_session"
86591
+ );
86592
+ }
86593
+ this.#nativeIdentity = { kind: "bound", nativeSessionId: sessionId };
86216
86594
  this.#nativeHistoryOwnership = { kind: "agent-owned" };
86217
86595
  };
86218
86596
  #processEvent = async (event) => {
@@ -86257,7 +86635,7 @@ var AgentSession = class _AgentSession {
86257
86635
  break;
86258
86636
  }
86259
86637
  }
86260
- if (this.#updates.sessionId().length > 0) {
86638
+ if (this.#nativeSessionId.length > 0) {
86261
86639
  this.writeStoredSession((/* @__PURE__ */ new Date()).toISOString());
86262
86640
  }
86263
86641
  await this.#getObserver().onInfo({
@@ -86279,31 +86657,28 @@ var AgentSession = class _AgentSession {
86279
86657
  await this.closeProcess();
86280
86658
  }
86281
86659
  }
86282
- if (this.#updates.sessionId().length === 0) {
86660
+ if (this.#nativeSessionId.length === 0) {
86283
86661
  await this.closeProcess();
86284
86662
  return;
86285
86663
  }
86286
- await this.#adapter.closeSession(this.#target(), AbortSignal.timeout(3e4));
86664
+ await this.#adapter.closeSession({ ...this.#target(), signal: AbortSignal.timeout(3e4) });
86287
86665
  };
86288
- closeProcess = () => this.#connection.closeProcess();
86289
- agentSettingsModelEffort = () => this.#connection.agentSettingsModelEffort();
86290
- race = (operation, exitMessage, signal) => this.#connection.race(operation, exitMessage, signal);
86291
- agentRequest(method, params, options) {
86292
- return this.#connection.connection.agent.request(
86293
- method,
86294
- params,
86295
- options
86296
- );
86297
- }
86298
- drained() {
86299
- return this.#updates.drained();
86300
- }
86301
- initializeAgent(signal) {
86302
- return this.#initializeAgent(signal);
86303
- }
86304
- async loadSession(signal, exitMessage) {
86305
- return await this.#loadSession(signal, exitMessage);
86306
- }
86666
+ closeProcess = async () => {
86667
+ if (this.#nativeIdentity.kind === "bound") {
86668
+ await this.#adapter.releaseSession({ ...this.#target(), signal: AbortSignal.timeout(3e4) });
86669
+ }
86670
+ this.#backgroundActivity = "none";
86671
+ };
86672
+ agentSettingsModelEffort = () => this.#modelEffort;
86673
+ #sessionParams = (signal) => ({
86674
+ ...this.#subscriber,
86675
+ scope: this.#scope,
86676
+ signal
86677
+ });
86678
+ createSession = (signal) => this.#adapter.createSession(this.#sessionParams(signal));
86679
+ forkSession = (sourceSessionId, signal) => this.#adapter.forkSession({ ...this.#sessionParams(signal), sourceNativeSessionId: sourceSessionId });
86680
+ openSession = (signal) => this.#adapter.openSession({ ...this.#sessionParams(signal), nativeSessionId: this.nativeSessionId() });
86681
+ openSessionWithReplay = async (signal) => (await this.#loadSession(signal)).opened;
86307
86682
  setConfigOptions(options) {
86308
86683
  this.#configOptions = options;
86309
86684
  this.#configRevision = crypto.randomUUID();
@@ -86321,7 +86696,7 @@ var AgentSession = class _AgentSession {
86321
86696
  this.#sessionTitle = title2;
86322
86697
  }
86323
86698
  assertNativeSession = (sessionId) => {
86324
- if (sessionId !== this.#updates.sessionId()) {
86699
+ if (sessionId !== this.#nativeSessionId) {
86325
86700
  throw new AcpExecutionError("ACP agent referenced an unknown session", {}, "invalid_agent_session");
86326
86701
  }
86327
86702
  };
@@ -86344,6 +86719,18 @@ function isNativeChatSessionId(agentId, sessionId) {
86344
86719
  return (agentId === "codex" || agentId === "claude" || agentId === "pi") && /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/iu.test(sessionId);
86345
86720
  }
86346
86721
 
86722
+ // src/engine/session/native/native-query.ts
86723
+ function nativeSessionQuery(options) {
86724
+ const externalize = options.externalizeSessionUpdate;
86725
+ return {
86726
+ agent: options.agent,
86727
+ cwd: options.cwd,
86728
+ additionalDirectories: options.additionalDirectories,
86729
+ signal: options.signal,
86730
+ ...externalize === void 0 ? {} : { externalizeUpdate: (update, signal) => externalize(options.sessionId, update, signal) }
86731
+ };
86732
+ }
86733
+
86347
86734
  // src/engine/session/turn/active-executions.ts
86348
86735
  var unreachable2 = (state) => {
86349
86736
  throw new AcpExecutionError("Unexpected execution state", { cause: state });
@@ -86543,21 +86930,29 @@ var SessionManager2 = class {
86543
86930
  if (retiring !== void 0) {
86544
86931
  await waitForSharedOperation(retiring, options.signal);
86545
86932
  }
86546
- const runtime = await this.#processes.startRetained(options.signal, start, this.#retention(options.sessionId));
86933
+ const stored = this.#store.read(options.sessionId);
86934
+ const capabilities = options.origin !== void 0 || stored instanceof FoundStoredSession && stored.session.prompted ? await options.adapter.getCapabilities(nativeSessionQuery(options)) : unsupportedSessionCapabilities();
86935
+ const runtime = await this.#processes.startRetained(
86936
+ options.signal,
86937
+ () => start(capabilities),
86938
+ this.#retention(options.sessionId)
86939
+ );
86547
86940
  this.#executionProcesses.retain(options.sessionId, runtime);
86548
86941
  return runtime;
86549
86942
  }
86550
86943
  async #startPreparation(options, recovery, metrics = unmeasuredOperationMetrics) {
86551
86944
  return await this.#executionProcesses.prepare(options.sessionId, async () => {
86945
+ const effectiveOptions = options.origin === void 0 && this.#sessionIdentity === "native" && isNativeChatSessionId(options.agent.id, options.sessionId) && this.#store.read(options.sessionId) instanceof MissingStoredSession ? { ...options, origin: { kind: "import", nativeSessionId: options.sessionId, title: "" } } : options;
86552
86946
  return await this.#startRetainedSessionProcess(
86553
- options,
86554
- async () => await AgentSession.start(
86555
- options.origin === void 0 && this.#sessionIdentity === "native" && isNativeChatSessionId(options.agent.id, options.sessionId) && this.#store.read(options.sessionId) instanceof MissingStoredSession ? { ...options, origin: { kind: "import", nativeSessionId: options.sessionId, title: "" } } : options,
86947
+ effectiveOptions,
86948
+ async (capabilities) => await AgentSession.start(
86949
+ effectiveOptions,
86556
86950
  recovery,
86557
86951
  () => this.#observer,
86558
86952
  this.#store,
86559
86953
  metrics,
86560
- options.adapter
86954
+ options.adapter,
86955
+ capabilities
86561
86956
  )
86562
86957
  );
86563
86958
  });
@@ -86572,13 +86967,14 @@ var SessionManager2 = class {
86572
86967
  this.#store.remove(options.sessionId);
86573
86968
  return await this.#startRetainedSessionProcess(
86574
86969
  options,
86575
- async () => await AgentSession.start(
86970
+ async (capabilities) => await AgentSession.start(
86576
86971
  options,
86577
86972
  recovery,
86578
86973
  () => this.#observer,
86579
86974
  this.#store,
86580
86975
  metrics,
86581
- options.adapter
86976
+ options.adapter,
86977
+ capabilities
86582
86978
  )
86583
86979
  );
86584
86980
  });
@@ -86590,13 +86986,14 @@ var SessionManager2 = class {
86590
86986
  await this.#retireSessionProcess(options.sessionId, existing, async () => await existing.close());
86591
86987
  const runtime = await this.#startRetainedSessionProcess(
86592
86988
  options,
86593
- async () => await AgentSession.start(
86989
+ async (capabilities) => await AgentSession.start(
86594
86990
  options,
86595
86991
  recovery,
86596
86992
  () => this.#observer,
86597
86993
  this.#store,
86598
86994
  unmeasuredOperationMetrics,
86599
- options.adapter
86995
+ options.adapter,
86996
+ capabilities
86600
86997
  )
86601
86998
  );
86602
86999
  try {
@@ -87207,7 +87604,7 @@ var SessionManager2 = class {
87207
87604
  };
87208
87605
 
87209
87606
  // src/engine/session/native/native-session-browser.ts
87210
- import { randomUUID as randomUUID15 } from "node:crypto";
87607
+ import { randomUUID as randomUUID14 } from "node:crypto";
87211
87608
 
87212
87609
  // src/engine/session/workspace/local-authorization-error.ts
87213
87610
  var LocalAuthorizationError = class extends OperationError {
@@ -87266,17 +87663,14 @@ var NativeSessionService = class {
87266
87663
  (scoped) => this.#sessions.withNativeSessionOperation(
87267
87664
  scoped,
87268
87665
  nativeSessionId,
87269
- (target) => target.adapter.readSessionHistory(
87270
- target.cwd,
87271
- target.additionalDirectories,
87272
- {
87666
+ (target) => target.adapter.readSessionHistory({
87667
+ query: nativeSessionQuery(target),
87668
+ request: {
87273
87669
  nativeSessionId,
87274
87670
  eventLimit,
87275
- cursor,
87276
- sessionId: target.sessionId
87277
- },
87278
- target.signal
87279
- )
87671
+ cursor
87672
+ }
87673
+ })
87280
87674
  )
87281
87675
  );
87282
87676
  #execute = async (command, signal) => {
@@ -87307,7 +87701,7 @@ var NativeSessionService = class {
87307
87701
  queuedCancellation: "before-start"
87308
87702
  };
87309
87703
  }
87310
- const capabilities = await options.adapter.getCapabilities(cwd, signal);
87704
+ const capabilities = await options.adapter.getCapabilities(nativeSessionQuery(options));
87311
87705
  if (!capabilities.listSessions) {
87312
87706
  throw new AcpExecutionError(
87313
87707
  "This Agent does not support native session listing",
@@ -87322,7 +87716,7 @@ var NativeSessionService = class {
87322
87716
  if (authorized === null) {
87323
87717
  return null;
87324
87718
  }
87325
- const entryId = decodeIdentifier(randomUUID15());
87719
+ const entryId = decodeIdentifier(randomUUID14());
87326
87720
  if (this.#entries.size >= 5e3) {
87327
87721
  this.#entries.clear();
87328
87722
  }
@@ -87361,7 +87755,7 @@ var NativeSessionService = class {
87361
87755
  }
87362
87756
  cursor = known.cursor;
87363
87757
  }
87364
- const page = await options.adapter.listSessions(cwd, cursor, signal);
87758
+ const page = await options.adapter.listSessions({ query: nativeSessionQuery(options), cursor });
87365
87759
  const entries = [];
87366
87760
  for (const info of page.sessions) {
87367
87761
  const entry = await register(info);
@@ -87378,7 +87772,7 @@ var NativeSessionService = class {
87378
87772
  "invalid_native_session_response"
87379
87773
  );
87380
87774
  }
87381
- nextCursor = decodeIdentifier(randomUUID15());
87775
+ nextCursor = decodeIdentifier(randomUUID14());
87382
87776
  if (this.#cursors.size >= 500) {
87383
87777
  this.#cursors.clear();
87384
87778
  }
@@ -87396,15 +87790,14 @@ var NativeSessionService = class {
87396
87790
  };
87397
87791
  }
87398
87792
  if (command.action === "find") {
87399
- const found = await options.adapter.findSession(
87400
- cwd,
87401
- command.nativeSessionId,
87402
- {
87793
+ const found = await options.adapter.findSession({
87794
+ query: nativeSessionQuery(options),
87795
+ nativeSessionId: command.nativeSessionId,
87796
+ budget: {
87403
87797
  maximumPages: 500,
87404
87798
  maximumEntries: 500
87405
- },
87406
- signal
87407
- );
87799
+ }
87800
+ });
87408
87801
  const entry = await register(found);
87409
87802
  if (entry !== null) {
87410
87803
  return { ...envelope2, action: "find", entry };
@@ -87542,15 +87935,14 @@ var NativeSessionService = class {
87542
87935
  }
87543
87936
  };
87544
87937
  resolveTarget = async (command, options, selected) => {
87545
- const info = await options.adapter.findSession(
87546
- options.cwd,
87547
- selected.nativeSessionId,
87548
- {
87938
+ const info = await options.adapter.findSession({
87939
+ query: nativeSessionQuery(options),
87940
+ nativeSessionId: selected.nativeSessionId,
87941
+ budget: {
87549
87942
  maximumPages: 100,
87550
87943
  maximumEntries: null
87551
- },
87552
- options.signal
87553
- ).catch((cause) => {
87944
+ }
87945
+ }).catch((cause) => {
87554
87946
  options.signal.throwIfAborted();
87555
87947
  if (cause instanceof AcpExecutionError && cause.code === "native_session_not_found") {
87556
87948
  throw new AcpExecutionError(
@@ -87819,7 +88211,7 @@ async function settleAbandonedTurn(projection, operations, cancellation) {
87819
88211
  }
87820
88212
 
87821
88213
  // src/engine/session/turn/execution-receipts.ts
87822
- import { createHash as createHash7, randomUUID as randomUUID16 } from "node:crypto";
88214
+ import { createHash as createHash7, randomUUID as randomUUID15 } from "node:crypto";
87823
88215
  var MAX_TERMINAL_RECEIPTS = 1024;
87824
88216
  var ExecutionReceipts = class {
87825
88217
  #executions = /* @__PURE__ */ new Map();
@@ -87960,7 +88352,7 @@ var ExecutionReceipts = class {
87960
88352
  ).digest("hex");
87961
88353
  this.#save(commandId, {
87962
88354
  admissionOrder: this.#nextAdmissionOrder(),
87963
- attemptId: randomUUID16(),
88355
+ attemptId: randomUUID15(),
87964
88356
  commandHash,
87965
88357
  sessionId,
87966
88358
  started: false,
@@ -88042,7 +88434,7 @@ var ExecutionReceipts = class {
88042
88434
  if (identity2 !== void 0) {
88043
88435
  return identity2.sessionId === sessionId && identity2.commandHash === commandHash ? { kind: "expired" } : { kind: "conflict" };
88044
88436
  }
88045
- const attemptId = randomUUID16();
88437
+ const attemptId = randomUUID15();
88046
88438
  this.#save(commandId, {
88047
88439
  admissionOrder: this.#nextAdmissionOrder(),
88048
88440
  attemptId,
@@ -88169,7 +88561,7 @@ var RuntimeTurnActivity = class {
88169
88561
  };
88170
88562
 
88171
88563
  // src/engine/session/turn/active-turn.ts
88172
- import { randomUUID as randomUUID17 } from "node:crypto";
88564
+ import { randomUUID as randomUUID16 } from "node:crypto";
88173
88565
  var ActiveRuntimeTurn = class {
88174
88566
  attemptId;
88175
88567
  command;
@@ -88179,7 +88571,7 @@ var ActiveRuntimeTurn = class {
88179
88571
  #dispatch;
88180
88572
  #sequence = 0;
88181
88573
  #interaction = null;
88182
- #epoch = decodeIdentifier(randomUUID17());
88574
+ #epoch = decodeIdentifier(randomUUID16());
88183
88575
  constructor(command, attemptId) {
88184
88576
  this.attemptId = attemptId;
88185
88577
  this.command = command;
@@ -88745,11 +89137,11 @@ import { extname as extname2, join as join29 } from "node:path";
88745
89137
  import { pathToFileURL as pathToFileURL3 } from "node:url";
88746
89138
 
88747
89139
  // src/engine/storage/files/scratch-directory.ts
88748
- import { randomUUID as randomUUID18 } from "node:crypto";
89140
+ import { randomUUID as randomUUID17 } from "node:crypto";
88749
89141
  import { lstat as lstat4, mkdir as mkdir5, readdir as readdir6, readFile as readFile6, realpath as realpath7, rename as rename4, rm as rm3, stat as stat6, utimes, writeFile as writeFile2 } from "node:fs/promises";
88750
89142
  import { dirname as dirname11, join as join28 } from "node:path";
88751
89143
  async function atomicWrite(path7, bytes, signal) {
88752
- const temporary = `${path7}.${randomUUID18()}.tmp`;
89144
+ const temporary = `${path7}.${randomUUID17()}.tmp`;
88753
89145
  try {
88754
89146
  await writeFile2(temporary, bytes, { mode: 384, signal });
88755
89147
  signal.throwIfAborted();
@@ -88761,7 +89153,7 @@ async function atomicWrite(path7, bytes, signal) {
88761
89153
  var ScratchDirectory = class {
88762
89154
  #root;
88763
89155
  constructor(parent) {
88764
- this.#root = join28(parent, randomUUID18());
89156
+ this.#root = join28(parent, randomUUID17());
88765
89157
  }
88766
89158
  /** Refreshes this directory's lease and removes sibling directories whose lease is older than `leaseMilliseconds`. */
88767
89159
  refreshLease = async (leaseMilliseconds) => {
@@ -90767,7 +91159,7 @@ function createNativeSessionCommands(context) {
90767
91159
  }
90768
91160
 
90769
91161
  // src/engine/session/prompt/apply-session-configuration.ts
90770
- import { randomUUID as randomUUID19 } from "node:crypto";
91162
+ import { randomUUID as randomUUID18 } from "node:crypto";
90771
91163
  function invalidSessionConfiguration(message) {
90772
91164
  return new AcpExecutionError(message, {}, "invalid_session_configuration");
90773
91165
  }
@@ -90905,7 +91297,7 @@ async function applySessionConfigurationSelection(sessions, options, selection,
90905
91297
  booleanValue: selection.booleanValue,
90906
91298
  configId: selection.configId,
90907
91299
  cwd,
90908
- requestId: `cfg_${randomUUID19()}`,
91300
+ requestId: `cfg_${randomUUID18()}`,
90909
91301
  sessionId,
90910
91302
  signal,
90911
91303
  value: selection.value,
@@ -90971,7 +91363,11 @@ async function executePrompt({
90971
91363
  command.additionalDirectoryIds,
90972
91364
  signal
90973
91365
  );
90974
- const { agent, adapter } = await resolveAgent(command.agentId, signal, command.sessionId);
91366
+ const { agent, adapter, externalizeSessionUpdate } = await resolveAgent(
91367
+ command.agentId,
91368
+ signal,
91369
+ command.sessionId
91370
+ );
90975
91371
  const availability = await waitForSessionAvailability(signal);
90976
91372
  if (availability.kind === "busy") {
90977
91373
  throw new AcpExecutionError("Another prompt is already running in this conversation", {}, "session_busy");
@@ -90989,6 +91385,7 @@ async function executePrompt({
90989
91385
  const recovery = command.historyPolicy === SessionHistoryPolicy.ExecutionOnly ? { kind: "execution-only" } : { kind: "interactive-only" };
90990
91386
  const preparation = {
90991
91387
  adapter,
91388
+ ...externalizeSessionUpdate === void 0 ? {} : { externalizeSessionUpdate },
90992
91389
  additionalDirectories: resolved.additionalDirectories,
90993
91390
  agent: executionAgent,
90994
91391
  cwd: resolved.cwd,
@@ -91043,6 +91440,7 @@ async function executePrompt({
91043
91440
  if (availability.disposition === SessionPromptDisposition.Steer) {
91044
91441
  await sessions.steerPrompt({
91045
91442
  adapter,
91443
+ ...externalizeSessionUpdate === void 0 ? {} : { externalizeSessionUpdate },
91046
91444
  additionalDirectories: resolved.additionalDirectories,
91047
91445
  agent: executionAgent,
91048
91446
  commandId: command.commandId,
@@ -91059,6 +91457,7 @@ async function executePrompt({
91059
91457
  } else {
91060
91458
  const result = await sessions.runPrompt({
91061
91459
  adapter,
91460
+ ...externalizeSessionUpdate === void 0 ? {} : { externalizeSessionUpdate },
91062
91461
  additionalDirectories: resolved.additionalDirectories,
91063
91462
  agent: executionAgent,
91064
91463
  commandId: command.commandId,
@@ -91195,7 +91594,7 @@ var sessionPromptCommand = {
91195
91594
  // package.json
91196
91595
  var package_default = {
91197
91596
  name: "@moxt-ai/mobius",
91198
- version: "0.0.359",
91597
+ version: "0.0.360",
91199
91598
  description: "Mobius CLI for pairing and running local AI agent services.",
91200
91599
  type: "module",
91201
91600
  bin: {
@@ -92457,7 +92856,7 @@ async function runRuntime(config2, parentSignal, timer = systemTimer, options =
92457
92856
  const publisher = new RuntimeSessionEventPublisher(timer);
92458
92857
  const externalContent = __using(_stack, new LocalExternalContentStore(stateDirectory), true);
92459
92858
  const processes = new AgentProcessPool(config2.localContext.maxAcpProcesses, timer);
92460
- const adapters = createRuntimeAdapterRegistry(
92859
+ const { adapters, externalizeSessionUpdate } = createRuntimeAdapterRegistry(
92461
92860
  config2.adapters,
92462
92861
  processes,
92463
92862
  (sessionId, content, contentSignal) => externalContent.put({ ...content, sessionId, signal: contentSignal }),
@@ -92467,7 +92866,11 @@ async function runRuntime(config2, parentSignal, timer = systemTimer, options =
92467
92866
  const catalogAgent = await resolveCatalogAgent(config2, agentId, resolveSignal);
92468
92867
  const environment = sessionId === void 0 ? void 0 : config2.sessionEnvironment?.({ sessionId, agentId });
92469
92868
  const agent = environment === void 0 ? catalogAgent : catalogAgent.withEnvironment({ ...catalogAgent.environment, ...environment });
92470
- return { agent, adapter: adapters.resolve(catalogAgent) };
92869
+ return {
92870
+ agent,
92871
+ adapter: adapters.resolve(catalogAgent),
92872
+ externalizeSessionUpdate
92873
+ };
92471
92874
  };
92472
92875
  const layer = buildSessionLayer({
92473
92876
  processes,