@moxt-ai/mobius 0.0.26 → 0.0.27

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -19340,6 +19340,9 @@ var SESSION_CANCEL_KIND = "session.cancel";
19340
19340
  var RUNTIME_LIVENESS_READY_KIND = "runtime.liveness.ready";
19341
19341
  var RUNTIME_HEARTBEAT_KIND = "runtime.heartbeat";
19342
19342
  var RUNTIME_HEARTBEAT_ACK_KIND = "runtime.heartbeat.ack";
19343
+ var RUNTIME_DELIVERY_KIND = "runtime.delivery";
19344
+ var RUNTIME_DELIVERY_RECEIVED_KIND = "runtime.delivery.received";
19345
+ var RUNTIME_DELIVERY_COMMITTED_KIND = "runtime.delivery.committed";
19343
19346
  var SESSION_STARTED_KIND = "session.started";
19344
19347
  var AGENT_MESSAGE_DELTA_KIND = "agent.message.delta";
19345
19348
  var AGENT_ACTIVITY_KIND = "agent.activity";
@@ -19362,6 +19365,7 @@ var DIRECTORY_IDENTIFIER_PATTERN2 = /^[a-zA-Z0-9][a-zA-Z0-9_-]{0,2047}$/;
19362
19365
  var MAX_PROMPT_LENGTH = 1e4;
19363
19366
  var MAX_PROMPT_ATTACHMENT_LENGTH = 6e6;
19364
19367
  var MAX_EVENT_TEXT_LENGTH = 1e5;
19368
+ var MAX_RUNTIME_DELIVERY_PAYLOAD_LENGTH = 8 * 1024 * 1024;
19365
19369
  var ACTIVITY_TYPES = /* @__PURE__ */ new Set(["plan", "progress", "reasoning", "tool"]);
19366
19370
  var ACTIVITY_STATUSES = /* @__PURE__ */ new Set(["pending", "running", "completed", "failed"]);
19367
19371
  var TOOL_KINDS = /* @__PURE__ */ new Set([
@@ -19640,6 +19644,37 @@ function decodeRuntimeHeartbeatAckEvent(encoded) {
19640
19644
  kind: RUNTIME_HEARTBEAT_ACK_KIND
19641
19645
  };
19642
19646
  }
19647
+ function decodeRuntimeDelivery(encoded) {
19648
+ const value = parseJson2(encoded);
19649
+ assertExactKeys(value, ["deliveryId", "kind", "payload", "sessionId"]);
19650
+ assertKind(value, RUNTIME_DELIVERY_KIND);
19651
+ return {
19652
+ deliveryId: readIdentifier(value, "deliveryId"),
19653
+ kind: RUNTIME_DELIVERY_KIND,
19654
+ payload: readString(value, "payload", MAX_RUNTIME_DELIVERY_PAYLOAD_LENGTH),
19655
+ sessionId: readIdentifier(value, "sessionId")
19656
+ };
19657
+ }
19658
+ function decodeRuntimeDeliveryReceived(encoded) {
19659
+ const value = parseJson2(encoded);
19660
+ assertExactKeys(value, ["deliveryId", "kind", "sessionId"]);
19661
+ assertKind(value, RUNTIME_DELIVERY_RECEIVED_KIND);
19662
+ return {
19663
+ deliveryId: readIdentifier(value, "deliveryId"),
19664
+ kind: RUNTIME_DELIVERY_RECEIVED_KIND,
19665
+ sessionId: readIdentifier(value, "sessionId")
19666
+ };
19667
+ }
19668
+ function decodeRuntimeDeliveryCommitted(encoded) {
19669
+ const value = parseJson2(encoded);
19670
+ assertExactKeys(value, ["deliveryId", "kind", "sessionId"]);
19671
+ assertKind(value, RUNTIME_DELIVERY_COMMITTED_KIND);
19672
+ return {
19673
+ deliveryId: readIdentifier(value, "deliveryId"),
19674
+ kind: RUNTIME_DELIVERY_COMMITTED_KIND,
19675
+ sessionId: readIdentifier(value, "sessionId")
19676
+ };
19677
+ }
19643
19678
  function decodeSessionStartedEvent(encoded) {
19644
19679
  const value = parseJson2(encoded);
19645
19680
  assertExactKeys(value, ["commandId", "kind", "attemptId", "sessionId"]);
@@ -19727,6 +19762,9 @@ function decodeSessionFailedEvent(encoded) {
19727
19762
  function encodeRuntimeHeartbeatEvent(message) {
19728
19763
  return JSON.stringify(decodeRuntimeHeartbeatEvent(JSON.stringify(message)));
19729
19764
  }
19765
+ function encodeRuntimeDeliveryReceived(message) {
19766
+ return JSON.stringify(decodeRuntimeDeliveryReceived(JSON.stringify(message)));
19767
+ }
19730
19768
  function encodeSessionStartedEvent(message) {
19731
19769
  return JSON.stringify(decodeSessionStartedEvent(JSON.stringify(message)));
19732
19770
  }
@@ -20425,7 +20463,8 @@ var SESSION_EVENT_COMMITTED_KIND = "session.event.committed";
20425
20463
  var SESSION_EVENT_REJECTED_KIND = "session.event.rejected";
20426
20464
  var SessionEventRejectionCode = {
20427
20465
  SessionDeleted: "session_deleted",
20428
- SessionNotFound: "session_not_found"
20466
+ SessionNotFound: "session_not_found",
20467
+ SessionRejected: "session_rejected"
20429
20468
  };
20430
20469
  var IDENTIFIER_PATTERN4 = /^[a-zA-Z0-9][a-zA-Z0-9._:-]{0,127}$/;
20431
20470
  var CURSOR_PATTERN = /^[A-Za-z0-9_-]{1,512}$/;
@@ -27468,12 +27507,12 @@ function decodePairingResponse(value, credentialField, expectedKeys) {
27468
27507
  throw new PairingClientError("invalid_relay_response", "The relay returned an invalid pairing response");
27469
27508
  }
27470
27509
  const channelId = value["channelId"];
27471
- const runtimeCredential = value[credentialField];
27510
+ const runtimeCredential2 = value[credentialField];
27472
27511
  const runtimeId = value["runtimeId"];
27473
- if (typeof channelId !== "string" || !IDENTIFIER_PATTERN6.test(channelId) || typeof runtimeCredential !== "string" || !TOKEN_PATTERN2.test(runtimeCredential) || typeof runtimeId !== "string" || !IDENTIFIER_PATTERN6.test(runtimeId)) {
27512
+ if (typeof channelId !== "string" || !IDENTIFIER_PATTERN6.test(channelId) || typeof runtimeCredential2 !== "string" || !TOKEN_PATTERN2.test(runtimeCredential2) || typeof runtimeId !== "string" || !IDENTIFIER_PATTERN6.test(runtimeId)) {
27474
27513
  throw new PairingClientError("invalid_relay_response", "The relay returned an invalid pairing response");
27475
27514
  }
27476
- return { channelId, runtimeCredential, runtimeId };
27515
+ return { channelId, runtimeCredential: runtimeCredential2, runtimeId };
27477
27516
  }
27478
27517
  async function claimPairing(options, defaultWorkspace, localAgents, installableAgents, signal) {
27479
27518
  const agents = localAgents.map((agent) => ({
@@ -27508,7 +27547,7 @@ async function claimPairing(options, defaultWorkspace, localAgents, installableA
27508
27547
  }
27509
27548
  return options.pairingId.length > 0 ? decodePairingResponse(value, "runtimeCredential", REDEEM_RESPONSE_KEYS) : decodePairingResponse(value, "daemonToken", CLAIM_RESPONSE_KEYS);
27510
27549
  }
27511
- async function persistConnection(channelId, relayOrigin, runtimeCredential, defaultWorkspace, environment) {
27550
+ async function persistConnection(channelId, relayOrigin, runtimeCredential2, defaultWorkspace, environment) {
27512
27551
  const connectionsDirectory = join14(readStateDirectory(environment), "connections");
27513
27552
  await mkdir4(connectionsDirectory, { mode: 448, recursive: true });
27514
27553
  const connectionPath = join14(connectionsDirectory, `${channelId}.json`);
@@ -27520,7 +27559,7 @@ async function persistConnection(channelId, relayOrigin, runtimeCredential, defa
27520
27559
  defaultWorkspace,
27521
27560
  channelId,
27522
27561
  relayOrigin: relayOrigin.toString(),
27523
- runtimeCredential
27562
+ runtimeCredential: runtimeCredential2
27524
27563
  },
27525
27564
  null,
27526
27565
  2
@@ -27537,16 +27576,16 @@ function decodeSavedConnection(value, expectedChannelId) {
27537
27576
  }
27538
27577
  const defaultWorkspace = value["defaultWorkspace"];
27539
27578
  const channelId = value["channelId"];
27540
- const runtimeCredential = value["runtimeCredential"] ?? value["daemonToken"];
27579
+ const runtimeCredential2 = value["runtimeCredential"] ?? value["daemonToken"];
27541
27580
  const relayOrigin = value["relayOrigin"];
27542
- if (typeof defaultWorkspace !== "string" || typeof channelId !== "string" || channelId !== expectedChannelId || !IDENTIFIER_PATTERN6.test(channelId) || typeof runtimeCredential !== "string" || !TOKEN_PATTERN2.test(runtimeCredential) || typeof relayOrigin !== "string") {
27581
+ if (typeof defaultWorkspace !== "string" || typeof channelId !== "string" || channelId !== expectedChannelId || !IDENTIFIER_PATTERN6.test(channelId) || typeof runtimeCredential2 !== "string" || !TOKEN_PATTERN2.test(runtimeCredential2) || typeof relayOrigin !== "string") {
27543
27582
  throw new PairingClientError("invalid_connection", "The saved connection is invalid");
27544
27583
  }
27545
27584
  return {
27546
27585
  defaultWorkspace,
27547
27586
  channelId,
27548
27587
  relayOrigin: parseRelayOrigin(relayOrigin),
27549
- runtimeCredential
27588
+ runtimeCredential: runtimeCredential2
27550
27589
  };
27551
27590
  }
27552
27591
  async function readSavedConnection(channelId, environment) {
@@ -27669,6 +27708,23 @@ import { fetch as fetch6, WebSocket as WebSocket2 } from "undici";
27669
27708
 
27670
27709
  // src/agent-catalog/publish-agent-catalog.ts
27671
27710
  import { fetch as fetch4 } from "undici";
27711
+
27712
+ // src/relay-connection/runtime-authentication.ts
27713
+ function runtimeCredential(relayUrl) {
27714
+ return relayUrl.searchParams.get("token") ?? "";
27715
+ }
27716
+ function runtimeAuthorization(relayUrl) {
27717
+ const credential = runtimeCredential(relayUrl);
27718
+ return credential.length === 0 ? {} : { authorization: `Bearer ${credential}` };
27719
+ }
27720
+ function relayHttpEndpoint(relayUrl) {
27721
+ const endpoint = new URL(relayUrl);
27722
+ endpoint.protocol = endpoint.protocol === "wss:" ? "https:" : "http:";
27723
+ endpoint.search = "";
27724
+ return endpoint;
27725
+ }
27726
+
27727
+ // src/agent-catalog/publish-agent-catalog.ts
27672
27728
  var CATALOG_UPDATE_TIMEOUT_MILLISECONDS = 2e4;
27673
27729
  var AgentCatalogPublishError = class extends Error {
27674
27730
  code = "agent_catalog_update_failed";
@@ -27678,8 +27734,7 @@ var AgentCatalogPublishError = class extends Error {
27678
27734
  }
27679
27735
  };
27680
27736
  function catalogEndpoint(config2) {
27681
- const endpoint = new URL(config2.relayUrl);
27682
- endpoint.protocol = endpoint.protocol === "wss:" ? "https:" : "http:";
27737
+ const endpoint = relayHttpEndpoint(config2.relayUrl);
27683
27738
  if (endpoint.pathname.endsWith("/daemon")) {
27684
27739
  endpoint.pathname = `${endpoint.pathname.slice(0, -"/daemon".length)}/catalog`;
27685
27740
  return endpoint;
@@ -27710,7 +27765,7 @@ async function publishAgentCatalog(config2, signal) {
27710
27765
  installableAgents: catalog.installableAgents
27711
27766
  }),
27712
27767
  dispatcher: environmentProxyDispatcher,
27713
- headers: { "content-type": "application/json" },
27768
+ headers: { ...runtimeAuthorization(config2.relayUrl), "content-type": "application/json" },
27714
27769
  method: "PUT",
27715
27770
  signal: requestSignal
27716
27771
  });
@@ -29066,8 +29121,7 @@ function parseReference(resource) {
29066
29121
  return new PromptArtifactReference(artifactId, byteLength, sha256, resource);
29067
29122
  }
29068
29123
  function downloadUrl(config2, command, reference) {
29069
- const url2 = new URL(config2.relayUrl);
29070
- url2.protocol = url2.protocol === "wss:" ? "https:" : "http:";
29124
+ const url2 = relayHttpEndpoint(config2.relayUrl);
29071
29125
  let channelPath = "";
29072
29126
  if (url2.pathname.endsWith("/daemon")) {
29073
29127
  channelPath = url2.pathname.slice(0, -"/daemon".length);
@@ -29079,7 +29133,6 @@ function downloadUrl(config2, command, reference) {
29079
29133
  channelPath = `${url2.pathname.slice(0, -runtimePath.length)}/channels/${encodeURIComponent(config2.channelId)}`;
29080
29134
  }
29081
29135
  url2.pathname = `${channelPath}/sessions/${encodeURIComponent(command.sessionId)}/commands/${encodeURIComponent(command.commandId)}/artifacts/${encodeURIComponent(reference.artifactId)}/content`;
29082
- url2.searchParams.delete("liveness");
29083
29136
  return url2;
29084
29137
  }
29085
29138
  async function responseBytes(response, expectedByteLength, signal) {
@@ -29130,7 +29183,11 @@ async function download(config2, command, reference, signal) {
29130
29183
  try {
29131
29184
  response = await fetch5(downloadUrl(config2, command, reference), {
29132
29185
  dispatcher: environmentProxyDispatcher,
29133
- headers: { accept: reference.resource.mimeType },
29186
+ headers: {
29187
+ accept: reference.resource.mimeType,
29188
+ "accept-encoding": "identity",
29189
+ ...runtimeAuthorization(config2.relayUrl)
29190
+ },
29134
29191
  signal: requestSignal
29135
29192
  });
29136
29193
  if (!response.ok) {
@@ -29240,12 +29297,8 @@ function connectRelay(url2, signal) {
29240
29297
  signal.throwIfAborted();
29241
29298
  return new Promise((resolve6, reject) => {
29242
29299
  const endpoint = new URL(url2);
29243
- const headers = {};
29244
- if (endpoint.pathname.endsWith("/v1/runtimes/connect")) {
29245
- const runtimeCredential = endpoint.searchParams.get("token") ?? "";
29246
- endpoint.searchParams.delete("token");
29247
- headers["authorization"] = `Bearer ${runtimeCredential}`;
29248
- }
29300
+ const headers = runtimeAuthorization(endpoint);
29301
+ endpoint.searchParams.delete("token");
29249
29302
  const socket = new WebSocket(endpoint, {
29250
29303
  dispatcher: environmentProxyDispatcher,
29251
29304
  headers
@@ -29568,6 +29621,42 @@ var RelayConnectionLiveness = class {
29568
29621
  import { mkdirSync as mkdirSync3 } from "node:fs";
29569
29622
  import { dirname as dirname7 } from "node:path";
29570
29623
  import { DatabaseSync as DatabaseSync4 } from "node:sqlite";
29624
+ var DEFAULT_OUTBOX_LIMITS = {
29625
+ criticalEventBytes: 136 * 1024 * 1024,
29626
+ criticalEventCount: 10128,
29627
+ runtimeDeliveryBytes: 64 * 1024 * 1024,
29628
+ runtimeDeliveryCount: 64,
29629
+ standardEventBytes: 128 * 1024 * 1024,
29630
+ standardEventCount: 1e4
29631
+ };
29632
+ var SessionEventOutboxCapacityError = class extends Error {
29633
+ code = "session_event_outbox_full";
29634
+ constructor() {
29635
+ super("The durable Session event outbox is full");
29636
+ this.name = "SessionEventOutboxCapacityError";
29637
+ }
29638
+ };
29639
+ var RuntimeDeliveryInboxCapacityError = class extends Error {
29640
+ code = "runtime_delivery_inbox_full";
29641
+ constructor() {
29642
+ super("The durable Runtime delivery inbox is full");
29643
+ this.name = "RuntimeDeliveryInboxCapacityError";
29644
+ }
29645
+ };
29646
+ var StoredRuntimeDelivery = class {
29647
+ deliveryId;
29648
+ duplicate;
29649
+ payload;
29650
+ sessionId;
29651
+ state;
29652
+ constructor(deliveryId, sessionId, payload, state, duplicate) {
29653
+ this.deliveryId = deliveryId;
29654
+ this.duplicate = duplicate;
29655
+ this.payload = payload;
29656
+ this.sessionId = sessionId;
29657
+ this.state = state;
29658
+ }
29659
+ };
29571
29660
  function readPendingEnvelope(row) {
29572
29661
  if (typeof row !== "object" || row === null || Array.isArray(row)) {
29573
29662
  throw new Error("SQLite returned an invalid session event outbox row");
@@ -29578,9 +29667,26 @@ function readPendingEnvelope(row) {
29578
29667
  }
29579
29668
  return envelope2;
29580
29669
  }
29670
+ function rowNumber(row, field) {
29671
+ const value = typeof row === "object" && row !== null ? Reflect.get(row, field) : void 0;
29672
+ if (typeof value !== "number" || !Number.isSafeInteger(value) || value < 0) {
29673
+ throw new Error(`SQLite returned an invalid ${field} value`);
29674
+ }
29675
+ return value;
29676
+ }
29677
+ function rowString2(row, field) {
29678
+ const value = typeof row === "object" && row !== null ? Reflect.get(row, field) : void 0;
29679
+ if (typeof value !== "string" || value.length === 0) {
29680
+ throw new Error(`SQLite returned an invalid ${field} value`);
29681
+ }
29682
+ return value;
29683
+ }
29581
29684
  var SessionEventOutbox = class {
29582
29685
  #database;
29583
- constructor(path2) {
29686
+ #limits;
29687
+ constructor(path2, limits = DEFAULT_OUTBOX_LIMITS) {
29688
+ validateLimits(limits);
29689
+ this.#limits = limits;
29584
29690
  mkdirSync3(dirname7(path2), { recursive: true });
29585
29691
  this.#database = new DatabaseSync4(path2);
29586
29692
  this.#database.exec(`
@@ -29589,6 +29695,7 @@ var SessionEventOutbox = class {
29589
29695
  event_id TEXT NOT NULL UNIQUE,
29590
29696
  session_id TEXT NOT NULL,
29591
29697
  source_key TEXT NOT NULL,
29698
+ byte_length INTEGER NOT NULL,
29592
29699
  envelope_json TEXT NOT NULL
29593
29700
  ) STRICT;
29594
29701
  CREATE INDEX IF NOT EXISTS relay_session_event_outbox_order
@@ -29599,7 +29706,7 @@ var SessionEventOutbox = class {
29599
29706
  session_id TEXT NOT NULL,
29600
29707
  envelope_json TEXT NOT NULL,
29601
29708
  rejection_code TEXT NOT NULL CHECK (
29602
- rejection_code IN ('session_deleted', 'session_not_found')
29709
+ rejection_code IN ('session_deleted', 'session_not_found', 'session_rejected')
29603
29710
  )
29604
29711
  ) STRICT;
29605
29712
  CREATE TABLE IF NOT EXISTS relay_session_event_sources (
@@ -29615,7 +29722,53 @@ var SessionEventOutbox = class {
29615
29722
  state IN ('dispatching', 'running', 'succeeded', 'failed', 'cancelled')
29616
29723
  )
29617
29724
  ) STRICT;
29725
+ CREATE TABLE IF NOT EXISTS relay_session_event_outbox_state (
29726
+ singleton INTEGER PRIMARY KEY CHECK (singleton = 1),
29727
+ event_count INTEGER NOT NULL,
29728
+ total_bytes INTEGER NOT NULL
29729
+ ) STRICT;
29730
+ INSERT OR IGNORE INTO relay_session_event_outbox_state (
29731
+ singleton, event_count, total_bytes
29732
+ ) VALUES (1, 0, 0);
29733
+ CREATE TABLE IF NOT EXISTS relay_runtime_deliveries (
29734
+ delivery_id TEXT PRIMARY KEY,
29735
+ session_id TEXT NOT NULL,
29736
+ payload_json TEXT NOT NULL,
29737
+ payload_bytes INTEGER NOT NULL,
29738
+ state TEXT NOT NULL CHECK (
29739
+ state IN ('received', 'relay_committed', 'processed')
29740
+ ),
29741
+ received_at INTEGER NOT NULL
29742
+ ) STRICT;
29618
29743
  `);
29744
+ const deadLetterTable = this.#database.prepare(
29745
+ `SELECT sql FROM sqlite_master
29746
+ WHERE type = 'table' AND name = 'relay_session_event_dead_letters'`
29747
+ ).get();
29748
+ const deadLetterSql = typeof deadLetterTable === "object" && deadLetterTable !== null ? Reflect.get(deadLetterTable, "sql") : void 0;
29749
+ if (typeof deadLetterSql !== "string" || !deadLetterSql.includes("'session_rejected'")) {
29750
+ this.#database.exec(`
29751
+ BEGIN IMMEDIATE;
29752
+ ALTER TABLE relay_session_event_dead_letters
29753
+ RENAME TO relay_session_event_dead_letters_legacy;
29754
+ CREATE TABLE relay_session_event_dead_letters (
29755
+ ordinal INTEGER PRIMARY KEY,
29756
+ event_id TEXT NOT NULL UNIQUE,
29757
+ session_id TEXT NOT NULL,
29758
+ envelope_json TEXT NOT NULL,
29759
+ rejection_code TEXT NOT NULL CHECK (
29760
+ rejection_code IN ('session_deleted', 'session_not_found', 'session_rejected')
29761
+ )
29762
+ ) STRICT;
29763
+ INSERT INTO relay_session_event_dead_letters (
29764
+ ordinal, event_id, session_id, envelope_json, rejection_code
29765
+ )
29766
+ SELECT ordinal, event_id, session_id, envelope_json, rejection_code
29767
+ FROM relay_session_event_dead_letters_legacy;
29768
+ DROP TABLE relay_session_event_dead_letters_legacy;
29769
+ COMMIT;
29770
+ `);
29771
+ }
29619
29772
  const outboxColumns = this.#database.prepare("PRAGMA table_info(relay_session_event_outbox)").all();
29620
29773
  const hasSourceKey = outboxColumns.some(
29621
29774
  (column) => typeof column === "object" && column !== null && Reflect.get(column, "name") === "source_key"
@@ -29626,6 +29779,15 @@ var SessionEventOutbox = class {
29626
29779
  ADD COLUMN source_key TEXT NOT NULL DEFAULT '';
29627
29780
  `);
29628
29781
  }
29782
+ const hasByteLength = outboxColumns.some(
29783
+ (column) => typeof column === "object" && column !== null && Reflect.get(column, "name") === "byte_length"
29784
+ );
29785
+ if (!hasByteLength) {
29786
+ this.#database.exec(`
29787
+ ALTER TABLE relay_session_event_outbox
29788
+ ADD COLUMN byte_length INTEGER NOT NULL DEFAULT 0;
29789
+ `);
29790
+ }
29629
29791
  this.#database.exec(`
29630
29792
  UPDATE relay_session_event_outbox
29631
29793
  SET source_key = CASE json_extract(envelope_json, '$.source.kind')
@@ -29634,6 +29796,16 @@ var SessionEventOutbox = class {
29634
29796
  ELSE 'runtime:' || session_id
29635
29797
  END
29636
29798
  WHERE source_key = '';
29799
+ UPDATE relay_session_event_outbox
29800
+ SET byte_length = length(CAST(envelope_json AS BLOB))
29801
+ WHERE byte_length = 0;
29802
+ UPDATE relay_session_event_outbox_state
29803
+ SET event_count = (SELECT COUNT(*) FROM relay_session_event_outbox),
29804
+ total_bytes = (
29805
+ SELECT COALESCE(SUM(byte_length), 0)
29806
+ FROM relay_session_event_outbox
29807
+ )
29808
+ WHERE singleton = 1;
29637
29809
  CREATE INDEX IF NOT EXISTS relay_session_event_outbox_source_order
29638
29810
  ON relay_session_event_outbox(source_key, ordinal);
29639
29811
  `);
@@ -29694,13 +29866,19 @@ var SessionEventOutbox = class {
29694
29866
  const state = typeof row === "object" && row !== null ? Reflect.get(row, "state") : void 0;
29695
29867
  return state === "succeeded" || state === "failed" || state === "cancelled";
29696
29868
  };
29697
- acknowledge = (acknowledgement) => this.#database.prepare(
29698
- `DELETE FROM relay_session_event_outbox
29699
- WHERE event_id = ? AND session_id = ?`
29700
- ).run(acknowledgement.eventId, acknowledgement.sessionId).changes === 1;
29869
+ acknowledge = (acknowledgement) => this.#removeAcknowledgedEvent(acknowledgement.eventId, acknowledgement.sessionId);
29701
29870
  quarantine = (rejection) => {
29702
29871
  this.#database.exec("BEGIN IMMEDIATE");
29703
29872
  try {
29873
+ const stored = this.#database.prepare(
29874
+ `SELECT byte_length FROM relay_session_event_outbox
29875
+ WHERE event_id = ? AND session_id = ?`
29876
+ ).get(rejection.eventId, rejection.sessionId);
29877
+ if (stored === void 0) {
29878
+ this.#database.exec("COMMIT");
29879
+ return false;
29880
+ }
29881
+ const byteLength = rowNumber(stored, "byte_length");
29704
29882
  const insertion = this.#database.prepare(
29705
29883
  `INSERT INTO relay_session_event_dead_letters (
29706
29884
  ordinal, event_id, session_id, envelope_json, rejection_code
@@ -29720,6 +29898,7 @@ var SessionEventOutbox = class {
29720
29898
  if (deletion.changes !== 1) {
29721
29899
  throw new Error("The rejected session event could not be removed from the durable outbox");
29722
29900
  }
29901
+ this.#decrementEventState(byteLength);
29723
29902
  this.#database.exec("COMMIT");
29724
29903
  return true;
29725
29904
  } catch (error61) {
@@ -29731,7 +29910,129 @@ var SessionEventOutbox = class {
29731
29910
  this.#database.close();
29732
29911
  };
29733
29912
  enqueue = (sessionId, payload, attemptId = null) => {
29734
- const sourceKey = attemptId === null ? `runtime:${sessionId}` : `attempt:${sessionId}:${attemptId}`;
29913
+ return this.#enqueueBounded(
29914
+ sessionId,
29915
+ payload,
29916
+ attemptId ?? "",
29917
+ this.#limits.standardEventCount,
29918
+ this.#limits.standardEventBytes
29919
+ );
29920
+ };
29921
+ enqueueCritical = (sessionId, payload, attemptId = "") => this.#enqueueBounded(
29922
+ sessionId,
29923
+ payload,
29924
+ attemptId,
29925
+ this.#limits.criticalEventCount,
29926
+ this.#limits.criticalEventBytes
29927
+ );
29928
+ claimRuntimeDelivery = (delivery) => {
29929
+ const payloadBytes = new TextEncoder().encode(delivery.payload).byteLength;
29930
+ this.#database.exec("BEGIN IMMEDIATE");
29931
+ try {
29932
+ const existing = this.#database.prepare(
29933
+ `SELECT session_id, payload_json, state
29934
+ FROM relay_runtime_deliveries
29935
+ WHERE delivery_id = ?`
29936
+ ).get(delivery.deliveryId);
29937
+ if (existing !== void 0) {
29938
+ const sessionId = rowString2(existing, "session_id");
29939
+ const payload = rowString2(existing, "payload_json");
29940
+ const state = runtimeDeliveryState(existing);
29941
+ if (sessionId !== delivery.sessionId || payload !== delivery.payload) {
29942
+ throw new Error("The Runtime delivery identity conflicts with its durable receipt");
29943
+ }
29944
+ this.#database.exec("COMMIT");
29945
+ return new StoredRuntimeDelivery(delivery.deliveryId, sessionId, payload, state, true);
29946
+ }
29947
+ const usage = this.#database.prepare(
29948
+ `SELECT COUNT(*) AS delivery_count,
29949
+ COALESCE(SUM(payload_bytes), 0) AS delivery_bytes
29950
+ FROM relay_runtime_deliveries`
29951
+ ).get();
29952
+ if (rowNumber(usage, "delivery_count") + 1 > this.#limits.runtimeDeliveryCount || rowNumber(usage, "delivery_bytes") + payloadBytes > this.#limits.runtimeDeliveryBytes) {
29953
+ throw new RuntimeDeliveryInboxCapacityError();
29954
+ }
29955
+ this.#database.prepare(
29956
+ `INSERT INTO relay_runtime_deliveries (
29957
+ delivery_id, session_id, payload_json, payload_bytes, state, received_at
29958
+ ) VALUES (?, ?, ?, ?, 'received', ?)`
29959
+ ).run(delivery.deliveryId, delivery.sessionId, delivery.payload, payloadBytes, Date.now());
29960
+ this.#database.exec("COMMIT");
29961
+ return new StoredRuntimeDelivery(
29962
+ delivery.deliveryId,
29963
+ delivery.sessionId,
29964
+ delivery.payload,
29965
+ "received",
29966
+ false
29967
+ );
29968
+ } catch (error61) {
29969
+ this.#database.exec("ROLLBACK");
29970
+ throw error61;
29971
+ }
29972
+ };
29973
+ markRuntimeDeliveryCommitted = (deliveryId, sessionId) => {
29974
+ this.#database.exec("BEGIN IMMEDIATE");
29975
+ try {
29976
+ const row = this.#database.prepare(
29977
+ `SELECT state FROM relay_runtime_deliveries
29978
+ WHERE delivery_id = ? AND session_id = ?`
29979
+ ).get(deliveryId, sessionId);
29980
+ if (row === void 0) {
29981
+ this.#database.exec("COMMIT");
29982
+ return false;
29983
+ }
29984
+ const state = runtimeDeliveryState(row);
29985
+ if (state === "processed") {
29986
+ this.#database.prepare(`DELETE FROM relay_runtime_deliveries WHERE delivery_id = ?`).run(deliveryId);
29987
+ } else if (state === "received") {
29988
+ this.#database.prepare(`UPDATE relay_runtime_deliveries SET state = 'relay_committed' WHERE delivery_id = ?`).run(deliveryId);
29989
+ }
29990
+ this.#database.exec("COMMIT");
29991
+ return true;
29992
+ } catch (error61) {
29993
+ this.#database.exec("ROLLBACK");
29994
+ throw error61;
29995
+ }
29996
+ };
29997
+ markRuntimeDeliveryProcessed = (deliveryId, sessionId) => {
29998
+ this.#database.exec("BEGIN IMMEDIATE");
29999
+ try {
30000
+ const row = this.#database.prepare(
30001
+ `SELECT state FROM relay_runtime_deliveries
30002
+ WHERE delivery_id = ? AND session_id = ?`
30003
+ ).get(deliveryId, sessionId);
30004
+ if (row === void 0) {
30005
+ this.#database.exec("COMMIT");
30006
+ return false;
30007
+ }
30008
+ const state = runtimeDeliveryState(row);
30009
+ if (state === "relay_committed") {
30010
+ this.#database.prepare(`DELETE FROM relay_runtime_deliveries WHERE delivery_id = ?`).run(deliveryId);
30011
+ } else if (state === "received") {
30012
+ this.#database.prepare(`UPDATE relay_runtime_deliveries SET state = 'processed' WHERE delivery_id = ?`).run(deliveryId);
30013
+ }
30014
+ this.#database.exec("COMMIT");
30015
+ return true;
30016
+ } catch (error61) {
30017
+ this.#database.exec("ROLLBACK");
30018
+ throw error61;
30019
+ }
30020
+ };
30021
+ runtimeDeliveries = () => this.#database.prepare(
30022
+ `SELECT delivery_id, session_id, payload_json, state
30023
+ FROM relay_runtime_deliveries
30024
+ ORDER BY received_at, delivery_id`
30025
+ ).all().map(
30026
+ (row) => new StoredRuntimeDelivery(
30027
+ rowString2(row, "delivery_id"),
30028
+ rowString2(row, "session_id"),
30029
+ rowString2(row, "payload_json"),
30030
+ runtimeDeliveryState(row),
30031
+ true
30032
+ )
30033
+ );
30034
+ #enqueueBounded = (sessionId, payload, attemptId, maximumEventCount, maximumEventBytes) => {
30035
+ const sourceKey = attemptId.length === 0 ? `runtime:${sessionId}` : `attempt:${sessionId}:${attemptId}`;
29735
30036
  this.#database.exec("BEGIN IMMEDIATE");
29736
30037
  try {
29737
30038
  const row = this.#database.prepare(
@@ -29748,13 +30049,22 @@ var SessionEventOutbox = class {
29748
30049
  kind: SESSION_EVENT_KIND,
29749
30050
  payload,
29750
30051
  sessionId,
29751
- source: attemptId === null ? { kind: "runtime", sourceSeq: nextSourceSeq.toString() } : {
30052
+ source: attemptId.length === 0 ? { kind: "runtime", sourceSeq: nextSourceSeq.toString() } : {
29752
30053
  attemptId,
29753
30054
  kind: "attempt",
29754
30055
  sourceSeq: nextSourceSeq.toString()
29755
30056
  }
29756
30057
  };
29757
30058
  const encoded = encodeSessionEventEnvelope(envelope2);
30059
+ const byteLength = new TextEncoder().encode(encoded).byteLength;
30060
+ const state = this.#database.prepare(
30061
+ `SELECT event_count, total_bytes
30062
+ FROM relay_session_event_outbox_state
30063
+ WHERE singleton = 1`
30064
+ ).get();
30065
+ if (rowNumber(state, "event_count") + 1 > maximumEventCount || rowNumber(state, "total_bytes") + byteLength > maximumEventBytes) {
30066
+ throw new SessionEventOutboxCapacityError();
30067
+ }
29758
30068
  this.#database.prepare(
29759
30069
  `INSERT INTO relay_session_event_sources (
29760
30070
  source_key, next_source_seq
@@ -29764,9 +30074,15 @@ var SessionEventOutbox = class {
29764
30074
  ).run(sourceKey, nextSourceSeq + 1);
29765
30075
  this.#database.prepare(
29766
30076
  `INSERT INTO relay_session_event_outbox (
29767
- event_id, session_id, source_key, envelope_json
29768
- ) VALUES (?, ?, ?, ?)`
29769
- ).run(envelope2.eventId, envelope2.sessionId, sourceKey, encoded);
30077
+ event_id, session_id, source_key, byte_length, envelope_json
30078
+ ) VALUES (?, ?, ?, ?, ?)`
30079
+ ).run(envelope2.eventId, envelope2.sessionId, sourceKey, byteLength, encoded);
30080
+ this.#database.prepare(
30081
+ `UPDATE relay_session_event_outbox_state
30082
+ SET event_count = event_count + 1,
30083
+ total_bytes = total_bytes + ?
30084
+ WHERE singleton = 1`
30085
+ ).run(byteLength);
29770
30086
  this.#database.exec("COMMIT");
29771
30087
  return encoded;
29772
30088
  } catch (error61) {
@@ -29774,6 +30090,44 @@ var SessionEventOutbox = class {
29774
30090
  throw error61;
29775
30091
  }
29776
30092
  };
30093
+ #removeAcknowledgedEvent = (eventId, sessionId) => {
30094
+ this.#database.exec("BEGIN IMMEDIATE");
30095
+ try {
30096
+ const stored = this.#database.prepare(
30097
+ `SELECT byte_length FROM relay_session_event_outbox
30098
+ WHERE event_id = ? AND session_id = ?`
30099
+ ).get(eventId, sessionId);
30100
+ if (stored === void 0) {
30101
+ this.#database.exec("COMMIT");
30102
+ return false;
30103
+ }
30104
+ const byteLength = rowNumber(stored, "byte_length");
30105
+ const deletion = this.#database.prepare(
30106
+ `DELETE FROM relay_session_event_outbox
30107
+ WHERE event_id = ? AND session_id = ?`
30108
+ ).run(eventId, sessionId);
30109
+ if (deletion.changes !== 1) {
30110
+ throw new Error("The acknowledged session event could not be removed from the durable outbox");
30111
+ }
30112
+ this.#decrementEventState(byteLength);
30113
+ this.#database.exec("COMMIT");
30114
+ return true;
30115
+ } catch (error61) {
30116
+ this.#database.exec("ROLLBACK");
30117
+ throw error61;
30118
+ }
30119
+ };
30120
+ #decrementEventState = (byteLength) => {
30121
+ const result = this.#database.prepare(
30122
+ `UPDATE relay_session_event_outbox_state
30123
+ SET event_count = event_count - 1,
30124
+ total_bytes = total_bytes - ?
30125
+ WHERE singleton = 1 AND event_count > 0 AND total_bytes >= ?`
30126
+ ).run(byteLength, byteLength);
30127
+ if (result.changes !== 1) {
30128
+ throw new Error("The Session event outbox capacity state is inconsistent");
30129
+ }
30130
+ };
29777
30131
  pending = () => this.#database.prepare(
29778
30132
  `SELECT envelope_json
29779
30133
  FROM relay_session_event_outbox
@@ -29800,7 +30154,68 @@ var SessionEventOutbox = class {
29800
30154
  LIMIT ?`
29801
30155
  ).all(limit).map(readPendingEnvelope);
29802
30156
  };
30157
+ pendingSourceHeads = (limit, excludedEventIds, excludedSourceKeys) => {
30158
+ if (!Number.isSafeInteger(limit) || limit < 1) {
30159
+ throw new Error("Session event replay batch limit must be a positive integer");
30160
+ }
30161
+ const exclusions = [];
30162
+ const parameters = [];
30163
+ if (excludedEventIds.length > 0) {
30164
+ exclusions.push(`event_id NOT IN (${excludedEventIds.map(() => "?").join(", ")})`);
30165
+ parameters.push(...excludedEventIds);
30166
+ }
30167
+ if (excludedSourceKeys.length > 0) {
30168
+ exclusions.push(`source_key NOT IN (${excludedSourceKeys.map(() => "?").join(", ")})`);
30169
+ parameters.push(...excludedSourceKeys);
30170
+ }
30171
+ parameters.push(limit.toString());
30172
+ const where = exclusions.length === 0 ? "" : `WHERE ${exclusions.join(" AND ")}`;
30173
+ return this.#database.prepare(
30174
+ `WITH available_events AS (
30175
+ SELECT ordinal, source_key
30176
+ FROM relay_session_event_outbox
30177
+ ${where}
30178
+ ), ranked_events AS (
30179
+ SELECT ordinal,
30180
+ ROW_NUMBER() OVER (
30181
+ PARTITION BY source_key
30182
+ ORDER BY ordinal
30183
+ ) AS source_position
30184
+ FROM available_events
30185
+ )
30186
+ SELECT outbox.envelope_json
30187
+ FROM ranked_events AS ranked
30188
+ INNER JOIN relay_session_event_outbox AS outbox
30189
+ ON outbox.ordinal = ranked.ordinal
30190
+ WHERE ranked.source_position = 1
30191
+ ORDER BY outbox.ordinal
30192
+ LIMIT ?`
30193
+ ).all(...parameters).map(readPendingEnvelope);
30194
+ };
29803
30195
  };
30196
+ function validateLimits(limits) {
30197
+ const values = [
30198
+ limits.criticalEventBytes,
30199
+ limits.criticalEventCount,
30200
+ limits.runtimeDeliveryBytes,
30201
+ limits.runtimeDeliveryCount,
30202
+ limits.standardEventBytes,
30203
+ limits.standardEventCount
30204
+ ];
30205
+ if (values.some((value) => !Number.isSafeInteger(value) || value < 1)) {
30206
+ throw new Error("Session event outbox limits must be positive integers");
30207
+ }
30208
+ if (limits.criticalEventBytes < limits.standardEventBytes || limits.criticalEventCount < limits.standardEventCount) {
30209
+ throw new Error("Critical Session event capacity must include the standard capacity");
30210
+ }
30211
+ }
30212
+ function runtimeDeliveryState(row) {
30213
+ const state = rowString2(row, "state");
30214
+ if (state !== "received" && state !== "relay_committed" && state !== "processed") {
30215
+ throw new Error("SQLite returned an invalid Runtime delivery state");
30216
+ }
30217
+ return state;
30218
+ }
29804
30219
  function isDaemonExecutionState(value) {
29805
30220
  return value === "cancelled" || value === "dispatching" || value === "failed" || value === "running" || value === "succeeded";
29806
30221
  }
@@ -30019,8 +30434,7 @@ var ActiveTurnReconciliationError = class extends Error {
30019
30434
  }
30020
30435
  };
30021
30436
  function activeTurnReconciliationEndpoint(config2, turn) {
30022
- const endpoint = new URL(config2.relayUrl);
30023
- endpoint.protocol = endpoint.protocol === "wss:" ? "https:" : "http:";
30437
+ const endpoint = relayHttpEndpoint(config2.relayUrl);
30024
30438
  let channelPath = "";
30025
30439
  if (endpoint.pathname.endsWith("/daemon")) {
30026
30440
  channelPath = endpoint.pathname.slice(0, -"/daemon".length);
@@ -30032,7 +30446,6 @@ function activeTurnReconciliationEndpoint(config2, turn) {
30032
30446
  channelPath = `${endpoint.pathname.slice(0, -runtimePath.length)}/channels/${encodeURIComponent(config2.channelId)}`;
30033
30447
  }
30034
30448
  endpoint.pathname = `${channelPath}/sessions/${encodeURIComponent(turn.command.sessionId)}/attempts/${encodeURIComponent(turn.attemptId)}/reconciliation`;
30035
- endpoint.searchParams.delete("liveness");
30036
30449
  return endpoint;
30037
30450
  }
30038
30451
  async function reconcileActiveTurn(config2, turn, signal) {
@@ -30044,7 +30457,7 @@ async function reconcileActiveTurn(config2, turn, signal) {
30044
30457
  response = await fetch6(activeTurnReconciliationEndpoint(config2, turn), {
30045
30458
  body: JSON.stringify({ outcome: { kind: "running" } }),
30046
30459
  dispatcher: environmentProxyDispatcher,
30047
- headers: { "content-type": "application/json" },
30460
+ headers: { ...runtimeAuthorization(config2.relayUrl), "content-type": "application/json" },
30048
30461
  method: "POST",
30049
30462
  signal: requestSignal
30050
30463
  });
@@ -30112,17 +30525,31 @@ var ConnectedDaemonSessionEventState = class extends DaemonSessionEventConnectio
30112
30525
  }
30113
30526
  };
30114
30527
  };
30115
- var SESSION_EVENT_REPLAY_WINDOW = 4;
30528
+ var SESSION_EVENT_REPLAY_WINDOW = 16;
30529
+ var SESSION_EVENT_SOURCE_REPLAY_WINDOW = 4;
30530
+ var SESSION_EVENT_REPLAY_BYTE_LIMIT = 32 * 1024 * 1024;
30531
+ var InFlightSessionEvent = class {
30532
+ byteLength;
30533
+ sourceKey;
30534
+ constructor(sourceKey, byteLength) {
30535
+ this.byteLength = byteLength;
30536
+ this.sourceKey = sourceKey;
30537
+ }
30538
+ };
30539
+ function sessionEventSourceKey(envelope2) {
30540
+ return envelope2.source.kind === "attempt" ? `attempt:${envelope2.sessionId}:${envelope2.source.attemptId}` : `runtime:${envelope2.sessionId}`;
30541
+ }
30116
30542
  var DaemonSessionEventPublisher = class {
30117
30543
  #outbox;
30118
- #inFlightEventIds = /* @__PURE__ */ new Set();
30544
+ #inFlightEvents = /* @__PURE__ */ new Map();
30545
+ #inFlightBytes = 0;
30119
30546
  #connection = new DisconnectedDaemonSessionEventState();
30120
30547
  constructor(outbox) {
30121
30548
  this.#outbox = outbox;
30122
30549
  }
30123
30550
  connect = (socket) => {
30124
30551
  this.#connection = new ConnectedDaemonSessionEventState(socket);
30125
- this.#inFlightEventIds.clear();
30552
+ this.#clearInFlight();
30126
30553
  this.#publishNextBatch();
30127
30554
  };
30128
30555
  disconnect = (socket) => {
@@ -30130,10 +30557,15 @@ var DaemonSessionEventPublisher = class {
30130
30557
  return;
30131
30558
  }
30132
30559
  this.#connection = this.#connection.disconnect(socket);
30133
- this.#inFlightEventIds.clear();
30560
+ this.#clearInFlight();
30134
30561
  };
30135
30562
  recordAttempt = (sessionId, payload, attemptId) => {
30136
- this.#outbox.enqueue(sessionId, payload, attemptId);
30563
+ const kind = decodeMessageKind(payload);
30564
+ if (kind === SESSION_COMPLETED_KIND || kind === SESSION_FAILED_KIND) {
30565
+ this.#outbox.enqueueCritical(sessionId, payload, attemptId);
30566
+ } else {
30567
+ this.#outbox.enqueue(sessionId, payload, attemptId);
30568
+ }
30137
30569
  this.#publishNextBatch();
30138
30570
  };
30139
30571
  recordRuntime = (sessionId, payload) => {
@@ -30144,7 +30576,7 @@ var DaemonSessionEventPublisher = class {
30144
30576
  if (!this.#outbox.acknowledge(acknowledgement)) {
30145
30577
  return;
30146
30578
  }
30147
- this.#inFlightEventIds.delete(acknowledgement.eventId);
30579
+ this.#removeInFlight(acknowledgement.eventId);
30148
30580
  this.#publishNextBatch();
30149
30581
  };
30150
30582
  quarantine = (rejection) => {
@@ -30152,24 +30584,60 @@ var DaemonSessionEventPublisher = class {
30152
30584
  if (!quarantined) {
30153
30585
  return false;
30154
30586
  }
30155
- this.#inFlightEventIds.delete(rejection.eventId);
30587
+ this.#removeInFlight(rejection.eventId);
30156
30588
  this.#publishNextBatch();
30157
30589
  return true;
30158
30590
  };
30159
30591
  #publishNextBatch = () => {
30160
- if (this.#inFlightEventIds.size > 0) {
30161
- return;
30162
- }
30163
- const batch = this.#outbox.pendingBatch(SESSION_EVENT_REPLAY_WINDOW);
30164
- for (const encoded of batch) {
30165
- const envelope2 = decodeSessionEventEnvelope(encoded);
30166
- if (!this.#connection.send(encoded)) {
30167
- this.#inFlightEventIds.clear();
30592
+ while (this.#inFlightEvents.size < SESSION_EVENT_REPLAY_WINDOW) {
30593
+ const sourceCounts = /* @__PURE__ */ new Map();
30594
+ for (const inFlight of this.#inFlightEvents.values()) {
30595
+ sourceCounts.set(inFlight.sourceKey, (sourceCounts.get(inFlight.sourceKey) ?? 0) + 1);
30596
+ }
30597
+ const saturatedSources = [...sourceCounts.entries()].filter(([, count]) => count >= SESSION_EVENT_SOURCE_REPLAY_WINDOW).map(([sourceKey]) => sourceKey);
30598
+ const batch = this.#outbox.pendingSourceHeads(
30599
+ SESSION_EVENT_REPLAY_WINDOW - this.#inFlightEvents.size,
30600
+ [...this.#inFlightEvents.keys()],
30601
+ saturatedSources
30602
+ );
30603
+ let sent = 0;
30604
+ for (const encoded of batch) {
30605
+ const envelope2 = decodeSessionEventEnvelope(encoded);
30606
+ const sourceKey = sessionEventSourceKey(envelope2);
30607
+ const sourceCount = sourceCounts.get(sourceKey) ?? 0;
30608
+ if (sourceCount >= SESSION_EVENT_SOURCE_REPLAY_WINDOW) {
30609
+ continue;
30610
+ }
30611
+ const byteLength = new TextEncoder().encode(encoded).byteLength;
30612
+ if (this.#inFlightBytes + byteLength > SESSION_EVENT_REPLAY_BYTE_LIMIT) {
30613
+ continue;
30614
+ }
30615
+ if (!this.#connection.send(encoded)) {
30616
+ this.#clearInFlight();
30617
+ return;
30618
+ }
30619
+ this.#inFlightEvents.set(envelope2.eventId, new InFlightSessionEvent(sourceKey, byteLength));
30620
+ this.#inFlightBytes += byteLength;
30621
+ sourceCounts.set(sourceKey, sourceCount + 1);
30622
+ sent += 1;
30623
+ }
30624
+ if (sent === 0) {
30168
30625
  return;
30169
30626
  }
30170
- this.#inFlightEventIds.add(envelope2.eventId);
30171
30627
  }
30172
30628
  };
30629
+ #removeInFlight = (eventId) => {
30630
+ const inFlight = this.#inFlightEvents.get(eventId);
30631
+ if (inFlight === void 0) {
30632
+ return;
30633
+ }
30634
+ this.#inFlightEvents.delete(eventId);
30635
+ this.#inFlightBytes -= inFlight.byteLength;
30636
+ };
30637
+ #clearInFlight = () => {
30638
+ this.#inFlightEvents.clear();
30639
+ this.#inFlightBytes = 0;
30640
+ };
30173
30641
  };
30174
30642
  var CoalescingDaemonActivityPublisher = class {
30175
30643
  #pending = /* @__PURE__ */ new Map();
@@ -30421,6 +30889,9 @@ async function executeSessionConfigure(publisher, socket, command, config2, dire
30421
30889
  })
30422
30890
  );
30423
30891
  } catch (error61) {
30892
+ if (signal.aborted) {
30893
+ signal.throwIfAborted();
30894
+ }
30424
30895
  reportOperationFailure(socket, command.requestId, command.sessionId, error61);
30425
30896
  }
30426
30897
  }
@@ -30760,6 +31231,7 @@ async function publishAgentCatalogUntilAvailable(config2, diagnostics, signal, t
30760
31231
  }
30761
31232
  async function runRelayConnection(config2, directories, audit, sessions, installations, installationObserver, nativeSessions, outbox, publisher, grants, contexts, applicator, ipc, activeTurns, activeAttemptIds, connectionEpoch, diagnostics, onConnected, signal, timer) {
30762
31233
  const relayUrl = new URL(config2.relayUrl);
31234
+ relayUrl.searchParams.set("deliveryReceipts", "1");
30763
31235
  relayUrl.searchParams.set("liveness", "1");
30764
31236
  const socket = await connectRelay(relayUrl, signal);
30765
31237
  const reconnectingTurns = [...activeTurns.values()];
@@ -30808,6 +31280,207 @@ async function runRelayConnection(config2, directories, audit, sessions, install
30808
31280
  closeRelaySocket(socket, code, reason);
30809
31281
  rejectConnection(failure);
30810
31282
  };
31283
+ const processingDeliveryIds = /* @__PURE__ */ new Set();
31284
+ const processDeliveredPrompt = async (delivery) => {
31285
+ const command = decodeSessionPromptCommand(delivery.payload);
31286
+ if (command.sessionId !== delivery.sessionId) {
31287
+ throw new Error("Runtime delivery Session identity does not match its payload");
31288
+ }
31289
+ const active = activeTurns.get(command.commandId);
31290
+ if (active !== void 0) {
31291
+ await active.completion;
31292
+ return;
31293
+ }
31294
+ const receipt = outbox.claimExecution(command.commandId, command.sessionId, delivery.payload);
31295
+ if (receipt.kind === "duplicate") {
31296
+ if (receipt.state === "running") {
31297
+ reportFailure(
31298
+ publisher,
31299
+ command,
31300
+ "agent_execution_interrupted",
31301
+ "The local Agent execution was interrupted before it completed",
31302
+ receipt.attemptId
31303
+ );
31304
+ outbox.transitionExecution(command.commandId, "failed");
31305
+ return;
31306
+ }
31307
+ if (receipt.state !== "dispatching") {
31308
+ return;
31309
+ }
31310
+ }
31311
+ const turn = new ActiveDaemonTurn(command, receipt.attemptId);
31312
+ activeTurns.set(command.commandId, turn);
31313
+ if (command.disposition !== SessionPromptDisposition.Steer) {
31314
+ activeAttemptIds.set(command.sessionId, receipt.attemptId);
31315
+ }
31316
+ try {
31317
+ await executePrompt(
31318
+ outbox,
31319
+ publisher,
31320
+ command,
31321
+ config2,
31322
+ directories,
31323
+ audit,
31324
+ sessions,
31325
+ receipt.attemptId,
31326
+ timer,
31327
+ turn.signal
31328
+ );
31329
+ } finally {
31330
+ activeTurns.delete(command.commandId);
31331
+ if (activeAttemptIds.get(command.sessionId) === receipt.attemptId) {
31332
+ activeAttemptIds.delete(command.sessionId);
31333
+ }
31334
+ turn.finish();
31335
+ }
31336
+ };
31337
+ const processDeliveredPayload = async (delivery) => {
31338
+ const kind = decodeMessageKind(delivery.payload);
31339
+ if (kind === SESSION_CANCEL_KIND) {
31340
+ const cancellation = decodeSessionCancelCommand(delivery.payload);
31341
+ if (cancellation.sessionId !== delivery.sessionId) {
31342
+ throw new Error("Runtime delivery Session identity does not match its payload");
31343
+ }
31344
+ const turn = activeTurns.get(cancellation.commandId);
31345
+ if (turn === void 0 || !turn.matches(cancellation) || !turn.requestCancellation()) {
31346
+ return;
31347
+ }
31348
+ audit.record({
31349
+ commandId: cancellation.commandId,
31350
+ event: "session_cancellation_requested",
31351
+ sessionId: cancellation.sessionId
31352
+ });
31353
+ await sessions.cancelPrompt(cancellation.sessionId);
31354
+ return;
31355
+ }
31356
+ if (kind === SESSION_CONFIGURE_KIND) {
31357
+ const command = decodeSessionConfigureCommand(delivery.payload);
31358
+ if (command.sessionId !== delivery.sessionId) {
31359
+ throw new Error("Runtime delivery Session identity does not match its payload");
31360
+ }
31361
+ await executeSessionConfigure(
31362
+ publisher,
31363
+ socket,
31364
+ command,
31365
+ config2,
31366
+ directories,
31367
+ audit,
31368
+ sessions,
31369
+ connectionController.signal
31370
+ );
31371
+ return;
31372
+ }
31373
+ if (kind === SESSION_PERMISSION_RESPOND_KIND) {
31374
+ const command = decodeSessionPermissionRespondCommand(delivery.payload);
31375
+ if (command.sessionId !== delivery.sessionId) {
31376
+ throw new Error("Runtime delivery Session identity does not match its payload");
31377
+ }
31378
+ try {
31379
+ await sessions.respondPermission(command);
31380
+ audit.record({
31381
+ commandId: command.interactionId,
31382
+ event: "session_permission_resolved",
31383
+ sessionId: command.sessionId
31384
+ });
31385
+ } catch (error61) {
31386
+ reportOperationFailure(socket, command.interactionId, command.sessionId, error61);
31387
+ }
31388
+ return;
31389
+ }
31390
+ if (kind === SESSION_ELICITATION_RESPOND_KIND) {
31391
+ const command = decodeSessionElicitationRespondCommand(delivery.payload);
31392
+ if (command.sessionId !== delivery.sessionId) {
31393
+ throw new Error("Runtime delivery Session identity does not match its payload");
31394
+ }
31395
+ try {
31396
+ await sessions.respondElicitation(command);
31397
+ audit.record({
31398
+ commandId: command.interactionId,
31399
+ event: "session_elicitation_resolved",
31400
+ sessionId: command.sessionId
31401
+ });
31402
+ } catch (error61) {
31403
+ reportOperationFailure(socket, command.interactionId, command.sessionId, error61);
31404
+ }
31405
+ return;
31406
+ }
31407
+ if (kind === SESSION_PROMPT_KIND) {
31408
+ await processDeliveredPrompt(delivery);
31409
+ return;
31410
+ }
31411
+ throw new Error("Runtime delivery contains an unsupported protocol message");
31412
+ };
31413
+ const processRuntimeDelivery = (delivery, state) => {
31414
+ if (state === "processed" || processingDeliveryIds.has(delivery.deliveryId)) {
31415
+ return;
31416
+ }
31417
+ processingDeliveryIds.add(delivery.deliveryId);
31418
+ void processDeliveredPayload(delivery).then(() => {
31419
+ outbox.markRuntimeDeliveryProcessed(delivery.deliveryId, delivery.sessionId);
31420
+ }).catch((error61) => {
31421
+ if (connectionController.signal.aborted) {
31422
+ return;
31423
+ }
31424
+ console.error("Mobius daemon could not process a durable Runtime delivery", error61);
31425
+ failAndClose(
31426
+ new Error("Runtime delivery processing failed", { cause: error61 }),
31427
+ 4008,
31428
+ "Invalid Runtime delivery",
31429
+ "delivery"
31430
+ );
31431
+ }).finally(() => processingDeliveryIds.delete(delivery.deliveryId));
31432
+ };
31433
+ const receiveRuntimeDelivery = (delivery) => {
31434
+ const payloadKind = decodeMessageKind(delivery.payload);
31435
+ let payloadSessionId = "";
31436
+ if (payloadKind === SESSION_CANCEL_KIND) {
31437
+ payloadSessionId = decodeSessionCancelCommand(delivery.payload).sessionId;
31438
+ } else if (payloadKind === SESSION_CONFIGURE_KIND) {
31439
+ payloadSessionId = decodeSessionConfigureCommand(delivery.payload).sessionId;
31440
+ } else if (payloadKind === SESSION_PERMISSION_RESPOND_KIND) {
31441
+ payloadSessionId = decodeSessionPermissionRespondCommand(delivery.payload).sessionId;
31442
+ } else if (payloadKind === SESSION_ELICITATION_RESPOND_KIND) {
31443
+ payloadSessionId = decodeSessionElicitationRespondCommand(delivery.payload).sessionId;
31444
+ } else if (payloadKind === SESSION_PROMPT_KIND) {
31445
+ payloadSessionId = decodeSessionPromptCommand(delivery.payload).sessionId;
31446
+ } else {
31447
+ throw new Error("Runtime delivery contains an unsupported protocol message");
31448
+ }
31449
+ if (payloadSessionId !== delivery.sessionId) {
31450
+ throw new Error("Runtime delivery Session identity does not match its payload");
31451
+ }
31452
+ const stored = outbox.claimRuntimeDelivery(delivery);
31453
+ send(
31454
+ socket,
31455
+ encodeRuntimeDeliveryReceived({
31456
+ deliveryId: delivery.deliveryId,
31457
+ kind: RUNTIME_DELIVERY_RECEIVED_KIND,
31458
+ sessionId: delivery.sessionId
31459
+ })
31460
+ );
31461
+ processRuntimeDelivery(delivery, stored.state);
31462
+ };
31463
+ const resumeRuntimeDeliveries = () => {
31464
+ for (const stored of outbox.runtimeDeliveries()) {
31465
+ const delivery = {
31466
+ deliveryId: stored.deliveryId,
31467
+ kind: RUNTIME_DELIVERY_KIND,
31468
+ payload: stored.payload,
31469
+ sessionId: stored.sessionId
31470
+ };
31471
+ if (stored.state !== "relay_committed") {
31472
+ send(
31473
+ socket,
31474
+ encodeRuntimeDeliveryReceived({
31475
+ deliveryId: stored.deliveryId,
31476
+ kind: RUNTIME_DELIVERY_RECEIVED_KIND,
31477
+ sessionId: stored.sessionId
31478
+ })
31479
+ );
31480
+ }
31481
+ processRuntimeDelivery(delivery, stored.state);
31482
+ }
31483
+ };
30811
31484
  const connectionLiveness = new RelayConnectionLiveness(timer, {
30812
31485
  send: (message) => send(socket, message),
30813
31486
  unresponsive: (heartbeatId, timeoutMilliseconds) => {
@@ -30846,6 +31519,17 @@ async function runRelayConnection(config2, directories, audit, sessions, install
30846
31519
  }
30847
31520
  try {
30848
31521
  const kind = decodeMessageKind(encoded);
31522
+ if (kind === RUNTIME_DELIVERY_COMMITTED_KIND) {
31523
+ const committed = decodeRuntimeDeliveryCommitted(encoded);
31524
+ if (!outbox.markRuntimeDeliveryCommitted(committed.deliveryId, committed.sessionId)) {
31525
+ console.warn("Mobius daemon ignored confirmation for an unknown Runtime delivery");
31526
+ }
31527
+ return;
31528
+ }
31529
+ if (kind === RUNTIME_DELIVERY_KIND) {
31530
+ receiveRuntimeDelivery(decodeRuntimeDelivery(encoded));
31531
+ return;
31532
+ }
30849
31533
  if (kind === SESSION_EVENT_ACK_KIND) {
30850
31534
  publisher.acknowledge(decodeSessionEventAcknowledgement(encoded));
30851
31535
  return;
@@ -31282,6 +31966,10 @@ async function runRelayConnection(config2, directories, audit, sessions, install
31282
31966
  });
31283
31967
  } catch (error61) {
31284
31968
  console.error("Mobius daemon rejected a message", error61);
31969
+ if (error61 instanceof RuntimeDeliveryInboxCapacityError) {
31970
+ failAndClose(error61, 4013, "Runtime delivery queue full", "delivery_backpressure");
31971
+ return;
31972
+ }
31285
31973
  failAndClose(
31286
31974
  new Error("Relay sent an invalid protocol message", { cause: error61 }),
31287
31975
  4008,
@@ -31299,6 +31987,7 @@ async function runRelayConnection(config2, directories, audit, sessions, install
31299
31987
  return;
31300
31988
  }
31301
31989
  publisher.connect(socket);
31990
+ resumeRuntimeDeliveries();
31302
31991
  },
31303
31992
  (error61) => {
31304
31993
  if (finished) {