@particle-academy/fancy-flow 0.50.0 → 0.51.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 (81) hide show
  1. package/dist/{ConfigFieldRenderer-CrXFq6Eb.d.cts → ConfigFieldRenderer-Bc9Txnql.d.cts} +2 -2
  2. package/dist/{ConfigFieldRenderer-u3nYHovX.d.ts → ConfigFieldRenderer-Bt3RGT7Z.d.ts} +2 -2
  3. package/dist/{FlowViewer-DRgjeWJ7.d.ts → FlowViewer-BI_AyyvU.d.ts} +1 -1
  4. package/dist/{FlowViewer-CFSMlCqi.d.cts → FlowViewer-DABx-6A-.d.cts} +1 -1
  5. package/dist/{capabilities-VzgDApur.d.cts → capabilities-BYa5p5jw.d.cts} +1 -1
  6. package/dist/{capabilities-B00VXLUp.d.ts → capabilities-COOXRiNL.d.ts} +1 -1
  7. package/dist/{chunk-XJMWMU4J.js → chunk-4GO2CHAY.js} +90 -7
  8. package/dist/chunk-4GO2CHAY.js.map +1 -0
  9. package/dist/{chunk-OWDSPRAF.js → chunk-OECW2E5D.js} +4 -4
  10. package/dist/{chunk-OWDSPRAF.js.map → chunk-OECW2E5D.js.map} +1 -1
  11. package/dist/{chunk-BAHJVX3S.js → chunk-OK7KJLWA.js} +3 -3
  12. package/dist/{chunk-BAHJVX3S.js.map → chunk-OK7KJLWA.js.map} +1 -1
  13. package/dist/{chunk-I4F6GI3A.js → chunk-RSRXKZ52.js} +3 -3
  14. package/dist/{chunk-I4F6GI3A.js.map → chunk-RSRXKZ52.js.map} +1 -1
  15. package/dist/{chunk-3W26FA7Q.js → chunk-SPINP4EJ.js} +18 -4
  16. package/dist/chunk-SPINP4EJ.js.map +1 -0
  17. package/dist/{chunk-DQJIU55F.js → chunk-VUU3CDBT.js} +3 -3
  18. package/dist/{chunk-DQJIU55F.js.map → chunk-VUU3CDBT.js.map} +1 -1
  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 +88 -5
  24. package/dist/durable.cjs.map +1 -1
  25. package/dist/durable.js +1 -1
  26. package/dist/engine.cjs +88 -5
  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 +103 -6
  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 +11 -11
  38. package/dist/layout/index.d.cts +1 -1
  39. package/dist/layout/index.d.ts +1 -1
  40. package/dist/llm/prism.d.cts +2 -2
  41. package/dist/llm/prism.d.ts +2 -2
  42. package/dist/llm/vercel-ai.d.cts +2 -2
  43. package/dist/llm/vercel-ai.d.ts +2 -2
  44. package/dist/registry/index.d.cts +6 -6
  45. package/dist/registry/index.d.ts +6 -6
  46. package/dist/{registry-6cB5wCv6.d.ts → registry-3RkSYrMi.d.ts} +1 -1
  47. package/dist/{registry-DQh7ZmnM.d.cts → registry-C6TMfiD_.d.cts} +1 -1
  48. package/dist/registry.cjs +88 -5
  49. package/dist/registry.cjs.map +1 -1
  50. package/dist/registry.js +2 -2
  51. package/dist/{run-cohort-VX4JG21l.d.ts → run-cohort-BPIOpE8A.d.ts} +2 -2
  52. package/dist/{run-cohort-DYCL8Qv6.d.cts → run-cohort-r-L8dMED.d.cts} +2 -2
  53. package/dist/{run-flow-B24QUO1H.d.cts → run-flow-COdAOFg2.d.cts} +10 -1
  54. package/dist/{run-flow-DPUPAWk6.d.ts → run-flow-DJ7KYT6E.d.ts} +10 -1
  55. package/dist/runtime/index.d.cts +5 -5
  56. package/dist/runtime/index.d.ts +5 -5
  57. package/dist/runtime.cjs +88 -5
  58. package/dist/runtime.cjs.map +1 -1
  59. package/dist/runtime.js +3 -3
  60. package/dist/schema/index.d.cts +12 -1
  61. package/dist/schema/index.d.ts +12 -1
  62. package/dist/schema.cjs +103 -6
  63. package/dist/schema.cjs.map +1 -1
  64. package/dist/schema.js +2 -2
  65. package/dist/screens.cjs +88 -5
  66. package/dist/screens.cjs.map +1 -1
  67. package/dist/screens.d.cts +2 -2
  68. package/dist/screens.d.ts +2 -2
  69. package/dist/screens.js +4 -4
  70. package/dist/{types-BtMOnb9I.d.cts → types-3sPauVRT.d.cts} +1 -1
  71. package/dist/{types-7cXcSQlx.d.cts → types-JFYjPJAG.d.cts} +37 -1
  72. package/dist/{types-7cXcSQlx.d.ts → types-JFYjPJAG.d.ts} +37 -1
  73. package/dist/{types-CDgIIj4c.d.ts → types-s643U1Hi.d.ts} +1 -1
  74. package/dist/ux.cjs +88 -5
  75. package/dist/ux.cjs.map +1 -1
  76. package/dist/ux.d.cts +2 -2
  77. package/dist/ux.d.ts +2 -2
  78. package/dist/ux.js +1 -1
  79. package/package.json +1 -1
  80. package/dist/chunk-3W26FA7Q.js.map +0 -1
  81. package/dist/chunk-XJMWMU4J.js.map +0 -1
@@ -1,6 +1,6 @@
1
- export { F as FlowNodeStatus, a as FlowViewer, b as FlowViewerClassNames, c as FlowViewerProps } from './FlowViewer-CFSMlCqi.cjs';
1
+ export { F as FlowNodeStatus, a as FlowViewer, b as FlowViewerClassNames, c as FlowViewerProps } from './FlowViewer-DABx-6A-.cjs';
2
2
  import 'react';
3
- import './types-7cXcSQlx.cjs';
3
+ import './types-JFYjPJAG.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-DRgjeWJ7.js';
1
+ export { F as FlowNodeStatus, a as FlowViewer, b as FlowViewerClassNames, c as FlowViewerProps } from './FlowViewer-BI_AyyvU.js';
2
2
  import 'react';
3
- import './types-7cXcSQlx.js';
3
+ import './types-JFYjPJAG.js';
4
4
  import '@xyflow/react';
5
5
 
6
6
  /**
package/dist/screens.js CHANGED
@@ -1,8 +1,8 @@
1
- import { FlowViewer } from './chunk-OWDSPRAF.js';
2
- export { FlowViewer } from './chunk-OWDSPRAF.js';
3
- import './chunk-I4F6GI3A.js';
1
+ import { FlowViewer } from './chunk-OECW2E5D.js';
2
+ export { FlowViewer } from './chunk-OECW2E5D.js';
3
+ import './chunk-RSRXKZ52.js';
4
4
  import './chunk-UEOE6B52.js';
5
- import './chunk-XJMWMU4J.js';
5
+ import './chunk-4GO2CHAY.js';
6
6
  import './chunk-F5RPRB7A.js';
7
7
  import './chunk-USL4FMFU.js';
8
8
  import { registerSchemaComponents } from '@particle-academy/fancy-screens';
@@ -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-7cXcSQlx.cjs';
2
+ import { F as FlowGraph, a as FlowNode, P as PortDescriptor, N as NodeExecutor } from './types-JFYjPJAG.cjs';
3
3
  import { NodeProps } from '@xyflow/react';
4
4
  import { P as PauseAwaiting } from './pause-9iT4tCEV.cjs';
5
5
 
@@ -202,10 +202,46 @@ type SubgraphNodeData = BaseNodeData & {
202
202
  type FlowNodeData = TriggerNodeData | ActionNodeData | DecisionNodeData | OutputNodeData | NoteNodeData | SubgraphNodeData;
203
203
  type FlowNode = Node<FlowNodeData>;
204
204
  type FlowEdge = Edge;
205
+ /**
206
+ * One value a workflow DECLARES that it accepts at run start.
207
+ *
208
+ * The declaration is the point. Before this existed, a caller passed
209
+ * `initialInputs` keyed BY NODE ID — so they had to know the trigger happened
210
+ * to be called `t`, and renaming that node broke every caller while the graph
211
+ * itself stayed valid. Nothing reported it.
212
+ *
213
+ * And nothing said what a workflow accepted at all: no names, no types, no
214
+ * defaults. An agent composing a call had nothing to read, and a misspelled key
215
+ * did not fail — the value simply sat unused while the run reported success.
216
+ */
217
+ type WorkflowInput = {
218
+ /** What a caller passes it as. */
219
+ name: string;
220
+ /**
221
+ * Optional. Omitting it means "I am not asserting a shape", which must not
222
+ * degrade into "nothing is allowed" — an undeclared type accepts anything.
223
+ */
224
+ type?: "string" | "number" | "boolean" | "object" | "array";
225
+ /**
226
+ * The run needs a value. Satisfied by a `default`, so `required` means
227
+ * "this must resolve to something" rather than "the caller must type it".
228
+ */
229
+ required?: boolean;
230
+ /** Used when the caller omits the key. An explicit value always wins. */
231
+ default?: unknown;
232
+ description?: string;
233
+ };
205
234
  /** A serializable graph — what hosts persist, what agents read/write. */
206
235
  type FlowGraph = {
207
236
  nodes: FlowNode[];
208
237
  edges: FlowEdge[];
238
+ /**
239
+ * What this workflow accepts. Callers pass a flat object BY NAME.
240
+ *
241
+ * Omitted entirely when a graph takes none, so existing saved graphs are
242
+ * unchanged byte for byte and every diff stays readable.
243
+ */
244
+ inputs?: WorkflowInput[];
209
245
  };
210
246
  /** Per-node executor signature. Inputs are keyed by input-port id. */
211
247
  type NodeExecutor<TIn = Record<string, unknown>, TOut = unknown> = (ctx: {
@@ -294,4 +330,4 @@ type RunEvent = {
294
330
  error: string;
295
331
  };
296
332
 
297
- export { type ActionNodeData as A, type BaseNodeData as B, type DecisionNodeData as D, type ExecutorRegistry as E, type FlowGraph as F, type NodeExecutor as N, type OutputNodeData as O, type PortDescriptor as P, type RunEvent as R, type SubgraphNodeData as S, type TriggerNodeData as T, type FlowNode as a, RunIdentity as b, type RunIdentityJson as c, type FlowEdge as d, type FlowNodeData as e, type FlowNodeKind as f, type NodeRunStatus as g, type NoteNodeData as h, escapeSegment as i };
333
+ export { type ActionNodeData as A, type BaseNodeData as B, type DecisionNodeData as D, type ExecutorRegistry as E, type FlowGraph as F, type NodeExecutor as N, type OutputNodeData as O, type PortDescriptor as P, type RunEvent as R, type SubgraphNodeData as S, type TriggerNodeData as T, type WorkflowInput as W, type FlowNode as a, RunIdentity as b, type RunIdentityJson as c, type FlowEdge as d, type FlowNodeData as e, type FlowNodeKind as f, type NodeRunStatus as g, type NoteNodeData as h, escapeSegment as i };
@@ -202,10 +202,46 @@ type SubgraphNodeData = BaseNodeData & {
202
202
  type FlowNodeData = TriggerNodeData | ActionNodeData | DecisionNodeData | OutputNodeData | NoteNodeData | SubgraphNodeData;
203
203
  type FlowNode = Node<FlowNodeData>;
204
204
  type FlowEdge = Edge;
205
+ /**
206
+ * One value a workflow DECLARES that it accepts at run start.
207
+ *
208
+ * The declaration is the point. Before this existed, a caller passed
209
+ * `initialInputs` keyed BY NODE ID — so they had to know the trigger happened
210
+ * to be called `t`, and renaming that node broke every caller while the graph
211
+ * itself stayed valid. Nothing reported it.
212
+ *
213
+ * And nothing said what a workflow accepted at all: no names, no types, no
214
+ * defaults. An agent composing a call had nothing to read, and a misspelled key
215
+ * did not fail — the value simply sat unused while the run reported success.
216
+ */
217
+ type WorkflowInput = {
218
+ /** What a caller passes it as. */
219
+ name: string;
220
+ /**
221
+ * Optional. Omitting it means "I am not asserting a shape", which must not
222
+ * degrade into "nothing is allowed" — an undeclared type accepts anything.
223
+ */
224
+ type?: "string" | "number" | "boolean" | "object" | "array";
225
+ /**
226
+ * The run needs a value. Satisfied by a `default`, so `required` means
227
+ * "this must resolve to something" rather than "the caller must type it".
228
+ */
229
+ required?: boolean;
230
+ /** Used when the caller omits the key. An explicit value always wins. */
231
+ default?: unknown;
232
+ description?: string;
233
+ };
205
234
  /** A serializable graph — what hosts persist, what agents read/write. */
206
235
  type FlowGraph = {
207
236
  nodes: FlowNode[];
208
237
  edges: FlowEdge[];
238
+ /**
239
+ * What this workflow accepts. Callers pass a flat object BY NAME.
240
+ *
241
+ * Omitted entirely when a graph takes none, so existing saved graphs are
242
+ * unchanged byte for byte and every diff stays readable.
243
+ */
244
+ inputs?: WorkflowInput[];
209
245
  };
210
246
  /** Per-node executor signature. Inputs are keyed by input-port id. */
211
247
  type NodeExecutor<TIn = Record<string, unknown>, TOut = unknown> = (ctx: {
@@ -294,4 +330,4 @@ type RunEvent = {
294
330
  error: string;
295
331
  };
296
332
 
297
- export { type ActionNodeData as A, type BaseNodeData as B, type DecisionNodeData as D, type ExecutorRegistry as E, type FlowGraph as F, type NodeExecutor as N, type OutputNodeData as O, type PortDescriptor as P, type RunEvent as R, type SubgraphNodeData as S, type TriggerNodeData as T, type FlowNode as a, RunIdentity as b, type RunIdentityJson as c, type FlowEdge as d, type FlowNodeData as e, type FlowNodeKind as f, type NodeRunStatus as g, type NoteNodeData as h, escapeSegment as i };
333
+ export { type ActionNodeData as A, type BaseNodeData as B, type DecisionNodeData as D, type ExecutorRegistry as E, type FlowGraph as F, type NodeExecutor as N, type OutputNodeData as O, type PortDescriptor as P, type RunEvent as R, type SubgraphNodeData as S, type TriggerNodeData as T, type WorkflowInput as W, type FlowNode as a, RunIdentity as b, type RunIdentityJson as c, type FlowEdge as d, type FlowNodeData as e, type FlowNodeKind as f, type NodeRunStatus as g, type NoteNodeData as h, escapeSegment as i };
@@ -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-7cXcSQlx.js';
2
+ import { F as FlowGraph, a as FlowNode, P as PortDescriptor, N as NodeExecutor } from './types-JFYjPJAG.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
@@ -9227,6 +9227,61 @@ var RunIdentity = class _RunIdentity {
9227
9227
  }
9228
9228
  };
9229
9229
 
9230
+ // src/runtime/workflow-props.ts
9231
+ function typeOf(value) {
9232
+ if (value === null) return "null";
9233
+ if (Array.isArray(value)) return "array";
9234
+ return typeof value;
9235
+ }
9236
+ function resolveWorkflowProps(declared, passed) {
9237
+ const inputs = declared ?? [];
9238
+ const given = passed ?? {};
9239
+ const byName = new Map(inputs.map((input) => [input.name, input]));
9240
+ for (const name of Object.keys(given)) {
9241
+ if (!byName.has(name)) {
9242
+ const known = inputs.map((input) => input.name);
9243
+ const suffix = known.length === 0 ? "this workflow declares no inputs" : `known inputs: ${known.join(", ")}`;
9244
+ return {
9245
+ ok: false,
9246
+ code: "unknown_input",
9247
+ error: `Unknown workflow input "${name}" \u2014 ${suffix}.`
9248
+ };
9249
+ }
9250
+ }
9251
+ const resolved = {};
9252
+ for (const input of inputs) {
9253
+ const supplied = Object.prototype.hasOwnProperty.call(given, input.name);
9254
+ const hasDefault = Object.prototype.hasOwnProperty.call(input, "default");
9255
+ if (!supplied) {
9256
+ if (hasDefault) {
9257
+ resolved[input.name] = input.default;
9258
+ continue;
9259
+ }
9260
+ if (input.required) {
9261
+ return {
9262
+ ok: false,
9263
+ code: "missing_required",
9264
+ error: `Missing required workflow input "${input.name}"${input.type ? ` (${input.type})` : ""}.`
9265
+ };
9266
+ }
9267
+ continue;
9268
+ }
9269
+ const value = given[input.name];
9270
+ if (input.type !== void 0) {
9271
+ const actual = typeOf(value);
9272
+ if (actual !== input.type) {
9273
+ return {
9274
+ ok: false,
9275
+ code: "type_mismatch",
9276
+ error: `Workflow input "${input.name}" expects ${input.type}, got ${actual}.`
9277
+ };
9278
+ }
9279
+ }
9280
+ resolved[input.name] = value;
9281
+ }
9282
+ return { ok: true, props: resolved };
9283
+ }
9284
+
9230
9285
  // src/runtime/run-flow.ts
9231
9286
  async function runFlow(graph, executors, onEvent = () => {
9232
9287
  }, options = {}) {
@@ -9242,6 +9297,13 @@ async function runFlow(graph, executors, onEvent = () => {
9242
9297
  onEvent({ type: "run-error", error: msg });
9243
9298
  return { ok: false, outputs, error: msg };
9244
9299
  }
9300
+ const propsCheck = resolveWorkflowProps(graph.inputs, options.props);
9301
+ if (!propsCheck.ok) {
9302
+ onEvent({ type: "run-error", error: propsCheck.error });
9303
+ return { ok: false, outputs, error: propsCheck.error };
9304
+ }
9305
+ const props = propsCheck.props;
9306
+ const declaresProps = (graph.inputs?.length ?? 0) > 0;
9245
9307
  const incomingByNode = indexIncoming(graph.edges);
9246
9308
  const timer2 = timeoutMs ? setTimeout(() => errors.push(`Run timed out after ${timeoutMs}ms`), timeoutMs) : null;
9247
9309
  onEvent({ type: "run-start" });
@@ -9283,10 +9345,11 @@ async function runFlow(graph, executors, onEvent = () => {
9283
9345
  }
9284
9346
  onEvent({ type: "node-status", nodeId: node.id, status: "running" });
9285
9347
  announce(onEvent, node, "start");
9286
- const inputs = collectInputs(node, incoming, portValues, initialInputs);
9348
+ const inputs = collectInputs(node, incoming, portValues, initialInputs, props, declaresProps);
9287
9349
  const exec = pickExecutor(executors, node);
9288
9350
  if (!exec) {
9289
- const msg = `No executor registered for kind=${node.type}`;
9351
+ const tried = executorLookupIds(node);
9352
+ const msg = `No executor registered for kind=${node.type} \u2014 tried ${tried.map((id2) => `"${id2}"`).join(", ")} and the wildcard "*". Key your registry by one of those.`;
9290
9353
  errors.push(msg);
9291
9354
  onEvent({ type: "node-status", nodeId: node.id, status: "error", text: msg });
9292
9355
  onEvent({ type: "log", nodeId: node.id, level: "error", message: msg });
@@ -9360,8 +9423,13 @@ function topoSort(graph) {
9360
9423
  const byId = new Map(graph.nodes.map((n) => [n.id, n]));
9361
9424
  return ordered.map((id2) => byId.get(id2)).filter(Boolean);
9362
9425
  }
9363
- function collectInputs(node, incoming, portValues, initial) {
9426
+ function collectInputs(node, incoming, portValues, initial, props, declaresProps) {
9364
9427
  const inputs = { ...initial[node.id] ?? {} };
9428
+ if (incoming.length === 0) {
9429
+ for (const [name, value] of Object.entries(props)) {
9430
+ if (!(name in inputs)) inputs[name] = value;
9431
+ }
9432
+ }
9365
9433
  for (const e of incoming) {
9366
9434
  const portId = e.targetHandle ?? "in";
9367
9435
  const key = `${e.source}:${e.sourceHandle ?? "out"}`;
@@ -9371,16 +9439,31 @@ function collectInputs(node, incoming, portValues, initial) {
9371
9439
  inputs[e.source] = portValues.get(key);
9372
9440
  }
9373
9441
  }
9442
+ if (declaresProps) inputs.$props = props;
9374
9443
  return inputs;
9375
9444
  }
9445
+ function executorLookupIds(node) {
9446
+ const ids = [node.id];
9447
+ if (node.type) ids.push(node.type);
9448
+ const declared = node.data?.kind;
9449
+ const kindName = typeof declared === "string" && declared !== "" ? declared : node.type;
9450
+ if (kindName && kindName !== node.type) ids.push(kindName);
9451
+ for (const name of [kindName, node.type]) {
9452
+ const kind = name ? getNodeKind(name) : null;
9453
+ if (!kind) continue;
9454
+ for (const id2 of kindIds(kind)) ids.push(id2);
9455
+ }
9456
+ return [...new Set(ids)];
9457
+ }
9376
9458
  function pickExecutor(executors, node) {
9377
9459
  if (executors[node.id]) return executors[node.id];
9378
9460
  if (node.type && executors[node.type]) return executors[node.type];
9379
9461
  const declared = node.data?.kind;
9380
9462
  const kindName = typeof declared === "string" && declared !== "" ? declared : node.type;
9381
9463
  if (kindName && kindName !== node.type && executors[kindName]) return executors[kindName];
9382
- const kind = kindName ? getNodeKind(kindName) : null;
9383
- if (kind) {
9464
+ for (const name of [kindName, node.type]) {
9465
+ const kind = name ? getNodeKind(name) : null;
9466
+ if (!kind) continue;
9384
9467
  for (const id2 of kindIds(kind)) {
9385
9468
  if (executors[id2]) return executors[id2];
9386
9469
  }