@mirasoth/soothe-client 0.2.1 → 0.4.0
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/README.md +59 -43
- package/dist/{chunk-AQZACDIC.js → chunk-U6RMINYV.js} +489 -5
- package/dist/chunk-U6RMINYV.js.map +1 -0
- package/dist/client-UNPC32NQ.js +7 -0
- package/dist/index.cjs +1402 -273
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +268 -99
- package/dist/index.d.ts +268 -99
- package/dist/index.js +939 -258
- package/dist/index.js.map +1 -1
- package/package.json +4 -1
- package/dist/chunk-AQZACDIC.js.map +0 -1
- package/dist/client-CB6WKQYW.js +0 -7
- /package/dist/{client-CB6WKQYW.js.map → client-UNPC32NQ.js.map} +0 -0
|
@@ -293,11 +293,335 @@ var DEFAULT_DELIVERABLE_PHASES = /* @__PURE__ */ new Set([
|
|
|
293
293
|
"embed"
|
|
294
294
|
]);
|
|
295
295
|
|
|
296
|
+
// src/verbosity.ts
|
|
297
|
+
var VerbosityTier = /* @__PURE__ */ ((VerbosityTier2) => {
|
|
298
|
+
VerbosityTier2[VerbosityTier2["Quiet"] = 0] = "Quiet";
|
|
299
|
+
VerbosityTier2[VerbosityTier2["Normal"] = 1] = "Normal";
|
|
300
|
+
VerbosityTier2[VerbosityTier2["Detailed"] = 2] = "Detailed";
|
|
301
|
+
VerbosityTier2[VerbosityTier2["Debug"] = 3] = "Debug";
|
|
302
|
+
VerbosityTier2[VerbosityTier2["Internal"] = 99] = "Internal";
|
|
303
|
+
return VerbosityTier2;
|
|
304
|
+
})(VerbosityTier || {});
|
|
305
|
+
var verbosityLevelValues = {
|
|
306
|
+
quiet: 0,
|
|
307
|
+
normal: 1,
|
|
308
|
+
debug: 3
|
|
309
|
+
};
|
|
310
|
+
function shouldShow(tier, verbosity) {
|
|
311
|
+
if (tier === 99 /* Internal */) {
|
|
312
|
+
return false;
|
|
313
|
+
}
|
|
314
|
+
const level = verbosityLevelValues[verbosity] ?? 1;
|
|
315
|
+
return tier <= level;
|
|
316
|
+
}
|
|
317
|
+
function isValidVerbosityLevel(s) {
|
|
318
|
+
return s in verbosityLevelValues;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
// src/events.ts
|
|
322
|
+
var EventPlanCreated = "soothe.cognition.plan.created";
|
|
323
|
+
var EventExploreStarted = "soothe.subagent.explore.started";
|
|
324
|
+
var EventExploreMilestone = "soothe.subagent.explore.milestone";
|
|
325
|
+
var EventExploreStepCompleted = "soothe.subagent.explore.step.completed";
|
|
326
|
+
var EventExploreCompleted = "soothe.subagent.explore.completed";
|
|
327
|
+
var EventTacitusStarted = "soothe.subagent.tacitus.started";
|
|
328
|
+
var EventTacitusGatherSummary = "soothe.subagent.tacitus.gather.summary";
|
|
329
|
+
var EventTacitusCompleted = "soothe.subagent.tacitus.completed";
|
|
330
|
+
var EventReplayComplete = "replay_complete";
|
|
331
|
+
var EventLoopReattachedWire = "loop_reattached";
|
|
332
|
+
var EventCardReplayBegin = "card.replay_begin";
|
|
333
|
+
var EventCardCreated = "card.created";
|
|
334
|
+
var EventCardReplayEnd = "card.replay_end";
|
|
335
|
+
var EventToolStarted = "soothe.tool.execution.started";
|
|
336
|
+
var EventToolCompleted = "soothe.tool.execution.completed";
|
|
337
|
+
var EventToolError = "soothe.tool.execution.error";
|
|
338
|
+
var EventStreamToolCallUpdate = "soothe.stream.tool_call.update";
|
|
339
|
+
var EventToolCallUpdatesBatch = "tool_call_updates_batch";
|
|
340
|
+
var EventStrangeLoopStarted = "soothe.cognition.strange_loop.started";
|
|
341
|
+
var EventStrangeLoopCompleted = "soothe.cognition.strange_loop.completed";
|
|
342
|
+
var EventStrangeLoopPlanDecision = "soothe.cognition.strange_loop.plan.decision";
|
|
343
|
+
var EventStrangeLoopReasoned = "soothe.cognition.strange_loop.reasoned";
|
|
344
|
+
var EventStrangeLoopStepStarted = "soothe.cognition.strange_loop.step.started";
|
|
345
|
+
var EventStrangeLoopStepQueued = "soothe.cognition.strange_loop.step.queued";
|
|
346
|
+
var EventStrangeLoopStepCompleted = "soothe.cognition.strange_loop.step.completed";
|
|
347
|
+
var EventStrangeLoopContextCompacted = "soothe.cognition.strange_loop.context.compacted";
|
|
348
|
+
var EventMessageReceived = "soothe.protocol.message.received";
|
|
349
|
+
var EventMessageSent = "soothe.protocol.message.sent";
|
|
350
|
+
var EventFinalReport = "soothe.output.autonomous.final_report.reported";
|
|
351
|
+
var EventAutopilotGoalStatus = "soothe.autopilot.goal.status";
|
|
352
|
+
var EventAutopilotGoalProgress = "soothe.autopilot.goal.progress";
|
|
353
|
+
var EventAutopilotGoalCreated = "soothe.autopilot.goal.created";
|
|
354
|
+
var EventAutopilotGoalCompleted = "soothe.autopilot.goal.completed";
|
|
355
|
+
var EventAutopilotWorkerAssigned = "soothe.autopilot.worker.assigned";
|
|
356
|
+
var EventAutopilotWorkerUnassigned = "soothe.autopilot.worker.unassigned";
|
|
357
|
+
var EventGeneralFailed = "soothe.error.general.failed";
|
|
358
|
+
function parseNamespace(ns) {
|
|
359
|
+
const parts = splitNamespace(ns);
|
|
360
|
+
if (parts.length < 4 || parts[0] !== "soothe") {
|
|
361
|
+
return null;
|
|
362
|
+
}
|
|
363
|
+
if (parts[1] === "internal") {
|
|
364
|
+
return null;
|
|
365
|
+
}
|
|
366
|
+
return { domain: parts[1], component: parts[2], action: parts[3] };
|
|
367
|
+
}
|
|
368
|
+
function splitNamespace(ns) {
|
|
369
|
+
const parts = [];
|
|
370
|
+
let start = 0;
|
|
371
|
+
for (let i = 0; i < ns.length; i++) {
|
|
372
|
+
if (ns[i] === ".") {
|
|
373
|
+
parts.push(ns.slice(start, i));
|
|
374
|
+
start = i + 1;
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
parts.push(ns.slice(start));
|
|
378
|
+
return parts;
|
|
379
|
+
}
|
|
380
|
+
function classifyEventVerbosity(eventTypeOrNamespace) {
|
|
381
|
+
const parsed = parseNamespace(eventTypeOrNamespace);
|
|
382
|
+
if (!parsed) {
|
|
383
|
+
return classifyByEventTypeString(eventTypeOrNamespace);
|
|
384
|
+
}
|
|
385
|
+
return classifyByDomainAndComponent(parsed.domain, parsed.component, eventTypeOrNamespace);
|
|
386
|
+
}
|
|
387
|
+
function classifyByDomainAndComponent(domain, _component, full) {
|
|
388
|
+
switch (domain) {
|
|
389
|
+
case "cognition":
|
|
390
|
+
return 1 /* Normal */;
|
|
391
|
+
case "protocol":
|
|
392
|
+
return 2 /* Detailed */;
|
|
393
|
+
case "tool":
|
|
394
|
+
return 99 /* Internal */;
|
|
395
|
+
case "subagent":
|
|
396
|
+
return classifySubagentEvent(full);
|
|
397
|
+
case "autopilot":
|
|
398
|
+
return 1 /* Normal */;
|
|
399
|
+
case "output":
|
|
400
|
+
case "error":
|
|
401
|
+
return 0 /* Quiet */;
|
|
402
|
+
default:
|
|
403
|
+
return 1 /* Normal */;
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
function classifySubagentEvent(full) {
|
|
407
|
+
const parsed = parseNamespace(full);
|
|
408
|
+
if (!parsed) return 1 /* Normal */;
|
|
409
|
+
switch (parsed.action) {
|
|
410
|
+
case "started":
|
|
411
|
+
case "completed":
|
|
412
|
+
return 1 /* Normal */;
|
|
413
|
+
default:
|
|
414
|
+
return 2 /* Detailed */;
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
function classifyByEventTypeString(eventType) {
|
|
418
|
+
if (eventType === EventFinalReport || eventType === EventGeneralFailed) {
|
|
419
|
+
return 0 /* Quiet */;
|
|
420
|
+
}
|
|
421
|
+
if (eventType === EventToolStarted) {
|
|
422
|
+
return 99 /* Internal */;
|
|
423
|
+
}
|
|
424
|
+
return 1 /* Normal */;
|
|
425
|
+
}
|
|
426
|
+
function isCompletionEvent(eventType) {
|
|
427
|
+
return eventType.endsWith(".completed") || eventType.endsWith(".failed") || eventType === EventGeneralFailed;
|
|
428
|
+
}
|
|
429
|
+
function isSubagentProgressEvent(eventType) {
|
|
430
|
+
const parsed = parseNamespace(eventType);
|
|
431
|
+
if (!parsed || parsed.domain !== "subagent") {
|
|
432
|
+
return false;
|
|
433
|
+
}
|
|
434
|
+
return parsed.action === "started" || parsed.action === "completed";
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
// src/stream_terminal.ts
|
|
438
|
+
var STREAM_END = "soothe.stream.end";
|
|
439
|
+
var TURN_END_CUSTOM_TYPES = /* @__PURE__ */ new Set([
|
|
440
|
+
STREAM_END,
|
|
441
|
+
EventStrangeLoopCompleted
|
|
442
|
+
]);
|
|
443
|
+
var TURN_PROGRESS_CUSTOM_TYPES = /* @__PURE__ */ new Set([
|
|
444
|
+
EventPlanCreated,
|
|
445
|
+
EventStrangeLoopStepStarted,
|
|
446
|
+
EventStrangeLoopStepQueued,
|
|
447
|
+
EventStrangeLoopStepCompleted
|
|
448
|
+
]);
|
|
449
|
+
var STALE_TURN_PENDING_TYPES = /* @__PURE__ */ new Set([
|
|
450
|
+
"connection_ack",
|
|
451
|
+
EventCardReplayBegin,
|
|
452
|
+
EventCardReplayEnd,
|
|
453
|
+
EventCardCreated,
|
|
454
|
+
"complete"
|
|
455
|
+
]);
|
|
456
|
+
function isTurnEndCustomData(data) {
|
|
457
|
+
if (!data || typeof data !== "object") return false;
|
|
458
|
+
const customType = String(data.type ?? "").trim();
|
|
459
|
+
if (!TURN_END_CUSTOM_TYPES.has(customType)) return false;
|
|
460
|
+
if (customType === STREAM_END) {
|
|
461
|
+
const scope = String(data.scope ?? "turn").trim().toLowerCase();
|
|
462
|
+
return scope === "" || scope === "turn";
|
|
463
|
+
}
|
|
464
|
+
return true;
|
|
465
|
+
}
|
|
466
|
+
function isTurnProgressChunk(mode, data) {
|
|
467
|
+
if (mode === "messages" || mode === "updates") return true;
|
|
468
|
+
if (mode !== "custom" || !data || typeof data !== "object") return false;
|
|
469
|
+
if (isTurnEndCustomData(data)) return false;
|
|
470
|
+
const customType = String(data.type ?? "").trim();
|
|
471
|
+
if (TURN_PROGRESS_CUSTOM_TYPES.has(customType)) return true;
|
|
472
|
+
if (customType.startsWith("soothe.cognition.strange_loop.step")) return true;
|
|
473
|
+
return false;
|
|
474
|
+
}
|
|
475
|
+
function stalePendingFrameLabel(event) {
|
|
476
|
+
const eventType = String(event.type ?? "");
|
|
477
|
+
if (STALE_TURN_PENDING_TYPES.has(eventType)) return eventType;
|
|
478
|
+
if (eventType === "next") {
|
|
479
|
+
const payload = event.payload;
|
|
480
|
+
if (!payload || typeof payload !== "object") return null;
|
|
481
|
+
const p = payload;
|
|
482
|
+
const staleMode = String(p.mode ?? "");
|
|
483
|
+
if (STALE_TURN_PENDING_TYPES.has(staleMode)) return staleMode;
|
|
484
|
+
const inner = p.data;
|
|
485
|
+
if (inner && typeof inner === "object") {
|
|
486
|
+
return stalePendingFrameLabel(inner);
|
|
487
|
+
}
|
|
488
|
+
return null;
|
|
489
|
+
}
|
|
490
|
+
if (eventType === "event") {
|
|
491
|
+
const mode = String(event.mode ?? "");
|
|
492
|
+
const data = event.data;
|
|
493
|
+
if (mode === "custom" && isTurnEndCustomData(data)) {
|
|
494
|
+
return String(data.type ?? "").trim();
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
return null;
|
|
498
|
+
}
|
|
499
|
+
function inboundNeedsDeliveryAck(event) {
|
|
500
|
+
const eventType = String(event.type ?? "");
|
|
501
|
+
if (eventType === "complete") return true;
|
|
502
|
+
if (eventType === "next") {
|
|
503
|
+
const payload = event.payload;
|
|
504
|
+
if (!payload || typeof payload !== "object") return false;
|
|
505
|
+
const p = payload;
|
|
506
|
+
const inner = p.data;
|
|
507
|
+
if (!inner || typeof inner !== "object") return false;
|
|
508
|
+
if (String(p.mode ?? "") === "event") {
|
|
509
|
+
return inboundNeedsAckFromEventShape(inner);
|
|
510
|
+
}
|
|
511
|
+
return false;
|
|
512
|
+
}
|
|
513
|
+
if (eventType === "event") return inboundNeedsAckFromEventShape(event);
|
|
514
|
+
return false;
|
|
515
|
+
}
|
|
516
|
+
function inboundNeedsAckFromEventShape(event) {
|
|
517
|
+
const mode = String(event.mode ?? "");
|
|
518
|
+
const data = event.data;
|
|
519
|
+
if (mode === "custom" && isTurnEndCustomData(data)) return true;
|
|
520
|
+
if (mode === "messages" && Array.isArray(data) && data.length > 0) {
|
|
521
|
+
const body = data[0];
|
|
522
|
+
if (!body || typeof body !== "object") return false;
|
|
523
|
+
const t = String(body.type ?? "");
|
|
524
|
+
return t === STREAM_END || t.includes("stream.end");
|
|
525
|
+
}
|
|
526
|
+
return false;
|
|
527
|
+
}
|
|
528
|
+
function extractLoopIdFromInbound(event) {
|
|
529
|
+
const direct = String(event.loop_id ?? "").trim();
|
|
530
|
+
if (direct) return direct;
|
|
531
|
+
if (String(event.type ?? "") !== "next") return "";
|
|
532
|
+
const payload = event.payload;
|
|
533
|
+
if (!payload || typeof payload !== "object") return "";
|
|
534
|
+
const p = payload;
|
|
535
|
+
const fromPayload = String(p.loop_id ?? "").trim();
|
|
536
|
+
if (fromPayload) return fromPayload;
|
|
537
|
+
const inner = p.data;
|
|
538
|
+
if (inner && typeof inner === "object") {
|
|
539
|
+
return String(inner.loop_id ?? "").trim();
|
|
540
|
+
}
|
|
541
|
+
return "";
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
// src/inbound_priority.ts
|
|
545
|
+
var DROP_PRIORITY_CRITICAL = 0;
|
|
546
|
+
var DROP_PRIORITY_HIGH = 1;
|
|
547
|
+
var DROP_PRIORITY_NORMAL = 2;
|
|
548
|
+
var DEFAULT_INBOUND_MAX_SIZE = 2e4;
|
|
549
|
+
function inboundFrameDropPriority(event) {
|
|
550
|
+
if (!event) return DROP_PRIORITY_CRITICAL;
|
|
551
|
+
let eventType = String(event.type ?? "");
|
|
552
|
+
if (eventType === "event_batch" || eventType === "tool_call_updates_batch") {
|
|
553
|
+
return DROP_PRIORITY_HIGH;
|
|
554
|
+
}
|
|
555
|
+
if (eventType === "next") {
|
|
556
|
+
const payload = event.payload;
|
|
557
|
+
if (payload && typeof payload === "object") {
|
|
558
|
+
const p = payload;
|
|
559
|
+
const innerMode = String(p.mode ?? "");
|
|
560
|
+
const innerData = p.data;
|
|
561
|
+
if (innerMode === "messages") {
|
|
562
|
+
if (messagesWireTerminal(innerData)) return DROP_PRIORITY_CRITICAL;
|
|
563
|
+
if (Array.isArray(innerData) && innerData[0] && typeof innerData[0] === "object") {
|
|
564
|
+
if (String(innerData[0].phase ?? "") === "goal_completion") {
|
|
565
|
+
return DROP_PRIORITY_CRITICAL;
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
if (String(p.type ?? "") === "complete") return DROP_PRIORITY_CRITICAL;
|
|
570
|
+
if (innerData && typeof innerData === "object") {
|
|
571
|
+
return inboundFrameDropPriority(innerData);
|
|
572
|
+
}
|
|
573
|
+
eventType = String(p.type ?? "");
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
if (eventType === "complete" || eventType === "error" || eventType === "connection_ack") {
|
|
577
|
+
return DROP_PRIORITY_CRITICAL;
|
|
578
|
+
}
|
|
579
|
+
if (eventType === "status") {
|
|
580
|
+
const state = String(event.state ?? "");
|
|
581
|
+
if (["idle", "running", "stopped", "detached"].includes(state)) {
|
|
582
|
+
return DROP_PRIORITY_CRITICAL;
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
if (eventType === "event") {
|
|
586
|
+
const mode = String(event.mode ?? "");
|
|
587
|
+
const data = event.data;
|
|
588
|
+
if (mode === "custom") {
|
|
589
|
+
if (isTurnEndCustomData(data)) return DROP_PRIORITY_CRITICAL;
|
|
590
|
+
if (data && typeof data === "object") {
|
|
591
|
+
const customType = String(data.type ?? "");
|
|
592
|
+
if (customType.startsWith("soothe.cognition.")) return DROP_PRIORITY_HIGH;
|
|
593
|
+
if (customType.startsWith("soothe.error.") || customType === "stream_degraded") {
|
|
594
|
+
return DROP_PRIORITY_CRITICAL;
|
|
595
|
+
}
|
|
596
|
+
if (customType === "soothe.ux.stream_tool_wire.tool_call_updates_batch") {
|
|
597
|
+
return DROP_PRIORITY_HIGH;
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
if (mode === "messages") {
|
|
602
|
+
if (messagesWireTerminal(data)) return DROP_PRIORITY_CRITICAL;
|
|
603
|
+
if (Array.isArray(data) && data[0] && typeof data[0] === "object") {
|
|
604
|
+
if (String(data[0].phase ?? "") === "goal_completion") {
|
|
605
|
+
return DROP_PRIORITY_CRITICAL;
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
return DROP_PRIORITY_NORMAL;
|
|
611
|
+
}
|
|
612
|
+
function messagesWireTerminal(data) {
|
|
613
|
+
if (!Array.isArray(data) || data.length === 0) return false;
|
|
614
|
+
const body = data[0];
|
|
615
|
+
if (!body || typeof body !== "object") return false;
|
|
616
|
+
const t = String(body.type ?? "");
|
|
617
|
+
return t === STREAM_END || t.includes("stream.end");
|
|
618
|
+
}
|
|
619
|
+
|
|
296
620
|
// src/protocol.ts
|
|
297
621
|
import { randomUUID } from "crypto";
|
|
298
622
|
var PROTO_VERSION = "1";
|
|
299
623
|
var DEFAULT_CLIENT_CAPABILITIES = ["streaming", "batch", "heartbeat", "receipts"];
|
|
300
|
-
var CLIENT_VERSION = "0.
|
|
624
|
+
var CLIENT_VERSION = "0.4.0";
|
|
301
625
|
function encodeMessage(msg) {
|
|
302
626
|
return JSON.stringify(msg) + "\n";
|
|
303
627
|
}
|
|
@@ -465,6 +789,9 @@ var Client = class extends EventEmitter {
|
|
|
465
789
|
config;
|
|
466
790
|
ws = null;
|
|
467
791
|
messageBuffer = [];
|
|
792
|
+
inboundMaxSize = DEFAULT_INBOUND_MAX_SIZE;
|
|
793
|
+
inboundDroppedCount = 0;
|
|
794
|
+
onStreamDegraded = null;
|
|
468
795
|
resolvers = [];
|
|
469
796
|
// Protocol-1 handshake state (RFC-450 §8.2)
|
|
470
797
|
handshakeComplete = false;
|
|
@@ -482,6 +809,8 @@ var Client = class extends EventEmitter {
|
|
|
482
809
|
// Pending-request/subscription multiplexer (RFC-629 constraint #1). Routes
|
|
483
810
|
// inbound frames by (type, id) instead of discarding non-matching events.
|
|
484
811
|
mux = new Multiplexer();
|
|
812
|
+
deliveryRecvSeq = /* @__PURE__ */ new Map();
|
|
813
|
+
deliveryAckedSeq = /* @__PURE__ */ new Map();
|
|
485
814
|
constructor(url, config) {
|
|
486
815
|
super();
|
|
487
816
|
this.url = url;
|
|
@@ -549,13 +878,15 @@ var Client = class extends EventEmitter {
|
|
|
549
878
|
this._signalDisconnect(1 /* Clean */);
|
|
550
879
|
}
|
|
551
880
|
if (this.mux.route(m)) {
|
|
881
|
+
this._trackInboundDeliveryAck(m);
|
|
552
882
|
continue;
|
|
553
883
|
}
|
|
884
|
+
this._trackInboundDeliveryAck(m);
|
|
554
885
|
const resolver = this.resolvers.shift();
|
|
555
886
|
if (resolver) {
|
|
556
887
|
resolver(msg);
|
|
557
888
|
} else {
|
|
558
|
-
this.
|
|
889
|
+
this.enqueueMessageBuffer(msg);
|
|
559
890
|
}
|
|
560
891
|
this.emit("message", msg);
|
|
561
892
|
}
|
|
@@ -868,6 +1199,84 @@ var Client = class extends EventEmitter {
|
|
|
868
1199
|
this.resolvers.push(resolver);
|
|
869
1200
|
});
|
|
870
1201
|
}
|
|
1202
|
+
/**
|
|
1203
|
+
* Remove stale handshake/terminal frames left in `messageBuffer` before a turn.
|
|
1204
|
+
* Returns labels of removed frames (in order).
|
|
1205
|
+
*/
|
|
1206
|
+
peelStalePendingControlEvents() {
|
|
1207
|
+
if (this.messageBuffer.length === 0) return [];
|
|
1208
|
+
const kept = [];
|
|
1209
|
+
const removed = [];
|
|
1210
|
+
while (this.messageBuffer.length > 0) {
|
|
1211
|
+
const event = this.messageBuffer.shift();
|
|
1212
|
+
const label = stalePendingFrameLabel(event);
|
|
1213
|
+
if (label !== null) {
|
|
1214
|
+
removed.push(label);
|
|
1215
|
+
continue;
|
|
1216
|
+
}
|
|
1217
|
+
kept.push(event);
|
|
1218
|
+
}
|
|
1219
|
+
this.messageBuffer = kept;
|
|
1220
|
+
return removed;
|
|
1221
|
+
}
|
|
1222
|
+
/** True when the underlying socket is still open (may not be handshaked). */
|
|
1223
|
+
isConnectionAlive() {
|
|
1224
|
+
return this.ws !== null && this.ws.readyState === WebSocket.OPEN;
|
|
1225
|
+
}
|
|
1226
|
+
/** Override pending buffer cap (tests / tuning). */
|
|
1227
|
+
setInboundMaxSize(n) {
|
|
1228
|
+
if (n > 0) this.inboundMaxSize = n;
|
|
1229
|
+
}
|
|
1230
|
+
/** How many NORMAL-priority frames were dropped under backpressure. */
|
|
1231
|
+
inboundDropped() {
|
|
1232
|
+
return this.inboundDroppedCount;
|
|
1233
|
+
}
|
|
1234
|
+
/** Hook invoked on the first inbound overflow drop. */
|
|
1235
|
+
setStreamDegradedCallback(fn) {
|
|
1236
|
+
this.onStreamDegraded = fn;
|
|
1237
|
+
}
|
|
1238
|
+
enqueueMessageBuffer(msg) {
|
|
1239
|
+
const max = this.inboundMaxSize > 0 ? this.inboundMaxSize : DEFAULT_INBOUND_MAX_SIZE;
|
|
1240
|
+
if (this.messageBuffer.length < max) {
|
|
1241
|
+
this.messageBuffer.push(msg);
|
|
1242
|
+
return;
|
|
1243
|
+
}
|
|
1244
|
+
const ev = msg;
|
|
1245
|
+
let dropIdx = -1;
|
|
1246
|
+
let dropPri = -1;
|
|
1247
|
+
for (let i = 0; i < this.messageBuffer.length; i++) {
|
|
1248
|
+
const p = inboundFrameDropPriority(this.messageBuffer[i]);
|
|
1249
|
+
if (p > dropPri) {
|
|
1250
|
+
dropPri = p;
|
|
1251
|
+
dropIdx = i;
|
|
1252
|
+
}
|
|
1253
|
+
}
|
|
1254
|
+
const incomingPri = inboundFrameDropPriority(ev);
|
|
1255
|
+
if (dropIdx >= 0 && dropPri >= DROP_PRIORITY_NORMAL) {
|
|
1256
|
+
this.messageBuffer.splice(dropIdx, 1);
|
|
1257
|
+
this.messageBuffer.push(msg);
|
|
1258
|
+
this.noteInboundDrop();
|
|
1259
|
+
return;
|
|
1260
|
+
}
|
|
1261
|
+
if (incomingPri >= DROP_PRIORITY_NORMAL) {
|
|
1262
|
+
this.noteInboundDrop();
|
|
1263
|
+
return;
|
|
1264
|
+
}
|
|
1265
|
+
if (this.messageBuffer.length > 0) {
|
|
1266
|
+
this.messageBuffer.shift();
|
|
1267
|
+
this.noteInboundDrop();
|
|
1268
|
+
}
|
|
1269
|
+
this.messageBuffer.push(msg);
|
|
1270
|
+
}
|
|
1271
|
+
noteInboundDrop() {
|
|
1272
|
+
this.inboundDroppedCount += 1;
|
|
1273
|
+
if (this.onStreamDegraded && this.inboundDroppedCount === 1) {
|
|
1274
|
+
try {
|
|
1275
|
+
this.onStreamDegraded(1, "inbound_queue_overflow");
|
|
1276
|
+
} catch {
|
|
1277
|
+
}
|
|
1278
|
+
}
|
|
1279
|
+
}
|
|
871
1280
|
// ---------------------------------------------------------------------------
|
|
872
1281
|
// Protocol-1 RPC primitives (RFC-450 §5/§9)
|
|
873
1282
|
// ---------------------------------------------------------------------------
|
|
@@ -972,6 +1381,35 @@ var Client = class extends EventEmitter {
|
|
|
972
1381
|
notify(method, params) {
|
|
973
1382
|
return this.sendMessage(notificationEnvelope(method, params));
|
|
974
1383
|
}
|
|
1384
|
+
_trackInboundDeliveryAck(event) {
|
|
1385
|
+
if (String(event.type ?? "") === "event_batch") {
|
|
1386
|
+
const events = event.events;
|
|
1387
|
+
if (Array.isArray(events)) {
|
|
1388
|
+
for (const sub of events) {
|
|
1389
|
+
if (sub && typeof sub === "object") {
|
|
1390
|
+
this._trackInboundDeliveryAck(sub);
|
|
1391
|
+
}
|
|
1392
|
+
}
|
|
1393
|
+
}
|
|
1394
|
+
return;
|
|
1395
|
+
}
|
|
1396
|
+
if (!inboundNeedsDeliveryAck(event)) return;
|
|
1397
|
+
const loopId = extractLoopIdFromInbound(event);
|
|
1398
|
+
if (!loopId) return;
|
|
1399
|
+
const next = (this.deliveryRecvSeq.get(loopId) ?? 0) + 1;
|
|
1400
|
+
this.deliveryRecvSeq.set(loopId, next);
|
|
1401
|
+
void this._sendDeliveryAck(loopId, next);
|
|
1402
|
+
}
|
|
1403
|
+
async _sendDeliveryAck(loopId, seq) {
|
|
1404
|
+
const acked = this.deliveryAckedSeq.get(loopId) ?? 0;
|
|
1405
|
+
if (seq <= acked) return;
|
|
1406
|
+
this.deliveryAckedSeq.set(loopId, seq);
|
|
1407
|
+
if (!this.isConnected()) return;
|
|
1408
|
+
try {
|
|
1409
|
+
await this.notify("delivery_ack", { loop_id: loopId, seq });
|
|
1410
|
+
} catch {
|
|
1411
|
+
}
|
|
1412
|
+
}
|
|
975
1413
|
/**
|
|
976
1414
|
* Starts a subscription stream. Returns the subscription `id` for later
|
|
977
1415
|
* correlation and `unsubscribe()`. Stream events arrive as `next` frames
|
|
@@ -989,7 +1427,7 @@ var Client = class extends EventEmitter {
|
|
|
989
1427
|
if (ev === null) break;
|
|
990
1428
|
const evId = ev.id;
|
|
991
1429
|
if (evId !== subId) {
|
|
992
|
-
this.
|
|
1430
|
+
this.enqueueMessageBuffer(ev);
|
|
993
1431
|
continue;
|
|
994
1432
|
}
|
|
995
1433
|
const typ = ev.type;
|
|
@@ -1364,6 +1802,9 @@ export {
|
|
|
1364
1802
|
disconnectCauseName,
|
|
1365
1803
|
ReconnectError,
|
|
1366
1804
|
StaleLoopError,
|
|
1805
|
+
VerbosityTier,
|
|
1806
|
+
shouldShow,
|
|
1807
|
+
isValidVerbosityLevel,
|
|
1367
1808
|
defaultConfig,
|
|
1368
1809
|
loadConfigFromEnv,
|
|
1369
1810
|
PROTO_VERSION,
|
|
@@ -1393,7 +1834,50 @@ export {
|
|
|
1393
1834
|
validateLoopInputIntentHint,
|
|
1394
1835
|
LOOP_ASSISTANT_OUTPUT_PHASES,
|
|
1395
1836
|
DEFAULT_DELIVERABLE_PHASES,
|
|
1396
|
-
|
|
1837
|
+
EventPlanCreated,
|
|
1838
|
+
EventExploreStarted,
|
|
1839
|
+
EventExploreMilestone,
|
|
1840
|
+
EventExploreStepCompleted,
|
|
1841
|
+
EventExploreCompleted,
|
|
1842
|
+
EventTacitusStarted,
|
|
1843
|
+
EventTacitusGatherSummary,
|
|
1844
|
+
EventTacitusCompleted,
|
|
1845
|
+
EventReplayComplete,
|
|
1846
|
+
EventLoopReattachedWire,
|
|
1847
|
+
EventCardReplayBegin,
|
|
1848
|
+
EventCardCreated,
|
|
1849
|
+
EventCardReplayEnd,
|
|
1850
|
+
EventToolStarted,
|
|
1851
|
+
EventToolCompleted,
|
|
1852
|
+
EventToolError,
|
|
1853
|
+
EventStreamToolCallUpdate,
|
|
1854
|
+
EventToolCallUpdatesBatch,
|
|
1855
|
+
EventStrangeLoopStarted,
|
|
1856
|
+
EventStrangeLoopCompleted,
|
|
1857
|
+
EventStrangeLoopPlanDecision,
|
|
1858
|
+
EventStrangeLoopReasoned,
|
|
1859
|
+
EventStrangeLoopStepStarted,
|
|
1860
|
+
EventStrangeLoopStepQueued,
|
|
1861
|
+
EventStrangeLoopStepCompleted,
|
|
1862
|
+
EventStrangeLoopContextCompacted,
|
|
1863
|
+
EventMessageReceived,
|
|
1864
|
+
EventMessageSent,
|
|
1865
|
+
EventFinalReport,
|
|
1866
|
+
EventAutopilotGoalStatus,
|
|
1867
|
+
EventAutopilotGoalProgress,
|
|
1868
|
+
EventAutopilotGoalCreated,
|
|
1869
|
+
EventAutopilotGoalCompleted,
|
|
1870
|
+
EventAutopilotWorkerAssigned,
|
|
1871
|
+
EventAutopilotWorkerUnassigned,
|
|
1872
|
+
EventGeneralFailed,
|
|
1873
|
+
parseNamespace,
|
|
1874
|
+
classifyEventVerbosity,
|
|
1875
|
+
isCompletionEvent,
|
|
1876
|
+
isSubagentProgressEvent,
|
|
1877
|
+
STREAM_END,
|
|
1878
|
+
isTurnEndCustomData,
|
|
1879
|
+
isTurnProgressChunk,
|
|
1880
|
+
inboundNeedsDeliveryAck,
|
|
1397
1881
|
Client
|
|
1398
1882
|
};
|
|
1399
|
-
//# sourceMappingURL=chunk-
|
|
1883
|
+
//# sourceMappingURL=chunk-U6RMINYV.js.map
|