@hraness/kb 0.17.1

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 (200) hide show
  1. package/DISCLOSURE +43 -0
  2. package/LICENSE +21 -0
  3. package/README.md +545 -0
  4. package/dist/agent-context.js +35 -0
  5. package/dist/agent-guide-audit.js +18 -0
  6. package/dist/attachments.js +19 -0
  7. package/dist/authoring.js +33 -0
  8. package/dist/benchmark.js +19 -0
  9. package/dist/capture.js +49 -0
  10. package/dist/cli.js +3646 -0
  11. package/dist/clip/acquire.js +57 -0
  12. package/dist/clip/args.js +21 -0
  13. package/dist/clip/bounded-byte-buffer.js +9 -0
  14. package/dist/clip/browser-profiles.js +17 -0
  15. package/dist/clip/bundle-reader.js +11 -0
  16. package/dist/clip/cli.js +27 -0
  17. package/dist/clip/cookies.js +21 -0
  18. package/dist/clip/defuddle-worker.js +84 -0
  19. package/dist/clip/doctor.js +32 -0
  20. package/dist/clip/jobs.js +784 -0
  21. package/dist/clip/network-proxy.js +9 -0
  22. package/dist/clip/network.js +28 -0
  23. package/dist/clip/persist.js +30 -0
  24. package/dist/clip/refresh.js +11 -0
  25. package/dist/clip/terminal.js +11 -0
  26. package/dist/evaluation-builder.js +12238 -0
  27. package/dist/evaluation-kb.js +26 -0
  28. package/dist/evaluation.js +35 -0
  29. package/dist/git.js +39 -0
  30. package/dist/graph.js +39 -0
  31. package/dist/index-01jj6rbv.js +1103 -0
  32. package/dist/index-06c9ctr6.js +738 -0
  33. package/dist/index-0kavxzqj.js +2480 -0
  34. package/dist/index-1gwbassd.js +743 -0
  35. package/dist/index-1n418kb9.js +827 -0
  36. package/dist/index-1vrd1rmn.js +56 -0
  37. package/dist/index-1xxnjn0d.js +171 -0
  38. package/dist/index-3rm7cz6h.js +373 -0
  39. package/dist/index-3v2z4f0q.js +328 -0
  40. package/dist/index-48pz4jpc.js +392 -0
  41. package/dist/index-4j3tt0c3.js +234 -0
  42. package/dist/index-5n05se68.js +307 -0
  43. package/dist/index-5vwpzb5a.js +764 -0
  44. package/dist/index-6g2pv9d2.js +370 -0
  45. package/dist/index-7fzc32gf.js +712 -0
  46. package/dist/index-84x0vjjp.js +432 -0
  47. package/dist/index-adx6khj5.js +488 -0
  48. package/dist/index-b88v3vtm.js +805 -0
  49. package/dist/index-cv6fh7z5.js +462 -0
  50. package/dist/index-cxfrakt7.js +1067 -0
  51. package/dist/index-d13v9ckt.js +150 -0
  52. package/dist/index-dycjbhw2.js +1943 -0
  53. package/dist/index-dyqwejk5.js +531 -0
  54. package/dist/index-e5fbsywq.js +658 -0
  55. package/dist/index-f984hw45.js +927 -0
  56. package/dist/index-gh719d91.js +63 -0
  57. package/dist/index-hgve9rh2.js +2046 -0
  58. package/dist/index-hya40gb2.js +474 -0
  59. package/dist/index-j4zgmzjr.js +152 -0
  60. package/dist/index-jsmvyyvf.js +1166 -0
  61. package/dist/index-kh0pwvdd.js +1974 -0
  62. package/dist/index-mqx4nd6v.js +119 -0
  63. package/dist/index-mxxxytys.js +1254 -0
  64. package/dist/index-n5dd7r0v.js +711 -0
  65. package/dist/index-npg9z1a4.js +431 -0
  66. package/dist/index-pj501bh1.js +140 -0
  67. package/dist/index-qry4vhxk.js +1041 -0
  68. package/dist/index-s2gw5aw9.js +199 -0
  69. package/dist/index-vvdj6kca.js +70 -0
  70. package/dist/index-w2zc0vwa.js +571 -0
  71. package/dist/index-x3fthpsc.js +585 -0
  72. package/dist/index-zr53sf63.js +44 -0
  73. package/dist/index-zxdy5pby.js +2728 -0
  74. package/dist/index-zzhgcwyt.js +966 -0
  75. package/dist/index.js +453 -0
  76. package/dist/navigation.js +13 -0
  77. package/dist/pdf.js +85 -0
  78. package/dist/percolate.js +24 -0
  79. package/dist/portfolio.js +77 -0
  80. package/dist/query.js +29 -0
  81. package/dist/repository-memory.js +60 -0
  82. package/dist/sdk.js +36 -0
  83. package/dist/search-rules.js +34 -0
  84. package/dist/search.js +22 -0
  85. package/dist/semantic.js +39 -0
  86. package/dist/source-inbox.js +17 -0
  87. package/dist/untrusted-content.js +32 -0
  88. package/dist/url-intelligence.js +74 -0
  89. package/dist/workflow.js +23 -0
  90. package/dist/workflows/decision-context.js +20 -0
  91. package/dist/workflows/explain-change.js +8 -0
  92. package/dist/workflows/index.js +28 -0
  93. package/dist/workflows/plan-radar.js +10 -0
  94. package/package.json +409 -0
  95. package/skills/kb/AGENTS.md +19 -0
  96. package/skills/kb/SKILL.md +82 -0
  97. package/skills/kb/agents/openai.yaml +4 -0
  98. package/skills/kb/references/pdf-review.md +51 -0
  99. package/skills/kb/references/percolate.md +144 -0
  100. package/skills/kb/references/plan-structure.md +105 -0
  101. package/skills/kb/references/plan.md +115 -0
  102. package/skills/kb/references/query.md +231 -0
  103. package/skills/kb/references/refresh.md +133 -0
  104. package/skills/kb/references/save-pdf.md +125 -0
  105. package/skills/kb/references/save-url.md +178 -0
  106. package/skills/kb/references/url-authentication.md +75 -0
  107. package/skills/kb/references/url-platforms.md +25 -0
  108. package/src/agent-context.ts +1241 -0
  109. package/src/agent-guide-audit.ts +750 -0
  110. package/src/attachments.ts +723 -0
  111. package/src/authoring.ts +1725 -0
  112. package/src/benchmark.ts +362 -0
  113. package/src/capture.ts +68 -0
  114. package/src/cli.ts +3660 -0
  115. package/src/clip/acquire.ts +1273 -0
  116. package/src/clip/archive-today.ts +402 -0
  117. package/src/clip/args.ts +423 -0
  118. package/src/clip/assets.ts +262 -0
  119. package/src/clip/bounded-byte-buffer.ts +75 -0
  120. package/src/clip/browser-profiles.ts +372 -0
  121. package/src/clip/bundle-reader.ts +608 -0
  122. package/src/clip/capture.ts +1054 -0
  123. package/src/clip/cli.ts +181 -0
  124. package/src/clip/cookies.ts +512 -0
  125. package/src/clip/doctor.ts +1110 -0
  126. package/src/clip/extract.ts +868 -0
  127. package/src/clip/jobs.ts +959 -0
  128. package/src/clip/lib.ts +861 -0
  129. package/src/clip/media.ts +1474 -0
  130. package/src/clip/metadata-search-tool/Cargo.lock +2498 -0
  131. package/src/clip/metadata-search-tool/Cargo.toml +18 -0
  132. package/src/clip/metadata-search-tool/runner.ts +685 -0
  133. package/src/clip/metadata-search-tool/src/main.rs +389 -0
  134. package/src/clip/metadata-search.ts +687 -0
  135. package/src/clip/network-proxy.ts +627 -0
  136. package/src/clip/network.ts +950 -0
  137. package/src/clip/package-root.ts +54 -0
  138. package/src/clip/persist.ts +1472 -0
  139. package/src/clip/platforms.ts +1824 -0
  140. package/src/clip/refresh.ts +197 -0
  141. package/src/clip/structured.ts +432 -0
  142. package/src/clip/terminal.ts +197 -0
  143. package/src/clip/url-intelligence.ts +581 -0
  144. package/src/clip/url-metadata-backfill.ts +616 -0
  145. package/src/clip/url-metadata-cli.ts +251 -0
  146. package/src/clip/url-metadata.ts +1397 -0
  147. package/src/evaluation-analysis-v2.ts +1440 -0
  148. package/src/evaluation-builder.ts +2539 -0
  149. package/src/evaluation-corpus-authoring.ts +2052 -0
  150. package/src/evaluation-evidence.ts +1147 -0
  151. package/src/evaluation-execution-v2.ts +426 -0
  152. package/src/evaluation-implementation.ts +131 -0
  153. package/src/evaluation-kb-closure.ts +1430 -0
  154. package/src/evaluation-kb-runner-v2.ts +735 -0
  155. package/src/evaluation-kb-v2.ts +2567 -0
  156. package/src/evaluation-kb.ts +1018 -0
  157. package/src/evaluation-measurement-v2.ts +1462 -0
  158. package/src/evaluation-packing-v2.ts +452 -0
  159. package/src/evaluation-redaction.ts +28 -0
  160. package/src/evaluation-v2.ts +3857 -0
  161. package/src/evaluation.ts +1220 -0
  162. package/src/git.ts +1276 -0
  163. package/src/graph.ts +1487 -0
  164. package/src/index.ts +20 -0
  165. package/src/init.ts +123 -0
  166. package/src/navigation.ts +277 -0
  167. package/src/note-lock.ts +529 -0
  168. package/src/pdf/args.ts +202 -0
  169. package/src/pdf/capture.ts +298 -0
  170. package/src/pdf/cli.ts +159 -0
  171. package/src/pdf/extract.ts +303 -0
  172. package/src/pdf/layout.ts +618 -0
  173. package/src/pdf/markdown.ts +154 -0
  174. package/src/pdf/model.ts +234 -0
  175. package/src/pdf/ocr.ts +190 -0
  176. package/src/pdf/persist.ts +314 -0
  177. package/src/pdf/source.ts +135 -0
  178. package/src/pdf/tools.ts +146 -0
  179. package/src/pdf.ts +92 -0
  180. package/src/percolate.ts +877 -0
  181. package/src/portfolio-audit.ts +574 -0
  182. package/src/portfolio-identity.ts +162 -0
  183. package/src/portfolio-registry.ts +473 -0
  184. package/src/portfolio.ts +765 -0
  185. package/src/query.ts +646 -0
  186. package/src/repository-memory.ts +1150 -0
  187. package/src/sdk.ts +1452 -0
  188. package/src/search-rules.ts +712 -0
  189. package/src/search.ts +710 -0
  190. package/src/semantic-runtime.ts +1139 -0
  191. package/src/semantic.ts +2480 -0
  192. package/src/source-inbox.ts +232 -0
  193. package/src/untrusted-content.ts +401 -0
  194. package/src/url-intelligence.ts +104 -0
  195. package/src/vault.ts +636 -0
  196. package/src/workflow.ts +653 -0
  197. package/src/workflows/decision-context.ts +81 -0
  198. package/src/workflows/explain-change.ts +73 -0
  199. package/src/workflows/index.ts +3 -0
  200. package/src/workflows/plan-radar.ts +101 -0
@@ -0,0 +1,328 @@
1
+ // @bun
2
+ // src/workflow.ts
3
+ import { serialize } from "v8";
4
+ var MAX_WORKFLOW_NODES = 64;
5
+ var MAX_WORKFLOW_CONCURRENCY = 8;
6
+ var MAX_GIT_WORKFLOW_CONCURRENCY = 4;
7
+ var DEFAULT_WORKFLOW_OUTPUT_BYTES = 16 * 1024 * 1024;
8
+ var MAX_WORKFLOW_OUTPUT_BYTES = 64 * 1024 * 1024;
9
+ var workflowIdPattern = /^[a-z][a-z0-9-]{0,63}$/u;
10
+
11
+ class WorkflowRunError extends Error {
12
+ kind;
13
+ node;
14
+ constructor(kind, message, options = {}) {
15
+ super(message, options);
16
+ this.name = "WorkflowRunError";
17
+ this.kind = kind;
18
+ if (options.node !== undefined)
19
+ this.node = options.node;
20
+ }
21
+ }
22
+ function isRecord(value) {
23
+ return typeof value === "object" && value !== null && !Array.isArray(value);
24
+ }
25
+ function needsFor(node) {
26
+ return node.needs ?? [];
27
+ }
28
+ function validateWorkflowId(id, label) {
29
+ if (!workflowIdPattern.test(id)) {
30
+ throw new Error(`${label} must start with a lowercase letter and contain at most 64 lowercase letters, digits, or hyphens.`);
31
+ }
32
+ }
33
+ function validateWorkflow(definition) {
34
+ validateWorkflowId(definition.id, "Workflow id");
35
+ if (definition.nodes.length < 1 || definition.nodes.length > MAX_WORKFLOW_NODES) {
36
+ throw new RangeError(`A workflow must contain from 1 through ${MAX_WORKFLOW_NODES} nodes.`);
37
+ }
38
+ const nodesById = new Map;
39
+ for (const node of definition.nodes) {
40
+ validateWorkflowId(node.id, "Workflow node id");
41
+ if (nodesById.has(node.id)) {
42
+ throw new Error(`Workflow node id ${JSON.stringify(node.id)} is duplicated.`);
43
+ }
44
+ if (typeof node.run !== "function") {
45
+ throw new Error(`Workflow node ${JSON.stringify(node.id)} must define run().`);
46
+ }
47
+ const needs = needsFor(node);
48
+ if (new Set(needs).size !== needs.length) {
49
+ throw new Error(`Workflow node ${JSON.stringify(node.id)} repeats a dependency.`);
50
+ }
51
+ nodesById.set(node.id, node);
52
+ }
53
+ if (!nodesById.has(definition.output)) {
54
+ throw new Error(`Workflow output node ${JSON.stringify(definition.output)} does not exist.`);
55
+ }
56
+ for (const node of definition.nodes) {
57
+ for (const dependency of needsFor(node)) {
58
+ if (!nodesById.has(dependency)) {
59
+ throw new Error(`Workflow node ${JSON.stringify(node.id)} depends on unknown node ${JSON.stringify(dependency)}.`);
60
+ }
61
+ if (dependency === node.id) {
62
+ throw new Error(`Workflow node ${JSON.stringify(node.id)} cannot depend on itself.`);
63
+ }
64
+ }
65
+ }
66
+ const remaining = new Set(nodesById.keys());
67
+ const completed = new Set;
68
+ while (remaining.size > 0) {
69
+ const ready = definition.nodes.filter((node) => remaining.has(node.id) && needsFor(node).every((dependency) => completed.has(dependency)));
70
+ if (ready.length === 0) {
71
+ throw new Error(`Workflow contains a dependency cycle among: ${[...remaining].join(", ")}.`);
72
+ }
73
+ for (const node of ready) {
74
+ remaining.delete(node.id);
75
+ completed.add(node.id);
76
+ }
77
+ }
78
+ }
79
+ function createWorkflowBuilder(id, nodes) {
80
+ const builder = {
81
+ node: (node) => createWorkflowBuilder(id, [...nodes, node]),
82
+ output: (output) => defineWorkflow({
83
+ id,
84
+ nodes,
85
+ output
86
+ })
87
+ };
88
+ return builder;
89
+ }
90
+ function defineWorkflow(specification) {
91
+ if (typeof specification === "string") {
92
+ return createWorkflowBuilder(specification, []);
93
+ }
94
+ const definition = {
95
+ kind: "hraness-kb-workflow",
96
+ version: 1,
97
+ ...specification
98
+ };
99
+ validateWorkflow(definition);
100
+ return definition;
101
+ }
102
+ function workflowFromUnknown(value) {
103
+ if (!isRecord(value))
104
+ throw new Error("Workflow export must be an object.");
105
+ if (value.kind !== "hraness-kb-workflow" || value.version !== 1) {
106
+ throw new Error("Workflow export has an unsupported kind or version.");
107
+ }
108
+ if (typeof value.id !== "string" || typeof value.output !== "string" || !Array.isArray(value.nodes)) {
109
+ throw new Error("Workflow export has malformed id, output, or nodes.");
110
+ }
111
+ const nodes = value.nodes.map((item, index) => {
112
+ if (!isRecord(item) || typeof item.id !== "string") {
113
+ throw new Error(`Workflow export node ${index} is malformed.`);
114
+ }
115
+ const run = item.run;
116
+ if (typeof run !== "function") {
117
+ throw new Error(`Workflow export node ${index} is malformed.`);
118
+ }
119
+ const needs = item.needs;
120
+ if (needs !== undefined && (!Array.isArray(needs) || needs.some((entry) => typeof entry !== "string"))) {
121
+ throw new Error(`Workflow export node ${index}.needs must be an array of strings.`);
122
+ }
123
+ const resource = item.resource;
124
+ if (resource !== undefined && resource !== "default" && resource !== "git" && resource !== "qmd") {
125
+ throw new Error(`Workflow export node ${index}.resource is invalid.`);
126
+ }
127
+ return {
128
+ id: item.id,
129
+ ...needs === undefined ? {} : { needs },
130
+ ...resource === undefined ? {} : { resource },
131
+ run: (context) => {
132
+ const returned = Reflect.apply(run, undefined, [context]);
133
+ return returned;
134
+ }
135
+ };
136
+ });
137
+ const definition = {
138
+ kind: "hraness-kb-workflow",
139
+ version: 1,
140
+ id: value.id,
141
+ nodes,
142
+ output: value.output
143
+ };
144
+ validateWorkflow(definition);
145
+ return definition;
146
+ }
147
+ function checkedConcurrency(value) {
148
+ const concurrency = value ?? 4;
149
+ if (!Number.isSafeInteger(concurrency) || concurrency < 1 || concurrency > MAX_WORKFLOW_CONCURRENCY) {
150
+ throw new RangeError(`Workflow concurrency must be an integer from 1 through ${MAX_WORKFLOW_CONCURRENCY}.`);
151
+ }
152
+ return concurrency;
153
+ }
154
+ function resourceLimits(concurrency, configured) {
155
+ const limits = {
156
+ default: concurrency,
157
+ git: Math.min(MAX_GIT_WORKFLOW_CONCURRENCY, concurrency),
158
+ qmd: 1
159
+ };
160
+ for (const resource of ["default", "git", "qmd"]) {
161
+ const value = configured?.[resource];
162
+ if (value === undefined)
163
+ continue;
164
+ if (resource === "qmd" && value !== 1) {
165
+ throw new RangeError("Workflow qmd concurrency is fixed at 1.");
166
+ }
167
+ if (!Number.isSafeInteger(value) || value < 1 || value > MAX_WORKFLOW_CONCURRENCY) {
168
+ throw new RangeError(`Workflow ${resource} concurrency must be an integer from 1 through ${MAX_WORKFLOW_CONCURRENCY}.`);
169
+ }
170
+ limits[resource] = resource === "git" ? Math.min(value, concurrency, MAX_GIT_WORKFLOW_CONCURRENCY) : Math.min(value, concurrency);
171
+ }
172
+ return limits;
173
+ }
174
+ function checkedOutputBytes(value) {
175
+ const maximum = value ?? DEFAULT_WORKFLOW_OUTPUT_BYTES;
176
+ if (!Number.isSafeInteger(maximum) || maximum < 1 || maximum > MAX_WORKFLOW_OUTPUT_BYTES) {
177
+ throw new RangeError(`Workflow output byte limit must be an integer from 1 through ${MAX_WORKFLOW_OUTPUT_BYTES}.`);
178
+ }
179
+ return maximum;
180
+ }
181
+ function structuredOutputBytes(value, node) {
182
+ try {
183
+ return serialize(value).byteLength;
184
+ } catch (error) {
185
+ throw new WorkflowRunError("node-failed", `Workflow node ${JSON.stringify(node)} returned a result that cannot be structurally serialized.`, { node, cause: error });
186
+ }
187
+ }
188
+ function abortedError() {
189
+ return new WorkflowRunError("aborted", "Workflow execution was aborted.");
190
+ }
191
+ async function runWorkflow(definition, options) {
192
+ validateWorkflow(definition);
193
+ const concurrency = checkedConcurrency(options.concurrency);
194
+ const limits = resourceLimits(concurrency, options.resourceConcurrency);
195
+ const outputLimit = checkedOutputBytes(options.maxOutputBytes);
196
+ if (options.signal?.aborted === true)
197
+ throw abortedError();
198
+ const controller = new AbortController;
199
+ let abortedByCaller = false;
200
+ const abort = () => {
201
+ abortedByCaller = true;
202
+ controller.abort(options.signal?.reason);
203
+ };
204
+ options.signal?.addEventListener("abort", abort, { once: true });
205
+ const pending = new Set(definition.nodes.map(({ id }) => id));
206
+ const completed = new Set;
207
+ const values = new Map;
208
+ const active = new Map;
209
+ const activeResource = new Map;
210
+ const resourceCounts = {
211
+ default: 0,
212
+ git: 0,
213
+ qmd: 0
214
+ };
215
+ let failure;
216
+ let outputBytes = 0;
217
+ const completedValue = (id) => {
218
+ if (!values.has(id)) {
219
+ throw new Error(`Workflow result ${JSON.stringify(id)} is unavailable after its dependency completed.`);
220
+ }
221
+ return values.get(id);
222
+ };
223
+ const launch = (node) => {
224
+ const resource = node.resource ?? "default";
225
+ pending.delete(node.id);
226
+ resourceCounts[resource] += 1;
227
+ activeResource.set(node.id, resource);
228
+ const needs = needsFor(node);
229
+ const allowedResults = new Set(needs);
230
+ const dependencyResults = new Map(needs.map((id) => [id, completedValue(id)]));
231
+ const context = {
232
+ input: options.input,
233
+ kb: options.kb,
234
+ signal: controller.signal,
235
+ results: dependencyResults,
236
+ result: (id) => {
237
+ if (!allowedResults.has(id)) {
238
+ throw new Error(`Workflow result ${JSON.stringify(id)} is not a declared dependency of ${JSON.stringify(node.id)}.`);
239
+ }
240
+ return dependencyResults.get(id);
241
+ }
242
+ };
243
+ const outcome = Promise.resolve().then(() => node.run(context)).then((value) => ({ ok: true, id: node.id, value })).catch((error) => ({
244
+ ok: false,
245
+ id: node.id,
246
+ error
247
+ }));
248
+ active.set(node.id, outcome);
249
+ };
250
+ try {
251
+ while (completed.size + (failure === undefined ? 0 : pending.size) < definition.nodes.length) {
252
+ if (controller.signal.aborted && failure === undefined)
253
+ failure = abortedError();
254
+ if (failure === undefined) {
255
+ for (const node of definition.nodes) {
256
+ if (!pending.has(node.id) || active.size >= concurrency)
257
+ continue;
258
+ if (!needsFor(node).every((dependency) => completed.has(dependency)))
259
+ continue;
260
+ const resource2 = node.resource ?? "default";
261
+ if (resourceCounts[resource2] >= limits[resource2])
262
+ continue;
263
+ launch(node);
264
+ }
265
+ }
266
+ if (active.size === 0) {
267
+ if (failure !== undefined)
268
+ break;
269
+ throw new Error("Workflow scheduler made no progress after validation.");
270
+ }
271
+ const outcome = await Promise.race(active.values());
272
+ active.delete(outcome.id);
273
+ const resource = activeResource.get(outcome.id);
274
+ if (resource !== undefined)
275
+ resourceCounts[resource] -= 1;
276
+ activeResource.delete(outcome.id);
277
+ if (outcome.ok && failure === undefined) {
278
+ try {
279
+ const resultBytes = structuredOutputBytes(outcome.value, outcome.id);
280
+ if (resultBytes > outputLimit - outputBytes) {
281
+ throw new WorkflowRunError("output-limit", `Workflow results exceed the ${outputLimit}-byte output limit at node ${JSON.stringify(outcome.id)}.`, { node: outcome.id });
282
+ }
283
+ outputBytes += resultBytes;
284
+ values.set(outcome.id, outcome.value);
285
+ completed.add(outcome.id);
286
+ } catch (error) {
287
+ controller.abort(error);
288
+ failure = error instanceof WorkflowRunError ? error : new WorkflowRunError("node-failed", `Workflow node ${JSON.stringify(outcome.id)} failed while validating its result.`, { node: outcome.id, cause: error });
289
+ }
290
+ } else if (!outcome.ok && failure === undefined) {
291
+ controller.abort(outcome.error);
292
+ failure = abortedByCaller ? abortedError() : new WorkflowRunError("node-failed", `Workflow node ${JSON.stringify(outcome.id)} failed.`, { node: outcome.id, cause: outcome.error });
293
+ }
294
+ }
295
+ while (active.size > 0) {
296
+ const outcome = await Promise.race(active.values());
297
+ active.delete(outcome.id);
298
+ }
299
+ if (failure !== undefined)
300
+ throw failure;
301
+ let finalOutputBytes = 0;
302
+ for (const node of definition.nodes) {
303
+ const resultBytes = structuredOutputBytes(values.get(node.id), node.id);
304
+ if (resultBytes > outputLimit - finalOutputBytes) {
305
+ throw new WorkflowRunError("output-limit", `Workflow results exceed the ${outputLimit}-byte output limit at node ${JSON.stringify(node.id)}.`, { node: node.id });
306
+ }
307
+ finalOutputBytes += resultBytes;
308
+ }
309
+ const orderedValues = new Map(definition.nodes.map((node) => [node.id, completedValue(node.id)]));
310
+ return {
311
+ workflow: definition.id,
312
+ outputNode: definition.output,
313
+ output: values.get(definition.output),
314
+ outputBytes: finalOutputBytes,
315
+ trace: definition.nodes.map((node) => ({
316
+ id: node.id,
317
+ needs: needsFor(node),
318
+ resource: node.resource ?? "default",
319
+ status: "completed"
320
+ })),
321
+ results: orderedValues
322
+ };
323
+ } finally {
324
+ options.signal?.removeEventListener("abort", abort);
325
+ }
326
+ }
327
+
328
+ export { MAX_WORKFLOW_NODES, MAX_WORKFLOW_CONCURRENCY, MAX_GIT_WORKFLOW_CONCURRENCY, DEFAULT_WORKFLOW_OUTPUT_BYTES, MAX_WORKFLOW_OUTPUT_BYTES, WorkflowRunError, defineWorkflow, workflowFromUnknown, runWorkflow };