@particle-academy/fancy-flow 0.11.0 → 0.13.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 (48) hide show
  1. package/dist/capabilities-B6r1Snfj.d.ts +77 -0
  2. package/dist/capabilities-D-V9Rxv1.d.cts +77 -0
  3. package/dist/chunk-BB45F6S3.js +38 -0
  4. package/dist/chunk-BB45F6S3.js.map +1 -0
  5. package/dist/{chunk-2NQT2A3I.js → chunk-L4AX73Q6.js} +5 -4
  6. package/dist/chunk-L4AX73Q6.js.map +1 -0
  7. package/dist/{chunk-3GMBLHTM.js → chunk-MFMRTRPO.js} +3 -3
  8. package/dist/{chunk-3GMBLHTM.js.map → chunk-MFMRTRPO.js.map} +1 -1
  9. package/dist/{chunk-YNOI7ONN.js → chunk-WEZJFMLV.js} +224 -51
  10. package/dist/chunk-WEZJFMLV.js.map +1 -0
  11. package/dist/engine.cjs +3 -2
  12. package/dist/engine.cjs.map +1 -1
  13. package/dist/engine.d.cts +4 -2
  14. package/dist/engine.d.ts +4 -2
  15. package/dist/engine.js +1 -1
  16. package/dist/index.cjs +396 -215
  17. package/dist/index.cjs.map +1 -1
  18. package/dist/index.d.cts +5 -4
  19. package/dist/index.d.ts +5 -4
  20. package/dist/index.js +6 -5
  21. package/dist/index.js.map +1 -1
  22. package/dist/llm/vercel-ai.cjs +59 -0
  23. package/dist/llm/vercel-ai.cjs.map +1 -0
  24. package/dist/llm/vercel-ai.d.cts +59 -0
  25. package/dist/llm/vercel-ai.d.ts +59 -0
  26. package/dist/llm/vercel-ai.js +49 -0
  27. package/dist/llm/vercel-ai.js.map +1 -0
  28. package/dist/registry/index.d.cts +60 -4
  29. package/dist/registry/index.d.ts +60 -4
  30. package/dist/registry.cjs +455 -93
  31. package/dist/registry.cjs.map +1 -1
  32. package/dist/registry.js +3 -1
  33. package/dist/runtime/index.d.cts +1 -1
  34. package/dist/runtime/index.d.ts +1 -1
  35. package/dist/runtime.cjs +3 -2
  36. package/dist/runtime.cjs.map +1 -1
  37. package/dist/runtime.js +2 -2
  38. package/dist/schema/index.d.cts +1 -1
  39. package/dist/schema/index.d.ts +1 -1
  40. package/dist/{types-CsEe3EQl.d.ts → types-CnnKPnpt.d.ts} +1 -1
  41. package/dist/{types-BwLr5tZV.d.cts → types-H60tQAxr.d.cts} +1 -1
  42. package/dist/{types-BS3Gwnkq.d.cts → types-fc0fFKkf.d.cts} +7 -1
  43. package/dist/{types-BS3Gwnkq.d.ts → types-fc0fFKkf.d.ts} +7 -1
  44. package/dist/ux.d.cts +2 -2
  45. package/dist/ux.d.ts +2 -2
  46. package/package.json +19 -3
  47. package/dist/chunk-2NQT2A3I.js.map +0 -1
  48. package/dist/chunk-YNOI7ONN.js.map +0 -1
@@ -1,10 +1,128 @@
1
1
  import { Handle, Position } from './chunk-NF6NPY5N.js';
2
+ import { runFlow } from './chunk-L4AX73Q6.js';
2
3
  import { resolveNodePorts, nodeConfig } from './chunk-TITD5W4Y.js';
3
4
  import { getNodeKind, categoryAccent, registerNodeKind, listNodeKinds, kindIds } from './chunk-U5F22BHV.js';
4
5
  import { RichInputPreview } from './chunk-F5RPRB7A.js';
6
+ import { getWorkflowResolver, getLlmClient } from './chunk-BB45F6S3.js';
5
7
  import { memo, useMemo, createElement } from 'react';
6
8
  import { jsxs, jsx } from 'react/jsx-runtime';
7
9
 
10
+ // src/registry/subflow.ts
11
+ var DEFAULT_MAX_DEPTH = 8;
12
+ function subflowMode(config) {
13
+ const mode = config.mode;
14
+ return mode === "stream" || mode === "both" ? mode : "output";
15
+ }
16
+ function subflowPorts(config) {
17
+ const mode = subflowMode(config);
18
+ const ports = [{ id: "out", label: "result" }];
19
+ if (mode === "stream" || mode === "both") ports.unshift({ id: "stream", label: "stream" });
20
+ return ports;
21
+ }
22
+ var subflowExecutor = async (ctx) => {
23
+ const config = ctx.node.data?.config ?? {};
24
+ const ref = String(config.workflow ?? "").trim();
25
+ if (!ref) ctx.abort("subflow has no workflow reference configured");
26
+ const resolver = getWorkflowResolver();
27
+ if (!resolver) {
28
+ ctx.abort(
29
+ "No workflow resolver registered. Call registerWorkflowResolver() so subflow can find the workflow it references."
30
+ );
31
+ }
32
+ const maxDepth = Number.isFinite(config.maxDepth) ? Number(config.maxDepth) : DEFAULT_MAX_DEPTH;
33
+ const depth = ctx.depth ?? 0;
34
+ if (depth + 1 > maxDepth) {
35
+ ctx.abort(
36
+ `subflow depth limit reached (${maxDepth}) at "${ref}" \u2014 a workflow is referencing itself, directly or through a chain.`
37
+ );
38
+ }
39
+ const child = await resolver(ref);
40
+ if (!child) ctx.abort(`subflow could not resolve workflow "${ref}"`);
41
+ const mode = subflowMode(config);
42
+ const streaming = mode === "stream" || mode === "both";
43
+ const forward = (event) => {
44
+ if (!streaming) return;
45
+ const detail = event.type === "node-status" ? `${event.nodeId} ${event.status}` : event.type === "run-end" ? `finished (${event.ok ? "ok" : "failed"})` : event.type;
46
+ ctx.emit({
47
+ type: "log",
48
+ nodeId: ctx.node.id,
49
+ level: "info",
50
+ message: `[${ref}] ${detail}`
51
+ });
52
+ };
53
+ const result = await runFlow(
54
+ child,
55
+ config.executors ?? {},
56
+ forward,
57
+ {
58
+ initialInputs: config.inputs ?? {
59
+ // With no explicit mapping, hand the parent's inputs to the child's
60
+ // entry points — the obvious default, and it makes the simple case
61
+ // require no configuration at all.
62
+ __parent: ctx.inputs
63
+ },
64
+ depth: depth + 1
65
+ }
66
+ );
67
+ if (!result.ok) {
68
+ ctx.abort(`subflow "${ref}" failed: ${result.error ?? "unknown error"}`);
69
+ }
70
+ if (mode === "stream") {
71
+ return { __port: "stream", value: result.outputs };
72
+ }
73
+ if (mode === "both") {
74
+ return result.outputs;
75
+ }
76
+ return { __port: "out", value: result.outputs };
77
+ };
78
+
79
+ // src/registry/llm-branch.ts
80
+ function declaredRoutes(config) {
81
+ const raw = config.routes;
82
+ if (!Array.isArray(raw)) return [];
83
+ return raw.map((r) => ({ port: String(r?.port ?? "").trim(), description: r?.description })).filter((r) => r.port !== "");
84
+ }
85
+ function resolveFallbackPort(routes, fallbackEnabled) {
86
+ if (fallbackEnabled) return "fallback";
87
+ return routes[0]?.port ?? "out";
88
+ }
89
+ var llmBranchExecutor = async (ctx) => {
90
+ const config = ctx.node.data?.config ?? {};
91
+ const routes = declaredRoutes(config);
92
+ if (routes.length === 0) {
93
+ ctx.abort("llm_branch has no routes configured");
94
+ }
95
+ const client = getLlmClient();
96
+ if (!client) {
97
+ ctx.abort(
98
+ "No LLM client registered. Call registerLlmClient() with your provider adapter \u2014 fancy-flow ships the routing, not the model call."
99
+ );
100
+ }
101
+ const fallbackEnabled = config.fallback !== false;
102
+ const choice = await client.chooseRoute({
103
+ system: typeof config.system === "string" ? config.system : void 0,
104
+ prompt: String(config.prompt ?? ctx.inputs ?? ""),
105
+ routes,
106
+ provider: typeof config.provider === "string" ? config.provider : void 0,
107
+ model: typeof config.model === "string" ? config.model : void 0,
108
+ credential: typeof config.credential === "string" ? config.credential : void 0
109
+ });
110
+ const offered = new Set(routes.map((r) => r.port));
111
+ let port = choice?.port ?? "";
112
+ let reason = choice?.reason;
113
+ if (!offered.has(port)) {
114
+ const safe = resolveFallbackPort(routes, fallbackEnabled);
115
+ ctx.emit({
116
+ type: "log",
117
+ nodeId: ctx.node.id,
118
+ level: "warn",
119
+ message: `llm_branch: model returned "${port || "(nothing)"}", which is not a declared route. Routing to "${safe}".`
120
+ });
121
+ reason = reason ?? `unrecognised route "${port}"`;
122
+ port = safe;
123
+ }
124
+ return { __port: port, value: { route: port, reason, input: ctx.inputs } };
125
+ };
8
126
  function RegistryNodeInner(props) {
9
127
  const kindName = props.data.kind ?? props.type;
10
128
  const kind = useMemo(() => getNodeKind(kindName), [kindName]);
@@ -163,8 +281,8 @@ var HTTP_METHODS = [
163
281
  var KINDS = [
164
282
  // ───────────── Triggers ─────────────
165
283
  {
166
- name: "@fancy/manual_trigger",
167
- aliases: ["manual_trigger"],
284
+ name: "@particle-academy/manual_trigger",
285
+ aliases: ["manual_trigger", "@fancy/manual_trigger"],
168
286
  category: "trigger",
169
287
  label: "Manual",
170
288
  description: "Entry point fired when the user clicks Run.",
@@ -173,8 +291,8 @@ var KINDS = [
173
291
  outputs: [{ id: "out" }]
174
292
  },
175
293
  {
176
- name: "@fancy/webhook_trigger",
177
- aliases: ["webhook_trigger"],
294
+ name: "@particle-academy/webhook_trigger",
295
+ aliases: ["webhook_trigger", "@fancy/webhook_trigger"],
178
296
  category: "trigger",
179
297
  label: "Webhook",
180
298
  description: "Triggered by an inbound HTTP request to a host-provided URL.",
@@ -191,8 +309,8 @@ var KINDS = [
191
309
  ]
192
310
  },
193
311
  {
194
- name: "@fancy/schedule_trigger",
195
- aliases: ["schedule_trigger"],
312
+ name: "@particle-academy/schedule_trigger",
313
+ aliases: ["schedule_trigger", "@fancy/schedule_trigger"],
196
314
  category: "trigger",
197
315
  label: "Schedule",
198
316
  description: "Fires on a cron schedule (host-implemented).",
@@ -212,8 +330,8 @@ var KINDS = [
212
330
  ]
213
331
  },
214
332
  {
215
- name: "@fancy/user_input",
216
- aliases: ["user_input"],
333
+ name: "@particle-academy/user_input",
334
+ aliases: ["user_input", "@fancy/user_input"],
217
335
  category: "human",
218
336
  label: "User Input",
219
337
  description: "Pause the flow until the user submits the configured form.",
@@ -253,8 +371,8 @@ var KINDS = [
253
371
  ]
254
372
  },
255
373
  {
256
- name: "@fancy/rich_user_input",
257
- aliases: ["rich_user_input"],
374
+ name: "@particle-academy/rich_user_input",
375
+ aliases: ["rich_user_input", "@fancy/rich_user_input"],
258
376
  category: "human",
259
377
  label: "Rich User Input",
260
378
  description: "Pause the flow on a fully authored page \u2014 content, required reading, multi-section forms.",
@@ -277,10 +395,61 @@ var KINDS = [
277
395
  // what the person hitting this step will actually see.
278
396
  renderBody: (ctx) => createElement(RichInputPreview, { config: ctx.config ?? {} })
279
397
  },
398
+ {
399
+ name: "@particle-academy/subflow",
400
+ aliases: ["subflow", "@fancy/subflow"],
401
+ category: "logic",
402
+ label: "SubFlow",
403
+ description: "Run another workflow and bring its result \u2014 or its live progress \u2014 back into this one.",
404
+ icon: "\u29C9",
405
+ inputs: [{ id: "in" }],
406
+ // The stream port only exists when something actually streams.
407
+ outputs: (config) => subflowPorts(config ?? {}),
408
+ // Core, not marketplace: it runs a child graph through this same engine and
409
+ // needs nothing from outside except where workflows live.
410
+ executor: subflowExecutor,
411
+ configSchema: [
412
+ {
413
+ type: "text",
414
+ key: "workflow",
415
+ label: "Workflow",
416
+ required: true,
417
+ placeholder: "onboarding-v2",
418
+ description: "Reference resolved by the host's registerWorkflowResolver()."
419
+ },
420
+ {
421
+ type: "select",
422
+ key: "mode",
423
+ label: "Return",
424
+ default: "output",
425
+ options: [
426
+ { value: "output", label: "Output when it finishes" },
427
+ { value: "stream", label: "Stream progress as it runs" },
428
+ { value: "both", label: "Both \u2014 stream, then output" }
429
+ ],
430
+ description: "Streaming adds a second port so a parent can show progress instead of a spinner."
431
+ },
432
+ {
433
+ type: "json",
434
+ key: "inputs",
435
+ label: "Input mapping",
436
+ description: "Entry-point inputs for the child run. Omit to pass this node's inputs straight through."
437
+ },
438
+ {
439
+ type: "number",
440
+ key: "maxDepth",
441
+ label: "Max nesting depth",
442
+ default: DEFAULT_MAX_DEPTH,
443
+ min: 1,
444
+ max: 32,
445
+ description: "Guards against a workflow referencing itself."
446
+ }
447
+ ]
448
+ },
280
449
  // ───────────── Logic ─────────────
281
450
  {
282
- name: "@fancy/branch",
283
- aliases: ["branch"],
451
+ name: "@particle-academy/branch",
452
+ aliases: ["branch", "@fancy/branch"],
284
453
  category: "logic",
285
454
  label: "Branch",
286
455
  description: "Multi-way branch on a condition or value.",
@@ -292,8 +461,8 @@ var KINDS = [
292
461
  ]
293
462
  },
294
463
  {
295
- name: "@fancy/switch_case",
296
- aliases: ["switch_case"],
464
+ name: "@particle-academy/switch_case",
465
+ aliases: ["switch_case", "@fancy/switch_case"],
297
466
  category: "logic",
298
467
  label: "Switch",
299
468
  description: "Route to one of N labelled outputs based on a key.",
@@ -320,8 +489,8 @@ var KINDS = [
320
489
  ]
321
490
  },
322
491
  {
323
- name: "@fancy/for_each",
324
- aliases: ["for_each"],
492
+ name: "@particle-academy/for_each",
493
+ aliases: ["for_each", "@fancy/for_each"],
325
494
  category: "logic",
326
495
  label: "For Each",
327
496
  description: "Iterate over a list, emitting each item on `item`.",
@@ -334,8 +503,8 @@ var KINDS = [
334
503
  ]
335
504
  },
336
505
  {
337
- name: "@fancy/merge",
338
- aliases: ["merge"],
506
+ name: "@particle-academy/merge",
507
+ aliases: ["merge", "@fancy/merge"],
339
508
  category: "logic",
340
509
  label: "Merge",
341
510
  description: "Combine multiple inputs into one object or array.",
@@ -353,8 +522,8 @@ var KINDS = [
353
522
  ]
354
523
  },
355
524
  {
356
- name: "@fancy/wait",
357
- aliases: ["wait"],
525
+ name: "@particle-academy/wait",
526
+ aliases: ["wait", "@fancy/wait"],
358
527
  category: "logic",
359
528
  label: "Wait",
360
529
  description: "Sleep or wait for an external event.",
@@ -371,8 +540,8 @@ var KINDS = [
371
540
  ]
372
541
  },
373
542
  {
374
- name: "@fancy/transform",
375
- aliases: ["transform"],
543
+ name: "@particle-academy/transform",
544
+ aliases: ["transform", "@fancy/transform"],
376
545
  category: "logic",
377
546
  label: "Transform",
378
547
  description: "Reshape data with an expression.",
@@ -389,8 +558,8 @@ var KINDS = [
389
558
  },
390
559
  // ───────────── Data ─────────────
391
560
  {
392
- name: "@fancy/memory_store",
393
- aliases: ["memory_store"],
561
+ name: "@particle-academy/memory_store",
562
+ aliases: ["memory_store", "@fancy/memory_store"],
394
563
  category: "data",
395
564
  label: "Memory Store",
396
565
  description: "Read or write per-conversation memory.",
@@ -410,8 +579,8 @@ var KINDS = [
410
579
  ]
411
580
  },
412
581
  {
413
- name: "@fancy/data_store",
414
- aliases: ["data_store"],
582
+ name: "@particle-academy/data_store",
583
+ aliases: ["data_store", "@fancy/data_store"],
415
584
  category: "data",
416
585
  label: "Data Store",
417
586
  description: "Key-value or table read/write against a host store.",
@@ -439,8 +608,8 @@ var KINDS = [
439
608
  ]
440
609
  },
441
610
  {
442
- name: "@fancy/variable",
443
- aliases: ["variable"],
611
+ name: "@particle-academy/variable",
612
+ aliases: ["variable", "@fancy/variable"],
444
613
  category: "data",
445
614
  label: "Variable",
446
615
  description: "Workflow-scoped value used by other nodes.",
@@ -452,8 +621,8 @@ var KINDS = [
452
621
  },
453
622
  // ───────────── AI ─────────────
454
623
  {
455
- name: "@fancy/llm_call",
456
- aliases: ["llm_call"],
624
+ name: "@particle-academy/llm_call",
625
+ aliases: ["llm_call", "@fancy/llm_call"],
457
626
  category: "ai",
458
627
  label: "LLM Call",
459
628
  description: "Send a prompt + context to a model and receive a response.",
@@ -480,8 +649,8 @@ var KINDS = [
480
649
  ]
481
650
  },
482
651
  {
483
- name: "@fancy/llm_branch",
484
- aliases: ["llm_branch"],
652
+ name: "@particle-academy/llm_branch",
653
+ aliases: ["llm_branch", "@fancy/llm_branch"],
485
654
  category: "ai",
486
655
  label: "LLM Router",
487
656
  description: "Let a model choose which route the flow takes.",
@@ -490,6 +659,10 @@ var KINDS = [
490
659
  // Each declared route is a port. The executor returns `{ __port: id }`
491
660
  // (or `Port.only(id)` on the PHP runtime) to pick one.
492
661
  outputs: (config) => routePorts(config?.routes, config?.fallback),
662
+ // A shuttle, not an engine: it carries the routes out to whatever LLM
663
+ // client the host registered and carries the choice back. No provider SDK
664
+ // reaches core, so this stays a builtin without adding a dependency.
665
+ executor: llmBranchExecutor,
493
666
  configSchema: [
494
667
  {
495
668
  type: "textarea",
@@ -551,8 +724,8 @@ var KINDS = [
551
724
  ]
552
725
  },
553
726
  {
554
- name: "@fancy/tool_use",
555
- aliases: ["tool_use"],
727
+ name: "@particle-academy/tool_use",
728
+ aliases: ["tool_use", "@fancy/tool_use"],
556
729
  category: "ai",
557
730
  label: "Tool Use",
558
731
  description: "Hand control to a host-registered tool by name.",
@@ -563,8 +736,8 @@ var KINDS = [
563
736
  ]
564
737
  },
565
738
  {
566
- name: "@fancy/embed_search",
567
- aliases: ["embed_search"],
739
+ name: "@particle-academy/embed_search",
740
+ aliases: ["embed_search", "@fancy/embed_search"],
568
741
  category: "ai",
569
742
  label: "Embed & Search",
570
743
  description: "Embed a query and search a vector store.",
@@ -577,8 +750,8 @@ var KINDS = [
577
750
  },
578
751
  // ───────────── IO ─────────────
579
752
  {
580
- name: "@fancy/api_request",
581
- aliases: ["api_request"],
753
+ name: "@particle-academy/api_request",
754
+ aliases: ["api_request", "@fancy/api_request"],
582
755
  category: "io",
583
756
  label: "API Request",
584
757
  description: "HTTP request to any URL.",
@@ -592,8 +765,8 @@ var KINDS = [
592
765
  ]
593
766
  },
594
767
  {
595
- name: "@fancy/webhook_out",
596
- aliases: ["webhook_out"],
768
+ name: "@particle-academy/webhook_out",
769
+ aliases: ["webhook_out", "@fancy/webhook_out"],
597
770
  category: "io",
598
771
  label: "Send Webhook",
599
772
  description: "POST a payload to a configured URL.",
@@ -606,8 +779,8 @@ var KINDS = [
606
779
  },
607
780
  // ───────────── Human ─────────────
608
781
  {
609
- name: "@fancy/human_approval",
610
- aliases: ["human_approval"],
782
+ name: "@particle-academy/human_approval",
783
+ aliases: ["human_approval", "@fancy/human_approval"],
611
784
  category: "human",
612
785
  label: "Human Approval",
613
786
  description: "Pause until a human approves or denies.",
@@ -621,8 +794,8 @@ var KINDS = [
621
794
  ]
622
795
  },
623
796
  {
624
- name: "@fancy/notify",
625
- aliases: ["notify"],
797
+ name: "@particle-academy/notify",
798
+ aliases: ["notify", "@fancy/notify"],
626
799
  category: "human",
627
800
  label: "Notify",
628
801
  description: "Send a message via Slack / email / SMS / etc.",
@@ -646,8 +819,8 @@ var KINDS = [
646
819
  },
647
820
  // ───────────── Output ─────────────
648
821
  {
649
- name: "@fancy/output",
650
- aliases: ["output"],
822
+ name: "@particle-academy/output",
823
+ aliases: ["output", "@fancy/output"],
651
824
  category: "output",
652
825
  label: "Output",
653
826
  description: "Terminal node \u2014 captures the workflow's result.",
@@ -656,8 +829,8 @@ var KINDS = [
656
829
  outputs: []
657
830
  },
658
831
  {
659
- name: "@fancy/log",
660
- aliases: ["log"],
832
+ name: "@particle-academy/log",
833
+ aliases: ["log", "@fancy/log"],
661
834
  category: "output",
662
835
  label: "Log",
663
836
  description: "Send to the run feed.",
@@ -690,6 +863,6 @@ function buildNodeTypes() {
690
863
  return map;
691
864
  }
692
865
 
693
- export { BUILTIN_KINDS, RegistryNode, buildNodeTypes, registerBuiltinKinds };
694
- //# sourceMappingURL=chunk-YNOI7ONN.js.map
695
- //# sourceMappingURL=chunk-YNOI7ONN.js.map
866
+ export { BUILTIN_KINDS, DEFAULT_MAX_DEPTH, RegistryNode, buildNodeTypes, declaredRoutes, llmBranchExecutor, registerBuiltinKinds, resolveFallbackPort, subflowExecutor, subflowMode, subflowPorts };
867
+ //# sourceMappingURL=chunk-WEZJFMLV.js.map
868
+ //# sourceMappingURL=chunk-WEZJFMLV.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/registry/subflow.ts","../src/registry/llm-branch.ts","../src/registry/RegistryNode.tsx","../src/registry/builtin.ts","../src/registry/index.ts"],"names":[],"mappings":"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","file":"chunk-WEZJFMLV.js","sourcesContent":["import { getWorkflowResolver } from \"./capabilities\";\nimport { runFlow } from \"../runtime/run-flow\";\nimport type { NodeExecutor, RunEvent } from \"../types\";\n\n/**\n * `@fancy/subflow` — run another workflow and bring its result home.\n *\n * Core, not marketplace: it introduces no third-party dependency. It runs a\n * child graph through the very same engine, so the only thing it needs from the\n * host is where workflows live (`registerWorkflowResolver`).\n *\n * Three output modes, because both halves are genuinely useful:\n *\n * - `output` — the child's outputs arrive on `out` when it finishes.\n * - `stream` — the child's events are forwarded live on `stream` as they\n * happen, so a parent can show progress instead of a spinner.\n * - `both` — stream while running AND deliver the final outputs.\n *\n * Recursion is guarded by depth. A workflow that references itself (directly or\n * through a chain) would otherwise recurse until the stack dies, which surfaces\n * as an opaque crash rather than \"you built a loop\".\n */\n\nexport const DEFAULT_MAX_DEPTH = 8;\n\nexport type SubflowMode = \"output\" | \"stream\" | \"both\";\n\nexport function subflowMode(config: Record<string, unknown>): SubflowMode {\n const mode = config.mode;\n return mode === \"stream\" || mode === \"both\" ? mode : \"output\";\n}\n\n/** Ports follow the mode — `stream` only exists when something streams. */\nexport function subflowPorts(config: Record<string, unknown>) {\n const mode = subflowMode(config);\n const ports = [{ id: \"out\", label: \"result\" }];\n if (mode === \"stream\" || mode === \"both\") ports.unshift({ id: \"stream\", label: \"stream\" });\n return ports;\n}\n\nexport const subflowExecutor: NodeExecutor = async (ctx) => {\n const config = ((ctx.node.data as any)?.config ?? {}) as Record<string, unknown>;\n const ref = String(config.workflow ?? \"\").trim();\n if (!ref) ctx.abort(\"subflow has no workflow reference configured\");\n\n const resolver = getWorkflowResolver();\n if (!resolver) {\n ctx.abort(\n \"No workflow resolver registered. Call registerWorkflowResolver() so subflow can find the workflow it references.\",\n );\n }\n\n const maxDepth = Number.isFinite(config.maxDepth) ? Number(config.maxDepth) : DEFAULT_MAX_DEPTH;\n const depth = ctx.depth ?? 0;\n if (depth + 1 > maxDepth) {\n // Name the cause. \"Maximum call stack exceeded\" tells an author nothing\n // about the workflow they wired into itself.\n ctx.abort(\n `subflow depth limit reached (${maxDepth}) at \"${ref}\" — a workflow is referencing itself, directly or through a chain.`,\n );\n }\n\n const child = await resolver!(ref);\n if (!child) ctx.abort(`subflow could not resolve workflow \"${ref}\"`);\n\n const mode = subflowMode(config);\n const streaming = mode === \"stream\" || mode === \"both\";\n\n const forward = (event: RunEvent) => {\n if (!streaming) return;\n // Surface the child's progress on the PARENT's feed as a log line against\n // this node. Re-emitting the child's raw events would collide with the\n // parent's own node ids — a child's \"node-status\" for its `output` node is\n // not a status for anything in the parent graph.\n const detail =\n event.type === \"node-status\"\n ? `${event.nodeId} ${event.status}`\n : event.type === \"run-end\"\n ? `finished (${event.ok ? \"ok\" : \"failed\"})`\n : event.type;\n ctx.emit({\n type: \"log\",\n nodeId: ctx.node.id,\n level: \"info\",\n message: `[${ref}] ${detail}`,\n });\n };\n\n const result = await runFlow(\n child!,\n (config.executors as never) ?? {},\n forward,\n {\n initialInputs: (config.inputs as Record<string, Record<string, unknown>>) ?? {\n // With no explicit mapping, hand the parent's inputs to the child's\n // entry points — the obvious default, and it makes the simple case\n // require no configuration at all.\n __parent: ctx.inputs as Record<string, unknown>,\n },\n depth: depth + 1,\n },\n );\n\n if (!result.ok) {\n ctx.abort(`subflow \"${ref}\" failed: ${result.error ?? \"unknown error\"}`);\n }\n\n // `stream` alone still emits a final value on `stream` so downstream nodes\n // have something to run on; `both` publishes on every declared port.\n if (mode === \"stream\") {\n return { __port: \"stream\", value: result.outputs };\n }\n if (mode === \"both\") {\n return result.outputs;\n }\n return { __port: \"out\", value: result.outputs };\n};\n","import { getLlmClient, type LlmRoute } from \"./capabilities\";\nimport type { NodeExecutor } from \"../types\";\n\n/**\n * `@fancy/llm_branch` — a SHUTTLE, not an engine.\n *\n * It carries the declared routes and the decision prompt out to whatever LLM\n * client the host registered, and carries the chosen port back down the graph.\n * It contains no provider SDK, no prompt engineering, no response parsing and\n * no retry policy — all of that belongs to the host's client, which is what\n * lets this node live in core without every consumer inheriting an LLM\n * dependency.\n *\n * The one thing it does own is graph integrity, because that is a workflow\n * concern rather than an AI one: a port the model invents must never route.\n */\n\n/** Read the node's declared routes out of config. */\nexport function declaredRoutes(config: Record<string, unknown>): LlmRoute[] {\n const raw = config.routes;\n if (!Array.isArray(raw)) return [];\n return raw\n .map((r) => ({ port: String((r as any)?.port ?? \"\").trim(), description: (r as any)?.description }))\n .filter((r) => r.port !== \"\");\n}\n\n/**\n * Where a run goes when the model returns a port that was never offered.\n *\n * Emitting on a port with no edge silently ends the branch — the worst failure\n * mode in a workflow engine, because the run reports success having done\n * nothing. So: the `fallback` port when it exists, else the first declared\n * route, and always loudly.\n */\nexport function resolveFallbackPort(routes: LlmRoute[], fallbackEnabled: boolean): string {\n if (fallbackEnabled) return \"fallback\";\n // Callers only reach this with at least one declared route (a node with none\n // aborts earlier), so there is always somewhere safe to land.\n return routes[0]?.port ?? \"out\";\n}\n\nexport const llmBranchExecutor: NodeExecutor = async (ctx) => {\n const config = ((ctx.node.data as any)?.config ?? {}) as Record<string, unknown>;\n const routes = declaredRoutes(config);\n\n if (routes.length === 0) {\n ctx.abort(\"llm_branch has no routes configured\");\n }\n\n const client = getLlmClient();\n if (!client) {\n // Fail loudly rather than guessing a branch. A silent default here would\n // look like the model made a choice.\n ctx.abort(\n \"No LLM client registered. Call registerLlmClient() with your provider adapter — fancy-flow ships the routing, not the model call.\",\n );\n }\n\n const fallbackEnabled = config.fallback !== false;\n\n const choice = await client!.chooseRoute({\n system: typeof config.system === \"string\" ? config.system : undefined,\n prompt: String(config.prompt ?? ctx.inputs ?? \"\"),\n routes,\n provider: typeof config.provider === \"string\" ? config.provider : undefined,\n model: typeof config.model === \"string\" ? config.model : undefined,\n credential: typeof config.credential === \"string\" ? config.credential : undefined,\n });\n\n const offered = new Set(routes.map((r) => r.port));\n let port = choice?.port ?? \"\";\n let reason = choice?.reason;\n\n if (!offered.has(port)) {\n const safe = resolveFallbackPort(routes, fallbackEnabled);\n ctx.emit({\n type: \"log\",\n nodeId: ctx.node.id,\n level: \"warn\",\n message: `llm_branch: model returned \"${port || \"(nothing)\"}\", which is not a declared route. Routing to \"${safe}\".`,\n });\n reason = reason ?? `unrecognised route \"${port}\"`;\n port = safe;\n }\n\n // The reason travels WITH the value, so a completed run explains itself\n // without needing the model call replayed.\n return { __port: port, value: { route: port, reason, input: ctx.inputs } };\n};\n","import { memo, useMemo } from \"react\";\nimport { Handle, Position, type NodeProps } from \"@xyflow/react\";\nimport type { FlowNode, NodeRunStatus, PortDescriptor } from \"../types\";\nimport { categoryAccent, getNodeKind } from \"./registry\";\nimport { nodeConfig, resolveNodePorts } from \"./ports\";\n\n/**\n * RegistryNode — generic node renderer that looks up the node's kind in\n * the registry and applies its `accent`/`label`/`icon`/`renderBody`. Used\n * as the xyflow node component for every registered kind.\n */\nfunction RegistryNodeInner(props: NodeProps<FlowNode>) {\n const kindName = (props.data as any).kind ?? props.type;\n const kind = useMemo(() => getNodeKind(kindName), [kindName]);\n\n if (!kind) {\n return (\n <div className=\"ff-node ff-node--unknown\">\n <div className=\"ff-node__header\" style={{ background: \"#71717a\" }}>\n <span className=\"ff-node__tag\">UNKNOWN</span>\n <span className=\"ff-node__label\">{kindName}</span>\n </div>\n <p className=\"ff-node__desc\">No registered kind for \"{kindName}\".</p>\n </div>\n );\n }\n\n const data = props.data;\n const status: NodeRunStatus = data.status ?? \"idle\";\n const accent = kind.accent ?? categoryAccent(kind.category);\n const resolved = resolveNodePorts(props, kind);\n const inputs: PortDescriptor[] = resolved.inputs ?? defaultInputs(kind.category);\n const outputs: PortDescriptor[] = resolved.outputs ?? defaultOutputs(kind.category);\n const config = nodeConfig(props);\n const label = data.label ?? kind.label;\n\n return (\n <div\n className={[\n \"ff-node\",\n `ff-node--status-${status}`,\n `ff-node--cat-${kind.category}`,\n props.selected ? \"ff-node--selected\" : \"\",\n ].filter(Boolean).join(\" \")}\n style={{ borderColor: props.selected ? accent : undefined }}\n >\n <header className=\"ff-node__header\" style={{ background: accent }}>\n {kind.icon && <span className=\"ff-node__icon\" aria-hidden>{kind.icon}</span>}\n <span className=\"ff-node__tag\">{kind.label.toUpperCase()}</span>\n <span className=\"ff-node__label\">{label}</span>\n {status !== \"idle\" && <span className={`ff-node__dot ff-node__dot--${status}`} aria-label={`status ${status}`} />}\n </header>\n\n {data.description && <p className=\"ff-node__desc\">{data.description}</p>}\n\n <div className=\"ff-node__body\">\n {kind.renderBody\n ? kind.renderBody({ nodeId: props.id, config: config as any, selected: props.selected ?? false })\n : <DefaultBody config={config} kind={kind.configSchema} />}\n </div>\n\n {data.statusText && <p className=\"ff-node__status-text\">{data.statusText}</p>}\n\n {inputs.map((p, i) => (\n <Handle\n key={p.id}\n type=\"target\"\n position={Position.Left}\n id={p.id}\n style={portStyle(i, inputs.length)}\n title={p.label ?? p.id}\n />\n ))}\n {outputs.map((p, i) => (\n <Handle\n key={p.id}\n type=\"source\"\n position={Position.Right}\n id={p.id}\n style={portStyle(i, outputs.length)}\n title={p.label ?? p.id}\n />\n ))}\n </div>\n );\n}\n\nexport const RegistryNode = memo(RegistryNodeInner);\n\nfunction defaultInputs(category: string): PortDescriptor[] {\n return category === \"trigger\" ? [] : [{ id: \"in\" }];\n}\nfunction defaultOutputs(category: string): PortDescriptor[] {\n return category === \"output\" ? [] : [{ id: \"out\" }];\n}\n\nfunction portStyle(i: number, total: number): React.CSSProperties {\n if (total <= 1) return {};\n const slot = (100 / (total + 1)) * (i + 1);\n return { top: `${slot}%` };\n}\n\n/**\n * DefaultBody — compact summary of the config values for nodes that\n * don't provide a custom renderBody. Skips fields that look empty.\n */\nfunction DefaultBody({ config, kind }: { config: Record<string, unknown>; kind?: import(\"./types\").ConfigField[] }) {\n const fields = kind ?? [];\n const visible = fields\n .map((f) => ({ field: f, value: config[f.key] }))\n .filter(({ value }) => value !== undefined && value !== \"\" && value !== null);\n if (visible.length === 0) {\n return <div className=\"ff-node__body-empty\">— configure in the panel</div>;\n }\n return (\n <ul className=\"ff-node__summary\">\n {visible.slice(0, 4).map(({ field, value }) => (\n <li key={field.key}>\n <span className=\"ff-node__summary-key\">{field.label}:</span>\n <span className=\"ff-node__summary-value\">{previewValue(value)}</span>\n </li>\n ))}\n {visible.length > 4 && <li className=\"ff-node__summary-more\">+ {visible.length - 4} more</li>}\n </ul>\n );\n}\n\nfunction previewValue(v: unknown): string {\n if (typeof v === \"string\") return v.length > 30 ? v.slice(0, 27) + \"…\" : v;\n if (typeof v === \"number\" || typeof v === \"boolean\") return String(v);\n try {\n const j = JSON.stringify(v);\n return j.length > 30 ? j.slice(0, 27) + \"…\" : j;\n } catch {\n return \"[object]\";\n }\n}\n","import { createElement } from \"react\";\nimport { registerNodeKind } from \"./registry\";\nimport { RichInputPreview } from \"./rich-input\";\nimport { llmBranchExecutor } from \"./llm-branch\";\nimport { subflowExecutor, subflowPorts, DEFAULT_MAX_DEPTH } from \"./subflow\";\nimport type { PortDescriptor } from \"../types\";\nimport type { ConfigField, NodeKindDefinition } from \"./types\";\n\n/**\n * Built-in agentic node kit. Every kind ships with schema + UI but\n * NO executor — host apps wire executors per kind so they control where\n * memory, data, network, and AI calls actually go.\n */\n\n/**\n * Ports for `switch_case`, derived from its `cases` map (match value → port).\n *\n * Several match values may route to the same port, so ports are de-duplicated\n * and labelled with every value that reaches them (\"a|c\"). `default` is always\n * present — unmatched input has to land somewhere.\n */\nfunction casePorts(cases: unknown): PortDescriptor[] {\n const byPort = new Map<string, string[]>();\n if (cases && typeof cases === \"object\" && !Array.isArray(cases)) {\n for (const [match, port] of Object.entries(cases as Record<string, unknown>)) {\n if (typeof port !== \"string\" || port === \"\" || port === \"default\") continue;\n const matches = byPort.get(port) ?? [];\n matches.push(match);\n byPort.set(port, matches);\n }\n }\n const ports: PortDescriptor[] = [...byPort].map(([id, matches]) => ({\n id,\n label: matches.join(\"|\"),\n }));\n return [...ports, { id: \"default\", label: \"default\" }];\n}\n\n/**\n * Ports for `llm_branch`, derived from its `routes` list. Blank and duplicate\n * port names are dropped so a half-typed route can't collide with a real one.\n */\nfunction routePorts(routes: unknown, fallback?: unknown): PortDescriptor[] {\n const ports: PortDescriptor[] = [];\n const seen = new Set<string>();\n if (Array.isArray(routes)) {\n for (const route of routes) {\n const id = (route as any)?.port;\n if (typeof id !== \"string\" || id.trim() === \"\" || seen.has(id)) continue;\n seen.add(id);\n ports.push({ id, label: id });\n }\n }\n if (fallback !== false && !seen.has(\"fallback\")) {\n ports.push({ id: \"fallback\", label: \"fallback\" });\n }\n if (ports.length === 0) ports.push({ id: \"out\" });\n return ports;\n}\n\nconst HTTP_METHODS: ConfigField[] = [\n { type: \"select\", key: \"method\", label: \"Method\", options: [\n { value: \"GET\", label: \"GET\" },\n { value: \"POST\", label: \"POST\" },\n { value: \"PUT\", label: \"PUT\" },\n { value: \"PATCH\", label: \"PATCH\" },\n { value: \"DELETE\", label: \"DELETE\" },\n ], default: \"GET\", required: true },\n];\n\nconst KINDS: NodeKindDefinition[] = [\n // ───────────── Triggers ─────────────\n {\n name: \"@particle-academy/manual_trigger\",\n aliases: [\"manual_trigger\", \"@fancy/manual_trigger\"],\n category: \"trigger\",\n label: \"Manual\",\n description: \"Entry point fired when the user clicks Run.\",\n icon: \"⚡\",\n inputs: [],\n outputs: [{ id: \"out\" }],\n },\n {\n name: \"@particle-academy/webhook_trigger\",\n aliases: [\"webhook_trigger\", \"@fancy/webhook_trigger\"],\n category: \"trigger\",\n label: \"Webhook\",\n description: \"Triggered by an inbound HTTP request to a host-provided URL.\",\n icon: \"📡\",\n inputs: [],\n outputs: [{ id: \"out\", label: \"payload\" }],\n configSchema: [\n { type: \"text\", key: \"path\", label: \"Path\", placeholder: \"/hooks/my-flow\", required: true },\n { type: \"select\", key: \"method\", label: \"Method\", options: [\n { value: \"POST\", label: \"POST\" }, { value: \"GET\", label: \"GET\" },\n ], default: \"POST\" },\n { type: \"credential\", key: \"secret\", label: \"Verifying secret\", credentialType: \"webhook_secret\" },\n ],\n },\n {\n name: \"@particle-academy/schedule_trigger\",\n aliases: [\"schedule_trigger\", \"@fancy/schedule_trigger\"],\n category: \"trigger\",\n label: \"Schedule\",\n description: \"Fires on a cron schedule (host-implemented).\",\n icon: \"⏱\",\n inputs: [],\n outputs: [{ id: \"out\" }],\n configSchema: [\n { type: \"text\", key: \"cron\", label: \"Cron\", placeholder: \"*/5 * * * *\", required: true,\n description: \"Standard 5-field cron expression.\" },\n { type: \"text\", key: \"timezone\", label: \"Timezone\", placeholder: \"UTC\", default: \"UTC\" },\n ],\n },\n {\n name: \"@particle-academy/user_input\",\n aliases: [\"user_input\", \"@fancy/user_input\"],\n category: \"human\",\n label: \"User Input\",\n description: \"Pause the flow until the user submits the configured form.\",\n icon: \"✎\",\n inputs: [{ id: \"in\" }],\n outputs: [{ id: \"out\", label: \"values\" }],\n configSchema: [\n { type: \"text\", key: \"title\", label: \"Form title\", default: \"Need your input\" },\n {\n type: \"repeater\",\n key: \"fields\",\n label: \"Fields\",\n description: \"The form the run pauses on.\",\n titleKey: \"label\",\n addLabel: \"Add field\",\n minItems: 1,\n fields: [\n { type: \"text\", key: \"key\", label: \"Key\", required: true, placeholder: \"answer\" },\n { type: \"text\", key: \"label\", label: \"Label\", required: true, placeholder: \"Your answer\" },\n {\n type: \"select\", key: \"type\", label: \"Type\", default: \"text\",\n options: [\n { value: \"text\", label: \"Text\" },\n { value: \"textarea\", label: \"Long text\" },\n { value: \"number\", label: \"Number\" },\n { value: \"select\", label: \"Select\" },\n { value: \"switch\", label: \"Switch\" },\n ],\n },\n { type: \"switch\", key: \"required\", label: \"Required\", default: false },\n ],\n default: [{ key: \"answer\", label: \"Your answer\", type: \"textarea\", required: true }],\n },\n ],\n },\n\n {\n name: \"@particle-academy/rich_user_input\",\n aliases: [\"rich_user_input\", \"@fancy/rich_user_input\"],\n category: \"human\",\n label: \"Rich User Input\",\n description: \"Pause the flow on a fully authored page — content, required reading, multi-section forms.\",\n icon: \"▤\",\n inputs: [{ id: \"in\" }],\n outputs: [{ id: \"out\", label: \"values\" }],\n configSchema: [\n { type: \"text\", key: \"title\", label: \"Step title\", default: \"Please review\" },\n {\n type: \"document\",\n key: \"document\",\n label: \"Page content\",\n documentType: \"stages\",\n description: \"Authored with the host's document editor (fancy-cms Stages).\",\n },\n { type: \"switch\", key: \"requireConfirm\", label: \"Require explicit confirmation\", default: true },\n { type: \"text\", key: \"submitLabel\", label: \"Submit button\", default: \"Continue\" },\n ],\n // Preview the authored page inside a FauxClient frame, so the canvas shows\n // what the person hitting this step will actually see.\n renderBody: (ctx) => createElement(RichInputPreview, { config: (ctx.config ?? {}) as Record<string, unknown> }),\n },\n\n {\n name: \"@particle-academy/subflow\",\n aliases: [\"subflow\", \"@fancy/subflow\"],\n category: \"logic\",\n label: \"SubFlow\",\n description: \"Run another workflow and bring its result — or its live progress — back into this one.\",\n icon: \"⧉\",\n inputs: [{ id: \"in\" }],\n // The stream port only exists when something actually streams.\n outputs: (config: any) => subflowPorts(config ?? {}),\n // Core, not marketplace: it runs a child graph through this same engine and\n // needs nothing from outside except where workflows live.\n executor: subflowExecutor,\n configSchema: [\n { type: \"text\", key: \"workflow\", label: \"Workflow\", required: true,\n placeholder: \"onboarding-v2\",\n description: \"Reference resolved by the host's registerWorkflowResolver().\" },\n {\n type: \"select\", key: \"mode\", label: \"Return\", default: \"output\",\n options: [\n { value: \"output\", label: \"Output when it finishes\" },\n { value: \"stream\", label: \"Stream progress as it runs\" },\n { value: \"both\", label: \"Both — stream, then output\" },\n ],\n description: \"Streaming adds a second port so a parent can show progress instead of a spinner.\",\n },\n { type: \"json\", key: \"inputs\", label: \"Input mapping\",\n description: \"Entry-point inputs for the child run. Omit to pass this node's inputs straight through.\" },\n { type: \"number\", key: \"maxDepth\", label: \"Max nesting depth\", default: DEFAULT_MAX_DEPTH, min: 1, max: 32,\n description: \"Guards against a workflow referencing itself.\" },\n ],\n },\n\n // ───────────── Logic ─────────────\n {\n name: \"@particle-academy/branch\",\n aliases: [\"branch\", \"@fancy/branch\"],\n category: \"logic\",\n label: \"Branch\",\n description: \"Multi-way branch on a condition or value.\",\n icon: \"◇\",\n inputs: [{ id: \"in\" }],\n outputs: [{ id: \"true\", label: \"true\" }, { id: \"false\", label: \"false\" }],\n configSchema: [\n { type: \"expression\", key: \"condition\", label: \"Condition\", example: \"{{ $json.active }}\", required: true },\n ],\n },\n {\n name: \"@particle-academy/switch_case\",\n aliases: [\"switch_case\", \"@fancy/switch_case\"],\n category: \"logic\",\n label: \"Switch\",\n description: \"Route to one of N labelled outputs based on a key.\",\n icon: \"⤳\",\n inputs: [{ id: \"in\" }],\n // Ports ARE the config: every distinct port a case routes to becomes an\n // output handle, plus the always-present `default`. Editing the cases map\n // moves the ports on the canvas and the ports the runtime activates.\n outputs: (config: any) => casePorts(config?.cases),\n configSchema: [\n { type: \"expression\", key: \"value\", label: \"Switch on\", example: \"{{ $json.kind }}\", required: true },\n {\n type: \"keyvalue\",\n key: \"cases\",\n label: \"Cases\",\n description: \"Match value → output port. Unmatched input takes `default`.\",\n keyLabel: \"When value is\",\n valueLabel: \"Route to port\",\n keyPlaceholder: \"a\",\n valuePlaceholder: \"case_a\",\n addLabel: \"Add case\",\n default: { a: \"case_a\", b: \"case_b\" },\n },\n ],\n },\n {\n name: \"@particle-academy/for_each\",\n aliases: [\"for_each\", \"@fancy/for_each\"],\n category: \"logic\",\n label: \"For Each\",\n description: \"Iterate over a list, emitting each item on `item`.\",\n icon: \"↻\",\n inputs: [{ id: \"in\" }],\n outputs: [{ id: \"item\", label: \"item\" }, { id: \"done\", label: \"done\" }],\n configSchema: [\n { type: \"expression\", key: \"source\", label: \"List\", example: \"{{ $json.users }}\", required: true },\n { type: \"number\", key: \"concurrency\", label: \"Concurrency\", default: 1, min: 1, max: 50 },\n ],\n },\n {\n name: \"@particle-academy/merge\",\n aliases: [\"merge\", \"@fancy/merge\"],\n category: \"logic\",\n label: \"Merge\",\n description: \"Combine multiple inputs into one object or array.\",\n icon: \"⊕\",\n inputs: [{ id: \"a\" }, { id: \"b\" }],\n outputs: [{ id: \"out\" }],\n configSchema: [\n { type: \"select\", key: \"mode\", label: \"Mode\", default: \"merge\",\n options: [{ value: \"merge\", label: \"Object merge\" }, { value: \"concat\", label: \"Array concat\" }] },\n ],\n },\n {\n name: \"@particle-academy/wait\",\n aliases: [\"wait\", \"@fancy/wait\"],\n category: \"logic\",\n label: \"Wait\",\n description: \"Sleep or wait for an external event.\",\n icon: \"⏸\",\n configSchema: [\n { type: \"select\", key: \"mode\", label: \"Mode\", default: \"duration\",\n options: [{ value: \"duration\", label: \"Duration\" }, { value: \"until\", label: \"Until timestamp\" }, { value: \"event\", label: \"External event\" }] },\n { type: \"text\", key: \"duration\", label: \"Duration\", placeholder: \"5s, 10m, 1h\", description: \"Used when mode = duration.\" },\n ],\n },\n {\n name: \"@particle-academy/transform\",\n aliases: [\"transform\", \"@fancy/transform\"],\n category: \"logic\",\n label: \"Transform\",\n description: \"Reshape data with an expression.\",\n icon: \"ƒ\",\n configSchema: [\n { type: \"expression\", key: \"expression\", label: \"Expression\",\n example: \"{{ { id: $json.id, name: $json.first + ' ' + $json.last } }}\", required: true },\n ],\n },\n\n // ───────────── Data ─────────────\n {\n name: \"@particle-academy/memory_store\",\n aliases: [\"memory_store\", \"@fancy/memory_store\"],\n category: \"data\",\n label: \"Memory Store\",\n description: \"Read or write per-conversation memory.\",\n icon: \"🧠\",\n configSchema: [\n { type: \"select\", key: \"operation\", label: \"Operation\", required: true, default: \"read\",\n options: [{ value: \"read\", label: \"Read\" }, { value: \"write\", label: \"Write\" }, { value: \"append\", label: \"Append\" }] },\n { type: \"text\", key: \"key\", label: \"Key\", placeholder: \"user.preferences\", required: true },\n { type: \"expression\", key: \"value\", label: \"Value (write/append only)\", example: \"{{ $json }}\" },\n { type: \"credential\", key: \"store\", label: \"Memory store\", credentialType: \"memory_store\" },\n ],\n },\n {\n name: \"@particle-academy/data_store\",\n aliases: [\"data_store\", \"@fancy/data_store\"],\n category: \"data\",\n label: \"Data Store\",\n description: \"Key-value or table read/write against a host store.\",\n icon: \"🗃\",\n configSchema: [\n { type: \"select\", key: \"operation\", label: \"Operation\", required: true, default: \"get\",\n options: [\n { value: \"get\", label: \"Get\" }, { value: \"set\", label: \"Set\" }, { value: \"delete\", label: \"Delete\" },\n { value: \"query\", label: \"Query\" }, { value: \"list\", label: \"List\" },\n ] },\n { type: \"text\", key: \"table\", label: \"Table / collection\", required: true },\n { type: \"text\", key: \"key\", label: \"Key\" },\n { type: \"json\", key: \"where\", label: \"Where (JSON)\", description: \"For query/list operations.\" },\n { type: \"expression\", key: \"value\", label: \"Value (set only)\", example: \"{{ $json }}\" },\n { type: \"credential\", key: \"store\", label: \"Data store\", credentialType: \"data_store\" },\n ],\n },\n {\n name: \"@particle-academy/variable\",\n aliases: [\"variable\", \"@fancy/variable\"],\n category: \"data\",\n label: \"Variable\",\n description: \"Workflow-scoped value used by other nodes.\",\n icon: \"𝓍\",\n configSchema: [\n { type: \"text\", key: \"name\", label: \"Name\", required: true },\n { type: \"expression\", key: \"value\", label: \"Value\", required: true },\n ],\n },\n\n // ───────────── AI ─────────────\n {\n name: \"@particle-academy/llm_call\",\n aliases: [\"llm_call\", \"@fancy/llm_call\"],\n category: \"ai\",\n label: \"LLM Call\",\n description: \"Send a prompt + context to a model and receive a response.\",\n icon: \"✦\",\n configSchema: [\n { type: \"select\", key: \"provider\", label: \"Provider\", default: \"anthropic\",\n options: [\n { value: \"anthropic\", label: \"Anthropic\" },\n { value: \"openai\", label: \"OpenAI\" },\n { value: \"custom\", label: \"Custom\" },\n ] },\n { type: \"text\", key: \"model\", label: \"Model\", placeholder: \"claude-sonnet-4-5\", required: true },\n { type: \"textarea\", key: \"system\", label: \"System prompt\", rows: 4 },\n { type: \"expression\", key: \"prompt\", label: \"User prompt\", example: \"{{ $json.question }}\", required: true },\n { type: \"number\", key: \"temperature\", label: \"Temperature\", min: 0, max: 2, step: 0.1, default: 0.7 },\n { type: \"number\", key: \"max_tokens\", label: \"Max tokens\", min: 1, max: 8192, default: 1024 },\n { type: \"json\", key: \"tools\", label: \"Tools (JSON)\", description: \"Optional Anthropic-style tool definitions.\" },\n { type: \"credential\", key: \"credential\", label: \"API credential\", credentialType: \"llm_credential\" },\n ],\n },\n {\n name: \"@particle-academy/llm_branch\",\n aliases: [\"llm_branch\", \"@fancy/llm_branch\"],\n category: \"ai\",\n label: \"LLM Router\",\n description: \"Let a model choose which route the flow takes.\",\n icon: \"✧\",\n inputs: [{ id: \"in\" }],\n // Each declared route is a port. The executor returns `{ __port: id }`\n // (or `Port.only(id)` on the PHP runtime) to pick one.\n outputs: (config: any) => routePorts(config?.routes, config?.fallback),\n // A shuttle, not an engine: it carries the routes out to whatever LLM\n // client the host registered and carries the choice back. No provider SDK\n // reaches core, so this stays a builtin without adding a dependency.\n executor: llmBranchExecutor,\n configSchema: [\n { type: \"textarea\", key: \"system\", label: \"System prompt\", rows: 3,\n description: \"Optional framing for the routing decision.\" },\n { type: \"expression\", key: \"prompt\", label: \"What to route on\",\n example: \"{{ $json.message }}\", required: true },\n {\n type: \"repeater\",\n key: \"routes\",\n label: \"Routes\",\n description: \"The model picks exactly one. Descriptions are what it chooses between — make them distinct.\",\n titleKey: \"port\",\n addLabel: \"Add route\",\n minItems: 2,\n fields: [\n { type: \"text\", key: \"port\", label: \"Port\", required: true, placeholder: \"billing\" },\n { type: \"text\", key: \"description\", label: \"When to choose it\", required: true,\n placeholder: \"The user is asking about an invoice, refund, or payment.\" },\n ],\n default: [\n { port: \"a\", description: \"Describe when the model should pick this route.\" },\n { port: \"b\", description: \"Describe when the model should pick this route.\" },\n ],\n },\n { type: \"select\", key: \"provider\", label: \"Provider\", default: \"anthropic\",\n options: [\n { value: \"anthropic\", label: \"Anthropic\" },\n { value: \"openai\", label: \"OpenAI\" },\n { value: \"custom\", label: \"Custom\" },\n ] },\n { type: \"text\", key: \"model\", label: \"Model\", placeholder: \"claude-sonnet-4-5\" },\n { type: \"switch\", key: \"fallback\", label: \"Add a `fallback` port\", default: true,\n description: \"Where the flow goes if the model returns no usable route.\" },\n { type: \"credential\", key: \"credential\", label: \"API credential\", credentialType: \"llm_credential\" },\n ],\n },\n {\n name: \"@particle-academy/tool_use\",\n aliases: [\"tool_use\", \"@fancy/tool_use\"],\n category: \"ai\",\n label: \"Tool Use\",\n description: \"Hand control to a host-registered tool by name.\",\n icon: \"🛠\",\n configSchema: [\n { type: \"text\", key: \"tool\", label: \"Tool name\", placeholder: \"search_index\", required: true },\n { type: \"expression\", key: \"args\", label: \"Arguments\", example: \"{{ { query: $json.q } }}\" },\n ],\n },\n {\n name: \"@particle-academy/embed_search\",\n aliases: [\"embed_search\", \"@fancy/embed_search\"],\n category: \"ai\",\n label: \"Embed & Search\",\n description: \"Embed a query and search a vector store.\",\n icon: \"✺\",\n configSchema: [\n { type: \"expression\", key: \"query\", label: \"Query\", required: true, example: \"{{ $json.question }}\" },\n { type: \"number\", key: \"topK\", label: \"Top K\", default: 5, min: 1, max: 50 },\n { type: \"credential\", key: \"vectorStore\", label: \"Vector store\", credentialType: \"vector_store\" },\n ],\n },\n\n // ───────────── IO ─────────────\n {\n name: \"@particle-academy/api_request\",\n aliases: [\"api_request\", \"@fancy/api_request\"],\n category: \"io\",\n label: \"API Request\",\n description: \"HTTP request to any URL.\",\n icon: \"↔\",\n configSchema: [\n ...HTTP_METHODS,\n { type: \"text\", key: \"url\", label: \"URL\", placeholder: \"https://api.example.com/...\", required: true },\n { type: \"json\", key: \"headers\", label: \"Headers\", default: { \"content-type\": \"application/json\" } },\n { type: \"json\", key: \"body\", label: \"Body\" },\n { type: \"credential\", key: \"auth\", label: \"Auth\", credentialType: \"api_credential\" },\n ],\n },\n {\n name: \"@particle-academy/webhook_out\",\n aliases: [\"webhook_out\", \"@fancy/webhook_out\"],\n category: \"io\",\n label: \"Send Webhook\",\n description: \"POST a payload to a configured URL.\",\n icon: \"↗\",\n configSchema: [\n { type: \"text\", key: \"url\", label: \"URL\", required: true },\n { type: \"json\", key: \"headers\", label: \"Headers\" },\n { type: \"expression\", key: \"payload\", label: \"Payload\", required: true, example: \"{{ $json }}\" },\n ],\n },\n\n // ───────────── Human ─────────────\n {\n name: \"@particle-academy/human_approval\",\n aliases: [\"human_approval\", \"@fancy/human_approval\"],\n category: \"human\",\n label: \"Human Approval\",\n description: \"Pause until a human approves or denies.\",\n icon: \"✓\",\n inputs: [{ id: \"in\" }],\n outputs: [{ id: \"approved\", label: \"approved\" }, { id: \"denied\", label: \"denied\" }],\n configSchema: [\n { type: \"text\", key: \"title\", label: \"Approval title\", default: \"Approve action\" },\n { type: \"textarea\", key: \"description\", label: \"Description for approver\", rows: 3 },\n { type: \"credential\", key: \"channel\", label: \"Notify channel\", credentialType: \"notify_channel\" },\n ],\n },\n {\n name: \"@particle-academy/notify\",\n aliases: [\"notify\", \"@fancy/notify\"],\n category: \"human\",\n label: \"Notify\",\n description: \"Send a message via Slack / email / SMS / etc.\",\n icon: \"🔔\",\n configSchema: [\n { type: \"select\", key: \"channel\", label: \"Channel\", default: \"slack\",\n options: [\n { value: \"slack\", label: \"Slack\" }, { value: \"email\", label: \"Email\" },\n { value: \"sms\", label: \"SMS\" }, { value: \"discord\", label: \"Discord\" },\n ] },\n { type: \"text\", key: \"to\", label: \"To\", required: true },\n { type: \"expression\", key: \"message\", label: \"Message\", required: true, example: \"{{ $json.summary }}\" },\n ],\n },\n\n // ───────────── Output ─────────────\n {\n name: \"@particle-academy/output\",\n aliases: [\"output\", \"@fancy/output\"],\n category: \"output\",\n label: \"Output\",\n description: \"Terminal node — captures the workflow's result.\",\n icon: \"●\",\n inputs: [{ id: \"in\" }],\n outputs: [],\n },\n {\n name: \"@particle-academy/log\",\n aliases: [\"log\", \"@fancy/log\"],\n category: \"output\",\n label: \"Log\",\n description: \"Send to the run feed.\",\n icon: \"≡\",\n inputs: [{ id: \"in\" }],\n outputs: [],\n configSchema: [\n { type: \"select\", key: \"level\", label: \"Level\", default: \"info\",\n options: [{ value: \"info\", label: \"info\" }, { value: \"warn\", label: \"warn\" }, { value: \"error\", label: \"error\" }] },\n { type: \"expression\", key: \"message\", label: \"Message\", required: true, example: \"{{ $json }}\" },\n ],\n },\n];\n\n/** Register every built-in kind. Idempotent via the registry. */\nexport function registerBuiltinKinds(): void {\n for (const k of KINDS) registerNodeKind(k);\n}\n\n/** Exported list for hosts that want to selectively re-register. */\nexport const BUILTIN_KINDS: NodeKindDefinition[] = KINDS;\n","export type {\n ConfigField,\n TextConfigField,\n TextareaConfigField,\n NumberConfigField,\n SelectConfigField,\n SwitchConfigField,\n JsonConfigField,\n ExpressionConfigField,\n CredentialConfigField,\n RepeaterConfigField,\n RepeaterRowField,\n KeyValueConfigField,\n DocumentConfigField,\n NodeCategory,\n NodeKindDefinition,\n PortSpec,\n RenderBodyContext,\n} from \"./types\";\n\nexport { resolvePortSpec, resolveNodePorts, nodeConfig } from \"./ports\";\n\n/** Host capabilities — core declares the contract, the host supplies the impl. */\nexport {\n registerLlmClient,\n getLlmClient,\n registerWorkflowResolver,\n getWorkflowResolver,\n capabilityStatus,\n type LlmClient,\n type LlmRoute,\n type LlmRouteRequest,\n type LlmRouteChoice,\n type WorkflowResolver,\n type CapabilityId,\n} from \"./capabilities\";\n\nexport { subflowExecutor, subflowPorts, subflowMode, DEFAULT_MAX_DEPTH, type SubflowMode } from \"./subflow\";\nexport { llmBranchExecutor, declaredRoutes, resolveFallbackPort } from \"./llm-branch\";\n\nexport {\n registerRichInputAdapter,\n getRichInputAdapter,\n isRichInputEnabled,\n onRichInputAdapterChanged,\n RichInputPreview,\n type RichInputAdapter,\n} from \"./rich-input\";\n\nexport {\n registerNodeKind,\n getNodeKind,\n resolveKindId,\n kindIds,\n listNodeKinds,\n onNodeKindsChanged,\n defaultConfigFor,\n validateConfig,\n categoryAccent,\n} from \"./registry\";\n\nexport { RegistryNode } from \"./RegistryNode\";\nexport { registerBuiltinKinds, BUILTIN_KINDS } from \"./builtin\";\n\nimport type { NodeTypes } from \"@xyflow/react\";\nimport { RegistryNode } from \"./RegistryNode\";\nimport { kindIds, listNodeKinds } from \"./registry\";\n\n/**\n * Build an xyflow `nodeTypes` map from the registry — every registered\n * kind gets `RegistryNode` as its renderer. Refresh manually via\n * `useNodeTypes()` (a hook that subscribes to registry changes).\n */\nexport function buildNodeTypes(): NodeTypes {\n const map: NodeTypes = {};\n for (const k of listNodeKinds()) {\n // Key on every id the kind answers to, not just the canonical one. xyflow\n // looks the renderer up by `node.type` BEFORE RegistryNode gets a chance to\n // resolve aliases, so a graph still carrying pre-namespace types would fall\n // through to the unknown-node placeholder.\n for (const id of kindIds(k)) map[id] = RegistryNode;\n }\n return map;\n}\n"]}