@particle-academy/fancy-flow 0.65.2 → 0.66.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 (105) hide show
  1. package/README.md +100 -3
  2. package/dist/{FlowViewer-BI_AyyvU.d.ts → FlowViewer-BCc_BvuD.d.ts} +1 -1
  3. package/dist/{FlowViewer-DABx-6A-.d.cts → FlowViewer-CoAJ3o52.d.cts} +1 -1
  4. package/dist/{HumanPrompt-Bpp3JiVH.d.cts → HumanPrompt--pXDOyYC.d.cts} +2 -2
  5. package/dist/{HumanPrompt-BKThiyjB.d.ts → HumanPrompt-DXm_FP9z.d.ts} +2 -2
  6. package/dist/chunk-2QXKDLGT.js +58 -0
  7. package/dist/chunk-2QXKDLGT.js.map +1 -0
  8. package/dist/{chunk-77V4QC6Y.js → chunk-B7HKJJVV.js} +3 -3
  9. package/dist/{chunk-77V4QC6Y.js.map → chunk-B7HKJJVV.js.map} +1 -1
  10. package/dist/{chunk-MBVX4ZRB.js → chunk-FNYLKSFJ.js} +3 -3
  11. package/dist/{chunk-MBVX4ZRB.js.map → chunk-FNYLKSFJ.js.map} +1 -1
  12. package/dist/{chunk-JF6WCRBU.js → chunk-HQGOFGAL.js} +861 -40
  13. package/dist/chunk-HQGOFGAL.js.map +1 -0
  14. package/dist/{chunk-5H54OTKT.js → chunk-IEYCNFXZ.js} +3 -3
  15. package/dist/{chunk-5H54OTKT.js.map → chunk-IEYCNFXZ.js.map} +1 -1
  16. package/dist/{chunk-W5DPKJY4.js → chunk-MTONBM53.js} +4 -4
  17. package/dist/chunk-MTONBM53.js.map +1 -0
  18. package/dist/{chunk-RIAFHQT5.js → chunk-PNHZHEWE.js} +3 -3
  19. package/dist/{chunk-RIAFHQT5.js.map → chunk-PNHZHEWE.js.map} +1 -1
  20. package/dist/{chunk-EO6444T2.js → chunk-UCCTXJXL.js} +4 -4
  21. package/dist/{chunk-EO6444T2.js.map → chunk-UCCTXJXL.js.map} +1 -1
  22. package/dist/connectors.d.cts +2 -2
  23. package/dist/connectors.d.ts +2 -2
  24. package/dist/durable/index.d.cts +2 -2
  25. package/dist/durable/index.d.ts +2 -2
  26. package/dist/durable.cjs +837 -47
  27. package/dist/durable.cjs.map +1 -1
  28. package/dist/durable.js +2 -3
  29. package/dist/durable.js.map +1 -1
  30. package/dist/engine.cjs +843 -132
  31. package/dist/engine.cjs.map +1 -1
  32. package/dist/engine.d.cts +6 -7
  33. package/dist/engine.d.ts +6 -7
  34. package/dist/engine.js +5 -6
  35. package/dist/engine.js.map +1 -1
  36. package/dist/fields/react-fancy.d.cts +3 -3
  37. package/dist/fields/react-fancy.d.ts +3 -3
  38. package/dist/index.cjs +853 -140
  39. package/dist/index.cjs.map +1 -1
  40. package/dist/index.d.cts +65 -36
  41. package/dist/index.d.ts +65 -36
  42. package/dist/index.js +19 -18
  43. package/dist/index.js.map +1 -1
  44. package/dist/layout/index.d.cts +1 -1
  45. package/dist/layout/index.d.ts +1 -1
  46. package/dist/llm/prism.cjs.map +1 -1
  47. package/dist/llm/prism.d.cts +1 -2
  48. package/dist/llm/prism.d.ts +1 -2
  49. package/dist/llm/prism.js +1 -1
  50. package/dist/llm/vercel-ai.cjs.map +1 -1
  51. package/dist/llm/vercel-ai.d.cts +1 -2
  52. package/dist/llm/vercel-ai.d.ts +1 -2
  53. package/dist/llm/vercel-ai.js +1 -1
  54. package/dist/registry/index.d.cts +5 -6
  55. package/dist/registry/index.d.ts +5 -6
  56. package/dist/{registry-CntAdUcY.d.cts → registry-BcgllSk2.d.cts} +1 -1
  57. package/dist/{registry-DYoV-MQi.d.ts → registry-h-2QswZ5.d.ts} +1 -1
  58. package/dist/registry.cjs +867 -37
  59. package/dist/registry.cjs.map +1 -1
  60. package/dist/registry.js +3 -3
  61. package/dist/{run-cohort-C1nRh_mi.d.ts → run-cohort-CjUBWg6X.d.ts} +2 -2
  62. package/dist/{run-cohort-CBRAUj-z.d.cts → run-cohort-DL9JzzPU.d.cts} +2 -2
  63. package/dist/{run-flow-2XsHBwpd.d.cts → run-flow-B_8hgO5_.d.cts} +1 -1
  64. package/dist/{run-flow-D7AOCcfE.d.ts → run-flow-CxEGBOxd.d.ts} +1 -1
  65. package/dist/runtime/index.d.cts +5 -5
  66. package/dist/runtime/index.d.ts +5 -5
  67. package/dist/runtime.cjs +837 -36
  68. package/dist/runtime.cjs.map +1 -1
  69. package/dist/runtime.js +4 -4
  70. package/dist/schema/index.d.cts +19 -6
  71. package/dist/schema/index.d.ts +19 -6
  72. package/dist/schema.cjs +837 -36
  73. package/dist/schema.cjs.map +1 -1
  74. package/dist/schema.js +4 -4
  75. package/dist/screens.cjs +837 -36
  76. package/dist/screens.cjs.map +1 -1
  77. package/dist/screens.d.cts +2 -2
  78. package/dist/screens.d.ts +2 -2
  79. package/dist/screens.js +5 -5
  80. package/dist/terminal/fancy-term-host.cjs +99 -0
  81. package/dist/terminal/fancy-term-host.cjs.map +1 -0
  82. package/dist/terminal/fancy-term-host.d.cts +76 -0
  83. package/dist/terminal/fancy-term-host.d.ts +76 -0
  84. package/dist/terminal/fancy-term-host.js +92 -0
  85. package/dist/terminal/fancy-term-host.js.map +1 -0
  86. package/dist/types-B-Syk9-M.d.cts +620 -0
  87. package/dist/types-B-Syk9-M.d.ts +620 -0
  88. package/dist/{types-D71SKA5A.d.cts → types-C2ATTmjN.d.cts} +1 -1
  89. package/dist/{types-Ckhz-YwC.d.ts → types-VunLGqrn.d.ts} +1 -1
  90. package/dist/ux.cjs +837 -36
  91. package/dist/ux.cjs.map +1 -1
  92. package/dist/ux.d.cts +2 -2
  93. package/dist/ux.d.ts +2 -2
  94. package/dist/ux.js +2 -2
  95. package/package.json +11 -1
  96. package/dist/capabilities-BYa5p5jw.d.cts +0 -112
  97. package/dist/capabilities-COOXRiNL.d.ts +0 -112
  98. package/dist/chunk-JF6WCRBU.js.map +0 -1
  99. package/dist/chunk-UM4C46AF.js +0 -103
  100. package/dist/chunk-UM4C46AF.js.map +0 -1
  101. package/dist/chunk-USL4FMFU.js +0 -41
  102. package/dist/chunk-USL4FMFU.js.map +0 -1
  103. package/dist/chunk-W5DPKJY4.js.map +0 -1
  104. package/dist/types-JFYjPJAG.d.cts +0 -333
  105. package/dist/types-JFYjPJAG.d.ts +0 -333
@@ -1,333 +0,0 @@
1
- import { Node, Edge } from '@xyflow/react';
2
-
3
- /**
4
- * Who is running, which step this is, and how many times it has been tried.
5
- *
6
- * ## Why an engine needs this at all
7
- *
8
- * A node that WRITES to somebody else's system — charge a card, send a message,
9
- * open a pull request — can only survive a retry if the retry carries the same
10
- * idempotency key the first attempt did. Otherwise the provider treats the
11
- * second call as a new request and the customer is charged twice.
12
- *
13
- * Until this existed the executor context was `{ node, inputs, emit, abort }`,
14
- * which is not enough to derive one. Both obvious fallbacks are worse than
15
- * sending no key at all:
16
- *
17
- * - **the node id alone** is stable across retries, and also across RUNS — two
18
- * legitimate payments share a key and the provider silently collapses the
19
- * second into the first. A payment that never happened, reported as success;
20
- * - **a fresh random value** is unique per run, and also per ATTEMPT — a retry
21
- * creates a second charge, which is the thing being avoided.
22
- *
23
- * ## What actually identifies a step
24
- *
25
- * Not `(run, node)`. A node legitimately executes more than once inside one
26
- * run: once per subflow invocation, once per iteration of a loop an executor
27
- * drives itself. `(run, node)` would give every one of those the same key, and
28
- * a provider would honour exactly one of them.
29
- *
30
- * So a step is identified by the **path of invocations that led to it**, plus
31
- * an optional **occurrence** for repetition at the same level:
32
- *
33
- * ```text
34
- * runKey ":" segment ("/" segment)* segment := escape(id) ["#" occurrence]
35
- * ```
36
- *
37
- * And the part that is easy to get backwards: **`attempt` is NOT in the key.**
38
- * It is carried here for logging and for {@link RunIdentity.isReplaySafe}, and
39
- * putting it in the key would restore the exact bug the key exists to prevent.
40
- *
41
- * Pinned cross-runtime by `shared/flow-run-identity` in
42
- * `@particle-academy/fancy-conformance`.
43
- */
44
- /** The wire shape — what a queue job payload carries. */
45
- type RunIdentityJson = {
46
- runKey: string;
47
- path?: string[];
48
- attempt?: number;
49
- firstAttemptAt?: string;
50
- };
51
- /**
52
- * Escape one segment so the composition is injective.
53
- *
54
- * `%` FIRST, or the escaping is not reversible: escaping `/` before `%` turns a
55
- * literal `a%2Fb` into the same text as the escaped form of `a/b`, which is the
56
- * collision this exists to prevent, reintroduced by its own fix.
57
- */
58
- declare function escapeSegment(value: string): string;
59
- /**
60
- * A run, a position inside it, and how many times this position has been tried.
61
- *
62
- * Immutable. {@link descend} returns a new identity rather than mutating, so an
63
- * executor cannot change what its siblings see.
64
- */
65
- declare class RunIdentity {
66
- /** Stable for the whole run: same across retries, resumes, workers and hosts. */
67
- readonly runKey: string;
68
- /**
69
- * Enclosing invocation segments, outermost first, ALREADY RENDERED.
70
- *
71
- * Empty at the top level. A subflow pushes the invoking node's id; an
72
- * executor that loops pushes `id#i`.
73
- */
74
- readonly path: readonly string[];
75
- /**
76
- * 1-based attempt of THIS logical step. Never part of the key.
77
- *
78
- * The durable driver sets it from the node's claim row, which is exact. A
79
- * plain in-process `runFlow` gets whatever the host passed, which is
80
- * run-scoped and therefore conservative — see `isReplaySafe`.
81
- */
82
- readonly attempt: number;
83
- /** ISO-8601 UTC instant of attempt 1 of this step. */
84
- readonly firstAttemptAt: string;
85
- constructor(runKey: string, path?: readonly string[], attempt?: number, firstAttemptAt?: string);
86
- /**
87
- * The identity of one execution of one node — stable across retries of that
88
- * execution, distinct from every other execution of the same node.
89
- *
90
- * Pass `occurrence` when an executor runs the same node more than once at the
91
- * same level (a loop body, one item of a fan-out it drives itself).
92
- */
93
- stepKey(nodeId: string, occurrence?: number | null): string;
94
- /**
95
- * A child identity for work nested inside this step.
96
- *
97
- * `subflow` pushes the invoking node's id, so a node inside the child graph
98
- * cannot collide with a same-named node in the parent. Attempt and
99
- * `firstAttemptAt` are carried down unchanged: the nested work happens inside
100
- * this step's attempt, and shares its clock.
101
- */
102
- descend(segment: string, occurrence?: number | null): RunIdentity;
103
- /** A copy on a different attempt, first-attempt clock preserved. */
104
- withAttempt(attempt: number, firstAttemptAt?: string): RunIdentity;
105
- /**
106
- * May this attempt reuse the step key and still be deduplicated?
107
- *
108
- * Providers forget idempotency keys — Stripe after 24 hours. Past that
109
- * window, resending the key creates a second charge and sending a fresh one
110
- * creates a second charge, so **the caller must refuse rather than pick
111
- * between them**: a loud stuck run beats a silent double write.
112
- *
113
- * `true` on attempt 1 whatever the elapsed time — nothing was sent on an
114
- * earlier attempt, so there is nothing for the provider to have forgotten.
115
- * That is what lets a run park on a human gate for a week and then write.
116
- *
117
- * `windowSeconds: null` means the provider does not expire keys. `0` means
118
- * it does not dedupe at all, so no retry may reuse a key — it is a real
119
- * window, not an absent one, and the two must not be conflated: reading `0`
120
- * as `null` turns "this provider does not dedupe" into "this provider
121
- * dedupes forever", which is the more dangerous of the two by a distance.
122
- */
123
- isReplaySafe(windowSeconds: number | null | undefined, now?: Date | string): boolean;
124
- toJSON(): Required<RunIdentityJson>;
125
- /** Rebuild from a queue payload. */
126
- static from(value: RunIdentity | RunIdentityJson | string): RunIdentity;
127
- }
128
-
129
- /**
130
- * Public domain types for fancy-flow. Built-in nodes are layered on top of
131
- * @xyflow/react's `Node` so consumers can mix custom xyflow nodes alongside
132
- * the kit. Edges remain xyflow's standard `Edge`.
133
- */
134
-
135
- type FlowNodeKind = "trigger" | "action" | "decision" | "output" | "note" | "subgraph";
136
- /** Status surfaced on the node while a run is in progress. */
137
- type NodeRunStatus = "idle" | "queued" | "running" | "done" | "error";
138
- /** Port description on a node. Ports are visual handles xyflow can connect. */
139
- type PortDescriptor = {
140
- id: string;
141
- label?: string;
142
- /** Optional logical type for hosts that want to validate connections. */
143
- type?: string;
144
- };
145
- /** Common shape every kit node carries in its `data` slot. */
146
- type BaseNodeData = {
147
- label: string;
148
- description?: string;
149
- /** Free-form configuration the host owns (form values, code, parameters). */
150
- config?: Record<string, unknown>;
151
- /** Set by the runner; hosts shouldn't edit this directly. */
152
- status?: NodeRunStatus;
153
- /** Optional human-readable status detail (e.g. error message, current step). */
154
- statusText?: string;
155
- /**
156
- * Announced to a person just BEFORE this node runs — "Starting the deep
157
- * analysis". Authored on the node, so a graph narrates itself without the
158
- * host writing any per-node reporting code.
159
- *
160
- * Optional on purpose. Most nodes in a real graph are plumbing, and a run
161
- * that narrates all of them buries the two or three steps anyone follows.
162
- */
163
- startingMsg?: string;
164
- /**
165
- * Announced AFTER this node finishes — "Analysis complete".
166
- *
167
- * Emitted only when the node SUCCEEDS. A completion message printed after a
168
- * failure tells a human the opposite of what happened, in the part of the UI
169
- * they trust most; failures report through `node-status` and `log`.
170
- */
171
- stoppingMsg?: string;
172
- /** Per-node accent override, e.g. for theming a custom subclass. */
173
- color?: string;
174
- /** Input ports rendered on the node. Defaults vary by kind. */
175
- inputs?: PortDescriptor[];
176
- /** Output ports rendered on the node. Defaults vary by kind. */
177
- outputs?: PortDescriptor[];
178
- };
179
- type TriggerNodeData = BaseNodeData & {
180
- kind: "trigger";
181
- };
182
- type ActionNodeData = BaseNodeData & {
183
- kind: "action";
184
- };
185
- type DecisionNodeData = BaseNodeData & {
186
- kind: "decision";
187
- };
188
- type OutputNodeData = BaseNodeData & {
189
- kind: "output";
190
- };
191
- type NoteNodeData = BaseNodeData & {
192
- kind: "note";
193
- body?: string;
194
- };
195
- type SubgraphNodeData = BaseNodeData & {
196
- kind: "subgraph";
197
- /** Ids of the nodes contained in this subgraph. */
198
- childIds?: string[];
199
- /** Whether the subgraph is shown collapsed (default true — children hidden). */
200
- collapsed?: boolean;
201
- };
202
- type FlowNodeData = TriggerNodeData | ActionNodeData | DecisionNodeData | OutputNodeData | NoteNodeData | SubgraphNodeData;
203
- type FlowNode = Node<FlowNodeData>;
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
- };
234
- /** A serializable graph — what hosts persist, what agents read/write. */
235
- type FlowGraph = {
236
- nodes: FlowNode[];
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[];
245
- };
246
- /** Per-node executor signature. Inputs are keyed by input-port id. */
247
- type NodeExecutor<TIn = Record<string, unknown>, TOut = unknown> = (ctx: {
248
- node: FlowNode;
249
- inputs: TIn;
250
- /** Stops the run if called. */
251
- abort: (reason?: string) => never;
252
- /** Lets the executor stream status updates and partial outputs. */
253
- emit: (event: RunEvent) => void;
254
- /**
255
- * The registry THIS run is executing against.
256
- *
257
- * Handed down so an executor that starts a NESTED run gives the child the
258
- * same executors as the parent. `subflow` previously ran its child against
259
- * `config.executors ?? {}` — an empty registry unless the graph happened to
260
- * carry one — so a host kind resolved at top level and vanished one level
261
- * down, and a host that had REPLACED a builtin got the package's version in
262
- * the child. Same graph, different behaviour by nesting depth, reported
263
- * against the PHP twin as fancy-flow-php#7.
264
- *
265
- * Inheriting from the context rather than from a parameter is what makes it
266
- * unforgettable: any future nesting executor gets it without opting in.
267
- */
268
- executors?: ExecutorRegistry;
269
- /**
270
- * How deep this run is nested. 0 for a top-level run; `subflow` passes
271
- * depth + 1 to its child, so runaway recursion can be reported by name
272
- * rather than as a stack overflow.
273
- */
274
- depth?: number;
275
- /**
276
- * Who is running, and which attempt of which step this is.
277
- *
278
- * `ctx.run.stepKey(ctx.node.id)` is the idempotency key for a node that
279
- * writes to somebody else's system — stable across retries of this step,
280
- * distinct for every other execution of the same node.
281
- *
282
- * `undefined` when the host supplied no identity, and that is a real
283
- * answer: a write with no key must decline or accept one attempt, never
284
- * invent a key. See `RunIdentity`.
285
- */
286
- run?: RunIdentity;
287
- }) => Promise<TOut> | TOut;
288
- type ExecutorRegistry = Partial<Record<FlowNodeKind | string, NodeExecutor>>;
289
- type RunEvent = {
290
- type: "node-status";
291
- nodeId: string;
292
- status: NodeRunStatus;
293
- text?: string;
294
- }
295
- /**
296
- * A human-facing announcement a node makes around its own execution, from
297
- * `data.startingMsg` / `data.stoppingMsg`. Opt-in per node: most nodes in a
298
- * real graph are plumbing, and narrating all of them buries the few steps a
299
- * person cares about.
300
- *
301
- * Deliberately NOT folded into `node-status.text`, which already carries
302
- * "skipped", "resumed", "lane", "annotation" and raw error strings. Those are
303
- * diagnostics; these are addressed to a person. A consumer rendering a
304
- * progress feed cannot be asked to guess which is which — that is how an
305
- * error string ends up shown to a user as a status update.
306
- */
307
- | {
308
- type: "node-message";
309
- nodeId: string;
310
- phase: "start" | "end";
311
- message: string;
312
- } | {
313
- type: "node-output";
314
- nodeId: string;
315
- portId: string;
316
- value: unknown;
317
- } | {
318
- type: "log";
319
- nodeId?: string;
320
- level: "info" | "warn" | "error";
321
- message: string;
322
- detail?: unknown;
323
- } | {
324
- type: "run-start";
325
- } | {
326
- type: "run-end";
327
- ok: boolean;
328
- } | {
329
- type: "run-error";
330
- error: string;
331
- };
332
-
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 };