@particle-academy/fancy-flow 0.24.0 → 0.26.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 (41) hide show
  1. package/dist/{chunk-OHVSEHDC.js → chunk-N5ICD2WZ.js} +3 -3
  2. package/dist/{chunk-OHVSEHDC.js.map → chunk-N5ICD2WZ.js.map} +1 -1
  3. package/dist/{chunk-ZS6DVGB3.js → chunk-OFW7GN3Y.js} +4 -4
  4. package/dist/{chunk-ZS6DVGB3.js.map → chunk-OFW7GN3Y.js.map} +1 -1
  5. package/dist/{chunk-YXRLIV7A.js → chunk-Q6IPK64P.js} +4 -2
  6. package/dist/chunk-Q6IPK64P.js.map +1 -0
  7. package/dist/{chunk-KDHLKBL2.js → chunk-U2VJB7HR.js} +7 -5
  8. package/dist/chunk-U2VJB7HR.js.map +1 -0
  9. package/dist/{chunk-QAA4CA22.js → chunk-YOFCVO2W.js} +118 -6
  10. package/dist/chunk-YOFCVO2W.js.map +1 -0
  11. package/dist/engine.cjs +4 -2
  12. package/dist/engine.cjs.map +1 -1
  13. package/dist/engine.js +3 -3
  14. package/dist/index.cjs +287 -24
  15. package/dist/index.cjs.map +1 -1
  16. package/dist/index.d.cts +3 -8
  17. package/dist/index.d.ts +3 -8
  18. package/dist/index.js +180 -33
  19. package/dist/index.js.map +1 -1
  20. package/dist/registry/index.d.cts +2 -2
  21. package/dist/registry/index.d.ts +2 -2
  22. package/dist/registry.cjs +111 -2
  23. package/dist/registry.cjs.map +1 -1
  24. package/dist/registry.js +3 -3
  25. package/dist/runtime.cjs +4 -2
  26. package/dist/runtime.cjs.map +1 -1
  27. package/dist/runtime.js +3 -3
  28. package/dist/schema.cjs.map +1 -1
  29. package/dist/schema.js +2 -2
  30. package/dist/styles.css +198 -0
  31. package/dist/styles.css.map +1 -1
  32. package/dist/{types-DwRpXXNy.d.ts → types-BGtR3k9J.d.ts} +1 -1
  33. package/dist/{types-BekE5JTG.d.cts → types-B_pxRqfw.d.cts} +1 -1
  34. package/dist/ux.cjs.map +1 -1
  35. package/dist/ux.d.cts +1 -1
  36. package/dist/ux.d.ts +1 -1
  37. package/dist/ux.js +1 -1
  38. package/package.json +1 -1
  39. package/dist/chunk-KDHLKBL2.js.map +0 -1
  40. package/dist/chunk-QAA4CA22.js.map +0 -1
  41. package/dist/chunk-YXRLIV7A.js.map +0 -1
package/dist/index.d.cts CHANGED
@@ -9,8 +9,8 @@ import { WorkflowSchema, WorkflowMetadata } from './schema/index.cjs';
9
9
  export { ImportIssue, ImportOptions, ImportResult, WORKFLOW_SCHEMA_URL, WORKFLOW_SCHEMA_VERSION, WorkflowSchemaEdge, WorkflowSchemaNode, exportWorkflow, importWorkflow, migrateSchema, workflowToBlob } from './schema/index.cjs';
10
10
  import { AutoLayoutOptions } from './layout/index.cjs';
11
11
  export { AutoLayoutDirection } from './layout/index.cjs';
12
- import { N as NodeCategory, a as NodeKindDefinition, C as ConfigField } from './types-BekE5JTG.cjs';
13
- export { D as DocumentConfigField, K as KeyValueConfigField, P as PortSpec, R as RenderBodyContext, d as RepeaterConfigField, e as RepeaterRowField } from './types-BekE5JTG.cjs';
12
+ import { N as NodeCategory, a as NodeKindDefinition, C as ConfigField } from './types-B_pxRqfw.cjs';
13
+ export { D as DocumentConfigField, K as KeyValueConfigField, P as PortSpec, R as RenderBodyContext, d as RepeaterConfigField, e as RepeaterRowField } from './types-B_pxRqfw.cjs';
14
14
  import { FlowRunFeedEntry } from './runtime/index.cjs';
15
15
  export { HistoryController, UseFlowHistoryReturn, UseFlowRunOptions, UseFlowRunReturn, UseFlowStateReturn, applyOutputsToNodes, applyStatusesToNodes, createHistory, useFlowHistory, useFlowRun, useFlowState } from './runtime/index.cjs';
16
16
  export { R as RunOptions, a as RunResult, r as runFlow } from './run-flow-AXzOR-Wq.cjs';
@@ -423,12 +423,7 @@ declare const DecisionNode: react.MemoExoticComponent<typeof DecisionNodeInner>;
423
423
  declare function OutputNodeInner(props: NodeProps<FlowNode>): react.JSX.Element;
424
424
  declare const OutputNode: react.MemoExoticComponent<typeof OutputNodeInner>;
425
425
 
426
- /**
427
- * NoteNode — annotation card with no ports. Useful for documenting graphs.
428
- * Body is plain text; hosts can wire onChange via the editor's onNodesChange
429
- * if they want it editable.
430
- */
431
- declare function NoteNodeInner({ data, selected }: NodeProps<FlowNode>): react.JSX.Element;
426
+ declare function NoteNodeInner(props: NodeProps<FlowNode>): react.JSX.Element;
432
427
  declare const NoteNode: react.MemoExoticComponent<typeof NoteNodeInner>;
433
428
 
434
429
  /**
package/dist/index.d.ts CHANGED
@@ -9,8 +9,8 @@ import { WorkflowSchema, WorkflowMetadata } from './schema/index.js';
9
9
  export { ImportIssue, ImportOptions, ImportResult, WORKFLOW_SCHEMA_URL, WORKFLOW_SCHEMA_VERSION, WorkflowSchemaEdge, WorkflowSchemaNode, exportWorkflow, importWorkflow, migrateSchema, workflowToBlob } from './schema/index.js';
10
10
  import { AutoLayoutOptions } from './layout/index.js';
11
11
  export { AutoLayoutDirection } from './layout/index.js';
12
- import { N as NodeCategory, a as NodeKindDefinition, C as ConfigField } from './types-DwRpXXNy.js';
13
- export { D as DocumentConfigField, K as KeyValueConfigField, P as PortSpec, R as RenderBodyContext, d as RepeaterConfigField, e as RepeaterRowField } from './types-DwRpXXNy.js';
12
+ import { N as NodeCategory, a as NodeKindDefinition, C as ConfigField } from './types-BGtR3k9J.js';
13
+ export { D as DocumentConfigField, K as KeyValueConfigField, P as PortSpec, R as RenderBodyContext, d as RepeaterConfigField, e as RepeaterRowField } from './types-BGtR3k9J.js';
14
14
  import { FlowRunFeedEntry } from './runtime/index.js';
15
15
  export { HistoryController, UseFlowHistoryReturn, UseFlowRunOptions, UseFlowRunReturn, UseFlowStateReturn, applyOutputsToNodes, applyStatusesToNodes, createHistory, useFlowHistory, useFlowRun, useFlowState } from './runtime/index.js';
16
16
  export { R as RunOptions, a as RunResult, r as runFlow } from './run-flow-9U-gaYVF.js';
@@ -423,12 +423,7 @@ declare const DecisionNode: react.MemoExoticComponent<typeof DecisionNodeInner>;
423
423
  declare function OutputNodeInner(props: NodeProps<FlowNode>): react.JSX.Element;
424
424
  declare const OutputNode: react.MemoExoticComponent<typeof OutputNodeInner>;
425
425
 
426
- /**
427
- * NoteNode — annotation card with no ports. Useful for documenting graphs.
428
- * Body is plain text; hosts can wire onChange via the editor's onNodesChange
429
- * if they want it editable.
430
- */
431
- declare function NoteNodeInner({ data, selected }: NodeProps<FlowNode>): react.JSX.Element;
426
+ declare function NoteNodeInner(props: NodeProps<FlowNode>): react.JSX.Element;
432
427
  declare const NoteNode: react.MemoExoticComponent<typeof NoteNodeInner>;
433
428
 
434
429
  /**
package/dist/index.js CHANGED
@@ -1,19 +1,19 @@
1
- import { useFlowState, useFlowRun, useFlowHistory, applyOutputsToNodes, applyStatusesToNodes } from './chunk-ZS6DVGB3.js';
2
- export { applyOutputsToNodes, applyStatusesToNodes, createHistory, useFlowHistory, useFlowRun, useFlowState } from './chunk-ZS6DVGB3.js';
3
- import { buildNodeTypes, registerBuiltinKinds, createConnectionValidator } from './chunk-QAA4CA22.js';
4
- export { ANY_PORT_TYPE, BUILTIN_KINDS, LaneNode, RegistryNode, buildNodeTypes, createConnectionValidator, defaultPortCompatibility, registerBuiltinKinds } from './chunk-QAA4CA22.js';
1
+ import { useFlowState, useFlowRun, useFlowHistory, applyOutputsToNodes, applyStatusesToNodes } from './chunk-OFW7GN3Y.js';
2
+ export { applyOutputsToNodes, applyStatusesToNodes, createHistory, useFlowHistory, useFlowRun, useFlowState } from './chunk-OFW7GN3Y.js';
3
+ import { buildNodeTypes, FlowEditorProvider, registerBuiltinKinds, NoteNode, createConnectionValidator } from './chunk-YOFCVO2W.js';
4
+ export { ANY_PORT_TYPE, BUILTIN_KINDS, LaneNode, NoteNode, RegistryNode, buildNodeTypes, createConnectionValidator, defaultPortCompatibility, registerBuiltinKinds, useFlowEditor, useFlowEditorOptional } from './chunk-YOFCVO2W.js';
5
5
  import { ReactFlowProvider, useReactFlow, addEdge, applyEdgeChanges, applyNodeChanges, Position, Handle, reconnectEdge, index, BackgroundVariant, Background, Controls, MiniMap, ViewportPortal } from './chunk-OWENS2H5.js';
6
6
  export { LEGACY_PAUSE_PREFIXES, PAUSE_PREFIX, decodePause, encodePause, isPause, pauseForHuman } from './chunk-UEOE6B52.js';
7
7
  import './chunk-USL4FMFU.js';
8
- export { runFlow } from './chunk-KDHLKBL2.js';
9
- import { workflowToBlob, importWorkflow, exportWorkflow } from './chunk-OHVSEHDC.js';
10
- export { WORKFLOW_SCHEMA_URL, WORKFLOW_SCHEMA_VERSION, exportWorkflow, importWorkflow, migrateSchema, workflowToBlob } from './chunk-OHVSEHDC.js';
8
+ export { runFlow } from './chunk-U2VJB7HR.js';
9
+ import { workflowToBlob, importWorkflow, exportWorkflow } from './chunk-N5ICD2WZ.js';
10
+ export { WORKFLOW_SCHEMA_URL, WORKFLOW_SCHEMA_VERSION, exportWorkflow, importWorkflow, migrateSchema, workflowToBlob } from './chunk-N5ICD2WZ.js';
11
11
  export { resolveNodePorts, resolvePortSpec } from './chunk-TITD5W4Y.js';
12
- import { onNodeKindsChanged, listNodeKinds, getNodeKind, defaultConfigFor, validateConfig, categoryAccent } from './chunk-YXRLIV7A.js';
13
- export { categoryAccent, defaultConfigFor, getNodeKind, listNodeKinds, onNodeKindsChanged, registerNodeKind, validateConfig } from './chunk-YXRLIV7A.js';
12
+ import { onNodeKindsChanged, listNodeKinds, getNodeKind, defaultConfigFor, validateConfig, categoryAccent } from './chunk-Q6IPK64P.js';
13
+ export { categoryAccent, defaultConfigFor, getNodeKind, listNodeKinds, onNodeKindsChanged, registerNodeKind, validateConfig } from './chunk-Q6IPK64P.js';
14
14
  import { getRichInputAdapter } from './chunk-F5RPRB7A.js';
15
15
  export { RichInputPreview, getRichInputAdapter, isRichInputEnabled, onRichInputAdapterChanged, registerRichInputAdapter } from './chunk-F5RPRB7A.js';
16
- import { memo, createContext, forwardRef, useState, useEffect, useMemo, useCallback, useRef, useImperativeHandle, useContext } from 'react';
16
+ import { memo, forwardRef, useState, useMemo, useEffect, useCallback, useRef, useImperativeHandle } from 'react';
17
17
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
18
18
 
19
19
  function NodeShellInner({
@@ -108,14 +108,6 @@ function OutputNodeInner(props) {
108
108
  return /* @__PURE__ */ jsx(NodeShell, { node: props, accent: "#a855f7", tag: "OUTPUT", icon: "\u25CF", showOutputs: false });
109
109
  }
110
110
  var OutputNode = memo(OutputNodeInner);
111
- function NoteNodeInner({ data, selected }) {
112
- const noteData = data;
113
- return /* @__PURE__ */ jsxs("div", { className: `ff-note ${selected ? "ff-note--selected" : ""}`, children: [
114
- noteData.label && /* @__PURE__ */ jsx("div", { className: "ff-note__title", children: noteData.label }),
115
- noteData.body && /* @__PURE__ */ jsx("p", { className: "ff-note__body", children: noteData.body })
116
- ] });
117
- }
118
- var NoteNode = memo(NoteNodeInner);
119
111
  function SubgraphNodeInner(props) {
120
112
  const data = props.data;
121
113
  const childCount = data.childIds?.length ?? 0;
@@ -468,7 +460,7 @@ function FlowCanvas({
468
460
  }
469
461
  );
470
462
  }
471
- var CATEGORY_ORDER = ["trigger", "logic", "data", "ai", "io", "human", "output", "layout", "custom"];
463
+ var CATEGORY_ORDER = ["trigger", "logic", "data", "ai", "io", "human", "output", "layout", "annotation", "custom"];
472
464
  var CATEGORY_LABELS = {
473
465
  trigger: "Triggers",
474
466
  logic: "Logic",
@@ -478,6 +470,7 @@ var CATEGORY_LABELS = {
478
470
  human: "Human",
479
471
  output: "Output",
480
472
  layout: "Layout",
473
+ annotation: "Notes",
481
474
  custom: "Custom"
482
475
  };
483
476
  function NodePalette({ categories, onPick, className, style }) {
@@ -1069,17 +1062,132 @@ function formatTime(at) {
1069
1062
  const d = new Date(at);
1070
1063
  return `${d.getMinutes().toString().padStart(2, "0")}:${d.getSeconds().toString().padStart(2, "0")}.${Math.floor(d.getMilliseconds() / 100)}`;
1071
1064
  }
1072
- var FlowEditorContext = createContext(null);
1073
- var FlowEditorProvider = FlowEditorContext.Provider;
1074
- function useFlowEditor() {
1075
- const api = useContext(FlowEditorContext);
1076
- if (api === null) {
1077
- throw new Error("useFlowEditor() must be called inside <FlowEditor>.");
1078
- }
1079
- return api;
1065
+ function humanInputFields(config) {
1066
+ const raw = Array.isArray(config?.fields) ? config.fields : [];
1067
+ const fields = raw.filter((f) => f && typeof f === "object" && typeof f.key === "string" && f.key).map((f) => ({
1068
+ key: f.key,
1069
+ label: typeof f.label === "string" && f.label ? f.label : f.key,
1070
+ type: ["text", "textarea", "number", "select", "switch"].includes(f.type) ? f.type : "text",
1071
+ required: !!f.required,
1072
+ placeholder: typeof f.placeholder === "string" ? f.placeholder : void 0,
1073
+ options: Array.isArray(f.options) ? f.options : void 0,
1074
+ default: f.default
1075
+ }));
1076
+ if (fields.length) return fields;
1077
+ const title = typeof config?.title === "string" && config.title ? config.title : "Your answer";
1078
+ return [{ key: "value", label: title, type: "textarea", required: true }];
1079
+ }
1080
+ function initialValues(fields) {
1081
+ const v = {};
1082
+ for (const f of fields) v[f.key] = f.type === "switch" ? !!f.default : f.default ?? "";
1083
+ return v;
1084
+ }
1085
+ function HumanPrompt({ request, onCancel }) {
1086
+ const firstRef = useRef(null);
1087
+ useEffect(() => {
1088
+ firstRef.current?.focus();
1089
+ const onKey = (e) => {
1090
+ if (e.key === "Escape") onCancel();
1091
+ };
1092
+ window.addEventListener("keydown", onKey);
1093
+ return () => window.removeEventListener("keydown", onKey);
1094
+ }, [onCancel]);
1095
+ return /* @__PURE__ */ jsx("div", { className: "ff-prompt-overlay", role: "dialog", "aria-modal": "true", "aria-label": request.title, children: /* @__PURE__ */ jsxs("div", { className: "ff-prompt", onClick: (e) => e.stopPropagation(), children: [
1096
+ /* @__PURE__ */ jsx("div", { className: "ff-prompt__title", children: request.title }),
1097
+ request.kind === "approval" ? /* @__PURE__ */ jsx(ApprovalBody, { request, onCancel }) : /* @__PURE__ */ jsx(InputBody, { request, onCancel, firstRef })
1098
+ ] }) });
1099
+ }
1100
+ function ApprovalBody({ request, onCancel }) {
1101
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
1102
+ request.description && /* @__PURE__ */ jsx("p", { className: "ff-prompt__desc", children: request.description }),
1103
+ /* @__PURE__ */ jsxs("div", { className: "ff-prompt__actions", children: [
1104
+ /* @__PURE__ */ jsx("button", { type: "button", className: "ff-prompt__btn ff-prompt__btn--ghost", onClick: onCancel, children: "Cancel" }),
1105
+ /* @__PURE__ */ jsx("button", { type: "button", className: "ff-prompt__btn ff-prompt__btn--danger", onClick: () => request.resolve(false), children: "Deny" }),
1106
+ /* @__PURE__ */ jsx("button", { type: "button", className: "ff-prompt__btn ff-prompt__btn--primary", onClick: () => request.resolve(true), children: "Approve" })
1107
+ ] })
1108
+ ] });
1109
+ }
1110
+ function InputBody({
1111
+ request,
1112
+ onCancel,
1113
+ firstRef
1114
+ }) {
1115
+ const [values, setValues] = useState(() => initialValues(request.fields));
1116
+ const set = (k, v) => setValues((prev) => ({ ...prev, [k]: v }));
1117
+ const missing = request.fields.filter((f) => f.required && (values[f.key] === void 0 || values[f.key] === ""));
1118
+ const submit = () => {
1119
+ if (missing.length === 0) request.resolve(values);
1120
+ };
1121
+ return /* @__PURE__ */ jsxs(
1122
+ "form",
1123
+ {
1124
+ onSubmit: (e) => {
1125
+ e.preventDefault();
1126
+ submit();
1127
+ },
1128
+ onKeyDown: (e) => {
1129
+ if (e.key === "Enter" && (e.metaKey || e.ctrlKey)) {
1130
+ e.preventDefault();
1131
+ submit();
1132
+ }
1133
+ },
1134
+ children: [
1135
+ /* @__PURE__ */ jsx("div", { className: "ff-prompt__fields", children: request.fields.map((f, i) => /* @__PURE__ */ jsxs("label", { className: "ff-prompt__field", children: [
1136
+ /* @__PURE__ */ jsxs("span", { className: "ff-prompt__label", children: [
1137
+ f.label ?? f.key,
1138
+ f.required && /* @__PURE__ */ jsx("span", { className: "ff-prompt__req", children: " *" })
1139
+ ] }),
1140
+ renderControl(f, values[f.key], (v) => set(f.key, v), i === 0 ? firstRef : void 0)
1141
+ ] }, f.key)) }),
1142
+ /* @__PURE__ */ jsxs("div", { className: "ff-prompt__actions", children: [
1143
+ /* @__PURE__ */ jsx("button", { type: "button", className: "ff-prompt__btn ff-prompt__btn--ghost", onClick: onCancel, children: "Cancel" }),
1144
+ /* @__PURE__ */ jsx("button", { type: "submit", className: "ff-prompt__btn ff-prompt__btn--primary", disabled: missing.length > 0, children: request.submitLabel || "Continue" })
1145
+ ] })
1146
+ ]
1147
+ }
1148
+ );
1080
1149
  }
1081
- function useFlowEditorOptional() {
1082
- return useContext(FlowEditorContext);
1150
+ function renderControl(f, value, onChange, ref) {
1151
+ const common = { className: "ff-prompt__input", placeholder: f.placeholder };
1152
+ if (f.type === "textarea") {
1153
+ return /* @__PURE__ */ jsx(
1154
+ "textarea",
1155
+ {
1156
+ ...common,
1157
+ ref,
1158
+ rows: 3,
1159
+ value: String(value ?? ""),
1160
+ onChange: (e) => onChange(e.target.value)
1161
+ }
1162
+ );
1163
+ }
1164
+ if (f.type === "switch") {
1165
+ return /* @__PURE__ */ jsx(
1166
+ "input",
1167
+ {
1168
+ type: "checkbox",
1169
+ className: "ff-prompt__switch",
1170
+ checked: !!value,
1171
+ onChange: (e) => onChange(e.target.checked)
1172
+ }
1173
+ );
1174
+ }
1175
+ if (f.type === "select" && f.options && f.options.length) {
1176
+ return /* @__PURE__ */ jsxs("select", { className: "ff-prompt__input", value: String(value ?? ""), onChange: (e) => onChange(e.target.value), children: [
1177
+ /* @__PURE__ */ jsx("option", { value: "", disabled: true, children: "Choose\u2026" }),
1178
+ f.options.map((o) => /* @__PURE__ */ jsx("option", { value: o.value, children: o.label }, o.value))
1179
+ ] });
1180
+ }
1181
+ return /* @__PURE__ */ jsx(
1182
+ "input",
1183
+ {
1184
+ ...common,
1185
+ ref,
1186
+ type: f.type === "number" ? "number" : "text",
1187
+ value: String(value ?? ""),
1188
+ onChange: (e) => onChange(f.type === "number" ? e.target.value === "" ? "" : Number(e.target.value) : e.target.value)
1189
+ }
1190
+ );
1083
1191
  }
1084
1192
  var FlowEditor = forwardRef(function FlowEditor2(props, ref) {
1085
1193
  return /* @__PURE__ */ jsx(ReactFlowProvider, { children: /* @__PURE__ */ jsx(
@@ -1114,6 +1222,41 @@ function FlowEditorInner({
1114
1222
  const internal = useFlowState(initial);
1115
1223
  const runner = useFlowRun();
1116
1224
  const rf = useReactFlow();
1225
+ const [prompt, setPrompt] = useState(null);
1226
+ const humanExecutors = useMemo(
1227
+ () => ({
1228
+ user_input: ({ node }) => new Promise((resolve) => {
1229
+ const cfg = node.data?.config ?? {};
1230
+ setPrompt({
1231
+ kind: "input",
1232
+ title: typeof cfg.title === "string" && cfg.title || "Your input",
1233
+ submitLabel: typeof cfg.submitLabel === "string" ? cfg.submitLabel : void 0,
1234
+ fields: humanInputFields(cfg),
1235
+ resolve: (values) => {
1236
+ setPrompt(null);
1237
+ resolve(values);
1238
+ }
1239
+ });
1240
+ }),
1241
+ human_approval: ({ node }) => new Promise((resolve) => {
1242
+ const cfg = node.data?.config ?? {};
1243
+ setPrompt({
1244
+ kind: "approval",
1245
+ title: typeof cfg.title === "string" && cfg.title || "Approve action",
1246
+ description: typeof cfg.description === "string" ? cfg.description : void 0,
1247
+ resolve: (approved) => {
1248
+ setPrompt(null);
1249
+ resolve({ branch: approved ? "approved" : "denied" });
1250
+ }
1251
+ });
1252
+ })
1253
+ }),
1254
+ []
1255
+ );
1256
+ const runExecutors = useMemo(() => ({ ...humanExecutors, ...executors }), [humanExecutors, executors]);
1257
+ useEffect(() => {
1258
+ if (!runner.running) setPrompt(null);
1259
+ }, [runner.running]);
1117
1260
  const controlled = value !== void 0;
1118
1261
  const baseFlow = controlled ? makeControlledFlowAdapter(value, onChange) : internal;
1119
1262
  const hist = useFlowHistory(baseFlow);
@@ -1423,7 +1566,7 @@ function FlowEditorInner({
1423
1566
  ({ autoLayout }) => flow.setGraph({ nodes: autoLayout({ nodes: flow.nodes, edges: flow.edges }, { scope: laneId }), edges: flow.edges })
1424
1567
  );
1425
1568
  },
1426
- run: () => runner.run({ nodes: flow.nodes, edges: flow.edges }, executors),
1569
+ run: () => runner.run({ nodes: flow.nodes, edges: flow.edges }, runExecutors),
1427
1570
  cancel: runner.cancel,
1428
1571
  reset: runner.reset,
1429
1572
  toWorkflow,
@@ -1435,7 +1578,7 @@ function FlowEditorInner({
1435
1578
  canUndo: hist.canUndo,
1436
1579
  canRedo: hist.canRedo
1437
1580
  };
1438
- }, [flow, selectedId, selected, selectedEdgeId, selectedEdge, selectedIds, selectedNodes, runner, executors, metadata, addNode, deleteNodes, deleteEdges, duplicateSelected, alignSelected, distributeSelected, copySelection, pasteClipboard, addLane, hist, rf]);
1581
+ }, [flow, selectedId, selected, selectedEdgeId, selectedEdge, selectedIds, selectedNodes, runner, runExecutors, metadata, addNode, deleteNodes, deleteEdges, duplicateSelected, alignSelected, distributeSelected, copySelection, pasteClipboard, addLane, hist, rf]);
1439
1582
  useImperativeHandle(apiRef, () => api, [api]);
1440
1583
  const dropHandlers = paletteDropHandlers((kindName, evt) => {
1441
1584
  const point = rf.screenToFlowPosition({ x: evt.clientX, y: evt.clientY });
@@ -1609,7 +1752,11 @@ function FlowEditorInner({
1609
1752
  onCancel: () => setLabelEdit(null)
1610
1753
  }
1611
1754
  ),
1612
- showFeed && (slots.feed ? slots.feed(api) : /* @__PURE__ */ jsx(FlowRunFeed, { entries: runner.feed, className: "ff-editor__feed" }))
1755
+ showFeed && (slots.feed ? slots.feed(api) : /* @__PURE__ */ jsx(FlowRunFeed, { entries: runner.feed, className: "ff-editor__feed" })),
1756
+ prompt && /* @__PURE__ */ jsx(HumanPrompt, { request: prompt, onCancel: () => {
1757
+ setPrompt(null);
1758
+ runner.cancel();
1759
+ } })
1613
1760
  ] }),
1614
1761
  showPanel && (slots.panel ? slots.panel(api) : /* @__PURE__ */ jsxs("div", { className: "ff-editor__panel-wrap", children: [
1615
1762
  /* @__PURE__ */ jsx(
@@ -1769,6 +1916,6 @@ function NodePort({ side, type, id, style, title, className }) {
1769
1916
  // src/index.ts
1770
1917
  registerBuiltinKinds();
1771
1918
 
1772
- export { ActionNode, ConfigFieldRenderer, DecisionNode, FlowCanvas, FlowEditor, FlowRunControls, FlowRunFeed, NodeConfigPanel, NodePalette, NodePort, NodeShell, NoteNode, OutputNode, SubgraphNode, TriggerNode, alignNodes, cloneSubgraph, defaultNodeTypes, defineNode, distributeNodes, paletteDropHandlers, reconnectEdge2 as reconnectEdge, useFlowEditor, useFlowEditorOptional };
1919
+ export { ActionNode, ConfigFieldRenderer, DecisionNode, FlowCanvas, FlowEditor, FlowRunControls, FlowRunFeed, NodeConfigPanel, NodePalette, NodePort, NodeShell, OutputNode, SubgraphNode, TriggerNode, alignNodes, cloneSubgraph, defaultNodeTypes, defineNode, distributeNodes, paletteDropHandlers, reconnectEdge2 as reconnectEdge };
1773
1920
  //# sourceMappingURL=index.js.map
1774
1921
  //# sourceMappingURL=index.js.map