@langchain/langgraph 1.3.4 → 1.3.5

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/index.cjs +4 -3
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.d.cts +2 -2
  4. package/dist/index.d.ts +2 -2
  5. package/dist/index.js +3 -3
  6. package/dist/index.js.map +1 -1
  7. package/dist/{setup/async_local_storage.cjs → node.cjs} +2 -2
  8. package/dist/node.cjs.map +1 -0
  9. package/dist/{setup/async_local_storage.js → node.js} +2 -2
  10. package/dist/node.js.map +1 -0
  11. package/dist/pregel/index.cjs +13 -12
  12. package/dist/pregel/index.cjs.map +1 -1
  13. package/dist/pregel/index.d.cts.map +1 -1
  14. package/dist/pregel/index.d.ts.map +1 -1
  15. package/dist/pregel/index.js +13 -12
  16. package/dist/pregel/index.js.map +1 -1
  17. package/dist/pregel/loop.cjs +19 -33
  18. package/dist/pregel/loop.cjs.map +1 -1
  19. package/dist/pregel/loop.js +19 -33
  20. package/dist/pregel/loop.js.map +1 -1
  21. package/dist/pregel/remote.cjs +1 -1
  22. package/dist/pregel/remote.cjs.map +1 -1
  23. package/dist/pregel/remote.d.cts +4 -3
  24. package/dist/pregel/remote.d.cts.map +1 -1
  25. package/dist/pregel/remote.d.ts +4 -3
  26. package/dist/pregel/remote.d.ts.map +1 -1
  27. package/dist/pregel/remote.js +1 -1
  28. package/dist/pregel/remote.js.map +1 -1
  29. package/dist/pregel/stream.cjs +12 -0
  30. package/dist/pregel/stream.cjs.map +1 -1
  31. package/dist/pregel/stream.d.cts +2 -24
  32. package/dist/pregel/stream.d.cts.map +1 -1
  33. package/dist/pregel/stream.d.ts +2 -24
  34. package/dist/pregel/stream.d.ts.map +1 -1
  35. package/dist/pregel/stream.js +12 -1
  36. package/dist/pregel/stream.js.map +1 -1
  37. package/dist/stream/convert.cjs +29 -23
  38. package/dist/stream/convert.cjs.map +1 -1
  39. package/dist/stream/convert.d.cts +9 -38
  40. package/dist/stream/convert.d.cts.map +1 -1
  41. package/dist/stream/convert.d.ts +9 -38
  42. package/dist/stream/convert.d.ts.map +1 -1
  43. package/dist/stream/convert.js +29 -24
  44. package/dist/stream/convert.js.map +1 -1
  45. package/dist/stream/index.cjs +1 -1
  46. package/dist/stream/index.d.cts +1 -1
  47. package/dist/stream/index.d.ts +1 -1
  48. package/dist/stream/index.js +1 -1
  49. package/dist/stream/mux.cjs +3 -4
  50. package/dist/stream/mux.cjs.map +1 -1
  51. package/dist/stream/mux.js +3 -4
  52. package/dist/stream/mux.js.map +1 -1
  53. package/dist/stream/types.d.cts +2 -2
  54. package/dist/stream/types.d.ts +2 -2
  55. package/dist/web.cjs +2 -1
  56. package/dist/web.d.cts +2 -2
  57. package/dist/web.d.ts +2 -2
  58. package/dist/web.js +2 -2
  59. package/package.json +13 -12
  60. package/dist/setup/async_local_storage.cjs.map +0 -1
  61. package/dist/setup/async_local_storage.js.map +0 -1
@@ -1,6 +1,5 @@
1
1
  import { Namespace, ProtocolEvent } from "./types.cjs";
2
2
  import { StreamMode } from "../pregel/types.cjs";
3
- import { StreamChunkMeta } from "../pregel/stream.cjs";
4
3
 
5
4
  //#region src/stream/convert.d.ts
6
5
  /**
@@ -13,57 +12,29 @@ import { StreamChunkMeta } from "../pregel/stream.cjs";
13
12
  *
14
13
  * The `"checkpoints"` mode is likewise excluded from the stream-mode
15
14
  * request because the protocol's `checkpoints` channel carries only a
16
- * lightweight envelope (`id`, `parent_id`, `step`, `source`) derived from
17
- * {@link StreamChunkMeta.checkpoint} on the adjacent `values` chunk — not
18
- * the full-state shape that Pregel's `checkpoints` stream mode produces.
19
- * `convertToProtocolEvent` emits a companion `checkpoints` protocol event
20
- * next to each `values` event when meta is present, so clients can build
21
- * branching/time-travel UIs without a full-state `checkpoints` subscription.
15
+ * lightweight envelope (`id`, `parent_id`, `step`, `source`) emitted as a
16
+ * separate ``[namespace, "checkpoints", envelope]`` chunk before each paired
17
+ * `values` chunk — not the full-state shape from Pregel's `checkpoints`
18
+ * stream mode when subscribed via `debug`.
22
19
  */
23
20
  declare const STREAM_EVENTS_V3_MODES: StreamMode[];
24
21
  /**
25
- * Converts a raw `[ns, mode, payload, meta?]` stream chunk emitted by
26
- * `graph.stream()` into one or more CDDL-aligned {@link ProtocolEvent}s.
27
- *
28
- * Most modes produce a single event. `values` chunks carrying
29
- * {@link StreamChunkMeta.checkpoint} additionally produce a companion
30
- * `checkpoints` event immediately after the `values` event, so clients
31
- * that subscribe only to `checkpoints` can build a branching timeline
32
- * without also paying for full-state `values` payloads, and clients that
33
- * subscribe to both can correlate the pair by `(namespace, step)` or by
34
- * adjacent `seq` numbers.
35
- *
36
- * Returns an empty array for stream modes that have no protocol mapping.
37
- *
38
- * @param options - Conversion inputs for a single raw stream chunk.
39
- * @param options.namespace - Hierarchical namespace path identifying the
40
- * source in the agent tree.
41
- * @param options.mode - The stream mode that produced this chunk (e.g.
42
- * `"messages"`, `"tools"`).
43
- * @param options.payload - The raw payload emitted by the stream for this
44
- * mode.
45
- * @param options.seq - Monotonically increasing sequence number assigned to
46
- * the first returned event; the companion `checkpoints` event (when
47
- * emitted) uses `seq + 1`.
48
- * @param options.meta - Optional chunk-level metadata (e.g. the checkpoint
49
- * envelope paired with a `values` chunk).
50
- * @returns An ordered list of {@link ProtocolEvent}s ready for downstream
51
- * reducers. Callers advance their `seq` counter by `result.length`.
22
+ * True when `payload` is a lightweight checkpoint envelope (not a full-state
23
+ * Pregel `checkpoints` debug payload).
52
24
  */
25
+ declare function isCheckpointEnvelope(payload: unknown): boolean;
53
26
  interface ConvertToProtocolEventOptions {
54
27
  namespace: Namespace;
55
28
  mode: StreamMode;
56
29
  payload: unknown;
57
30
  seq: number;
58
- meta?: StreamChunkMeta;
59
31
  }
60
32
  declare function convertToProtocolEvent({
61
33
  namespace: ns,
62
34
  mode,
63
35
  payload,
64
- seq,
65
- meta
36
+ seq
66
37
  }: ConvertToProtocolEventOptions): ProtocolEvent[];
67
38
  //#endregion
68
- export { ConvertToProtocolEventOptions, STREAM_EVENTS_V3_MODES, convertToProtocolEvent };
39
+ export { ConvertToProtocolEventOptions, STREAM_EVENTS_V3_MODES, convertToProtocolEvent, isCheckpointEnvelope };
69
40
  //# sourceMappingURL=convert.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"convert.d.cts","names":[],"sources":["../../src/stream/convert.ts"],"mappings":";;;;;;;;AAqEA;;;;;;;;;;;;;;cAtCa,sBAAA,EAAwB,UAAA;;;;AAsErC;;;;;;;;;;;;;;;;;;;;;;;;;;UAhCiB,6BAAA;EACf,SAAA,EAAW,SAAA;EACX,IAAA,EAAM,UAAA;EACN,OAAA;EACA,GAAA;EACA,IAAA,GAAO,eAAA;AAAA;AAAA,iBA2BO,sBAAA,CAAA;EACd,SAAA,EAAW,EAAA;EACX,IAAA;EACA,OAAA;EACA,GAAA;EACA;AAAA,GACC,6BAAA,GAAgC,aAAA"}
1
+ {"version":3,"file":"convert.d.cts","names":[],"sources":["../../src/stream/convert.ts"],"mappings":";;;;;;;AAyCA;;;;;AAWA;;;;;;;cAxBa,sBAAA,EAAwB,UAAA;;;;;iBAarB,oBAAA,CAAqB,OAAA;AAAA,UAWpB,6BAAA;EACf,SAAA,EAAW,SAAA;EACX,IAAA,EAAM,UAAA;EACN,OAAA;EACA,GAAA;AAAA;AAAA,iBA2Bc,sBAAA,CAAA;EACd,SAAA,EAAW,EAAA;EACX,IAAA;EACA,OAAA;EACA;AAAA,GACC,6BAAA,GAAgC,aAAA"}
@@ -1,6 +1,5 @@
1
1
  import { Namespace, ProtocolEvent } from "./types.js";
2
2
  import { StreamMode } from "../pregel/types.js";
3
- import { StreamChunkMeta } from "../pregel/stream.js";
4
3
 
5
4
  //#region src/stream/convert.d.ts
6
5
  /**
@@ -13,57 +12,29 @@ import { StreamChunkMeta } from "../pregel/stream.js";
13
12
  *
14
13
  * The `"checkpoints"` mode is likewise excluded from the stream-mode
15
14
  * request because the protocol's `checkpoints` channel carries only a
16
- * lightweight envelope (`id`, `parent_id`, `step`, `source`) derived from
17
- * {@link StreamChunkMeta.checkpoint} on the adjacent `values` chunk — not
18
- * the full-state shape that Pregel's `checkpoints` stream mode produces.
19
- * `convertToProtocolEvent` emits a companion `checkpoints` protocol event
20
- * next to each `values` event when meta is present, so clients can build
21
- * branching/time-travel UIs without a full-state `checkpoints` subscription.
15
+ * lightweight envelope (`id`, `parent_id`, `step`, `source`) emitted as a
16
+ * separate ``[namespace, "checkpoints", envelope]`` chunk before each paired
17
+ * `values` chunk — not the full-state shape from Pregel's `checkpoints`
18
+ * stream mode when subscribed via `debug`.
22
19
  */
23
20
  declare const STREAM_EVENTS_V3_MODES: StreamMode[];
24
21
  /**
25
- * Converts a raw `[ns, mode, payload, meta?]` stream chunk emitted by
26
- * `graph.stream()` into one or more CDDL-aligned {@link ProtocolEvent}s.
27
- *
28
- * Most modes produce a single event. `values` chunks carrying
29
- * {@link StreamChunkMeta.checkpoint} additionally produce a companion
30
- * `checkpoints` event immediately after the `values` event, so clients
31
- * that subscribe only to `checkpoints` can build a branching timeline
32
- * without also paying for full-state `values` payloads, and clients that
33
- * subscribe to both can correlate the pair by `(namespace, step)` or by
34
- * adjacent `seq` numbers.
35
- *
36
- * Returns an empty array for stream modes that have no protocol mapping.
37
- *
38
- * @param options - Conversion inputs for a single raw stream chunk.
39
- * @param options.namespace - Hierarchical namespace path identifying the
40
- * source in the agent tree.
41
- * @param options.mode - The stream mode that produced this chunk (e.g.
42
- * `"messages"`, `"tools"`).
43
- * @param options.payload - The raw payload emitted by the stream for this
44
- * mode.
45
- * @param options.seq - Monotonically increasing sequence number assigned to
46
- * the first returned event; the companion `checkpoints` event (when
47
- * emitted) uses `seq + 1`.
48
- * @param options.meta - Optional chunk-level metadata (e.g. the checkpoint
49
- * envelope paired with a `values` chunk).
50
- * @returns An ordered list of {@link ProtocolEvent}s ready for downstream
51
- * reducers. Callers advance their `seq` counter by `result.length`.
22
+ * True when `payload` is a lightweight checkpoint envelope (not a full-state
23
+ * Pregel `checkpoints` debug payload).
52
24
  */
25
+ declare function isCheckpointEnvelope(payload: unknown): boolean;
53
26
  interface ConvertToProtocolEventOptions {
54
27
  namespace: Namespace;
55
28
  mode: StreamMode;
56
29
  payload: unknown;
57
30
  seq: number;
58
- meta?: StreamChunkMeta;
59
31
  }
60
32
  declare function convertToProtocolEvent({
61
33
  namespace: ns,
62
34
  mode,
63
35
  payload,
64
- seq,
65
- meta
36
+ seq
66
37
  }: ConvertToProtocolEventOptions): ProtocolEvent[];
67
38
  //#endregion
68
- export { ConvertToProtocolEventOptions, STREAM_EVENTS_V3_MODES, convertToProtocolEvent };
39
+ export { ConvertToProtocolEventOptions, STREAM_EVENTS_V3_MODES, convertToProtocolEvent, isCheckpointEnvelope };
69
40
  //# sourceMappingURL=convert.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"convert.d.ts","names":[],"sources":["../../src/stream/convert.ts"],"mappings":";;;;;;;;AAqEA;;;;;;;;;;;;;;cAtCa,sBAAA,EAAwB,UAAA;;;;AAsErC;;;;;;;;;;;;;;;;;;;;;;;;;;UAhCiB,6BAAA;EACf,SAAA,EAAW,SAAA;EACX,IAAA,EAAM,UAAA;EACN,OAAA;EACA,GAAA;EACA,IAAA,GAAO,eAAA;AAAA;AAAA,iBA2BO,sBAAA,CAAA;EACd,SAAA,EAAW,EAAA;EACX,IAAA;EACA,OAAA;EACA,GAAA;EACA;AAAA,GACC,6BAAA,GAAgC,aAAA"}
1
+ {"version":3,"file":"convert.d.ts","names":[],"sources":["../../src/stream/convert.ts"],"mappings":";;;;;;;AAyCA;;;;;AAWA;;;;;;;cAxBa,sBAAA,EAAwB,UAAA;;;;;iBAarB,oBAAA,CAAqB,OAAA;AAAA,UAWpB,6BAAA;EACf,SAAA,EAAW,SAAA;EACX,IAAA,EAAM,UAAA;EACN,OAAA;EACA,GAAA;AAAA;AAAA,iBA2Bc,sBAAA,CAAA;EACd,SAAA,EAAW,EAAA;EACX,IAAA;EACA,OAAA;EACA;AAAA,GACC,6BAAA,GAAgC,aAAA"}
@@ -9,12 +9,10 @@
9
9
  *
10
10
  * The `"checkpoints"` mode is likewise excluded from the stream-mode
11
11
  * request because the protocol's `checkpoints` channel carries only a
12
- * lightweight envelope (`id`, `parent_id`, `step`, `source`) derived from
13
- * {@link StreamChunkMeta.checkpoint} on the adjacent `values` chunk — not
14
- * the full-state shape that Pregel's `checkpoints` stream mode produces.
15
- * `convertToProtocolEvent` emits a companion `checkpoints` protocol event
16
- * next to each `values` event when meta is present, so clients can build
17
- * branching/time-travel UIs without a full-state `checkpoints` subscription.
12
+ * lightweight envelope (`id`, `parent_id`, `step`, `source`) emitted as a
13
+ * separate ``[namespace, "checkpoints", envelope]`` chunk before each paired
14
+ * `values` chunk — not the full-state shape from Pregel's `checkpoints`
15
+ * stream mode when subscribed via `debug`.
18
16
  */
19
17
  const STREAM_EVENTS_V3_MODES = [
20
18
  "values",
@@ -24,6 +22,15 @@ const STREAM_EVENTS_V3_MODES = [
24
22
  "custom",
25
23
  "tasks"
26
24
  ];
25
+ /**
26
+ * True when `payload` is a lightweight checkpoint envelope (not a full-state
27
+ * Pregel `checkpoints` debug payload).
28
+ */
29
+ function isCheckpointEnvelope(payload) {
30
+ if (payload == null || typeof payload !== "object") return false;
31
+ const p = payload;
32
+ return typeof p.id === "string" && ("source" in p || typeof p.step === "number") && !("values" in p) && !("config" in p);
33
+ }
27
34
  function unwrapMessagesPayload(payload) {
28
35
  if (!Array.isArray(payload) || payload.length !== 2) return { data: payload };
29
36
  const [data, metadata] = payload;
@@ -39,7 +46,7 @@ function unwrapMessagesPayload(payload) {
39
46
  node
40
47
  };
41
48
  }
42
- function convertToProtocolEvent({ namespace: ns, mode, payload, seq, meta }) {
49
+ function convertToProtocolEvent({ namespace: ns, mode, payload, seq }) {
43
50
  const timestamp = Date.now();
44
51
  const base = { type: "event" };
45
52
  switch (mode) {
@@ -67,30 +74,28 @@ function convertToProtocolEvent({ namespace: ns, mode, payload, seq, meta }) {
67
74
  data: convertToolsPayload(payload)
68
75
  }
69
76
  }];
70
- case "values": {
71
- const events = [];
72
- if (meta?.checkpoint != null) events.push({
77
+ case "checkpoints":
78
+ if (!isCheckpointEnvelope(payload)) return [];
79
+ return [{
73
80
  ...base,
74
81
  seq,
75
82
  method: "checkpoints",
76
- params: {
77
- namespace: ns,
78
- timestamp,
79
- data: meta.checkpoint
80
- }
81
- });
82
- events.push({
83
- ...base,
84
- seq: meta?.checkpoint != null ? seq + 1 : seq,
85
- method: "values",
86
83
  params: {
87
84
  namespace: ns,
88
85
  timestamp,
89
86
  data: payload
90
87
  }
91
- });
92
- return events;
93
- }
88
+ }];
89
+ case "values": return [{
90
+ ...base,
91
+ seq,
92
+ method: "values",
93
+ params: {
94
+ namespace: ns,
95
+ timestamp,
96
+ data: payload
97
+ }
98
+ }];
94
99
  case "updates": {
95
100
  const data = convertUpdatesPayload(payload);
96
101
  return [{
@@ -201,6 +206,6 @@ function convertUpdatesPayload(payload) {
201
206
  };
202
207
  }
203
208
  //#endregion
204
- export { STREAM_EVENTS_V3_MODES, convertToProtocolEvent };
209
+ export { STREAM_EVENTS_V3_MODES, convertToProtocolEvent, isCheckpointEnvelope };
205
210
 
206
211
  //# sourceMappingURL=convert.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"convert.js","names":[],"sources":["../../src/stream/convert.ts"],"sourcesContent":["/**\n * Protocol event conversion — maps raw `[ns, mode, payload, meta?]` stream\n * chunks from graph.stream() to CDDL-aligned ProtocolEvents.\n */\n\nimport type { StreamMode } from \"../pregel/types.js\";\nimport type { StreamChunkMeta } from \"../pregel/stream.js\";\nimport type {\n Namespace,\n ProtocolEvent,\n ToolsEventData,\n UpdatesEventData,\n} from \"./types.js\";\n\n/**\n * The set of stream modes requested by\n * `streamEvents(..., { version: \"v3\" })` — every mode the protocol maps\n * to a channel.\n *\n * The verbose `\"debug\"` mode is intentionally excluded: it was a thin\n * re-wrap of `checkpoints` + `tasks` carrying no new information.\n *\n * The `\"checkpoints\"` mode is likewise excluded from the stream-mode\n * request because the protocol's `checkpoints` channel carries only a\n * lightweight envelope (`id`, `parent_id`, `step`, `source`) derived from\n * {@link StreamChunkMeta.checkpoint} on the adjacent `values` chunk — not\n * the full-state shape that Pregel's `checkpoints` stream mode produces.\n * `convertToProtocolEvent` emits a companion `checkpoints` protocol event\n * next to each `values` event when meta is present, so clients can build\n * branching/time-travel UIs without a full-state `checkpoints` subscription.\n */\nexport const STREAM_EVENTS_V3_MODES: StreamMode[] = [\n \"values\",\n \"updates\",\n \"messages\",\n \"tools\",\n \"custom\",\n \"tasks\",\n];\n\n/**\n * Converts a raw `[ns, mode, payload, meta?]` stream chunk emitted by\n * `graph.stream()` into one or more CDDL-aligned {@link ProtocolEvent}s.\n *\n * Most modes produce a single event. `values` chunks carrying\n * {@link StreamChunkMeta.checkpoint} additionally produce a companion\n * `checkpoints` event immediately after the `values` event, so clients\n * that subscribe only to `checkpoints` can build a branching timeline\n * without also paying for full-state `values` payloads, and clients that\n * subscribe to both can correlate the pair by `(namespace, step)` or by\n * adjacent `seq` numbers.\n *\n * Returns an empty array for stream modes that have no protocol mapping.\n *\n * @param options - Conversion inputs for a single raw stream chunk.\n * @param options.namespace - Hierarchical namespace path identifying the\n * source in the agent tree.\n * @param options.mode - The stream mode that produced this chunk (e.g.\n * `\"messages\"`, `\"tools\"`).\n * @param options.payload - The raw payload emitted by the stream for this\n * mode.\n * @param options.seq - Monotonically increasing sequence number assigned to\n * the first returned event; the companion `checkpoints` event (when\n * emitted) uses `seq + 1`.\n * @param options.meta - Optional chunk-level metadata (e.g. the checkpoint\n * envelope paired with a `values` chunk).\n * @returns An ordered list of {@link ProtocolEvent}s ready for downstream\n * reducers. Callers advance their `seq` counter by `result.length`.\n */\nexport interface ConvertToProtocolEventOptions {\n namespace: Namespace;\n mode: StreamMode;\n payload: unknown;\n seq: number;\n meta?: StreamChunkMeta;\n}\n\nfunction unwrapMessagesPayload(payload: unknown) {\n if (!Array.isArray(payload) || payload.length !== 2) {\n return { data: payload };\n }\n\n const [data, metadata] = payload;\n if (metadata == null || typeof metadata !== \"object\") {\n return { data: payload };\n }\n\n const record = metadata as Record<string, unknown>;\n const node =\n typeof record.langgraph_node === \"string\"\n ? record.langgraph_node\n : undefined;\n const runId = typeof record.run_id === \"string\" ? record.run_id : undefined;\n const dataWithRunId =\n runId != null && data != null && typeof data === \"object\"\n ? { ...(data as Record<string, unknown>), run_id: runId }\n : data;\n\n return { data: dataWithRunId, node };\n}\n\nexport function convertToProtocolEvent({\n namespace: ns,\n mode,\n payload,\n seq,\n meta,\n}: ConvertToProtocolEventOptions): ProtocolEvent[] {\n const timestamp = Date.now();\n const base = { type: \"event\" as const };\n\n switch (mode) {\n case \"messages\": {\n const { data, node } = unwrapMessagesPayload(payload);\n return [\n {\n ...base,\n seq,\n method: \"messages\",\n params: { namespace: ns, timestamp, ...(node ? { node } : {}), data },\n },\n ];\n }\n\n case \"tools\":\n return [\n {\n ...base,\n seq,\n method: \"tools\",\n params: {\n namespace: ns,\n timestamp,\n data: convertToolsPayload(payload),\n },\n },\n ];\n\n case \"values\": {\n // Emit the `checkpoints` event immediately BEFORE its companion\n // `values` event so clients subscribed to both channels have the\n // envelope buffered by the time the values payload arrives. This\n // lets the SDK attach `parentCheckpointId` to messages extracted\n // from the values snapshot without waiting for a second pass.\n const events: ProtocolEvent[] = [];\n if (meta?.checkpoint != null) {\n events.push({\n ...base,\n seq,\n method: \"checkpoints\",\n params: { namespace: ns, timestamp, data: meta.checkpoint },\n });\n }\n events.push({\n ...base,\n seq: meta?.checkpoint != null ? seq + 1 : seq,\n method: \"values\",\n params: { namespace: ns, timestamp, data: payload },\n });\n return events;\n }\n\n case \"updates\": {\n const data = convertUpdatesPayload(payload);\n return [\n {\n ...base,\n seq,\n method: \"updates\",\n params: {\n namespace: ns,\n timestamp,\n // Surface the completed node at the top level of `params` so\n // transformers (notably `LifecycleTransformer`) can attribute\n // a finished task to its child namespace without re-parsing\n // the payload. The same value is retained inside `data` for\n // downstream consumers that inspect the event body.\n ...(typeof data.node === \"string\" ? { node: data.node } : {}),\n data,\n },\n },\n ];\n }\n\n case \"custom\": {\n const data =\n typeof payload === \"object\" &&\n payload !== null &&\n !Array.isArray(payload) &&\n \"name\" in payload\n ? payload\n : { payload };\n return [\n {\n ...base,\n seq,\n method: \"custom\",\n params: { namespace: ns, timestamp, data },\n },\n ];\n }\n\n case \"tasks\":\n return [\n {\n ...base,\n seq,\n method: \"tasks\",\n params: { namespace: ns, timestamp, data: payload },\n },\n ];\n\n default:\n return [];\n }\n}\n\n/**\n * Normalises a raw tools-mode payload into a typed {@link ToolsEventData}\n * discriminated union, mapping internal lifecycle events (`on_tool_start`,\n * `on_tool_end`, etc.) to their protocol counterparts.\n *\n * @param payload - The raw payload from a `\"tools\"` stream chunk.\n * @returns A {@link ToolsEventData} object with the appropriate `event`\n * discriminant and associated fields.\n */\nfunction convertToolsPayload(payload: unknown): ToolsEventData {\n if (typeof payload !== \"object\" || payload === null) {\n return {\n event: \"tool-error\",\n tool_call_id: \"\",\n message: \"Unexpected tools payload shape\",\n };\n }\n\n const p = payload as Record<string, unknown>;\n const tool_call_id = String(p.toolCallId ?? \"\");\n\n switch (p.event) {\n case \"on_tool_start\":\n return {\n event: \"tool-started\",\n tool_call_id,\n tool_name: String(p.name ?? \"unknown\"),\n input: p.input,\n };\n\n case \"on_tool_event\": {\n const delta =\n typeof p.data === \"string\" ? p.data : JSON.stringify(p.data ?? \"\");\n return {\n event: \"tool-output-delta\",\n tool_call_id,\n delta,\n };\n }\n\n case \"on_tool_end\":\n return {\n event: \"tool-finished\",\n tool_call_id,\n output: p.output,\n };\n\n case \"on_tool_error\": {\n const err = p.error;\n const errMessage =\n typeof err === \"object\" &&\n err !== null &&\n \"message\" in err &&\n typeof (err as { message: unknown }).message === \"string\"\n ? (err as { message: string }).message\n : String(err ?? \"unknown error\");\n return {\n event: \"tool-error\",\n tool_call_id,\n message: errMessage,\n };\n }\n\n default:\n return {\n event: \"tool-error\",\n tool_call_id: \"\",\n message: `Unknown tool event: ${String(p.event)}`,\n };\n }\n}\n\n/**\n * Extracts the first `{node: delta}` entry from an updates-mode payload and\n * reshapes it into an {@link UpdatesEventData} with explicit `node` and\n * `values` fields. Non-object payloads are coerced to `{ values: {} }`.\n *\n * @param payload - The raw payload from an `\"updates\"` stream chunk,\n * expected to be a `Record<string, unknown>` keyed by node name.\n * @returns An {@link UpdatesEventData} containing the extracted node name\n * and its associated delta values.\n */\nfunction convertUpdatesPayload(payload: unknown): UpdatesEventData {\n if (typeof payload !== \"object\" || payload === null) {\n return { values: {} };\n }\n\n const entries = Object.entries(payload as Record<string, unknown>);\n if (entries.length === 0) {\n return { values: {} };\n }\n\n const [node, values] = entries[0];\n return {\n node,\n values: (typeof values === \"object\" && values !== null\n ? values\n : { value: values }) as Record<string, unknown>,\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"convert.js","names":[],"sources":["../../src/stream/convert.ts"],"sourcesContent":["/**\n * Protocol event conversion — maps raw `[ns, mode, payload]` stream chunks\n * from graph.stream() to CDDL-aligned ProtocolEvents.\n */\n\nimport type { StreamMode } from \"../pregel/types.js\";\nimport type {\n Namespace,\n ProtocolEvent,\n ToolsEventData,\n UpdatesEventData,\n} from \"./types.js\";\n\n/**\n * The set of stream modes requested by\n * `streamEvents(..., { version: \"v3\" })` — every mode the protocol maps\n * to a channel.\n *\n * The verbose `\"debug\"` mode is intentionally excluded: it was a thin\n * re-wrap of `checkpoints` + `tasks` carrying no new information.\n *\n * The `\"checkpoints\"` mode is likewise excluded from the stream-mode\n * request because the protocol's `checkpoints` channel carries only a\n * lightweight envelope (`id`, `parent_id`, `step`, `source`) emitted as a\n * separate ``[namespace, \"checkpoints\", envelope]`` chunk before each paired\n * `values` chunk — not the full-state shape from Pregel's `checkpoints`\n * stream mode when subscribed via `debug`.\n */\nexport const STREAM_EVENTS_V3_MODES: StreamMode[] = [\n \"values\",\n \"updates\",\n \"messages\",\n \"tools\",\n \"custom\",\n \"tasks\",\n];\n\n/**\n * True when `payload` is a lightweight checkpoint envelope (not a full-state\n * Pregel `checkpoints` debug payload).\n */\nexport function isCheckpointEnvelope(payload: unknown): boolean {\n if (payload == null || typeof payload !== \"object\") return false;\n const p = payload as Record<string, unknown>;\n return (\n typeof p.id === \"string\" &&\n (\"source\" in p || typeof p.step === \"number\") &&\n !(\"values\" in p) &&\n !(\"config\" in p)\n );\n}\n\nexport interface ConvertToProtocolEventOptions {\n namespace: Namespace;\n mode: StreamMode;\n payload: unknown;\n seq: number;\n}\n\nfunction unwrapMessagesPayload(payload: unknown) {\n if (!Array.isArray(payload) || payload.length !== 2) {\n return { data: payload };\n }\n\n const [data, metadata] = payload;\n if (metadata == null || typeof metadata !== \"object\") {\n return { data: payload };\n }\n\n const record = metadata as Record<string, unknown>;\n const node =\n typeof record.langgraph_node === \"string\"\n ? record.langgraph_node\n : undefined;\n const runId = typeof record.run_id === \"string\" ? record.run_id : undefined;\n const dataWithRunId =\n runId != null && data != null && typeof data === \"object\"\n ? { ...(data as Record<string, unknown>), run_id: runId }\n : data;\n\n return { data: dataWithRunId, node };\n}\n\nexport function convertToProtocolEvent({\n namespace: ns,\n mode,\n payload,\n seq,\n}: ConvertToProtocolEventOptions): ProtocolEvent[] {\n const timestamp = Date.now();\n const base = { type: \"event\" as const };\n\n switch (mode) {\n case \"messages\": {\n const { data, node } = unwrapMessagesPayload(payload);\n return [\n {\n ...base,\n seq,\n method: \"messages\",\n params: { namespace: ns, timestamp, ...(node ? { node } : {}), data },\n },\n ];\n }\n\n case \"tools\":\n return [\n {\n ...base,\n seq,\n method: \"tools\",\n params: {\n namespace: ns,\n timestamp,\n data: convertToolsPayload(payload),\n },\n },\n ];\n\n case \"checkpoints\": {\n if (!isCheckpointEnvelope(payload)) {\n return [];\n }\n return [\n {\n ...base,\n seq,\n method: \"checkpoints\",\n params: { namespace: ns, timestamp, data: payload },\n },\n ];\n }\n\n case \"values\": {\n return [\n {\n ...base,\n seq,\n method: \"values\",\n params: { namespace: ns, timestamp, data: payload },\n },\n ];\n }\n\n case \"updates\": {\n const data = convertUpdatesPayload(payload);\n return [\n {\n ...base,\n seq,\n method: \"updates\",\n params: {\n namespace: ns,\n timestamp,\n // Surface the completed node at the top level of `params` so\n // transformers (notably `LifecycleTransformer`) can attribute\n // a finished task to its child namespace without re-parsing\n // the payload. The same value is retained inside `data` for\n // downstream consumers that inspect the event body.\n ...(typeof data.node === \"string\" ? { node: data.node } : {}),\n data,\n },\n },\n ];\n }\n\n case \"custom\": {\n const data =\n typeof payload === \"object\" &&\n payload !== null &&\n !Array.isArray(payload) &&\n \"name\" in payload\n ? payload\n : { payload };\n return [\n {\n ...base,\n seq,\n method: \"custom\",\n params: { namespace: ns, timestamp, data },\n },\n ];\n }\n\n case \"tasks\":\n return [\n {\n ...base,\n seq,\n method: \"tasks\",\n params: { namespace: ns, timestamp, data: payload },\n },\n ];\n\n default:\n return [];\n }\n}\n\n/**\n * Normalises a raw tools-mode payload into a typed {@link ToolsEventData}\n * discriminated union, mapping internal lifecycle events (`on_tool_start`,\n * `on_tool_end`, etc.) to their protocol counterparts.\n *\n * @param payload - The raw payload from a `\"tools\"` stream chunk.\n * @returns A {@link ToolsEventData} object with the appropriate `event`\n * discriminant and associated fields.\n */\nfunction convertToolsPayload(payload: unknown): ToolsEventData {\n if (typeof payload !== \"object\" || payload === null) {\n return {\n event: \"tool-error\",\n tool_call_id: \"\",\n message: \"Unexpected tools payload shape\",\n };\n }\n\n const p = payload as Record<string, unknown>;\n const tool_call_id = String(p.toolCallId ?? \"\");\n\n switch (p.event) {\n case \"on_tool_start\":\n return {\n event: \"tool-started\",\n tool_call_id,\n tool_name: String(p.name ?? \"unknown\"),\n input: p.input,\n };\n\n case \"on_tool_event\": {\n const delta =\n typeof p.data === \"string\" ? p.data : JSON.stringify(p.data ?? \"\");\n return {\n event: \"tool-output-delta\",\n tool_call_id,\n delta,\n };\n }\n\n case \"on_tool_end\":\n return {\n event: \"tool-finished\",\n tool_call_id,\n output: p.output,\n };\n\n case \"on_tool_error\": {\n const err = p.error;\n const errMessage =\n typeof err === \"object\" &&\n err !== null &&\n \"message\" in err &&\n typeof (err as { message: unknown }).message === \"string\"\n ? (err as { message: string }).message\n : String(err ?? \"unknown error\");\n return {\n event: \"tool-error\",\n tool_call_id,\n message: errMessage,\n };\n }\n\n default:\n return {\n event: \"tool-error\",\n tool_call_id: \"\",\n message: `Unknown tool event: ${String(p.event)}`,\n };\n }\n}\n\n/**\n * Extracts the first `{node: delta}` entry from an updates-mode payload and\n * reshapes it into an {@link UpdatesEventData} with explicit `node` and\n * `values` fields. Non-object payloads are coerced to `{ values: {} }`.\n *\n * @param payload - The raw payload from an `\"updates\"` stream chunk,\n * expected to be a `Record<string, unknown>` keyed by node name.\n * @returns An {@link UpdatesEventData} containing the extracted node name\n * and its associated delta values.\n */\nfunction convertUpdatesPayload(payload: unknown): UpdatesEventData {\n if (typeof payload !== \"object\" || payload === null) {\n return { values: {} };\n }\n\n const entries = Object.entries(payload as Record<string, unknown>);\n if (entries.length === 0) {\n return { values: {} };\n }\n\n const [node, values] = entries[0];\n return {\n node,\n values: (typeof values === \"object\" && values !== null\n ? values\n : { value: values }) as Record<string, unknown>,\n };\n}\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
- require("./stream-channel.cjs");
2
1
  require("./convert.cjs");
2
+ require("./stream-channel.cjs");
3
3
  require("./mux.cjs");
4
4
  require("./transformers/lifecycle.cjs");
5
5
  require("./transformers/messages.cjs");
@@ -1,6 +1,6 @@
1
1
  import { AgentStatus, ChatModelStream as ChatModelStream$1, InferExtensions, InterruptPayload, LifecycleCause, LifecycleData, MessagesEventData, Namespace, NativeStreamTransformer, ProtocolEvent, StreamEmitter, StreamTransformer, ToolCallStatus, ToolCallStream, ToolsEventData, UpdatesEventData, UsageInfo, isNativeTransformer } from "./types.cjs";
2
2
  import { StreamChannel } from "./stream-channel.cjs";
3
- import { ConvertToProtocolEventOptions, STREAM_EVENTS_V3_MODES, convertToProtocolEvent } from "./convert.cjs";
3
+ import { ConvertToProtocolEventOptions, STREAM_EVENTS_V3_MODES, convertToProtocolEvent, isCheckpointEnvelope } from "./convert.cjs";
4
4
  import { REJECT_VALUES, RESOLVE_VALUES, StreamHandle, StreamMux, SubgraphDiscovery } from "./mux.cjs";
5
5
  import { LifecycleEntry, LifecycleTransformerOptions } from "./transformers/types.cjs";
6
6
  import { LifecycleProjection, createLifecycleTransformer, filterLifecycleEntries } from "./transformers/lifecycle.cjs";
@@ -1,6 +1,6 @@
1
1
  import { AgentStatus, ChatModelStream as ChatModelStream$1, InferExtensions, InterruptPayload, LifecycleCause, LifecycleData, MessagesEventData, Namespace, NativeStreamTransformer, ProtocolEvent, StreamEmitter, StreamTransformer, ToolCallStatus, ToolCallStream, ToolsEventData, UpdatesEventData, UsageInfo, isNativeTransformer } from "./types.js";
2
2
  import { StreamChannel } from "./stream-channel.js";
3
- import { ConvertToProtocolEventOptions, STREAM_EVENTS_V3_MODES, convertToProtocolEvent } from "./convert.js";
3
+ import { ConvertToProtocolEventOptions, STREAM_EVENTS_V3_MODES, convertToProtocolEvent, isCheckpointEnvelope } from "./convert.js";
4
4
  import { REJECT_VALUES, RESOLVE_VALUES, StreamHandle, StreamMux, SubgraphDiscovery } from "./mux.js";
5
5
  import { LifecycleEntry, LifecycleTransformerOptions } from "./transformers/types.js";
6
6
  import { LifecycleProjection, createLifecycleTransformer, filterLifecycleEntries } from "./transformers/lifecycle.js";
@@ -1,5 +1,5 @@
1
- import "./stream-channel.js";
2
1
  import "./convert.js";
2
+ import "./stream-channel.js";
3
3
  import "./mux.js";
4
4
  import "./transformers/lifecycle.js";
5
5
  import "./transformers/messages.js";
@@ -1,6 +1,6 @@
1
1
  const require_constants = require("../constants.cjs");
2
- const require_stream_channel = require("./stream-channel.cjs");
3
2
  const require_convert = require("./convert.cjs");
3
+ const require_stream_channel = require("./stream-channel.cjs");
4
4
  //#region src/stream/mux.ts
5
5
  /**
6
6
  * Structural `PromiseLike<T>` predicate — true for thenables including
@@ -293,7 +293,7 @@ async function pump(source, mux) {
293
293
  let seq = 0;
294
294
  try {
295
295
  for await (const chunk of source) {
296
- const [ns, mode, payload, meta] = chunk;
296
+ const [ns, mode, payload] = chunk;
297
297
  if (mode === "values" && require_constants.isInterrupted(payload)) {
298
298
  const interrupts = payload[require_constants.INTERRUPT];
299
299
  mux.markInterrupted(interrupts.map((i) => ({
@@ -305,8 +305,7 @@ async function pump(source, mux) {
305
305
  namespace: ns,
306
306
  mode,
307
307
  payload,
308
- seq,
309
- meta
308
+ seq
310
309
  });
311
310
  seq += events.length;
312
311
  for (const event of events) mux.push(ns, event);
@@ -1 +1 @@
1
- {"version":3,"file":"mux.cjs","names":["StreamChannel","#transformers","#channels","#streamMap","#latestValues","#interrupts","#finalValues","#closed","#error","isStreamChannel","#nextEmitSeq","#currentNamespace","#interrupted","isInterrupted","INTERRUPT","convertToProtocolEvent"],"sources":["../../src/stream/mux.ts"],"sourcesContent":["/**\n * StreamMux — central dispatcher with transformer pipeline.\n *\n * Routes raw stream chunks through registered StreamTransformers, then appends\n * the resulting ProtocolEvents to the main local channel. Also tracks\n * namespace discovery for SubgraphRunStream creation.\n *\n * lifecycle:\n * graph.streamEvents(input, { version: \"v3\" })\n * ├─ StreamMux starts pumping from graph.stream(…, { subgraphs: true })\n * ├─ For each ProtocolEvent:\n * │ ├─ transformer_1.process(event)\n * │ ├─ transformer_2.process(event)\n * │ └─ event appended to _events (unless suppressed)\n * └─ On close: transformer_n.finalize() called in registration order\n */\n\nimport type { StreamChunk } from \"../pregel/stream.js\";\nimport { INTERRUPT, isInterrupted, type Interrupt } from \"../constants.js\";\nimport { convertToProtocolEvent, STREAM_EVENTS_V3_MODES } from \"./convert.js\";\nimport { StreamChannel, isStreamChannel } from \"./stream-channel.js\";\nimport type {\n InterruptPayload,\n Namespace,\n ProtocolEvent,\n StreamEmitter,\n StreamTransformer,\n} from \"./types.js\";\n\nexport { STREAM_EVENTS_V3_MODES };\n\n/**\n * Structural `PromiseLike<T>` predicate — true for thenables including\n * native promises, user-constructed `{ then }` objects, and helper\n * wrappers. Used by {@link StreamMux.wireChannels} to detect final-value\n * projections distinctly from streaming `StreamChannel` values.\n */\nfunction isPromiseLike(value: unknown): value is PromiseLike<unknown> {\n return (\n value != null &&\n (typeof value === \"object\" || typeof value === \"function\") &&\n typeof (value as { then?: unknown }).then === \"function\"\n );\n}\n\n/**\n * Symbol key used by {@link StreamMux} to resolve the values promise on a\n * stream handle. Using a symbol keeps this off the public autocomplete surface.\n */\nexport const RESOLVE_VALUES: unique symbol = Symbol(\"resolveValues\");\n\n/**\n * Symbol key used by {@link StreamMux} to reject the values promise on a\n * stream handle. Using a symbol keeps this off the public autocomplete surface.\n */\nexport const REJECT_VALUES: unique symbol = Symbol(\"rejectValues\");\n\n/**\n * Minimal interface that {@link StreamMux} requires from stream handles\n * for lifecycle resolution. This avoids a direct dependency on\n * `GraphRunStream` / `SubgraphRunStream`.\n */\nexport interface StreamHandle {\n [RESOLVE_VALUES](values: unknown): void;\n [REJECT_VALUES](err: unknown): void;\n}\n\n/**\n * Factory function that creates a subgraph stream handle for a newly\n * discovered namespace.\n *\n * Historically consumed by {@link StreamMux} at construction time;\n * today factories are consumed by\n * `createSubgraphDiscoveryTransformer` (via its `createStream`\n * option). This shape is retained for consumers that still thread a\n * mux reference through the factory — the narrower transformer\n * option omits `mux` because it captures the mux in a closure.\n */\nexport type SubgraphStreamFactory = (\n path: Namespace,\n mux: StreamMux,\n discoveryStart: number,\n eventStart: number\n) => StreamHandle;\n\n/**\n * A discovered subgraph namespace paired with its run stream handle.\n */\nexport type SubgraphDiscovery = {\n ns: Namespace;\n stream: StreamHandle;\n};\n\n/**\n * Central event dispatcher that routes {@link ProtocolEvent}s through a\n * pipeline of {@link StreamTransformer}s, manages namespace discovery for\n * subgraph streams, and exposes async iteration over filtered event\n * sequences.\n *\n * One `StreamMux` instance exists per top-level\n * `streamEvents(..., { version: \"v3\" })` invocation.\n */\nexport class StreamMux {\n /** @internal All protocol events in arrival order (after reducer pipeline). */\n readonly _events = StreamChannel.local<ProtocolEvent>();\n\n /** @internal New-namespace discovery notifications. */\n readonly _discoveries = StreamChannel.local<SubgraphDiscovery>();\n\n /** Monotonic counter for auto-forwarded channel events. */\n #nextEmitSeq = 0;\n\n /** Whether the mux has been closed or failed. */\n #closed = false;\n\n /** The error passed to {@link fail}, if any. */\n #error: unknown;\n\n /** Whether the run was interrupted. */\n #interrupted = false;\n\n /**\n * Namespace of the event currently being processed by\n * {@link push}. Read by {@link StreamChannel} wiring callbacks so\n * auto-forwarded events inherit the triggering event's namespace.\n */\n #currentNamespace: Namespace = [];\n\n readonly #transformers: StreamTransformer<unknown>[] = [];\n readonly #channels: StreamChannel<unknown>[] = [];\n readonly #streamMap = new Map<string, StreamHandle>();\n readonly #latestValues = new Map<string, Record<string, unknown>>();\n readonly #interrupts: InterruptPayload[] = [];\n\n /**\n * Final-value projection keys tracked for remote surfacing. Populated\n * by {@link wireChannels} when a transformer's projection contains a\n * `PromiseLike` value. Each entry is flushed as a `custom:<name>`\n * protocol event during {@link close} so that remote clients can\n * observe final-value transformers via `thread.extensions.<name>`.\n */\n readonly #finalValues: Array<{ name: string; promise: Promise<unknown> }> =\n [];\n\n /**\n * Associates a pre-existing stream handle with a namespace so that\n * {@link close} can resolve its values promise later.\n *\n * @param path - The namespace path to register.\n * @param stream - The run stream handle for that namespace.\n */\n register(path: Namespace, stream: StreamHandle): void {\n this.#streamMap.set(nsKey(path), stream);\n }\n\n /**\n * Registers a transformer and replays all buffered events through it so\n * it catches up with events already processed by the mux. When the event\n * log is empty (typical at construction time) the replay is a no-op.\n *\n * The transformer must already have been initialised (i.e. `init()` called\n * and any projection wired). The sequence is:\n *\n * 1. Snapshot the current event log length.\n * 2. Append the transformer so future {@link push} calls reach it.\n * 3. Replay events `[0, snapshot)` through `process()`.\n * 4. If the mux is already closed, call `finalize()` (or `fail()`)\n * immediately so the transformer's log/channel terminates cleanly.\n *\n * @param transformer - An already-initialised transformer to register.\n */\n addTransformer(transformer: StreamTransformer<unknown>): void {\n const snapshot = this._events.size;\n this.#transformers.push(transformer);\n\n // Hand the transformer a narrow emitter handle *before* replay so\n // synthetic-emission transformers (e.g. deepagents\n // `SubagentTransformer`) can inject events into the mux during\n // their own `process()` calls — including the initial replay\n // triggered just below.\n if (transformer.onRegister) {\n const emitter: StreamEmitter = {\n // Transformer-originated events use a placeholder `seq` of\n // `0`. `push()` is the single authority for sequence numbers\n // and will re-stamp this event with the next monotonically\n // increasing value.\n push: (ns, event) => this.push(ns, event),\n };\n transformer.onRegister(emitter);\n }\n\n for (let i = 0; i < snapshot; i += 1) {\n transformer.process(this._events.get(i));\n }\n\n if (this.#closed) {\n if (this.#error !== undefined) {\n transformer.fail?.(this.#error);\n } else {\n transformer.finalize?.();\n }\n }\n }\n\n /**\n * Scans a transformer projection for streaming and final-value primitives.\n * Remote stream channels are wired to auto-forward to the protocol event\n * stream; local stream channels are tracked for lifecycle only.\n *\n * Two projection shapes are recognised:\n *\n * - {@link StreamChannel} values — named channels forward each `push()`\n * immediately as a protocol event on the channel's declared\n * `channelName` method. Unnamed channels remain in-process-only.\n *\n * - `PromiseLike<unknown>` values — tracked as final-value\n * projections and flushed on {@link close} as a single\n * `custom:<key>` event, where `<key>` is the projection key.\n * This mirrors the in-process `await run.extensions.<key>`\n * ergonomics on remote clients via\n * `await thread.extensions.<key>`.\n *\n * Plain values that are neither are ignored — they remain in-process-only,\n * matching prior behaviour.\n *\n * @param projection - The object returned by `transformer.init()`.\n */\n wireChannels(projection: Record<string, unknown>): void {\n for (const [key, value] of Object.entries(projection)) {\n if (isStreamChannel(value)) {\n this.#channels.push(value);\n if (typeof value.channelName !== \"string\") {\n continue;\n }\n value._wire((item: unknown) => {\n this._events.push({\n type: \"event\",\n seq: this.#nextEmitSeq++,\n method: value.channelName as ProtocolEvent[\"method\"],\n params: {\n namespace: this.#currentNamespace,\n timestamp: Date.now(),\n data: item,\n },\n });\n });\n continue;\n }\n if (isPromiseLike(value)) {\n this.#finalValues.push({\n name: key,\n promise: Promise.resolve(value),\n });\n }\n }\n }\n\n /**\n * Distributes an event through the transformer pipeline, then appends it to\n * the main event log.\n *\n * Subgraph discovery (materializing a {@link StreamHandle} for each\n * newly observed top-level namespace) is handled by the\n * {@link createSubgraphDiscoveryTransformer} when installed, not here.\n *\n * @param ns - The namespace path that produced the event.\n * @param event - The protocol event to process and store.\n */\n push(ns: Namespace, event: ProtocolEvent): void {\n if (event.method === \"values\") {\n this.#latestValues.set(\n nsKey(ns),\n event.params.data as Record<string, unknown>\n );\n }\n\n // Save the outer namespace so re-entrant `push()` calls (e.g. from\n // `StreamTransformer.onRegister` emitters synthesizing events\n // inside a transformer's `process()`) can set their own namespace\n // without clobbering the outer scope's `StreamChannel` routing\n // when control returns to the outer transformer loop.\n const outerNamespace = this.#currentNamespace;\n this.#currentNamespace = ns;\n\n let keep = true;\n for (const transformer of this.#transformers) {\n if (!transformer.process(event)) {\n keep = false;\n }\n }\n\n this.#currentNamespace = outerNamespace;\n\n if (keep) {\n // The mux is the single authority for sequence numbers. Callers\n // (the `pump`, transformer emitters, channel forwarders) pass a\n // placeholder `seq`; we re-stamp every event here so the log is\n // strictly monotonic across all origination paths. Stamping\n // happens *after* `process()` so that any channel-forwarded\n // events pushed during processing get earlier sequence numbers\n // than the triggering event, matching their in-order appearance\n // in `_events`.\n this._events.push({ ...event, seq: this.#nextEmitSeq++ });\n }\n }\n\n /**\n * Gracefully ends the stream: resolves values promises on all known\n * streams, finalizes every transformer, auto-closes streaming\n * channels, flushes any final-value projections as `custom:<name>`\n * events, and closes both event logs.\n *\n * When final-value projections are present, `_events.close()` is\n * deferred until every tracked projection promise has settled so\n * remote consumers observe the flushed values before their event\n * stream ends. Callers do not need to await — `close()` returns\n * synchronously and any downstream consumer iterating\n * {@link _events} naturally waits for the final events.\n */\n close(): void {\n this.#closed = true;\n for (const [key, values] of this.#latestValues.entries()) {\n const ns = key ? key.split(\"\\x00\") : [];\n const stream = this.#streamMap.get(nsKey(ns));\n stream?.[RESOLVE_VALUES](values);\n }\n\n const finalizePromises: PromiseLike<void>[] = [];\n for (const transformer of this.#transformers) {\n const result = transformer.finalize?.();\n if (\n result != null &&\n typeof (result as PromiseLike<void>).then === \"function\"\n ) {\n finalizePromises.push(result as PromiseLike<void>);\n }\n }\n\n for (const channel of this.#channels) {\n channel._close();\n }\n\n const finalValues = this.#finalValues;\n if (finalValues.length === 0 && finalizePromises.length === 0) {\n this._events.close();\n this._discoveries.close();\n } else {\n void Promise.allSettled([\n ...finalizePromises,\n ...finalValues.map(async ({ name, promise }) => {\n try {\n const resolved = await promise;\n if (!this._events.done) {\n this._events.push({\n type: \"event\",\n seq: this.#nextEmitSeq++,\n method: \"custom\",\n params: {\n namespace: [],\n timestamp: Date.now(),\n data: { name, payload: resolved },\n },\n });\n }\n } catch {\n // Rejected final-value projections are intentionally dropped\n // so a single failing extension can't poison the protocol\n // stream. The corresponding in-process Promise still\n // surfaces the rejection to its direct awaiters via the\n // transformer's own `fail()` hook.\n }\n }),\n ]).then(() => {\n this._events.close();\n this._discoveries.close();\n });\n }\n\n for (const stream of this.#streamMap.values()) {\n stream[RESOLVE_VALUES](undefined);\n }\n }\n\n /**\n * Propagates a failure to all transformers, channels, event logs, and\n * stream handles.\n *\n * @param err - The error that caused the run to fail.\n */\n fail(err: unknown): void {\n this.#closed = true;\n this.#error = err;\n for (const transformer of this.#transformers) {\n transformer.fail?.(err);\n }\n for (const channel of this.#channels) {\n channel._fail(err);\n }\n this._events.fail(err);\n this._discoveries.fail(err);\n for (const stream of this.#streamMap.values()) {\n stream[REJECT_VALUES](err);\n }\n }\n\n /**\n * Records that the run was interrupted, appending the supplied payloads\n * for later retrieval.\n *\n * @param interrupts - The interrupt payloads to store.\n */\n markInterrupted(interrupts: InterruptPayload[]): void {\n this.#interrupted = true;\n this.#interrupts.push(...interrupts);\n }\n\n /**\n * Whether the run ended due to an interrupt.\n *\n * @returns `true` if {@link markInterrupted} was called.\n */\n get interrupted(): boolean {\n return this.#interrupted;\n }\n\n /**\n * All interrupt payloads collected during the run.\n *\n * @returns A readonly view of the accumulated interrupt payloads.\n */\n get interrupts(): readonly InterruptPayload[] {\n return this.#interrupts;\n }\n\n /**\n * Returns an async iterator that yields only events whose namespace\n * starts with {@link path}.\n *\n * @param path - Namespace prefix to filter on.\n * @param startAt - Zero-based index into the event log to begin from.\n * @returns An async iterator over matching {@link ProtocolEvent}s.\n */\n subscribeEvents(path: Namespace, startAt = 0): AsyncIterator<ProtocolEvent> {\n const base = this._events.iterate(startAt);\n return {\n async next(): Promise<IteratorResult<ProtocolEvent>> {\n // eslint-disable-next-line no-constant-condition\n while (true) {\n const result = await base.next();\n if (result.done) return result;\n if (hasPrefix(result.value.params.namespace, path)) {\n return result;\n }\n }\n },\n };\n }\n}\n\n/**\n * Background consumer that drains a raw `graph.stream()` source into a\n * {@link StreamMux}. Converts each chunk to a {@link ProtocolEvent} and\n * pushes it; calls {@link StreamMux.close} on normal completion or\n * {@link StreamMux.fail} on error.\n *\n * @param source - The async iterable of raw stream chunks from the engine.\n * @param mux - The mux instance to feed.\n * @returns A promise that resolves when the source is fully consumed.\n */\nexport async function pump(\n source: AsyncIterable<StreamChunk>,\n mux: StreamMux\n): Promise<void> {\n let seq = 0;\n try {\n for await (const chunk of source) {\n const [ns, mode, payload, meta] = chunk;\n\n // Detect interrupt payloads attached to values-mode chunks.\n if (mode === \"values\" && isInterrupted(payload)) {\n const interrupts = (payload as { [INTERRUPT]: Interrupt[] })[INTERRUPT];\n mux.markInterrupted(\n interrupts.map((i) => ({\n interruptId: i.id ?? \"\",\n payload: i.value,\n }))\n );\n }\n\n const events = convertToProtocolEvent({\n namespace: ns,\n mode,\n payload,\n seq,\n meta,\n });\n seq += events.length;\n for (const event of events) {\n mux.push(ns, event);\n }\n }\n } catch (err) {\n mux.fail(err);\n return;\n }\n mux.close();\n}\n\n/**\n * Serialises a {@link Namespace} array into a single string key using the\n * null byte (`\\x00`) as separator, suitable for `Map`/`Set` lookups.\n *\n * @param ns - The namespace segments to join.\n * @returns A null-byte-joined string key.\n */\nexport function nsKey(ns: Namespace): string {\n return ns.join(\"\\x00\");\n}\n\n/**\n * Tests whether {@link ns} starts with every segment in {@link prefix}.\n *\n * @param ns - The full namespace to check.\n * @param prefix - The prefix to match against.\n * @returns `true` if `ns` begins with `prefix` segment-by-segment.\n */\nexport function hasPrefix(ns: Namespace, prefix: Namespace): boolean {\n if (prefix.length > ns.length) return false;\n for (let i = 0; i < prefix.length; i += 1) {\n if (ns[i] !== prefix[i]) return false;\n }\n return true;\n}\n"],"mappings":";;;;;;;;;;AAqCA,SAAS,cAAc,OAA+C;AACpE,QACE,SAAS,SACR,OAAO,UAAU,YAAY,OAAO,UAAU,eAC/C,OAAQ,MAA6B,SAAS;;;;;;AAQlD,MAAa,iBAAgC,OAAO,gBAAgB;;;;;AAMpE,MAAa,gBAA+B,OAAO,eAAe;;;;;;;;;;AA+ClE,IAAa,YAAb,MAAuB;;CAErB,UAAmBA,uBAAAA,cAAc,OAAsB;;CAGvD,eAAwBA,uBAAAA,cAAc,OAA0B;;CAGhE,eAAe;;CAGf,UAAU;;CAGV;;CAGA,eAAe;;;;;;CAOf,oBAA+B,EAAE;CAEjC,gBAAuD,EAAE;CACzD,YAA+C,EAAE;CACjD,6BAAsB,IAAI,KAA2B;CACrD,gCAAyB,IAAI,KAAsC;CACnE,cAA2C,EAAE;;;;;;;;CAS7C,eACE,EAAE;;;;;;;;CASJ,SAAS,MAAiB,QAA4B;AACpD,QAAA,UAAgB,IAAI,MAAM,KAAK,EAAE,OAAO;;;;;;;;;;;;;;;;;;CAmB1C,eAAe,aAA+C;EAC5D,MAAM,WAAW,KAAK,QAAQ;AAC9B,QAAA,aAAmB,KAAK,YAAY;AAOpC,MAAI,YAAY,WAQd,aAAY,WAPmB,EAK7B,OAAO,IAAI,UAAU,KAAK,KAAK,IAAI,MAAM,EAC1C,CAC8B;AAGjC,OAAK,IAAI,IAAI,GAAG,IAAI,UAAU,KAAK,EACjC,aAAY,QAAQ,KAAK,QAAQ,IAAI,EAAE,CAAC;AAG1C,MAAI,MAAA,OACF,KAAI,MAAA,UAAgB,KAAA,EAClB,aAAY,OAAO,MAAA,MAAY;MAE/B,aAAY,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;CA4B9B,aAAa,YAA2C;AACtD,OAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,WAAW,EAAE;AACrD,OAAIS,uBAAAA,gBAAgB,MAAM,EAAE;AAC1B,UAAA,SAAe,KAAK,MAAM;AAC1B,QAAI,OAAO,MAAM,gBAAgB,SAC/B;AAEF,UAAM,OAAO,SAAkB;AAC7B,UAAK,QAAQ,KAAK;MAChB,MAAM;MACN,KAAK,MAAA;MACL,QAAQ,MAAM;MACd,QAAQ;OACN,WAAW,MAAA;OACX,WAAW,KAAK,KAAK;OACrB,MAAM;OACP;MACF,CAAC;MACF;AACF;;AAEF,OAAI,cAAc,MAAM,CACtB,OAAA,YAAkB,KAAK;IACrB,MAAM;IACN,SAAS,QAAQ,QAAQ,MAAM;IAChC,CAAC;;;;;;;;;;;;;;CAgBR,KAAK,IAAe,OAA4B;AAC9C,MAAI,MAAM,WAAW,SACnB,OAAA,aAAmB,IACjB,MAAM,GAAG,EACT,MAAM,OAAO,KACd;EAQH,MAAM,iBAAiB,MAAA;AACvB,QAAA,mBAAyB;EAEzB,IAAI,OAAO;AACX,OAAK,MAAM,eAAe,MAAA,aACxB,KAAI,CAAC,YAAY,QAAQ,MAAM,CAC7B,QAAO;AAIX,QAAA,mBAAyB;AAEzB,MAAI,KASF,MAAK,QAAQ,KAAK;GAAE,GAAG;GAAO,KAAK,MAAA;GAAqB,CAAC;;;;;;;;;;;;;;;CAiB7D,QAAc;AACZ,QAAA,SAAe;AACf,OAAK,MAAM,CAAC,KAAK,WAAW,MAAA,aAAmB,SAAS,EAAE;GACxD,MAAM,KAAK,MAAM,IAAI,MAAM,KAAO,GAAG,EAAE;AACxB,SAAA,UAAgB,IAAI,MAAM,GAAG,CAAC,GACpC,gBAAgB,OAAO;;EAGlC,MAAM,mBAAwC,EAAE;AAChD,OAAK,MAAM,eAAe,MAAA,cAAoB;GAC5C,MAAM,SAAS,YAAY,YAAY;AACvC,OACE,UAAU,QACV,OAAQ,OAA6B,SAAS,WAE9C,kBAAiB,KAAK,OAA4B;;AAItD,OAAK,MAAM,WAAW,MAAA,SACpB,SAAQ,QAAQ;EAGlB,MAAM,cAAc,MAAA;AACpB,MAAI,YAAY,WAAW,KAAK,iBAAiB,WAAW,GAAG;AAC7D,QAAK,QAAQ,OAAO;AACpB,QAAK,aAAa,OAAO;QAEpB,SAAQ,WAAW,CACtB,GAAG,kBACH,GAAG,YAAY,IAAI,OAAO,EAAE,MAAM,cAAc;AAC9C,OAAI;IACF,MAAM,WAAW,MAAM;AACvB,QAAI,CAAC,KAAK,QAAQ,KAChB,MAAK,QAAQ,KAAK;KAChB,MAAM;KACN,KAAK,MAAA;KACL,QAAQ;KACR,QAAQ;MACN,WAAW,EAAE;MACb,WAAW,KAAK,KAAK;MACrB,MAAM;OAAE;OAAM,SAAS;OAAU;MAClC;KACF,CAAC;WAEE;IAOR,CACH,CAAC,CAAC,WAAW;AACZ,QAAK,QAAQ,OAAO;AACpB,QAAK,aAAa,OAAO;IACzB;AAGJ,OAAK,MAAM,UAAU,MAAA,UAAgB,QAAQ,CAC3C,QAAO,gBAAgB,KAAA,EAAU;;;;;;;;CAUrC,KAAK,KAAoB;AACvB,QAAA,SAAe;AACf,QAAA,QAAc;AACd,OAAK,MAAM,eAAe,MAAA,aACxB,aAAY,OAAO,IAAI;AAEzB,OAAK,MAAM,WAAW,MAAA,SACpB,SAAQ,MAAM,IAAI;AAEpB,OAAK,QAAQ,KAAK,IAAI;AACtB,OAAK,aAAa,KAAK,IAAI;AAC3B,OAAK,MAAM,UAAU,MAAA,UAAgB,QAAQ,CAC3C,QAAO,eAAe,IAAI;;;;;;;;CAU9B,gBAAgB,YAAsC;AACpD,QAAA,cAAoB;AACpB,QAAA,WAAiB,KAAK,GAAG,WAAW;;;;;;;CAQtC,IAAI,cAAuB;AACzB,SAAO,MAAA;;;;;;;CAQT,IAAI,aAA0C;AAC5C,SAAO,MAAA;;;;;;;;;;CAWT,gBAAgB,MAAiB,UAAU,GAAiC;EAC1E,MAAM,OAAO,KAAK,QAAQ,QAAQ,QAAQ;AAC1C,SAAO,EACL,MAAM,OAA+C;AAEnD,UAAO,MAAM;IACX,MAAM,SAAS,MAAM,KAAK,MAAM;AAChC,QAAI,OAAO,KAAM,QAAO;AACxB,QAAI,UAAU,OAAO,MAAM,OAAO,WAAW,KAAK,CAChD,QAAO;;KAId;;;;;;;;;;;;;AAcL,eAAsB,KACpB,QACA,KACe;CACf,IAAI,MAAM;AACV,KAAI;AACF,aAAW,MAAM,SAAS,QAAQ;GAChC,MAAM,CAAC,IAAI,MAAM,SAAS,QAAQ;AAGlC,OAAI,SAAS,YAAYI,kBAAAA,cAAc,QAAQ,EAAE;IAC/C,MAAM,aAAc,QAAyCC,kBAAAA;AAC7D,QAAI,gBACF,WAAW,KAAK,OAAO;KACrB,aAAa,EAAE,MAAM;KACrB,SAAS,EAAE;KACZ,EAAE,CACJ;;GAGH,MAAM,SAASC,gBAAAA,uBAAuB;IACpC,WAAW;IACX;IACA;IACA;IACA;IACD,CAAC;AACF,UAAO,OAAO;AACd,QAAK,MAAM,SAAS,OAClB,KAAI,KAAK,IAAI,MAAM;;UAGhB,KAAK;AACZ,MAAI,KAAK,IAAI;AACb;;AAEF,KAAI,OAAO;;;;;;;;;AAUb,SAAgB,MAAM,IAAuB;AAC3C,QAAO,GAAG,KAAK,KAAO;;;;;;;;;AAUxB,SAAgB,UAAU,IAAe,QAA4B;AACnE,KAAI,OAAO,SAAS,GAAG,OAAQ,QAAO;AACtC,MAAK,IAAI,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK,EACtC,KAAI,GAAG,OAAO,OAAO,GAAI,QAAO;AAElC,QAAO"}
1
+ {"version":3,"file":"mux.cjs","names":["StreamChannel","#transformers","#channels","#streamMap","#latestValues","#interrupts","#finalValues","#closed","#error","isStreamChannel","#nextEmitSeq","#currentNamespace","#interrupted","isInterrupted","INTERRUPT","convertToProtocolEvent"],"sources":["../../src/stream/mux.ts"],"sourcesContent":["/**\n * StreamMux — central dispatcher with transformer pipeline.\n *\n * Routes raw stream chunks through registered StreamTransformers, then appends\n * the resulting ProtocolEvents to the main local channel. Also tracks\n * namespace discovery for SubgraphRunStream creation.\n *\n * lifecycle:\n * graph.streamEvents(input, { version: \"v3\" })\n * ├─ StreamMux starts pumping from graph.stream(…, { subgraphs: true })\n * ├─ For each ProtocolEvent:\n * │ ├─ transformer_1.process(event)\n * │ ├─ transformer_2.process(event)\n * │ └─ event appended to _events (unless suppressed)\n * └─ On close: transformer_n.finalize() called in registration order\n */\n\nimport type { StreamChunk } from \"../pregel/stream.js\";\nimport { INTERRUPT, isInterrupted, type Interrupt } from \"../constants.js\";\nimport { convertToProtocolEvent, STREAM_EVENTS_V3_MODES } from \"./convert.js\";\nimport { StreamChannel, isStreamChannel } from \"./stream-channel.js\";\nimport type {\n InterruptPayload,\n Namespace,\n ProtocolEvent,\n StreamEmitter,\n StreamTransformer,\n} from \"./types.js\";\n\nexport { STREAM_EVENTS_V3_MODES };\n\n/**\n * Structural `PromiseLike<T>` predicate — true for thenables including\n * native promises, user-constructed `{ then }` objects, and helper\n * wrappers. Used by {@link StreamMux.wireChannels} to detect final-value\n * projections distinctly from streaming `StreamChannel` values.\n */\nfunction isPromiseLike(value: unknown): value is PromiseLike<unknown> {\n return (\n value != null &&\n (typeof value === \"object\" || typeof value === \"function\") &&\n typeof (value as { then?: unknown }).then === \"function\"\n );\n}\n\n/**\n * Symbol key used by {@link StreamMux} to resolve the values promise on a\n * stream handle. Using a symbol keeps this off the public autocomplete surface.\n */\nexport const RESOLVE_VALUES: unique symbol = Symbol(\"resolveValues\");\n\n/**\n * Symbol key used by {@link StreamMux} to reject the values promise on a\n * stream handle. Using a symbol keeps this off the public autocomplete surface.\n */\nexport const REJECT_VALUES: unique symbol = Symbol(\"rejectValues\");\n\n/**\n * Minimal interface that {@link StreamMux} requires from stream handles\n * for lifecycle resolution. This avoids a direct dependency on\n * `GraphRunStream` / `SubgraphRunStream`.\n */\nexport interface StreamHandle {\n [RESOLVE_VALUES](values: unknown): void;\n [REJECT_VALUES](err: unknown): void;\n}\n\n/**\n * Factory function that creates a subgraph stream handle for a newly\n * discovered namespace.\n *\n * Historically consumed by {@link StreamMux} at construction time;\n * today factories are consumed by\n * `createSubgraphDiscoveryTransformer` (via its `createStream`\n * option). This shape is retained for consumers that still thread a\n * mux reference through the factory — the narrower transformer\n * option omits `mux` because it captures the mux in a closure.\n */\nexport type SubgraphStreamFactory = (\n path: Namespace,\n mux: StreamMux,\n discoveryStart: number,\n eventStart: number\n) => StreamHandle;\n\n/**\n * A discovered subgraph namespace paired with its run stream handle.\n */\nexport type SubgraphDiscovery = {\n ns: Namespace;\n stream: StreamHandle;\n};\n\n/**\n * Central event dispatcher that routes {@link ProtocolEvent}s through a\n * pipeline of {@link StreamTransformer}s, manages namespace discovery for\n * subgraph streams, and exposes async iteration over filtered event\n * sequences.\n *\n * One `StreamMux` instance exists per top-level\n * `streamEvents(..., { version: \"v3\" })` invocation.\n */\nexport class StreamMux {\n /** @internal All protocol events in arrival order (after reducer pipeline). */\n readonly _events = StreamChannel.local<ProtocolEvent>();\n\n /** @internal New-namespace discovery notifications. */\n readonly _discoveries = StreamChannel.local<SubgraphDiscovery>();\n\n /** Monotonic counter for auto-forwarded channel events. */\n #nextEmitSeq = 0;\n\n /** Whether the mux has been closed or failed. */\n #closed = false;\n\n /** The error passed to {@link fail}, if any. */\n #error: unknown;\n\n /** Whether the run was interrupted. */\n #interrupted = false;\n\n /**\n * Namespace of the event currently being processed by\n * {@link push}. Read by {@link StreamChannel} wiring callbacks so\n * auto-forwarded events inherit the triggering event's namespace.\n */\n #currentNamespace: Namespace = [];\n\n readonly #transformers: StreamTransformer<unknown>[] = [];\n readonly #channels: StreamChannel<unknown>[] = [];\n readonly #streamMap = new Map<string, StreamHandle>();\n readonly #latestValues = new Map<string, Record<string, unknown>>();\n readonly #interrupts: InterruptPayload[] = [];\n\n /**\n * Final-value projection keys tracked for remote surfacing. Populated\n * by {@link wireChannels} when a transformer's projection contains a\n * `PromiseLike` value. Each entry is flushed as a `custom:<name>`\n * protocol event during {@link close} so that remote clients can\n * observe final-value transformers via `thread.extensions.<name>`.\n */\n readonly #finalValues: Array<{ name: string; promise: Promise<unknown> }> =\n [];\n\n /**\n * Associates a pre-existing stream handle with a namespace so that\n * {@link close} can resolve its values promise later.\n *\n * @param path - The namespace path to register.\n * @param stream - The run stream handle for that namespace.\n */\n register(path: Namespace, stream: StreamHandle): void {\n this.#streamMap.set(nsKey(path), stream);\n }\n\n /**\n * Registers a transformer and replays all buffered events through it so\n * it catches up with events already processed by the mux. When the event\n * log is empty (typical at construction time) the replay is a no-op.\n *\n * The transformer must already have been initialised (i.e. `init()` called\n * and any projection wired). The sequence is:\n *\n * 1. Snapshot the current event log length.\n * 2. Append the transformer so future {@link push} calls reach it.\n * 3. Replay events `[0, snapshot)` through `process()`.\n * 4. If the mux is already closed, call `finalize()` (or `fail()`)\n * immediately so the transformer's log/channel terminates cleanly.\n *\n * @param transformer - An already-initialised transformer to register.\n */\n addTransformer(transformer: StreamTransformer<unknown>): void {\n const snapshot = this._events.size;\n this.#transformers.push(transformer);\n\n // Hand the transformer a narrow emitter handle *before* replay so\n // synthetic-emission transformers (e.g. deepagents\n // `SubagentTransformer`) can inject events into the mux during\n // their own `process()` calls — including the initial replay\n // triggered just below.\n if (transformer.onRegister) {\n const emitter: StreamEmitter = {\n // Transformer-originated events use a placeholder `seq` of\n // `0`. `push()` is the single authority for sequence numbers\n // and will re-stamp this event with the next monotonically\n // increasing value.\n push: (ns, event) => this.push(ns, event),\n };\n transformer.onRegister(emitter);\n }\n\n for (let i = 0; i < snapshot; i += 1) {\n transformer.process(this._events.get(i));\n }\n\n if (this.#closed) {\n if (this.#error !== undefined) {\n transformer.fail?.(this.#error);\n } else {\n transformer.finalize?.();\n }\n }\n }\n\n /**\n * Scans a transformer projection for streaming and final-value primitives.\n * Remote stream channels are wired to auto-forward to the protocol event\n * stream; local stream channels are tracked for lifecycle only.\n *\n * Two projection shapes are recognised:\n *\n * - {@link StreamChannel} values — named channels forward each `push()`\n * immediately as a protocol event on the channel's declared\n * `channelName` method. Unnamed channels remain in-process-only.\n *\n * - `PromiseLike<unknown>` values — tracked as final-value\n * projections and flushed on {@link close} as a single\n * `custom:<key>` event, where `<key>` is the projection key.\n * This mirrors the in-process `await run.extensions.<key>`\n * ergonomics on remote clients via\n * `await thread.extensions.<key>`.\n *\n * Plain values that are neither are ignored — they remain in-process-only,\n * matching prior behaviour.\n *\n * @param projection - The object returned by `transformer.init()`.\n */\n wireChannels(projection: Record<string, unknown>): void {\n for (const [key, value] of Object.entries(projection)) {\n if (isStreamChannel(value)) {\n this.#channels.push(value);\n if (typeof value.channelName !== \"string\") {\n continue;\n }\n value._wire((item: unknown) => {\n this._events.push({\n type: \"event\",\n seq: this.#nextEmitSeq++,\n method: value.channelName as ProtocolEvent[\"method\"],\n params: {\n namespace: this.#currentNamespace,\n timestamp: Date.now(),\n data: item,\n },\n });\n });\n continue;\n }\n if (isPromiseLike(value)) {\n this.#finalValues.push({\n name: key,\n promise: Promise.resolve(value),\n });\n }\n }\n }\n\n /**\n * Distributes an event through the transformer pipeline, then appends it to\n * the main event log.\n *\n * Subgraph discovery (materializing a {@link StreamHandle} for each\n * newly observed top-level namespace) is handled by the\n * {@link createSubgraphDiscoveryTransformer} when installed, not here.\n *\n * @param ns - The namespace path that produced the event.\n * @param event - The protocol event to process and store.\n */\n push(ns: Namespace, event: ProtocolEvent): void {\n if (event.method === \"values\") {\n this.#latestValues.set(\n nsKey(ns),\n event.params.data as Record<string, unknown>\n );\n }\n\n // Save the outer namespace so re-entrant `push()` calls (e.g. from\n // `StreamTransformer.onRegister` emitters synthesizing events\n // inside a transformer's `process()`) can set their own namespace\n // without clobbering the outer scope's `StreamChannel` routing\n // when control returns to the outer transformer loop.\n const outerNamespace = this.#currentNamespace;\n this.#currentNamespace = ns;\n\n let keep = true;\n for (const transformer of this.#transformers) {\n if (!transformer.process(event)) {\n keep = false;\n }\n }\n\n this.#currentNamespace = outerNamespace;\n\n if (keep) {\n // The mux is the single authority for sequence numbers. Callers\n // (the `pump`, transformer emitters, channel forwarders) pass a\n // placeholder `seq`; we re-stamp every event here so the log is\n // strictly monotonic across all origination paths. Stamping\n // happens *after* `process()` so that any channel-forwarded\n // events pushed during processing get earlier sequence numbers\n // than the triggering event, matching their in-order appearance\n // in `_events`.\n this._events.push({ ...event, seq: this.#nextEmitSeq++ });\n }\n }\n\n /**\n * Gracefully ends the stream: resolves values promises on all known\n * streams, finalizes every transformer, auto-closes streaming\n * channels, flushes any final-value projections as `custom:<name>`\n * events, and closes both event logs.\n *\n * When final-value projections are present, `_events.close()` is\n * deferred until every tracked projection promise has settled so\n * remote consumers observe the flushed values before their event\n * stream ends. Callers do not need to await — `close()` returns\n * synchronously and any downstream consumer iterating\n * {@link _events} naturally waits for the final events.\n */\n close(): void {\n this.#closed = true;\n for (const [key, values] of this.#latestValues.entries()) {\n const ns = key ? key.split(\"\\x00\") : [];\n const stream = this.#streamMap.get(nsKey(ns));\n stream?.[RESOLVE_VALUES](values);\n }\n\n const finalizePromises: PromiseLike<void>[] = [];\n for (const transformer of this.#transformers) {\n const result = transformer.finalize?.();\n if (\n result != null &&\n typeof (result as PromiseLike<void>).then === \"function\"\n ) {\n finalizePromises.push(result as PromiseLike<void>);\n }\n }\n\n for (const channel of this.#channels) {\n channel._close();\n }\n\n const finalValues = this.#finalValues;\n if (finalValues.length === 0 && finalizePromises.length === 0) {\n this._events.close();\n this._discoveries.close();\n } else {\n void Promise.allSettled([\n ...finalizePromises,\n ...finalValues.map(async ({ name, promise }) => {\n try {\n const resolved = await promise;\n if (!this._events.done) {\n this._events.push({\n type: \"event\",\n seq: this.#nextEmitSeq++,\n method: \"custom\",\n params: {\n namespace: [],\n timestamp: Date.now(),\n data: { name, payload: resolved },\n },\n });\n }\n } catch {\n // Rejected final-value projections are intentionally dropped\n // so a single failing extension can't poison the protocol\n // stream. The corresponding in-process Promise still\n // surfaces the rejection to its direct awaiters via the\n // transformer's own `fail()` hook.\n }\n }),\n ]).then(() => {\n this._events.close();\n this._discoveries.close();\n });\n }\n\n for (const stream of this.#streamMap.values()) {\n stream[RESOLVE_VALUES](undefined);\n }\n }\n\n /**\n * Propagates a failure to all transformers, channels, event logs, and\n * stream handles.\n *\n * @param err - The error that caused the run to fail.\n */\n fail(err: unknown): void {\n this.#closed = true;\n this.#error = err;\n for (const transformer of this.#transformers) {\n transformer.fail?.(err);\n }\n for (const channel of this.#channels) {\n channel._fail(err);\n }\n this._events.fail(err);\n this._discoveries.fail(err);\n for (const stream of this.#streamMap.values()) {\n stream[REJECT_VALUES](err);\n }\n }\n\n /**\n * Records that the run was interrupted, appending the supplied payloads\n * for later retrieval.\n *\n * @param interrupts - The interrupt payloads to store.\n */\n markInterrupted(interrupts: InterruptPayload[]): void {\n this.#interrupted = true;\n this.#interrupts.push(...interrupts);\n }\n\n /**\n * Whether the run ended due to an interrupt.\n *\n * @returns `true` if {@link markInterrupted} was called.\n */\n get interrupted(): boolean {\n return this.#interrupted;\n }\n\n /**\n * All interrupt payloads collected during the run.\n *\n * @returns A readonly view of the accumulated interrupt payloads.\n */\n get interrupts(): readonly InterruptPayload[] {\n return this.#interrupts;\n }\n\n /**\n * Returns an async iterator that yields only events whose namespace\n * starts with {@link path}.\n *\n * @param path - Namespace prefix to filter on.\n * @param startAt - Zero-based index into the event log to begin from.\n * @returns An async iterator over matching {@link ProtocolEvent}s.\n */\n subscribeEvents(path: Namespace, startAt = 0): AsyncIterator<ProtocolEvent> {\n const base = this._events.iterate(startAt);\n return {\n async next(): Promise<IteratorResult<ProtocolEvent>> {\n // eslint-disable-next-line no-constant-condition\n while (true) {\n const result = await base.next();\n if (result.done) return result;\n if (hasPrefix(result.value.params.namespace, path)) {\n return result;\n }\n }\n },\n };\n }\n}\n\n/**\n * Background consumer that drains a raw `graph.stream()` source into a\n * {@link StreamMux}. Converts each chunk to a {@link ProtocolEvent} and\n * pushes it; calls {@link StreamMux.close} on normal completion or\n * {@link StreamMux.fail} on error.\n *\n * @param source - The async iterable of raw stream chunks from the engine.\n * @param mux - The mux instance to feed.\n * @returns A promise that resolves when the source is fully consumed.\n */\nexport async function pump(\n source: AsyncIterable<StreamChunk>,\n mux: StreamMux\n): Promise<void> {\n let seq = 0;\n try {\n for await (const chunk of source) {\n const [ns, mode, payload] = chunk;\n\n // Detect interrupt payloads attached to values-mode chunks.\n if (mode === \"values\" && isInterrupted(payload)) {\n const interrupts = (payload as { [INTERRUPT]: Interrupt[] })[INTERRUPT];\n mux.markInterrupted(\n interrupts.map((i) => ({\n interruptId: i.id ?? \"\",\n payload: i.value,\n }))\n );\n }\n\n const events = convertToProtocolEvent({\n namespace: ns,\n mode,\n payload,\n seq,\n });\n seq += events.length;\n for (const event of events) {\n mux.push(ns, event);\n }\n }\n } catch (err) {\n mux.fail(err);\n return;\n }\n mux.close();\n}\n\n/**\n * Serialises a {@link Namespace} array into a single string key using the\n * null byte (`\\x00`) as separator, suitable for `Map`/`Set` lookups.\n *\n * @param ns - The namespace segments to join.\n * @returns A null-byte-joined string key.\n */\nexport function nsKey(ns: Namespace): string {\n return ns.join(\"\\x00\");\n}\n\n/**\n * Tests whether {@link ns} starts with every segment in {@link prefix}.\n *\n * @param ns - The full namespace to check.\n * @param prefix - The prefix to match against.\n * @returns `true` if `ns` begins with `prefix` segment-by-segment.\n */\nexport function hasPrefix(ns: Namespace, prefix: Namespace): boolean {\n if (prefix.length > ns.length) return false;\n for (let i = 0; i < prefix.length; i += 1) {\n if (ns[i] !== prefix[i]) return false;\n }\n return true;\n}\n"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { INTERRUPT, isInterrupted } from "../constants.js";
2
- import { StreamChannel, isStreamChannel } from "./stream-channel.js";
3
2
  import { convertToProtocolEvent } from "./convert.js";
3
+ import { StreamChannel, isStreamChannel } from "./stream-channel.js";
4
4
  //#region src/stream/mux.ts
5
5
  /**
6
6
  * Structural `PromiseLike<T>` predicate — true for thenables including
@@ -293,7 +293,7 @@ async function pump(source, mux) {
293
293
  let seq = 0;
294
294
  try {
295
295
  for await (const chunk of source) {
296
- const [ns, mode, payload, meta] = chunk;
296
+ const [ns, mode, payload] = chunk;
297
297
  if (mode === "values" && isInterrupted(payload)) {
298
298
  const interrupts = payload[INTERRUPT];
299
299
  mux.markInterrupted(interrupts.map((i) => ({
@@ -305,8 +305,7 @@ async function pump(source, mux) {
305
305
  namespace: ns,
306
306
  mode,
307
307
  payload,
308
- seq,
309
- meta
308
+ seq
310
309
  });
311
310
  seq += events.length;
312
311
  for (const event of events) mux.push(ns, event);