@moxt-ai/mobius 0.0.153 → 0.0.155

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/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.153",
3384
+ version: "0.0.155",
3385
3385
  description: "Mobius CLI for pairing and running local AI agent services.",
3386
3386
  type: "module",
3387
3387
  bin: {
@@ -29338,16 +29338,8 @@ function decodeSessionQueuedEvent(encoded) {
29338
29338
  function decodeRuntimeLivenessReadyEvent(encoded) {
29339
29339
  const value = parseJson2(encoded);
29340
29340
  assertKind(value, RUNTIME_LIVENESS_READY_KIND);
29341
- if (value["sessionEventDelivery"] === void 0) {
29342
- assertExactKeys(value, ["kind"]);
29343
- return { kind: RUNTIME_LIVENESS_READY_KIND };
29344
- }
29345
- assertExactKeys(value, ["kind", "sessionEventDelivery"]);
29346
- const sessionEventDelivery = readString2(value, "sessionEventDelivery", 32);
29347
- if (sessionEventDelivery !== "reliable-v1") {
29348
- throw new ProtocolMessageError("Unsupported Session event delivery mode");
29349
- }
29350
- return { kind: RUNTIME_LIVENESS_READY_KIND, sessionEventDelivery };
29341
+ assertExactKeys(value, ["kind"]);
29342
+ return { kind: RUNTIME_LIVENESS_READY_KIND };
29351
29343
  }
29352
29344
  function decodeRuntimeHeartbeatEvent(encoded) {
29353
29345
  const value = parseJson2(encoded);
@@ -29814,60 +29806,13 @@ var encodeNativeSessionCancel = (value) => JSON.stringify(nativeSessionCancelSch
29814
29806
 
29815
29807
  // ../protocol/src/session-events.ts
29816
29808
  var SESSION_EVENT_KIND = "session.event";
29817
- var SESSION_EVENT_ACK_KIND = "session.event.ack";
29818
- var SESSION_EVENT_DEFERRED_KIND = "session.event.deferred";
29819
- var SESSION_EVENT_REJECTED_KIND = "session.event.rejected";
29820
29809
  var SESSION_FORKED_KIND = "session.forked";
29821
- var SessionEventRejectionCode = {
29822
- IdempotencyConflict: "idempotency_conflict",
29823
- InvalidEvent: "invalid_event",
29824
- RecordingRejected: "recording_rejected"
29825
- };
29826
29810
  var MAX_RECORDED_EVENT_LENGTH = 8 * 1024 * 1024;
29827
- var ephemeralEventEnvelopeSchema = external_exports.strictObject({
29828
- kind: external_exports.literal(SESSION_EVENT_KIND),
29829
- payload: external_exports.string().min(2).max(MAX_RECORDED_EVENT_LENGTH),
29830
- sessionId: identifierStringSchema
29831
- }).readonly();
29832
- var reliableDeliverySchema = external_exports.strictObject({
29833
- eventId: identifierStringSchema,
29834
- kind: external_exports.literal("reliable"),
29835
- sourceSeq: external_exports.string().regex(/^(?:0|[1-9][0-9]*)$/u).max(40),
29836
- streamId: identifierStringSchema
29837
- }).readonly();
29838
- var reliableSessionEventEnvelopeSchema = external_exports.strictObject({
29839
- delivery: reliableDeliverySchema,
29811
+ var sessionEventEnvelopeSchema = external_exports.strictObject({
29840
29812
  kind: external_exports.literal(SESSION_EVENT_KIND),
29841
29813
  payload: external_exports.string().min(2).max(MAX_RECORDED_EVENT_LENGTH),
29842
29814
  sessionId: identifierStringSchema
29843
29815
  }).readonly();
29844
- var eventEnvelopeSchema = external_exports.union([ephemeralEventEnvelopeSchema, reliableSessionEventEnvelopeSchema]).readonly();
29845
- var acknowledgementOutcomeSchema = external_exports.discriminatedUnion("kind", [
29846
- external_exports.strictObject({ kind: external_exports.literal("relayed") }).readonly(),
29847
- external_exports.strictObject({
29848
- kind: external_exports.literal("recorded"),
29849
- providerId: identifierStringSchema,
29850
- recordingEpoch: identifierStringSchema
29851
- }).readonly()
29852
- ]);
29853
- var eventAcknowledgementSchema = external_exports.strictObject({
29854
- eventId: identifierStringSchema,
29855
- kind: external_exports.literal(SESSION_EVENT_ACK_KIND),
29856
- outcome: acknowledgementOutcomeSchema,
29857
- sessionId: identifierStringSchema
29858
- }).readonly();
29859
- var eventDeferredSchema = external_exports.strictObject({
29860
- eventId: identifierStringSchema,
29861
- kind: external_exports.literal(SESSION_EVENT_DEFERRED_KIND),
29862
- retryAfterMilliseconds: external_exports.number().int().min(100).max(6e4),
29863
- sessionId: identifierStringSchema
29864
- }).readonly();
29865
- var eventRejectedSchema = external_exports.strictObject({
29866
- code: external_exports.enum(SessionEventRejectionCode),
29867
- eventId: identifierStringSchema,
29868
- kind: external_exports.literal(SESSION_EVENT_REJECTED_KIND),
29869
- sessionId: identifierStringSchema
29870
- }).readonly();
29871
29816
  var SESSION_QUEUE_CHANGED_KIND = "session.queue.changed";
29872
29817
  var sessionQueueChangedSchema = external_exports.strictObject({ kind: external_exports.literal(SESSION_QUEUE_CHANGED_KIND), sessionId: identifierStringSchema }).readonly();
29873
29818
  var sessionForkedSchema = external_exports.strictObject({
@@ -29900,14 +29845,8 @@ var encode4 = (message, schema) => {
29900
29845
  }
29901
29846
  return JSON.stringify(decoded.data);
29902
29847
  };
29903
- var decodeSessionEventEnvelope = (encoded) => decode5(encoded, eventEnvelopeSchema);
29904
- var encodeSessionEventEnvelope = (message) => encode4(message, eventEnvelopeSchema);
29905
- var decodeSessionEventAcknowledgement = (encoded) => decode5(encoded, eventAcknowledgementSchema);
29906
- var encodeSessionEventAcknowledgement = (message) => encode4(message, eventAcknowledgementSchema);
29907
- var decodeSessionEventDeferred = (encoded) => decode5(encoded, eventDeferredSchema);
29908
- var encodeSessionEventDeferred = (message) => encode4(message, eventDeferredSchema);
29909
- var decodeSessionEventRejected = (encoded) => decode5(encoded, eventRejectedSchema);
29910
- var encodeSessionEventRejected = (message) => encode4(message, eventRejectedSchema);
29848
+ var decodeSessionEventEnvelope = (encoded) => decode5(encoded, sessionEventEnvelopeSchema);
29849
+ var encodeSessionEventEnvelope = (message) => encode4(message, sessionEventEnvelopeSchema);
29911
29850
  function decodeRecordedSessionEvent(encoded) {
29912
29851
  const kind = decodeMessageKind(encoded);
29913
29852
  switch (kind) {
@@ -30081,21 +30020,6 @@ var serviceToDaemonSignatures = {
30081
30020
  encodeSessionElicitationRespondCommand,
30082
30021
  decodeSessionElicitationRespondCommand
30083
30022
  ),
30084
- [SESSION_EVENT_ACK_KIND]: defineMessageSignature(
30085
- SESSION_EVENT_ACK_KIND,
30086
- encodeSessionEventAcknowledgement,
30087
- decodeSessionEventAcknowledgement
30088
- ),
30089
- [SESSION_EVENT_DEFERRED_KIND]: defineMessageSignature(
30090
- SESSION_EVENT_DEFERRED_KIND,
30091
- encodeSessionEventDeferred,
30092
- decodeSessionEventDeferred
30093
- ),
30094
- [SESSION_EVENT_REJECTED_KIND]: defineMessageSignature(
30095
- SESSION_EVENT_REJECTED_KIND,
30096
- encodeSessionEventRejected,
30097
- decodeSessionEventRejected
30098
- ),
30099
30023
  [SESSION_LIVE_HISTORY_LOAD_KIND]: defineMessageSignature(
30100
30024
  SESSION_LIVE_HISTORY_LOAD_KIND,
30101
30025
  encodeSessionLiveHistoryLoad,
@@ -31154,7 +31078,7 @@ var AuditStore = class {
31154
31078
  };
31155
31079
 
31156
31080
  // src/run-daemon.ts
31157
- import { createHash as createHash6, randomUUID as randomUUID8 } from "node:crypto";
31081
+ import { createHash as createHash6, randomUUID as randomUUID7 } from "node:crypto";
31158
31082
  import { join as join18 } from "node:path";
31159
31083
  import { styleText } from "node:util";
31160
31084
 
@@ -46840,7 +46764,6 @@ async function runRelayConnection({
46840
46764
  }) {
46841
46765
  const relayUrl = new URL(config2.relayUrl);
46842
46766
  relayUrl.searchParams.set("liveness", "1");
46843
- relayUrl.searchParams.set("sessionEventDelivery", "reliable-v1");
46844
46767
  const socket = await connectRelay(relayUrl, signal);
46845
46768
  diagnostics.connectionOpened(connectionEpoch);
46846
46769
  const connectionController = new AbortController();
@@ -46960,10 +46883,7 @@ async function runRelayConnection({
46960
46883
  const message = decodeServiceToDaemonMessage(encoded);
46961
46884
  const kind = message.kind;
46962
46885
  if (kind === RUNTIME_LIVENESS_READY_KIND) {
46963
- publisher.connect(
46964
- socket,
46965
- message.sessionEventDelivery === "reliable-v1" ? "reliable" : "ephemeral"
46966
- );
46886
+ publisher.connect(socket);
46967
46887
  connectionLiveness.start();
46968
46888
  return;
46969
46889
  }
@@ -46971,18 +46891,6 @@ async function runRelayConnection({
46971
46891
  connectionLiveness.acknowledge(message);
46972
46892
  return;
46973
46893
  }
46974
- if (kind === SESSION_EVENT_ACK_KIND) {
46975
- publisher.acknowledge(message);
46976
- return;
46977
- }
46978
- if (kind === SESSION_EVENT_DEFERRED_KIND) {
46979
- publisher.defer(message);
46980
- return;
46981
- }
46982
- if (kind === SESSION_EVENT_REJECTED_KIND) {
46983
- publisher.quarantine(message);
46984
- return;
46985
- }
46986
46894
  commands.handle(message);
46987
46895
  } catch (error62) {
46988
46896
  console.error("Mobius daemon rejected a message", error62);
@@ -47007,404 +46915,44 @@ async function runRelayConnection({
47007
46915
  }
47008
46916
  }
47009
46917
 
47010
- // src/relay-connection/session-event-outbox.ts
47011
- import { randomUUID as randomUUID7 } from "node:crypto";
47012
- import { mkdirSync as mkdirSync3 } from "node:fs";
47013
- import { dirname as dirname6 } from "node:path";
47014
- import { DatabaseSync } from "node:sqlite";
47015
- var DEFAULT_STANDARD_EVENT_BYTES = 96 * 1024 * 1024;
47016
- var DEFAULT_CRITICAL_EVENT_BYTES = 128 * 1024 * 1024;
47017
- var MAX_DEAD_LETTERS = 1024;
47018
- var DEFAULT_LIMITS = {
47019
- criticalEventBytes: DEFAULT_CRITICAL_EVENT_BYTES,
47020
- standardEventBytes: DEFAULT_STANDARD_EVENT_BYTES
47021
- };
47022
- var SessionEventOutboxCapacityError = class extends Error {
47023
- code = "session_event_outbox_full";
47024
- constructor() {
47025
- super("The persistent Session event outbox is full");
47026
- this.name = "SessionEventOutboxCapacityError";
47027
- }
47028
- };
47029
- function rowNumber(row, field) {
47030
- const value = typeof row === "object" && row !== null ? Reflect.get(row, field) : void 0;
47031
- if (typeof value !== "number" || !Number.isSafeInteger(value) || value < 0) {
47032
- throw new Error(`SQLite returned an invalid ${field} value`);
47033
- }
47034
- return value;
47035
- }
47036
- function rowString(row, field) {
47037
- const value = typeof row === "object" && row !== null ? Reflect.get(row, field) : void 0;
47038
- if (typeof value !== "string" || value.length === 0) {
47039
- throw new Error(`SQLite returned an invalid ${field} value`);
47040
- }
47041
- return value;
47042
- }
47043
- function validateLimits(limits) {
47044
- if (!Number.isSafeInteger(limits.standardEventBytes) || limits.standardEventBytes < 1 || !Number.isSafeInteger(limits.criticalEventBytes) || limits.criticalEventBytes < limits.standardEventBytes) {
47045
- throw new Error("Session event outbox limits are invalid");
47046
- }
47047
- }
47048
- var SessionEventOutbox = class {
47049
- #database;
47050
- #limits;
47051
- constructor(path3, limits = DEFAULT_LIMITS) {
47052
- validateLimits(limits);
47053
- mkdirSync3(dirname6(path3), { mode: 448, recursive: true });
47054
- this.#limits = limits;
47055
- this.#database = new DatabaseSync(path3);
47056
- this.#database.exec("PRAGMA journal_mode = WAL; PRAGMA synchronous = FULL; PRAGMA busy_timeout = 5000;");
47057
- this.#database.exec(`
47058
- CREATE TABLE IF NOT EXISTS relay_session_event_outbox (
47059
- ordinal INTEGER PRIMARY KEY AUTOINCREMENT,
47060
- event_id TEXT NOT NULL UNIQUE,
47061
- session_id TEXT NOT NULL,
47062
- source_seq INTEGER NOT NULL UNIQUE,
47063
- byte_length INTEGER NOT NULL,
47064
- envelope_json TEXT NOT NULL
47065
- ) STRICT;
47066
- CREATE INDEX IF NOT EXISTS relay_session_event_outbox_order
47067
- ON relay_session_event_outbox(source_seq);
47068
- CREATE TABLE IF NOT EXISTS relay_session_event_outbox_state (
47069
- singleton INTEGER PRIMARY KEY CHECK (singleton = 1),
47070
- stream_id TEXT NOT NULL,
47071
- next_source_seq INTEGER NOT NULL,
47072
- total_bytes INTEGER NOT NULL
47073
- ) STRICT;
47074
- CREATE TABLE IF NOT EXISTS relay_session_event_dead_letters (
47075
- ordinal INTEGER PRIMARY KEY AUTOINCREMENT,
47076
- event_id TEXT NOT NULL UNIQUE,
47077
- session_id TEXT NOT NULL,
47078
- rejection_code TEXT NOT NULL,
47079
- envelope_json TEXT NOT NULL
47080
- ) STRICT;
47081
- `);
47082
- this.#database.prepare(
47083
- `INSERT OR IGNORE INTO relay_session_event_outbox_state (
47084
- singleton, stream_id, next_source_seq, total_bytes
47085
- ) VALUES (1, ?, 1, 0)`
47086
- ).run(randomUUID7());
47087
- }
47088
- acknowledge = (acknowledgement) => this.#remove(acknowledgement.eventId, acknowledgement.sessionId);
47089
- close = () => {
47090
- this.#database.close();
47091
- };
47092
- enqueue = (sessionId, payload, critical) => {
47093
- const envelope2 = this.enqueueBatch(sessionId, [payload], critical)[0];
47094
- if (envelope2 === void 0) {
47095
- throw new Error("The Session event outbox did not enqueue the event");
47096
- }
47097
- return envelope2;
47098
- };
47099
- enqueueBatch = (sessionId, payloads, critical) => {
47100
- if (payloads.length < 1 || payloads.length > 32) {
47101
- throw new Error("A Session event batch must contain between 1 and 32 events");
47102
- }
47103
- this.#database.exec("BEGIN IMMEDIATE");
47104
- try {
47105
- const state = this.#database.prepare(
47106
- `SELECT stream_id, next_source_seq, total_bytes
47107
- FROM relay_session_event_outbox_state
47108
- WHERE singleton = 1`
47109
- ).get();
47110
- const sourceSeq = rowNumber(state, "next_source_seq");
47111
- if (sourceSeq < 1 || !Number.isSafeInteger(sourceSeq + payloads.length)) {
47112
- throw new Error("The Session event source sequence is exhausted");
47113
- }
47114
- const streamId = rowString(state, "stream_id");
47115
- const stored = payloads.map((payload, index) => {
47116
- const envelope2 = {
47117
- delivery: {
47118
- eventId: randomUUID7(),
47119
- kind: "reliable",
47120
- sourceSeq: (sourceSeq + index).toString(),
47121
- streamId
47122
- },
47123
- kind: SESSION_EVENT_KIND,
47124
- payload,
47125
- sessionId
47126
- };
47127
- const encoded = encodeSessionEventEnvelope(envelope2);
47128
- return { byteLength: Buffer.byteLength(encoded, "utf8"), encoded, envelope: envelope2 };
47129
- });
47130
- const byteLength = stored.reduce((total, entry) => total + entry.byteLength, 0);
47131
- const maximumBytes = critical ? this.#limits.criticalEventBytes : this.#limits.standardEventBytes;
47132
- if (rowNumber(state, "total_bytes") + byteLength > maximumBytes) {
47133
- throw new SessionEventOutboxCapacityError();
47134
- }
47135
- const insert = this.#database.prepare(
47136
- `INSERT INTO relay_session_event_outbox (
47137
- event_id, session_id, source_seq, byte_length, envelope_json
47138
- ) VALUES (?, ?, ?, ?, ?)`
47139
- );
47140
- for (const entry of stored) {
47141
- insert.run(
47142
- entry.envelope.delivery.eventId,
47143
- sessionId,
47144
- Number(entry.envelope.delivery.sourceSeq),
47145
- entry.byteLength,
47146
- entry.encoded
47147
- );
47148
- }
47149
- this.#database.prepare(
47150
- `UPDATE relay_session_event_outbox_state
47151
- SET next_source_seq = next_source_seq + ?,
47152
- total_bytes = total_bytes + ?
47153
- WHERE singleton = 1`
47154
- ).run(stored.length, byteLength);
47155
- this.#database.exec("COMMIT");
47156
- return stored.map((entry) => entry.envelope);
47157
- } catch (error62) {
47158
- this.#database.exec("ROLLBACK");
47159
- throw error62;
47160
- }
47161
- };
47162
- pending = (limit, excludedEventIds) => {
47163
- if (!Number.isSafeInteger(limit) || limit < 1) {
47164
- throw new Error("Session event replay limit must be a positive integer");
47165
- }
47166
- const exclusion = excludedEventIds.length === 0 ? "" : `WHERE event_id NOT IN (${excludedEventIds.map(() => "?").join(", ")})`;
47167
- return this.#database.prepare(
47168
- `SELECT envelope_json
47169
- FROM relay_session_event_outbox
47170
- ${exclusion}
47171
- ORDER BY source_seq
47172
- LIMIT ?`
47173
- ).all(...excludedEventIds, limit).map((row) => {
47174
- const envelope2 = decodeSessionEventEnvelope(rowString(row, "envelope_json"));
47175
- if (!("delivery" in envelope2)) {
47176
- throw new Error("SQLite returned an invalid reliable Session event envelope");
47177
- }
47178
- return envelope2;
47179
- });
47180
- };
47181
- quarantine = (rejection) => {
47182
- this.#database.exec("BEGIN IMMEDIATE");
47183
- try {
47184
- const stored = this.#database.prepare(
47185
- `SELECT byte_length, envelope_json
47186
- FROM relay_session_event_outbox
47187
- WHERE event_id = ? AND session_id = ?`
47188
- ).get(rejection.eventId, rejection.sessionId);
47189
- if (stored === void 0) {
47190
- this.#database.exec("COMMIT");
47191
- return false;
47192
- }
47193
- this.#database.prepare(
47194
- `INSERT INTO relay_session_event_dead_letters (
47195
- event_id, session_id, rejection_code, envelope_json
47196
- ) VALUES (?, ?, ?, ?)`
47197
- ).run(rejection.eventId, rejection.sessionId, rejection.code, rowString(stored, "envelope_json"));
47198
- this.#deleteStored(rejection.eventId, rejection.sessionId, rowNumber(stored, "byte_length"));
47199
- this.#database.prepare(
47200
- `DELETE FROM relay_session_event_dead_letters
47201
- WHERE ordinal NOT IN (
47202
- SELECT ordinal FROM relay_session_event_dead_letters
47203
- ORDER BY ordinal DESC LIMIT ?
47204
- )`
47205
- ).run(MAX_DEAD_LETTERS);
47206
- this.#database.exec("COMMIT");
47207
- return true;
47208
- } catch (error62) {
47209
- this.#database.exec("ROLLBACK");
47210
- throw error62;
47211
- }
47212
- };
47213
- #deleteStored = (eventId, sessionId, byteLength) => {
47214
- const deletion = this.#database.prepare(
47215
- `DELETE FROM relay_session_event_outbox
47216
- WHERE event_id = ? AND session_id = ?`
47217
- ).run(eventId, sessionId);
47218
- if (deletion.changes !== 1) {
47219
- throw new Error("The Session event could not be removed from the outbox");
47220
- }
47221
- const state = this.#database.prepare(
47222
- `UPDATE relay_session_event_outbox_state
47223
- SET total_bytes = total_bytes - ?
47224
- WHERE singleton = 1 AND total_bytes >= ?`
47225
- ).run(byteLength, byteLength);
47226
- if (state.changes !== 1) {
47227
- throw new Error("The Session event outbox capacity state is inconsistent");
47228
- }
47229
- };
47230
- #remove = (eventId, sessionId) => {
47231
- this.#database.exec("BEGIN IMMEDIATE");
47232
- try {
47233
- const stored = this.#database.prepare(
47234
- `SELECT byte_length
47235
- FROM relay_session_event_outbox
47236
- WHERE event_id = ? AND session_id = ?`
47237
- ).get(eventId, sessionId);
47238
- if (stored === void 0) {
47239
- this.#database.exec("COMMIT");
47240
- return false;
47241
- }
47242
- this.#deleteStored(eventId, sessionId, rowNumber(stored, "byte_length"));
47243
- this.#database.exec("COMMIT");
47244
- return true;
47245
- } catch (error62) {
47246
- this.#database.exec("ROLLBACK");
47247
- throw error62;
47248
- }
47249
- };
47250
- };
47251
-
47252
46918
  // src/relay-connection/session-event-publisher.ts
47253
46919
  import { WebSocket as WebSocket9 } from "undici";
47254
- var SESSION_EVENT_REPLAY_WINDOW = 16;
47255
- var SESSION_EVENT_REPLAY_BYTE_LIMIT = 32 * 1024 * 1024;
47256
- function reservesSessionEventCapacity(event) {
47257
- if (event.kind === SESSION_COMPLETED_KIND || event.kind === SESSION_FAILED_KIND || event.kind === SESSION_FORKED_KIND || event.kind === SESSION_READY_KIND) {
47258
- return true;
47259
- }
47260
- return event.kind === AGENT_ACTIVITY_KIND && (event.activityType === "progress" || event.activityType === "reasoning") && (event.status === "completed" || event.status === "failed");
47261
- }
46920
+ var MAX_BUFFERED_BYTES = 32 * 1024 * 1024;
47262
46921
  var DaemonSessionEventPublisher = class {
47263
- #inFlight = /* @__PURE__ */ new Map();
47264
- #outbox;
47265
- #reportedCapacityKinds = /* @__PURE__ */ new Set();
47266
- #timer;
47267
- #connection = { kind: "disconnected" };
47268
- #deferredReplay = null;
47269
- #inFlightBytes = 0;
47270
- constructor(outbox, timer) {
47271
- this.#outbox = outbox;
47272
- this.#timer = timer;
47273
- }
47274
- acknowledge = (acknowledgement) => {
47275
- if (!this.#outbox.acknowledge(acknowledgement)) {
47276
- return;
47277
- }
47278
- this.#removeInFlight(acknowledgement.eventId);
47279
- this.#publishNextBatch();
47280
- };
47281
- close = () => {
47282
- this.#deferredReplay?.cancel();
47283
- this.#deferredReplay = null;
47284
- this.#connection = { kind: "disconnected" };
47285
- this.#clearInFlight();
47286
- this.#outbox.close();
47287
- };
47288
- connect = (socket, delivery) => {
47289
- this.#connection = { delivery, kind: "connected", socket };
47290
- this.#clearInFlight();
47291
- this.#publishNextBatch();
47292
- };
47293
- defer = (deferred) => {
47294
- if (!this.#inFlight.has(deferred.eventId)) {
47295
- return;
47296
- }
47297
- this.#clearInFlight();
47298
- if (this.#deferredReplay !== null) {
47299
- return;
47300
- }
47301
- this.#deferredReplay = this.#timer.schedule(() => {
47302
- this.#deferredReplay = null;
47303
- this.#publishNextBatch();
47304
- }, deferred.retryAfterMilliseconds);
46922
+ #socket = null;
46923
+ connect = (socket) => {
46924
+ this.#socket = socket;
47305
46925
  };
47306
46926
  disconnect = (socket) => {
47307
- if (this.#connection.kind !== "connected" || this.#connection.socket !== socket) {
47308
- return;
47309
- }
47310
- this.#connection = { kind: "disconnected" };
47311
- this.#clearInFlight();
47312
- };
47313
- publish = (sessionId, event) => {
47314
- try {
47315
- this.#outbox.enqueue(sessionId, encodeRecordedSessionEvent(event), reservesSessionEventCapacity(event));
47316
- } catch (error62) {
47317
- if (!(error62 instanceof SessionEventOutboxCapacityError)) {
47318
- throw error62;
47319
- }
47320
- if (!this.#reportedCapacityKinds.has(event.kind)) {
47321
- this.#reportedCapacityKinds.add(event.kind);
47322
- console.warn(
47323
- `Mobius daemon could not persist "${event.kind}" because the Session event outbox is full`
47324
- );
47325
- }
47326
- return;
47327
- }
47328
- this.#publishNextBatch();
47329
- };
47330
- publishBatch = (sessionId, events) => {
47331
- const critical = events.some(reservesSessionEventCapacity);
47332
- this.#outbox.enqueueBatch(sessionId, events.map(encodeRecordedSessionEvent), critical);
47333
- this.#publishNextBatch();
47334
- };
47335
- quarantine = (rejection) => {
47336
- if (!this.#outbox.quarantine(rejection)) {
47337
- return;
46927
+ if (this.#socket === socket) {
46928
+ this.#socket = null;
47338
46929
  }
47339
- this.#removeInFlight(rejection.eventId);
47340
- console.error(`Mobius Relay rejected Session event ${rejection.eventId} with code ${rejection.code}`);
47341
- this.#publishNextBatch();
47342
46930
  };
47343
- #clearInFlight = () => {
47344
- this.#inFlight.clear();
47345
- this.#inFlightBytes = 0;
46931
+ close = () => {
46932
+ this.#socket = null;
47346
46933
  };
47347
- #publishNextBatch = () => {
47348
- if (this.#deferredReplay !== null || this.#connection.kind !== "connected") {
46934
+ publish = (sessionId, event) => {
46935
+ const socket = this.#socket;
46936
+ if (socket === null || socket.readyState !== WebSocket9.OPEN) {
47349
46937
  return;
47350
46938
  }
47351
- while (this.#inFlight.size < SESSION_EVENT_REPLAY_WINDOW) {
47352
- const batch = this.#outbox.pending(SESSION_EVENT_REPLAY_WINDOW - this.#inFlight.size, [
47353
- ...this.#inFlight.keys()
47354
- ]);
47355
- let sent = 0;
47356
- for (const envelope2 of batch) {
47357
- const encoded = encodeDaemonToServiceMessage(
47358
- this.#connection.delivery === "reliable" ? envelope2 : {
47359
- kind: envelope2.kind,
47360
- payload: envelope2.payload,
47361
- sessionId: envelope2.sessionId
47362
- }
47363
- );
47364
- const byteLength = Buffer.byteLength(encoded, "utf8");
47365
- if (this.#inFlightBytes + byteLength > SESSION_EVENT_REPLAY_BYTE_LIMIT) {
47366
- return;
47367
- }
47368
- if (!this.#send(encoded)) {
47369
- this.#clearInFlight();
47370
- return;
47371
- }
47372
- if (this.#connection.delivery === "ephemeral") {
47373
- this.#outbox.acknowledge({
47374
- eventId: envelope2.delivery.eventId,
47375
- kind: "session.event.ack",
47376
- outcome: { kind: "relayed" },
47377
- sessionId: envelope2.sessionId
47378
- });
47379
- sent += 1;
47380
- continue;
47381
- }
47382
- this.#inFlight.set(envelope2.delivery.eventId, { byteLength });
47383
- this.#inFlightBytes += byteLength;
47384
- sent += 1;
47385
- }
47386
- if (sent === 0) {
47387
- return;
47388
- }
47389
- }
47390
- };
47391
- #removeInFlight = (eventId) => {
47392
- const inFlight = this.#inFlight.get(eventId);
47393
- if (inFlight === void 0) {
46939
+ const encoded = encodeDaemonToServiceMessage({
46940
+ kind: SESSION_EVENT_KIND,
46941
+ payload: encodeRecordedSessionEvent(event),
46942
+ sessionId
46943
+ });
46944
+ if (socket.bufferedAmount + Buffer.byteLength(encoded, "utf8") > MAX_BUFFERED_BYTES) {
46945
+ socket.close(1013, "Live event transport overloaded");
47394
46946
  return;
47395
46947
  }
47396
- this.#inFlight.delete(eventId);
47397
- this.#inFlightBytes -= inFlight.byteLength;
47398
- };
47399
- #send = (encoded) => {
47400
- if (this.#connection.kind !== "connected" || this.#connection.socket.readyState !== WebSocket9.OPEN) {
47401
- return false;
47402
- }
47403
46948
  try {
47404
- this.#connection.socket.send(encoded);
47405
- return true;
46949
+ socket.send(encoded);
47406
46950
  } catch {
47407
- return false;
46951
+ }
46952
+ };
46953
+ publishBatch = (sessionId, events) => {
46954
+ for (const event of events) {
46955
+ this.publish(sessionId, event);
47408
46956
  }
47409
46957
  };
47410
46958
  };
@@ -47466,7 +47014,7 @@ async function installDetectedAgentIntegrations(config2, installations, signal)
47466
47014
  {
47467
47015
  agentId: agent.id,
47468
47016
  kind: AGENT_INSTALL_REQUEST_KIND,
47469
- requestId: `automatic-integration-${randomUUID8()}`
47017
+ requestId: `automatic-integration-${randomUUID7()}`
47470
47018
  },
47471
47019
  signal
47472
47020
  );
@@ -47488,11 +47036,7 @@ async function runDaemon(config2, audit, signal, timer = systemDaemonTimer, opti
47488
47036
  join18(stateDirectory, "sessions", `${createHash6("sha256").update(config2.channelId).digest("hex")}.sqlite`)
47489
47037
  );
47490
47038
  const operations = new DaemonOperationState();
47491
- const channelHash = createHash6("sha256").update(config2.channelId).digest("hex");
47492
- const publisher = new DaemonSessionEventPublisher(
47493
- new SessionEventOutbox(join18(stateDirectory, "events", `${channelHash}.sqlite`)),
47494
- timer
47495
- );
47039
+ const publisher = new DaemonSessionEventPublisher();
47496
47040
  const activeTurns = new DaemonTurnRegistry(operations);
47497
47041
  const recordSessionEvent = (sessionId, event) => {
47498
47042
  publisher.publish(sessionId, activeTurns.recordEvent(event));