@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.
@@ -20,19 +20,6 @@ export declare class DaemonTurnRegistry {
20
20
  epoch: string;
21
21
  hasOlder: boolean;
22
22
  interaction: Readonly<{
23
- commandId: string;
24
- interactionId: string;
25
- kind: "session.permission.requested";
26
- options: readonly Readonly<{
27
- kind: "allow_always" | "allow_once" | "reject_always" | "reject_once";
28
- name: string;
29
- optionId: string;
30
- }>[];
31
- sessionId: string;
32
- title: string;
33
- toolCallId: string;
34
- toolKind: string;
35
- }> | Readonly<{
36
23
  accepted: boolean;
37
24
  commandId: string;
38
25
  elicitationId: string;
@@ -64,6 +51,19 @@ export declare class DaemonTurnRegistry {
64
51
  mode: "form" | "url";
65
52
  sessionId: string;
66
53
  url: string;
54
+ }> | Readonly<{
55
+ commandId: string;
56
+ interactionId: string;
57
+ kind: "session.permission.requested";
58
+ options: readonly Readonly<{
59
+ kind: "allow_always" | "allow_once" | "reject_always" | "reject_once";
60
+ name: string;
61
+ optionId: string;
62
+ }>[];
63
+ sessionId: string;
64
+ title: string;
65
+ toolCallId: string;
66
+ toolKind: string;
67
67
  }> | null;
68
68
  messages: readonly (Readonly<{
69
69
  id: string;
package/dist/index.js CHANGED
@@ -20767,16 +20767,8 @@ function decodeSessionQueuedEvent(encoded) {
20767
20767
  function decodeRuntimeLivenessReadyEvent(encoded) {
20768
20768
  const value = parseJson2(encoded);
20769
20769
  assertKind(value, RUNTIME_LIVENESS_READY_KIND);
20770
- if (value["sessionEventDelivery"] === void 0) {
20771
- assertExactKeys(value, ["kind"]);
20772
- return { kind: RUNTIME_LIVENESS_READY_KIND };
20773
- }
20774
- assertExactKeys(value, ["kind", "sessionEventDelivery"]);
20775
- const sessionEventDelivery = readString(value, "sessionEventDelivery", 32);
20776
- if (sessionEventDelivery !== "reliable-v1") {
20777
- throw new ProtocolMessageError("Unsupported Session event delivery mode");
20778
- }
20779
- return { kind: RUNTIME_LIVENESS_READY_KIND, sessionEventDelivery };
20770
+ assertExactKeys(value, ["kind"]);
20771
+ return { kind: RUNTIME_LIVENESS_READY_KIND };
20780
20772
  }
20781
20773
  function decodeRuntimeHeartbeatEvent(encoded) {
20782
20774
  const value = parseJson2(encoded);
@@ -21243,60 +21235,13 @@ var encodeNativeSessionCancel = (value) => JSON.stringify(nativeSessionCancelSch
21243
21235
 
21244
21236
  // ../protocol/src/session-events.ts
21245
21237
  var SESSION_EVENT_KIND = "session.event";
21246
- var SESSION_EVENT_ACK_KIND = "session.event.ack";
21247
- var SESSION_EVENT_DEFERRED_KIND = "session.event.deferred";
21248
- var SESSION_EVENT_REJECTED_KIND = "session.event.rejected";
21249
21238
  var SESSION_FORKED_KIND = "session.forked";
21250
- var SessionEventRejectionCode = {
21251
- IdempotencyConflict: "idempotency_conflict",
21252
- InvalidEvent: "invalid_event",
21253
- RecordingRejected: "recording_rejected"
21254
- };
21255
21239
  var MAX_RECORDED_EVENT_LENGTH = 8 * 1024 * 1024;
21256
- var ephemeralEventEnvelopeSchema = external_exports.strictObject({
21257
- kind: external_exports.literal(SESSION_EVENT_KIND),
21258
- payload: external_exports.string().min(2).max(MAX_RECORDED_EVENT_LENGTH),
21259
- sessionId: identifierStringSchema
21260
- }).readonly();
21261
- var reliableDeliverySchema = external_exports.strictObject({
21262
- eventId: identifierStringSchema,
21263
- kind: external_exports.literal("reliable"),
21264
- sourceSeq: external_exports.string().regex(/^(?:0|[1-9][0-9]*)$/u).max(40),
21265
- streamId: identifierStringSchema
21266
- }).readonly();
21267
- var reliableSessionEventEnvelopeSchema = external_exports.strictObject({
21268
- delivery: reliableDeliverySchema,
21240
+ var sessionEventEnvelopeSchema = external_exports.strictObject({
21269
21241
  kind: external_exports.literal(SESSION_EVENT_KIND),
21270
21242
  payload: external_exports.string().min(2).max(MAX_RECORDED_EVENT_LENGTH),
21271
21243
  sessionId: identifierStringSchema
21272
21244
  }).readonly();
21273
- var eventEnvelopeSchema = external_exports.union([ephemeralEventEnvelopeSchema, reliableSessionEventEnvelopeSchema]).readonly();
21274
- var acknowledgementOutcomeSchema = external_exports.discriminatedUnion("kind", [
21275
- external_exports.strictObject({ kind: external_exports.literal("relayed") }).readonly(),
21276
- external_exports.strictObject({
21277
- kind: external_exports.literal("recorded"),
21278
- providerId: identifierStringSchema,
21279
- recordingEpoch: identifierStringSchema
21280
- }).readonly()
21281
- ]);
21282
- var eventAcknowledgementSchema = external_exports.strictObject({
21283
- eventId: identifierStringSchema,
21284
- kind: external_exports.literal(SESSION_EVENT_ACK_KIND),
21285
- outcome: acknowledgementOutcomeSchema,
21286
- sessionId: identifierStringSchema
21287
- }).readonly();
21288
- var eventDeferredSchema = external_exports.strictObject({
21289
- eventId: identifierStringSchema,
21290
- kind: external_exports.literal(SESSION_EVENT_DEFERRED_KIND),
21291
- retryAfterMilliseconds: external_exports.number().int().min(100).max(6e4),
21292
- sessionId: identifierStringSchema
21293
- }).readonly();
21294
- var eventRejectedSchema = external_exports.strictObject({
21295
- code: external_exports.enum(SessionEventRejectionCode),
21296
- eventId: identifierStringSchema,
21297
- kind: external_exports.literal(SESSION_EVENT_REJECTED_KIND),
21298
- sessionId: identifierStringSchema
21299
- }).readonly();
21300
21245
  var SESSION_QUEUE_CHANGED_KIND = "session.queue.changed";
21301
21246
  var sessionQueueChangedSchema = external_exports.strictObject({ kind: external_exports.literal(SESSION_QUEUE_CHANGED_KIND), sessionId: identifierStringSchema }).readonly();
21302
21247
  var sessionForkedSchema = external_exports.strictObject({
@@ -21329,14 +21274,8 @@ var encode4 = (message, schema) => {
21329
21274
  }
21330
21275
  return JSON.stringify(decoded.data);
21331
21276
  };
21332
- var decodeSessionEventEnvelope = (encoded) => decode5(encoded, eventEnvelopeSchema);
21333
- var encodeSessionEventEnvelope = (message) => encode4(message, eventEnvelopeSchema);
21334
- var decodeSessionEventAcknowledgement = (encoded) => decode5(encoded, eventAcknowledgementSchema);
21335
- var encodeSessionEventAcknowledgement = (message) => encode4(message, eventAcknowledgementSchema);
21336
- var decodeSessionEventDeferred = (encoded) => decode5(encoded, eventDeferredSchema);
21337
- var encodeSessionEventDeferred = (message) => encode4(message, eventDeferredSchema);
21338
- var decodeSessionEventRejected = (encoded) => decode5(encoded, eventRejectedSchema);
21339
- var encodeSessionEventRejected = (message) => encode4(message, eventRejectedSchema);
21277
+ var decodeSessionEventEnvelope = (encoded) => decode5(encoded, sessionEventEnvelopeSchema);
21278
+ var encodeSessionEventEnvelope = (message) => encode4(message, sessionEventEnvelopeSchema);
21340
21279
  function decodeRecordedSessionEvent(encoded) {
21341
21280
  const kind = decodeMessageKind(encoded);
21342
21281
  switch (kind) {
@@ -21510,21 +21449,6 @@ var serviceToDaemonSignatures = {
21510
21449
  encodeSessionElicitationRespondCommand,
21511
21450
  decodeSessionElicitationRespondCommand
21512
21451
  ),
21513
- [SESSION_EVENT_ACK_KIND]: defineMessageSignature(
21514
- SESSION_EVENT_ACK_KIND,
21515
- encodeSessionEventAcknowledgement,
21516
- decodeSessionEventAcknowledgement
21517
- ),
21518
- [SESSION_EVENT_DEFERRED_KIND]: defineMessageSignature(
21519
- SESSION_EVENT_DEFERRED_KIND,
21520
- encodeSessionEventDeferred,
21521
- decodeSessionEventDeferred
21522
- ),
21523
- [SESSION_EVENT_REJECTED_KIND]: defineMessageSignature(
21524
- SESSION_EVENT_REJECTED_KIND,
21525
- encodeSessionEventRejected,
21526
- decodeSessionEventRejected
21527
- ),
21528
21452
  [SESSION_LIVE_HISTORY_LOAD_KIND]: defineMessageSignature(
21529
21453
  SESSION_LIVE_HISTORY_LOAD_KIND,
21530
21454
  encodeSessionLiveHistoryLoad,
@@ -37660,7 +37584,7 @@ function isRuntimeRelayRevocation(closeCode, closeReason) {
37660
37584
  }
37661
37585
 
37662
37586
  // src/run-daemon.ts
37663
- import { createHash as createHash6, randomUUID as randomUUID8 } from "node:crypto";
37587
+ import { createHash as createHash6, randomUUID as randomUUID7 } from "node:crypto";
37664
37588
  import { join as join18 } from "node:path";
37665
37589
  import { styleText } from "node:util";
37666
37590
 
@@ -43337,7 +43261,6 @@ async function runRelayConnection({
43337
43261
  }) {
43338
43262
  const relayUrl = new URL(config2.relayUrl);
43339
43263
  relayUrl.searchParams.set("liveness", "1");
43340
- relayUrl.searchParams.set("sessionEventDelivery", "reliable-v1");
43341
43264
  const socket = await connectRelay(relayUrl, signal);
43342
43265
  diagnostics.connectionOpened(connectionEpoch);
43343
43266
  const connectionController = new AbortController();
@@ -43457,10 +43380,7 @@ async function runRelayConnection({
43457
43380
  const message = decodeServiceToDaemonMessage(encoded);
43458
43381
  const kind = message.kind;
43459
43382
  if (kind === RUNTIME_LIVENESS_READY_KIND) {
43460
- publisher.connect(
43461
- socket,
43462
- message.sessionEventDelivery === "reliable-v1" ? "reliable" : "ephemeral"
43463
- );
43383
+ publisher.connect(socket);
43464
43384
  connectionLiveness.start();
43465
43385
  return;
43466
43386
  }
@@ -43468,18 +43388,6 @@ async function runRelayConnection({
43468
43388
  connectionLiveness.acknowledge(message);
43469
43389
  return;
43470
43390
  }
43471
- if (kind === SESSION_EVENT_ACK_KIND) {
43472
- publisher.acknowledge(message);
43473
- return;
43474
- }
43475
- if (kind === SESSION_EVENT_DEFERRED_KIND) {
43476
- publisher.defer(message);
43477
- return;
43478
- }
43479
- if (kind === SESSION_EVENT_REJECTED_KIND) {
43480
- publisher.quarantine(message);
43481
- return;
43482
- }
43483
43391
  commands.handle(message);
43484
43392
  } catch (error62) {
43485
43393
  console.error("Mobius daemon rejected a message", error62);
@@ -43504,404 +43412,44 @@ async function runRelayConnection({
43504
43412
  }
43505
43413
  }
43506
43414
 
43507
- // src/relay-connection/session-event-outbox.ts
43508
- import { randomUUID as randomUUID7 } from "node:crypto";
43509
- import { mkdirSync as mkdirSync3 } from "node:fs";
43510
- import { dirname as dirname6 } from "node:path";
43511
- import { DatabaseSync } from "node:sqlite";
43512
- var DEFAULT_STANDARD_EVENT_BYTES = 96 * 1024 * 1024;
43513
- var DEFAULT_CRITICAL_EVENT_BYTES = 128 * 1024 * 1024;
43514
- var MAX_DEAD_LETTERS = 1024;
43515
- var DEFAULT_LIMITS = {
43516
- criticalEventBytes: DEFAULT_CRITICAL_EVENT_BYTES,
43517
- standardEventBytes: DEFAULT_STANDARD_EVENT_BYTES
43518
- };
43519
- var SessionEventOutboxCapacityError = class extends Error {
43520
- code = "session_event_outbox_full";
43521
- constructor() {
43522
- super("The persistent Session event outbox is full");
43523
- this.name = "SessionEventOutboxCapacityError";
43524
- }
43525
- };
43526
- function rowNumber(row, field) {
43527
- const value = typeof row === "object" && row !== null ? Reflect.get(row, field) : void 0;
43528
- if (typeof value !== "number" || !Number.isSafeInteger(value) || value < 0) {
43529
- throw new Error(`SQLite returned an invalid ${field} value`);
43530
- }
43531
- return value;
43532
- }
43533
- function rowString(row, field) {
43534
- const value = typeof row === "object" && row !== null ? Reflect.get(row, field) : void 0;
43535
- if (typeof value !== "string" || value.length === 0) {
43536
- throw new Error(`SQLite returned an invalid ${field} value`);
43537
- }
43538
- return value;
43539
- }
43540
- function validateLimits(limits) {
43541
- if (!Number.isSafeInteger(limits.standardEventBytes) || limits.standardEventBytes < 1 || !Number.isSafeInteger(limits.criticalEventBytes) || limits.criticalEventBytes < limits.standardEventBytes) {
43542
- throw new Error("Session event outbox limits are invalid");
43543
- }
43544
- }
43545
- var SessionEventOutbox = class {
43546
- #database;
43547
- #limits;
43548
- constructor(path2, limits = DEFAULT_LIMITS) {
43549
- validateLimits(limits);
43550
- mkdirSync3(dirname6(path2), { mode: 448, recursive: true });
43551
- this.#limits = limits;
43552
- this.#database = new DatabaseSync(path2);
43553
- this.#database.exec("PRAGMA journal_mode = WAL; PRAGMA synchronous = FULL; PRAGMA busy_timeout = 5000;");
43554
- this.#database.exec(`
43555
- CREATE TABLE IF NOT EXISTS relay_session_event_outbox (
43556
- ordinal INTEGER PRIMARY KEY AUTOINCREMENT,
43557
- event_id TEXT NOT NULL UNIQUE,
43558
- session_id TEXT NOT NULL,
43559
- source_seq INTEGER NOT NULL UNIQUE,
43560
- byte_length INTEGER NOT NULL,
43561
- envelope_json TEXT NOT NULL
43562
- ) STRICT;
43563
- CREATE INDEX IF NOT EXISTS relay_session_event_outbox_order
43564
- ON relay_session_event_outbox(source_seq);
43565
- CREATE TABLE IF NOT EXISTS relay_session_event_outbox_state (
43566
- singleton INTEGER PRIMARY KEY CHECK (singleton = 1),
43567
- stream_id TEXT NOT NULL,
43568
- next_source_seq INTEGER NOT NULL,
43569
- total_bytes INTEGER NOT NULL
43570
- ) STRICT;
43571
- CREATE TABLE IF NOT EXISTS relay_session_event_dead_letters (
43572
- ordinal INTEGER PRIMARY KEY AUTOINCREMENT,
43573
- event_id TEXT NOT NULL UNIQUE,
43574
- session_id TEXT NOT NULL,
43575
- rejection_code TEXT NOT NULL,
43576
- envelope_json TEXT NOT NULL
43577
- ) STRICT;
43578
- `);
43579
- this.#database.prepare(
43580
- `INSERT OR IGNORE INTO relay_session_event_outbox_state (
43581
- singleton, stream_id, next_source_seq, total_bytes
43582
- ) VALUES (1, ?, 1, 0)`
43583
- ).run(randomUUID7());
43584
- }
43585
- acknowledge = (acknowledgement) => this.#remove(acknowledgement.eventId, acknowledgement.sessionId);
43586
- close = () => {
43587
- this.#database.close();
43588
- };
43589
- enqueue = (sessionId, payload, critical) => {
43590
- const envelope2 = this.enqueueBatch(sessionId, [payload], critical)[0];
43591
- if (envelope2 === void 0) {
43592
- throw new Error("The Session event outbox did not enqueue the event");
43593
- }
43594
- return envelope2;
43595
- };
43596
- enqueueBatch = (sessionId, payloads, critical) => {
43597
- if (payloads.length < 1 || payloads.length > 32) {
43598
- throw new Error("A Session event batch must contain between 1 and 32 events");
43599
- }
43600
- this.#database.exec("BEGIN IMMEDIATE");
43601
- try {
43602
- const state = this.#database.prepare(
43603
- `SELECT stream_id, next_source_seq, total_bytes
43604
- FROM relay_session_event_outbox_state
43605
- WHERE singleton = 1`
43606
- ).get();
43607
- const sourceSeq = rowNumber(state, "next_source_seq");
43608
- if (sourceSeq < 1 || !Number.isSafeInteger(sourceSeq + payloads.length)) {
43609
- throw new Error("The Session event source sequence is exhausted");
43610
- }
43611
- const streamId = rowString(state, "stream_id");
43612
- const stored = payloads.map((payload, index) => {
43613
- const envelope2 = {
43614
- delivery: {
43615
- eventId: randomUUID7(),
43616
- kind: "reliable",
43617
- sourceSeq: (sourceSeq + index).toString(),
43618
- streamId
43619
- },
43620
- kind: SESSION_EVENT_KIND,
43621
- payload,
43622
- sessionId
43623
- };
43624
- const encoded = encodeSessionEventEnvelope(envelope2);
43625
- return { byteLength: Buffer.byteLength(encoded, "utf8"), encoded, envelope: envelope2 };
43626
- });
43627
- const byteLength = stored.reduce((total, entry) => total + entry.byteLength, 0);
43628
- const maximumBytes = critical ? this.#limits.criticalEventBytes : this.#limits.standardEventBytes;
43629
- if (rowNumber(state, "total_bytes") + byteLength > maximumBytes) {
43630
- throw new SessionEventOutboxCapacityError();
43631
- }
43632
- const insert = this.#database.prepare(
43633
- `INSERT INTO relay_session_event_outbox (
43634
- event_id, session_id, source_seq, byte_length, envelope_json
43635
- ) VALUES (?, ?, ?, ?, ?)`
43636
- );
43637
- for (const entry of stored) {
43638
- insert.run(
43639
- entry.envelope.delivery.eventId,
43640
- sessionId,
43641
- Number(entry.envelope.delivery.sourceSeq),
43642
- entry.byteLength,
43643
- entry.encoded
43644
- );
43645
- }
43646
- this.#database.prepare(
43647
- `UPDATE relay_session_event_outbox_state
43648
- SET next_source_seq = next_source_seq + ?,
43649
- total_bytes = total_bytes + ?
43650
- WHERE singleton = 1`
43651
- ).run(stored.length, byteLength);
43652
- this.#database.exec("COMMIT");
43653
- return stored.map((entry) => entry.envelope);
43654
- } catch (error62) {
43655
- this.#database.exec("ROLLBACK");
43656
- throw error62;
43657
- }
43658
- };
43659
- pending = (limit, excludedEventIds) => {
43660
- if (!Number.isSafeInteger(limit) || limit < 1) {
43661
- throw new Error("Session event replay limit must be a positive integer");
43662
- }
43663
- const exclusion = excludedEventIds.length === 0 ? "" : `WHERE event_id NOT IN (${excludedEventIds.map(() => "?").join(", ")})`;
43664
- return this.#database.prepare(
43665
- `SELECT envelope_json
43666
- FROM relay_session_event_outbox
43667
- ${exclusion}
43668
- ORDER BY source_seq
43669
- LIMIT ?`
43670
- ).all(...excludedEventIds, limit).map((row) => {
43671
- const envelope2 = decodeSessionEventEnvelope(rowString(row, "envelope_json"));
43672
- if (!("delivery" in envelope2)) {
43673
- throw new Error("SQLite returned an invalid reliable Session event envelope");
43674
- }
43675
- return envelope2;
43676
- });
43677
- };
43678
- quarantine = (rejection) => {
43679
- this.#database.exec("BEGIN IMMEDIATE");
43680
- try {
43681
- const stored = this.#database.prepare(
43682
- `SELECT byte_length, envelope_json
43683
- FROM relay_session_event_outbox
43684
- WHERE event_id = ? AND session_id = ?`
43685
- ).get(rejection.eventId, rejection.sessionId);
43686
- if (stored === void 0) {
43687
- this.#database.exec("COMMIT");
43688
- return false;
43689
- }
43690
- this.#database.prepare(
43691
- `INSERT INTO relay_session_event_dead_letters (
43692
- event_id, session_id, rejection_code, envelope_json
43693
- ) VALUES (?, ?, ?, ?)`
43694
- ).run(rejection.eventId, rejection.sessionId, rejection.code, rowString(stored, "envelope_json"));
43695
- this.#deleteStored(rejection.eventId, rejection.sessionId, rowNumber(stored, "byte_length"));
43696
- this.#database.prepare(
43697
- `DELETE FROM relay_session_event_dead_letters
43698
- WHERE ordinal NOT IN (
43699
- SELECT ordinal FROM relay_session_event_dead_letters
43700
- ORDER BY ordinal DESC LIMIT ?
43701
- )`
43702
- ).run(MAX_DEAD_LETTERS);
43703
- this.#database.exec("COMMIT");
43704
- return true;
43705
- } catch (error62) {
43706
- this.#database.exec("ROLLBACK");
43707
- throw error62;
43708
- }
43709
- };
43710
- #deleteStored = (eventId, sessionId, byteLength) => {
43711
- const deletion = this.#database.prepare(
43712
- `DELETE FROM relay_session_event_outbox
43713
- WHERE event_id = ? AND session_id = ?`
43714
- ).run(eventId, sessionId);
43715
- if (deletion.changes !== 1) {
43716
- throw new Error("The Session event could not be removed from the outbox");
43717
- }
43718
- const state = this.#database.prepare(
43719
- `UPDATE relay_session_event_outbox_state
43720
- SET total_bytes = total_bytes - ?
43721
- WHERE singleton = 1 AND total_bytes >= ?`
43722
- ).run(byteLength, byteLength);
43723
- if (state.changes !== 1) {
43724
- throw new Error("The Session event outbox capacity state is inconsistent");
43725
- }
43726
- };
43727
- #remove = (eventId, sessionId) => {
43728
- this.#database.exec("BEGIN IMMEDIATE");
43729
- try {
43730
- const stored = this.#database.prepare(
43731
- `SELECT byte_length
43732
- FROM relay_session_event_outbox
43733
- WHERE event_id = ? AND session_id = ?`
43734
- ).get(eventId, sessionId);
43735
- if (stored === void 0) {
43736
- this.#database.exec("COMMIT");
43737
- return false;
43738
- }
43739
- this.#deleteStored(eventId, sessionId, rowNumber(stored, "byte_length"));
43740
- this.#database.exec("COMMIT");
43741
- return true;
43742
- } catch (error62) {
43743
- this.#database.exec("ROLLBACK");
43744
- throw error62;
43745
- }
43746
- };
43747
- };
43748
-
43749
43415
  // src/relay-connection/session-event-publisher.ts
43750
43416
  import { WebSocket as WebSocket9 } from "undici";
43751
- var SESSION_EVENT_REPLAY_WINDOW = 16;
43752
- var SESSION_EVENT_REPLAY_BYTE_LIMIT = 32 * 1024 * 1024;
43753
- function reservesSessionEventCapacity(event) {
43754
- if (event.kind === SESSION_COMPLETED_KIND || event.kind === SESSION_FAILED_KIND || event.kind === SESSION_FORKED_KIND || event.kind === SESSION_READY_KIND) {
43755
- return true;
43756
- }
43757
- return event.kind === AGENT_ACTIVITY_KIND && (event.activityType === "progress" || event.activityType === "reasoning") && (event.status === "completed" || event.status === "failed");
43758
- }
43417
+ var MAX_BUFFERED_BYTES = 32 * 1024 * 1024;
43759
43418
  var DaemonSessionEventPublisher = class {
43760
- #inFlight = /* @__PURE__ */ new Map();
43761
- #outbox;
43762
- #reportedCapacityKinds = /* @__PURE__ */ new Set();
43763
- #timer;
43764
- #connection = { kind: "disconnected" };
43765
- #deferredReplay = null;
43766
- #inFlightBytes = 0;
43767
- constructor(outbox, timer) {
43768
- this.#outbox = outbox;
43769
- this.#timer = timer;
43770
- }
43771
- acknowledge = (acknowledgement) => {
43772
- if (!this.#outbox.acknowledge(acknowledgement)) {
43773
- return;
43774
- }
43775
- this.#removeInFlight(acknowledgement.eventId);
43776
- this.#publishNextBatch();
43777
- };
43778
- close = () => {
43779
- this.#deferredReplay?.cancel();
43780
- this.#deferredReplay = null;
43781
- this.#connection = { kind: "disconnected" };
43782
- this.#clearInFlight();
43783
- this.#outbox.close();
43784
- };
43785
- connect = (socket, delivery) => {
43786
- this.#connection = { delivery, kind: "connected", socket };
43787
- this.#clearInFlight();
43788
- this.#publishNextBatch();
43789
- };
43790
- defer = (deferred) => {
43791
- if (!this.#inFlight.has(deferred.eventId)) {
43792
- return;
43793
- }
43794
- this.#clearInFlight();
43795
- if (this.#deferredReplay !== null) {
43796
- return;
43797
- }
43798
- this.#deferredReplay = this.#timer.schedule(() => {
43799
- this.#deferredReplay = null;
43800
- this.#publishNextBatch();
43801
- }, deferred.retryAfterMilliseconds);
43419
+ #socket = null;
43420
+ connect = (socket) => {
43421
+ this.#socket = socket;
43802
43422
  };
43803
43423
  disconnect = (socket) => {
43804
- if (this.#connection.kind !== "connected" || this.#connection.socket !== socket) {
43805
- return;
43806
- }
43807
- this.#connection = { kind: "disconnected" };
43808
- this.#clearInFlight();
43809
- };
43810
- publish = (sessionId, event) => {
43811
- try {
43812
- this.#outbox.enqueue(sessionId, encodeRecordedSessionEvent(event), reservesSessionEventCapacity(event));
43813
- } catch (error62) {
43814
- if (!(error62 instanceof SessionEventOutboxCapacityError)) {
43815
- throw error62;
43816
- }
43817
- if (!this.#reportedCapacityKinds.has(event.kind)) {
43818
- this.#reportedCapacityKinds.add(event.kind);
43819
- console.warn(
43820
- `Mobius daemon could not persist "${event.kind}" because the Session event outbox is full`
43821
- );
43822
- }
43823
- return;
43824
- }
43825
- this.#publishNextBatch();
43826
- };
43827
- publishBatch = (sessionId, events) => {
43828
- const critical = events.some(reservesSessionEventCapacity);
43829
- this.#outbox.enqueueBatch(sessionId, events.map(encodeRecordedSessionEvent), critical);
43830
- this.#publishNextBatch();
43831
- };
43832
- quarantine = (rejection) => {
43833
- if (!this.#outbox.quarantine(rejection)) {
43834
- return;
43424
+ if (this.#socket === socket) {
43425
+ this.#socket = null;
43835
43426
  }
43836
- this.#removeInFlight(rejection.eventId);
43837
- console.error(`Mobius Relay rejected Session event ${rejection.eventId} with code ${rejection.code}`);
43838
- this.#publishNextBatch();
43839
43427
  };
43840
- #clearInFlight = () => {
43841
- this.#inFlight.clear();
43842
- this.#inFlightBytes = 0;
43428
+ close = () => {
43429
+ this.#socket = null;
43843
43430
  };
43844
- #publishNextBatch = () => {
43845
- if (this.#deferredReplay !== null || this.#connection.kind !== "connected") {
43431
+ publish = (sessionId, event) => {
43432
+ const socket = this.#socket;
43433
+ if (socket === null || socket.readyState !== WebSocket9.OPEN) {
43846
43434
  return;
43847
43435
  }
43848
- while (this.#inFlight.size < SESSION_EVENT_REPLAY_WINDOW) {
43849
- const batch = this.#outbox.pending(SESSION_EVENT_REPLAY_WINDOW - this.#inFlight.size, [
43850
- ...this.#inFlight.keys()
43851
- ]);
43852
- let sent = 0;
43853
- for (const envelope2 of batch) {
43854
- const encoded = encodeDaemonToServiceMessage(
43855
- this.#connection.delivery === "reliable" ? envelope2 : {
43856
- kind: envelope2.kind,
43857
- payload: envelope2.payload,
43858
- sessionId: envelope2.sessionId
43859
- }
43860
- );
43861
- const byteLength = Buffer.byteLength(encoded, "utf8");
43862
- if (this.#inFlightBytes + byteLength > SESSION_EVENT_REPLAY_BYTE_LIMIT) {
43863
- return;
43864
- }
43865
- if (!this.#send(encoded)) {
43866
- this.#clearInFlight();
43867
- return;
43868
- }
43869
- if (this.#connection.delivery === "ephemeral") {
43870
- this.#outbox.acknowledge({
43871
- eventId: envelope2.delivery.eventId,
43872
- kind: "session.event.ack",
43873
- outcome: { kind: "relayed" },
43874
- sessionId: envelope2.sessionId
43875
- });
43876
- sent += 1;
43877
- continue;
43878
- }
43879
- this.#inFlight.set(envelope2.delivery.eventId, { byteLength });
43880
- this.#inFlightBytes += byteLength;
43881
- sent += 1;
43882
- }
43883
- if (sent === 0) {
43884
- return;
43885
- }
43886
- }
43887
- };
43888
- #removeInFlight = (eventId) => {
43889
- const inFlight = this.#inFlight.get(eventId);
43890
- if (inFlight === void 0) {
43436
+ const encoded = encodeDaemonToServiceMessage({
43437
+ kind: SESSION_EVENT_KIND,
43438
+ payload: encodeRecordedSessionEvent(event),
43439
+ sessionId
43440
+ });
43441
+ if (socket.bufferedAmount + Buffer.byteLength(encoded, "utf8") > MAX_BUFFERED_BYTES) {
43442
+ socket.close(1013, "Live event transport overloaded");
43891
43443
  return;
43892
43444
  }
43893
- this.#inFlight.delete(eventId);
43894
- this.#inFlightBytes -= inFlight.byteLength;
43895
- };
43896
- #send = (encoded) => {
43897
- if (this.#connection.kind !== "connected" || this.#connection.socket.readyState !== WebSocket9.OPEN) {
43898
- return false;
43899
- }
43900
43445
  try {
43901
- this.#connection.socket.send(encoded);
43902
- return true;
43446
+ socket.send(encoded);
43903
43447
  } catch {
43904
- return false;
43448
+ }
43449
+ };
43450
+ publishBatch = (sessionId, events) => {
43451
+ for (const event of events) {
43452
+ this.publish(sessionId, event);
43905
43453
  }
43906
43454
  };
43907
43455
  };
@@ -43963,7 +43511,7 @@ async function installDetectedAgentIntegrations(config2, installations, signal)
43963
43511
  {
43964
43512
  agentId: agent.id,
43965
43513
  kind: AGENT_INSTALL_REQUEST_KIND,
43966
- requestId: `automatic-integration-${randomUUID8()}`
43514
+ requestId: `automatic-integration-${randomUUID7()}`
43967
43515
  },
43968
43516
  signal
43969
43517
  );
@@ -43985,11 +43533,7 @@ async function runDaemon(config2, audit, signal, timer = systemDaemonTimer, opti
43985
43533
  join18(stateDirectory, "sessions", `${createHash6("sha256").update(config2.channelId).digest("hex")}.sqlite`)
43986
43534
  );
43987
43535
  const operations = new DaemonOperationState();
43988
- const channelHash = createHash6("sha256").update(config2.channelId).digest("hex");
43989
- const publisher = new DaemonSessionEventPublisher(
43990
- new SessionEventOutbox(join18(stateDirectory, "events", `${channelHash}.sqlite`)),
43991
- timer
43992
- );
43536
+ const publisher = new DaemonSessionEventPublisher();
43993
43537
  const activeTurns = new DaemonTurnRegistry(operations);
43994
43538
  const recordSessionEvent = (sessionId, event) => {
43995
43539
  publisher.publish(sessionId, activeTurns.recordEvent(event));