@moxt-ai/mobius 0.0.387 → 0.0.389

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 (57) hide show
  1. package/dist/{chunk-A62FEGIN.js → chunk-77O2RBRQ.js} +232 -188
  2. package/dist/{chunk-A62FEGIN.js.map → chunk-77O2RBRQ.js.map} +4 -4
  3. package/dist/{chunk-S7PKNDIS.js → chunk-Z6ERJZ2H.js} +2 -2
  4. package/dist/{chunk-S7PKNDIS.js.map → chunk-Z6ERJZ2H.js.map} +1 -1
  5. package/dist/{cli-43LPJ5ID.js → cli-I4NLPVNV.js} +3 -3
  6. package/dist/cli.js +2 -2
  7. package/dist/engine/runtime/command/registry/prompt.d.ts.map +1 -1
  8. package/dist/engine/runtime/command/registry/prompt.js +1 -3
  9. package/dist/engine/runtime/command/registry/prompt.js.map +1 -1
  10. package/dist/engine/runtime/relay/session-event-publisher.d.ts.map +1 -1
  11. package/dist/engine/runtime/relay/session-event-publisher.js +2 -4
  12. package/dist/engine/runtime/relay/session-event-publisher.js.map +1 -1
  13. package/dist/engine/session/api/session-layer.js +3 -3
  14. package/dist/engine/session/api/session-layer.js.map +1 -1
  15. package/dist/engine/session/live/agent-session.d.ts +13 -3
  16. package/dist/engine/session/live/agent-session.d.ts.map +1 -1
  17. package/dist/engine/session/live/agent-session.js +27 -23
  18. package/dist/engine/session/live/agent-session.js.map +1 -1
  19. package/dist/engine/session/manager/session-manager.d.ts +2 -0
  20. package/dist/engine/session/manager/session-manager.d.ts.map +1 -1
  21. package/dist/engine/session/manager/session-manager.js +27 -28
  22. package/dist/engine/session/manager/session-manager.js.map +1 -1
  23. package/dist/engine/session/prompt/execute-prompt.d.ts +7 -8
  24. package/dist/engine/session/prompt/execute-prompt.d.ts.map +1 -1
  25. package/dist/engine/session/prompt/execute-prompt.js +14 -11
  26. package/dist/engine/session/prompt/execute-prompt.js.map +1 -1
  27. package/dist/engine/session/prompt/prompt-lifecycle.d.ts +8 -4
  28. package/dist/engine/session/prompt/prompt-lifecycle.d.ts.map +1 -1
  29. package/dist/engine/session/prompt/prompt-lifecycle.js +18 -17
  30. package/dist/engine/session/prompt/prompt-lifecycle.js.map +1 -1
  31. package/dist/engine/session/turn/active-executions.d.ts +27 -8
  32. package/dist/engine/session/turn/active-executions.d.ts.map +1 -1
  33. package/dist/engine/session/turn/active-executions.js +76 -22
  34. package/dist/engine/session/turn/active-executions.js.map +1 -1
  35. package/dist/engine/session/turn/active-turn.d.ts +10 -8
  36. package/dist/engine/session/turn/active-turn.d.ts.map +1 -1
  37. package/dist/engine/session/turn/active-turn.js +45 -36
  38. package/dist/engine/session/turn/active-turn.js.map +1 -1
  39. package/dist/engine/session/turn/execution-receipts.d.ts +6 -2
  40. package/dist/engine/session/turn/execution-receipts.d.ts.map +1 -1
  41. package/dist/engine/session/turn/execution-receipts.js +18 -32
  42. package/dist/engine/session/turn/execution-receipts.js.map +1 -1
  43. package/dist/engine/session/turn/session-execution.d.ts +4 -2
  44. package/dist/engine/session/turn/session-execution.d.ts.map +1 -1
  45. package/dist/engine/session/turn/session-execution.js +8 -7
  46. package/dist/engine/session/turn/session-execution.js.map +1 -1
  47. package/dist/engine/session/turn/session-turns.d.ts +0 -1
  48. package/dist/engine/session/turn/session-turns.d.ts.map +1 -1
  49. package/dist/engine/session/turn/session-turns.js +0 -1
  50. package/dist/engine/session/turn/session-turns.js.map +1 -1
  51. package/dist/engine.js +2 -2
  52. package/package.json +2 -2
  53. package/dist/engine/session/live/agent-turn.d.ts +0 -14
  54. package/dist/engine/session/live/agent-turn.d.ts.map +0 -1
  55. package/dist/engine/session/live/agent-turn.js +0 -16
  56. package/dist/engine/session/live/agent-turn.js.map +0 -1
  57. /package/dist/{cli-43LPJ5ID.js.map → cli-I4NLPVNV.js.map} +0 -0
@@ -3,7 +3,7 @@ import {
3
3
  __export,
4
4
  __using,
5
5
  package_default
6
- } from "./chunk-S7PKNDIS.js";
6
+ } from "./chunk-Z6ERJZ2H.js";
7
7
 
8
8
  // src/engine/runtime/relay/runtime-revocation.ts
9
9
  var runtimeRevocationCloseCode = 1008;
@@ -20760,6 +20760,27 @@ var lifecycleMetadataSchema = external_exports.discriminatedUnion("kind", [
20760
20760
  message: external_exports.string().min(1).max(500)
20761
20761
  }).readonly()
20762
20762
  ]);
20763
+ var isPromptTerminal = (payload) => {
20764
+ switch (payload.kind) {
20765
+ case "prompt.completed":
20766
+ case "prompt.failed":
20767
+ case "prompt.failed-before-start":
20768
+ return true;
20769
+ case "prompt.requested":
20770
+ case "prompt.started":
20771
+ case "session.queue.changed":
20772
+ case "session.permission.requested":
20773
+ case "session.permission.resolved":
20774
+ case "session.elicitation.requested":
20775
+ case "session.elicitation.resolved":
20776
+ return false;
20777
+ default: {
20778
+ const unknownKind = payload;
20779
+ void unknownKind;
20780
+ return false;
20781
+ }
20782
+ }
20783
+ };
20763
20784
  var sessionEventPayloadSchema = external_exports.discriminatedUnion("type", [
20764
20785
  external_exports.object({ payload: acpSessionUpdateSchema, type: external_exports.literal("acp") }).readonly(),
20765
20786
  external_exports.object({ payload: lifecycleMetadataSchema, type: external_exports.literal("lifecycle-metadata") }).readonly()
@@ -86005,23 +86026,6 @@ var SqliteSessionStore = class {
86005
86026
  };
86006
86027
  };
86007
86028
 
86008
- // src/engine/session/live/agent-turn.ts
86009
- var SESSION_CONTROL_COMMAND_ID = "session-control";
86010
- var AgentTurnState = class {
86011
- };
86012
- var IdleAgentTurn = class extends AgentTurnState {
86013
- commandId = SESSION_CONTROL_COMMAND_ID;
86014
- running = false;
86015
- };
86016
- var RunningAgentTurn = class extends AgentTurnState {
86017
- commandId;
86018
- running = true;
86019
- constructor(commandId) {
86020
- super();
86021
- this.commandId = commandId;
86022
- }
86023
- };
86024
-
86025
86029
  // src/engine/session/live/session-restore.ts
86026
86030
  function hasMethodNotFoundCode(cause) {
86027
86031
  const visited = /* @__PURE__ */ new Set();
@@ -86171,6 +86175,7 @@ async function restoreSession(session, signal, recovery, origin) {
86171
86175
  }
86172
86176
 
86173
86177
  // src/engine/session/live/agent-session.ts
86178
+ var SESSION_CONTROL_COMMAND_ID = "session-control";
86174
86179
  var AgentSession = class _AgentSession {
86175
86180
  // The restore surface: AgentSessionRestore members expose private state to
86176
86181
  // session-restore.ts only. The class keeps the fields private.
@@ -86215,6 +86220,7 @@ var AgentSession = class _AgentSession {
86215
86220
  #cwd;
86216
86221
  #environment;
86217
86222
  #getObserver;
86223
+ #agentCommand;
86218
86224
  #interactions;
86219
86225
  #mobiusSessionId;
86220
86226
  #metrics;
@@ -86235,8 +86241,8 @@ var AgentSession = class _AgentSession {
86235
86241
  #restored = false;
86236
86242
  #sessionTitle = null;
86237
86243
  #sessionUpdatedAt = "";
86238
- #turn = new IdleAgentTurn();
86239
- constructor(agent, cwd, additionalDirectories, mobiusSessionId, getObserver, store, metrics, adapter, externalize) {
86244
+ constructor(agent, cwd, additionalDirectories, mobiusSessionId, getObserver, agentCommand, store, metrics, adapter, externalize) {
86245
+ this.#agentCommand = () => agentCommand(this.#mobiusSessionId);
86240
86246
  this.#additionalDirectories = [...additionalDirectories];
86241
86247
  this.#adapter = adapter;
86242
86248
  this.#agentId = agent.id;
@@ -86251,7 +86257,7 @@ var AgentSession = class _AgentSession {
86251
86257
  cwd: () => this.#cwd,
86252
86258
  getToolCall: (toolCallId) => this.#store.events.getToolCall(this.#mobiusSessionId, toolCallId),
86253
86259
  sessionId: () => this.#mobiusSessionId,
86254
- commandId: () => this.#turn.commandId,
86260
+ commandId: () => this.#agentCommand() ?? SESSION_CONTROL_COMMAND_ID,
86255
86261
  assertNativeSession: this.assertNativeSession,
86256
86262
  observer: getObserver,
86257
86263
  recordSessionEvent: this.recordLifecycleEvent
@@ -86286,7 +86292,7 @@ var AgentSession = class _AgentSession {
86286
86292
  }
86287
86293
  };
86288
86294
  }
86289
- static async #start(options, getObserver, store, initialize, metrics, adapter) {
86295
+ static async #start(options, getObserver, agentCommand, store, initialize, metrics, adapter) {
86290
86296
  for (let attempt = 1; attempt <= 2; attempt += 1) {
86291
86297
  await metrics.measure(
86292
86298
  "executable-validation",
@@ -86300,6 +86306,7 @@ var AgentSession = class _AgentSession {
86300
86306
  options.additionalDirectories,
86301
86307
  options.sessionId,
86302
86308
  getObserver,
86309
+ agentCommand,
86303
86310
  store,
86304
86311
  metrics,
86305
86312
  adapter,
@@ -86326,9 +86333,10 @@ var AgentSession = class _AgentSession {
86326
86333
  }
86327
86334
  throw new AcpExecutionError("ACP agent initialization failed");
86328
86335
  }
86329
- static start = async (options, recovery, getObserver, store, metrics, adapter, capabilities = unsupportedSessionCapabilities()) => await _AgentSession.#start(
86336
+ static start = async (options, recovery, getObserver, agentCommand, store, metrics, adapter, capabilities = unsupportedSessionCapabilities()) => await _AgentSession.#start(
86330
86337
  options,
86331
86338
  getObserver,
86339
+ agentCommand,
86332
86340
  store,
86333
86341
  async (runtime) => {
86334
86342
  runtime.#capabilities = capabilities;
@@ -86339,8 +86347,6 @@ var AgentSession = class _AgentSession {
86339
86347
  );
86340
86348
  belongsTo = (agentId, cwd, additionalDirectories) => this.#agentId === agentId && this.#cwd === cwd && arraysEqual(this.#additionalDirectories, additionalDirectories);
86341
86349
  usesEnvironment = (environment) => recordsEqual(this.#environment, environment);
86342
- canRebind = () => !this.#prompted && !this.#turn.running;
86343
- hasRunningTurn = () => this.#turn.running;
86344
86350
  writeStoredSession = (updatedAt) => {
86345
86351
  this.#store.write(
86346
86352
  new StoredSession(
@@ -86671,10 +86677,8 @@ var AgentSession = class _AgentSession {
86671
86677
  cwd: this.#cwd,
86672
86678
  additionalDirectories: this.#additionalDirectories
86673
86679
  });
86674
- prompt = async (options) => {
86675
- if (this.#turn.running) {
86676
- throw new AcpExecutionError("Another prompt is already running in this conversation", {}, "session_busy");
86677
- }
86680
+ /** Loads what the Agent needs before it can receive a prompt; the Agent does not receive it yet. */
86681
+ preparePrompt = async (signal) => {
86678
86682
  if (!this.#capabilities.loadSession && this.#sessionLoad.kind === "not-requested") {
86679
86683
  this.#sessionLoad = {
86680
86684
  kind: "loaded",
@@ -86690,16 +86694,21 @@ var AgentSession = class _AgentSession {
86690
86694
  };
86691
86695
  }
86692
86696
  if (this.#capabilities.loadSession && this.#sessionLoad.kind !== "execution-only") {
86693
- await this.#completedHistory(options.signal);
86697
+ await this.#completedHistory(signal);
86694
86698
  }
86699
+ };
86700
+ /**
86701
+ * Hands a prepared prompt to the Agent. Precondition: `preparePrompt` completed and the Session's execution
86702
+ * authority records this command as started.
86703
+ */
86704
+ prompt = async (options) => {
86695
86705
  validatePromptContent(options, this.#capabilities);
86706
+ options.signal.throwIfAborted();
86696
86707
  if (this.#sessionTitle === null || this.#sessionTitle.length === 0) {
86697
86708
  this.#sessionTitle = conversationTitleFromText(options.prompt);
86698
86709
  }
86699
86710
  this.#prompted = true;
86700
86711
  this.writeStoredSession((/* @__PURE__ */ new Date()).toISOString());
86701
- const running = new RunningAgentTurn(options.commandId);
86702
- this.#turn = running;
86703
86712
  const lifecycle = options.lifecycle;
86704
86713
  if (lifecycle !== void 0) {
86705
86714
  await this.recordLifecycleEvent({
@@ -86757,10 +86766,12 @@ var AgentSession = class _AgentSession {
86757
86766
  throw error62;
86758
86767
  }
86759
86768
  throw failure2;
86760
- } finally {
86761
- this.#turn = new IdleAgentTurn();
86762
86769
  }
86763
86770
  };
86771
+ /**
86772
+ * Adds a steering prompt to the prompt the Agent holds. Precondition: the Session's execution authority accepts
86773
+ * steering into `options.targetCommandId`.
86774
+ */
86764
86775
  steer = async (options) => {
86765
86776
  if (!this.#capabilities.steering) {
86766
86777
  throw new AcpExecutionError(
@@ -86769,10 +86780,8 @@ var AgentSession = class _AgentSession {
86769
86780
  "steering_unsupported"
86770
86781
  );
86771
86782
  }
86772
- if (!this.#turn.running || this.#turn.commandId !== options.targetCommandId) {
86773
- throw new AcpExecutionError("The target turn is no longer active", {}, "steering_target_unavailable");
86774
- }
86775
86783
  validatePromptContent(options, this.#capabilities);
86784
+ options.signal.throwIfAborted();
86776
86785
  const lifecycle = options.lifecycle;
86777
86786
  if (lifecycle !== void 0) {
86778
86787
  await this.recordLifecycleEvent({
@@ -86830,7 +86839,7 @@ var AgentSession = class _AgentSession {
86830
86839
  signal.throwIfAborted();
86831
86840
  await this.#interactions.cancelPendingInteractions();
86832
86841
  signal.throwIfAborted();
86833
- if (this.#turn.running) {
86842
+ if (this.#agentCommand() !== void 0) {
86834
86843
  return await this.#adapter.cancel({ ...this.#target(), signal });
86835
86844
  }
86836
86845
  return "retained";
@@ -87011,35 +87020,83 @@ function nativeSessionQuery(options) {
87011
87020
  // src/engine/session/turn/active-executions.ts
87012
87021
  var ActiveExecutions = class {
87013
87022
  #entries = /* @__PURE__ */ new Map();
87014
- command = (id) => this.#entries.get(id)?.commandId;
87015
- cancellation = (id) => {
87016
- const state = this.#entries.get(id);
87017
- return state?.kind === "cancelling" ? state.completion : void 0;
87018
- };
87019
- isBusy = (id) => this.#entries.has(id);
87020
- begin = (id, commandId) => {
87021
- if (this.#entries.has(id)) {
87022
- throw new AcpExecutionError("Another prompt is already running in this conversation", {}, "session_busy");
87023
+ #statusChanged;
87024
+ constructor(statusChanged) {
87025
+ this.#statusChanged = statusChanged;
87026
+ }
87027
+ status = (sessionId) => {
87028
+ const execution = this.#entries.get(sessionId);
87029
+ return execution === void 0 ? { kind: "idle" } : { commandId: execution.commandId, kind: "working" };
87030
+ };
87031
+ isBusy = (sessionId) => this.#entries.has(sessionId);
87032
+ /** A steering prompt can join only the named execution while the Agent holds it and no one is stopping it. */
87033
+ acceptsSteering = (sessionId, targetCommandId) => {
87034
+ const execution = this.#entries.get(sessionId);
87035
+ return execution?.commandId === targetCommandId && execution.phase === "started" && execution.cancellation.kind === "none";
87036
+ };
87037
+ /** The command whose prompt the Session's Agent holds, if any. */
87038
+ agentCommand = (sessionId) => {
87039
+ const execution = this.#entries.get(sessionId);
87040
+ return execution?.phase === "started" ? execution.commandId : void 0;
87041
+ };
87042
+ cancellationRequested = (sessionId, commandId) => {
87043
+ const execution = this.#entries.get(sessionId);
87044
+ return execution?.commandId === commandId && execution.cancellation.kind === "requested";
87045
+ };
87046
+ cancellation = (sessionId) => {
87047
+ const cancellation = this.#entries.get(sessionId)?.cancellation;
87048
+ return cancellation?.kind === "requested" ? cancellation.completion : void 0;
87049
+ };
87050
+ begin = (sessionId, commandId) => {
87051
+ if (this.#entries.has(sessionId)) {
87052
+ throw new Error("A Session executes one command at a time");
87053
+ }
87054
+ this.#entries.set(sessionId, { commandId, phase: "preparing", cancellation: { kind: "none" } });
87055
+ this.#statusChanged(sessionId, this.status(sessionId));
87056
+ };
87057
+ /** The Agent receives the prompt. A cancelled execution must not start. */
87058
+ start = (sessionId, commandId) => {
87059
+ const execution = this.#entries.get(sessionId);
87060
+ if (execution?.commandId !== commandId || execution.phase !== "preparing") {
87061
+ throw new Error("Only the Session's preparing execution can start");
87062
+ }
87063
+ if (execution.cancellation.kind !== "none") {
87064
+ throw new Error("A cancelled execution cannot start");
87065
+ }
87066
+ this.#entries.set(sessionId, { ...execution, phase: "started" });
87067
+ };
87068
+ settle = (sessionId, commandId) => {
87069
+ const execution = this.#entries.get(sessionId);
87070
+ if (execution?.commandId === commandId) {
87071
+ this.#entries.set(sessionId, { ...execution, phase: "settled" });
87023
87072
  }
87024
- this.#entries.set(id, { kind: "running", commandId });
87025
87073
  };
87026
- cancel = (id, commandId, stop) => {
87027
- const state = this.#entries.get(id);
87028
- if (state?.commandId !== commandId) {
87074
+ /**
87075
+ * Records a cancellation of the named execution and asks `stop` to end it once. Another command's cancellation,
87076
+ * or one for an idle Session, has nothing to stop. A cancelled execution that has not started never starts.
87077
+ */
87078
+ cancel = (sessionId, commandId, stop) => {
87079
+ const execution = this.#entries.get(sessionId);
87080
+ if (execution?.commandId !== commandId) {
87029
87081
  return Promise.resolve();
87030
87082
  }
87031
- if (state.kind === "cancelling") {
87032
- return state.completion;
87083
+ if (execution.cancellation.kind === "requested") {
87084
+ return execution.cancellation.completion;
87033
87085
  }
87034
87086
  const completion = Promise.withResolvers();
87035
- this.#entries.set(id, { kind: "cancelling", commandId, completion: completion.promise });
87087
+ this.#entries.set(sessionId, {
87088
+ ...execution,
87089
+ cancellation: { kind: "requested", completion: completion.promise }
87090
+ });
87036
87091
  void (async () => await stop())().then(completion.resolve, completion.reject);
87037
87092
  return completion.promise;
87038
87093
  };
87039
- finish = (id, commandId) => {
87040
- if (this.command(id) === commandId) {
87041
- this.#entries.delete(id);
87094
+ finish = (sessionId, commandId) => {
87095
+ if (this.#entries.get(sessionId)?.commandId !== commandId) {
87096
+ return;
87042
87097
  }
87098
+ this.#entries.delete(sessionId);
87099
+ this.#statusChanged(sessionId, this.status(sessionId));
87043
87100
  };
87044
87101
  };
87045
87102
 
@@ -87054,7 +87111,7 @@ var SessionManager2 = class {
87054
87111
  touch: (runtime) => this.#processes.touch(runtime),
87055
87112
  changed: () => this.#processes.notifyChanged()
87056
87113
  });
87057
- #executions = new ActiveExecutions();
87114
+ #executions;
87058
87115
  #agentSettingsObserver = new NullSessionObserver();
87059
87116
  #nativeOperations = /* @__PURE__ */ new Set();
87060
87117
  #sessionClosures = /* @__PURE__ */ new Map();
@@ -87063,7 +87120,6 @@ var SessionManager2 = class {
87063
87120
  #closedSessions = /* @__PURE__ */ new Set();
87064
87121
  #store;
87065
87122
  #sessionIdentity;
87066
- #onSessionStatusChanged;
87067
87123
  #onSessionClosed;
87068
87124
  #timer;
87069
87125
  #observer;
@@ -87080,7 +87136,9 @@ var SessionManager2 = class {
87080
87136
  this.#processes = processes;
87081
87137
  this.#store = store;
87082
87138
  this.#sessionIdentity = sessionIdentity;
87083
- this.#onSessionStatusChanged = onSessionStatusChanged;
87139
+ this.#executions = new ActiveExecutions(
87140
+ (sessionId, status) => onSessionStatusChanged({ kind: "session.status.changed", sessionId, status })
87141
+ );
87084
87142
  this.#onSessionClosed = onSessionClosed;
87085
87143
  this.#timer = timer;
87086
87144
  }
@@ -87181,6 +87239,7 @@ var SessionManager2 = class {
87181
87239
  effectiveOptions,
87182
87240
  recovery,
87183
87241
  () => this.#observer,
87242
+ this.#executions.agentCommand,
87184
87243
  this.#store,
87185
87244
  metrics,
87186
87245
  options.adapter,
@@ -87203,6 +87262,7 @@ var SessionManager2 = class {
87203
87262
  options,
87204
87263
  recovery,
87205
87264
  () => this.#observer,
87265
+ this.#executions.agentCommand,
87206
87266
  this.#store,
87207
87267
  metrics,
87208
87268
  options.adapter,
@@ -87222,6 +87282,7 @@ var SessionManager2 = class {
87222
87282
  options,
87223
87283
  recovery,
87224
87284
  () => this.#observer,
87285
+ this.#executions.agentCommand,
87225
87286
  this.#store,
87226
87287
  unmeasuredOperationMetrics,
87227
87288
  options.adapter,
@@ -87293,6 +87354,7 @@ var SessionManager2 = class {
87293
87354
  options,
87294
87355
  recovery,
87295
87356
  () => this.#observer,
87357
+ this.#executions.agentCommand,
87296
87358
  this.#store,
87297
87359
  unmeasuredOperationMetrics,
87298
87360
  options.adapter,
@@ -87351,7 +87413,7 @@ var SessionManager2 = class {
87351
87413
  }
87352
87414
  return runtime3.prepared();
87353
87415
  }
87354
- if (!existing.canRebind()) {
87416
+ if (existing.prepared().prompted || this.#executions.isBusy(options2.sessionId)) {
87355
87417
  throw new AcpExecutionError(
87356
87418
  "The agent or workspace cannot change after a conversation has started",
87357
87419
  {},
@@ -87383,6 +87445,7 @@ var SessionManager2 = class {
87383
87445
  },
87384
87446
  { kind: "interactive-only" },
87385
87447
  () => this.#agentSettingsObserver,
87448
+ () => void 0,
87386
87449
  new MemorySessionStore(),
87387
87450
  unmeasuredOperationMetrics,
87388
87451
  options2.adapter
@@ -87467,7 +87530,7 @@ var SessionManager2 = class {
87467
87530
  this.#executionProcesses.touch(options2.sessionId, runtime);
87468
87531
  return runtime.prepared();
87469
87532
  }
87470
- if (existing.hasRunningTurn()) {
87533
+ if (this.#executions.isBusy(options2.sessionId)) {
87471
87534
  throw new AcpExecutionError(
87472
87535
  "The execution environment cannot change while a conversation turn is running",
87473
87536
  {},
@@ -87519,15 +87582,17 @@ var SessionManager2 = class {
87519
87582
  }
87520
87583
  });
87521
87584
  });
87585
+ /** Whether a steering prompt can join the named execution: the one rule every steering check asks. */
87586
+ acceptsSteering = (sessionId, targetCommandId) => this.#executions.acceptsSteering(sessionId, targetCommandId);
87522
87587
  steerPrompt = async (options) => this.#operations.run(options, async (options2) => {
87523
- if (this.#executions.command(options2.sessionId) !== options2.targetCommandId) {
87588
+ if (!this.acceptsSteering(options2.sessionId, options2.targetCommandId)) {
87524
87589
  throw new AcpExecutionError("The target turn is no longer active", {}, "steering_target_unavailable");
87525
87590
  }
87526
87591
  const pending = this.#executionProcesses.pending(options2.sessionId);
87527
87592
  if (pending !== void 0) {
87528
87593
  await waitForSharedOperation(pending, options2.signal);
87529
87594
  }
87530
- if (this.#executions.command(options2.sessionId) !== options2.targetCommandId) {
87595
+ if (!this.acceptsSteering(options2.sessionId, options2.targetCommandId)) {
87531
87596
  throw new AcpExecutionError("The target turn is no longer active", {}, "steering_target_unavailable");
87532
87597
  }
87533
87598
  const runtime = this.#executionProcesses.get(options2.sessionId);
@@ -87566,13 +87631,8 @@ var SessionManager2 = class {
87566
87631
  throw new AcpExecutionError("The native session is being managed", {}, "session_busy");
87567
87632
  }
87568
87633
  this.#executions.begin(options2.sessionId, options2.commandId);
87569
- const cancelled = () => options2.cancellationRequested?.() === true || this.#executions.cancellation(options2.sessionId) !== void 0;
87634
+ const cancelled = () => options2.cancellationRequested?.() === true || this.#executions.cancellationRequested(options2.sessionId, options2.commandId);
87570
87635
  try {
87571
- this.#onSessionStatusChanged({
87572
- kind: "session.status.changed",
87573
- sessionId: options2.sessionId,
87574
- status: { commandId: options2.commandId, kind: "working" }
87575
- });
87576
87636
  if (cancelled()) {
87577
87637
  return { stopReason: "cancelled" };
87578
87638
  }
@@ -87584,6 +87644,11 @@ var SessionManager2 = class {
87584
87644
  return { stopReason: "cancelled" };
87585
87645
  }
87586
87646
  try {
87647
+ await runtime.preparePrompt(options2.signal);
87648
+ if (cancelled()) {
87649
+ return { stopReason: "cancelled" };
87650
+ }
87651
+ this.#executions.start(options2.sessionId, options2.commandId);
87587
87652
  const result = await runtime.prompt({
87588
87653
  ...options2,
87589
87654
  cancellationRequested: cancelled
@@ -87595,6 +87660,8 @@ var SessionManager2 = class {
87595
87660
  return { stopReason: "cancelled" };
87596
87661
  }
87597
87662
  throw error62;
87663
+ } finally {
87664
+ this.#executions.settle(options2.sessionId, options2.commandId);
87598
87665
  }
87599
87666
  } catch (error62) {
87600
87667
  const failedRuntime = this.#executionProcesses.get(options2.sessionId);
@@ -87619,11 +87686,6 @@ var SessionManager2 = class {
87619
87686
  await this.#executions.cancellation(options2.sessionId);
87620
87687
  } finally {
87621
87688
  this.#executions.finish(options2.sessionId, options2.commandId);
87622
- this.#onSessionStatusChanged({
87623
- kind: "session.status.changed",
87624
- sessionId: options2.sessionId,
87625
- status: { kind: "idle" }
87626
- });
87627
87689
  this.#executionProcesses.touch(options2.sessionId);
87628
87690
  this.#processes.notifyChanged();
87629
87691
  }
@@ -87701,10 +87763,7 @@ var SessionManager2 = class {
87701
87763
  const stored = this.#store.read(sessionId);
87702
87764
  return stored instanceof FoundStoredSession ? [stored.session] : [];
87703
87765
  });
87704
- sessionStatus = (sessionId) => {
87705
- const commandId = this.#executions.command(sessionId);
87706
- return commandId === void 0 ? { kind: "idle" } : { commandId, kind: "working" };
87707
- };
87766
+ sessionStatus = (sessionId) => this.#executions.status(sessionId);
87708
87767
  listSessions = (limit) => this.#store.list().filter((session) => session.prompted).slice(0, limit);
87709
87768
  findLinkedSessions = (agentId, nativeSessionId) => this.#store.findNative(agentId, nativeSessionId);
87710
87769
  interactionSnapshot = (options) => {
@@ -87850,7 +87909,7 @@ var SessionManager2 = class {
87850
87909
  });
87851
87910
  }
87852
87911
  if (linked.some(
87853
- (entry) => this.#executions.command(entry.sessionId) !== void 0 || this.#executionProcesses.pending(entry.sessionId) !== void 0
87912
+ (entry) => this.#executions.isBusy(entry.sessionId) || this.#executionProcesses.pending(entry.sessionId) !== void 0
87854
87913
  )) {
87855
87914
  throw new AcpExecutionError(
87856
87915
  "Wait for the native session's running operation to finish",
@@ -88351,16 +88410,17 @@ function promptContent(command) {
88351
88410
  }
88352
88411
  var PromptLifecycle = class {
88353
88412
  #sink;
88413
+ /** Terminal events held until their command's admission and execution state are released. */
88354
88414
  #terminal = /* @__PURE__ */ new Map();
88355
88415
  #publications = /* @__PURE__ */ new Map();
88356
88416
  #queued = /* @__PURE__ */ new Map();
88357
88417
  #recordActiveTurn;
88358
- #hasStarted;
88418
+ #executions;
88359
88419
  #recordLifecycle;
88360
- constructor(sink, recordLifecycle, recordActiveTurn, hasStarted) {
88420
+ constructor(sink, recordLifecycle, recordActiveTurn, executions) {
88361
88421
  this.#recordLifecycle = recordLifecycle;
88362
88422
  this.#recordActiveTurn = recordActiveTurn;
88363
- this.#hasStarted = hasStarted;
88423
+ this.#executions = executions;
88364
88424
  this.#sink = sink;
88365
88425
  }
88366
88426
  requested = (command) => {
@@ -88377,8 +88437,8 @@ var PromptLifecycle = class {
88377
88437
  ...command.targetCommandId.length === 0 ? {} : { targetCommandId: command.targetCommandId }
88378
88438
  });
88379
88439
  };
88380
- /** Metadata for an execution already claimed by the receipt owner. */
88381
- started = (sessionId, commandId, attemptId, epoch, disposition) => {
88440
+ /** The lifecycle metadata the Agent session records when it starts this claimed command. */
88441
+ lifecycle = (sessionId, commandId, attemptId, epoch, disposition) => {
88382
88442
  const request = this.#queued.get(commandId);
88383
88443
  if (request?.sessionId === sessionId) {
88384
88444
  return {
@@ -88395,7 +88455,7 @@ var PromptLifecycle = class {
88395
88455
  record = (recorded) => {
88396
88456
  this.#recordActiveTurn(recorded);
88397
88457
  const sessionId = recorded.sessionId;
88398
- if (recorded.type === "lifecycle-metadata" && (recorded.payload.kind === "prompt.completed" || recorded.payload.kind === "prompt.failed" || recorded.payload.kind === "prompt.failed-before-start")) {
88458
+ if (recorded.type === "lifecycle-metadata" && isPromptTerminal(recorded.payload)) {
88399
88459
  this.#terminal.set(recorded.payload.commandId, recorded);
88400
88460
  const pending2 = this.#publications.get(sessionId) ?? [];
88401
88461
  pending2.push(recorded);
@@ -88446,7 +88506,7 @@ var PromptLifecycle = class {
88446
88506
  };
88447
88507
  completed = async (sessionId, commandId, stopReason) => {
88448
88508
  const request = this.#queued.get(commandId);
88449
- if (request?.sessionId !== sessionId || this.#terminal.has(commandId)) {
88509
+ if (request?.sessionId !== sessionId || this.#executions.isTerminalExecution(commandId, sessionId)) {
88450
88510
  return;
88451
88511
  }
88452
88512
  const recorded = await this.#recordLifecycle(sessionId, {
@@ -88455,7 +88515,7 @@ var PromptLifecycle = class {
88455
88515
  kind: "prompt.completed",
88456
88516
  commandId,
88457
88517
  stopReason,
88458
- ...this.#hasStarted(commandId, sessionId) ? {} : { execution: "not-started" }
88518
+ ...this.#executions.hasStarted(commandId, sessionId) ? {} : { execution: "not-started" }
88459
88519
  }
88460
88520
  });
88461
88521
  if (!recorded) {
@@ -88467,21 +88527,24 @@ var PromptLifecycle = class {
88467
88527
  );
88468
88528
  }
88469
88529
  };
88470
- failed = async (sessionId, commandId, code, message) => {
88530
+ /** Settles a failed command; whether it failed before or after starting is its receipt's fact. */
88531
+ failed = async (sessionId, commandId, attemptId, code, message) => {
88471
88532
  const request = this.#queued.get(commandId);
88472
- if (request?.sessionId !== sessionId || this.#terminal.has(commandId)) {
88533
+ if (request?.sessionId !== sessionId || this.#executions.isTerminalExecution(commandId, sessionId)) {
88473
88534
  return;
88474
88535
  }
88475
88536
  const recorded = await this.#recordLifecycle(sessionId, {
88476
88537
  type: "lifecycle-metadata",
88477
- payload: { kind: "prompt.failed-before-start", commandId, code, message }
88538
+ payload: this.#executions.hasStarted(commandId, sessionId) ? { kind: "prompt.failed", attemptId, commandId, code, message } : { kind: "prompt.failed-before-start", commandId, code, message }
88478
88539
  });
88479
88540
  if (!recorded || code === SESSION_CLOSED_ERROR_CODE) {
88480
88541
  this.#sink.publishOperationFailure(sessionId, commandId, code, message);
88481
88542
  }
88482
88543
  };
88483
88544
  promptRequestRecovery = (sessionId) => ({
88484
- queuedPromptRequests: [...this.#queued.values()].filter((request) => request.sessionId === sessionId && !this.#hasStarted(request.commandId, sessionId)).map(({ commandId, content, disposition, targetCommandId }) => ({
88545
+ queuedPromptRequests: [...this.#queued.values()].filter(
88546
+ (request) => request.sessionId === sessionId && !this.#executions.hasStarted(request.commandId, sessionId)
88547
+ ).map(({ commandId, content, disposition, targetCommandId }) => ({
88485
88548
  commandId,
88486
88549
  content,
88487
88550
  ...disposition === void 0 ? {} : { disposition },
@@ -88503,6 +88566,7 @@ async function settleAbandonedTurn(projection, operations, cancellation) {
88503
88566
  await projection.failed(
88504
88567
  cancellation.sessionId,
88505
88568
  cancellation.commandId,
88569
+ attemptId,
88506
88570
  "agent_execution_abandoned",
88507
88571
  "The local Agent execution was abandoned before it completed"
88508
88572
  );
@@ -88614,7 +88678,7 @@ var ExecutionReceipts = class {
88614
88678
  return { state: "accepted" };
88615
88679
  }
88616
88680
  const outcome = this.outcome(commandId);
88617
- if (outcome?.type !== "lifecycle-metadata") {
88681
+ if (outcome?.type !== "lifecycle-metadata" || !isPromptTerminal(outcome.payload)) {
88618
88682
  return { state: "expired" };
88619
88683
  }
88620
88684
  switch (outcome.payload.kind) {
@@ -88623,8 +88687,6 @@ var ExecutionReceipts = class {
88623
88687
  case "prompt.failed":
88624
88688
  case "prompt.failed-before-start":
88625
88689
  return { code: outcome.payload.code, state: "failed" };
88626
- default:
88627
- return { state: "expired" };
88628
88690
  }
88629
88691
  };
88630
88692
  /**
@@ -88647,7 +88709,7 @@ var ExecutionReceipts = class {
88647
88709
  }
88648
88710
  }
88649
88711
  const outcome = last === void 0 ? void 0 : this.outcome(last);
88650
- if (last === void 0 || outcome?.type !== "lifecycle-metadata") {
88712
+ if (last === void 0 || outcome?.type !== "lifecycle-metadata" || !isPromptTerminal(outcome.payload)) {
88651
88713
  return void 0;
88652
88714
  }
88653
88715
  switch (outcome.payload.kind) {
@@ -88661,8 +88723,6 @@ var ExecutionReceipts = class {
88661
88723
  message: outcome.payload.message,
88662
88724
  state: "failed"
88663
88725
  };
88664
- default:
88665
- return void 0;
88666
88726
  }
88667
88727
  };
88668
88728
  /** Started identities remain authoritative after their detailed receipt is evicted. */
@@ -88706,12 +88766,24 @@ var ExecutionReceipts = class {
88706
88766
  });
88707
88767
  return outcome;
88708
88768
  };
88709
- recordOutcome = (event) => {
88769
+ /**
88770
+ * Receipts follow their command's recorded lifecycle. `prompt.started` is recorded where the command is handed
88771
+ * to the Agent, so the started mark and the event clients see are one transition; a terminal event settles the
88772
+ * receipt. Nothing else marks a command started.
88773
+ */
88774
+ record = (event) => {
88710
88775
  if (event.type !== "lifecycle-metadata") {
88711
88776
  return;
88712
88777
  }
88713
88778
  const payload = event.payload;
88714
- if (payload.kind !== "prompt.completed" && payload.kind !== "prompt.failed" && payload.kind !== "prompt.failed-before-start") {
88779
+ if (payload.kind === "prompt.started") {
88780
+ const receipt2 = this.#executions.get(payload.commandId);
88781
+ if (receipt2?.state.kind === "pending") {
88782
+ this.#save(payload.commandId, { ...receipt2, state: { kind: "started" } });
88783
+ }
88784
+ return;
88785
+ }
88786
+ if (!isPromptTerminal(payload)) {
88715
88787
  return;
88716
88788
  }
88717
88789
  const receipt = this.#executions.get(payload.commandId);
@@ -88794,27 +88866,6 @@ var ExecutionReceipts = class {
88794
88866
  });
88795
88867
  return { attemptId, commandId, kind: "accepted" };
88796
88868
  };
88797
- markExecutionStarted = (commandId) => {
88798
- const current = this.#executions.get(commandId);
88799
- if (current === void 0) {
88800
- throw new Error("The runtime execution receipt does not exist");
88801
- }
88802
- const state = current.state;
88803
- switch (state.kind) {
88804
- case "pending":
88805
- this.#save(commandId, { ...current, state: { kind: "started" } });
88806
- return;
88807
- case "started":
88808
- return;
88809
- case "settled-before-start":
88810
- case "settled-after-start":
88811
- throw new Error("The runtime execution transition is invalid");
88812
- default: {
88813
- const unreachable2 = state;
88814
- throw new Error("Unexpected execution state", { cause: unreachable2 });
88815
- }
88816
- }
88817
- };
88818
88869
  /** Only commands without a terminal result can still be cancelled. */
88819
88870
  findUnsettledAttemptId = (commandId, sessionId) => {
88820
88871
  const receipt = this.#executions.get(commandId);
@@ -88922,69 +88973,77 @@ import { randomUUID as randomUUID16 } from "node:crypto";
88922
88973
  var ActiveRuntimeTurn = class {
88923
88974
  attemptId;
88924
88975
  command;
88976
+ epoch = decodeIdentifier(randomUUID16());
88925
88977
  #controller;
88926
88978
  #finished = Promise.withResolvers();
88979
+ #started;
88927
88980
  #cancellationRequested = false;
88928
- #dispatch;
88981
+ #admission = { kind: "waiting" };
88929
88982
  #sequence = 0;
88930
88983
  #interaction = null;
88931
- #epoch = decodeIdentifier(randomUUID16());
88932
- constructor(command, attemptId) {
88984
+ /** `started` reads the command's execution receipt, the single owner of whether the command started. */
88985
+ constructor(command, attemptId, started) {
88933
88986
  this.attemptId = attemptId;
88934
88987
  this.command = command;
88935
88988
  this.#controller = new AbortController();
88936
- this.#dispatch = { kind: "pending" };
88989
+ this.#started = started;
88937
88990
  }
88938
88991
  enqueue = () => {
88939
- if (this.#dispatch.kind !== "pending") {
88940
- throw new Error("Only a pending prompt can enter the queue");
88992
+ if (this.#admission.kind !== "waiting") {
88993
+ throw new Error("Only a waiting prompt can enter the queue");
88941
88994
  }
88942
- this.#dispatch = { kind: "queued", promotion: Promise.withResolvers() };
88995
+ this.#admission = { kind: "queued", promotion: Promise.withResolvers() };
88943
88996
  };
88944
- isQueued = () => (this.#dispatch.kind === "queued" || this.#dispatch.kind === "admitted" && this.#dispatch.disposition === SessionPromptDisposition.Queue) && !this.#controller.signal.aborted;
88997
+ isQueued = () => (this.#admission.kind === "queued" || this.#admission.kind === "admitted" && this.#admission.disposition === SessionPromptDisposition.Queue) && !this.#started() && !this.#controller.signal.aborted;
88945
88998
  abortRuntime = () => {
88946
88999
  this.#controller.abort();
88947
89000
  };
88948
89001
  finish = () => {
88949
89002
  this.#finished.resolve();
88950
89003
  };
88951
- activate = (execution) => {
88952
- this.#dispatch = { kind: "running", execution };
88953
- return { epoch: this.#epoch, sequence: 0 };
88954
- };
88955
89004
  promoteQueuedPrompt = (command) => {
88956
89005
  if (command.commandId !== this.command.commandId || command.sessionId !== this.command.sessionId || this.#controller.signal.aborted) {
88957
89006
  return "unavailable";
88958
89007
  }
88959
- switch (this.#dispatch.kind) {
89008
+ switch (this.#admission.kind) {
88960
89009
  case "queued": {
88961
- const promotion = this.#dispatch.promotion;
88962
- this.#dispatch = { kind: "promoted" };
89010
+ const promotion = this.#admission.promotion;
89011
+ this.#admission = { kind: "promoted" };
88963
89012
  promotion.resolve();
88964
89013
  return "accepted";
88965
89014
  }
88966
89015
  case "promoted":
88967
89016
  return "accepted";
88968
89017
  case "admitted":
88969
- return this.#dispatch.disposition === SessionPromptDisposition.Steer ? "accepted" : "already-started";
88970
- case "running":
88971
- return "already-started";
88972
- case "pending":
89018
+ return this.#admission.disposition === SessionPromptDisposition.Steer ? "accepted" : "already-started";
89019
+ case "waiting":
88973
89020
  return "unavailable";
88974
89021
  }
88975
89022
  };
88976
89023
  admit = () => {
88977
89024
  const disposition = this.effectiveDisposition();
88978
- this.#dispatch = { kind: "admitted", disposition };
89025
+ this.#admission = { kind: "admitted", disposition };
88979
89026
  return disposition;
88980
89027
  };
88981
89028
  queuePromotion = () => {
88982
- if (this.#dispatch.kind === "queued") {
88983
- return this.#dispatch.promotion.promise;
89029
+ if (this.#admission.kind === "queued") {
89030
+ return this.#admission.promotion.promise;
89031
+ }
89032
+ return this.#admission.kind === "promoted" ? Promise.resolve() : null;
89033
+ };
89034
+ effectiveDisposition = () => {
89035
+ switch (this.#admission.kind) {
89036
+ case "waiting":
89037
+ case "queued":
89038
+ return this.command.disposition;
89039
+ case "promoted":
89040
+ return SessionPromptDisposition.Steer;
89041
+ case "admitted":
89042
+ return this.#admission.disposition;
88984
89043
  }
88985
- return this.#dispatch.kind === "promoted" ? Promise.resolve() : null;
88986
89044
  };
88987
- effectiveDisposition = () => this.#dispatch.kind === "promoted" ? SessionPromptDisposition.Steer : this.command.disposition;
89045
+ /** A steering prompt joins the execution of the turn it steers; every other prompt owns its execution. */
89046
+ execution = () => this.effectiveDisposition() === SessionPromptDisposition.Steer ? this.command.targetCommandId : this.command.commandId;
88988
89047
  recordEvent = (event) => {
88989
89048
  if (event.sessionId !== this.command.sessionId || "commandId" in event && event.commandId !== this.command.commandId) {
88990
89049
  return event;
@@ -88996,33 +89055,33 @@ var ActiveRuntimeTurn = class {
88996
89055
  }
88997
89056
  return event;
88998
89057
  };
88999
- recordSteeringPrompt = (command) => {
89000
- return this.#dispatch.kind === "running" && command.sessionId === this.command.sessionId && command.targetCommandId === this.command.commandId;
89001
- };
89002
89058
  snapshot = () => {
89003
- if (this.#dispatch.kind !== "running") {
89059
+ if (!this.#started()) {
89004
89060
  return null;
89005
89061
  }
89006
89062
  return {
89007
89063
  commandId: decodeIdentifier(this.command.commandId),
89008
- epoch: this.#epoch,
89064
+ epoch: this.epoch,
89009
89065
  interaction: this.#interaction,
89010
89066
  sequence: this.#sequence,
89011
89067
  state: "running"
89012
89068
  };
89013
89069
  };
89014
- matches = (cancellation) => cancellation.commandId === this.command.commandId && cancellation.sessionId === this.command.sessionId;
89015
89070
  matchesInteraction = (interactionId, sessionId) => this.command.sessionId === sessionId && this.#interaction?.interactionId === interactionId;
89071
+ /**
89072
+ * Before the command starts, cancellation withdraws it by aborting its own admission and preparation. Once it
89073
+ * started, the Agent execution it belongs to must be asked to stop.
89074
+ */
89016
89075
  requestCancellation = () => {
89017
89076
  if (this.#cancellationRequested) {
89018
89077
  return { kind: "already-requested" };
89019
89078
  }
89020
89079
  this.#cancellationRequested = true;
89021
- if (this.#dispatch.kind !== "running") {
89022
- this.#controller.abort(new Error("The queued Agent turn was cancelled"));
89080
+ if (!this.#started()) {
89081
+ this.#controller.abort(new Error("The Agent turn was cancelled before it started"));
89023
89082
  return { kind: "pending" };
89024
89083
  }
89025
- return { kind: "running", execution: this.#dispatch.execution };
89084
+ return { kind: "running", execution: this.execution() };
89026
89085
  };
89027
89086
  cancellationRequested = () => this.#cancellationRequested;
89028
89087
  get signal() {
@@ -89068,7 +89127,11 @@ var SessionExecutionState = class {
89068
89127
  }
89069
89128
  isEmpty = () => this.#turnsByCommandId.size === 0;
89070
89129
  start = (command, attemptId) => {
89071
- const turn = new ActiveRuntimeTurn(command, attemptId);
89130
+ const turn = new ActiveRuntimeTurn(
89131
+ command,
89132
+ attemptId,
89133
+ () => this.#operations.hasStarted(command.commandId, this.#sessionId)
89134
+ );
89072
89135
  this.#turnsByCommandId.set(command.commandId, turn);
89073
89136
  return turn;
89074
89137
  };
@@ -89093,10 +89156,6 @@ var SessionExecutionState = class {
89093
89156
  }
89094
89157
  return event;
89095
89158
  };
89096
- recordSteeringPrompt = (command) => {
89097
- const target = this.#turnsByCommandId.get(command.targetCommandId);
89098
- return target?.recordSteeringPrompt(command) ?? false;
89099
- };
89100
89159
  turns = () => [...this.#turnsByCommandId.values()];
89101
89160
  close = async () => {
89102
89161
  const turns = [...this.#turnsByCommandId.values()];
@@ -89109,7 +89168,7 @@ var SessionExecutionState = class {
89109
89168
  const command = turn.command;
89110
89169
  waitSignal.throwIfAborted();
89111
89170
  const head = () => [...this.#turnsByCommandId.values()].find(
89112
- (turn2) => turn2.command.disposition !== SessionPromptDisposition.Steer
89171
+ (turn2) => turn2.effectiveDisposition() !== SessionPromptDisposition.Steer
89113
89172
  );
89114
89173
  if (command.disposition === SessionPromptDisposition.Queue) {
89115
89174
  const target = head();
@@ -89181,7 +89240,6 @@ var SessionTurns = class {
89181
89240
  this.recordEvent(event.payload.event);
89182
89241
  }
89183
89242
  };
89184
- recordSteeringPrompt = (command) => this.#bySessionId.get(command.sessionId)?.recordSteeringPrompt(command) ?? false;
89185
89243
  executionSnapshot = async (matches) => {
89186
89244
  for (const session of this.#bySessionId.values()) {
89187
89245
  const matching = [];
@@ -89431,7 +89489,7 @@ function buildSessionLayer(options) {
89431
89489
  const manager = new SessionManager2({
89432
89490
  observer: new SessionLayerObserver(
89433
89491
  (event) => {
89434
- operations.recordOutcome(event);
89492
+ operations.record(event);
89435
89493
  eventProjection.record(event);
89436
89494
  },
89437
89495
  sink.publishInfo,
@@ -89454,12 +89512,12 @@ function buildSessionLayer(options) {
89454
89512
  return true;
89455
89513
  }
89456
89514
  const recorded = events.append(sessionId, event);
89457
- operations.recordOutcome(recorded);
89515
+ operations.record(recorded);
89458
89516
  eventProjection.record(recorded);
89459
89517
  return true;
89460
89518
  },
89461
89519
  activeSessions.recordSessionEvent,
89462
- operations.hasStarted
89520
+ operations
89463
89521
  );
89464
89522
  const nativeSessions = new NativeSessionService(
89465
89523
  bindingId,
@@ -91742,7 +91800,6 @@ function warnIgnoredSetting(event, commandId, sessionId, agentId, selection, cat
91742
91800
 
91743
91801
  // src/engine/session/prompt/execute-prompt.ts
91744
91802
  async function executePrompt({
91745
- operations,
91746
91803
  eventProjection,
91747
91804
  command,
91748
91805
  resolveAgent,
@@ -91751,10 +91808,9 @@ async function executePrompt({
91751
91808
  directories,
91752
91809
  sessions,
91753
91810
  attemptId,
91754
- activateAttempt,
91811
+ epoch,
91755
91812
  waitForSessionAvailability,
91756
91813
  signal,
91757
- recordSteeringPrompt,
91758
91814
  cancellationRequested
91759
91815
  }) {
91760
91816
  try {
@@ -91781,6 +91837,9 @@ async function executePrompt({
91781
91837
  "prompt_queue_target_unavailable"
91782
91838
  );
91783
91839
  }
91840
+ if (availability.disposition === SessionPromptDisposition.Steer && !sessions.acceptsSteering(command.sessionId, command.targetCommandId)) {
91841
+ throw new AcpExecutionError("The steering target is unavailable", {}, "prompt_queue_target_unavailable");
91842
+ }
91784
91843
  const appliedSettings = command.sessionConfigurations === void 0 ? void 0 : agentForSessionConfiguration(agent, command.sessionConfigurations);
91785
91844
  const executionAgent = appliedSettings?.agent ?? agent;
91786
91845
  const sessionConfigurations = appliedSettings?.sessionConfigurations;
@@ -91812,24 +91871,11 @@ async function executePrompt({
91812
91871
  prepared = await sessions.prepareExecutionSession(preparation);
91813
91872
  }
91814
91873
  signal.throwIfAborted();
91815
- operations.markExecutionStarted(command.commandId);
91816
- if (availability.disposition === SessionPromptDisposition.Steer) {
91817
- if (!recordSteeringPrompt()) {
91818
- throw new AcpExecutionError(
91819
- "The steering target is unavailable",
91820
- {},
91821
- "prompt_queue_target_unavailable"
91822
- );
91823
- }
91824
- }
91825
- const stream = activateAttempt(
91826
- availability.disposition === SessionPromptDisposition.Steer ? command.targetCommandId : command.commandId
91827
- );
91828
- const lifecycle = eventProjection.started(
91874
+ const lifecycle = eventProjection.lifecycle(
91829
91875
  command.sessionId,
91830
91876
  command.commandId,
91831
91877
  attemptId,
91832
- stream.epoch,
91878
+ epoch,
91833
91879
  availability.disposition
91834
91880
  );
91835
91881
  const attachments = await resolvePromptArtifacts(readArtifact, command.attachments, signal);
@@ -91888,7 +91934,7 @@ async function executePrompt({
91888
91934
  const code = operationErrorCode(error62);
91889
91935
  const failureCode = code === "session_operation_failed" ? "agent_execution_failed" : code;
91890
91936
  const failureMessage = code === "session_operation_failed" ? "The local agent could not complete the request" : operationErrorMessage(error62);
91891
- await eventProjection.failed(command.sessionId, command.commandId, failureCode, failureMessage);
91937
+ await eventProjection.failed(command.sessionId, command.commandId, attemptId, failureCode, failureMessage);
91892
91938
  reportFailure("session_prompt_failed", command.commandId, {
91893
91939
  agentId: command.agentId,
91894
91940
  code: failureCode,
@@ -91958,7 +92004,6 @@ var sessionPromptCommand = {
91958
92004
  });
91959
92005
  };
91960
92006
  void executePrompt({
91961
- operations: context.operations,
91962
92007
  eventProjection: context.eventProjection,
91963
92008
  command: message,
91964
92009
  resolveAgent: context.resolveAgent,
@@ -91977,12 +92022,11 @@ var sessionPromptCommand = {
91977
92022
  directories: context.directories,
91978
92023
  sessions: context.sessions,
91979
92024
  attemptId: receipt.attemptId,
91980
- activateAttempt: turn.activate,
92025
+ epoch: turn.epoch,
91981
92026
  waitForSessionAvailability: (signal) => context.sessionTurns.admitAndWait(turn, signal, () => {
91982
92027
  queueChanged();
91983
92028
  }),
91984
92029
  signal: turn.signal,
91985
- recordSteeringPrompt: () => context.sessionTurns.recordSteeringPrompt(message),
91986
92030
  cancellationRequested: turn.cancellationRequested
91987
92031
  }).catch((error62) => {
91988
92032
  console.error("Mobius daemon turn failed", error62);
@@ -93082,7 +93126,7 @@ var RuntimeSessionEventPublisher = class {
93082
93126
  commandId: payload.commandId,
93083
93127
  generationId: event.sessionGenerationId
93084
93128
  });
93085
- } else if ((payload.kind === "prompt.completed" || payload.kind === "prompt.failed" || payload.kind === "prompt.failed-before-start") && this.#awaitingFirstAnswer.get(event.sessionId)?.commandId === payload.commandId && this.#awaitingFirstAnswer.get(event.sessionId)?.generationId === event.sessionGenerationId) {
93129
+ } else if (isPromptTerminal(payload) && this.#awaitingFirstAnswer.get(event.sessionId)?.commandId === payload.commandId && this.#awaitingFirstAnswer.get(event.sessionId)?.generationId === event.sessionGenerationId) {
93086
93130
  this.#awaitingFirstAnswer.delete(event.sessionId);
93087
93131
  }
93088
93132
  return false;
@@ -93587,4 +93631,4 @@ export {
93587
93631
  * MIT Licensed
93588
93632
  *)
93589
93633
  */
93590
- //# sourceMappingURL=chunk-A62FEGIN.js.map
93634
+ //# sourceMappingURL=chunk-77O2RBRQ.js.map