@particle-academy/fancy-flow 0.56.0 → 0.58.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 (57) hide show
  1. package/dist/{HumanPrompt-DlJSFi3F.d.ts → HumanPrompt-Bw09OyS3.d.ts} +1 -1
  2. package/dist/{HumanPrompt-CPl-Spmp.d.cts → HumanPrompt-DV5-xnDa.d.cts} +1 -1
  3. package/dist/{chunk-KP4TBF3A.js → chunk-A3TLZS5B.js} +3 -3
  4. package/dist/{chunk-KP4TBF3A.js.map → chunk-A3TLZS5B.js.map} +1 -1
  5. package/dist/{chunk-GB4A7DFM.js → chunk-FGYG5JVW.js} +3 -3
  6. package/dist/{chunk-GB4A7DFM.js.map → chunk-FGYG5JVW.js.map} +1 -1
  7. package/dist/{chunk-22OJOD4X.js → chunk-HBE4LVPX.js} +54 -2
  8. package/dist/chunk-HBE4LVPX.js.map +1 -0
  9. package/dist/{chunk-L4QAAGLV.js → chunk-LGLOBK6Q.js} +3 -3
  10. package/dist/{chunk-L4QAAGLV.js.map → chunk-LGLOBK6Q.js.map} +1 -1
  11. package/dist/{chunk-E3AGYTHP.js → chunk-M7M6GLFV.js} +3 -3
  12. package/dist/{chunk-E3AGYTHP.js.map → chunk-M7M6GLFV.js.map} +1 -1
  13. package/dist/{chunk-HMEI2LFU.js → chunk-MX4SJDNI.js} +4 -4
  14. package/dist/{chunk-HMEI2LFU.js.map → chunk-MX4SJDNI.js.map} +1 -1
  15. package/dist/connectors.d.cts +1 -1
  16. package/dist/connectors.d.ts +1 -1
  17. package/dist/durable.cjs +52 -0
  18. package/dist/durable.cjs.map +1 -1
  19. package/dist/durable.js +1 -1
  20. package/dist/engine.cjs +52 -0
  21. package/dist/engine.cjs.map +1 -1
  22. package/dist/engine.d.cts +2 -2
  23. package/dist/engine.d.ts +2 -2
  24. package/dist/engine.js +3 -3
  25. package/dist/fields/react-fancy.d.cts +2 -2
  26. package/dist/fields/react-fancy.d.ts +2 -2
  27. package/dist/index.cjs +52 -0
  28. package/dist/index.cjs.map +1 -1
  29. package/dist/index.d.cts +5 -5
  30. package/dist/index.d.ts +5 -5
  31. package/dist/index.js +11 -11
  32. package/dist/index.js.map +1 -1
  33. package/dist/registry/index.d.cts +3 -3
  34. package/dist/registry/index.d.ts +3 -3
  35. package/dist/{registry-C6TMfiD_.d.cts → registry-1qhmRtvC.d.cts} +1 -1
  36. package/dist/{registry-3RkSYrMi.d.ts → registry-D2qocEsY.d.ts} +1 -1
  37. package/dist/registry.cjs +52 -0
  38. package/dist/registry.cjs.map +1 -1
  39. package/dist/registry.js +2 -2
  40. package/dist/runtime.cjs +52 -0
  41. package/dist/runtime.cjs.map +1 -1
  42. package/dist/runtime.js +3 -3
  43. package/dist/schema.cjs +52 -0
  44. package/dist/schema.cjs.map +1 -1
  45. package/dist/schema.js +2 -2
  46. package/dist/screens.cjs +52 -0
  47. package/dist/screens.cjs.map +1 -1
  48. package/dist/screens.js +4 -4
  49. package/dist/{types-3sPauVRT.d.cts → types-BLVpNNLN.d.cts} +40 -1
  50. package/dist/{types-s643U1Hi.d.ts → types-CLSUZW8c.d.ts} +40 -1
  51. package/dist/ux.cjs +52 -0
  52. package/dist/ux.cjs.map +1 -1
  53. package/dist/ux.d.cts +1 -1
  54. package/dist/ux.d.ts +1 -1
  55. package/dist/ux.js +1 -1
  56. package/package.json +1 -1
  57. package/dist/chunk-22OJOD4X.js.map +0 -1
package/dist/screens.js CHANGED
@@ -1,8 +1,8 @@
1
- import { FlowViewer } from './chunk-HMEI2LFU.js';
2
- export { FlowViewer } from './chunk-HMEI2LFU.js';
3
- import './chunk-E3AGYTHP.js';
1
+ import { FlowViewer } from './chunk-MX4SJDNI.js';
2
+ export { FlowViewer } from './chunk-MX4SJDNI.js';
3
+ import './chunk-M7M6GLFV.js';
4
4
  import './chunk-UEOE6B52.js';
5
- import './chunk-22OJOD4X.js';
5
+ import './chunk-HBE4LVPX.js';
6
6
  import './chunk-F5RPRB7A.js';
7
7
  import './chunk-USL4FMFU.js';
8
8
  import { registerSchemaComponents } from '@particle-academy/fancy-screens';
@@ -485,6 +485,13 @@ type RenderBodyContext<TConfig = unknown> = {
485
485
  config: TConfig;
486
486
  selected: boolean;
487
487
  };
488
+ /**
489
+ * How a kind's output relates to its input. See `NodeKindDefinition.emits`.
490
+ *
491
+ * Every value is TOP-LEVEL by construction — a relation cannot describe a value
492
+ * nested under a key, which is why `wait` declares a field list instead.
493
+ */
494
+ type EmitsRelation = "input" | "inputs-merged" | `expression:${string}`;
488
495
  /**
489
496
  * NodeKindDefinition — declares an authorable node type. Register one
490
497
  * via `registerNodeKind()`. Hosts (and the agent bridge) introspect the
@@ -538,6 +545,38 @@ type NodeKindDefinition<TConfig = Record<string, unknown>, TIn = any, TOut = any
538
545
  * emits the field keys its author defined, which no static list can know.
539
546
  */
540
547
  outputShape?: OutputShape<TConfig>;
548
+ /**
549
+ * How this kind's output RELATES to its input, when the relation is what is
550
+ * knowable rather than a field list.
551
+ *
552
+ * `outputShape` answers *which fields*; this answers *where they come from*.
553
+ * Separate because they are separate questions, and one field carrying
554
+ * sometimes-a-list-sometimes-a-keyword is one a reader handles only in the
555
+ * form it met first.
556
+ *
557
+ * - `"input"` — emits its input unchanged
558
+ * - `"inputs-merged"` — the union of every input's fields
559
+ * - `` `expression:${string}` `` — the shape the expression in THAT CONFIG KEY
560
+ * names. The key is part of the value because a consumer hardcoding "the
561
+ * field called expression" has copied our knowledge one level down, which is
562
+ * the thing this removes: `transform` reads `expression`, `variable` reads
563
+ * `value`.
564
+ * - a function of config, for a kind whose relation depends on how it was
565
+ * configured.
566
+ *
567
+ * **A relation with no destination can only express a TOP-LEVEL merge.**
568
+ * `wait` returns `{ waited, duration, input }` — it NESTS its input under a
569
+ * key. `emits: "input"` there would make a reader accept
570
+ * `{{ in.<any inbound field> }}` at top level, which resolves to nothing at
571
+ * run time. It keeps a static `outputShape` with an opaque `input` field
572
+ * instead. Read the executor and ask *merge or nest* before assigning one;
573
+ * under-claiming is free.
574
+ *
575
+ * An `expression` relation is knowable only when the whole config string is a
576
+ * SINGLE reference. Interpolating several yields a string with no addressable
577
+ * fields, and a reader that expands it anyway over-permits.
578
+ */
579
+ emits?: EmitsRelation | ((config: TConfig) => EmitsRelation | null);
541
580
  /** Optional custom body rendered inside the node card. */
542
581
  renderBody?: (ctx: RenderBodyContext<TConfig>) => ReactNode;
543
582
  /**
@@ -621,4 +660,4 @@ type NodeKindDefinition<TConfig = Record<string, unknown>, TIn = any, TOut = any
621
660
  reactive?: boolean;
622
661
  };
623
662
 
624
- export { type AvailableVariable as A, type ConfigField as C, type DocumentConfigField as D, type ExpressionConfigField as E, type JsonConfigField as J, type KeyValueConfigField as K, type ManifestProblem as M, type NodeKindDefinition as N, type OutputField as O, type PortSpec as P, type RenderBodyContext as R, type SideEffects as S, type TextConfigField as T, type NodeCategory as a, type CapabilityRequirement as b, type ManifestValidation as c, NODE_MANIFEST_SCHEMA_VERSION as d, type NodePackageManifest as e, type NodeRuntimeId as f, type NodeRuntimeSpec as g, type OutputShape as h, checkCapabilities as i, checkRuntimeSupport as j, type CredentialConfigField as k, type NumberConfigField as l, type RepeaterConfigField as m, type RepeaterRowField as n, type SelectConfigField as o, type SwitchConfigField as p, type TextareaConfigField as q, type ExpressionForm as r, satisfiesRange as s, type ExpressionGrammarHelp as t, availableVariables as u, validateNodeManifest as v, baseVariables as w, describeExpressionGrammar as x, outputFieldsFor as y };
663
+ export { type AvailableVariable as A, type ConfigField as C, type DocumentConfigField as D, type EmitsRelation as E, type JsonConfigField as J, type KeyValueConfigField as K, type ManifestProblem as M, type NodeKindDefinition as N, type OutputField as O, type PortSpec as P, type RenderBodyContext as R, type SideEffects as S, type TextConfigField as T, type NodeCategory as a, type CapabilityRequirement as b, type ManifestValidation as c, NODE_MANIFEST_SCHEMA_VERSION as d, type NodePackageManifest as e, type NodeRuntimeId as f, type NodeRuntimeSpec as g, type OutputShape as h, checkCapabilities as i, checkRuntimeSupport as j, type CredentialConfigField as k, type ExpressionConfigField as l, type NumberConfigField as m, type RepeaterConfigField as n, type RepeaterRowField as o, type SelectConfigField as p, type SwitchConfigField as q, type TextareaConfigField as r, satisfiesRange as s, type ExpressionForm as t, type ExpressionGrammarHelp as u, validateNodeManifest as v, availableVariables as w, baseVariables as x, describeExpressionGrammar as y, outputFieldsFor as z };
@@ -485,6 +485,13 @@ type RenderBodyContext<TConfig = unknown> = {
485
485
  config: TConfig;
486
486
  selected: boolean;
487
487
  };
488
+ /**
489
+ * How a kind's output relates to its input. See `NodeKindDefinition.emits`.
490
+ *
491
+ * Every value is TOP-LEVEL by construction — a relation cannot describe a value
492
+ * nested under a key, which is why `wait` declares a field list instead.
493
+ */
494
+ type EmitsRelation = "input" | "inputs-merged" | `expression:${string}`;
488
495
  /**
489
496
  * NodeKindDefinition — declares an authorable node type. Register one
490
497
  * via `registerNodeKind()`. Hosts (and the agent bridge) introspect the
@@ -538,6 +545,38 @@ type NodeKindDefinition<TConfig = Record<string, unknown>, TIn = any, TOut = any
538
545
  * emits the field keys its author defined, which no static list can know.
539
546
  */
540
547
  outputShape?: OutputShape<TConfig>;
548
+ /**
549
+ * How this kind's output RELATES to its input, when the relation is what is
550
+ * knowable rather than a field list.
551
+ *
552
+ * `outputShape` answers *which fields*; this answers *where they come from*.
553
+ * Separate because they are separate questions, and one field carrying
554
+ * sometimes-a-list-sometimes-a-keyword is one a reader handles only in the
555
+ * form it met first.
556
+ *
557
+ * - `"input"` — emits its input unchanged
558
+ * - `"inputs-merged"` — the union of every input's fields
559
+ * - `` `expression:${string}` `` — the shape the expression in THAT CONFIG KEY
560
+ * names. The key is part of the value because a consumer hardcoding "the
561
+ * field called expression" has copied our knowledge one level down, which is
562
+ * the thing this removes: `transform` reads `expression`, `variable` reads
563
+ * `value`.
564
+ * - a function of config, for a kind whose relation depends on how it was
565
+ * configured.
566
+ *
567
+ * **A relation with no destination can only express a TOP-LEVEL merge.**
568
+ * `wait` returns `{ waited, duration, input }` — it NESTS its input under a
569
+ * key. `emits: "input"` there would make a reader accept
570
+ * `{{ in.<any inbound field> }}` at top level, which resolves to nothing at
571
+ * run time. It keeps a static `outputShape` with an opaque `input` field
572
+ * instead. Read the executor and ask *merge or nest* before assigning one;
573
+ * under-claiming is free.
574
+ *
575
+ * An `expression` relation is knowable only when the whole config string is a
576
+ * SINGLE reference. Interpolating several yields a string with no addressable
577
+ * fields, and a reader that expands it anyway over-permits.
578
+ */
579
+ emits?: EmitsRelation | ((config: TConfig) => EmitsRelation | null);
541
580
  /** Optional custom body rendered inside the node card. */
542
581
  renderBody?: (ctx: RenderBodyContext<TConfig>) => ReactNode;
543
582
  /**
@@ -621,4 +660,4 @@ type NodeKindDefinition<TConfig = Record<string, unknown>, TIn = any, TOut = any
621
660
  reactive?: boolean;
622
661
  };
623
662
 
624
- export { type AvailableVariable as A, type ConfigField as C, type DocumentConfigField as D, type ExpressionConfigField as E, type JsonConfigField as J, type KeyValueConfigField as K, type ManifestProblem as M, type NodeKindDefinition as N, type OutputField as O, type PortSpec as P, type RenderBodyContext as R, type SideEffects as S, type TextConfigField as T, type NodeCategory as a, type CapabilityRequirement as b, type ManifestValidation as c, NODE_MANIFEST_SCHEMA_VERSION as d, type NodePackageManifest as e, type NodeRuntimeId as f, type NodeRuntimeSpec as g, type OutputShape as h, checkCapabilities as i, checkRuntimeSupport as j, type CredentialConfigField as k, type NumberConfigField as l, type RepeaterConfigField as m, type RepeaterRowField as n, type SelectConfigField as o, type SwitchConfigField as p, type TextareaConfigField as q, type ExpressionForm as r, satisfiesRange as s, type ExpressionGrammarHelp as t, availableVariables as u, validateNodeManifest as v, baseVariables as w, describeExpressionGrammar as x, outputFieldsFor as y };
663
+ export { type AvailableVariable as A, type ConfigField as C, type DocumentConfigField as D, type EmitsRelation as E, type JsonConfigField as J, type KeyValueConfigField as K, type ManifestProblem as M, type NodeKindDefinition as N, type OutputField as O, type PortSpec as P, type RenderBodyContext as R, type SideEffects as S, type TextConfigField as T, type NodeCategory as a, type CapabilityRequirement as b, type ManifestValidation as c, NODE_MANIFEST_SCHEMA_VERSION as d, type NodePackageManifest as e, type NodeRuntimeId as f, type NodeRuntimeSpec as g, type OutputShape as h, checkCapabilities as i, checkRuntimeSupport as j, type CredentialConfigField as k, type ExpressionConfigField as l, type NumberConfigField as m, type RepeaterConfigField as n, type RepeaterRowField as o, type SelectConfigField as p, type SwitchConfigField as q, type TextareaConfigField as r, satisfiesRange as s, type ExpressionForm as t, type ExpressionGrammarHelp as u, validateNodeManifest as v, availableVariables as w, baseVariables as x, describeExpressionGrammar as y, outputFieldsFor as z };
package/dist/ux.cjs CHANGED
@@ -9694,6 +9694,8 @@ var KINDS = [
9694
9694
  // ───────────── Triggers ─────────────
9695
9695
  {
9696
9696
  name: "@particle-academy/manual_trigger",
9697
+ // returns the inputs it was started with
9698
+ emits: "input",
9697
9699
  aliases: ["manual_trigger", "@fancy/manual_trigger"],
9698
9700
  category: "trigger",
9699
9701
  label: "Manual",
@@ -9722,6 +9724,12 @@ var KINDS = [
9722
9724
  },
9723
9725
  {
9724
9726
  name: "@particle-academy/schedule_trigger",
9727
+ outputShape: [
9728
+ { path: "cron", type: "string", description: "The cron expression that fired." },
9729
+ { path: "timezone", type: "string", description: "The timezone it was evaluated in." }
9730
+ ],
9731
+ // merges its inputs into the TOP level beside cron/timezone
9732
+ emits: "inputs-merged",
9725
9733
  aliases: ["schedule_trigger", "@fancy/schedule_trigger"],
9726
9734
  category: "trigger",
9727
9735
  label: "Schedule",
@@ -9909,6 +9917,8 @@ var KINDS = [
9909
9917
  // ───────────── Logic ─────────────
9910
9918
  {
9911
9919
  name: "@particle-academy/branch",
9920
+ // returns its input on the chosen port
9921
+ emits: "input",
9912
9922
  aliases: ["branch", "@fancy/branch"],
9913
9923
  category: "logic",
9914
9924
  label: "Branch",
@@ -9972,6 +9982,8 @@ var KINDS = [
9972
9982
  },
9973
9983
  {
9974
9984
  name: "@particle-academy/switch_case",
9985
+ // returns its input on the chosen port
9986
+ emits: "input",
9975
9987
  aliases: ["switch_case", "@fancy/switch_case"],
9976
9988
  category: "logic",
9977
9989
  label: "Switch",
@@ -10018,6 +10030,12 @@ var KINDS = [
10018
10030
  },
10019
10031
  {
10020
10032
  name: "@particle-academy/merge",
10033
+ // `merge` mode unions every object input at the TOP level; `concat` builds
10034
+ // a list instead, whose elements are not addressable as fields. So concat
10035
+ // declares NOTHING rather than an empty list -- `[]` would claim "emits no
10036
+ // fields" of a kind that emits a list, which is false and refuses every
10037
+ // reference.
10038
+ emits: (config) => (config?.mode ?? "merge") === "concat" ? null : "inputs-merged",
10021
10039
  aliases: ["merge", "@fancy/merge"],
10022
10040
  category: "logic",
10023
10041
  label: "Merge",
@@ -10037,6 +10055,11 @@ var KINDS = [
10037
10055
  },
10038
10056
  {
10039
10057
  name: "@particle-academy/wait",
10058
+ outputShape: [
10059
+ { path: "waited", type: "string", description: "Which wait mode ran." },
10060
+ { path: "duration", type: "number", description: "How long it waited." },
10061
+ { path: "input", type: "unknown", description: "The value that arrived, carried forward." }
10062
+ ],
10040
10063
  aliases: ["wait", "@fancy/wait"],
10041
10064
  category: "logic",
10042
10065
  label: "Wait",
@@ -10055,6 +10078,9 @@ var KINDS = [
10055
10078
  },
10056
10079
  {
10057
10080
  name: "@particle-academy/transform",
10081
+ // Two behaviours: the input unchanged when no expression is configured,
10082
+ // else the shape that expression names. So the RELATION is config-dependent.
10083
+ emits: (config) => (config?.expression ?? "") === "" ? "input" : "expression:expression",
10058
10084
  aliases: ["transform", "@fancy/transform"],
10059
10085
  category: "logic",
10060
10086
  label: "Transform",
@@ -10154,6 +10180,8 @@ var KINDS = [
10154
10180
  },
10155
10181
  {
10156
10182
  name: "@particle-academy/variable",
10183
+ // evaluates the expression in config.value
10184
+ emits: "expression:value",
10157
10185
  aliases: ["variable", "@fancy/variable"],
10158
10186
  category: "data",
10159
10187
  label: "Variable",
@@ -10234,6 +10262,11 @@ var KINDS = [
10234
10262
  },
10235
10263
  {
10236
10264
  name: "@particle-academy/llm_router",
10265
+ outputShape: [
10266
+ { path: "route", type: "string", description: "The port the model chose." },
10267
+ { path: "reason", type: "string", description: "Why the model chose it." },
10268
+ { path: "input", type: "unknown", description: "The value that arrived, carried forward." }
10269
+ ],
10237
10270
  // Every id this node has ever shipped under keeps resolving — MOIC's saved
10238
10271
  // flows carry the bare `llm_branch`.
10239
10272
  aliases: ["llm_router", "llm_branch", "@fancy/llm_branch", "@fancy/llm_router"],
@@ -10372,6 +10405,11 @@ var KINDS = [
10372
10405
  },
10373
10406
  {
10374
10407
  name: "@particle-academy/webhook_out",
10408
+ outputShape: [
10409
+ { path: "sent", type: "boolean", description: "True once the request was made." },
10410
+ { path: "status", type: "number", description: "HTTP status, when the transport reported one." },
10411
+ { path: "response", type: "unknown", description: "The response body, when there was one." }
10412
+ ],
10375
10413
  aliases: ["webhook_out", "@fancy/webhook_out"],
10376
10414
  category: "io",
10377
10415
  label: "Send Webhook",
@@ -10393,6 +10431,8 @@ var KINDS = [
10393
10431
  // ───────────── Human ─────────────
10394
10432
  {
10395
10433
  name: "@particle-academy/human_approval",
10434
+ // returns its input on approved/denied
10435
+ emits: "input",
10396
10436
  aliases: ["human_approval", "@fancy/human_approval"],
10397
10437
  pausesForHuman: "approval",
10398
10438
  category: "human",
@@ -10409,6 +10449,12 @@ var KINDS = [
10409
10449
  },
10410
10450
  {
10411
10451
  name: "@particle-academy/notify",
10452
+ outputShape: [
10453
+ { path: "sent", type: "boolean", description: "True once the message was handed to the channel." },
10454
+ { path: "channel", type: "string", description: "The channel it went to." },
10455
+ { path: "to", type: "string", description: "The recipient." },
10456
+ { path: "message", type: "string", description: "The rendered message." }
10457
+ ],
10412
10458
  aliases: ["notify", "@fancy/notify"],
10413
10459
  category: "human",
10414
10460
  label: "Notify",
@@ -10434,6 +10480,8 @@ var KINDS = [
10434
10480
  // ───────────── Output ─────────────
10435
10481
  {
10436
10482
  name: "@particle-academy/output",
10483
+ // returns its input unchanged
10484
+ emits: "input",
10437
10485
  aliases: ["output", "@fancy/output"],
10438
10486
  category: "output",
10439
10487
  label: "Output",
@@ -10444,6 +10492,10 @@ var KINDS = [
10444
10492
  },
10445
10493
  {
10446
10494
  name: "@particle-academy/log",
10495
+ outputShape: [
10496
+ { path: "logged", type: "string", description: "The message that was written." },
10497
+ { path: "level", type: "string", description: "The level it was written at." }
10498
+ ],
10447
10499
  aliases: ["log", "@fancy/log"],
10448
10500
  category: "output",
10449
10501
  label: "Log",