@particle-academy/fancy-flow 0.49.0 → 0.51.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 (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-6XKR65XM.js → chunk-6AI6CBNL.js} +3 -3
  8. package/dist/{chunk-6XKR65XM.js.map → chunk-6AI6CBNL.js.map} +1 -1
  9. package/dist/{chunk-AVRGZFXG.js → chunk-7XTTXMGB.js} +4 -4
  10. package/dist/{chunk-AVRGZFXG.js.map → chunk-7XTTXMGB.js.map} +1 -1
  11. package/dist/{chunk-UL3DGSSG.js → chunk-HXGGCMR7.js} +3 -3
  12. package/dist/{chunk-UL3DGSSG.js.map → chunk-HXGGCMR7.js.map} +1 -1
  13. package/dist/{chunk-YOK3WKWC.js → chunk-LH76EIFL.js} +18 -4
  14. package/dist/chunk-LH76EIFL.js.map +1 -0
  15. package/dist/{chunk-VUL7CUFW.js → chunk-SKEZ5AGI.js} +3 -3
  16. package/dist/{chunk-VUL7CUFW.js.map → chunk-SKEZ5AGI.js.map} +1 -1
  17. package/dist/{chunk-6FP3F5YR.js → chunk-XCT2CJ5O.js} +75 -4
  18. package/dist/chunk-XCT2CJ5O.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 +73 -2
  24. package/dist/durable.cjs.map +1 -1
  25. package/dist/durable.js +1 -1
  26. package/dist/engine.cjs +73 -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 +88 -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 +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 +73 -2
  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 +73 -2
  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 +88 -3
  63. package/dist/schema.cjs.map +1 -1
  64. package/dist/schema.js +2 -2
  65. package/dist/screens.cjs +73 -2
  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.ts → types-JFYjPJAG.d.cts} +37 -1
  72. package/dist/{types-7cXcSQlx.d.cts → types-JFYjPJAG.d.ts} +37 -1
  73. package/dist/{types-CDgIIj4c.d.ts → types-s643U1Hi.d.ts} +1 -1
  74. package/dist/ux.cjs +73 -2
  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-6FP3F5YR.js.map +0 -1
  81. package/dist/chunk-YOK3WKWC.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-AVRGZFXG.js';
2
- export { FlowViewer } from './chunk-AVRGZFXG.js';
3
- import './chunk-6XKR65XM.js';
1
+ import { FlowViewer } from './chunk-7XTTXMGB.js';
2
+ export { FlowViewer } from './chunk-7XTTXMGB.js';
3
+ import './chunk-6AI6CBNL.js';
4
4
  import './chunk-UEOE6B52.js';
5
- import './chunk-6FP3F5YR.js';
5
+ import './chunk-XCT2CJ5O.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,7 +9345,7 @@ 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
9351
  const msg = `No executor registered for kind=${node.type}`;
@@ -9360,14 +9422,23 @@ function topoSort(graph) {
9360
9422
  const byId = new Map(graph.nodes.map((n) => [n.id, n]));
9361
9423
  return ordered.map((id2) => byId.get(id2)).filter(Boolean);
9362
9424
  }
9363
- function collectInputs(node, incoming, portValues, initial) {
9425
+ function collectInputs(node, incoming, portValues, initial, props, declaresProps) {
9364
9426
  const inputs = { ...initial[node.id] ?? {} };
9427
+ if (incoming.length === 0) {
9428
+ for (const [name, value] of Object.entries(props)) {
9429
+ if (!(name in inputs)) inputs[name] = value;
9430
+ }
9431
+ }
9365
9432
  for (const e of incoming) {
9366
9433
  const portId = e.targetHandle ?? "in";
9367
9434
  const key = `${e.source}:${e.sourceHandle ?? "out"}`;
9368
9435
  if (!portValues.has(key)) continue;
9369
9436
  inputs[portId] = portValues.get(key);
9437
+ if (e.targetHandle == null && !(e.source in inputs)) {
9438
+ inputs[e.source] = portValues.get(key);
9439
+ }
9370
9440
  }
9441
+ if (declaresProps) inputs.$props = props;
9371
9442
  return inputs;
9372
9443
  }
9373
9444
  function pickExecutor(executors, node) {