@moxt-ai/mobius 0.0.176 → 0.0.178

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 (59) hide show
  1. package/dist/acp/agent-connection.d.ts +1 -3
  2. package/dist/acp/agent-connection.d.ts.map +1 -1
  3. package/dist/acp/agent-connection.js +3 -4
  4. package/dist/acp/agent-connection.js.map +1 -1
  5. package/dist/acp/agent-runtime-manager.d.ts +2 -1
  6. package/dist/acp/agent-runtime-manager.d.ts.map +1 -1
  7. package/dist/acp/agent-runtime-manager.js +12 -9
  8. package/dist/acp/agent-runtime-manager.js.map +1 -1
  9. package/dist/acp/agent-session.d.ts +4 -3
  10. package/dist/acp/agent-session.d.ts.map +1 -1
  11. package/dist/acp/agent-session.js +54 -32
  12. package/dist/acp/agent-session.js.map +1 -1
  13. package/dist/acp/codex/agent.d.ts.map +1 -1
  14. package/dist/acp/codex/agent.js +1 -13
  15. package/dist/acp/codex/agent.js.map +1 -1
  16. package/dist/acp/session-contracts.d.ts +3 -1
  17. package/dist/acp/session-contracts.d.ts.map +1 -1
  18. package/dist/acp/session-contracts.js.map +1 -1
  19. package/dist/cli.js +241 -617
  20. package/dist/cli.js.map +4 -4
  21. package/dist/daemon-command-handler.d.ts +1 -3
  22. package/dist/daemon-command-handler.d.ts.map +1 -1
  23. package/dist/daemon-command-handler.js +11 -9
  24. package/dist/daemon-command-handler.js.map +1 -1
  25. package/dist/daemon-command-results.d.ts +2 -3
  26. package/dist/daemon-command-results.d.ts.map +1 -1
  27. package/dist/daemon-command-results.js +4 -12
  28. package/dist/daemon-command-results.js.map +1 -1
  29. package/dist/daemon-prompt-executor.d.ts +2 -6
  30. package/dist/daemon-prompt-executor.d.ts.map +1 -1
  31. package/dist/daemon-prompt-executor.js +20 -73
  32. package/dist/daemon-prompt-executor.js.map +1 -1
  33. package/dist/daemon-session-commands.d.ts +2 -3
  34. package/dist/daemon-session-commands.d.ts.map +1 -1
  35. package/dist/daemon-session-commands.js +3 -15
  36. package/dist/daemon-session-commands.js.map +1 -1
  37. package/dist/index.js +240 -616
  38. package/dist/index.js.map +4 -4
  39. package/dist/relay-connection/run-relay-connection.d.ts.map +1 -1
  40. package/dist/relay-connection/run-relay-connection.js +0 -1
  41. package/dist/relay-connection/run-relay-connection.js.map +1 -1
  42. package/dist/relay-connection/session-event-publisher.d.ts +7 -3
  43. package/dist/relay-connection/session-event-publisher.d.ts.map +1 -1
  44. package/dist/relay-connection/session-event-publisher.js +35 -27
  45. package/dist/relay-connection/session-event-publisher.js.map +1 -1
  46. package/dist/run-daemon.d.ts.map +1 -1
  47. package/dist/run-daemon.js +5 -6
  48. package/dist/run-daemon.js.map +1 -1
  49. package/dist/runtime.js +240 -616
  50. package/dist/runtime.js.map +4 -4
  51. package/dist/session-event-log-v2.d.ts +7 -5
  52. package/dist/session-event-log-v2.d.ts.map +1 -1
  53. package/dist/session-event-log-v2.js +83 -12
  54. package/dist/session-event-log-v2.js.map +1 -1
  55. package/package.json +1 -1
  56. package/dist/relay-connection/coalescing-agent-event-publisher.d.ts +0 -32
  57. package/dist/relay-connection/coalescing-agent-event-publisher.d.ts.map +0 -1
  58. package/dist/relay-connection/coalescing-agent-event-publisher.js +0 -116
  59. package/dist/relay-connection/coalescing-agent-event-publisher.js.map +0 -1
package/dist/cli.js CHANGED
@@ -3381,7 +3381,7 @@ var program = new Command();
3381
3381
  // package.json
3382
3382
  var package_default = {
3383
3383
  name: "@moxt-ai/mobius",
3384
- version: "0.0.176",
3384
+ version: "0.0.178",
3385
3385
  description: "Mobius CLI for pairing and running local AI agent services.",
3386
3386
  type: "module",
3387
3387
  bin: {
@@ -25913,14 +25913,6 @@ var CodexAcpAgent = class {
25913
25913
  if (isCompactPrompt(context.params.prompt)) {
25914
25914
  return await this.#compact(context.signal);
25915
25915
  }
25916
- const messageId = crypto.randomUUID();
25917
- for (const content of context.params.prompt) {
25918
- await this.#emit({
25919
- content,
25920
- messageId,
25921
- sessionUpdate: "user_message_chunk"
25922
- });
25923
- }
25924
25916
  return await this.#runTurn(promptInput(context.params.prompt), context.signal);
25925
25917
  }).onRequest(
25926
25918
  "_session/steering",
@@ -26406,10 +26398,6 @@ var CodexAcpAgent = class {
26406
26398
  if (steering.length === 0) {
26407
26399
  throw new AcpExecutionError("Codex received an empty steering request", {}, "invalid_request");
26408
26400
  }
26409
- const messageId = crypto.randomUUID();
26410
- for (const block of steering) {
26411
- await this.#emit({ content: block.content, messageId, sessionUpdate: "user_message_chunk" });
26412
- }
26413
26401
  const response = turnSteerResponseSchema.parse(
26414
26402
  await this.#appServer.request(
26415
26403
  "turn/steer",
@@ -26446,7 +26434,7 @@ var CodexAcpAgent = class {
26446
26434
  };
26447
26435
  #completeTurn = async (turn) => {
26448
26436
  const active = this.#turn;
26449
- if (active === null) {
26437
+ if (active === null || active.turn.id !== turn.id) {
26450
26438
  return;
26451
26439
  }
26452
26440
  await this.#updateTail;
@@ -28970,8 +28958,6 @@ function decodeValue(value, schema) {
28970
28958
  }
28971
28959
  return result.data;
28972
28960
  }
28973
- var decodeAgentDisplayContentValue = (value) => decodeValue(value, displayContentSchema);
28974
- var decodeRecordedAgentContentValue = (value) => decodeValue(value, recordedDisplayContentSchema);
28975
28961
  var decodePromptImagesValue = (value) => decodeValue(value, external_exports.array(promptImageSchema).max(8).readonly());
28976
28962
  var decodePromptResourcesValue = (value) => decodeValue(value, external_exports.array(promptResourceSchema).max(16).readonly());
28977
28963
  var decodeSessionConfigurationSelections = (value) => decodeValue(value, sessionConfigurationSelectionsSchema);
@@ -29013,20 +28999,13 @@ var encodeSessionReadyEvent = (message) => encode3(message, sessionReadyEventSch
29013
28999
  var decodeSessionConfigureCommand = (encoded) => decode3(encoded, sessionConfigureCommandSchema);
29014
29000
  var encodeSessionConfigureCommand = (message) => encode3(message, sessionConfigureCommandSchema);
29015
29001
  var decodeSessionConfigUpdatedEvent = (encoded) => decode3(encoded, sessionConfigUpdatedEventSchema);
29016
- var decodeSessionUsageUpdatedEvent = (encoded) => decode3(encoded, sessionUsageUpdatedEventSchema);
29017
- var decodeSessionCommandsUpdatedEvent = (encoded) => decode3(encoded, sessionCommandsUpdatedEventSchema);
29018
- var decodeSessionInfoUpdatedEvent = (encoded) => decode3(encoded, sessionInfoUpdatedEventSchema);
29019
- var decodeSessionPermissionRequestedEvent = (encoded) => decode3(encoded, sessionPermissionRequestedEventSchema);
29002
+ var encodeSessionConfigUpdatedEvent = (message) => encode3(message, sessionConfigUpdatedEventSchema);
29020
29003
  var decodeSessionPermissionRespondCommand = (encoded) => decode3(encoded, sessionPermissionRespondCommandSchema);
29021
29004
  var encodeSessionPermissionRespondCommand = (message) => encode3(message, sessionPermissionRespondCommandSchema);
29022
- var decodeSessionPermissionResolvedEvent = (encoded) => decode3(encoded, sessionPermissionResolvedEventSchema);
29023
- var decodeSessionElicitationRequestedEvent = (encoded) => decode3(encoded, sessionElicitationRequestedEventSchema);
29024
29005
  var decodeSessionElicitationRespondCommand = (encoded) => decode3(encoded, sessionElicitationRespondCommandSchema);
29025
29006
  var encodeSessionElicitationRespondCommand = (message) => encode3(message, sessionElicitationRespondCommandSchema);
29026
- var decodeSessionElicitationResolvedEvent = (encoded) => decode3(encoded, sessionElicitationResolvedEventSchema);
29027
29007
  var decodeSessionOperationFailedEvent = (encoded) => decode3(encoded, sessionOperationFailedEventSchema);
29028
29008
  var encodeSessionOperationFailedEvent = (message) => encode3(message, sessionOperationFailedEventSchema);
29029
- var decodeAgentContentEvent = (encoded) => decode3(encoded, agentContentEventSchema);
29030
29009
  var decodeAgentInstallRequestCommand = (encoded) => decode3(encoded, agentInstallRequestCommandSchema);
29031
29010
  var encodeAgentInstallRequestCommand = (message) => encode3(message, agentInstallRequestCommandSchema);
29032
29011
  var decodeAgentInstallCancelCommand = (encoded) => decode3(encoded, agentInstallCancelCommandSchema);
@@ -29052,7 +29031,6 @@ var RUNTIME_HEARTBEAT_KIND = "runtime.heartbeat";
29052
29031
  var RUNTIME_HEARTBEAT_ACK_KIND = "runtime.heartbeat.ack";
29053
29032
  var RUNTIME_PING_KIND = "runtime.ping";
29054
29033
  var RUNTIME_PONG_KIND = "runtime.pong";
29055
- var SESSION_STARTED_KIND = "session.started";
29056
29034
  var SESSION_QUEUED_KIND = "session.queued";
29057
29035
  var AGENT_MESSAGE_DELTA_KIND = "agent.message.delta";
29058
29036
  var AGENT_ACTIVITY_KIND = "agent.activity";
@@ -29062,8 +29040,6 @@ var AGENT_ACTIVITY_RECORDED_FIELD_LIMIT = 4e6;
29062
29040
  var AGENT_ACTIVITY_RECORDED_DETAIL_LIMIT = 6e6;
29063
29041
  var AGENT_ACTIVITY_LOCATION_LIMIT = 12;
29064
29042
  var AGENT_ACTIVITY_LOCATION_LENGTH_LIMIT = 1024;
29065
- var SESSION_COMPLETED_KIND = "session.completed";
29066
- var SESSION_FAILED_KIND = "session.failed";
29067
29043
  var SessionPromptDisposition = Object.freeze({
29068
29044
  Queue: "queue",
29069
29045
  Reject: "reject",
@@ -29074,23 +29050,6 @@ var SessionPromptDisposition = Object.freeze({
29074
29050
  var DIRECTORY_IDENTIFIER_PATTERN2 = /^[a-zA-Z0-9][a-zA-Z0-9_-]{0,2047}$/;
29075
29051
  var MAX_PROMPT_LENGTH = 1e4;
29076
29052
  var MAX_PROMPT_ATTACHMENT_LENGTH = 6e6;
29077
- var MAX_EVENT_TEXT_LENGTH = 1e5;
29078
- var ACTIVITY_TYPES = /* @__PURE__ */ new Set(["notice", "plan", "progress", "reasoning", "tool"]);
29079
- var NARRATION_ACTIVITY_TYPES = /* @__PURE__ */ new Set(["progress", "reasoning"]);
29080
- var ACTIVITY_STATUSES = /* @__PURE__ */ new Set(["pending", "running", "completed", "failed"]);
29081
- var TOOL_KINDS = /* @__PURE__ */ new Set([
29082
- "",
29083
- "delete",
29084
- "edit",
29085
- "execute",
29086
- "fetch",
29087
- "move",
29088
- "other",
29089
- "read",
29090
- "search",
29091
- "switch_mode",
29092
- "think"
29093
- ]);
29094
29053
  var ProtocolMessageError = class extends Error {
29095
29054
  code = "invalid_protocol_message";
29096
29055
  constructor(message, options = {}) {
@@ -29140,13 +29099,6 @@ function readText(value, key, maximumLength) {
29140
29099
  }
29141
29100
  return field;
29142
29101
  }
29143
- function readAllowedString(value, key, allowedValues) {
29144
- const field = readText(value, key, 64);
29145
- if (!allowedValues.has(field)) {
29146
- throw new ProtocolMessageError(`Invalid value field: ${key}`);
29147
- }
29148
- return field;
29149
- }
29150
29102
  function readPromptDisposition(value) {
29151
29103
  const field = value["disposition"];
29152
29104
  if (field === void 0 || field === SessionPromptDisposition.Reject) {
@@ -29160,32 +29112,6 @@ function readPromptDisposition(value) {
29160
29112
  }
29161
29113
  throw new ProtocolMessageError("Invalid value field: disposition");
29162
29114
  }
29163
- function readSequence(value, key) {
29164
- const field = value[key];
29165
- if (typeof field !== "number" || !Number.isSafeInteger(field) || field < 0) {
29166
- throw new ProtocolMessageError(`Invalid integer field: ${key}`);
29167
- }
29168
- return field;
29169
- }
29170
- function readLocations(value) {
29171
- const field = value["locations"];
29172
- if (!Array.isArray(field) || field.length > AGENT_ACTIVITY_LOCATION_LIMIT) {
29173
- throw new ProtocolMessageError("Invalid locations field");
29174
- }
29175
- const locations = [];
29176
- const unique = /* @__PURE__ */ new Set();
29177
- for (const location of field) {
29178
- if (typeof location !== "string" || location.length === 0 || location.length > AGENT_ACTIVITY_LOCATION_LENGTH_LIMIT) {
29179
- throw new ProtocolMessageError("Invalid activity location");
29180
- }
29181
- if (unique.has(location)) {
29182
- throw new ProtocolMessageError("Duplicate activity location");
29183
- }
29184
- unique.add(location);
29185
- locations.push(location);
29186
- }
29187
- return locations;
29188
- }
29189
29115
  function readDirectoryIdentifiers(value, key, maximumCount) {
29190
29116
  const field = value[key];
29191
29117
  if (!Array.isArray(field) || field.length > maximumCount) {
@@ -29202,54 +29128,6 @@ function readDirectoryIdentifiers(value, key, maximumCount) {
29202
29128
  }
29203
29129
  return identifiers;
29204
29130
  }
29205
- function readActivityContent(value) {
29206
- const field = value["content"];
29207
- if (!Array.isArray(field) || field.length > 100) {
29208
- throw new ProtocolMessageError("Invalid activity content field");
29209
- }
29210
- return field.map((entry) => decodeAgentDisplayContentValue(entry));
29211
- }
29212
- function readActivityDetail(value) {
29213
- const field = value["detail"];
29214
- if (!isRecord5(field)) {
29215
- throw new ProtocolMessageError("Invalid activity detail field");
29216
- }
29217
- const kind = readString2(field, "kind", 32);
29218
- if (kind === "available") {
29219
- return {
29220
- artifactId: readIdentifier(field, "artifactId"),
29221
- kind
29222
- };
29223
- }
29224
- if (kind === "unrecorded") {
29225
- return { kind };
29226
- }
29227
- if (kind === "truncated") {
29228
- const capturedBytes = readSequence(field, "capturedBytes");
29229
- const originalBytes = readSequence(field, "originalBytes");
29230
- if (capturedBytes > originalBytes) {
29231
- throw new ProtocolMessageError("Invalid truncated activity detail size");
29232
- }
29233
- return { capturedBytes, kind, originalBytes };
29234
- }
29235
- if (kind === "recorded") {
29236
- const contentValue = field["content"];
29237
- if (!Array.isArray(contentValue) || contentValue.length > 100) {
29238
- throw new ProtocolMessageError("Invalid recorded activity content");
29239
- }
29240
- const detail = {
29241
- content: contentValue.map((entry) => decodeRecordedAgentContentValue(entry)),
29242
- input: readText(field, "input", AGENT_ACTIVITY_RECORDED_FIELD_LIMIT),
29243
- kind,
29244
- output: readText(field, "output", AGENT_ACTIVITY_RECORDED_FIELD_LIMIT)
29245
- };
29246
- if (JSON.stringify(detail).length > AGENT_ACTIVITY_RECORDED_DETAIL_LIMIT) {
29247
- throw new ProtocolMessageError("Recorded activity detail is too large");
29248
- }
29249
- return detail;
29250
- }
29251
- throw new ProtocolMessageError("Invalid activity detail availability");
29252
- }
29253
29131
  function readIdentifier(value, key) {
29254
29132
  try {
29255
29133
  return decodeIdentifier(value[key]);
@@ -29374,82 +29252,6 @@ function decodeRuntimePongEvent(encoded) {
29374
29252
  assertKind(value, RUNTIME_PONG_KIND);
29375
29253
  return { kind: RUNTIME_PONG_KIND, requestId: readIdentifier(value, "requestId") };
29376
29254
  }
29377
- function decodeSessionStartedEvent(encoded) {
29378
- const value = parseJson2(encoded);
29379
- assertKind(value, SESSION_STARTED_KIND);
29380
- const sequence = readSequence(value, "sequence");
29381
- if (sequence !== 0) {
29382
- throw new ProtocolMessageError("Invalid live start sequence");
29383
- }
29384
- return {
29385
- commandId: readIdentifier(value, "commandId"),
29386
- epoch: readIdentifier(value, "epoch"),
29387
- kind: SESSION_STARTED_KIND,
29388
- attemptId: readIdentifier(value, "attemptId"),
29389
- prompt: readText(value, "prompt", MAX_PROMPT_LENGTH),
29390
- sequence,
29391
- sessionId: readIdentifier(value, "sessionId")
29392
- };
29393
- }
29394
- function decodeAgentMessageDeltaEvent(encoded) {
29395
- const value = parseJson2(encoded);
29396
- assertKind(value, AGENT_MESSAGE_DELTA_KIND);
29397
- const sequence = readSequence(value, "sequence");
29398
- if (sequence === 0) {
29399
- throw new ProtocolMessageError("Invalid live sequence");
29400
- }
29401
- return {
29402
- commandId: readIdentifier(value, "commandId"),
29403
- epoch: readIdentifier(value, "epoch"),
29404
- kind: AGENT_MESSAGE_DELTA_KIND,
29405
- messageId: value["messageId"] === void 0 ? "" : readText(value, "messageId", 255),
29406
- sequence,
29407
- sessionId: readIdentifier(value, "sessionId"),
29408
- text: readString2(value, "text", MAX_EVENT_TEXT_LENGTH)
29409
- };
29410
- }
29411
- function decodeAgentActivityEvent(encoded) {
29412
- const value = parseJson2(encoded);
29413
- assertKind(value, AGENT_ACTIVITY_KIND);
29414
- return {
29415
- activityId: readIdentifier(value, "activityId"),
29416
- activityType: readAllowedString(value, "activityType", ACTIVITY_TYPES),
29417
- commandId: readIdentifier(value, "commandId"),
29418
- content: readActivityContent(value),
29419
- detail: readActivityDetail(value),
29420
- input: readText(value, "input", AGENT_ACTIVITY_DETAIL_LIMIT),
29421
- kind: AGENT_ACTIVITY_KIND,
29422
- locations: readLocations(value),
29423
- name: readText(value, "name", 128),
29424
- output: readText(value, "output", AGENT_ACTIVITY_DETAIL_LIMIT),
29425
- sequence: readSequence(value, "sequence"),
29426
- sessionId: readIdentifier(value, "sessionId"),
29427
- status: readAllowedString(value, "status", ACTIVITY_STATUSES),
29428
- title: readString2(value, "title", 500),
29429
- toolKind: readAllowedString(value, "toolKind", TOOL_KINDS)
29430
- };
29431
- }
29432
- function decodeSessionCompletedEvent(encoded) {
29433
- const value = parseJson2(encoded);
29434
- assertKind(value, SESSION_COMPLETED_KIND);
29435
- return {
29436
- commandId: readIdentifier(value, "commandId"),
29437
- kind: SESSION_COMPLETED_KIND,
29438
- sessionId: readIdentifier(value, "sessionId"),
29439
- stopReason: readString2(value, "stopReason", 64)
29440
- };
29441
- }
29442
- function decodeSessionFailedEvent(encoded) {
29443
- const value = parseJson2(encoded);
29444
- assertKind(value, SESSION_FAILED_KIND);
29445
- return {
29446
- code: readIdentifier(value, "code"),
29447
- commandId: readIdentifier(value, "commandId"),
29448
- kind: SESSION_FAILED_KIND,
29449
- message: readString2(value, "message", 500),
29450
- sessionId: readIdentifier(value, "sessionId")
29451
- };
29452
- }
29453
29255
  function encodeSessionPromptCommand(message) {
29454
29256
  return JSON.stringify(decodeSessionPromptCommand(JSON.stringify(message)));
29455
29257
  }
@@ -29477,19 +29279,6 @@ function encodeRuntimePingCommand(message) {
29477
29279
  function encodeRuntimePongEvent(message) {
29478
29280
  return JSON.stringify(decodeRuntimePongEvent(JSON.stringify(message)));
29479
29281
  }
29480
- function decodeAgentActivityNarrationEvent(encoded) {
29481
- const value = parseJson2(encoded);
29482
- assertKind(value, AGENT_ACTIVITY_NARRATION_KIND);
29483
- return {
29484
- activityId: readIdentifier(value, "activityId"),
29485
- activityType: readAllowedString(value, "activityType", NARRATION_ACTIVITY_TYPES),
29486
- commandId: readIdentifier(value, "commandId"),
29487
- kind: AGENT_ACTIVITY_NARRATION_KIND,
29488
- sequence: readSequence(value, "sequence"),
29489
- sessionId: readIdentifier(value, "sessionId"),
29490
- text: readText(value, "text", MAX_EVENT_TEXT_LENGTH)
29491
- };
29492
- }
29493
29282
 
29494
29283
  // ../protocol/src/session-history.ts
29495
29284
  var SESSION_HISTORY_CHARACTER_LIMIT = 256e3;
@@ -29755,6 +29544,7 @@ var MAX_CONTENT_LENGTH = 1e6;
29755
29544
  var MAX_JSON_DEPTH = 16;
29756
29545
  var MAX_JSON_KEYS = 1e3;
29757
29546
  var SESSION_EVENT_V2_KIND = "session.event.v2";
29547
+ var SESSION_EVENT_V2_BATCH_MAX_SIZE = 1e3;
29758
29548
  var boundedString = external_exports.string().max(MAX_CONTENT_LENGTH);
29759
29549
  var shortString = external_exports.string().max(2048);
29760
29550
  var externalContentKeySchema = external_exports.string().regex(/^[a-f0-9]{64}$/u);
@@ -30058,6 +29848,11 @@ var acpSessionUpdateV2Schema = external_exports.discriminatedUnion("sessionUpdat
30058
29848
  }).readonly()
30059
29849
  ]);
30060
29850
  var lifecycleBase = { commandId: identifierStringSchema };
29851
+ var promptExecutionContextV2Schema = external_exports.object({
29852
+ agentId: identifierStringSchema,
29853
+ directoryId: shortString,
29854
+ additionalDirectoryIds: external_exports.array(identifierStringSchema).max(16).readonly()
29855
+ }).readonly();
30061
29856
  var lifecycleMetadataV2Schema = external_exports.discriminatedUnion("kind", [
30062
29857
  external_exports.object({ kind: external_exports.literal("session.queue.changed") }).readonly(),
30063
29858
  external_exports.object({ event: sessionPermissionRequestedEventSchema, kind: external_exports.literal("session.permission.requested") }).readonly(),
@@ -30067,7 +29862,8 @@ var lifecycleMetadataV2Schema = external_exports.discriminatedUnion("kind", [
30067
29862
  external_exports.object({
30068
29863
  ...lifecycleBase,
30069
29864
  content: external_exports.array(contentBlockV2Schema).min(1).max(100).readonly(),
30070
- kind: external_exports.literal("prompt.requested")
29865
+ kind: external_exports.literal("prompt.requested"),
29866
+ context: promptExecutionContextV2Schema.optional()
30071
29867
  }).readonly(),
30072
29868
  external_exports.object({ ...lifecycleBase, attemptId: identifierStringSchema, epoch: identifierStringSchema, kind: external_exports.literal("prompt.started") }).readonly(),
30073
29869
  external_exports.object({ ...lifecycleBase, kind: external_exports.literal("prompt.completed"), stopReason: shortString }).readonly(),
@@ -30120,6 +29916,7 @@ var sessionEventV2Schema = external_exports.discriminatedUnion("type", [
30120
29916
  type: external_exports.literal("lifecycle-metadata")
30121
29917
  }).readonly()
30122
29918
  ]);
29919
+ var sessionEventBatchV2Schema = external_exports.array(sessionEventV2Schema).min(1).max(SESSION_EVENT_V2_BATCH_MAX_SIZE).readonly();
30123
29920
  var sessionExportV2Schema = external_exports.object({
30124
29921
  binding: external_exports.object({
30125
29922
  bindingId: identifierStringSchema,
@@ -30162,7 +29959,7 @@ var mobiusSessionExportV2Schema = external_exports.object({
30162
29959
  formatVersion: external_exports.literal("2"),
30163
29960
  session: sessionExportV2Schema
30164
29961
  }).readonly();
30165
- var sessionEventEnvelopeV2Schema = external_exports.object({ event: sessionEventV2Schema, kind: external_exports.literal(SESSION_EVENT_V2_KIND) }).readonly();
29962
+ var sessionEventEnvelopeV2Schema = external_exports.object({ events: sessionEventBatchV2Schema, kind: external_exports.literal(SESSION_EVENT_V2_KIND) }).readonly();
30166
29963
  var sessionEventLogPageV2Schema = external_exports.object({
30167
29964
  daemonGenerationId: identifierStringSchema,
30168
29965
  events: external_exports.array(sessionEventV2Schema).max(MAX_EVENT_COUNT).readonly(),
@@ -30207,94 +30004,6 @@ var decodeSessionEventEnvelopeV2 = (value) => decode5(value, sessionEventEnvelop
30207
30004
  var encodeSessionEventEnvelopeV2 = (value) => encode4(value, sessionEventEnvelopeV2Schema);
30208
30005
  var decodeAcpSessionUpdateV2 = (value) => decode5(value, acpSessionUpdateV2Schema);
30209
30006
 
30210
- // ../protocol/src/session-events.ts
30211
- var SESSION_EVENT_KIND = "session.event";
30212
- var SESSION_FORKED_KIND = "session.forked";
30213
- var MAX_RECORDED_EVENT_LENGTH = 8 * 1024 * 1024;
30214
- var sessionEventEnvelopeSchema = external_exports.object({
30215
- kind: external_exports.literal(SESSION_EVENT_KIND),
30216
- payload: external_exports.string().min(2).max(MAX_RECORDED_EVENT_LENGTH),
30217
- sessionId: identifierStringSchema
30218
- }).readonly();
30219
- var SESSION_QUEUE_CHANGED_KIND = "session.queue.changed";
30220
- var sessionQueueChangedSchema = external_exports.object({ kind: external_exports.literal(SESSION_QUEUE_CHANGED_KIND), sessionId: identifierStringSchema }).readonly();
30221
- var sessionForkedSchema = external_exports.object({
30222
- kind: external_exports.literal(SESSION_FORKED_KIND),
30223
- sessionId: identifierStringSchema,
30224
- sourceSessionId: identifierStringSchema,
30225
- throughCommandId: identifierStringSchema
30226
- }).readonly();
30227
- function decode6(encoded, schema) {
30228
- let value;
30229
- try {
30230
- value = JSON.parse(encoded);
30231
- } catch (cause) {
30232
- throw new ProtocolMessageError("Message is not valid JSON", { cause });
30233
- }
30234
- const decoded = schema.safeParse(value);
30235
- if (!decoded.success) {
30236
- throw new ProtocolMessageError("Message does not match its schema", {
30237
- cause: decoded.error
30238
- });
30239
- }
30240
- return decoded.data;
30241
- }
30242
- var encode5 = (message, schema) => {
30243
- const decoded = schema.safeParse(message);
30244
- if (!decoded.success) {
30245
- throw new ProtocolMessageError("Message does not match its schema", {
30246
- cause: decoded.error
30247
- });
30248
- }
30249
- return JSON.stringify(decoded.data);
30250
- };
30251
- var decodeSessionEventEnvelope = (encoded) => decode6(encoded, sessionEventEnvelopeSchema);
30252
- var encodeSessionEventEnvelope = (message) => encode5(message, sessionEventEnvelopeSchema);
30253
- function decodeRecordedSessionEvent(encoded) {
30254
- const kind = decodeMessageKind(encoded);
30255
- switch (kind) {
30256
- case SESSION_QUEUE_CHANGED_KIND:
30257
- return decode6(encoded, sessionQueueChangedSchema);
30258
- case SESSION_FORKED_KIND:
30259
- return decode6(encoded, sessionForkedSchema);
30260
- case AGENT_ACTIVITY_KIND:
30261
- return decodeAgentActivityEvent(encoded);
30262
- case AGENT_ACTIVITY_NARRATION_KIND:
30263
- return decodeAgentActivityNarrationEvent(encoded);
30264
- case AGENT_CONTENT_KIND:
30265
- return decodeAgentContentEvent(encoded);
30266
- case AGENT_MESSAGE_DELTA_KIND:
30267
- return decodeAgentMessageDeltaEvent(encoded);
30268
- case SESSION_COMMANDS_UPDATED_KIND:
30269
- return decodeSessionCommandsUpdatedEvent(encoded);
30270
- case SESSION_COMPLETED_KIND:
30271
- return decodeSessionCompletedEvent(encoded);
30272
- case SESSION_CONFIG_UPDATED_KIND:
30273
- return decodeSessionConfigUpdatedEvent(encoded);
30274
- case SESSION_ELICITATION_REQUESTED_KIND:
30275
- return decodeSessionElicitationRequestedEvent(encoded);
30276
- case SESSION_ELICITATION_RESOLVED_KIND:
30277
- return decodeSessionElicitationResolvedEvent(encoded);
30278
- case SESSION_FAILED_KIND:
30279
- return decodeSessionFailedEvent(encoded);
30280
- case SESSION_INFO_UPDATED_KIND:
30281
- return decodeSessionInfoUpdatedEvent(encoded);
30282
- case SESSION_PERMISSION_REQUESTED_KIND:
30283
- return decodeSessionPermissionRequestedEvent(encoded);
30284
- case SESSION_PERMISSION_RESOLVED_KIND:
30285
- return decodeSessionPermissionResolvedEvent(encoded);
30286
- case SESSION_READY_KIND:
30287
- return decodeSessionReadyEvent(encoded);
30288
- case SESSION_STARTED_KIND:
30289
- return decodeSessionStartedEvent(encoded);
30290
- case SESSION_USAGE_UPDATED_KIND:
30291
- return decodeSessionUsageUpdatedEvent(encoded);
30292
- default:
30293
- throw new UnsupportedProtocolMessageKindError("daemon-to-service", kind);
30294
- }
30295
- }
30296
- var encodeRecordedSessionEvent = (event) => JSON.stringify(decodeRecordedSessionEvent(JSON.stringify(event)));
30297
-
30298
30007
  // ../protocol/src/session-live-history.ts
30299
30008
  var SESSION_LIVE_HISTORY_V2_PAGE_LOAD_KIND = "session.live-history.v2.page.load";
30300
30009
  var SESSION_LIVE_HISTORY_V2_PAGE_LOADED_KIND = "session.live-history.v2.page.loaded";
@@ -30316,7 +30025,7 @@ var sessionLiveHistoryV2PageLoadedSchema = external_exports.object({
30316
30025
  requestId: identifierStringSchema,
30317
30026
  sessionId: identifierStringSchema
30318
30027
  }).readonly();
30319
- function decode7(schema, encoded) {
30028
+ function decode6(schema, encoded) {
30320
30029
  try {
30321
30030
  const value = JSON.parse(encoded);
30322
30031
  return schema.parse(value);
@@ -30324,8 +30033,8 @@ function decode7(schema, encoded) {
30324
30033
  throw new ProtocolMessageError("Invalid live Session history message", { cause });
30325
30034
  }
30326
30035
  }
30327
- var decodeSessionLiveHistoryV2PageLoad = (encoded) => decode7(sessionLiveHistoryV2PageLoadSchema, encoded);
30328
- var decodeSessionLiveHistoryV2PageLoaded = (encoded) => decode7(sessionLiveHistoryV2PageLoadedSchema, encoded);
30036
+ var decodeSessionLiveHistoryV2PageLoad = (encoded) => decode6(sessionLiveHistoryV2PageLoadSchema, encoded);
30037
+ var decodeSessionLiveHistoryV2PageLoaded = (encoded) => decode6(sessionLiveHistoryV2PageLoadedSchema, encoded);
30329
30038
  var encodeSessionLiveHistoryV2PageLoad = (value) => JSON.stringify(sessionLiveHistoryV2PageLoadSchema.parse(value));
30330
30039
  var encodeSessionLiveHistoryV2PageLoaded = (value) => JSON.stringify(sessionLiveHistoryV2PageLoadedSchema.parse(value));
30331
30040
 
@@ -30439,6 +30148,11 @@ function decodeServiceToDaemonMessage(encoded) {
30439
30148
  return signature.decoder(encoded);
30440
30149
  }
30441
30150
  var daemonToServiceSignatures = {
30151
+ [SESSION_CONFIG_UPDATED_KIND]: defineMessageSignature(
30152
+ SESSION_CONFIG_UPDATED_KIND,
30153
+ encodeSessionConfigUpdatedEvent,
30154
+ decodeSessionConfigUpdatedEvent
30155
+ ),
30442
30156
  [AGENT_INSTALL_CANCELLED_KIND]: defineMessageSignature(
30443
30157
  AGENT_INSTALL_CANCELLED_KIND,
30444
30158
  encodeAgentInstallCancelledEvent,
@@ -30509,11 +30223,6 @@ var daemonToServiceSignatures = {
30509
30223
  decodeRuntimeHeartbeatEvent
30510
30224
  ),
30511
30225
  [RUNTIME_PONG_KIND]: defineMessageSignature(RUNTIME_PONG_KIND, encodeRuntimePongEvent, decodeRuntimePongEvent),
30512
- [SESSION_EVENT_KIND]: defineMessageSignature(
30513
- SESSION_EVENT_KIND,
30514
- encodeSessionEventEnvelope,
30515
- decodeSessionEventEnvelope
30516
- ),
30517
30226
  [SESSION_EVENT_V2_KIND]: defineMessageSignature(
30518
30227
  SESSION_EVENT_V2_KIND,
30519
30228
  encodeSessionEventEnvelopeV2,
@@ -32247,14 +31956,13 @@ var AgentConnection = class {
32247
31956
  get inProcessAgent() {
32248
31957
  return this.#process.kind === "in-process" ? this.#process.endpoint : null;
32249
31958
  }
32250
- captureProcessTree = async () => this.#process.kind === "child" ? await captureProcessTree(this.#process.child) : [];
32251
- closeProcess = async (capturedProcesses = []) => {
31959
+ closeProcess = async () => {
32252
31960
  try {
32253
31961
  if (this.#process.kind === "in-process") {
32254
31962
  await this.#process.endpoint.close();
32255
31963
  return;
32256
31964
  }
32257
- await stopProcessTree(this.#process.child, capturedProcesses);
31965
+ await stopProcessTree(this.#process.child);
32258
31966
  } finally {
32259
31967
  this.connection.close();
32260
31968
  }
@@ -39007,7 +38715,7 @@ var AgentSession = class _AgentSession {
39007
38715
  commandId: () => this.#turn.commandId,
39008
38716
  assertNativeSession: (sessionId) => this.assertNativeSession(sessionId),
39009
38717
  observer: getObserver,
39010
- recordSessionEventV2: this.#recordLifecycleEventV2
38718
+ recordSessionEventV2: this.recordLifecycleEventV2
39011
38719
  });
39012
38720
  this.#connection = new AgentConnection(agent, cwd, this);
39013
38721
  this.#contentExternalizer = contentExternalizer;
@@ -39590,7 +39298,14 @@ var AgentSession = class _AgentSession {
39590
39298
  if (this.#turn.running) {
39591
39299
  throw new AcpExecutionError("Another prompt is already running in this conversation", {}, "session_busy");
39592
39300
  }
39593
- const completedHistory = this.#capabilities.loadSession ? await this.#completedHistory(options.signal, "ACP agent exited while loading history before a prompt") : null;
39301
+ if (!this.#capabilities.loadSession && this.#sessionLoad.kind === "not-requested") {
39302
+ this.#sessionLoad = {
39303
+ kind: "loaded",
39304
+ history: new AcpHistoryReplay(this.#store.eventsV2, this.#mobiusSessionId),
39305
+ response: {}
39306
+ };
39307
+ }
39308
+ const completedHistory = this.#capabilities.loadSession ? await this.#completedHistory(options.signal, "ACP agent exited while loading history before a prompt") : this.#sessionLoad.kind === "loaded" ? this.#sessionLoad.history : null;
39594
39309
  const prompt = this.buildPrompt(options);
39595
39310
  if (this.#sessionTitle === null || this.#sessionTitle.length === 0) {
39596
39311
  this.#sessionTitle = truncate(options.prompt, 500);
@@ -39619,11 +39334,16 @@ var AgentSession = class _AgentSession {
39619
39334
  this.#turnHistory = completedHistory === null ? null : new AcpHistoryReplay(this.#store.eventsV2, this.#mobiusSessionId);
39620
39335
  const lifecycleV2 = options.lifecycleV2;
39621
39336
  if (lifecycleV2 !== void 0) {
39622
- await this.#recordLifecycleEventV2({
39623
- payload: { commandId: options.commandId, content: lifecycleV2.content, kind: "prompt.requested" },
39337
+ await this.recordLifecycleEventV2({
39338
+ payload: {
39339
+ commandId: options.commandId,
39340
+ content: lifecycleV2.content,
39341
+ kind: "prompt.requested",
39342
+ ...lifecycleV2.context === void 0 ? {} : { context: lifecycleV2.context }
39343
+ },
39624
39344
  type: "lifecycle-metadata"
39625
39345
  });
39626
- await this.#recordLifecycleEventV2({
39346
+ await this.recordLifecycleEventV2({
39627
39347
  payload: {
39628
39348
  attemptId: lifecycleV2.attemptId,
39629
39349
  commandId: options.commandId,
@@ -39686,7 +39406,7 @@ var AgentSession = class _AgentSession {
39686
39406
  )
39687
39407
  );
39688
39408
  if (lifecycleV2 !== void 0) {
39689
- await this.#recordLifecycleEventV2({
39409
+ await this.recordLifecycleEventV2({
39690
39410
  payload: { commandId: options.commandId, kind: "prompt.completed", stopReason: result.stopReason },
39691
39411
  type: "lifecycle-metadata"
39692
39412
  });
@@ -39696,8 +39416,8 @@ var AgentSession = class _AgentSession {
39696
39416
  await running.activities.finish();
39697
39417
  const failure2 = error62 instanceof AcpExecutionError ? error62 : new AcpExecutionError("ACP agent execution failed", { cause: error62 });
39698
39418
  if (lifecycleV2 !== void 0) {
39699
- await this.#recordLifecycleEventV2({
39700
- payload: {
39419
+ await this.recordLifecycleEventV2({
39420
+ payload: options.cancellationRequested?.() === true ? { commandId: options.commandId, kind: "prompt.completed", stopReason: "cancelled" } : {
39701
39421
  attemptId: lifecycleV2.attemptId,
39702
39422
  code: failure2.code,
39703
39423
  commandId: options.commandId,
@@ -39733,11 +39453,16 @@ var AgentSession = class _AgentSession {
39733
39453
  const prompt = this.buildPrompt(options);
39734
39454
  const lifecycleV2 = options.lifecycleV2;
39735
39455
  if (lifecycleV2 !== void 0) {
39736
- await this.#recordLifecycleEventV2({
39737
- payload: { commandId: options.commandId, content: lifecycleV2.content, kind: "prompt.requested" },
39456
+ await this.recordLifecycleEventV2({
39457
+ payload: {
39458
+ commandId: options.commandId,
39459
+ content: lifecycleV2.content,
39460
+ kind: "prompt.requested",
39461
+ ...lifecycleV2.context === void 0 ? {} : { context: lifecycleV2.context }
39462
+ },
39738
39463
  type: "lifecycle-metadata"
39739
39464
  });
39740
- await this.#recordLifecycleEventV2({
39465
+ await this.recordLifecycleEventV2({
39741
39466
  payload: {
39742
39467
  attemptId: lifecycleV2.attemptId,
39743
39468
  commandId: options.commandId,
@@ -39767,7 +39492,7 @@ var AgentSession = class _AgentSession {
39767
39492
  const outcome = response["outcome"];
39768
39493
  if (outcome === "injected" || outcome === "startedNewTurn") {
39769
39494
  if (lifecycleV2 !== void 0) {
39770
- await this.#recordLifecycleEventV2({
39495
+ await this.recordLifecycleEventV2({
39771
39496
  payload: { commandId: options.commandId, kind: "prompt.completed", stopReason: "steered" },
39772
39497
  type: "lifecycle-metadata"
39773
39498
  });
@@ -39792,7 +39517,7 @@ var AgentSession = class _AgentSession {
39792
39517
  } catch (error62) {
39793
39518
  const failure2 = error62 instanceof AcpExecutionError ? error62 : new AcpExecutionError("ACP agent execution failed", { cause: error62 });
39794
39519
  if (lifecycleV2 !== void 0) {
39795
- await this.#recordLifecycleEventV2({
39520
+ await this.recordLifecycleEventV2({
39796
39521
  payload: {
39797
39522
  attemptId: lifecycleV2.attemptId,
39798
39523
  code: failure2.code,
@@ -39807,16 +39532,11 @@ var AgentSession = class _AgentSession {
39807
39532
  }
39808
39533
  };
39809
39534
  cancel = async () => {
39810
- const capturedProcesses = await this.#connection.captureProcessTree();
39811
- try {
39812
- await this.#interactions.cancelPendingInteractions();
39813
- if (this.#turn.running) {
39814
- await this.#connection.connection.agent.notify(methods8.agent.session.cancel, {
39815
- sessionId: this.#updates.sessionId()
39816
- });
39817
- }
39818
- } finally {
39819
- await this.closeProcess(capturedProcesses);
39535
+ await this.#interactions.cancelPendingInteractions();
39536
+ if (this.#turn.running) {
39537
+ await this.#connection.connection.agent.notify(methods8.agent.session.cancel, {
39538
+ sessionId: this.#updates.sessionId()
39539
+ });
39820
39540
  }
39821
39541
  };
39822
39542
  respondPermission = (options) => this.#interactions.respondPermission(options);
@@ -39825,7 +39545,14 @@ var AgentSession = class _AgentSession {
39825
39545
  onElicitation = (request, signal) => this.#interactions.onElicitation(request, signal);
39826
39546
  onElicitationComplete = (notification) => this.#interactions.onElicitationComplete(notification);
39827
39547
  onUpdate = (notification) => this.#updates.receive(notification);
39828
- #recordLifecycleEventV2 = async (event) => {
39548
+ recordControlEventV2 = async (event) => {
39549
+ if (this.#sessionLoad.kind !== "loaded") {
39550
+ return false;
39551
+ }
39552
+ await this.recordLifecycleEventV2(event);
39553
+ return true;
39554
+ };
39555
+ recordLifecycleEventV2 = async (event) => {
39829
39556
  if (event.type !== "lifecycle-metadata" || this.#sessionLoad.kind !== "loaded") {
39830
39557
  return;
39831
39558
  }
@@ -40009,7 +39736,7 @@ var AgentSession = class _AgentSession {
40009
39736
  await this.closeProcess();
40010
39737
  }
40011
39738
  };
40012
- closeProcess = (capturedProcesses = []) => this.#connection.closeProcess(capturedProcesses);
39739
+ closeProcess = () => this.#connection.closeProcess();
40013
39740
  race = (operation, exitMessage, signal) => this.#connection.race(operation, exitMessage, signal);
40014
39741
  assertNativeSession = (sessionId) => {
40015
39742
  if (sessionId !== this.#updates.sessionId()) {
@@ -40888,6 +40615,13 @@ var AgentRuntimeManager = class {
40888
40615
  this.#contentExternalizer = contentExternalizer;
40889
40616
  this.#queryProcesses = new AgentQueryProcesses(this.#processes, contentExternalizer);
40890
40617
  }
40618
+ recordLifecycleEventV2 = async (sessionId, event) => {
40619
+ const runtime = this.#executionProcesses.get(sessionId);
40620
+ if (runtime === void 0) {
40621
+ return false;
40622
+ }
40623
+ return await runtime.recordControlEventV2(event);
40624
+ };
40891
40625
  setObserver = (observer) => {
40892
40626
  this.#observer = observer;
40893
40627
  };
@@ -41143,13 +40877,7 @@ var AgentRuntimeManager = class {
41143
40877
  await this.#executions.cancel(sessionId, async () => {
41144
40878
  const runtime = this.#executionProcesses.get(sessionId);
41145
40879
  if (runtime !== void 0) {
41146
- try {
41147
- await runtime.cancel();
41148
- } finally {
41149
- if (this.#executionProcesses.detach(sessionId, runtime)) {
41150
- this.#processes.releaseClosed(runtime);
41151
- }
41152
- }
40880
+ await runtime.cancel();
41153
40881
  }
41154
40882
  });
41155
40883
  };
@@ -41217,7 +40945,10 @@ var AgentRuntimeManager = class {
41217
40945
  return { stopReason: "cancelled" };
41218
40946
  }
41219
40947
  try {
41220
- const result = await runtime.prompt(options2);
40948
+ const result = await runtime.prompt({
40949
+ ...options2,
40950
+ cancellationRequested: () => this.#executions.cancellation(options2.sessionId) !== void 0
40951
+ });
41221
40952
  return this.#executions.cancellation(options2.sessionId) !== void 0 ? { stopReason: "cancelled" } : result;
41222
40953
  } catch (error62) {
41223
40954
  if (this.#executions.cancellation(options2.sessionId) !== void 0) {
@@ -42515,16 +42246,7 @@ function send(socket, message) {
42515
42246
  }
42516
42247
  socket.send(encodeDaemonToServiceMessage(message));
42517
42248
  }
42518
- function reportFailure(publisher, command, code, message) {
42519
- publisher.publish(command.sessionId, {
42520
- code,
42521
- commandId: command.commandId,
42522
- kind: SESSION_FAILED_KIND,
42523
- message,
42524
- sessionId: command.sessionId
42525
- });
42526
- }
42527
- function settleAbandonedTurn(publisher, operations, audit, cancellation) {
42249
+ async function settleAbandonedTurn(eventLog, operations, audit, cancellation) {
42528
42250
  const attemptId = operations.findUnsettledAttemptId(cancellation.commandId, cancellation.sessionId);
42529
42251
  if (attemptId === null) {
42530
42252
  console.warn("Mobius daemon ignored cancellation for an inactive turn");
@@ -42535,13 +42257,14 @@ function settleAbandonedTurn(publisher, operations, audit, cancellation) {
42535
42257
  event: "session_abandoned_turn_settled",
42536
42258
  sessionId: cancellation.sessionId
42537
42259
  });
42538
- reportFailure(
42539
- publisher,
42540
- cancellation,
42260
+ await eventLog.failed(
42261
+ cancellation.sessionId,
42262
+ cancellation.commandId,
42541
42263
  "agent_execution_abandoned",
42542
42264
  "The local Agent execution was abandoned before it completed"
42543
42265
  );
42544
42266
  operations.transitionExecution(cancellation.commandId, "failed");
42267
+ eventLog.publishTerminal(cancellation.sessionId, cancellation.commandId);
42545
42268
  }
42546
42269
  function operationErrorCode(error62) {
42547
42270
  if (error62 instanceof AcpExecutionError || error62 instanceof LocalAuthorizationError || error62 instanceof LocalAgentCatalogError || error62 instanceof PromptArtifactError) {
@@ -45630,112 +45353,6 @@ function warnIgnoredSetting(audit, event, commandId, sessionId, agentId, selecti
45630
45353
  `);
45631
45354
  }
45632
45355
 
45633
- // src/relay-connection/coalescing-agent-event-publisher.ts
45634
- var AGENT_EVENT_COALESCING_MILLISECONDS = 100;
45635
- var AGENT_EVENT_TEXT_MAXIMUM_LENGTH = 1e5;
45636
- var CoalescingAgentEventPublisher = class {
45637
- #entries = [];
45638
- #publish;
45639
- #publishedActivityIds = /* @__PURE__ */ new Set();
45640
- #scheduled = null;
45641
- #timer;
45642
- constructor(timer, publish) {
45643
- this.#publish = publish;
45644
- this.#timer = timer;
45645
- }
45646
- flush = () => {
45647
- this.#scheduled?.cancel();
45648
- this.#scheduled = null;
45649
- const entries = this.#entries;
45650
- this.#entries = [];
45651
- for (const entry of entries) {
45652
- this.#publish(entry);
45653
- }
45654
- };
45655
- recordActivity = (activity2) => {
45656
- const latest = this.#entries.at(-1);
45657
- this.#entries = latest?.kind === "activity" && latest.activity.activityId === activity2.activityId ? [...this.#entries.slice(0, -1), { activity: activity2, kind: "activity" }] : [...this.#entries, { activity: activity2, kind: "activity" }];
45658
- const first = !this.#publishedActivityIds.has(activity2.activityId);
45659
- this.#publishedActivityIds.add(activity2.activityId);
45660
- if (first || activity2.status !== "pending" && activity2.status !== "running") {
45661
- this.flush();
45662
- } else {
45663
- this.schedule();
45664
- }
45665
- return Promise.resolve();
45666
- };
45667
- recordNarration = (increment) => {
45668
- if (increment.text.length === 0) {
45669
- return Promise.resolve();
45670
- }
45671
- let remaining = increment.text;
45672
- while (remaining.length > 0) {
45673
- const latest = this.#entries.at(-1);
45674
- if (latest?.kind === "narration" && latest.increment.activityId === increment.activityId) {
45675
- const available = AGENT_EVENT_TEXT_MAXIMUM_LENGTH - latest.increment.text.length;
45676
- if (available > 0) {
45677
- this.#entries = [
45678
- ...this.#entries.slice(0, -1),
45679
- {
45680
- increment: {
45681
- ...increment,
45682
- text: `${latest.increment.text}${remaining.slice(0, available)}`
45683
- },
45684
- kind: "narration"
45685
- }
45686
- ];
45687
- remaining = remaining.slice(available);
45688
- continue;
45689
- }
45690
- }
45691
- this.#entries = [
45692
- ...this.#entries,
45693
- {
45694
- increment: { ...increment, text: remaining.slice(0, AGENT_EVENT_TEXT_MAXIMUM_LENGTH) },
45695
- kind: "narration"
45696
- }
45697
- ];
45698
- remaining = remaining.slice(AGENT_EVENT_TEXT_MAXIMUM_LENGTH);
45699
- }
45700
- this.schedule();
45701
- return Promise.resolve();
45702
- };
45703
- recordText = (text2, messageId) => {
45704
- if (text2.length === 0) {
45705
- return Promise.resolve();
45706
- }
45707
- let remaining = text2;
45708
- while (remaining.length > 0) {
45709
- const latest = this.#entries.at(-1);
45710
- if (latest?.kind === "text" && latest.messageId === messageId) {
45711
- const available = AGENT_EVENT_TEXT_MAXIMUM_LENGTH - latest.text.length;
45712
- if (available > 0) {
45713
- this.#entries = [
45714
- ...this.#entries.slice(0, -1),
45715
- { ...latest, text: `${latest.text}${remaining.slice(0, available)}` }
45716
- ];
45717
- remaining = remaining.slice(available);
45718
- continue;
45719
- }
45720
- }
45721
- this.#entries = [
45722
- ...this.#entries,
45723
- {
45724
- kind: "text",
45725
- messageId,
45726
- text: remaining.slice(0, AGENT_EVENT_TEXT_MAXIMUM_LENGTH)
45727
- }
45728
- ];
45729
- remaining = remaining.slice(AGENT_EVENT_TEXT_MAXIMUM_LENGTH);
45730
- }
45731
- this.schedule();
45732
- return Promise.resolve();
45733
- };
45734
- schedule() {
45735
- this.#scheduled ??= this.#timer.schedule(this.flush, AGENT_EVENT_COALESCING_MILLISECONDS);
45736
- }
45737
- };
45738
-
45739
45356
  // src/daemon-prompt-executor.ts
45740
45357
  function daemonActivity(command, activity2) {
45741
45358
  return {
@@ -45758,7 +45375,6 @@ function daemonActivity(command, activity2) {
45758
45375
  }
45759
45376
  async function executePrompt({
45760
45377
  operations,
45761
- publisher,
45762
45378
  eventLogV2,
45763
45379
  command,
45764
45380
  config: config2,
@@ -45768,36 +45384,11 @@ async function executePrompt({
45768
45384
  attemptId,
45769
45385
  activateAttempt,
45770
45386
  waitForSessionAvailability,
45771
- timer,
45772
45387
  signal,
45773
- recordLiveEvent,
45388
+ recordTurnEvent,
45774
45389
  recordSteeringPrompt,
45775
45390
  cancellationRequested
45776
45391
  }) {
45777
- const events = new CoalescingAgentEventPublisher(timer, (event) => {
45778
- if (event.kind === "text") {
45779
- publisher.publish(
45780
- command.sessionId,
45781
- recordLiveEvent({ kind: AGENT_MESSAGE_DELTA_KIND, messageId: event.messageId, text: event.text })
45782
- );
45783
- return;
45784
- }
45785
- if (event.kind === "narration") {
45786
- const recorded = {
45787
- activityId: event.increment.activityId,
45788
- activityType: event.increment.activityType,
45789
- commandId: command.commandId,
45790
- kind: AGENT_ACTIVITY_NARRATION_KIND,
45791
- sequence: event.increment.sequence,
45792
- sessionId: command.sessionId,
45793
- text: event.increment.text
45794
- };
45795
- publisher.publish(command.sessionId, recordLiveEvent(recorded));
45796
- return;
45797
- }
45798
- const activity2 = daemonActivity(command, event.activity);
45799
- publisher.publish(command.sessionId, recordLiveEvent(activity2));
45800
- });
45801
45392
  try {
45802
45393
  const resolved = await resolveSessionDirectories(
45803
45394
  directories,
@@ -45865,33 +45456,6 @@ async function executePrompt({
45865
45456
  }
45866
45457
  const stream = activateAttempt();
45867
45458
  const lifecycleV2 = eventLogV2.started(command.sessionId, command.commandId, attemptId, stream.epoch);
45868
- if (!prepared.prompted) {
45869
- const listing = await directories.list(config2.bindingId, command.directoryId, signal);
45870
- publisher.publish(command.sessionId, {
45871
- additionalDirectories: resolved.additionalDirectoryEntries,
45872
- agentId: command.agentId,
45873
- agentName: prepared.agentName,
45874
- agentVersion: prepared.agentVersion,
45875
- capabilities: prepared.capabilities,
45876
- commands: prepared.commands,
45877
- configOptions: prepared.configOptions,
45878
- directoryId: command.directoryId,
45879
- directoryLabel: listing.directoryLabel,
45880
- kind: SESSION_READY_KIND,
45881
- requestId: command.commandId,
45882
- restored: prepared.restored,
45883
- sessionId: command.sessionId
45884
- });
45885
- }
45886
- publisher.publish(command.sessionId, {
45887
- commandId: command.commandId,
45888
- epoch: stream.epoch,
45889
- kind: SESSION_STARTED_KIND,
45890
- attemptId,
45891
- prompt: command.prompt,
45892
- sequence: stream.sequence,
45893
- sessionId: command.sessionId
45894
- });
45895
45459
  const attachments = await resolvePromptArtifacts(config2, command, signal);
45896
45460
  let stopReason;
45897
45461
  if (availability.disposition === SessionPromptDisposition.Steer) {
@@ -45918,9 +45482,20 @@ async function executePrompt({
45918
45482
  disposition: availability.disposition,
45919
45483
  images: attachments.images,
45920
45484
  lifecycleV2,
45921
- onActivity: events.recordActivity,
45922
- onNarration: events.recordNarration,
45923
- onText: events.recordText,
45485
+ onActivity: async (activity2) => {
45486
+ recordTurnEvent(daemonActivity(command, activity2));
45487
+ },
45488
+ onNarration: async (increment) => {
45489
+ recordTurnEvent({
45490
+ ...increment,
45491
+ commandId: command.commandId,
45492
+ sessionId: command.sessionId,
45493
+ kind: AGENT_ACTIVITY_NARRATION_KIND
45494
+ });
45495
+ },
45496
+ onText: async (text2, messageId) => {
45497
+ recordTurnEvent({ kind: AGENT_MESSAGE_DELTA_KIND, text: text2, messageId });
45498
+ },
45924
45499
  prompt: command.prompt,
45925
45500
  resources: attachments.resources,
45926
45501
  sessionId: command.sessionId,
@@ -45929,14 +45504,7 @@ async function executePrompt({
45929
45504
  });
45930
45505
  stopReason = result.stopReason;
45931
45506
  }
45932
- events.flush();
45933
- publisher.publish(command.sessionId, {
45934
- commandId: command.commandId,
45935
- kind: SESSION_COMPLETED_KIND,
45936
- sessionId: command.sessionId,
45937
- stopReason
45938
- });
45939
- eventLogV2.completed(command.sessionId, command.commandId, stopReason);
45507
+ await eventLogV2.completed(command.sessionId, command.commandId, stopReason);
45940
45508
  operations.transitionExecution(command.commandId, stopReason === "cancelled" ? "cancelled" : "succeeded");
45941
45509
  audit.record({
45942
45510
  commandId: command.commandId,
@@ -45944,15 +45512,8 @@ async function executePrompt({
45944
45512
  sessionId: command.sessionId
45945
45513
  });
45946
45514
  } catch (error62) {
45947
- events.flush();
45948
45515
  if (signal.aborted && cancellationRequested()) {
45949
- publisher.publish(command.sessionId, {
45950
- commandId: command.commandId,
45951
- kind: SESSION_COMPLETED_KIND,
45952
- sessionId: command.sessionId,
45953
- stopReason: "cancelled"
45954
- });
45955
- eventLogV2.completed(command.sessionId, command.commandId, "cancelled");
45516
+ await eventLogV2.completed(command.sessionId, command.commandId, "cancelled");
45956
45517
  operations.transitionExecution(command.commandId, "cancelled");
45957
45518
  audit.record({
45958
45519
  commandId: command.commandId,
@@ -45969,8 +45530,7 @@ async function executePrompt({
45969
45530
  const code = operationErrorCode(error62);
45970
45531
  const failureCode = code === "session_operation_failed" ? "agent_execution_failed" : code;
45971
45532
  const failureMessage = code === "session_operation_failed" ? "The local agent could not complete the request" : operationErrorMessage(error62);
45972
- eventLogV2.failed(command.sessionId, command.commandId, failureCode, failureMessage);
45973
- reportFailure(publisher, command, failureCode, failureMessage);
45533
+ await eventLogV2.failed(command.sessionId, command.commandId, failureCode, failureMessage);
45974
45534
  operations.transitionExecution(command.commandId, "failed");
45975
45535
  console.error("Mobius daemon command failed", error62);
45976
45536
  }
@@ -45998,7 +45558,7 @@ async function executeWorkspaceList(socket, command, directories, audit, signal)
45998
45558
  reportOperationFailure(socket, command.requestId, "", error62);
45999
45559
  }
46000
45560
  }
46001
- async function executeSessionPrepare(publisher, socket, command, config2, directories, audit, sessions, diagnostics, signal) {
45561
+ async function executeSessionPrepare(socket, command, config2, directories, audit, sessions, diagnostics, signal) {
46002
45562
  const metrics = new AccumulatingOperationMetrics();
46003
45563
  try {
46004
45564
  const readyEvent = await metrics.measure("prepare-total", async () => {
@@ -46048,12 +45608,6 @@ async function executeSessionPrepare(publisher, socket, command, config2, direct
46048
45608
  event: "session_configured",
46049
45609
  sessionId: command.sessionId
46050
45610
  });
46051
- publisher.publish(command.sessionId, {
46052
- configOptions,
46053
- kind: "session.config.updated",
46054
- requestId: command.requestId,
46055
- sessionId: command.sessionId
46056
- });
46057
45611
  }
46058
45612
  const event = {
46059
45613
  additionalDirectories: resolved.additionalDirectoryEntries,
@@ -46071,11 +45625,6 @@ async function executeSessionPrepare(publisher, socket, command, config2, direct
46071
45625
  sessionId: command.sessionId,
46072
45626
  runtimeTimings: metrics.snapshot()
46073
45627
  };
46074
- if (command.transient !== true) {
46075
- metrics.measureSync("readiness-commit", () => {
46076
- publisher.publish(command.sessionId, event);
46077
- });
46078
- }
46079
45628
  return event;
46080
45629
  });
46081
45630
  send(socket, {
@@ -46105,7 +45654,7 @@ async function executeSessionPrepare(publisher, socket, command, config2, direct
46105
45654
  reportOperationFailure(socket, command.requestId, command.sessionId, error62, metrics.snapshot());
46106
45655
  }
46107
45656
  }
46108
- async function executeSessionConfigure(publisher, socket, command, config2, directories, audit, sessions, signal) {
45657
+ async function executeSessionConfigure(socket, command, config2, directories, audit, sessions, signal) {
46109
45658
  try {
46110
45659
  const resolved = await resolveSessionDirectories(
46111
45660
  directories,
@@ -46131,7 +45680,7 @@ async function executeSessionConfigure(publisher, socket, command, config2, dire
46131
45680
  event: "session_configured",
46132
45681
  sessionId: command.sessionId
46133
45682
  });
46134
- publisher.publish(command.sessionId, {
45683
+ send(socket, {
46135
45684
  configOptions,
46136
45685
  kind: "session.config.updated",
46137
45686
  requestId: command.requestId,
@@ -46251,7 +45800,6 @@ function createDaemonCommandHandler({
46251
45800
  installations,
46252
45801
  nativeSessions,
46253
45802
  operations,
46254
- publisher,
46255
45803
  eventLogV2,
46256
45804
  externalContent,
46257
45805
  activeTurns,
@@ -46272,8 +45820,9 @@ function createDaemonCommandHandler({
46272
45820
  timer
46273
45821
  });
46274
45822
  const queueChanged = (sessionId) => {
46275
- publisher.publish(sessionId, { kind: "session.queue.changed", sessionId });
46276
- eventLogV2.queueChanged(sessionId);
45823
+ void eventLogV2.queueChanged(sessionId).catch((error62) => {
45824
+ console.error("Could not record queue change", error62);
45825
+ });
46277
45826
  };
46278
45827
  const nativeRequestHandler = createNativeSessionRequestHandler({
46279
45828
  audit,
@@ -46342,7 +45891,9 @@ function createDaemonCommandHandler({
46342
45891
  const cancellation = message;
46343
45892
  const turn2 = activeTurns.get(cancellation.commandId);
46344
45893
  if (turn2 === void 0 || !turn2.matches(cancellation)) {
46345
- settleAbandonedTurn(publisher, operations, audit, cancellation);
45894
+ void settleAbandonedTurn(eventLogV2, operations, audit, cancellation).catch((error62) => {
45895
+ console.error("Could not settle abandoned turn", error62);
45896
+ });
46346
45897
  return;
46347
45898
  }
46348
45899
  const cancellationState = turn2.requestCancellation();
@@ -46382,22 +45933,12 @@ function createDaemonCommandHandler({
46382
45933
  }
46383
45934
  if (kind === SESSION_PREPARE_KIND) {
46384
45935
  const command2 = message;
46385
- void executeSessionPrepare(
46386
- publisher,
46387
- socket,
46388
- command2,
46389
- config2,
46390
- directories,
46391
- audit,
46392
- sessions,
46393
- diagnostics,
46394
- signal
46395
- );
45936
+ void executeSessionPrepare(socket, command2, config2, directories, audit, sessions, diagnostics, signal);
46396
45937
  return;
46397
45938
  }
46398
45939
  if (kind === SESSION_CONFIGURE_KIND) {
46399
45940
  const command2 = message;
46400
- void executeSessionConfigure(publisher, socket, command2, config2, directories, audit, sessions, signal);
45941
+ void executeSessionConfigure(socket, command2, config2, directories, audit, sessions, signal);
46401
45942
  return;
46402
45943
  }
46403
45944
  if (kind === SESSION_LIST_KIND) {
@@ -46499,7 +46040,6 @@ function createDaemonCommandHandler({
46499
46040
  eventLogV2.requested(command);
46500
46041
  void executePrompt({
46501
46042
  operations,
46502
- publisher,
46503
46043
  eventLogV2,
46504
46044
  command,
46505
46045
  config: config2,
@@ -46516,15 +46056,15 @@ function createDaemonCommandHandler({
46516
46056
  sessionId: command.sessionId
46517
46057
  });
46518
46058
  }),
46519
- timer,
46520
46059
  signal: turn.signal,
46521
- recordLiveEvent: turn.recordEvent,
46060
+ recordTurnEvent: turn.recordEvent,
46522
46061
  recordSteeringPrompt: () => activeTurns.recordSteeringPrompt(command),
46523
46062
  cancellationRequested: turn.cancellationRequested
46524
46063
  }).catch((error62) => {
46525
46064
  console.error("Mobius daemon turn failed", error62);
46526
46065
  }).finally(() => {
46527
46066
  activeTurns.finish(turn);
46067
+ eventLogV2.publishTerminal(command.sessionId, command.commandId);
46528
46068
  if (command.disposition === SessionPromptDisposition.Queue) {
46529
46069
  queueChanged(command.sessionId);
46530
46070
  }
@@ -46808,7 +46348,6 @@ async function runRelayConnection({
46808
46348
  installations,
46809
46349
  nativeSessions,
46810
46350
  operations,
46811
- publisher,
46812
46351
  eventLogV2,
46813
46352
  externalContent,
46814
46353
  activeTurns,
@@ -46960,29 +46499,39 @@ async function runRelayConnection({
46960
46499
  // src/relay-connection/session-event-publisher.ts
46961
46500
  import { WebSocket as WebSocket8 } from "undici";
46962
46501
  var MAX_BUFFERED_BYTES = 32 * 1024 * 1024;
46502
+ var SESSION_EVENT_V2_BATCH_WINDOW_MILLISECONDS = 200;
46963
46503
  var DaemonSessionEventPublisher = class {
46504
+ #pendingV2Events = [];
46505
+ #pendingV2Task = null;
46964
46506
  #socket = null;
46507
+ #timer;
46508
+ constructor(timer) {
46509
+ this.#timer = timer;
46510
+ }
46965
46511
  connect = (socket) => {
46512
+ this.dropPendingV2Events();
46966
46513
  this.#socket = socket;
46967
46514
  };
46968
46515
  disconnect = (socket) => {
46969
46516
  if (this.#socket === socket) {
46970
46517
  this.#socket = null;
46518
+ this.dropPendingV2Events();
46971
46519
  }
46972
46520
  };
46973
46521
  close = () => {
46974
46522
  this.#socket = null;
46523
+ this.dropPendingV2Events();
46975
46524
  };
46976
- publish = (sessionId, event) => {
46525
+ publishOperationFailure = (sessionId, requestId, code, message) => {
46526
+ this.#send({ kind: "session.operation.failed", sessionId, requestId, code, message });
46527
+ };
46528
+ publishStatus = (event) => this.#send(event);
46529
+ #send = (message) => {
46977
46530
  const socket = this.#socket;
46978
46531
  if (socket === null || socket.readyState !== WebSocket8.OPEN) {
46979
46532
  return;
46980
46533
  }
46981
- const encoded = encodeDaemonToServiceMessage({
46982
- kind: SESSION_EVENT_KIND,
46983
- payload: encodeRecordedSessionEvent(event),
46984
- sessionId
46985
- });
46534
+ const encoded = encodeDaemonToServiceMessage(message);
46986
46535
  if (socket.bufferedAmount + Buffer.byteLength(encoded, "utf8") > MAX_BUFFERED_BYTES) {
46987
46536
  socket.close(1013, "Live event transport overloaded");
46988
46537
  return;
@@ -46992,32 +46541,35 @@ var DaemonSessionEventPublisher = class {
46992
46541
  } catch {
46993
46542
  }
46994
46543
  };
46995
- publishBatch = (sessionId, events) => {
46996
- for (const event of events) {
46997
- this.publish(sessionId, event);
46998
- }
46999
- };
47000
- publishStatus = (event) => {
46544
+ publishV2 = (event) => {
47001
46545
  const socket = this.#socket;
47002
46546
  if (socket === null || socket.readyState !== WebSocket8.OPEN) {
47003
46547
  return;
47004
46548
  }
47005
- const encoded = encodeDaemonToServiceMessage(event);
47006
- if (socket.bufferedAmount + Buffer.byteLength(encoded, "utf8") > MAX_BUFFERED_BYTES) {
47007
- socket.close(1013, "Live event transport overloaded");
46549
+ this.#pendingV2Events.push(event);
46550
+ if (this.#pendingV2Events.length >= SESSION_EVENT_V2_BATCH_MAX_SIZE) {
46551
+ this.flushV2Events(socket);
47008
46552
  return;
47009
46553
  }
47010
- try {
47011
- socket.send(encoded);
47012
- } catch {
47013
- }
46554
+ this.#pendingV2Task ??= this.#timer.schedule(
46555
+ () => this.flushV2Events(socket),
46556
+ SESSION_EVENT_V2_BATCH_WINDOW_MILLISECONDS
46557
+ );
47014
46558
  };
47015
- publishV2 = (event) => {
47016
- const socket = this.#socket;
47017
- if (socket === null || socket.readyState !== WebSocket8.OPEN) {
46559
+ dropPendingV2Events = () => {
46560
+ this.#pendingV2Task?.cancel();
46561
+ this.#pendingV2Task = null;
46562
+ this.#pendingV2Events = [];
46563
+ };
46564
+ flushV2Events = (socket) => {
46565
+ this.#pendingV2Task?.cancel();
46566
+ this.#pendingV2Task = null;
46567
+ const events = this.#pendingV2Events;
46568
+ this.#pendingV2Events = [];
46569
+ if (events.length === 0 || this.#socket !== socket || socket.readyState !== WebSocket8.OPEN) {
47018
46570
  return;
47019
46571
  }
47020
- const encoded = encodeDaemonToServiceMessage({ event, kind: SESSION_EVENT_V2_KIND });
46572
+ const encoded = encodeDaemonToServiceMessage({ events, kind: SESSION_EVENT_V2_KIND });
47021
46573
  if (socket.bufferedAmount + Buffer.byteLength(encoded, "utf8") > MAX_BUFFERED_BYTES) {
47022
46574
  socket.close(1013, "Live event transport overloaded");
47023
46575
  return;
@@ -47077,8 +46629,12 @@ function sessionEventV22(daemonGenerationId, sessionId, position, event, recorde
47077
46629
  var DaemonSessionEventLogV2 = class {
47078
46630
  daemonGenerationId;
47079
46631
  #publisher;
46632
+ #terminal = /* @__PURE__ */ new Map();
46633
+ #publications = /* @__PURE__ */ new Map();
47080
46634
  #queued = /* @__PURE__ */ new Map();
47081
- constructor(publisher, daemonGenerationId = randomUUID9()) {
46635
+ #recordLifecycle;
46636
+ constructor(publisher, recordLifecycle, daemonGenerationId = randomUUID9()) {
46637
+ this.#recordLifecycle = recordLifecycle;
47082
46638
  this.#publisher = publisher;
47083
46639
  this.daemonGenerationId = daemonGenerationId;
47084
46640
  }
@@ -47086,36 +46642,101 @@ var DaemonSessionEventLogV2 = class {
47086
46642
  this.#queued.set(command.commandId, {
47087
46643
  commandId: command.commandId,
47088
46644
  content: promptContent(command),
46645
+ context: {
46646
+ agentId: command.agentId,
46647
+ directoryId: command.directoryId,
46648
+ additionalDirectoryIds: command.additionalDirectoryIds
46649
+ },
46650
+ phase: "queued",
47089
46651
  sessionId: command.sessionId
47090
46652
  });
47091
46653
  };
47092
46654
  started = (sessionId, commandId, attemptId, epoch) => {
47093
46655
  const request = this.#queued.get(commandId);
47094
46656
  if (request?.sessionId === sessionId) {
47095
- this.#queued.delete(commandId);
47096
- return { attemptId, content: request.content, epoch };
46657
+ this.#queued.set(commandId, { ...request, phase: "running" });
46658
+ return { attemptId, content: request.content, epoch, context: request.context };
47097
46659
  }
47098
46660
  throw new Error("The executing prompt was not registered in the V2 queue");
47099
46661
  };
47100
46662
  record = (sessionId, event, position) => {
47101
- this.#publisher.publishV2(this.event(sessionId, position, event, (/* @__PURE__ */ new Date()).toISOString()));
46663
+ const recorded = this.event(sessionId, position, event, (/* @__PURE__ */ new Date()).toISOString());
46664
+ if (event.type === "lifecycle-metadata" && (event.payload.kind === "prompt.completed" || event.payload.kind === "prompt.failed" || event.payload.kind === "prompt.failed-before-start")) {
46665
+ this.#terminal.set(event.payload.commandId, recorded);
46666
+ const pending2 = this.#publications.get(sessionId) ?? [];
46667
+ pending2.push(recorded);
46668
+ this.#publications.set(sessionId, pending2);
46669
+ return;
46670
+ }
46671
+ const pending = this.#publications.get(sessionId);
46672
+ if (pending !== void 0) {
46673
+ pending.push(recorded);
46674
+ } else {
46675
+ this.#publisher.publishV2(recorded);
46676
+ }
46677
+ };
46678
+ publishTerminal = (sessionId, commandId) => {
46679
+ const event = this.#terminal.get(commandId);
46680
+ if (event?.sessionId === sessionId) {
46681
+ this.#terminal.delete(commandId);
46682
+ const pending = this.#publications.get(sessionId) ?? [];
46683
+ while (pending.length > 0) {
46684
+ const next = pending[0];
46685
+ if (next === void 0) {
46686
+ break;
46687
+ }
46688
+ if (next.type === "lifecycle-metadata" && "commandId" in next.payload && this.#terminal.has(next.payload.commandId)) {
46689
+ break;
46690
+ }
46691
+ pending.shift();
46692
+ this.#publisher.publishV2(next);
46693
+ }
46694
+ if (pending.length === 0) {
46695
+ this.#publications.delete(sessionId);
46696
+ }
46697
+ }
46698
+ this.#queued.delete(commandId);
47102
46699
  };
47103
46700
  event = (sessionId, position, event, recordedAt) => sessionEventV22(this.daemonGenerationId, sessionId, position, event, recordedAt);
47104
- queueChanged = (_sessionId) => void 0;
47105
- completed = (sessionId, commandId, _stopReason) => {
46701
+ queueChanged = async (sessionId) => {
46702
+ await this.#recordLifecycle(sessionId, {
46703
+ type: "lifecycle-metadata",
46704
+ payload: { kind: "session.queue.changed" }
46705
+ });
46706
+ };
46707
+ completed = async (sessionId, commandId, stopReason) => {
47106
46708
  const request = this.#queued.get(commandId);
47107
- if (request?.sessionId === sessionId) {
47108
- this.#queued.delete(commandId);
46709
+ if (request?.sessionId !== sessionId || this.#terminal.has(commandId)) {
46710
+ return;
46711
+ }
46712
+ const recorded = await this.#recordLifecycle(sessionId, {
46713
+ type: "lifecycle-metadata",
46714
+ payload: { kind: "prompt.completed", commandId, stopReason }
46715
+ });
46716
+ if (!recorded) {
46717
+ this.#publisher.publishOperationFailure(
46718
+ sessionId,
46719
+ commandId,
46720
+ "cancelled",
46721
+ "The prompt was cancelled before execution"
46722
+ );
47109
46723
  }
47110
46724
  };
47111
- failed = (sessionId, commandId, _code, _message) => {
46725
+ failed = async (sessionId, commandId, code, message) => {
47112
46726
  const request = this.#queued.get(commandId);
47113
- if (request?.sessionId === sessionId) {
47114
- this.#queued.delete(commandId);
46727
+ if (request?.sessionId !== sessionId || this.#terminal.has(commandId)) {
46728
+ return;
46729
+ }
46730
+ const recorded = await this.#recordLifecycle(sessionId, {
46731
+ type: "lifecycle-metadata",
46732
+ payload: { kind: "prompt.failed-before-start", commandId, code, message }
46733
+ });
46734
+ if (!recorded) {
46735
+ this.#publisher.publishOperationFailure(sessionId, commandId, code, message);
47115
46736
  }
47116
46737
  };
47117
46738
  promptRequestRecovery = (sessionId) => ({
47118
- queuedPromptRequests: [...this.#queued.values()].filter((request) => request.sessionId === sessionId).map(({ commandId, content }) => ({ commandId, content }))
46739
+ queuedPromptRequests: [...this.#queued.values()].filter((request) => request.sessionId === sessionId && request.phase === "queued").map(({ commandId, content }) => ({ commandId, content }))
47119
46740
  });
47120
46741
  };
47121
46742
 
@@ -47201,14 +46822,17 @@ async function runDaemon(config2, audit, signal, timer = systemDaemonTimer, opti
47201
46822
  const sessionStore = new SqliteAcpSessionStore(sessionDatabase, eventsV2);
47202
46823
  await using externalContent = new LocalExternalContentStore(stateDirectory);
47203
46824
  const operations = new DaemonOperationState();
47204
- const publisher = new DaemonSessionEventPublisher();
47205
- const eventLogV2 = new DaemonSessionEventLogV2(publisher, daemonGenerationId);
46825
+ const publisher = new DaemonSessionEventPublisher(timer);
46826
+ const eventLogV2 = new DaemonSessionEventLogV2(
46827
+ publisher,
46828
+ (sessionId, event) => agentRuntime.recordLifecycleEventV2(sessionId, event),
46829
+ daemonGenerationId
46830
+ );
47206
46831
  const activeTurns = new DaemonTurnRegistry(operations);
47207
- const recordSessionEvent = (sessionId, event) => {
47208
- publisher.publish(sessionId, activeTurns.recordEvent(event));
47209
- };
47210
46832
  const agentRuntime = new AgentRuntimeManager(
47211
- new DaemonAcpObserver(recordSessionEvent, eventLogV2.record),
46833
+ new DaemonAcpObserver((_sessionId, event) => {
46834
+ activeTurns.recordEvent(event);
46835
+ }, eventLogV2.record),
47212
46836
  sessionStore,
47213
46837
  {
47214
46838
  read: async (options2, nativeSessionId, nativeTurn) => options2.agent.id === "codex" ? (await readCodexFullHistory(