@moxt-ai/mobius 0.0.183 → 0.0.185

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/runtime.js CHANGED
@@ -27549,6 +27549,18 @@ function isProgressMessage(content) {
27549
27549
  // src/acp/agent-connection.ts
27550
27550
  import { spawn as spawn4 } from "node:child_process";
27551
27551
  import { ndJsonStream as ndJsonStream2, RequestError as RequestError3 } from "@agentclientprotocol/sdk";
27552
+ function requestErrorMessage(error62) {
27553
+ const fallback = truncate(error62.message, 500);
27554
+ if (error62.message !== "Internal error" || !isRecord4(error62.data)) {
27555
+ return fallback;
27556
+ }
27557
+ const agentError = error62.data["error"];
27558
+ if (!isRecord4(agentError)) {
27559
+ return fallback;
27560
+ }
27561
+ const message = agentError["message"];
27562
+ return typeof message === "string" && message.length > 0 ? truncate(message, 500) : fallback;
27563
+ }
27552
27564
  function readableWebStream(input2) {
27553
27565
  let streamOpen = true;
27554
27566
  return new ReadableStream({
@@ -27720,7 +27732,7 @@ var AgentConnection = class {
27720
27732
  );
27721
27733
  }
27722
27734
  if (error62 instanceof RequestError3) {
27723
- throw new AcpExecutionError(truncate(error62.message, 500), { cause: error62 }, "acp_agent_error");
27735
+ throw new AcpExecutionError(requestErrorMessage(error62), { cause: error62 }, "acp_agent_error");
27724
27736
  }
27725
27737
  throw error62;
27726
27738
  }
@@ -34528,11 +34540,11 @@ var AgentSession = class _AgentSession {
34528
34540
  }
34529
34541
  throw new AcpExecutionError("ACP agent initialization failed");
34530
34542
  }
34531
- static start = async (options, getObserver, store, metrics, contentExternalizer) => await _AgentSession.#start(
34543
+ static start = async (options, recovery, getObserver, store, metrics, contentExternalizer) => await _AgentSession.#start(
34532
34544
  options,
34533
34545
  getObserver,
34534
34546
  store,
34535
- async (runtime) => await runtime.initialize(options.signal, options.origin),
34547
+ async (runtime) => await runtime.initialize(options.signal, recovery, options.origin),
34536
34548
  metrics,
34537
34549
  contentExternalizer
34538
34550
  );
@@ -34570,6 +34582,16 @@ var AgentSession = class _AgentSession {
34570
34582
  const history = await this.#completedHistory(signal, "ACP agent exited while loading history");
34571
34583
  return await embedLocalHistoryImages(await history.snapshot(), signal);
34572
34584
  };
34585
+ ensureHistoryLoaded = async (signal) => {
34586
+ if (!this.#capabilities.loadSession) {
34587
+ throw new AcpExecutionError(
34588
+ "This Agent restores context but does not provide message history.",
34589
+ {},
34590
+ "native_history_unsupported"
34591
+ );
34592
+ }
34593
+ await this.#completedHistory(signal, "ACP agent exited while loading history");
34594
+ };
34573
34595
  loadHistoryEventsV2 = async (eventLimit, cursor, signal) => {
34574
34596
  if (!this.#capabilities.loadSession) {
34575
34597
  throw new AcpExecutionError(
@@ -34742,7 +34764,7 @@ var AgentSession = class _AgentSession {
34742
34764
  128
34743
34765
  );
34744
34766
  }
34745
- initialize = async (signal, origin) => {
34767
+ initialize = async (signal, recovery, origin) => {
34746
34768
  await this.#initializeAgent(signal);
34747
34769
  let stored = this.#metrics.measureSync(
34748
34770
  "session-state-read",
@@ -34811,7 +34833,19 @@ var AgentSession = class _AgentSession {
34811
34833
  this.#prompted = stored.session.prompted;
34812
34834
  this.#sessionTitle = stored.session.title;
34813
34835
  this.#restored = true;
34814
- if (this.#capabilities.resumeSession) {
34836
+ if (recovery.kind === "history-required") {
34837
+ if (!this.#capabilities.loadSession) {
34838
+ throw new AcpExecutionError(
34839
+ "This Agent restores context but does not provide message history.",
34840
+ {},
34841
+ "native_history_unsupported"
34842
+ );
34843
+ }
34844
+ lifecycleResponse = await this.#metrics.measure(
34845
+ "session-load",
34846
+ async () => (await this.#loadSession(signal, "ACP agent exited while loading a session")).response
34847
+ );
34848
+ } else if (this.#capabilities.resumeSession) {
34815
34849
  lifecycleResponse = await this.#metrics.measure(
34816
34850
  "session-resume",
34817
34851
  async () => await this.race(
@@ -36429,12 +36463,13 @@ var AgentRuntimeManager = class {
36429
36463
  this.#executionProcesses.retain(options.sessionId, runtime);
36430
36464
  return runtime;
36431
36465
  }
36432
- async #startPreparation(options, metrics = unmeasuredOperationMetrics) {
36466
+ async #startPreparation(options, recovery, metrics = unmeasuredOperationMetrics) {
36433
36467
  return await this.#executionProcesses.prepare(options.sessionId, async () => {
36434
36468
  return await this.#startRetainedSessionProcess(
36435
36469
  options,
36436
36470
  async () => await AgentSession.start(
36437
36471
  options.origin === void 0 && this.#sessionIdentity === "native" && isNativeChatSessionId(options.agent.id, options.sessionId) && this.#store.read(options.sessionId) instanceof MissingAcpStoredSession ? { ...options, origin: { kind: "import", nativeSessionId: options.sessionId } } : options,
36472
+ recovery,
36438
36473
  () => this.#observer,
36439
36474
  this.#store,
36440
36475
  metrics,
@@ -36443,7 +36478,7 @@ var AgentRuntimeManager = class {
36443
36478
  );
36444
36479
  });
36445
36480
  }
36446
- async #replacePreparation(existing, options, metrics) {
36481
+ async #replacePreparation(existing, options, recovery, metrics) {
36447
36482
  return await this.#executionProcesses.prepare(options.sessionId, async () => {
36448
36483
  await this.#retireSessionProcess(
36449
36484
  options.sessionId,
@@ -36455,6 +36490,7 @@ var AgentRuntimeManager = class {
36455
36490
  options,
36456
36491
  async () => await AgentSession.start(
36457
36492
  options,
36493
+ recovery,
36458
36494
  () => this.#observer,
36459
36495
  this.#store,
36460
36496
  metrics,
@@ -36471,6 +36507,7 @@ var AgentRuntimeManager = class {
36471
36507
  options,
36472
36508
  async () => await AgentSession.start(
36473
36509
  options,
36510
+ { kind: "interactive-only" },
36474
36511
  () => this.#observer,
36475
36512
  this.#store,
36476
36513
  unmeasuredOperationMetrics,
@@ -36514,42 +36551,58 @@ var AgentRuntimeManager = class {
36514
36551
  return runtime;
36515
36552
  });
36516
36553
  }
36517
- prepareSession = async (options, metrics = unmeasuredOperationMetrics) => this.#operations.run(options, async (options2) => {
36518
- const stored = metrics.measureSync("session-state-read", () => this.#store.read(options2.sessionId));
36519
- if (stored instanceof FoundAcpStoredSession && this.#nativeOperations.has(`${stored.session.agentId}:${stored.session.nativeSessionId}`)) {
36520
- throw new AcpExecutionError("The native session is being managed", {}, "session_busy");
36521
- }
36522
- const pending = this.#executionProcesses.pending(options2.sessionId);
36523
- if (pending !== void 0) {
36524
- const runtime2 = await metrics.measure(
36525
- "session-preparation-wait",
36526
- async () => await waitForSharedOperation(pending, options2.signal)
36527
- );
36528
- if (runtime2.belongsTo(options2.agent.id, options2.cwd, options2.additionalDirectories)) {
36529
- this.#executionProcesses.touch(options2.sessionId, runtime2);
36530
- return runtime2.prepared();
36531
- }
36532
- return await this.prepareSession(options2, metrics);
36533
- }
36534
- const existing = this.#executionProcesses.get(options2.sessionId);
36535
- if (existing !== void 0) {
36536
- if (existing.belongsTo(options2.agent.id, options2.cwd, options2.additionalDirectories)) {
36537
- this.#executionProcesses.touch(options2.sessionId, existing);
36538
- return existing.prepared();
36554
+ async #prepareSession(options, recovery, metrics = unmeasuredOperationMetrics) {
36555
+ return await this.#operations.run(options, async (options2) => {
36556
+ const stored = metrics.measureSync("session-state-read", () => this.#store.read(options2.sessionId));
36557
+ if (stored instanceof FoundAcpStoredSession && this.#nativeOperations.has(`${stored.session.agentId}:${stored.session.nativeSessionId}`)) {
36558
+ throw new AcpExecutionError("The native session is being managed", {}, "session_busy");
36539
36559
  }
36540
- if (!existing.canRebind()) {
36541
- throw new AcpExecutionError(
36542
- "The agent or workspace cannot change after a conversation has started",
36543
- {},
36544
- "session_identity_mismatch"
36560
+ const pending = this.#executionProcesses.pending(options2.sessionId);
36561
+ if (pending !== void 0) {
36562
+ const runtime2 = await metrics.measure(
36563
+ "session-preparation-wait",
36564
+ async () => await waitForSharedOperation(pending, options2.signal)
36545
36565
  );
36566
+ if (runtime2.belongsTo(options2.agent.id, options2.cwd, options2.additionalDirectories)) {
36567
+ this.#executionProcesses.touch(options2.sessionId, runtime2);
36568
+ if (recovery.kind === "history-required") {
36569
+ await metrics.measure(
36570
+ "session-load",
36571
+ async () => await runtime2.ensureHistoryLoaded(options2.signal)
36572
+ );
36573
+ }
36574
+ return runtime2.prepared();
36575
+ }
36576
+ return await this.#prepareSession(options2, recovery, metrics);
36577
+ }
36578
+ const existing = this.#executionProcesses.get(options2.sessionId);
36579
+ if (existing !== void 0) {
36580
+ if (existing.belongsTo(options2.agent.id, options2.cwd, options2.additionalDirectories)) {
36581
+ this.#executionProcesses.touch(options2.sessionId, existing);
36582
+ if (recovery.kind === "history-required") {
36583
+ await metrics.measure(
36584
+ "session-load",
36585
+ async () => await existing.ensureHistoryLoaded(options2.signal)
36586
+ );
36587
+ }
36588
+ return existing.prepared();
36589
+ }
36590
+ if (!existing.canRebind()) {
36591
+ throw new AcpExecutionError(
36592
+ "The agent or workspace cannot change after a conversation has started",
36593
+ {},
36594
+ "session_identity_mismatch"
36595
+ );
36596
+ }
36597
+ const runtime2 = await this.#replacePreparation(existing, options2, recovery, metrics);
36598
+ return runtime2.prepared();
36546
36599
  }
36547
- const runtime2 = await this.#replacePreparation(existing, options2, metrics);
36548
- return runtime2.prepared();
36549
- }
36550
- const runtime = await this.#startPreparation(options2, metrics);
36551
- return runtime.prepared();
36552
- });
36600
+ const runtime = await this.#startPreparation(options2, recovery, metrics);
36601
+ return runtime.prepared();
36602
+ });
36603
+ }
36604
+ prepareSession = async (options, metrics = unmeasuredOperationMetrics) => await this.#prepareSession(options, { kind: "interactive-only" }, metrics);
36605
+ restoreSession = async (options, metrics = unmeasuredOperationMetrics) => await this.#prepareSession(options, { kind: "history-required" }, metrics);
36553
36606
  /**
36554
36607
  * Opens a short-lived native ACP session only to read the local Agent's
36555
36608
  * authoritative settings. Its identity and store are private to this
@@ -36563,6 +36616,7 @@ var AgentRuntimeManager = class {
36563
36616
  ...options2,
36564
36617
  sessionId: `agent-settings-${crypto.randomUUID()}`
36565
36618
  },
36619
+ { kind: "interactive-only" },
36566
36620
  () => this.#agentSettingsObserver,
36567
36621
  new MemoryAcpSessionStore(),
36568
36622
  unmeasuredOperationMetrics,
@@ -36600,7 +36654,7 @@ var AgentRuntimeManager = class {
36600
36654
  );
36601
36655
  }
36602
36656
  return await this.#executionProcesses.use(options2.sessionId, async () => {
36603
- const runtime = await this.#startPreparation(options2, metrics);
36657
+ const runtime = await this.#startPreparation(options2, { kind: "interactive-only" }, metrics);
36604
36658
  try {
36605
36659
  return runtime.prepared();
36606
36660
  } finally {
@@ -36620,7 +36674,7 @@ var AgentRuntimeManager = class {
36620
36674
  }
36621
36675
  const existing = this.#executionProcesses.get(options2.sessionId);
36622
36676
  if (existing === void 0) {
36623
- return (await this.#startPreparation(options2)).prepared();
36677
+ return (await this.#startPreparation(options2, { kind: "interactive-only" })).prepared();
36624
36678
  }
36625
36679
  if (!existing.belongsTo(options2.agent.id, options2.cwd, options2.additionalDirectories)) {
36626
36680
  throw new AcpExecutionError(
@@ -36805,7 +36859,7 @@ var AgentRuntimeManager = class {
36805
36859
  const temporaryOptions = { ...options2, sessionId: temporarySessionId };
36806
36860
  return await this.#executionProcesses.use(temporarySessionId, async () => {
36807
36861
  try {
36808
- const runtime = await this.#startPreparation(temporaryOptions);
36862
+ const runtime = await this.#startPreparation(temporaryOptions, { kind: "interactive-only" });
36809
36863
  let adopted = false;
36810
36864
  try {
36811
36865
  const nativeSessionId = runtime.nativeSessionId();
@@ -36971,7 +37025,7 @@ var AgentRuntimeManager = class {
36971
37025
  return await this.#executionProcesses.use(options2.sessionId, async () => {
36972
37026
  this.#nativeOperations.add(key);
36973
37027
  try {
36974
- const runtime = await this.#startPreparation({ ...options2, origin });
37028
+ const runtime = await this.#startPreparation({ ...options2, origin }, { kind: "interactive-only" });
36975
37029
  const openedKey = `${options2.agent.id}:${runtime.nativeSessionId()}`;
36976
37030
  this.#nativeOperations.add(openedKey);
36977
37031
  try {
@@ -41319,7 +41373,7 @@ async function executePrompt({
41319
41373
  }
41320
41374
 
41321
41375
  // src/daemon-session-commands.ts
41322
- async function prepareSession(command, config2, directories, audit, sessions, metrics, signal) {
41376
+ async function prepareSession(command, recovery, config2, directories, audit, sessions, metrics, signal) {
41323
41377
  return await metrics.measure("prepare-total", async () => {
41324
41378
  const resolved = await metrics.measure(
41325
41379
  "workspace-resolve",
@@ -41339,7 +41393,7 @@ async function prepareSession(command, config2, directories, audit, sessions, me
41339
41393
  sessionId: command.sessionId,
41340
41394
  signal
41341
41395
  };
41342
- const prepared = command.transient === true ? await sessions.inspectSession(preparation, metrics) : await sessions.prepareSession(preparation, metrics);
41396
+ const prepared = command.transient === true ? await sessions.inspectSession(preparation, metrics) : recovery.kind === "history-required" ? await sessions.restoreSession(preparation, metrics) : await sessions.prepareSession(preparation, metrics);
41343
41397
  const configuration = command.configuration;
41344
41398
  const configOptions = configuration === void 0 ? prepared.configOptions : await metrics.measure(
41345
41399
  "configuration",
@@ -41409,7 +41463,16 @@ async function executeWorkspaceList(socket, command, directories, audit, signal)
41409
41463
  async function executeSessionPrepare(socket, command, config2, directories, audit, sessions, diagnostics, signal) {
41410
41464
  const metrics = new AccumulatingOperationMetrics();
41411
41465
  try {
41412
- const readyEvent = await prepareSession(command, config2, directories, audit, sessions, metrics, signal);
41466
+ const readyEvent = await prepareSession(
41467
+ command,
41468
+ { kind: "interactive-only" },
41469
+ config2,
41470
+ directories,
41471
+ audit,
41472
+ sessions,
41473
+ metrics,
41474
+ signal
41475
+ );
41413
41476
  send(socket, {
41414
41477
  ...readyEvent,
41415
41478
  runtimeTimings: metrics.snapshot()
@@ -41458,6 +41521,7 @@ async function executeSessionRestore(socket, command, config2, directories, audi
41458
41521
  sessionId: command.sessionId,
41459
41522
  sessionState: "provisioned"
41460
41523
  },
41524
+ { kind: "history-required" },
41461
41525
  config2,
41462
41526
  directories,
41463
41527
  audit,