@particle-academy/agent-integrations 0.2.4

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 (49) hide show
  1. package/README.md +131 -0
  2. package/dist/bridges/flow.d.cts +72 -0
  3. package/dist/bridges/flow.d.ts +72 -0
  4. package/dist/bridges/whiteboard.d.cts +40 -0
  5. package/dist/bridges/whiteboard.d.ts +40 -0
  6. package/dist/bridges-flow.cjs +330 -0
  7. package/dist/bridges-flow.cjs.map +1 -0
  8. package/dist/bridges-flow.js +4 -0
  9. package/dist/bridges-flow.js.map +1 -0
  10. package/dist/bridges-whiteboard.cjs +409 -0
  11. package/dist/bridges-whiteboard.cjs.map +1 -0
  12. package/dist/bridges-whiteboard.js +4 -0
  13. package/dist/bridges-whiteboard.js.map +1 -0
  14. package/dist/chunk-2VOQJKSU.js +320 -0
  15. package/dist/chunk-2VOQJKSU.js.map +1 -0
  16. package/dist/chunk-5ZUHNNLR.js +398 -0
  17. package/dist/chunk-5ZUHNNLR.js.map +1 -0
  18. package/dist/chunk-6LTKCNLF.js +68 -0
  19. package/dist/chunk-6LTKCNLF.js.map +1 -0
  20. package/dist/chunk-FLEOQUKF.js +157 -0
  21. package/dist/chunk-FLEOQUKF.js.map +1 -0
  22. package/dist/chunk-QGCF7YKW.js +130 -0
  23. package/dist/chunk-QGCF7YKW.js.map +1 -0
  24. package/dist/index.cjs +1632 -0
  25. package/dist/index.cjs.map +1 -0
  26. package/dist/index.d.cts +155 -0
  27. package/dist/index.d.ts +155 -0
  28. package/dist/index.js +567 -0
  29. package/dist/index.js.map +1 -0
  30. package/dist/mcp/index.d.cts +73 -0
  31. package/dist/mcp/index.d.ts +73 -0
  32. package/dist/mcp.cjs +210 -0
  33. package/dist/mcp.cjs.map +1 -0
  34. package/dist/mcp.js +4 -0
  35. package/dist/mcp.js.map +1 -0
  36. package/dist/server-Bv985us3.d.cts +173 -0
  37. package/dist/server-Bv985us3.d.ts +173 -0
  38. package/dist/sharing/index.d.cts +89 -0
  39. package/dist/sharing/index.d.ts +89 -0
  40. package/dist/sharing.cjs +166 -0
  41. package/dist/sharing.cjs.map +1 -0
  42. package/dist/sharing.js +3 -0
  43. package/dist/sharing.js.map +1 -0
  44. package/dist/styles.css +331 -0
  45. package/dist/styles.css.map +1 -0
  46. package/dist/types-CRPA_D0z.d.ts +18 -0
  47. package/dist/types-DR5AS6Rd.d.cts +18 -0
  48. package/docs/relay-protocol.md +57 -0
  49. package/package.json +61 -0
@@ -0,0 +1,320 @@
1
+ import { errorResult, textResult } from './chunk-QGCF7YKW.js';
2
+
3
+ var num = (v, fallback) => typeof v === "number" && Number.isFinite(v) ? v : 0;
4
+ var str = (v, fallback = "") => typeof v === "string" ? v : fallback;
5
+ var newId = (prefix) => `${prefix}_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 7)}`;
6
+ function registerFlowBridge(server, options) {
7
+ const { adapter } = options;
8
+ ({ ...options.agent ?? {} });
9
+ const disposers = [];
10
+ const reg = (name, description, properties, required, handler) => {
11
+ disposers.push(
12
+ server.registerTool(
13
+ {
14
+ name,
15
+ description,
16
+ inputSchema: { type: "object", properties, required, additionalProperties: false }
17
+ },
18
+ async (args) => {
19
+ try {
20
+ return await handler(args);
21
+ } catch (e) {
22
+ return errorResult(e instanceof Error ? e.message : String(e));
23
+ }
24
+ }
25
+ )
26
+ );
27
+ };
28
+ reg("flow_get_state", "Get the full graph: nodes + edges.", {}, [], () => {
29
+ const state = { nodes: adapter.getNodes(), edges: adapter.getEdges() };
30
+ return textResult(JSON.stringify(state, null, 2), state);
31
+ });
32
+ reg("flow_list_nodes", "Summarise every node: id, kind, label, position, status.", {}, [], () => {
33
+ const items = adapter.getNodes().map((n) => ({
34
+ id: n.id,
35
+ kind: n.type,
36
+ label: n.data?.label,
37
+ x: Math.round(n.position.x),
38
+ y: Math.round(n.position.y),
39
+ status: n.data?.status ?? "idle"
40
+ }));
41
+ const text = items.map((i) => `${i.kind} ${i.id}: "${i.label}" @(${i.x},${i.y}) [${i.status}]`).join("\n") || "(empty graph)";
42
+ return textResult(text, items);
43
+ });
44
+ reg(
45
+ "flow_get_node",
46
+ "Get a single node's full record by id.",
47
+ { id: { type: "string" } },
48
+ ["id"],
49
+ (args) => {
50
+ const id = str(args.id);
51
+ const node = adapter.getNodes().find((n) => n.id === id);
52
+ if (!node) return errorResult(`No node with id ${id}`);
53
+ return textResult(JSON.stringify(node, null, 2), node);
54
+ }
55
+ );
56
+ reg(
57
+ "flow_list_node_kinds",
58
+ "List every node kind registered in fancy-flow's registry. Use this to discover what's authorable before adding nodes.",
59
+ { category: { type: "string", description: "Optional category filter: trigger | logic | data | ai | io | human | output | custom." } },
60
+ [],
61
+ async () => {
62
+ try {
63
+ const { listNodeKinds } = await import('@particle-academy/fancy-flow');
64
+ const cat = adapter ? void 0 : void 0;
65
+ const all = (cat ? listNodeKinds(cat) : listNodeKinds()).map((k) => ({
66
+ name: k.name,
67
+ category: k.category,
68
+ label: k.label,
69
+ description: k.description,
70
+ icon: k.icon,
71
+ accent: k.accent,
72
+ inputs: k.inputs ?? [],
73
+ outputs: k.outputs ?? [],
74
+ configFields: (k.configSchema ?? []).map((f) => ({ key: f.key, type: f.type, label: f.label, required: !!f.required }))
75
+ }));
76
+ const text = all.map((k) => `${k.category}/${k.name}: ${k.label}${k.description ? " \u2014 " + k.description : ""}`).join("\n");
77
+ return textResult(text || "(no kinds registered)", all);
78
+ } catch (e) {
79
+ return errorResult(`fancy-flow registry not available: ${e instanceof Error ? e.message : String(e)}`);
80
+ }
81
+ }
82
+ );
83
+ reg(
84
+ "flow_get_node_schema",
85
+ "Get the full configSchema + ports for a node kind. Use to know exactly what fields a kind accepts before calling flow_add_node.",
86
+ { name: { type: "string" } },
87
+ ["name"],
88
+ async (args) => {
89
+ try {
90
+ const { getNodeKind } = await import('@particle-academy/fancy-flow');
91
+ const k = getNodeKind(str(args.name));
92
+ if (!k) return errorResult(`No kind registered: ${args.name}`);
93
+ const summary = {
94
+ name: k.name,
95
+ category: k.category,
96
+ label: k.label,
97
+ description: k.description,
98
+ inputs: k.inputs ?? [],
99
+ outputs: k.outputs ?? [],
100
+ configSchema: k.configSchema ?? [],
101
+ defaultConfig: k.defaultConfig ?? null
102
+ };
103
+ return textResult(JSON.stringify(summary, null, 2), summary);
104
+ } catch (e) {
105
+ return errorResult(`fancy-flow registry not available: ${e instanceof Error ? e.message : String(e)}`);
106
+ }
107
+ }
108
+ );
109
+ reg("flow_list_edges", "Summarise every edge.", {}, [], () => {
110
+ const items = adapter.getEdges().map((e) => ({
111
+ id: e.id,
112
+ from: `${e.source}${e.sourceHandle ? `:${e.sourceHandle}` : ""}`,
113
+ to: `${e.target}${e.targetHandle ? `:${e.targetHandle}` : ""}`
114
+ }));
115
+ return textResult(items.map((i) => `${i.id}: ${i.from} \u2192 ${i.to}`).join("\n") || "(no edges)", items);
116
+ });
117
+ reg(
118
+ "flow_add_node",
119
+ "Add a node of any kind registered in fancy-flow's registry. Call flow_list_node_kinds first to discover what's available.",
120
+ {
121
+ kind: { type: "string", description: "Registry kind name (e.g. memory_store, llm_call, branch)." },
122
+ label: { type: "string" },
123
+ x: { type: "number" },
124
+ y: { type: "number" },
125
+ description: { type: "string" },
126
+ config: { type: "object", description: "Config fields per the kind's configSchema." },
127
+ body: { type: "string", description: "Note kinds only \u2014 body text." }
128
+ },
129
+ ["kind", "label", "x", "y"],
130
+ async (args) => {
131
+ const kindName = str(args.kind);
132
+ let kindDef = null;
133
+ try {
134
+ const { getNodeKind, defaultConfigFor } = await import('@particle-academy/fancy-flow');
135
+ kindDef = getNodeKind(kindName);
136
+ var defaults = kindDef ? defaultConfigFor(kindDef) : {};
137
+ } catch {
138
+ var defaults = {};
139
+ }
140
+ const isLegacy = ["trigger", "action", "decision", "output", "note", "subgraph"].includes(kindName);
141
+ if (!kindDef && !isLegacy) {
142
+ return errorResult(`Unknown kind: ${kindName} \u2014 call flow_list_node_kinds for the registry.`);
143
+ }
144
+ const id = newId("n");
145
+ const config = { ...defaults, ...args.config && typeof args.config === "object" ? args.config : {} };
146
+ const node = {
147
+ id,
148
+ type: kindName,
149
+ position: { x: num(args.x), y: num(args.y) },
150
+ data: {
151
+ kind: kindName,
152
+ label: str(args.label),
153
+ ...args.description ? { description: str(args.description) } : {},
154
+ config,
155
+ ...kindName === "note" && args.body ? { body: str(args.body) } : {}
156
+ }
157
+ };
158
+ adapter.setNodes((all) => [...all, node]);
159
+ return textResult(`Added ${kindName} ${id} ("${str(args.label)}")`, node);
160
+ }
161
+ );
162
+ reg(
163
+ "flow_update_node",
164
+ "Update fields on a node. Only provided fields change.",
165
+ {
166
+ id: { type: "string" },
167
+ label: { type: "string" },
168
+ x: { type: "number" },
169
+ y: { type: "number" },
170
+ description: { type: "string" },
171
+ config: { type: "object" }
172
+ },
173
+ ["id"],
174
+ (args) => {
175
+ const id = str(args.id);
176
+ let updated = null;
177
+ adapter.setNodes(
178
+ (all) => all.map((n) => {
179
+ if (n.id !== id) return n;
180
+ updated = {
181
+ ...n,
182
+ position: {
183
+ x: args.x !== void 0 ? num(args.x) : n.position.x,
184
+ y: args.y !== void 0 ? num(args.y) : n.position.y
185
+ },
186
+ data: {
187
+ ...n.data,
188
+ ...args.label !== void 0 ? { label: str(args.label) } : {},
189
+ ...args.description !== void 0 ? { description: str(args.description) } : {},
190
+ ...args.config && typeof args.config === "object" ? { config: { ...n.data.config ?? {}, ...args.config } } : {}
191
+ }
192
+ };
193
+ return updated;
194
+ })
195
+ );
196
+ if (!updated) return errorResult(`No node with id ${id}`);
197
+ return textResult(`Updated node ${id}`, updated);
198
+ }
199
+ );
200
+ reg(
201
+ "flow_delete_node",
202
+ "Remove a node by id (also removes any connected edges).",
203
+ { id: { type: "string" } },
204
+ ["id"],
205
+ (args) => {
206
+ const id = str(args.id);
207
+ if (!adapter.getNodes().some((n) => n.id === id)) {
208
+ return errorResult(`No node with id ${id}`);
209
+ }
210
+ adapter.setNodes((all) => all.filter((n) => n.id !== id));
211
+ adapter.setEdges((all) => all.filter((e) => e.source !== id && e.target !== id));
212
+ return textResult(`Deleted node ${id}`);
213
+ }
214
+ );
215
+ reg(
216
+ "flow_connect",
217
+ "Create an edge between two nodes (optionally specifying handle ids).",
218
+ {
219
+ source: { type: "string" },
220
+ target: { type: "string" },
221
+ sourceHandle: { type: "string" },
222
+ targetHandle: { type: "string" },
223
+ label: { type: "string" }
224
+ },
225
+ ["source", "target"],
226
+ (args) => {
227
+ const source = str(args.source);
228
+ const target = str(args.target);
229
+ const all = adapter.getNodes();
230
+ if (!all.find((n) => n.id === source)) return errorResult(`No source node ${source}`);
231
+ if (!all.find((n) => n.id === target)) return errorResult(`No target node ${target}`);
232
+ const edge = {
233
+ id: newId("e"),
234
+ source,
235
+ target,
236
+ ...args.sourceHandle ? { sourceHandle: str(args.sourceHandle) } : {},
237
+ ...args.targetHandle ? { targetHandle: str(args.targetHandle) } : {},
238
+ ...args.label ? { label: str(args.label) } : {}
239
+ };
240
+ adapter.setEdges((existing) => [...existing, edge]);
241
+ return textResult(`Connected ${source}${edge.sourceHandle ? `:${edge.sourceHandle}` : ""} \u2192 ${target}${edge.targetHandle ? `:${edge.targetHandle}` : ""}`, edge);
242
+ }
243
+ );
244
+ reg(
245
+ "flow_disconnect",
246
+ "Remove an edge by id.",
247
+ { id: { type: "string" } },
248
+ ["id"],
249
+ (args) => {
250
+ const id = str(args.id);
251
+ if (!adapter.getEdges().some((e) => e.id === id)) {
252
+ return errorResult(`No edge ${id}`);
253
+ }
254
+ adapter.setEdges((all) => all.filter((e) => e.id !== id));
255
+ return textResult(`Disconnected ${id}`);
256
+ }
257
+ );
258
+ reg(
259
+ "flow_set_node_status",
260
+ "Manually set a node's status badge (idle | queued | running | done | error) and optional text. Useful for narration outside a run.",
261
+ {
262
+ id: { type: "string" },
263
+ status: { type: "string", enum: ["idle", "queued", "running", "done", "error"] },
264
+ text: { type: "string" }
265
+ },
266
+ ["id", "status"],
267
+ (args) => {
268
+ const id = str(args.id);
269
+ const status = str(args.status);
270
+ const text = args.text !== void 0 ? str(args.text) : void 0;
271
+ if (adapter.setNodeStatus) {
272
+ adapter.setNodeStatus(id, status, text);
273
+ } else {
274
+ let found = false;
275
+ adapter.setNodes(
276
+ (all) => all.map((n) => {
277
+ if (n.id !== id) return n;
278
+ found = true;
279
+ return { ...n, data: { ...n.data, status, statusText: text } };
280
+ })
281
+ );
282
+ if (!found) return errorResult(`No node with id ${id}`);
283
+ }
284
+ return textResult(`${id} \u2192 ${status}${text ? ` (${text})` : ""}`);
285
+ }
286
+ );
287
+ reg(
288
+ "flow_run",
289
+ "Trigger a run of the current graph. Returns the topological result. Requires the host to have wired `run` into the adapter.",
290
+ {},
291
+ [],
292
+ async () => {
293
+ if (!adapter.run) return errorResult("Host did not provide a run handler.");
294
+ const result = await adapter.run();
295
+ return textResult(result.ok ? "Run complete" : `Run failed: ${result.error ?? "unknown"}`, result);
296
+ }
297
+ );
298
+ reg(
299
+ "flow_cancel",
300
+ "Cancel an in-flight run.",
301
+ {},
302
+ [],
303
+ () => {
304
+ if (!adapter.cancel) return errorResult("Host did not provide a cancel handler.");
305
+ adapter.cancel();
306
+ return textResult("Run cancelled");
307
+ }
308
+ );
309
+ return {
310
+ id: "flow",
311
+ title: "Flow",
312
+ dispose: () => {
313
+ for (const d of disposers) d();
314
+ }
315
+ };
316
+ }
317
+
318
+ export { registerFlowBridge };
319
+ //# sourceMappingURL=chunk-2VOQJKSU.js.map
320
+ //# sourceMappingURL=chunk-2VOQJKSU.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/bridges/flow.ts"],"names":[],"mappings":"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","file":"chunk-2VOQJKSU.js","sourcesContent":["// Loose types so this bridge builds standalone without a hard dep on\n// fancy-flow. Hosts that have fancy-flow installed get full editor\n// integration via the runtime dynamic imports below.\ntype FlowNode = {\n id: string;\n type?: string;\n position: { x: number; y: number };\n data: { kind?: string; label?: string; description?: string; status?: string; statusText?: string; config?: Record<string, unknown>; [k: string]: unknown };\n};\ntype FlowEdge = {\n id: string;\n source: string;\n target: string;\n sourceHandle?: string;\n targetHandle?: string;\n label?: string;\n [k: string]: unknown;\n};\ntype FlowGraph = { nodes: FlowNode[]; edges: FlowEdge[] };\ntype NodeRunStatus = \"idle\" | \"queued\" | \"running\" | \"done\" | \"error\";\ntype ExecutorRegistry = Record<string, unknown>;\ntype RunResult = { ok: boolean; outputs: Record<string, unknown>; error?: string };\n\nimport { textResult, errorResult } from \"../mcp/server\";\nimport type { MicroMcpServer } from \"../mcp/server\";\nimport type { JsonObject } from \"../mcp/types\";\nimport type { Bridge } from \"./types\";\n\n/**\n * Adapter the host provides — same shape as the editor's local state plus\n * an optional `run`/`cancel` pair so agents can trigger executions.\n */\nexport type FlowBridgeAdapter = {\n getNodes: () => FlowNode[];\n setNodes: (next: FlowNode[] | ((prev: FlowNode[]) => FlowNode[])) => void;\n getEdges: () => FlowEdge[];\n setEdges: (next: FlowEdge[] | ((prev: FlowEdge[]) => FlowEdge[])) => void;\n /** Optional: invoke runFlow with the host's executor registry. */\n run?: (executors?: ExecutorRegistry) => Promise<RunResult>;\n /** Optional: cancel the in-flight run. */\n cancel?: () => void;\n /** Optional: set per-node status text without going through the runner\n * (useful for agents narrating). */\n setNodeStatus?: (id: string, status: NodeRunStatus, text?: string) => void;\n};\n\nexport type FlowBridgeOptions = {\n adapter: FlowBridgeAdapter;\n /** Identity tagged onto agent-authored nodes. */\n agent?: { id: string; name?: string; color?: string };\n};\n\nconst DEFAULT_AGENT = { id: \"agent\", name: \"Agent\", color: \"#a855f7\" };\nconst KINDS: string[] = [\"trigger\", \"action\", \"decision\", \"output\", \"note\", \"subgraph\"];\n\nconst num = (v: unknown, fallback?: number): number =>\n typeof v === \"number\" && Number.isFinite(v) ? v : fallback ?? 0;\nconst str = (v: unknown, fallback = \"\"): string => (typeof v === \"string\" ? v : fallback);\n\nconst newId = (prefix: string) =>\n `${prefix}_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 7)}`;\n\n/**\n * registerFlowBridge — wires an MCP tool set against a fancy-flow editor's\n * controlled state. Mirrors the whiteboard bridge in shape: read tools,\n * mutation tools (add / update / delete nodes + edges), and optional\n * run/cancel if the host provides those callbacks.\n */\nexport function registerFlowBridge(\n server: MicroMcpServer,\n options: FlowBridgeOptions,\n): Bridge {\n const { adapter } = options;\n const agent = { ...DEFAULT_AGENT, ...(options.agent ?? {}) };\n const disposers: Array<() => void> = [];\n\n const reg = (\n name: string,\n description: string,\n properties: Record<string, unknown>,\n required: string[],\n handler: (args: JsonObject) => Promise<any> | any,\n ) => {\n disposers.push(\n server.registerTool(\n {\n name,\n description,\n inputSchema: { type: \"object\", properties: properties as any, required, additionalProperties: false },\n },\n async (args) => {\n try {\n return await handler(args);\n } catch (e) {\n return errorResult(e instanceof Error ? e.message : String(e));\n }\n },\n ),\n );\n };\n\n // ───────────── Read tools ─────────────\n\n reg(\"flow_get_state\", \"Get the full graph: nodes + edges.\", {}, [], () => {\n const state: FlowGraph = { nodes: adapter.getNodes(), edges: adapter.getEdges() };\n return textResult(JSON.stringify(state, null, 2), state);\n });\n\n reg(\"flow_list_nodes\", \"Summarise every node: id, kind, label, position, status.\", {}, [], () => {\n const items = adapter.getNodes().map((n) => ({\n id: n.id,\n kind: n.type,\n label: n.data?.label,\n x: Math.round(n.position.x),\n y: Math.round(n.position.y),\n status: n.data?.status ?? \"idle\",\n }));\n const text = items.map((i) => `${i.kind} ${i.id}: \"${i.label}\" @(${i.x},${i.y}) [${i.status}]`).join(\"\\n\") || \"(empty graph)\";\n return textResult(text, items);\n });\n\n reg(\n \"flow_get_node\",\n \"Get a single node's full record by id.\",\n { id: { type: \"string\" } },\n [\"id\"],\n (args) => {\n const id = str(args.id);\n const node = adapter.getNodes().find((n) => n.id === id);\n if (!node) return errorResult(`No node with id ${id}`);\n return textResult(JSON.stringify(node, null, 2), node);\n },\n );\n\n reg(\n \"flow_list_node_kinds\",\n \"List every node kind registered in fancy-flow's registry. Use this to discover what's authorable before adding nodes.\",\n { category: { type: \"string\", description: \"Optional category filter: trigger | logic | data | ai | io | human | output | custom.\" } },\n [],\n async () => {\n // Dynamic import keeps the bridge usable even when fancy-flow isn't loaded.\n try {\n // @ts-ignore — optional peer dep, may not be installed\n const { listNodeKinds } = await import(\"@particle-academy/fancy-flow\" as any);\n const cat = adapter ? undefined : undefined; // placeholder\n const all = (cat ? listNodeKinds(cat) : listNodeKinds()).map((k: any) => ({\n name: k.name,\n category: k.category,\n label: k.label,\n description: k.description,\n icon: k.icon,\n accent: k.accent,\n inputs: k.inputs ?? [],\n outputs: k.outputs ?? [],\n configFields: (k.configSchema ?? []).map((f: any) => ({ key: f.key, type: f.type, label: f.label, required: !!f.required })),\n }));\n const text = all.map((k: any) => `${k.category}/${k.name}: ${k.label}${k.description ? \" — \" + k.description : \"\"}`).join(\"\\n\");\n return textResult(text || \"(no kinds registered)\", all);\n } catch (e) {\n return errorResult(`fancy-flow registry not available: ${e instanceof Error ? e.message : String(e)}`);\n }\n },\n );\n\n reg(\n \"flow_get_node_schema\",\n \"Get the full configSchema + ports for a node kind. Use to know exactly what fields a kind accepts before calling flow_add_node.\",\n { name: { type: \"string\" } },\n [\"name\"],\n async (args) => {\n try {\n // @ts-ignore — optional peer dep\n const { getNodeKind } = await import(\"@particle-academy/fancy-flow\" as any);\n const k: any = getNodeKind(str(args.name));\n if (!k) return errorResult(`No kind registered: ${args.name}`);\n const summary = {\n name: k.name,\n category: k.category,\n label: k.label,\n description: k.description,\n inputs: k.inputs ?? [],\n outputs: k.outputs ?? [],\n configSchema: k.configSchema ?? [],\n defaultConfig: k.defaultConfig ?? null,\n };\n return textResult(JSON.stringify(summary, null, 2), summary);\n } catch (e) {\n return errorResult(`fancy-flow registry not available: ${e instanceof Error ? e.message : String(e)}`);\n }\n },\n );\n\n reg(\"flow_list_edges\", \"Summarise every edge.\", {}, [], () => {\n const items = adapter.getEdges().map((e) => ({\n id: e.id,\n from: `${e.source}${e.sourceHandle ? `:${e.sourceHandle}` : \"\"}`,\n to: `${e.target}${e.targetHandle ? `:${e.targetHandle}` : \"\"}`,\n }));\n return textResult(items.map((i) => `${i.id}: ${i.from} → ${i.to}`).join(\"\\n\") || \"(no edges)\", items);\n });\n\n // ───────────── Node CRUD ─────────────\n\n reg(\n \"flow_add_node\",\n \"Add a node of any kind registered in fancy-flow's registry. Call flow_list_node_kinds first to discover what's available.\",\n {\n kind: { type: \"string\", description: \"Registry kind name (e.g. memory_store, llm_call, branch).\" },\n label: { type: \"string\" },\n x: { type: \"number\" },\n y: { type: \"number\" },\n description: { type: \"string\" },\n config: { type: \"object\", description: \"Config fields per the kind's configSchema.\" },\n body: { type: \"string\", description: \"Note kinds only — body text.\" },\n },\n [\"kind\", \"label\", \"x\", \"y\"],\n async (args) => {\n const kindName = str(args.kind);\n // Resolve the kind dynamically from the registry. Falls back to the\n // legacy 6-pack so old graphs keep working.\n let kindDef: any = null;\n try {\n // @ts-ignore — optional peer dep\n const { getNodeKind, defaultConfigFor } = await import(\"@particle-academy/fancy-flow\" as any);\n kindDef = getNodeKind(kindName);\n var defaults: Record<string, unknown> = kindDef ? defaultConfigFor(kindDef) : {};\n } catch {\n var defaults: Record<string, unknown> = {};\n }\n const isLegacy = [\"trigger\", \"action\", \"decision\", \"output\", \"note\", \"subgraph\"].includes(kindName);\n if (!kindDef && !isLegacy) {\n return errorResult(`Unknown kind: ${kindName} — call flow_list_node_kinds for the registry.`);\n }\n const id = newId(\"n\");\n const config = { ...defaults, ...((args.config && typeof args.config === \"object\") ? (args.config as Record<string, unknown>) : {}) };\n const node: FlowNode = {\n id,\n type: kindName,\n position: { x: num(args.x), y: num(args.y) },\n data: {\n kind: kindName,\n label: str(args.label),\n ...(args.description ? { description: str(args.description) } : {}),\n config,\n ...(kindName === \"note\" && args.body ? { body: str(args.body) } : {}),\n } as any,\n };\n adapter.setNodes((all) => [...all, node]);\n return textResult(`Added ${kindName} ${id} (\"${str(args.label)}\")`, node);\n },\n );\n\n reg(\n \"flow_update_node\",\n \"Update fields on a node. Only provided fields change.\",\n {\n id: { type: \"string\" },\n label: { type: \"string\" },\n x: { type: \"number\" },\n y: { type: \"number\" },\n description: { type: \"string\" },\n config: { type: \"object\" },\n },\n [\"id\"],\n (args) => {\n const id = str(args.id);\n let updated: FlowNode | null = null;\n adapter.setNodes((all) =>\n all.map((n) => {\n if (n.id !== id) return n;\n updated = {\n ...n,\n position: {\n x: args.x !== undefined ? num(args.x) : n.position.x,\n y: args.y !== undefined ? num(args.y) : n.position.y,\n },\n data: {\n ...n.data,\n ...(args.label !== undefined ? { label: str(args.label) } : {}),\n ...(args.description !== undefined ? { description: str(args.description) } : {}),\n ...(args.config && typeof args.config === \"object\"\n ? { config: { ...(n.data.config ?? {}), ...(args.config as Record<string, unknown>) } }\n : {}),\n },\n };\n return updated;\n }),\n );\n if (!updated) return errorResult(`No node with id ${id}`);\n return textResult(`Updated node ${id}`, updated);\n },\n );\n\n reg(\n \"flow_delete_node\",\n \"Remove a node by id (also removes any connected edges).\",\n { id: { type: \"string\" } },\n [\"id\"],\n (args) => {\n const id = str(args.id);\n // Validate existence BEFORE scheduling the state update — React's\n // functional updaters may run async in strict mode, so checking a\n // flag set inside the updater would race the response.\n if (!adapter.getNodes().some((n) => n.id === id)) {\n return errorResult(`No node with id ${id}`);\n }\n adapter.setNodes((all) => all.filter((n) => n.id !== id));\n adapter.setEdges((all) => all.filter((e) => e.source !== id && e.target !== id));\n return textResult(`Deleted node ${id}`);\n },\n );\n\n // ───────────── Edges ─────────────\n\n reg(\n \"flow_connect\",\n \"Create an edge between two nodes (optionally specifying handle ids).\",\n {\n source: { type: \"string\" },\n target: { type: \"string\" },\n sourceHandle: { type: \"string\" },\n targetHandle: { type: \"string\" },\n label: { type: \"string\" },\n },\n [\"source\", \"target\"],\n (args) => {\n const source = str(args.source);\n const target = str(args.target);\n const all = adapter.getNodes();\n if (!all.find((n) => n.id === source)) return errorResult(`No source node ${source}`);\n if (!all.find((n) => n.id === target)) return errorResult(`No target node ${target}`);\n const edge: FlowEdge = {\n id: newId(\"e\"),\n source,\n target,\n ...(args.sourceHandle ? { sourceHandle: str(args.sourceHandle) } : {}),\n ...(args.targetHandle ? { targetHandle: str(args.targetHandle) } : {}),\n ...(args.label ? { label: str(args.label) } : {}),\n };\n adapter.setEdges((existing) => [...existing, edge]);\n return textResult(`Connected ${source}${edge.sourceHandle ? `:${edge.sourceHandle}` : \"\"} → ${target}${edge.targetHandle ? `:${edge.targetHandle}` : \"\"}`, edge);\n },\n );\n\n reg(\n \"flow_disconnect\",\n \"Remove an edge by id.\",\n { id: { type: \"string\" } },\n [\"id\"],\n (args) => {\n const id = str(args.id);\n if (!adapter.getEdges().some((e) => e.id === id)) {\n return errorResult(`No edge ${id}`);\n }\n adapter.setEdges((all) => all.filter((e) => e.id !== id));\n return textResult(`Disconnected ${id}`);\n },\n );\n\n // ───────────── Status / run ─────────────\n\n reg(\n \"flow_set_node_status\",\n \"Manually set a node's status badge (idle | queued | running | done | error) and optional text. Useful for narration outside a run.\",\n {\n id: { type: \"string\" },\n status: { type: \"string\", enum: [\"idle\", \"queued\", \"running\", \"done\", \"error\"] },\n text: { type: \"string\" },\n },\n [\"id\", \"status\"],\n (args) => {\n const id = str(args.id);\n const status = str(args.status) as NodeRunStatus;\n const text = args.text !== undefined ? str(args.text) : undefined;\n if (adapter.setNodeStatus) {\n adapter.setNodeStatus(id, status, text);\n } else {\n // Fall back to mutating the node data directly.\n let found = false;\n adapter.setNodes((all) =>\n all.map((n) => {\n if (n.id !== id) return n;\n found = true;\n return { ...n, data: { ...n.data, status, statusText: text } };\n }),\n );\n if (!found) return errorResult(`No node with id ${id}`);\n }\n return textResult(`${id} → ${status}${text ? ` (${text})` : \"\"}`);\n },\n );\n\n reg(\n \"flow_run\",\n \"Trigger a run of the current graph. Returns the topological result. Requires the host to have wired `run` into the adapter.\",\n {},\n [],\n async () => {\n if (!adapter.run) return errorResult(\"Host did not provide a run handler.\");\n const result = await adapter.run();\n return textResult(result.ok ? \"Run complete\" : `Run failed: ${result.error ?? \"unknown\"}`, result);\n },\n );\n\n reg(\n \"flow_cancel\",\n \"Cancel an in-flight run.\",\n {},\n [],\n () => {\n if (!adapter.cancel) return errorResult(\"Host did not provide a cancel handler.\");\n adapter.cancel();\n return textResult(\"Run cancelled\");\n },\n );\n\n return {\n id: \"flow\",\n title: \"Flow\",\n dispose: () => {\n for (const d of disposers) d();\n },\n };\n}\n"]}