@anvia/core 1.0.0-rc.1 → 1.0.0-rc.2

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 (136) hide show
  1. package/README.md +283 -84
  2. package/dist/agent/index.d.ts +26 -18
  3. package/dist/agent/index.js +19 -15
  4. package/dist/agent-yBG8e9Jj.d.ts +153 -0
  5. package/dist/chunk-4WI3VGZK.js +127 -0
  6. package/dist/chunk-4WI3VGZK.js.map +1 -0
  7. package/dist/{chunk-R2LJSQUW.js → chunk-77AIYARB.js} +251 -104
  8. package/dist/chunk-77AIYARB.js.map +1 -0
  9. package/dist/chunk-AI5JMUW7.js +45 -0
  10. package/dist/chunk-AI5JMUW7.js.map +1 -0
  11. package/dist/chunk-BEYBU7VJ.js +53 -0
  12. package/dist/chunk-BEYBU7VJ.js.map +1 -0
  13. package/dist/chunk-CWM7B2OO.js +315 -0
  14. package/dist/chunk-CWM7B2OO.js.map +1 -0
  15. package/dist/{chunk-6WGGTJE6.js → chunk-D37WMSP6.js} +52 -60
  16. package/dist/chunk-D37WMSP6.js.map +1 -0
  17. package/dist/{chunk-IL3ZSNJI.js → chunk-DBSCKTUL.js} +845 -800
  18. package/dist/chunk-DBSCKTUL.js.map +1 -0
  19. package/dist/chunk-EINTGEGY.js +629 -0
  20. package/dist/chunk-EINTGEGY.js.map +1 -0
  21. package/dist/chunk-FMHLROPQ.js +351 -0
  22. package/dist/chunk-FMHLROPQ.js.map +1 -0
  23. package/dist/{chunk-A3UBYTJT.js → chunk-FN7HLLAZ.js} +60 -6
  24. package/dist/chunk-FN7HLLAZ.js.map +1 -0
  25. package/dist/chunk-GKDERULJ.js +50 -0
  26. package/dist/chunk-GKDERULJ.js.map +1 -0
  27. package/dist/{chunk-FNQB2JEH.js → chunk-KIDGIJM7.js} +26 -5
  28. package/dist/chunk-KIDGIJM7.js.map +1 -0
  29. package/dist/chunk-KR3RCCHJ.js +500 -0
  30. package/dist/chunk-KR3RCCHJ.js.map +1 -0
  31. package/dist/{chunk-I6G7BC42.js → chunk-MGNTXGTX.js} +2 -6
  32. package/dist/chunk-MGNTXGTX.js.map +1 -0
  33. package/dist/{chunk-5XKDW36Z.js → chunk-OJH6HWHX.js} +64 -75
  34. package/dist/chunk-OJH6HWHX.js.map +1 -0
  35. package/dist/chunk-QOUPWOGW.js +29 -0
  36. package/dist/chunk-QOUPWOGW.js.map +1 -0
  37. package/dist/chunk-TIZYTPJO.js +208 -0
  38. package/dist/chunk-TIZYTPJO.js.map +1 -0
  39. package/dist/{chunk-DMPUP4R3.js → chunk-XKYYBABH.js} +5 -5
  40. package/dist/client-B8DT1vUG.d.ts +83 -0
  41. package/dist/completion/index.d.ts +5 -4
  42. package/dist/completion/index.js +25 -28
  43. package/dist/{dynamic-tools-i9woysFa.d.ts → dynamic-tools-KwEGRbHp.d.ts} +21 -9
  44. package/dist/embeddings/index.d.ts +11 -9
  45. package/dist/embeddings/index.js +2 -3
  46. package/dist/evals/index.d.ts +44 -24
  47. package/dist/evals/index.js +86 -69
  48. package/dist/evals/index.js.map +1 -1
  49. package/dist/extractor/index.d.ts +23 -26
  50. package/dist/extractor/index.js +7 -8
  51. package/dist/guardrails/index.d.ts +2 -1
  52. package/dist/guardrails/index.js +1 -1
  53. package/dist/image-generation/index.d.ts +18 -16
  54. package/dist/image-generation/index.js +2 -2
  55. package/dist/index.d.ts +24 -22
  56. package/dist/index.js +50 -48
  57. package/dist/internal/agent.d.ts +30 -19
  58. package/dist/internal/agent.js +13 -11
  59. package/dist/loaders/index.d.ts +2 -1
  60. package/dist/mcp/index.d.ts +19 -13
  61. package/dist/mcp/index.js +13 -348
  62. package/dist/mcp/index.js.map +1 -1
  63. package/dist/memory/index.d.ts +20 -6
  64. package/dist/memory/index.js +10 -10
  65. package/dist/message-schema-Cn7ezRfJ.d.ts +52 -0
  66. package/dist/{middleware-KynLg_RW.d.ts → middleware-C7PdmKF7.d.ts} +4 -4
  67. package/dist/model-call-options-CZkSw_xN.d.ts +6 -0
  68. package/dist/model-listing/index.d.ts +3 -1
  69. package/dist/observability/index.d.ts +19 -5
  70. package/dist/observability/index.js +8 -5
  71. package/dist/observability/index.js.map +1 -1
  72. package/dist/pipeline/index.d.ts +105 -56
  73. package/dist/pipeline/index.js +422 -230
  74. package/dist/pipeline/index.js.map +1 -1
  75. package/dist/{retry-D3Ruy-ba.d.ts → retry-CjvSlKGW.d.ts} +2 -1
  76. package/dist/skills/index.d.ts +5 -4
  77. package/dist/skills/index.js +7 -7
  78. package/dist/speech-generation/index.d.ts +37 -0
  79. package/dist/speech-generation/index.js +8 -0
  80. package/dist/{think-tool-DZqZj2LV.d.ts → think-tool-6H2QNQzQ.d.ts} +1 -1
  81. package/dist/tool/index.d.ts +9 -7
  82. package/dist/tool/index.js +7 -10
  83. package/dist/{tool-C_8GudXn.d.ts → tool--Mz4v1eL.d.ts} +15 -7
  84. package/dist/transcription/index.d.ts +23 -14
  85. package/dist/transcription/index.js +2 -2
  86. package/dist/{index-DxB74ybJ.d.ts → types-3x3mOLHU.d.ts} +94 -64
  87. package/dist/types-BVzM4RsC.d.ts +155 -0
  88. package/dist/types-CQ_ioXWK.d.ts +319 -0
  89. package/dist/types-Cr4uiYo5.d.ts +99 -0
  90. package/dist/{types-DhQfwiZn.d.ts → types-DiJqJejp.d.ts} +1 -1
  91. package/dist/types-Dld1TpWj.d.ts +130 -0
  92. package/dist/vector-store/index.d.ts +33 -34
  93. package/dist/vector-store/index.js +6 -6
  94. package/package.json +6 -10
  95. package/dist/agent-DGYY_onS.d.ts +0 -145
  96. package/dist/audio-generation/index.d.ts +0 -31
  97. package/dist/audio-generation/index.js +0 -8
  98. package/dist/chunk-5XKDW36Z.js.map +0 -1
  99. package/dist/chunk-6WGGTJE6.js.map +0 -1
  100. package/dist/chunk-A3UBYTJT.js.map +0 -1
  101. package/dist/chunk-ADH7NNCS.js +0 -512
  102. package/dist/chunk-ADH7NNCS.js.map +0 -1
  103. package/dist/chunk-DZ3CKYTH.js +0 -267
  104. package/dist/chunk-DZ3CKYTH.js.map +0 -1
  105. package/dist/chunk-FNQB2JEH.js.map +0 -1
  106. package/dist/chunk-I6G7BC42.js.map +0 -1
  107. package/dist/chunk-IL3ZSNJI.js.map +0 -1
  108. package/dist/chunk-J6GNQART.js +0 -122
  109. package/dist/chunk-J6GNQART.js.map +0 -1
  110. package/dist/chunk-M3IOWB4Y.js +0 -280
  111. package/dist/chunk-M3IOWB4Y.js.map +0 -1
  112. package/dist/chunk-QY5GZ7HR.js +0 -39
  113. package/dist/chunk-QY5GZ7HR.js.map +0 -1
  114. package/dist/chunk-R2LJSQUW.js.map +0 -1
  115. package/dist/chunk-RFDVKCIE.js +0 -12
  116. package/dist/chunk-RFDVKCIE.js.map +0 -1
  117. package/dist/chunk-RMUBRRSK.js +0 -34
  118. package/dist/chunk-RMUBRRSK.js.map +0 -1
  119. package/dist/chunk-RXKHOYEH.js +0 -466
  120. package/dist/chunk-RXKHOYEH.js.map +0 -1
  121. package/dist/chunk-XDRSPSR7.js +0 -38
  122. package/dist/chunk-XDRSPSR7.js.map +0 -1
  123. package/dist/chunk-XWUC7CIT.js +0 -1
  124. package/dist/chunk-XWUC7CIT.js.map +0 -1
  125. package/dist/errors-CYKUcU89.d.ts +0 -17
  126. package/dist/json-Zo7K3xmt.d.ts +0 -40
  127. package/dist/types-B3A4YxaA.d.ts +0 -354
  128. package/dist/types-BBEGKB9m.d.ts +0 -119
  129. package/dist/types-DT3nEemY.d.ts +0 -79
  130. package/dist/types-DulRCYdB.d.ts +0 -70
  131. package/dist/types-p55Jc-sr.d.ts +0 -47
  132. package/dist/ui/index.d.ts +0 -107
  133. package/dist/ui/index.js +0 -10
  134. package/dist/ui/index.js.map +0 -1
  135. /package/dist/{chunk-DMPUP4R3.js.map → chunk-XKYYBABH.js.map} +0 -0
  136. /package/dist/{audio-generation → speech-generation}/index.js.map +0 -0
@@ -1,195 +1,304 @@
1
1
  import {
2
+ AgentRunBlockedError,
2
3
  cancelAgentApproval
3
- } from "../chunk-IL3ZSNJI.js";
4
+ } from "../chunk-DBSCKTUL.js";
4
5
  import "../chunk-YK4WAAS4.js";
5
- import "../chunk-6WGGTJE6.js";
6
- import "../chunk-R2LJSQUW.js";
7
- import "../chunk-5XKDW36Z.js";
6
+ import "../chunk-EINTGEGY.js";
7
+ import "../chunk-CQNNSZPG.js";
8
+ import "../chunk-D37WMSP6.js";
9
+ import "../chunk-77AIYARB.js";
10
+ import "../chunk-OJH6HWHX.js";
11
+ import "../chunk-CWM7B2OO.js";
8
12
  import {
9
13
  mapWithConcurrency
10
- } from "../chunk-DZ3CKYTH.js";
11
- import "../chunk-I6G7BC42.js";
12
- import "../chunk-M3IOWB4Y.js";
13
- import "../chunk-RFDVKCIE.js";
14
- import "../chunk-ADH7NNCS.js";
15
- import "../chunk-A3UBYTJT.js";
16
- import "../chunk-FNQB2JEH.js";
14
+ } from "../chunk-FMHLROPQ.js";
15
+ import {
16
+ extract
17
+ } from "../chunk-4WI3VGZK.js";
18
+ import "../chunk-MGNTXGTX.js";
19
+ import "../chunk-KR3RCCHJ.js";
20
+ import "../chunk-TIZYTPJO.js";
21
+ import "../chunk-KIDGIJM7.js";
22
+ import {
23
+ abortError,
24
+ throwIfAborted
25
+ } from "../chunk-FN7HLLAZ.js";
26
+
27
+ // src/pipeline/errors.ts
28
+ var PipelineAgentApprovalError = class extends Error {
29
+ constructor(result) {
30
+ super("Pipeline agent stage required tool approval and was rejected.");
31
+ this.result = result;
32
+ this.name = "PipelineAgentApprovalError";
33
+ }
34
+ result;
35
+ };
17
36
 
18
37
  // src/pipeline/pipeline.ts
19
38
  import { z } from "zod";
20
39
 
21
40
  // src/pipeline/graph.ts
22
- function initialPipelineState(metadata) {
23
- return {
24
- graph: initialGraph(metadata),
25
- terminalNodeId: "input",
26
- terminalNodeIds: ["input"],
27
- nextNodeIndex: 1,
28
- nextEdgeIndex: 1
29
- };
30
- }
31
- function initialGraph(metadata) {
32
- const id = metadata.id ?? "pipeline";
41
+ var INPUT_ID = "$input";
42
+ var OUTPUT_ID = "$output";
43
+ var RESERVED_STAGE_IDS = /* @__PURE__ */ new Set([INPUT_ID, OUTPUT_ID]);
44
+ function initialPipelineState(options) {
45
+ const input = graphNode(INPUT_ID, [INPUT_ID], "input", "Input");
33
46
  const graph = {
34
- id,
35
- nodes: [{ id: "input", kind: "input", label: "Input" }],
47
+ id: options.id,
48
+ nodes: [input],
36
49
  edges: []
37
50
  };
38
- if (metadata.name !== void 0) {
39
- graph.name = metadata.name;
40
- }
41
- if (metadata.description !== void 0) {
42
- graph.description = metadata.description;
43
- }
44
- if (metadata.metadata !== void 0) {
45
- graph.metadata = metadata.metadata;
46
- }
47
- return graph;
48
- }
49
- function appendNode(state, kind, label, options = {}) {
50
- const node = graphNode(kind, label, state.nextNodeIndex, {
51
- ...options,
52
- existingIds: new Set(state.graph.nodes.map((item) => item.id))
53
- });
51
+ if (options.name !== void 0) graph.name = options.name;
52
+ if (options.description !== void 0) graph.description = options.description;
53
+ if (options.metadata !== void 0) graph.metadata = options.metadata;
54
54
  return {
55
- node,
56
- state: appendGraphNode(state, node, activeTerminalNodeIds(state), [node.id])
55
+ graph,
56
+ terminalPaths: [input.path],
57
+ stageIds: /* @__PURE__ */ new Set(),
58
+ nextEdgeIndex: 1
57
59
  };
58
60
  }
59
- function appendChildNode(state, parentId, kind, label, options = {}) {
60
- const node = graphNode(kind, label, state.nextNodeIndex, {
61
- ...options,
62
- existingIds: new Set(state.graph.nodes.map((item) => item.id))
61
+ function appendStageNode(state, kind, stage, options = {}) {
62
+ const id = validateStageId(stage.id);
63
+ if (state.stageIds.has(id)) {
64
+ throw new TypeError(`Pipeline stage id "${id}" is already registered.`);
65
+ }
66
+ const node = graphNode(id, [id], kind, stage.name ?? options.defaultLabel ?? id, {
67
+ description: stage.description,
68
+ metadata: stage.metadata,
69
+ agentId: options.agentId,
70
+ agentName: options.agentName,
71
+ pipelineId: options.pipelineId
63
72
  });
64
73
  return {
65
74
  node,
66
- state: appendGraphNode(state, node, [parentId], activeTerminalNodeIds(state))
75
+ state: appendNode(state, node, state.terminalPaths, [node.path], id)
67
76
  };
68
77
  }
69
- function activeTerminalNodeIds(state) {
70
- return state.terminalNodeIds.length > 0 ? state.terminalNodeIds : [state.terminalNodeId];
78
+ function appendComposedGraph(state, boundary, child) {
79
+ return appendChildGraph(state, boundary.path, child);
71
80
  }
72
- function withTerminalNodes(state, terminalNodeIds) {
73
- return {
74
- ...state,
75
- terminalNodeId: terminalNodeIds.at(-1) ?? state.terminalNodeId,
76
- terminalNodeIds
77
- };
81
+ function appendParallelBranch(state, parallel, branchKey, child) {
82
+ const id = validateStageId(branchKey);
83
+ const path = [...parallel.path, id];
84
+ const node = graphNode(id, path, "branch", id, { branchKey: id, pipelineId: child.id });
85
+ const withBranch = appendNode(state, node, [parallel.path], state.terminalPaths);
86
+ const withChild = appendChildGraph(withBranch, node.path, child);
87
+ return { state: withChild, node, terminalPaths: withChild.terminalPaths };
88
+ }
89
+ function withTerminalPaths(state, terminalPaths) {
90
+ return { ...state, terminalPaths };
78
91
  }
79
92
  function withOutputNode(state) {
80
93
  const graph = cloneGraph(state.graph);
81
- if (graph.nodes.some((node) => node.id === "output")) {
94
+ const outputPath = [OUTPUT_ID];
95
+ if (graph.nodes.some((node) => pathEquals(node.path, outputPath))) {
82
96
  return graph;
83
97
  }
84
- graph.nodes.push({ id: "output", kind: "output", label: "Output" });
98
+ graph.nodes.push(graphNode(OUTPUT_ID, outputPath, "output", "Output"));
85
99
  graph.edges.push(
86
- ...activeTerminalNodeIds(state).map((sourceId, index) => ({
100
+ ...state.terminalPaths.map((source, index) => ({
87
101
  id: `edge_${state.nextEdgeIndex + index}`,
88
- source: sourceId,
89
- target: "output"
102
+ source: [...source],
103
+ target: outputPath
90
104
  }))
91
105
  );
92
106
  return graph;
93
107
  }
94
- function nextStageLabel(state, prefix) {
95
- return `${prefix} ${state.nextNodeIndex}`;
96
- }
97
108
  function cloneGraph(graph) {
98
109
  return {
99
110
  ...graph,
100
- nodes: graph.nodes.map((node) => ({ ...node })),
101
- edges: graph.edges.map((edge) => ({ ...edge }))
111
+ nodes: graph.nodes.map((node) => ({ ...node, path: [...node.path] })),
112
+ edges: graph.edges.map((edge) => ({
113
+ ...edge,
114
+ source: [...edge.source],
115
+ target: [...edge.target]
116
+ }))
102
117
  };
103
118
  }
104
- function appendGraphNode(state, node, sourceIds, terminalNodeIds) {
105
- const edges = sourceIds.map((sourceId, index) => ({
119
+ function scopedNode(node, path) {
120
+ return { ...node, path: [...path] };
121
+ }
122
+ function appendChildGraph(state, parentPath, child) {
123
+ const childNodes = child.nodes.filter((node) => !isBoundaryPath(node.path)).map((node) => scopedNode(node, [...parentPath, ...node.path]));
124
+ const childEdges = [];
125
+ const terminalPaths = [];
126
+ let nextEdgeIndex = state.nextEdgeIndex;
127
+ for (const edge of child.edges) {
128
+ const sourceIsInput = isInputPath(edge.source);
129
+ const targetIsOutput = isOutputPath(edge.target);
130
+ const source = sourceIsInput ? [...parentPath] : [...parentPath, ...edge.source];
131
+ if (targetIsOutput) {
132
+ terminalPaths.push(source);
133
+ continue;
134
+ }
135
+ const target = [...parentPath, ...edge.target];
136
+ childEdges.push({
137
+ id: `edge_${nextEdgeIndex}`,
138
+ source,
139
+ target,
140
+ ...edge.label === void 0 ? {} : { label: edge.label }
141
+ });
142
+ nextEdgeIndex += 1;
143
+ }
144
+ return {
145
+ ...state,
146
+ graph: {
147
+ ...state.graph,
148
+ nodes: [...state.graph.nodes, ...childNodes],
149
+ edges: [...state.graph.edges, ...childEdges]
150
+ },
151
+ terminalPaths: terminalPaths.length === 0 ? [[...parentPath]] : terminalPaths,
152
+ nextEdgeIndex
153
+ };
154
+ }
155
+ function appendNode(state, node, sourcePaths, terminalPaths, stageId) {
156
+ const edges = sourcePaths.map((source, index) => ({
106
157
  id: `edge_${state.nextEdgeIndex + index}`,
107
- source: sourceId,
108
- target: node.id
158
+ source: [...source],
159
+ target: [...node.path]
109
160
  }));
110
- const terminalNodeId = terminalNodeIds.at(-1) ?? state.terminalNodeId;
161
+ const stageIds = new Set(state.stageIds);
162
+ if (stageId !== void 0) stageIds.add(stageId);
111
163
  return {
112
164
  graph: {
113
165
  ...state.graph,
114
166
  nodes: [...state.graph.nodes, node],
115
167
  edges: [...state.graph.edges, ...edges]
116
168
  },
117
- terminalNodeId,
118
- terminalNodeIds,
119
- nextNodeIndex: state.nextNodeIndex + 1,
169
+ terminalPaths,
170
+ stageIds,
120
171
  nextEdgeIndex: state.nextEdgeIndex + edges.length
121
172
  };
122
173
  }
123
- function graphNode(kind, label, index, options = {}) {
124
- const id = uniqueGraphNodeId(
125
- normalizeId(options.preferredId ?? `${kind}_${index}`),
126
- options.existingIds ?? /* @__PURE__ */ new Set()
127
- );
128
- const node = {
129
- id,
130
- kind,
131
- label
132
- };
133
- if (options.description !== void 0) {
134
- node.description = options.description;
135
- }
136
- if (options.metadata !== void 0) {
137
- node.metadata = options.metadata;
138
- }
139
- if (options.agentId !== void 0) {
140
- node.agentId = options.agentId;
141
- }
142
- if (options.agentName !== void 0) {
143
- node.agentName = options.agentName;
174
+ function graphNode(id, path, kind, label, options = {}) {
175
+ const node = { id, path: [...path], kind, label };
176
+ if (options.description !== void 0) node.description = options.description;
177
+ if (options.metadata !== void 0) node.metadata = options.metadata;
178
+ if (options.agentId !== void 0) node.agentId = options.agentId;
179
+ if (options.agentName !== void 0) node.agentName = options.agentName;
180
+ if (options.pipelineId !== void 0) node.pipelineId = options.pipelineId;
181
+ if (options.branchKey !== void 0) node.branchKey = options.branchKey;
182
+ return node;
183
+ }
184
+ function validateStageId(value) {
185
+ if (typeof value !== "string") {
186
+ throw new TypeError("Pipeline stage id must be a string.");
144
187
  }
145
- if (options.pipelineId !== void 0) {
146
- node.pipelineId = options.pipelineId;
188
+ const id = value.trim();
189
+ if (id.length === 0) {
190
+ throw new TypeError("Pipeline stage id must be a non-empty string.");
147
191
  }
148
- if (options.branchKey !== void 0) {
149
- node.branchKey = options.branchKey;
192
+ if (RESERVED_STAGE_IDS.has(id)) {
193
+ throw new TypeError(`Pipeline stage id "${id}" is reserved.`);
150
194
  }
151
- return node;
195
+ return id;
152
196
  }
153
- function normalizeId(value) {
154
- const normalized = value.trim().toLowerCase().replace(/[^a-z0-9_-]+/g, "_").replace(/^_+|_+$/g, "");
155
- return normalized.length === 0 ? "pipeline" : normalized;
197
+ function isBoundaryPath(path) {
198
+ return isInputPath(path) || isOutputPath(path);
156
199
  }
157
- function uniqueGraphNodeId(baseId, existingIds) {
158
- let id = baseId;
159
- let suffix = 2;
160
- while (existingIds.has(id)) {
161
- id = `${baseId}_${suffix}`;
162
- suffix += 1;
163
- }
164
- return id;
200
+ function isInputPath(path) {
201
+ return path.length === 1 && path[0] === INPUT_ID;
202
+ }
203
+ function isOutputPath(path) {
204
+ return path.length === 1 && path[0] === OUTPUT_ID;
205
+ }
206
+ function pathEquals(left, right) {
207
+ return left.length === right.length && left.every((segment, index) => segment === right[index]);
165
208
  }
166
209
 
167
210
  // src/pipeline/runtime.ts
168
- async function runNode(context, node, fn) {
211
+ async function runNode(context, node, path, fn) {
212
+ throwIfAborted(context.abortSignal);
213
+ const eventNode = scopedNode(node, path);
169
214
  const startedAt = Date.now();
170
- await context.observer?.onEvent({ type: "stage_started", node });
215
+ await emitEvent(context, {
216
+ type: "stage_started",
217
+ runId: context.runId,
218
+ pipelineId: context.pipelineId,
219
+ path: [...path],
220
+ node: eventNode
221
+ });
171
222
  try {
172
223
  const output = await fn();
173
- await context.observer?.onEvent({
224
+ throwIfAborted(context.abortSignal);
225
+ await emitEvent(context, {
174
226
  type: "stage_completed",
175
- node,
227
+ runId: context.runId,
228
+ pipelineId: context.pipelineId,
229
+ path: [...path],
230
+ node: eventNode,
176
231
  durationMs: Date.now() - startedAt
177
232
  });
178
233
  return output;
179
234
  } catch (error) {
180
- await context.observer?.onEvent({
235
+ const failureEvent = {
181
236
  type: "stage_failed",
182
- node,
237
+ runId: context.runId,
238
+ pipelineId: context.pipelineId,
239
+ path: [...path],
240
+ node: eventNode,
183
241
  durationMs: Date.now() - startedAt,
184
242
  error
185
- });
243
+ };
244
+ try {
245
+ await emitEvent(context, failureEvent);
246
+ } catch (observerError) {
247
+ throw new AggregateError(
248
+ [error, observerError],
249
+ `Pipeline stage "${node.id}" and its observer both failed.`
250
+ );
251
+ }
186
252
  throw error;
187
253
  }
188
254
  }
255
+ function stageContext(input, context) {
256
+ return {
257
+ input,
258
+ runId: context.runId,
259
+ pipelineId: context.pipelineId,
260
+ runMetadata: context.runMetadata,
261
+ abortSignal: context.abortSignal
262
+ };
263
+ }
264
+ function childContext(context, abortSignal) {
265
+ return { ...context, abortSignal };
266
+ }
267
+ function combineAbortSignals(parent, local) {
268
+ const controller = new AbortController();
269
+ const abortFromParent = () => controller.abort(parent?.reason);
270
+ const abortFromLocal = () => controller.abort(local.reason);
271
+ if (parent?.aborted === true) {
272
+ controller.abort(parent.reason);
273
+ } else if (local.aborted) {
274
+ controller.abort(local.reason);
275
+ } else {
276
+ parent?.addEventListener("abort", abortFromParent, { once: true });
277
+ local.addEventListener("abort", abortFromLocal, { once: true });
278
+ }
279
+ return {
280
+ signal: controller.signal,
281
+ dispose() {
282
+ parent?.removeEventListener("abort", abortFromParent);
283
+ local.removeEventListener("abort", abortFromLocal);
284
+ }
285
+ };
286
+ }
287
+ function pipelineAbortError(signal) {
288
+ return abortError(signal?.reason);
289
+ }
290
+ async function emitEvent(context, event) {
291
+ if (context.observer === void 0) return;
292
+ try {
293
+ await context.observer.onEvent(event);
294
+ } catch (error) {
295
+ if (context.failOnObserverError) throw error;
296
+ }
297
+ }
189
298
 
190
299
  // src/pipeline/pipeline.ts
191
300
  var internalPipelineOptions = /* @__PURE__ */ Symbol("internal-pipeline-options");
192
- var Pipeline = class _Pipeline {
301
+ var Pipeline = class {
193
302
  id;
194
303
  name;
195
304
  description;
@@ -206,7 +315,10 @@ var Pipeline = class _Pipeline {
206
315
  throw new TypeError("Pipeline inputSchema must be a Zod schema.");
207
316
  }
208
317
  const inputSchema = options.inputSchema;
209
- this.executor = ((input) => inputSchema.parse(input));
318
+ this.executor = (async (input, context) => {
319
+ throwIfAborted(context.abortSignal);
320
+ return inputSchema.parseAsync(input);
321
+ });
210
322
  this.state = initialPipelineState({
211
323
  id,
212
324
  name: options.name,
@@ -220,143 +332,192 @@ var Pipeline = class _Pipeline {
220
332
  this.description = graph.description;
221
333
  this.metadata = graph.metadata;
222
334
  }
223
- /** Add a synchronous or asynchronous transform stage. */
224
- step(fn, metadata) {
225
- const next = appendNode(
226
- this.state,
227
- "step",
228
- metadata?.name ?? nextStageLabel(this.state, "Step"),
229
- {
230
- description: metadata?.description,
231
- metadata: metadata?.metadata,
232
- preferredId: metadata?.id
233
- }
234
- );
235
- return this.derive(async (input, context) => {
236
- const value = await this.runStep(input, context);
237
- const result = await runNode(context, next.node, () => fn(value));
238
- return result;
239
- }, next.state);
335
+ step(options) {
336
+ const next = appendStageNode(this.state, "step", options);
337
+ const executor = (async (input, context, pathPrefix) => {
338
+ const value = await this.execute(input, context, pathPrefix);
339
+ const path = [...pathPrefix, next.node.id];
340
+ return await runNode(
341
+ context,
342
+ next.node,
343
+ path,
344
+ () => options.run(stageContext(value, context))
345
+ );
346
+ });
347
+ return this.derive(executor, next.state);
240
348
  }
241
- /** Compose another pipeline operation after the current stage. */
242
- use(op, metadata) {
243
- const nested = op instanceof _Pipeline ? op : void 0;
244
- const next = appendNode(
245
- this.state,
246
- nested === void 0 ? "step" : "pipeline",
247
- metadata?.name ?? nested?.name ?? nested?.id ?? nextStageLabel(this.state, nested === void 0 ? "Operation" : "Pipeline"),
248
- {
249
- description: metadata?.description ?? nested?.description,
250
- metadata: metadata?.metadata ?? nested?.metadata,
251
- preferredId: metadata?.id,
252
- pipelineId: nested?.id
253
- }
254
- );
255
- return this.derive(async (input, context) => {
256
- const value = await this.runStep(input, context);
257
- const result = await runNode(context, next.node, () => op.run(value));
258
- return result;
259
- }, next.state);
349
+ compose(options) {
350
+ const boundary = appendStageNode(this.state, "pipeline", options, {
351
+ defaultLabel: options.pipeline.name ?? options.pipeline.id,
352
+ pipelineId: options.pipeline.id
353
+ });
354
+ const state = appendComposedGraph(boundary.state, boundary.node, options.pipeline.graph());
355
+ const executor = (async (input, context, pathPrefix) => {
356
+ const value = await this.execute(input, context, pathPrefix);
357
+ const path = [...pathPrefix, boundary.node.id];
358
+ return await runNode(
359
+ context,
360
+ boundary.node,
361
+ path,
362
+ () => options.pipeline.execute(value, context, path)
363
+ );
364
+ });
365
+ return this.derive(executor, state);
260
366
  }
261
- /** Run named branch operations concurrently from the current value. */
262
- parallel(branches, metadata) {
263
- const parallel = appendNode(
264
- this.state,
265
- "parallel",
266
- metadata?.name ?? `${Object.keys(branches).length} parallel branches`,
267
- {
268
- description: metadata?.description,
269
- metadata: metadata?.metadata,
270
- preferredId: metadata?.id
271
- }
272
- );
367
+ parallel(options) {
368
+ const branchEntries = normalizeParallelBranches(options.branches);
369
+ if (branchEntries.length === 0) {
370
+ throw new TypeError("Pipeline parallel branches must not be empty.");
371
+ }
372
+ const parallel = appendStageNode(this.state, "parallel", options, {
373
+ defaultLabel: `${branchEntries.length} parallel branches`
374
+ });
273
375
  let nextState = parallel.state;
274
- const branchNodes = {};
275
- for (const key of Object.keys(branches)) {
276
- const branch = appendChildNode(nextState, parallel.node.id, "branch", key, {
277
- branchKey: key
278
- });
279
- nextState = branch.state;
280
- branchNodes[key] = branch.node;
376
+ const branchNodes = /* @__PURE__ */ new Map();
377
+ const terminalPaths = [];
378
+ for (const [key, branch] of branchEntries) {
379
+ const appended = appendParallelBranch(nextState, parallel.node, key, branch.graph());
380
+ nextState = appended.state;
381
+ branchNodes.set(key, appended.node);
382
+ terminalPaths.push(...appended.terminalPaths);
281
383
  }
282
- nextState = withTerminalNodes(
283
- nextState,
284
- Object.values(branchNodes).map((node) => node.id)
285
- );
286
- return this.derive(async (input, context) => {
287
- const value = await this.runStep(input, context);
288
- const entries = await runNode(
289
- context,
290
- parallel.node,
291
- () => Promise.all(
292
- Object.entries(branches).map(async ([key, op]) => {
293
- const node = branchNodes[key];
294
- const output = await runNode(context, node, () => op.run(value));
384
+ nextState = withTerminalPaths(nextState, terminalPaths);
385
+ return this.derive(async (input, context, pathPrefix) => {
386
+ const value = await this.execute(input, context, pathPrefix);
387
+ const parallelPath = [...pathPrefix, parallel.node.id];
388
+ return runNode(context, parallel.node, parallelPath, async () => {
389
+ const controller = new AbortController();
390
+ const combined = combineAbortSignals(context.abortSignal, controller.signal);
391
+ const branchContext = childContext(context, combined.signal);
392
+ let firstError;
393
+ const promises = branchEntries.map(async ([key, branch]) => {
394
+ const node = branchNodes.get(key);
395
+ const path = [...parallelPath, node.id];
396
+ try {
397
+ const output = await runNode(
398
+ branchContext,
399
+ node,
400
+ path,
401
+ () => branch.execute(value, branchContext, path)
402
+ );
295
403
  return [key, output];
296
- })
297
- )
298
- );
299
- return Object.fromEntries(entries);
404
+ } catch (error) {
405
+ if (firstError === void 0) firstError = error;
406
+ if (!controller.signal.aborted) controller.abort(error);
407
+ throw error;
408
+ }
409
+ });
410
+ const settled = await Promise.allSettled(promises);
411
+ combined.dispose();
412
+ if (context.abortSignal?.aborted === true) {
413
+ throw pipelineAbortError(context.abortSignal);
414
+ }
415
+ if (firstError !== void 0) throw firstError;
416
+ return Object.fromEntries(
417
+ settled.map(
418
+ (result) => result.value
419
+ )
420
+ );
421
+ });
300
422
  }, nextState);
301
423
  }
302
- /** Send the current value to an agent as text and continue with the agent output. */
303
- agent(agent, metadata) {
304
- const next = appendNode(this.state, "agent", metadata?.name ?? agent.name ?? agent.id, {
305
- description: metadata?.description ?? agent.description,
306
- metadata: metadata?.metadata,
307
- preferredId: metadata?.id,
308
- agentId: agent.id,
309
- agentName: agent.name
424
+ agent(options) {
425
+ const next = appendStageNode(this.state, "agent", options, {
426
+ defaultLabel: options.agent.name ?? options.agent.id,
427
+ agentId: options.agent.id,
428
+ agentName: options.agent.name
310
429
  });
311
- return this.derive(async (input, context) => {
312
- const value = await this.runStep(input, context);
313
- return runNode(context, next.node, async () => {
314
- const response = await agent.generate(String(value));
430
+ return this.derive(async (input, context, pathPrefix) => {
431
+ const value = await this.execute(input, context, pathPrefix);
432
+ const path = [...pathPrefix, next.node.id];
433
+ return runNode(context, next.node, path, async () => {
434
+ const request = await options.request(stageContext(value, context));
435
+ const response = await options.agent.generate({
436
+ ...request,
437
+ abortSignal: context.abortSignal
438
+ });
315
439
  if (response.status === "approval_required") {
316
440
  await cancelAgentApproval(
317
441
  response,
318
- "Pipeline agent stages cannot suspend for tool approval."
442
+ `Pipeline agent stage "${next.node.id}" rejects tool approval suspension.`
319
443
  );
320
- throw new Error("Pipeline agent stages cannot suspend for tool approval.");
444
+ throw new PipelineAgentApprovalError(response);
445
+ }
446
+ if (response.status === "blocked") {
447
+ throw new AgentRunBlockedError(response);
321
448
  }
322
449
  return response.output;
323
450
  });
324
451
  }, next.state);
325
452
  }
326
- /** Send the current value to an extractor as text and continue with typed schema data. */
327
- extract(extractor, metadata) {
328
- const next = appendNode(
329
- this.state,
330
- "extractor",
331
- metadata?.name ?? nextStageLabel(this.state, "Extractor"),
332
- {
333
- description: metadata?.description,
334
- metadata: metadata?.metadata,
335
- preferredId: metadata?.id
336
- }
337
- );
338
- return this.derive(async (input, context) => {
339
- const value = await this.runStep(input, context);
340
- return runNode(context, next.node, () => extractor.extract(String(value)));
453
+ extract(options) {
454
+ const next = appendStageNode(this.state, "extractor", options);
455
+ return this.derive(async (input, context, pathPrefix) => {
456
+ const value = await this.execute(input, context, pathPrefix);
457
+ const path = [...pathPrefix, next.node.id];
458
+ return runNode(context, next.node, path, async () => {
459
+ const text = await options.text(stageContext(value, context));
460
+ const result = await extract({
461
+ model: options.model,
462
+ text,
463
+ outputSchema: options.outputSchema,
464
+ instructions: options.instructions,
465
+ retries: options.retries,
466
+ temperature: options.temperature,
467
+ maxTokens: options.maxTokens,
468
+ providerOptions: options.providerOptions,
469
+ abortSignal: context.abortSignal
470
+ });
471
+ return result.output;
472
+ });
341
473
  }, next.state);
342
474
  }
343
- /** Run one input through the pipeline and return the final stage output. */
344
- async run(input, options = {}) {
345
- return this.runStep(input, { observer: options.observer });
475
+ async run(options) {
476
+ const runId = normalizeRunId(options.runId ?? globalThis.crypto.randomUUID());
477
+ const context = {
478
+ runId,
479
+ pipelineId: this.id,
480
+ runMetadata: options.metadata,
481
+ abortSignal: options.abortSignal,
482
+ observer: options.observer,
483
+ failOnObserverError: options.failOnObserverError === true
484
+ };
485
+ throwIfAborted(context.abortSignal);
486
+ const output = await this.execute(options.input, context, []);
487
+ throwIfAborted(context.abortSignal);
488
+ return { runId, output };
346
489
  }
347
- /** Run many inputs through the same pipeline with bounded concurrency. */
348
- async batch(inputs, options) {
349
- return mapWithConcurrency([...inputs], options.concurrency, (input) => this.run(input));
490
+ async runBatch(options) {
491
+ throwIfAborted(options.abortSignal);
492
+ return mapWithConcurrency([...options.inputs], options.concurrency, async (input) => {
493
+ const runId = globalThis.crypto.randomUUID();
494
+ try {
495
+ const result = await this.run({
496
+ input,
497
+ runId,
498
+ metadata: options.metadata,
499
+ abortSignal: options.abortSignal,
500
+ observer: options.observer,
501
+ failOnObserverError: options.failOnObserverError
502
+ });
503
+ return { status: "completed", ...result };
504
+ } catch (error) {
505
+ if (options.abortSignal?.aborted === true) {
506
+ throw pipelineAbortError(options.abortSignal);
507
+ }
508
+ return { status: "failed", runId, error };
509
+ }
510
+ });
350
511
  }
351
- /** Return an isolated graph snapshot for the current pipeline stages. */
352
512
  graph() {
353
513
  return cloneGraph(withOutputNode(this.state));
354
514
  }
355
515
  derive(executor, state) {
356
516
  return createDerivedPipeline(executor, state);
357
517
  }
358
- async runStep(input, context) {
359
- return await this.executor(input, context);
518
+ async execute(input, context, pathPrefix) {
519
+ throwIfAborted(context.abortSignal);
520
+ return await this.executor(input, context, pathPrefix);
360
521
  }
361
522
  };
362
523
  function createDerivedPipeline(executor, state) {
@@ -381,7 +542,38 @@ function normalizePipelineId(id) {
381
542
  }
382
543
  return normalized;
383
544
  }
545
+ function normalizeRunId(runId) {
546
+ if (typeof runId !== "string") {
547
+ throw new TypeError("Pipeline runId must be a string.");
548
+ }
549
+ const normalized = runId.trim();
550
+ if (normalized.length === 0) {
551
+ throw new TypeError("Pipeline runId must be a non-empty string.");
552
+ }
553
+ return normalized;
554
+ }
555
+ function normalizeParallelBranches(branches) {
556
+ const entries = [];
557
+ const ids = /* @__PURE__ */ new Set();
558
+ for (const key of Object.keys(branches)) {
559
+ const pipeline = branches[key];
560
+ const id = key.trim();
561
+ if (id.length === 0) {
562
+ throw new TypeError("Pipeline parallel branch id must be a non-empty string.");
563
+ }
564
+ if (ids.has(id)) {
565
+ throw new TypeError(`Pipeline parallel branch id "${id}" is already registered.`);
566
+ }
567
+ ids.add(id);
568
+ if (id !== key) {
569
+ throw new TypeError("Pipeline parallel branch ids must not contain surrounding whitespace.");
570
+ }
571
+ entries.push([id, pipeline]);
572
+ }
573
+ return entries;
574
+ }
384
575
  export {
385
- Pipeline
576
+ Pipeline,
577
+ PipelineAgentApprovalError
386
578
  };
387
579
  //# sourceMappingURL=index.js.map