agenthub-multiagent-mcp 1.52.0 → 1.53.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.
Files changed (61) hide show
  1. package/dist/captureHookInstall.d.ts +127 -0
  2. package/dist/captureHookInstall.d.ts.map +1 -0
  3. package/dist/captureHookInstall.js +256 -0
  4. package/dist/captureHookInstall.js.map +1 -0
  5. package/dist/captureHookInstall.test.d.ts +10 -0
  6. package/dist/captureHookInstall.test.d.ts.map +1 -0
  7. package/dist/captureHookInstall.test.js +325 -0
  8. package/dist/captureHookInstall.test.js.map +1 -0
  9. package/dist/channel.js +96 -0
  10. package/dist/channel.js.map +1 -1
  11. package/dist/client.d.ts +50 -0
  12. package/dist/client.d.ts.map +1 -1
  13. package/dist/client.js +90 -0
  14. package/dist/client.js.map +1 -1
  15. package/dist/commands/setup-shell.js +11 -11
  16. package/dist/daemon.js +142 -3
  17. package/dist/daemon.js.map +1 -1
  18. package/dist/index.js +25 -0
  19. package/dist/index.js.map +1 -1
  20. package/dist/session-capture.sh +410 -0
  21. package/dist/sessionCapture.d.ts +163 -0
  22. package/dist/sessionCapture.d.ts.map +1 -0
  23. package/dist/sessionCapture.js +279 -0
  24. package/dist/sessionCapture.js.map +1 -0
  25. package/dist/sessionCapture.test.d.ts +9 -0
  26. package/dist/sessionCapture.test.d.ts.map +1 -0
  27. package/dist/sessionCapture.test.js +366 -0
  28. package/dist/sessionCapture.test.js.map +1 -0
  29. package/dist/sessionCaptureScript.test.d.ts +16 -0
  30. package/dist/sessionCaptureScript.test.d.ts.map +1 -0
  31. package/dist/sessionCaptureScript.test.js +92 -0
  32. package/dist/sessionCaptureScript.test.js.map +1 -0
  33. package/dist/steering.test.d.ts +2 -0
  34. package/dist/steering.test.d.ts.map +1 -0
  35. package/dist/steering.test.js +223 -0
  36. package/dist/steering.test.js.map +1 -0
  37. package/dist/streamingRuntimeLib.d.ts +260 -1
  38. package/dist/streamingRuntimeLib.d.ts.map +1 -1
  39. package/dist/streamingRuntimeLib.js +474 -1
  40. package/dist/streamingRuntimeLib.js.map +1 -1
  41. package/dist/streamingRuntimeLib.test.js +87 -1
  42. package/dist/streamingRuntimeLib.test.js.map +1 -1
  43. package/dist/tools/index.d.ts.map +1 -1
  44. package/dist/tools/index.js +8 -0
  45. package/dist/tools/index.js.map +1 -1
  46. package/dist/tools/sessionControl.d.ts +53 -0
  47. package/dist/tools/sessionControl.d.ts.map +1 -0
  48. package/dist/tools/sessionControl.js +265 -0
  49. package/dist/tools/sessionControl.js.map +1 -0
  50. package/dist/tools/sessionControl.test.d.ts +14 -0
  51. package/dist/tools/sessionControl.test.d.ts.map +1 -0
  52. package/dist/tools/sessionControl.test.js +298 -0
  53. package/dist/tools/sessionControl.test.js.map +1 -0
  54. package/dist/tools/tools.test.js +4 -2
  55. package/dist/tools/tools.test.js.map +1 -1
  56. package/native/agenthub-memvid/agenthub-memvid.linux-x64-gnu.node +0 -0
  57. package/package.json +2 -2
  58. package/skills/commands/start-session.md +77 -77
  59. package/skills/skills/deploy-staging/SKILL.md +164 -164
  60. package/skills/skills/deploy-vps-openclaw/SKILL.md +97 -97
  61. package/skills/skills/karpathy-guidelines/SKILL.md +67 -67
@@ -8,6 +8,21 @@
8
8
  * Verified premise (VPS spike 2026-06-26, org brain #2209): the Claude Agent SDK
9
9
  * streaming mode runs on the subscription (CLAUDE_CODE_OAUTH_TOKEN, no
10
10
  * ANTHROPIC_API_KEY) and processes a mid-run yielded message in the same session.
11
+ *
12
+ * ---------------------------------------------------------------------------
13
+ * CANONICAL COPY — `employee-runtime/src/streamingRuntimeLib.ts` is vendored
14
+ * from this file and must stay **functionally** in sync (add-multiplayer-sessions
15
+ * §2.4). Change one, change the other in the same commit.
16
+ *
17
+ * Why two copies rather than an import: `employee-runtime` is a separate package
18
+ * precisely because the agent-sdk's peer deps conflict with this package's, so it
19
+ * cannot depend on `agenthub-multiagent-mcp`. The daemon side imports this copy
20
+ * (for the `streamingEnabled()` gate); the runtime imports the vendored one.
21
+ *
22
+ * The two headers differ, and the vendored copy carries fewer prose comments;
23
+ * everything below the header is expected to be identical. Keep it import-free —
24
+ * pure logic only — so neither copy drags a package-specific dependency across.
25
+ * ---------------------------------------------------------------------------
11
26
  */
12
27
  // =============================================================================
13
28
  // Kill switch + auth (§2.1 / §D3)
@@ -16,6 +31,22 @@
16
31
  export function streamingEnabled(env = process.env) {
17
32
  return /^(1|true|yes|on)$/i.test((env.AGENTHUB_EMPLOYEE_STREAMING_ENABLED || "").trim());
18
33
  }
34
+ /**
35
+ * Human steering kill switch (add-multiplayer-sessions §4.8). Default **off** —
36
+ * unset, empty, or unrecognised means disabled, and while it is off the producer
37
+ * side does no I/O at all: no transport is declared, nothing is polled, and the
38
+ * runtime loop is what it was before this feature existed.
39
+ *
40
+ * It lives here rather than in a runtime-only module because both producers
41
+ * consult it: the streaming runtime (which declares `turn_queue` and pulls
42
+ * steers) and the one-shot daemon (which declares `one_shot` so its shifts are
43
+ * refused explicitly rather than by accident of having declared nothing).
44
+ * Mirrors the server's `AGENTHUB_SESSION_STEER_ENABLED`; a producer that polled
45
+ * while the server had it off would earn a 503 on every tick.
46
+ */
47
+ export function sessionSteerEnabled(env = process.env) {
48
+ return /^(1|true|yes|on)$/i.test((env.AGENTHUB_SESSION_STEER_ENABLED || "").trim());
49
+ }
19
50
  /**
20
51
  * §D3 — assert subscription auth and fail CLOSED against metered billing. The
21
52
  * SDK subprocess inherits the env; if ANTHROPIC_API_KEY were set it would take
@@ -55,8 +86,26 @@ export function decideInbound(envelope, agentId, handled) {
55
86
  return { yield: false, reason: "duplicate", message: m };
56
87
  return { yield: true, message: m };
57
88
  }
58
- /** Render an AgentHub message as the text content of a session turn. */
89
+ /**
90
+ * The message type a human steer arrives as. Mirrors `sessions.SteerMessageType`
91
+ * on the server, which validates it on the way in — an unrecognised type would be
92
+ * persisted and then framed by whatever branch this function fell through to,
93
+ * which is the same silent-wrong-behaviour class as a dropped steer.
94
+ */
95
+ export const STEER_MESSAGE_TYPE = "steer";
96
+ /**
97
+ * Render an AgentHub message as the text content of a session turn.
98
+ *
99
+ * Two framings, and the distinction is the whole point of §4.3. An inbox message
100
+ * is agent-to-agent: somebody is waiting on an answer, so the turn tells the
101
+ * model to answer with `mcp__agenthub__reply`. A steer is a human leaning over
102
+ * the session and redirecting the work: nobody is waiting on a message, and
103
+ * telling the model to reply would turn "stop rewriting that file" into a note
104
+ * written back to the person who typed it while the work carried on unchanged.
105
+ */
59
106
  export function buildTurnContent(m) {
107
+ if (m.type === STEER_MESSAGE_TYPE)
108
+ return buildSteerTurnContent(m);
60
109
  const priority = m.priority && m.priority !== "normal" ? ` | Priority: ${m.priority}` : "";
61
110
  return (`You received a message on AgentHub.\n` +
62
111
  `From: ${m.from_agent}\n` +
@@ -66,6 +115,63 @@ export function buildTurnContent(m) {
66
115
  `Reply with mcp__agenthub__reply(message_id="${m.id}", body="…"). ` +
67
116
  `If this is outside your charter, escalate via send_message instead of guessing.`);
68
117
  }
118
+ /**
119
+ * Frame a steer as what it is: a direct instruction from a human operator
120
+ * watching this session (§4.3).
121
+ *
122
+ * Deliberately parallel to `buildInstructionTurnContent` in `workstation.ts`,
123
+ * which solves the same problem for a driven personal workspace. Both say the
124
+ * same three things, because all three are load-bearing: who this came from, that
125
+ * it is an instruction rather than correspondence, and that no reply is wanted.
126
+ * The refusal clause is here for the same reason it is there — a human can steer
127
+ * a session into something the agent should not do, and "say so and stop" is a
128
+ * better outcome than either silent compliance or silent refusal.
129
+ */
130
+ export function buildSteerTurnContent(m) {
131
+ const from = m.from_agent && m.from_agent !== "" ? m.from_agent : "a human operator";
132
+ return (`A person is steering this session from the AgentHub dashboard.\n` +
133
+ `From: ${from}\n\n` +
134
+ `${m.body}\n\n` +
135
+ `This is a direct instruction from a human operator, not an agent-to-agent ` +
136
+ `message: change what you are doing to follow it and carry on with the work in ` +
137
+ `this session. Do NOT call mcp__agenthub__reply — nobody is waiting on a ` +
138
+ `message, and a reply would leave the work itself unchanged. If the instruction ` +
139
+ `is unsafe, or conflicts with your charter, say so in your next message and stop.`);
140
+ }
141
+ /**
142
+ * Parse a `session_steer` WebSocket frame (the channel transport's delivery
143
+ * path). Returns `null` for anything that is not a well-formed steer.
144
+ *
145
+ * Lives here rather than in the channel plugin because the plugin is an
146
+ * executable script — importing it to test it would start an MCP server — and
147
+ * because the frame is a wire contract shared with the server, which is the kind
148
+ * of thing that should have one parser and one test.
149
+ *
150
+ * A frame missing an id or text is `null` rather than a partially-populated
151
+ * steer: an instruction with no text delivers nothing, and one with no id cannot
152
+ * be acked, so "deliver it anyway" would produce exactly the accepted-and-dropped
153
+ * outcome the whole transport contract exists to rule out.
154
+ */
155
+ export function parseSteerFrame(envelope) {
156
+ if (envelope === null || typeof envelope !== "object")
157
+ return null;
158
+ const e = envelope;
159
+ if (e.type !== "session_steer")
160
+ return null;
161
+ const data = e.data !== null && typeof e.data === "object" ? e.data : {};
162
+ const sessionId = typeof data.session_id === "string" ? data.session_id.trim() : "";
163
+ const steerId = typeof data.steer_id === "string" ? data.steer_id.trim() : "";
164
+ const text = typeof data.text === "string" ? data.text : "";
165
+ if (sessionId === "" || steerId === "" || text.trim() === "")
166
+ return null;
167
+ return {
168
+ sessionId,
169
+ steerId,
170
+ text,
171
+ createdBy: typeof data.created_by === "string" ? data.created_by : "",
172
+ messageType: typeof data.message_type === "string" && data.message_type !== "" ? data.message_type : STEER_MESSAGE_TYPE,
173
+ };
174
+ }
69
175
  export function toUserTurn(content, sessionId) {
70
176
  return { type: "user", message: { role: "user", content }, parent_tool_use_id: null, session_id: sessionId };
71
177
  }
@@ -152,4 +258,371 @@ export function assertWorkerIdentityReady(stateExists, agentId) {
152
258
  `off; a missing token would hang the in-session MCP. Exiting for restart + re-heal.`);
153
259
  }
154
260
  }
261
+ /**
262
+ * Client-side payload bounds. The server is authoritative for truncation and
263
+ * redaction (add-multiplayer-sessions §1.8/§1.9) and this code deliberately does
264
+ * **not** duplicate either. These bounds exist only so a single event is never
265
+ * megabytes on the wire; they mirror `session-capture.sh`'s TRUNC / TRUNC_SHORT
266
+ * so both producers put comparable volumes in front of the same server pipeline.
267
+ */
268
+ export const PAYLOAD_MAX_CHARS = 8000;
269
+ export const PAYLOAD_SUMMARY_MAX_CHARS = 1000;
270
+ function asRecord(value) {
271
+ return value !== null && typeof value === "object" ? value : {};
272
+ }
273
+ /** JSON that never throws — a cyclic or exotic value degrades to its String form. */
274
+ function safeStringify(value) {
275
+ try {
276
+ return JSON.stringify(value) ?? String(value);
277
+ }
278
+ catch {
279
+ return String(value);
280
+ }
281
+ }
282
+ function truncate(value, limit) {
283
+ if (value === undefined || value === null)
284
+ return "";
285
+ const s = typeof value === "string" ? value : safeStringify(value);
286
+ return s.length > limit ? s.slice(0, limit) + "..." : s;
287
+ }
288
+ /** `tool_result.content` is a string, a block list, or (rarely) something else. */
289
+ function flattenToolResult(content) {
290
+ if (typeof content === "string")
291
+ return content;
292
+ if (Array.isArray(content)) {
293
+ return content
294
+ .map((block) => {
295
+ const b = asRecord(block);
296
+ return b.type === "text" ? String(b.text ?? "") : "";
297
+ })
298
+ .filter((s) => s !== "")
299
+ .join("\n");
300
+ }
301
+ return truncate(content, PAYLOAD_MAX_CHARS);
302
+ }
303
+ function sessionEvent(eventType, payload) {
304
+ return { event_type: eventType, payload: safeStringify(payload), token_count: 0 };
305
+ }
306
+ /**
307
+ * Turn SDK stream messages into session events (§2.2).
308
+ *
309
+ * The event vocabulary is exactly the one `session-capture.sh` already produces
310
+ * (`assistant_message`, `command_exec`, `file_read`, `file_edit`, `file_write`,
311
+ * `tool_call`) so the dashboard renders hook-captured and runtime-captured
312
+ * sessions identically. No new event types are introduced here.
313
+ *
314
+ * One deliberate difference from the hook: the hook runs PostToolUse and so sees
315
+ * a tool's input and response together, emitting a single merged event. The
316
+ * stream delivers them as two separate messages (`tool_use` on the assistant
317
+ * message, `tool_result` on the following user message), so this emits two
318
+ * events. The class is stateful only to carry `tool_use_id → tool name` across
319
+ * that gap, so the result event can name the tool it belongs to. The map is
320
+ * bounded: a long session must not accumulate ids forever.
321
+ */
322
+ export class SessionEventExtractor {
323
+ toolNames = new Map();
324
+ maxCorrelations;
325
+ constructor(maxCorrelations = 256) {
326
+ this.maxCorrelations = Math.max(1, maxCorrelations);
327
+ }
328
+ extract(message) {
329
+ const m = asRecord(message);
330
+ if (m.type === "assistant")
331
+ return this.fromAssistant(m);
332
+ if (m.type === "user")
333
+ return this.fromToolResults(m);
334
+ // `result` (usage/recycle), `system`, and every other message type produce no
335
+ // events. `result` in particular is handled by the runtime's existing usage
336
+ // branch and must stay that way — context recycling depends on it.
337
+ return [];
338
+ }
339
+ blocks(m) {
340
+ const content = asRecord(m.message).content;
341
+ return Array.isArray(content) ? content : [];
342
+ }
343
+ fromAssistant(m) {
344
+ const events = [];
345
+ for (const block of this.blocks(m)) {
346
+ const b = asRecord(block);
347
+ if (b.type === "text") {
348
+ const text = String(b.text ?? "");
349
+ if (text.trim() === "")
350
+ continue; // whitespace-only frames are noise
351
+ events.push(sessionEvent("assistant_message", { content: truncate(text, PAYLOAD_MAX_CHARS) }));
352
+ }
353
+ else if (b.type === "tool_use") {
354
+ const name = String(b.name ?? "");
355
+ const id = typeof b.id === "string" ? b.id : "";
356
+ if (id !== "")
357
+ this.rememberTool(id, name);
358
+ events.push(toolUseEvent(name, id, b.input));
359
+ }
360
+ // `thinking` / `redacted_thinking` are intentionally not captured: they are
361
+ // model-internal and watchers have no consent story for them.
362
+ }
363
+ return events;
364
+ }
365
+ fromToolResults(m) {
366
+ const events = [];
367
+ for (const block of this.blocks(m)) {
368
+ const b = asRecord(block);
369
+ if (b.type !== "tool_result")
370
+ continue;
371
+ const id = typeof b.tool_use_id === "string" ? b.tool_use_id : "";
372
+ const payload = {
373
+ tool_name: this.toolNames.get(id) ?? "",
374
+ tool_use_id: id,
375
+ result_summary: truncate(flattenToolResult(b.content), PAYLOAD_SUMMARY_MAX_CHARS),
376
+ };
377
+ if (b.is_error === true)
378
+ payload.is_error = true;
379
+ if (id !== "")
380
+ this.toolNames.delete(id);
381
+ events.push(sessionEvent("tool_call", payload));
382
+ }
383
+ return events;
384
+ }
385
+ rememberTool(id, name) {
386
+ if (this.toolNames.size >= this.maxCorrelations) {
387
+ // Map iteration is insertion-ordered, so this evicts the oldest pending id.
388
+ const oldest = this.toolNames.keys().next();
389
+ if (!oldest.done)
390
+ this.toolNames.delete(oldest.value);
391
+ }
392
+ this.toolNames.set(id, name);
393
+ }
394
+ }
395
+ /**
396
+ * Map one `tool_use` block onto the hook's per-tool event vocabulary. Field names
397
+ * match `session-capture.sh` exactly, because the dashboard reads those names
398
+ * (`command`, `file_path`, `old_string`/`new_string`, `content_preview`,
399
+ * `input_summary`) and renders nothing useful without them.
400
+ */
401
+ function toolUseEvent(name, toolUseId, rawInput) {
402
+ const input = asRecord(rawInput);
403
+ const base = { tool_name: name, tool_use_id: toolUseId };
404
+ switch (name.toLowerCase()) {
405
+ case "bash":
406
+ return sessionEvent("command_exec", {
407
+ ...base,
408
+ command: truncate(input.command, PAYLOAD_SUMMARY_MAX_CHARS),
409
+ });
410
+ case "read":
411
+ return sessionEvent("file_read", {
412
+ ...base,
413
+ file_path: String(input.file_path ?? ""),
414
+ lines_read: typeof input.limit === "number" ? input.limit : 0,
415
+ });
416
+ case "edit":
417
+ return sessionEvent("file_edit", {
418
+ ...base,
419
+ file_path: String(input.file_path ?? ""),
420
+ old_string: truncate(input.old_string, PAYLOAD_SUMMARY_MAX_CHARS),
421
+ new_string: truncate(input.new_string, PAYLOAD_SUMMARY_MAX_CHARS),
422
+ });
423
+ case "write":
424
+ return sessionEvent("file_write", {
425
+ ...base,
426
+ file_path: String(input.file_path ?? ""),
427
+ content_preview: truncate(input.content, PAYLOAD_SUMMARY_MAX_CHARS),
428
+ });
429
+ case "glob":
430
+ case "grep":
431
+ return sessionEvent("tool_call", {
432
+ ...base,
433
+ pattern: String(input.pattern ?? ""),
434
+ path: String(input.path ?? ""),
435
+ });
436
+ default:
437
+ return sessionEvent("tool_call", {
438
+ ...base,
439
+ input_summary: truncate(input, PAYLOAD_SUMMARY_MAX_CHARS),
440
+ });
441
+ }
442
+ }
443
+ /**
444
+ * Batches session events and owns the captured session's lifecycle (§2.3).
445
+ *
446
+ * Why batching: a chatty turn emits an event per text block and per tool call.
447
+ * One HTTP request each would put the runtime's throughput at the mercy of
448
+ * network latency and would trip the server's per-session rate cap on volume
449
+ * that is really one turn. Events are flushed when `maxBatch` accumulates, when
450
+ * `flushIntervalMs` elapses, and unconditionally at turn end and session end, so
451
+ * the tail of a conversation is never left sitting in the buffer.
452
+ *
453
+ * Why lazy open: the session is created on the first event rather than at
454
+ * construction, so an idle employee (the common case — the runtime blocks on the
455
+ * turn queue) creates nothing, and a runtime that crash-loops before producing
456
+ * output does not create a session per retry.
457
+ *
458
+ * Everything here is fail-soft, matching `sessionCapture.ts`: a failed create
459
+ * degrades the whole session to uncaptured (`failed` state, no retry storm), a
460
+ * failed post drops that batch, and no method ever throws. Capture is
461
+ * observability; it must never take down real work.
462
+ */
463
+ export class SessionEventEmitter {
464
+ transport;
465
+ enabled;
466
+ maxBatch;
467
+ flushIntervalMs;
468
+ maxPending;
469
+ onOpen;
470
+ log;
471
+ pending = [];
472
+ state = "idle";
473
+ openSessionId = null;
474
+ timer = null;
475
+ chain = Promise.resolve();
476
+ dropped = 0;
477
+ dropWarned = false;
478
+ constructor(opts) {
479
+ this.transport = opts.transport;
480
+ this.enabled = opts.enabled;
481
+ this.maxBatch = Math.max(1, opts.maxBatch ?? 25);
482
+ this.flushIntervalMs = Math.max(1, opts.flushIntervalMs ?? 1000);
483
+ this.maxPending = Math.max(1, opts.maxPending ?? 1000);
484
+ this.onOpen = opts.onOpen;
485
+ this.log = opts.log ?? (() => { });
486
+ }
487
+ /** The session events are being recorded under, or `null` before/after capture. */
488
+ get currentSessionId() {
489
+ return this.openSessionId;
490
+ }
491
+ get pendingCount() {
492
+ return this.pending.length;
493
+ }
494
+ get droppedCount() {
495
+ return this.dropped;
496
+ }
497
+ /** Queue events. Synchronous and non-throwing — safe to call from the stream loop. */
498
+ emit(events) {
499
+ if (!this.enabled || events.length === 0)
500
+ return;
501
+ if (this.state === "failed" || this.state === "closed")
502
+ return;
503
+ for (const ev of events) {
504
+ if (this.pending.length >= this.maxPending) {
505
+ this.dropped++;
506
+ if (!this.dropWarned) {
507
+ this.dropWarned = true;
508
+ this.log(`session capture: event backlog exceeded ${this.maxPending} — dropping events ` +
509
+ `(the shift continues; capture is lossy under backpressure by design)`);
510
+ }
511
+ continue;
512
+ }
513
+ this.pending.push(ev);
514
+ }
515
+ if (this.pending.length >= this.maxBatch) {
516
+ void this.drain();
517
+ return;
518
+ }
519
+ this.schedule();
520
+ }
521
+ /** Send everything pending now. Awaits the in-flight post; never throws. */
522
+ async flush() {
523
+ this.clearTimer();
524
+ await this.drain();
525
+ }
526
+ /**
527
+ * Flush the tail and close the captured session. After this the emitter is
528
+ * inert — a late `emit` from a straggling stream message is discarded rather
529
+ * than reopening a session nobody is watching.
530
+ */
531
+ async end(reason) {
532
+ if (!this.enabled || this.state === "closed")
533
+ return;
534
+ await this.flush();
535
+ const sessionId = this.openSessionId;
536
+ this.state = "closed";
537
+ this.openSessionId = null;
538
+ this.clearTimer();
539
+ if (sessionId !== null) {
540
+ try {
541
+ await this.transport.close(sessionId, reason);
542
+ }
543
+ catch (e) {
544
+ this.log(`session capture: terminate failed (${errText(e)}) — session left open server-side`);
545
+ }
546
+ }
547
+ if (this.dropped > 0) {
548
+ this.log(`session capture: ${this.dropped} event(s) dropped under backpressure this session`);
549
+ }
550
+ }
551
+ schedule() {
552
+ if (this.timer !== null)
553
+ return;
554
+ this.timer = setTimeout(() => {
555
+ this.timer = null;
556
+ void this.drain();
557
+ }, this.flushIntervalMs);
558
+ // Metrics/observability must never keep the process alive.
559
+ this.timer.unref?.();
560
+ }
561
+ clearTimer() {
562
+ if (this.timer !== null) {
563
+ clearTimeout(this.timer);
564
+ this.timer = null;
565
+ }
566
+ }
567
+ /** Serialized: posts must not race, or the server assigns sequence numbers out of order. */
568
+ drain() {
569
+ // The .catch is load-bearing: without it one rejection poisons `chain`
570
+ // forever, and every later `void this.drain()` becomes an unhandled
571
+ // rejection in a process that runs for weeks. drainOnce is written not to
572
+ // throw; this is the belt to that braces.
573
+ this.chain = this.chain
574
+ .then(() => this.drainOnce())
575
+ .catch((e) => this.log(`session capture: drain failed (${errText(e)}) — capture continues`));
576
+ return this.chain;
577
+ }
578
+ async drainOnce() {
579
+ if (this.pending.length === 0)
580
+ return;
581
+ if (!this.enabled || this.state === "failed" || this.state === "closed") {
582
+ this.pending = [];
583
+ return;
584
+ }
585
+ if (this.state === "idle") {
586
+ let sessionId = null;
587
+ try {
588
+ sessionId = await this.transport.open();
589
+ }
590
+ catch (e) {
591
+ this.log(`session capture: create threw (${errText(e)}) — shift runs without capture`);
592
+ }
593
+ if (sessionId === null || sessionId === "") {
594
+ // One attempt only. Retrying per batch would hammer a server that is
595
+ // already failing, for an observability feature.
596
+ this.state = "failed";
597
+ this.pending = [];
598
+ return;
599
+ }
600
+ this.openSessionId = sessionId;
601
+ this.state = "open";
602
+ // Fires exactly once per session, before the first batch is posted. The
603
+ // try/catch is not defensive habit: the listener is steering, and a broken
604
+ // steering path must cost the shift its steerability, never its capture.
605
+ try {
606
+ this.onOpen?.(sessionId);
607
+ }
608
+ catch (e) {
609
+ this.log(`session capture: onOpen listener threw (${errText(e)}) — capture continues`);
610
+ }
611
+ }
612
+ const batch = this.pending;
613
+ this.pending = [];
614
+ try {
615
+ await this.transport.post(this.openSessionId, batch);
616
+ }
617
+ catch (e) {
618
+ // Dropped, not requeued: a retry queue behind a down server grows without
619
+ // bound in a process that runs for weeks.
620
+ this.log(`session capture: posting ${batch.length} event(s) failed (${errText(e)}) — batch dropped`);
621
+ }
622
+ }
623
+ }
624
+ /** Same shape as `sessionCapture.ts`'s internal helper — errors are logged, never thrown. */
625
+ function errText(e) {
626
+ return e instanceof Error ? e.message : String(e);
627
+ }
155
628
  //# sourceMappingURL=streamingRuntimeLib.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"streamingRuntimeLib.js","sourceRoot":"","sources":["../src/streamingRuntimeLib.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"streamingRuntimeLib.js","sourceRoot":"","sources":["../src/streamingRuntimeLib.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,8 @@
1
1
  import { describe, it, expect } from "vitest";
2
- import { streamingEnabled, assertSubscriptionAuth, decideInbound, buildTurnContent, toUserTurn, shouldRecycle, defaultRecycleOptions, newRuntimeStats, recordResultUsage, formatUsageLine, inSessionMcpEnv, assertWorkerIdentityReady, } from "./streamingRuntimeLib.js";
2
+ import { streamingEnabled, assertSubscriptionAuth, decideInbound, buildTurnContent, toUserTurn, shouldRecycle, defaultRecycleOptions, newRuntimeStats, recordResultUsage, formatUsageLine, inSessionMcpEnv, assertWorkerIdentityReady, SessionEventExtractor, SessionEventEmitter, } from "./streamingRuntimeLib.js";
3
+ import * as fs from "fs";
4
+ import * as path from "path";
5
+ import { fileURLToPath } from "url";
3
6
  // add-employee-streaming-runtime §2 — pure-helper tests.
4
7
  describe("streamingEnabled (kill switch §2.1)", () => {
5
8
  it("off by default / falsey", () => {
@@ -144,4 +147,87 @@ describe("assertWorkerIdentityReady (§3 fail-fast identity guard)", () => {
144
147
  expect(() => assertWorkerIdentityReady(true, "eng-ic-test")).not.toThrow();
145
148
  });
146
149
  });
150
+ // ---------------------------------------------------------------------------
151
+ // add-multiplayer-sessions §2 — session events.
152
+ //
153
+ // The behavioural suite for the extractor and emitter lives beside the runtime
154
+ // that uses them (employee-runtime/src/sessionEvents.test.ts). What matters here
155
+ // is that the canonical copy exposes the same API and the same behaviour, and
156
+ // that the two copies have not drifted (§2.4).
157
+ // ---------------------------------------------------------------------------
158
+ describe("SessionEventExtractor (canonical copy parity)", () => {
159
+ it("maps assistant text, tool_use, and tool_result onto the hook's vocabulary", () => {
160
+ const x = new SessionEventExtractor();
161
+ expect(x.extract({ type: "assistant", message: { content: [{ type: "text", text: "hi" }] } })[0].event_type).toBe("assistant_message");
162
+ expect(x.extract({
163
+ type: "assistant",
164
+ message: { content: [{ type: "tool_use", id: "t1", name: "Bash", input: { command: "ls" } }] },
165
+ })[0].event_type).toBe("command_exec");
166
+ const result = x.extract({
167
+ type: "user",
168
+ message: { content: [{ type: "tool_result", tool_use_id: "t1", content: "a.ts" }] },
169
+ })[0];
170
+ expect(result.event_type).toBe("tool_call");
171
+ expect(JSON.parse(result.payload)).toMatchObject({ tool_name: "Bash", result_summary: "a.ts" });
172
+ });
173
+ it("emits nothing for a result message — usage/recycle handling owns it", () => {
174
+ expect(new SessionEventExtractor().extract({ type: "result", usage: { input_tokens: 9 } })).toEqual([]);
175
+ });
176
+ });
177
+ describe("SessionEventEmitter (canonical copy parity)", () => {
178
+ const event = { event_type: "assistant_message", payload: "{}", token_count: 0 };
179
+ it("batches, then flushes the tail and closes on end()", async () => {
180
+ const posts = [];
181
+ const closes = [];
182
+ const emitter = new SessionEventEmitter({
183
+ enabled: true,
184
+ maxBatch: 100,
185
+ transport: {
186
+ open: async () => "sess-1",
187
+ post: async (_id, events) => void posts.push(events.length),
188
+ close: async (_id, reason) => void closes.push(reason),
189
+ },
190
+ });
191
+ for (let i = 0; i < 5; i++)
192
+ emitter.emit([event]);
193
+ expect(posts).toEqual([]);
194
+ await emitter.end("completed");
195
+ expect(posts).toEqual([5]);
196
+ expect(closes).toEqual(["completed"]);
197
+ });
198
+ it("is a hard no-op when capture is disabled", async () => {
199
+ let opened = 0;
200
+ const emitter = new SessionEventEmitter({
201
+ enabled: false,
202
+ transport: {
203
+ open: async () => {
204
+ opened++;
205
+ return "sess-1";
206
+ },
207
+ post: async () => { },
208
+ close: async () => { },
209
+ },
210
+ });
211
+ emitter.emit([event]);
212
+ await emitter.end("completed");
213
+ expect(opened).toBe(0);
214
+ });
215
+ });
216
+ describe("vendored copy stays in sync (§2.4)", () => {
217
+ // Comments and the file header are allowed to differ between the two copies;
218
+ // code is not. Strip comments and whitespace, then require an exact match.
219
+ const strip = (src) => src
220
+ .replace(/\/\*[\s\S]*?\*\//g, "")
221
+ .replace(/(^|\s)\/\/[^\n]*/g, "$1")
222
+ .split("\n")
223
+ .map((l) => l.trim())
224
+ .filter((l) => l !== "")
225
+ .join("\n");
226
+ const here = path.dirname(fileURLToPath(import.meta.url));
227
+ const canonical = path.join(here, "streamingRuntimeLib.ts");
228
+ const vendored = path.join(here, "..", "..", "employee-runtime", "src", "streamingRuntimeLib.ts");
229
+ it.skipIf(!fs.existsSync(vendored))("employee-runtime/src/streamingRuntimeLib.ts is code-identical to this one", () => {
230
+ expect(strip(fs.readFileSync(vendored, "utf8"))).toBe(strip(fs.readFileSync(canonical, "utf8")));
231
+ });
232
+ });
147
233
  //# sourceMappingURL=streamingRuntimeLib.test.js.map