@particle-academy/fancy-flow 0.77.1 → 0.78.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{FlowViewer-Ak8kbY0e.d.cts → FlowViewer-BqYQl2vS.d.cts} +1 -1
- package/dist/{FlowViewer-BAV29Zpi.d.ts → FlowViewer-_Fq8AX9V.d.ts} +1 -1
- package/dist/{HumanPrompt-xYPCL2jO.d.cts → HumanPrompt-Sl1wD9Bx.d.cts} +2 -2
- package/dist/{HumanPrompt-Ge_ccCgS.d.ts → HumanPrompt-_SKIdSpx.d.ts} +2 -2
- package/dist/{chunk-G5RAGPVD.js → chunk-3EDB6ELL.js} +3 -3
- package/dist/{chunk-G5RAGPVD.js.map → chunk-3EDB6ELL.js.map} +1 -1
- package/dist/{chunk-CQAMEPPI.js → chunk-4GNDRRJ3.js} +3 -3
- package/dist/{chunk-CQAMEPPI.js.map → chunk-4GNDRRJ3.js.map} +1 -1
- package/dist/{chunk-EGXA4SYJ.js → chunk-BBFHGAEN.js} +4 -4
- package/dist/{chunk-EGXA4SYJ.js.map → chunk-BBFHGAEN.js.map} +1 -1
- package/dist/{chunk-ARSOSEJV.js → chunk-GPFIJR2K.js} +4 -4
- package/dist/{chunk-ARSOSEJV.js.map → chunk-GPFIJR2K.js.map} +1 -1
- package/dist/{chunk-EEIWAIXW.js → chunk-J5YUYDMK.js} +106 -6
- package/dist/chunk-J5YUYDMK.js.map +1 -0
- package/dist/{chunk-2VI24UPB.js → chunk-S4MOUOG4.js} +3 -3
- package/dist/{chunk-2VI24UPB.js.map → chunk-S4MOUOG4.js.map} +1 -1
- package/dist/{chunk-T6WIIGSK.js → chunk-XO4ODEY2.js} +3 -3
- package/dist/{chunk-T6WIIGSK.js.map → chunk-XO4ODEY2.js.map} +1 -1
- package/dist/connectors.d.cts +2 -2
- package/dist/connectors.d.ts +2 -2
- package/dist/durable/index.d.cts +2 -2
- package/dist/durable/index.d.ts +2 -2
- package/dist/durable.cjs +104 -4
- package/dist/durable.cjs.map +1 -1
- package/dist/durable.js +1 -1
- package/dist/engine.cjs +104 -4
- package/dist/engine.cjs.map +1 -1
- package/dist/engine.d.cts +6 -6
- package/dist/engine.d.ts +6 -6
- package/dist/engine.js +4 -4
- package/dist/fields/react-fancy.d.cts +3 -3
- package/dist/fields/react-fancy.d.ts +3 -3
- package/dist/index.cjs +104 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +10 -10
- package/dist/index.d.ts +10 -10
- package/dist/index.js +12 -12
- package/dist/layout/index.d.cts +1 -1
- package/dist/layout/index.d.ts +1 -1
- package/dist/llm/prism.d.cts +1 -1
- package/dist/llm/prism.d.ts +1 -1
- package/dist/llm/vercel-ai.d.cts +1 -1
- package/dist/llm/vercel-ai.d.ts +1 -1
- package/dist/registry/index.d.cts +5 -5
- package/dist/registry/index.d.ts +5 -5
- package/dist/{registry-JUcN_xWK.d.ts → registry-C4GcH583.d.ts} +1 -1
- package/dist/{registry-B6SiTaLZ.d.cts → registry-DWIY3bMP.d.cts} +1 -1
- package/dist/registry.cjs +104 -4
- package/dist/registry.cjs.map +1 -1
- package/dist/registry.js +2 -2
- package/dist/{run-cohort-rgT_FX3V.d.ts → run-cohort-DAfhZm-p.d.ts} +2 -2
- package/dist/{run-cohort-DNpPa0mq.d.cts → run-cohort-DRJvUWO9.d.cts} +2 -2
- package/dist/{run-flow-pW0PllaZ.d.cts → run-flow-Bdrn4lQV.d.cts} +1 -1
- package/dist/{run-flow-BLP9rXfO.d.ts → run-flow-D2iOjWsj.d.ts} +1 -1
- package/dist/runtime/index.d.cts +5 -5
- package/dist/runtime/index.d.ts +5 -5
- package/dist/runtime.cjs +104 -4
- package/dist/runtime.cjs.map +1 -1
- package/dist/runtime.js +3 -3
- package/dist/schema/index.d.cts +1 -1
- package/dist/schema/index.d.ts +1 -1
- package/dist/schema.cjs +104 -4
- package/dist/schema.cjs.map +1 -1
- package/dist/schema.js +3 -3
- package/dist/screens.cjs +104 -4
- package/dist/screens.cjs.map +1 -1
- package/dist/screens.d.cts +2 -2
- package/dist/screens.d.ts +2 -2
- package/dist/screens.js +4 -4
- package/dist/terminal/fancy-term-host.d.cts +1 -1
- package/dist/terminal/fancy-term-host.d.ts +1 -1
- package/dist/{types-BdkXxjFh.d.cts → types-B1jftRa9.d.cts} +1 -1
- package/dist/{types-CbekKMMO.d.ts → types-D5SBBpbe.d.ts} +1 -1
- package/dist/{types-B-Syk9-M.d.ts → types-E48Dpesq.d.cts} +20 -0
- package/dist/{types-B-Syk9-M.d.cts → types-E48Dpesq.d.ts} +20 -0
- package/dist/ux.cjs +104 -4
- package/dist/ux.cjs.map +1 -1
- package/dist/ux.d.cts +2 -2
- package/dist/ux.d.ts +2 -2
- package/dist/ux.js +1 -1
- package/package.json +2 -2
- package/dist/chunk-EEIWAIXW.js.map +0 -1
package/dist/screens.d.cts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export { F as FlowNodeStatus, a as FlowViewer, b as FlowViewerClassNames, c as FlowViewerProps } from './FlowViewer-
|
|
1
|
+
export { F as FlowNodeStatus, a as FlowViewer, b as FlowViewerClassNames, c as FlowViewerProps } from './FlowViewer-BqYQl2vS.cjs';
|
|
2
2
|
import 'react';
|
|
3
|
-
import './types-
|
|
3
|
+
import './types-E48Dpesq.cjs';
|
|
4
4
|
import '@xyflow/react';
|
|
5
5
|
|
|
6
6
|
/**
|
package/dist/screens.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export { F as FlowNodeStatus, a as FlowViewer, b as FlowViewerClassNames, c as FlowViewerProps } from './FlowViewer-
|
|
1
|
+
export { F as FlowNodeStatus, a as FlowViewer, b as FlowViewerClassNames, c as FlowViewerProps } from './FlowViewer-_Fq8AX9V.js';
|
|
2
2
|
import 'react';
|
|
3
|
-
import './types-
|
|
3
|
+
import './types-E48Dpesq.js';
|
|
4
4
|
import '@xyflow/react';
|
|
5
5
|
|
|
6
6
|
/**
|
package/dist/screens.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { FlowViewer } from './chunk-
|
|
2
|
-
export { FlowViewer } from './chunk-
|
|
3
|
-
import './chunk-
|
|
1
|
+
import { FlowViewer } from './chunk-BBFHGAEN.js';
|
|
2
|
+
export { FlowViewer } from './chunk-BBFHGAEN.js';
|
|
3
|
+
import './chunk-XO4ODEY2.js';
|
|
4
4
|
import './chunk-F5RPRB7A.js';
|
|
5
5
|
import './chunk-OWENS2H5.js';
|
|
6
|
-
import './chunk-
|
|
6
|
+
import './chunk-J5YUYDMK.js';
|
|
7
7
|
import './chunk-2QXKDLGT.js';
|
|
8
8
|
import { registerSchemaComponents } from '@particle-academy/fancy-screens';
|
|
9
9
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ReactNode, ComponentType } from 'react';
|
|
2
|
-
import { F as FlowGraph, a as FlowNode, P as PortDescriptor, N as NodeExecutor } from './types-
|
|
2
|
+
import { F as FlowGraph, a as FlowNode, P as PortDescriptor, N as NodeExecutor } from './types-E48Dpesq.cjs';
|
|
3
3
|
import { NodeProps } from '@xyflow/react';
|
|
4
4
|
import { P as PauseAwaiting } from './pause-9iT4tCEV.cjs';
|
|
5
5
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ReactNode, ComponentType } from 'react';
|
|
2
|
-
import { F as FlowGraph, a as FlowNode, P as PortDescriptor, N as NodeExecutor } from './types-
|
|
2
|
+
import { F as FlowGraph, a as FlowNode, P as PortDescriptor, N as NodeExecutor } from './types-E48Dpesq.js';
|
|
3
3
|
import { NodeProps } from '@xyflow/react';
|
|
4
4
|
import { P as PauseAwaiting } from './pause-9iT4tCEV.js';
|
|
5
5
|
|
|
@@ -538,6 +538,26 @@ type NodeExecutor<TIn = Record<string, unknown>, TOut = unknown> = (ctx: {
|
|
|
538
538
|
* invent a key. See `RunIdentity`.
|
|
539
539
|
*/
|
|
540
540
|
run?: RunIdentity;
|
|
541
|
+
/**
|
|
542
|
+
* The graph this node belongs to.
|
|
543
|
+
*
|
|
544
|
+
* A STRUCTURAL executor needs it: `for_each`'s `item` port fans out over a
|
|
545
|
+
* lane derived from the graph — the nodes reachable from `item`, stopping
|
|
546
|
+
* at anything also reachable from `done` — and that lane cannot be computed
|
|
547
|
+
* from `node` and `inputs` alone.
|
|
548
|
+
*
|
|
549
|
+
* Without it the `item` port was accepted by the schema, drawn by the
|
|
550
|
+
* editor, and silently ignored at run time on this runtime: downstream
|
|
551
|
+
* nodes ran ONCE against the whole collection instead of once per item,
|
|
552
|
+
* with no error. The PHP twin derives the same lane from `$ctx->graph` and
|
|
553
|
+
* has since 0.6; parity was measured against a reference graph where the
|
|
554
|
+
* two disagreed.
|
|
555
|
+
*
|
|
556
|
+
* Optional, because a host may construct a context by hand. An executor
|
|
557
|
+
* that needs it must degrade rather than throw — `for_each` falls back to
|
|
558
|
+
* publishing the collection, which is what it did everywhere before.
|
|
559
|
+
*/
|
|
560
|
+
graph?: FlowGraph;
|
|
541
561
|
/**
|
|
542
562
|
* The terminal this node's lane owns, if it is inside a terminal lane.
|
|
543
563
|
*
|
|
@@ -538,6 +538,26 @@ type NodeExecutor<TIn = Record<string, unknown>, TOut = unknown> = (ctx: {
|
|
|
538
538
|
* invent a key. See `RunIdentity`.
|
|
539
539
|
*/
|
|
540
540
|
run?: RunIdentity;
|
|
541
|
+
/**
|
|
542
|
+
* The graph this node belongs to.
|
|
543
|
+
*
|
|
544
|
+
* A STRUCTURAL executor needs it: `for_each`'s `item` port fans out over a
|
|
545
|
+
* lane derived from the graph — the nodes reachable from `item`, stopping
|
|
546
|
+
* at anything also reachable from `done` — and that lane cannot be computed
|
|
547
|
+
* from `node` and `inputs` alone.
|
|
548
|
+
*
|
|
549
|
+
* Without it the `item` port was accepted by the schema, drawn by the
|
|
550
|
+
* editor, and silently ignored at run time on this runtime: downstream
|
|
551
|
+
* nodes ran ONCE against the whole collection instead of once per item,
|
|
552
|
+
* with no error. The PHP twin derives the same lane from `$ctx->graph` and
|
|
553
|
+
* has since 0.6; parity was measured against a reference graph where the
|
|
554
|
+
* two disagreed.
|
|
555
|
+
*
|
|
556
|
+
* Optional, because a host may construct a context by hand. An executor
|
|
557
|
+
* that needs it must degrade rather than throw — `for_each` falls back to
|
|
558
|
+
* publishing the collection, which is what it did everywhere before.
|
|
559
|
+
*/
|
|
560
|
+
graph?: FlowGraph;
|
|
541
561
|
/**
|
|
542
562
|
* The terminal this node's lane owns, if it is inside a terminal lane.
|
|
543
563
|
*
|
package/dist/ux.cjs
CHANGED
|
@@ -729,6 +729,9 @@ async function runFlow(graph, executors, onEvent = () => {
|
|
|
729
729
|
executors,
|
|
730
730
|
depth,
|
|
731
731
|
run,
|
|
732
|
+
// Structural executors derive a nested lane from the graph they are
|
|
733
|
+
// in; `for_each`'s `item` port cannot be implemented without it.
|
|
734
|
+
graph,
|
|
732
735
|
terminal: terminalAccessorFor(node)
|
|
733
736
|
})
|
|
734
737
|
);
|
|
@@ -1217,14 +1220,102 @@ var mergeExecutor = (ctx) => {
|
|
|
1217
1220
|
}
|
|
1218
1221
|
return merged;
|
|
1219
1222
|
};
|
|
1220
|
-
var
|
|
1221
|
-
|
|
1223
|
+
var FOR_EACH_DEFAULT_MAX_ITEMS = 1e3;
|
|
1224
|
+
var FOR_EACH_HARD_MAX_ITEMS = 1e4;
|
|
1225
|
+
function reachable(adjacency, starts) {
|
|
1226
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1227
|
+
const queue = [...starts];
|
|
1228
|
+
for (let cursor = 0; cursor < queue.length; cursor += 1) {
|
|
1229
|
+
const id = queue[cursor];
|
|
1230
|
+
if (seen.has(id)) continue;
|
|
1231
|
+
seen.add(id);
|
|
1232
|
+
for (const target of adjacency.get(id) ?? []) queue.push(target);
|
|
1233
|
+
}
|
|
1234
|
+
return seen;
|
|
1235
|
+
}
|
|
1236
|
+
function forEachLane(graph, nodeId) {
|
|
1237
|
+
const handleOf = (edge) => edge.sourceHandle ?? "out";
|
|
1238
|
+
const itemEdges = graph.edges.filter((e) => e.source === nodeId && handleOf(e) === "item");
|
|
1239
|
+
if (itemEdges.length === 0) return null;
|
|
1240
|
+
const adjacency = /* @__PURE__ */ new Map();
|
|
1241
|
+
for (const edge of graph.edges) {
|
|
1242
|
+
const list = adjacency.get(edge.source) ?? [];
|
|
1243
|
+
list.push(edge.target);
|
|
1244
|
+
adjacency.set(edge.source, list);
|
|
1245
|
+
}
|
|
1246
|
+
const done = reachable(
|
|
1247
|
+
adjacency,
|
|
1248
|
+
graph.edges.filter((e) => e.source === nodeId && handleOf(e) === "done").map((e) => e.target)
|
|
1249
|
+
);
|
|
1250
|
+
const body = new Set(
|
|
1251
|
+
[...reachable(adjacency, itemEdges.map((e) => e.target))].filter(
|
|
1252
|
+
(id) => !done.has(id) && id !== nodeId
|
|
1253
|
+
)
|
|
1254
|
+
);
|
|
1255
|
+
return {
|
|
1256
|
+
graph: {
|
|
1257
|
+
nodes: graph.nodes.filter((n) => body.has(n.id)),
|
|
1258
|
+
edges: graph.edges.filter((e) => body.has(e.source) && body.has(e.target)),
|
|
1259
|
+
...graph.inputs === void 0 ? {} : { inputs: graph.inputs }
|
|
1260
|
+
},
|
|
1261
|
+
entries: itemEdges.filter((e) => body.has(e.target))
|
|
1262
|
+
};
|
|
1263
|
+
}
|
|
1264
|
+
var forEachExecutor = async (ctx) => {
|
|
1265
|
+
const config = configOf(ctx.node);
|
|
1266
|
+
const source = resolve(config.source, ctx.inputs);
|
|
1222
1267
|
let items;
|
|
1223
1268
|
if (Array.isArray(source)) items = source;
|
|
1224
1269
|
else if (source === null || source === void 0) items = [];
|
|
1225
1270
|
else if (typeof source === "object") items = Object.values(source);
|
|
1226
1271
|
else items = [source];
|
|
1227
|
-
|
|
1272
|
+
const lane = ctx.graph ? forEachLane(ctx.graph, ctx.node.id) : null;
|
|
1273
|
+
if (lane === null || config.mode === "collect") {
|
|
1274
|
+
return { items, count: items.length };
|
|
1275
|
+
}
|
|
1276
|
+
if (lane.graph.nodes.length === 0) {
|
|
1277
|
+
ctx.abort(`for_each "${ctx.node.id}" has an item edge but its derived lane is empty`);
|
|
1278
|
+
}
|
|
1279
|
+
const maxItems = Number(config.maxItems ?? FOR_EACH_DEFAULT_MAX_ITEMS);
|
|
1280
|
+
if (!Number.isFinite(maxItems) || maxItems < 1 || maxItems > FOR_EACH_HARD_MAX_ITEMS) {
|
|
1281
|
+
ctx.abort(`for_each "${ctx.node.id}" maxItems must be between 1 and ${FOR_EACH_HARD_MAX_ITEMS}`);
|
|
1282
|
+
}
|
|
1283
|
+
if (items.length > maxItems) {
|
|
1284
|
+
ctx.abort(
|
|
1285
|
+
`for_each "${ctx.node.id}" resolved ${items.length} items exceeds its maxItems cap of ${maxItems}`
|
|
1286
|
+
);
|
|
1287
|
+
}
|
|
1288
|
+
const results = [];
|
|
1289
|
+
const failures = [];
|
|
1290
|
+
for (const [index, item] of items.entries()) {
|
|
1291
|
+
const initialInputs = {};
|
|
1292
|
+
for (const edge of lane.entries) {
|
|
1293
|
+
initialInputs[edge.target] = {
|
|
1294
|
+
...initialInputs[edge.target] ?? {},
|
|
1295
|
+
[edge.targetHandle ?? "in"]: item
|
|
1296
|
+
};
|
|
1297
|
+
}
|
|
1298
|
+
const nested = await runFlow(lane.graph, { ...ctx.executors ?? {} }, () => {
|
|
1299
|
+
}, {
|
|
1300
|
+
initialInputs,
|
|
1301
|
+
depth: (ctx.depth ?? 0) + 1,
|
|
1302
|
+
// The index rides on the identity, so a node in iteration 3 cannot share
|
|
1303
|
+
// an idempotency key with the same node in iteration 4.
|
|
1304
|
+
run: ctx.run?.descend(ctx.node.id, index)
|
|
1305
|
+
});
|
|
1306
|
+
if (!nested.ok) {
|
|
1307
|
+
const reason = nested.error ?? "unknown error";
|
|
1308
|
+
if (decodePause(reason)) ctx.abort(reason);
|
|
1309
|
+
results.push(null);
|
|
1310
|
+
failures.push({ index, item, error: reason });
|
|
1311
|
+
continue;
|
|
1312
|
+
}
|
|
1313
|
+
results.push(nested.outputs);
|
|
1314
|
+
}
|
|
1315
|
+
return {
|
|
1316
|
+
__port: "done",
|
|
1317
|
+
value: { items, results, failures, count: items.length }
|
|
1318
|
+
};
|
|
1228
1319
|
};
|
|
1229
1320
|
var manualTriggerExecutor = (ctx) => ctx.inputs;
|
|
1230
1321
|
var outputExecutor = (ctx) => {
|
|
@@ -1781,6 +1872,15 @@ var KINDS = [
|
|
|
1781
1872
|
name: "@particle-academy/for_each",
|
|
1782
1873
|
outputShape: [
|
|
1783
1874
|
{ path: "items", type: "array" },
|
|
1875
|
+
// `results` and `failures` are the WIRED shape -- what a lane produces
|
|
1876
|
+
// when the `item` port is connected. Declared unconditionally because a
|
|
1877
|
+
// declaration describes the kind, not one graph's use of it, and because
|
|
1878
|
+
// the shared table requires them: fancy-conformance 0.30.0 added
|
|
1879
|
+
// `results` and 0.31.0 added `failures`, both BREAKING, both so that a
|
|
1880
|
+
// runtime which has not implemented iteration fails here rather than
|
|
1881
|
+
// reporting surface parity it does not have.
|
|
1882
|
+
{ path: "results", type: "array" },
|
|
1883
|
+
{ path: "failures", type: "array" },
|
|
1784
1884
|
{ path: "count", type: "number" }
|
|
1785
1885
|
],
|
|
1786
1886
|
aliases: ["for_each", "@fancy/for_each"],
|
|
@@ -1789,7 +1889,7 @@ var KINDS = [
|
|
|
1789
1889
|
executor: forEachExecutor,
|
|
1790
1890
|
category: "logic",
|
|
1791
1891
|
label: "For Each",
|
|
1792
|
-
description: "
|
|
1892
|
+
description: "Wire `item` to a lane and it runs once per item, aggregating `results` and `failures` on `done`. Leave `item` unwired (or set `mode: collect`) and it just publishes the list and its size -- one node, one checkpoint.",
|
|
1793
1893
|
icon: "\u21BB",
|
|
1794
1894
|
inputs: [{ id: "in" }],
|
|
1795
1895
|
outputs: [{ id: "item", label: "item" }, { id: "done", label: "done" }],
|