@particle-academy/fancy-flow 0.48.0 → 0.49.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/dist/{ConfigFieldRenderer-NuDjtun1.d.cts → ConfigFieldRenderer-CrXFq6Eb.d.cts} +2 -2
  2. package/dist/{ConfigFieldRenderer-DrD2-Qml.d.ts → ConfigFieldRenderer-u3nYHovX.d.ts} +2 -2
  3. package/dist/{FlowViewer-CY3_vHSg.d.cts → FlowViewer-CFSMlCqi.d.cts} +1 -1
  4. package/dist/{FlowViewer-DGW6t-80.d.ts → FlowViewer-DRgjeWJ7.d.ts} +1 -1
  5. package/dist/{capabilities-DMUhnyZD.d.ts → capabilities-B00VXLUp.d.ts} +1 -1
  6. package/dist/{capabilities-Dmd26aAs.d.cts → capabilities-VzgDApur.d.cts} +1 -1
  7. package/dist/{chunk-MJ3A3TAI.js → chunk-6FP3F5YR.js} +21 -4
  8. package/dist/chunk-6FP3F5YR.js.map +1 -0
  9. package/dist/{chunk-DRRZEAYB.js → chunk-6XKR65XM.js} +3 -3
  10. package/dist/{chunk-DRRZEAYB.js.map → chunk-6XKR65XM.js.map} +1 -1
  11. package/dist/{chunk-UVP43XU2.js → chunk-AVRGZFXG.js} +4 -4
  12. package/dist/{chunk-UVP43XU2.js.map → chunk-AVRGZFXG.js.map} +1 -1
  13. package/dist/{chunk-E6T3FZZP.js → chunk-UL3DGSSG.js} +9 -4
  14. package/dist/chunk-UL3DGSSG.js.map +1 -0
  15. package/dist/{chunk-7DTUZUTB.js → chunk-VUL7CUFW.js} +3 -3
  16. package/dist/{chunk-7DTUZUTB.js.map → chunk-VUL7CUFW.js.map} +1 -1
  17. package/dist/{chunk-KTGXZBUM.js → chunk-YOK3WKWC.js} +7 -3
  18. package/dist/chunk-YOK3WKWC.js.map +1 -0
  19. package/dist/connectors.d.cts +2 -2
  20. package/dist/connectors.d.ts +2 -2
  21. package/dist/durable/index.d.cts +2 -2
  22. package/dist/durable/index.d.ts +2 -2
  23. package/dist/durable.cjs +19 -2
  24. package/dist/durable.cjs.map +1 -1
  25. package/dist/durable.js +1 -1
  26. package/dist/engine.cjs +19 -2
  27. package/dist/engine.cjs.map +1 -1
  28. package/dist/engine.d.cts +7 -7
  29. package/dist/engine.d.ts +7 -7
  30. package/dist/engine.js +3 -3
  31. package/dist/fields/react-fancy.d.cts +3 -3
  32. package/dist/fields/react-fancy.d.ts +3 -3
  33. package/dist/index.cjs +60 -3
  34. package/dist/index.cjs.map +1 -1
  35. package/dist/index.d.cts +11 -11
  36. package/dist/index.d.ts +11 -11
  37. package/dist/index.js +42 -11
  38. package/dist/index.js.map +1 -1
  39. package/dist/layout/index.d.cts +1 -1
  40. package/dist/layout/index.d.ts +1 -1
  41. package/dist/llm/prism.d.cts +2 -2
  42. package/dist/llm/prism.d.ts +2 -2
  43. package/dist/llm/vercel-ai.d.cts +2 -2
  44. package/dist/llm/vercel-ai.d.ts +2 -2
  45. package/dist/registry/index.d.cts +6 -6
  46. package/dist/registry/index.d.ts +6 -6
  47. package/dist/{registry-DpARG95T.d.ts → registry-6cB5wCv6.d.ts} +1 -1
  48. package/dist/{registry-BnnifM-t.d.cts → registry-DQh7ZmnM.d.cts} +1 -1
  49. package/dist/registry.cjs +19 -2
  50. package/dist/registry.cjs.map +1 -1
  51. package/dist/registry.js +2 -2
  52. package/dist/{run-cohort-DdPPowJ3.d.cts → run-cohort-DYCL8Qv6.d.cts} +2 -2
  53. package/dist/{run-cohort-Cyeny2Uu.d.ts → run-cohort-VX4JG21l.d.ts} +2 -2
  54. package/dist/{run-flow-1KiXhy59.d.cts → run-flow-B24QUO1H.d.cts} +1 -1
  55. package/dist/{run-flow-CQvTDBYk.d.ts → run-flow-DPUPAWk6.d.ts} +1 -1
  56. package/dist/runtime/index.d.cts +18 -6
  57. package/dist/runtime/index.d.ts +18 -6
  58. package/dist/runtime.cjs +25 -3
  59. package/dist/runtime.cjs.map +1 -1
  60. package/dist/runtime.js +3 -3
  61. package/dist/schema/index.d.cts +9 -1
  62. package/dist/schema/index.d.ts +9 -1
  63. package/dist/schema.cjs +23 -2
  64. package/dist/schema.cjs.map +1 -1
  65. package/dist/schema.js +2 -2
  66. package/dist/screens.cjs +19 -2
  67. package/dist/screens.cjs.map +1 -1
  68. package/dist/screens.d.cts +2 -2
  69. package/dist/screens.d.ts +2 -2
  70. package/dist/screens.js +4 -4
  71. package/dist/{types-Jx1TwehV.d.ts → types-7cXcSQlx.d.cts} +50 -0
  72. package/dist/{types-Jx1TwehV.d.cts → types-7cXcSQlx.d.ts} +50 -0
  73. package/dist/{types-BO8TgI2M.d.cts → types-BtMOnb9I.d.cts} +1 -1
  74. package/dist/{types-DJAmfiJC.d.ts → types-CDgIIj4c.d.ts} +1 -1
  75. package/dist/ux.cjs +19 -2
  76. package/dist/ux.cjs.map +1 -1
  77. package/dist/ux.d.cts +2 -2
  78. package/dist/ux.d.ts +2 -2
  79. package/dist/ux.js +1 -1
  80. package/package.json +1 -1
  81. package/dist/chunk-E6T3FZZP.js.map +0 -1
  82. package/dist/chunk-KTGXZBUM.js.map +0 -1
  83. package/dist/chunk-MJ3A3TAI.js.map +0 -1
@@ -1,6 +1,6 @@
1
- export { F as FlowNodeStatus, a as FlowViewer, b as FlowViewerClassNames, c as FlowViewerProps } from './FlowViewer-CY3_vHSg.cjs';
1
+ export { F as FlowNodeStatus, a as FlowViewer, b as FlowViewerClassNames, c as FlowViewerProps } from './FlowViewer-CFSMlCqi.cjs';
2
2
  import 'react';
3
- import './types-Jx1TwehV.cjs';
3
+ import './types-7cXcSQlx.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-DGW6t-80.js';
1
+ export { F as FlowNodeStatus, a as FlowViewer, b as FlowViewerClassNames, c as FlowViewerProps } from './FlowViewer-DRgjeWJ7.js';
2
2
  import 'react';
3
- import './types-Jx1TwehV.js';
3
+ import './types-7cXcSQlx.js';
4
4
  import '@xyflow/react';
5
5
 
6
6
  /**
package/dist/screens.js CHANGED
@@ -1,8 +1,8 @@
1
- import { FlowViewer } from './chunk-UVP43XU2.js';
2
- export { FlowViewer } from './chunk-UVP43XU2.js';
3
- import './chunk-DRRZEAYB.js';
1
+ import { FlowViewer } from './chunk-AVRGZFXG.js';
2
+ export { FlowViewer } from './chunk-AVRGZFXG.js';
3
+ import './chunk-6XKR65XM.js';
4
4
  import './chunk-UEOE6B52.js';
5
- import './chunk-MJ3A3TAI.js';
5
+ import './chunk-6FP3F5YR.js';
6
6
  import './chunk-F5RPRB7A.js';
7
7
  import './chunk-USL4FMFU.js';
8
8
  import { registerSchemaComponents } from '@particle-academy/fancy-screens';
@@ -152,6 +152,23 @@ type BaseNodeData = {
152
152
  status?: NodeRunStatus;
153
153
  /** Optional human-readable status detail (e.g. error message, current step). */
154
154
  statusText?: string;
155
+ /**
156
+ * Announced to a person just BEFORE this node runs — "Starting the deep
157
+ * analysis". Authored on the node, so a graph narrates itself without the
158
+ * host writing any per-node reporting code.
159
+ *
160
+ * Optional on purpose. Most nodes in a real graph are plumbing, and a run
161
+ * that narrates all of them buries the two or three steps anyone follows.
162
+ */
163
+ startingMsg?: string;
164
+ /**
165
+ * Announced AFTER this node finishes — "Analysis complete".
166
+ *
167
+ * Emitted only when the node SUCCEEDS. A completion message printed after a
168
+ * failure tells a human the opposite of what happened, in the part of the UI
169
+ * they trust most; failures report through `node-status` and `log`.
170
+ */
171
+ stoppingMsg?: string;
155
172
  /** Per-node accent override, e.g. for theming a custom subclass. */
156
173
  color?: string;
157
174
  /** Input ports rendered on the node. Defaults vary by kind. */
@@ -198,6 +215,21 @@ type NodeExecutor<TIn = Record<string, unknown>, TOut = unknown> = (ctx: {
198
215
  abort: (reason?: string) => never;
199
216
  /** Lets the executor stream status updates and partial outputs. */
200
217
  emit: (event: RunEvent) => void;
218
+ /**
219
+ * The registry THIS run is executing against.
220
+ *
221
+ * Handed down so an executor that starts a NESTED run gives the child the
222
+ * same executors as the parent. `subflow` previously ran its child against
223
+ * `config.executors ?? {}` — an empty registry unless the graph happened to
224
+ * carry one — so a host kind resolved at top level and vanished one level
225
+ * down, and a host that had REPLACED a builtin got the package's version in
226
+ * the child. Same graph, different behaviour by nesting depth, reported
227
+ * against the PHP twin as fancy-flow-php#7.
228
+ *
229
+ * Inheriting from the context rather than from a parameter is what makes it
230
+ * unforgettable: any future nesting executor gets it without opting in.
231
+ */
232
+ executors?: ExecutorRegistry;
201
233
  /**
202
234
  * How deep this run is nested. 0 for a top-level run; `subflow` passes
203
235
  * depth + 1 to its child, so runaway recursion can be reported by name
@@ -223,6 +255,24 @@ type RunEvent = {
223
255
  nodeId: string;
224
256
  status: NodeRunStatus;
225
257
  text?: string;
258
+ }
259
+ /**
260
+ * A human-facing announcement a node makes around its own execution, from
261
+ * `data.startingMsg` / `data.stoppingMsg`. Opt-in per node: most nodes in a
262
+ * real graph are plumbing, and narrating all of them buries the few steps a
263
+ * person cares about.
264
+ *
265
+ * Deliberately NOT folded into `node-status.text`, which already carries
266
+ * "skipped", "resumed", "lane", "annotation" and raw error strings. Those are
267
+ * diagnostics; these are addressed to a person. A consumer rendering a
268
+ * progress feed cannot be asked to guess which is which — that is how an
269
+ * error string ends up shown to a user as a status update.
270
+ */
271
+ | {
272
+ type: "node-message";
273
+ nodeId: string;
274
+ phase: "start" | "end";
275
+ message: string;
226
276
  } | {
227
277
  type: "node-output";
228
278
  nodeId: string;
@@ -152,6 +152,23 @@ type BaseNodeData = {
152
152
  status?: NodeRunStatus;
153
153
  /** Optional human-readable status detail (e.g. error message, current step). */
154
154
  statusText?: string;
155
+ /**
156
+ * Announced to a person just BEFORE this node runs — "Starting the deep
157
+ * analysis". Authored on the node, so a graph narrates itself without the
158
+ * host writing any per-node reporting code.
159
+ *
160
+ * Optional on purpose. Most nodes in a real graph are plumbing, and a run
161
+ * that narrates all of them buries the two or three steps anyone follows.
162
+ */
163
+ startingMsg?: string;
164
+ /**
165
+ * Announced AFTER this node finishes — "Analysis complete".
166
+ *
167
+ * Emitted only when the node SUCCEEDS. A completion message printed after a
168
+ * failure tells a human the opposite of what happened, in the part of the UI
169
+ * they trust most; failures report through `node-status` and `log`.
170
+ */
171
+ stoppingMsg?: string;
155
172
  /** Per-node accent override, e.g. for theming a custom subclass. */
156
173
  color?: string;
157
174
  /** Input ports rendered on the node. Defaults vary by kind. */
@@ -198,6 +215,21 @@ type NodeExecutor<TIn = Record<string, unknown>, TOut = unknown> = (ctx: {
198
215
  abort: (reason?: string) => never;
199
216
  /** Lets the executor stream status updates and partial outputs. */
200
217
  emit: (event: RunEvent) => void;
218
+ /**
219
+ * The registry THIS run is executing against.
220
+ *
221
+ * Handed down so an executor that starts a NESTED run gives the child the
222
+ * same executors as the parent. `subflow` previously ran its child against
223
+ * `config.executors ?? {}` — an empty registry unless the graph happened to
224
+ * carry one — so a host kind resolved at top level and vanished one level
225
+ * down, and a host that had REPLACED a builtin got the package's version in
226
+ * the child. Same graph, different behaviour by nesting depth, reported
227
+ * against the PHP twin as fancy-flow-php#7.
228
+ *
229
+ * Inheriting from the context rather than from a parameter is what makes it
230
+ * unforgettable: any future nesting executor gets it without opting in.
231
+ */
232
+ executors?: ExecutorRegistry;
201
233
  /**
202
234
  * How deep this run is nested. 0 for a top-level run; `subflow` passes
203
235
  * depth + 1 to its child, so runaway recursion can be reported by name
@@ -223,6 +255,24 @@ type RunEvent = {
223
255
  nodeId: string;
224
256
  status: NodeRunStatus;
225
257
  text?: string;
258
+ }
259
+ /**
260
+ * A human-facing announcement a node makes around its own execution, from
261
+ * `data.startingMsg` / `data.stoppingMsg`. Opt-in per node: most nodes in a
262
+ * real graph are plumbing, and narrating all of them buries the few steps a
263
+ * person cares about.
264
+ *
265
+ * Deliberately NOT folded into `node-status.text`, which already carries
266
+ * "skipped", "resumed", "lane", "annotation" and raw error strings. Those are
267
+ * diagnostics; these are addressed to a person. A consumer rendering a
268
+ * progress feed cannot be asked to guess which is which — that is how an
269
+ * error string ends up shown to a user as a status update.
270
+ */
271
+ | {
272
+ type: "node-message";
273
+ nodeId: string;
274
+ phase: "start" | "end";
275
+ message: string;
226
276
  } | {
227
277
  type: "node-output";
228
278
  nodeId: string;
@@ -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-Jx1TwehV.cjs';
2
+ import { F as FlowGraph, a as FlowNode, P as PortDescriptor, N as NodeExecutor } from './types-7cXcSQlx.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-Jx1TwehV.js';
2
+ import { F as FlowGraph, a as FlowNode, P as PortDescriptor, N as NodeExecutor } from './types-7cXcSQlx.js';
3
3
  import { NodeProps } from '@xyflow/react';
4
4
  import { P as PauseAwaiting } from './pause-9iT4tCEV.js';
5
5
 
package/dist/ux.cjs CHANGED
@@ -9282,6 +9282,7 @@ async function runFlow(graph, executors, onEvent = () => {
9282
9282
  continue;
9283
9283
  }
9284
9284
  onEvent({ type: "node-status", nodeId: node.id, status: "running" });
9285
+ announce(onEvent, node, "start");
9285
9286
  const inputs = collectInputs(node, incoming, portValues, initialInputs);
9286
9287
  const exec = pickExecutor(executors, node);
9287
9288
  if (!exec) {
@@ -9300,6 +9301,7 @@ async function runFlow(graph, executors, onEvent = () => {
9300
9301
  throw new Error(reason ?? "aborted");
9301
9302
  },
9302
9303
  emit: onEvent,
9304
+ executors,
9303
9305
  depth,
9304
9306
  run
9305
9307
  })
@@ -9312,6 +9314,7 @@ async function runFlow(graph, executors, onEvent = () => {
9312
9314
  }
9313
9315
  completed.add(node.id);
9314
9316
  onEvent({ type: "node-status", nodeId: node.id, status: "done" });
9317
+ announce(onEvent, node, "end");
9315
9318
  } catch (e) {
9316
9319
  const msg = e instanceof Error ? e.message : String(e);
9317
9320
  errors.push(msg);
@@ -9370,7 +9373,10 @@ function collectInputs(node, incoming, portValues, initial) {
9370
9373
  function pickExecutor(executors, node) {
9371
9374
  if (executors[node.id]) return executors[node.id];
9372
9375
  if (node.type && executors[node.type]) return executors[node.type];
9373
- const kind = node.type ? getNodeKind(node.type) : null;
9376
+ const declared = node.data?.kind;
9377
+ const kindName = typeof declared === "string" && declared !== "" ? declared : node.type;
9378
+ if (kindName && kindName !== node.type && executors[kindName]) return executors[kindName];
9379
+ const kind = kindName ? getNodeKind(kindName) : null;
9374
9380
  if (kind) {
9375
9381
  for (const id2 of kindIds(kind)) {
9376
9382
  if (executors[id2]) return executors[id2];
@@ -9392,6 +9398,14 @@ function activatedPorts(node, result) {
9392
9398
  const declared = resolveNodePorts(node, kind).outputs?.map((p) => p.id);
9393
9399
  return { ports: declared?.length ? declared : ["out"], value: result };
9394
9400
  }
9401
+ function announce(onEvent, node, phase) {
9402
+ const data = node.data;
9403
+ const raw = phase === "start" ? data?.startingMsg : data?.stoppingMsg;
9404
+ if (typeof raw !== "string") return;
9405
+ const message = raw.trim();
9406
+ if (message === "") return;
9407
+ onEvent({ type: "node-message", nodeId: node.id, phase, message });
9408
+ }
9395
9409
 
9396
9410
  // src/registry/subflow.ts
9397
9411
  var DEFAULT_MAX_DEPTH = 8;
@@ -9445,7 +9459,10 @@ var subflowExecutor = async (ctx) => {
9445
9459
  };
9446
9460
  const result = await runFlow(
9447
9461
  child,
9448
- config.executors ?? {},
9462
+ // Inherit the parent's registry, then let the graph layer its own on top.
9463
+ // The inherited half is the fix; the layered half keeps a graph that
9464
+ // deliberately hands its child extra or different executors working.
9465
+ { ...ctx.executors ?? {}, ...config.executors ?? {} },
9449
9466
  forward,
9450
9467
  {
9451
9468
  initialInputs: config.inputs ?? {