langflower 0.0.9 → 0.1.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 (223) hide show
  1. package/README.md +96 -70
  2. package/docs/public/README.md +2 -2
  3. package/docs/public/configuration.md +4 -0
  4. package/docs/public/extending.md +18 -2
  5. package/docs/public/getting-started.md +7 -0
  6. package/docs/public/how-it-works.md +18 -11
  7. package/docs/public/product.md +35 -25
  8. package/package.json +2 -2
  9. package/ui-dist/chunk-QI4IYILJ.js +4 -0
  10. package/ui-dist/{chunk-7UMVYN3A.js → chunk-UG3GFV4Y.js} +1 -1
  11. package/ui-dist/index.html +2 -2
  12. package/ui-dist/main-ODIDCCNX.js +315 -0
  13. package/ui-dist/styles-2JMBAQC3.css +1 -0
  14. package/vendor/common-nodes/dist/ai/features/llm-loop/llm-loop-reducer.js +0 -12
  15. package/vendor/common-nodes/dist/ai/features/llm-loop/llm-loop-types.d.ts +2 -7
  16. package/vendor/common-nodes/dist/ai/features/llm-loop/llm-loop-types.js +1 -1
  17. package/vendor/common-nodes/dist/ai/features/llm-loop/run-agent-loop.d.ts +0 -3
  18. package/vendor/common-nodes/dist/ai/features/llm-loop/run-agent-loop.js +22 -36
  19. package/vendor/common-nodes/dist/ai/features/llm-loop/run-llm-loop.d.ts +1 -7
  20. package/vendor/common-nodes/dist/ai/features/llm-loop/run-llm-loop.js +12 -35
  21. package/vendor/common-nodes/dist/ai/features/llm-session/llm-session-shell.d.ts +5 -12
  22. package/vendor/common-nodes/dist/ai/features/llm-session/llm-session-shell.js +48 -21
  23. package/vendor/common-nodes/dist/ai/features/llm-session/run-session-machine.d.ts +11 -0
  24. package/vendor/common-nodes/dist/ai/features/llm-session/run-session-machine.js +2 -2
  25. package/vendor/common-nodes/dist/ai/features/path-choice/run-reactive-path-choice-loop.d.ts +0 -3
  26. package/vendor/common-nodes/dist/ai/features/path-choice/run-reactive-path-choice-loop.js +2 -15
  27. package/vendor/common-nodes/dist/ai/features/run-host-services.d.ts +10 -0
  28. package/vendor/common-nodes/dist/ai/features/sub-agent-protocol.d.ts +1 -0
  29. package/vendor/common-nodes/dist/ai/features/sub-agent-protocol.js +1 -0
  30. package/vendor/common-nodes/dist/ai/features/ui-schema/llm-recovery-ui-schema.d.ts +1 -1
  31. package/vendor/common-nodes/dist/ai/features/ui-schema/llm-recovery-ui-schema.js +1 -1
  32. package/vendor/common-nodes/dist/ai/features/wait-for-subagent-result.d.ts +1 -0
  33. package/vendor/common-nodes/dist/ai/features/wait-for-subagent-result.js +1 -0
  34. package/vendor/common-nodes/dist/ai/nodes/critique/node.d.ts +3 -3
  35. package/vendor/common-nodes/dist/ai/nodes/critique/node.js +10 -19
  36. package/vendor/common-nodes/dist/ai/nodes/fake-llm/node.d.ts +3 -3
  37. package/vendor/common-nodes/dist/ai/nodes/fake-llm/node.js +10 -11
  38. package/vendor/common-nodes/dist/ai/nodes/openai-llm/node.d.ts +3 -3
  39. package/vendor/common-nodes/dist/ai/nodes/openai-llm/node.js +7 -10
  40. package/vendor/common-nodes/dist/ai/nodes/review/node.d.ts +3 -3
  41. package/vendor/common-nodes/dist/ai/nodes/review/node.js +12 -19
  42. package/vendor/common-nodes/dist/ai/nodes/sub-agent/node.d.ts +5 -5
  43. package/vendor/common-nodes/dist/ai/nodes/sub-agent/node.js +251 -96
  44. package/vendor/common-nodes/dist/catalog.js +12 -0
  45. package/vendor/common-nodes/dist/crawl/crawl/node.js +11 -3
  46. package/vendor/common-nodes/dist/crawl/crawl-tools/node.js +5 -1
  47. package/vendor/common-nodes/dist/crawl/extract-links/node.js +7 -1
  48. package/vendor/common-nodes/dist/crawl/fetch-url/node.js +13 -4
  49. package/vendor/common-nodes/dist/crawl/save-page/node.js +11 -3
  50. package/vendor/common-nodes/dist/embeddings/create-embedding.d.ts +39 -0
  51. package/vendor/common-nodes/dist/embeddings/create-embedding.js +154 -0
  52. package/vendor/common-nodes/dist/embeddings/embed-provider/node.d.ts +53 -0
  53. package/vendor/common-nodes/dist/embeddings/embed-provider/node.js +126 -0
  54. package/vendor/common-nodes/dist/embeddings/embed-similarity/node.d.ts +20 -0
  55. package/vendor/common-nodes/dist/embeddings/embed-similarity/node.js +81 -0
  56. package/vendor/common-nodes/dist/embeddings/embed-text/node.d.ts +53 -0
  57. package/vendor/common-nodes/dist/embeddings/embed-text/node.js +91 -0
  58. package/vendor/common-nodes/dist/embeddings/from-embedding.d.ts +8 -0
  59. package/vendor/common-nodes/dist/embeddings/from-embedding.js +24 -0
  60. package/vendor/common-nodes/dist/embeddings/resolve-embedding-provider-model.d.ts +11 -0
  61. package/vendor/common-nodes/dist/embeddings/resolve-embedding-provider-model.js +8 -0
  62. package/vendor/common-nodes/dist/flow/checkpoint/node.js +7 -3
  63. package/vendor/common-nodes/dist/flow/delay/node.d.ts +2 -6
  64. package/vendor/common-nodes/dist/flow/delay/node.js +13 -9
  65. package/vendor/common-nodes/dist/flow/loop/node.js +7 -1
  66. package/vendor/common-nodes/dist/flow/merge/node.js +7 -1
  67. package/vendor/common-nodes/dist/flow/repeat/node.js +5 -1
  68. package/vendor/common-nodes/dist/flow/router/node.js +7 -1
  69. package/vendor/common-nodes/dist/hitl/chat-input/node.d.ts +2 -2
  70. package/vendor/common-nodes/dist/hitl/chat-input/node.js +8 -4
  71. package/vendor/common-nodes/dist/hitl/review-gate/node.js +11 -5
  72. package/vendor/common-nodes/dist/langflower-tools/node.js +5 -1
  73. package/vendor/common-nodes/dist/logic/assert/node.js +7 -1
  74. package/vendor/common-nodes/dist/logic/compare/node.js +7 -1
  75. package/vendor/common-nodes/dist/logic/gate/node.js +7 -1
  76. package/vendor/common-nodes/dist/logic/if/node.js +7 -1
  77. package/vendor/common-nodes/dist/logic/switch/node.js +7 -1
  78. package/vendor/common-nodes/dist/mcp/mcp-http/node.d.ts +4 -4
  79. package/vendor/common-nodes/dist/mcp/mcp-http/node.js +61 -60
  80. package/vendor/common-nodes/dist/mcp/mcp-stdio/node.d.ts +4 -4
  81. package/vendor/common-nodes/dist/mcp/mcp-stdio/node.js +58 -57
  82. package/vendor/common-nodes/dist/memory/memory-tools/node.js +5 -1
  83. package/vendor/common-nodes/dist/output/finish/node.js +13 -1
  84. package/vendor/common-nodes/dist/output/preview/node.js +9 -2
  85. package/vendor/common-nodes/dist/primitives/boolean/node.js +7 -1
  86. package/vendor/common-nodes/dist/primitives/number/node.js +7 -1
  87. package/vendor/common-nodes/dist/primitives/string/node.js +7 -1
  88. package/vendor/common-nodes/dist/primitives/string-multiline/node.d.ts +17 -0
  89. package/vendor/common-nodes/dist/primitives/string-multiline/node.js +31 -0
  90. package/vendor/common-nodes/dist/text/append-file/node.js +11 -3
  91. package/vendor/common-nodes/dist/text/concat/node.js +5 -1
  92. package/vendor/common-nodes/dist/text/read-file/node.js +9 -3
  93. package/vendor/common-nodes/dist/text/split-paced/node.d.ts +21 -0
  94. package/vendor/common-nodes/dist/text/split-paced/node.js +93 -0
  95. package/vendor/common-nodes/dist/text/write-file/node.js +11 -3
  96. package/vendor/common-nodes/dist/tools/collect-agent-tool-handles.d.ts +4 -4
  97. package/vendor/common-nodes/dist/tools/collect-agent-tool-handles.js +3 -11
  98. package/vendor/common-nodes/dist/tools/inventory-tool-round.d.ts +0 -10
  99. package/vendor/common-nodes/dist/tools/inventory-tool-round.js +0 -84
  100. package/vendor/common-nodes/dist/tools/tool-collection/node.d.ts +20 -0
  101. package/vendor/common-nodes/dist/tools/tool-collection/node.js +45 -0
  102. package/vendor/common-nodes/package.json +5 -5
  103. package/vendor/compiler/package.json +1 -1
  104. package/vendor/node-sdk/dist/node-factory/define-embed/embed-handle.d.ts +25 -0
  105. package/vendor/node-sdk/dist/node-factory/define-embed/embed-handle.js +25 -0
  106. package/vendor/node-sdk/dist/node-factory/define-llm-node/default-llm-ports.d.ts +3 -7
  107. package/vendor/node-sdk/dist/node-factory/define-llm-node/default-llm-ports.js +4 -44
  108. package/vendor/node-sdk/dist/node-factory/define-llm-node/define-llm-node.d.ts +3 -5
  109. package/vendor/node-sdk/dist/node-factory/define-llm-node/define-llm-node.js +3 -5
  110. package/vendor/node-sdk/dist/node-factory/define-llm-node/llm-inventory-wire.d.ts +1 -0
  111. package/vendor/node-sdk/dist/node-factory/define-llm-node/llm-inventory-wire.js +1 -0
  112. package/vendor/node-sdk/dist/node-factory/define-mcp/mcp-handle.d.ts +4 -4
  113. package/vendor/node-sdk/dist/node-factory/define-mcp/mcp-handle.js +2 -1
  114. package/vendor/node-sdk/dist/node-factory/define-node/define-node.d.ts +2 -0
  115. package/vendor/node-sdk/dist/node-factory/define-node/define-node.js +4 -1
  116. package/vendor/node-sdk/dist/node-factory/define-reactive-node/define-reactive-node.d.ts +3 -1
  117. package/vendor/node-sdk/dist/node-factory/define-reactive-node/define-reactive-node.js +2 -1
  118. package/vendor/node-sdk/dist/node-factory/define-reactive-node/io-helpers.d.ts +15 -0
  119. package/vendor/node-sdk/dist/node-factory/define-reactive-node/io-helpers.js +17 -1
  120. package/vendor/node-sdk/dist/node-factory/define-reactive-node/port-meta.d.ts +17 -4
  121. package/vendor/node-sdk/dist/node-factory/define-reactive-node/test/samples/delay-node.js +4 -2
  122. package/vendor/node-sdk/dist/node-factory/define-reactive-node/types.d.ts +6 -7
  123. package/vendor/node-sdk/dist/node-factory/define-reactive-node/ui-schema-inference.d.ts +1 -1
  124. package/vendor/node-sdk/dist/testing/create-node-harness.d.ts +30 -0
  125. package/vendor/node-sdk/dist/testing/create-node-harness.js +68 -0
  126. package/vendor/node-sdk/package.json +5 -5
  127. package/vendor/runtime/dist/port-feed-override.d.ts +13 -0
  128. package/vendor/runtime/dist/port-feed-override.js +21 -0
  129. package/vendor/runtime/dist/port-signal-from-response.d.ts +15 -0
  130. package/vendor/runtime/dist/port-signal-from-response.js +48 -0
  131. package/vendor/runtime/dist/runtime-runner.d.ts +8 -3
  132. package/vendor/runtime/dist/runtime-runner.js +102 -81
  133. package/vendor/runtime/dist/runtime.d.ts +3 -2
  134. package/vendor/runtime/dist/runtime.js +1 -1
  135. package/vendor/runtime/dist/testing/workflows/workflow-events.d.ts +2 -0
  136. package/vendor/runtime/dist/testing/workflows/workflow-events.js +7 -5
  137. package/vendor/runtime/dist/types.d.ts +26 -9
  138. package/vendor/runtime/dist/types.js +3 -0
  139. package/vendor/runtime/package.json +1 -1
  140. package/vendor/server/dist/bootstrap/project-bootstrap.service.d.ts +1 -1
  141. package/vendor/server/dist/bootstrap/seed-skeleton.d.ts +2 -2
  142. package/vendor/server/dist/bootstrap/seed-skeleton.js +17 -2
  143. package/vendor/server/dist/bridge/bind-embed-context.d.ts +7 -0
  144. package/vendor/server/dist/bridge/bind-embed-context.js +16 -0
  145. package/vendor/server/dist/bridge/build-execution-context.d.ts +2 -2
  146. package/vendor/server/dist/bridge/build-execution-context.js +8 -4
  147. package/vendor/server/dist/bridge/emit-bootstrap.js +4 -1
  148. package/vendor/server/dist/bridge/get-live-wired-tools.d.ts +3 -2
  149. package/vendor/server/dist/bridge/get-live-wired-tools.js +8 -5
  150. package/vendor/server/dist/bridge/settings-draft-controller.js +7 -3
  151. package/vendor/server/dist/bridge/wire-config-handlers.js +2 -0
  152. package/vendor/server/dist/bridge/wire-editor-handlers.js +14 -0
  153. package/vendor/server/dist/bridge/wire-runner-handlers.js +2 -2
  154. package/vendor/server/dist/bridge/wire-workflow-handlers.js +23 -9
  155. package/vendor/server/dist/checkpoint/run-checkpoint-session.js +3 -3
  156. package/vendor/server/dist/config/langflower-config.service.d.ts +2 -0
  157. package/vendor/server/dist/config/langflower-config.service.js +30 -0
  158. package/vendor/server/dist/session/build-session-bootstrap.js +1 -0
  159. package/vendor/server/dist/session/langflower-session.d.ts +3 -1
  160. package/vendor/server/dist/session/langflower-session.js +3 -1
  161. package/vendor/server/dist/session/reset-session-execution-feed.d.ts +6 -0
  162. package/vendor/server/dist/session/reset-session-execution-feed.js +8 -0
  163. package/vendor/server/dist/workflow/apply-editor-mutation.js +6 -0
  164. package/vendor/server/dist/workflow/workflow-persisted-inputs.js +8 -6
  165. package/vendor/server/skeleton/instructions.md +15 -3
  166. package/vendor/server/skeleton/nodes/hello-embed/README.md +185 -0
  167. package/vendor/server/skeleton/nodes/hello-embed/hello-embed.nodes.test.ts +181 -0
  168. package/vendor/server/skeleton/nodes/hello-embed/ingest.ts +126 -0
  169. package/vendor/server/skeleton/nodes/hello-embed/lib/chunk-markdown.test.ts +40 -0
  170. package/vendor/server/skeleton/nodes/hello-embed/lib/chunk-markdown.ts +123 -0
  171. package/vendor/server/skeleton/nodes/hello-embed/lib/ingest-search.test.ts +180 -0
  172. package/vendor/server/skeleton/nodes/hello-embed/lib/ingest.ts +128 -0
  173. package/vendor/server/skeleton/nodes/hello-embed/lib/paths.test.ts +20 -0
  174. package/vendor/server/skeleton/nodes/hello-embed/lib/paths.ts +70 -0
  175. package/vendor/server/skeleton/nodes/hello-embed/lib/schema.ts +21 -0
  176. package/vendor/server/skeleton/nodes/hello-embed/lib/search.ts +254 -0
  177. package/vendor/server/skeleton/nodes/hello-embed/lib/text-embedder.ts +14 -0
  178. package/vendor/server/skeleton/nodes/hello-embed/lib/vectors.ts +126 -0
  179. package/vendor/server/skeleton/nodes/hello-embed/lib/walk-markdown.test.ts +62 -0
  180. package/vendor/server/skeleton/nodes/hello-embed/lib/walk-markdown.ts +67 -0
  181. package/vendor/server/skeleton/nodes/hello-embed/package.json +11 -0
  182. package/vendor/server/skeleton/nodes/hello-embed/search-handle.ts +119 -0
  183. package/vendor/server/skeleton/nodes/hello-embed/search.ts +98 -0
  184. package/vendor/server/skeleton/nodes/hello-embed/tsconfig.json +14 -0
  185. package/vendor/server/skeleton/nodes/my-nodes/README.md +13 -3
  186. package/vendor/server/skeleton/nodes/my-nodes/package.json +1 -1
  187. package/vendor/server/skeleton/schemas/langflower-config.schema.json +4 -0
  188. package/vendor/server/skeleton/skills/langflower-helper/SKILL.md +125 -38
  189. package/vendor/server/skeleton/skills/langflower-helper/architecture.md +17 -6
  190. package/vendor/server/skeleton/skills/langflower-helper/layout.md +24 -17
  191. package/vendor/server/skeleton/skills/langflower-node-writer/SKILL.md +8 -1
  192. package/vendor/server/skeleton/skills/langflower-workflow-writer/SKILL.md +12 -8
  193. package/vendor/server/skeleton/workflows/kb-create.json +15 -43
  194. package/vendor/server/skeleton/workflows/kb-ingest.json +88 -0
  195. package/vendor/server/skeleton/workflows/kb-manual-search.json +105 -0
  196. package/vendor/server/skeleton/workflows/kb-navigate.json +8 -22
  197. package/vendor/server/skeleton/workflows/kb-rag.json +192 -0
  198. package/vendor/server/skeleton/workflows/kb-tool.json +111 -0
  199. package/vendor/server/skeleton/workflows/simple-coder.json +18 -46
  200. package/vendor/server/skeleton/workflows/starter.json +8 -22
  201. package/vendor/shared/dist/execution/derive-run-settle-outcome.js +2 -2
  202. package/vendor/shared/dist/execution/derive-run-settle-outcome.test.js +11 -8
  203. package/vendor/shared/dist/langflower-bus-config.d.ts +22 -6
  204. package/vendor/shared/dist/langflower-bus-config.js +23 -7
  205. package/vendor/shared/dist/langflower-config/merge-langflower-config-layers.test.js +8 -0
  206. package/vendor/shared/dist/langflower-config/settings-draft.d.ts +5 -0
  207. package/vendor/shared/dist/langflower-config/settings-draft.js +15 -7
  208. package/vendor/shared/dist/langflower-ws-waits.d.ts +3 -1
  209. package/vendor/shared/dist/langflower-ws-waits.js +2 -2
  210. package/vendor/shared/dist/langflower.d.ts +1 -1
  211. package/vendor/shared/dist/langflower.js +1 -1
  212. package/vendor/shared/dist/types/langflower-bootstrap.d.ts +6 -0
  213. package/vendor/shared/dist/types/langflower-config.d.ts +17 -0
  214. package/vendor/shared/dist/types/langflower-palette.d.ts +2 -1
  215. package/vendor/tools/dist/harness-types.d.ts +1 -1
  216. package/vendor/tools/dist/mcp/build-mcp-handle.d.ts +3 -21
  217. package/vendor/tools/dist/mcp/build-mcp-handle.js +2 -11
  218. package/vendor/tools/dist/mcp/create-system-mcp-handles.d.ts +9 -6
  219. package/vendor/tools/dist/mcp/create-system-mcp-handles.js +21 -17
  220. package/vendor/tools/package.json +1 -0
  221. package/ui-dist/chunk-MDGXX73Z.js +0 -4
  222. package/ui-dist/main-2JJGCNTD.js +0 -313
  223. package/ui-dist/styles-EOXODOI7.css +0 -1
@@ -17,10 +17,6 @@
17
17
  "types": "./dist/ai/features/llm-role-preset.d.ts",
18
18
  "import": "./dist/ai/features/llm-role-preset.js"
19
19
  },
20
- "./ai/sub-agent-protocol": {
21
- "types": "./dist/ai/features/sub-agent-protocol.d.ts",
22
- "import": "./dist/ai/features/sub-agent-protocol.js"
23
- },
24
20
  "./ai/run-host-services": {
25
21
  "types": "./dist/ai/features/run-host-services.d.ts",
26
22
  "import": "./dist/ai/features/run-host-services.js"
@@ -32,13 +28,17 @@
32
28
  "./ai/openai/list-provider-models": {
33
29
  "types": "./dist/ai/features/openai/list-provider-models.d.ts",
34
30
  "import": "./dist/ai/features/openai/list-provider-models.js"
31
+ },
32
+ "./embeddings/create-embedding": {
33
+ "types": "./dist/embeddings/create-embedding.d.ts",
34
+ "import": "./dist/embeddings/create-embedding.js"
35
35
  }
36
36
  },
37
37
  "dependencies": {
38
38
  "@langflower/node-sdk": "file:../node-sdk",
39
39
  "@langflower/runtime": "file:../runtime",
40
40
  "@langflower/tools": "file:../tools",
41
- "@rx-evo/stateful-observable": "^0.5.2",
41
+ "@rx-evo/stateful-observable": "^0.6.0",
42
42
  "openai": "^4.104.0",
43
43
  "rxjs": "^7.8.1"
44
44
  },
@@ -14,7 +14,7 @@
14
14
  },
15
15
  "dependencies": {
16
16
  "@langflower/node-sdk": "file:../node-sdk",
17
- "@rx-evo/stateful-observable": "^0.5.2",
17
+ "@rx-evo/stateful-observable": "^0.6.0",
18
18
  "@types/node": "^22.10.0",
19
19
  "esbuild": "^0.25.0",
20
20
  "rxjs": "^7.8.1",
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Canvas capability for batch embeddings. Parallel to {@link ToolHandle}
3
+ * but **not** agent inventory: `embedTexts` returns float vectors, never
4
+ * LLM-facing strings.
5
+ *
6
+ * Wire: provider `embed` out → consumer `embed` in, both
7
+ * {@link EMBED_HANDLE_WIRE_TYPE}. Live closure (not JSON-serializable).
8
+ */
9
+ export declare const EMBED_HANDLE_WIRE_TYPE = "embed-handle";
10
+ export type EmbedTextRole = 'document' | 'query';
11
+ export type EmbedTextsOptions = {
12
+ readonly role?: EmbedTextRole;
13
+ readonly signal?: AbortSignal;
14
+ };
15
+ export type EmbedHandle = {
16
+ /** Vector size for this bound model; packs MUST reject a mismatch. */
17
+ readonly dim: number;
18
+ readonly embedTexts: (texts: readonly string[], options?: EmbedTextsOptions) => Promise<readonly Float32Array[]>;
19
+ };
20
+ /**
21
+ * Duck-type guard for {@link EmbedHandle} on `defineNode` `execute` inputs
22
+ * (`Record<string, unknown>`). Requires a positive finite `dim` (emit only
23
+ * once dim is set) and an `embedTexts` function.
24
+ */
25
+ export declare const isEmbedHandle: (value: unknown) => value is EmbedHandle;
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Canvas capability for batch embeddings. Parallel to {@link ToolHandle}
3
+ * but **not** agent inventory: `embedTexts` returns float vectors, never
4
+ * LLM-facing strings.
5
+ *
6
+ * Wire: provider `embed` out → consumer `embed` in, both
7
+ * {@link EMBED_HANDLE_WIRE_TYPE}. Live closure (not JSON-serializable).
8
+ */
9
+ export const EMBED_HANDLE_WIRE_TYPE = 'embed-handle';
10
+ const isRecord = (value) => typeof value === 'object' && value !== null;
11
+ /**
12
+ * Duck-type guard for {@link EmbedHandle} on `defineNode` `execute` inputs
13
+ * (`Record<string, unknown>`). Requires a positive finite `dim` (emit only
14
+ * once dim is set) and an `embedTexts` function.
15
+ */
16
+ export const isEmbedHandle = (value) => {
17
+ if (!isRecord(value)) {
18
+ return false;
19
+ }
20
+ const dim = value['dim'];
21
+ return (typeof dim === 'number' &&
22
+ Number.isFinite(dim) &&
23
+ dim > 0 &&
24
+ typeof value['embedTexts'] === 'function');
25
+ };
@@ -3,13 +3,10 @@ import type { StatefulObservable } from '@rx-evo/stateful-observable';
3
3
  import type { configureOutput, InputConfig, makeInput, OutputConfig } from '../define-reactive-node/io-helpers.js';
4
4
  import type { LlmRecoveryNotice } from './recovery-notice.js';
5
5
  /** Port ids that every LLM-class node must expose (inventory + observability). */
6
- export declare const LLM_INVENTORY_INPUT_PORT_IDS: readonly ["tools", "mcp", "subagentRegistration", "subagentResult", "steerControl"];
7
- export declare const LLM_INVENTORY_OUTPUT_PORT_IDS: readonly ["toolLog", "recovery", "subagent"];
6
+ export declare const LLM_INVENTORY_INPUT_PORT_IDS: readonly ["tools", "steerControl"];
7
+ export declare const LLM_INVENTORY_OUTPUT_PORT_IDS: readonly ["toolLog", "recovery"];
8
8
  export type LlmInventoryInputs = {
9
9
  readonly tools: InputConfig;
10
- readonly mcp: InputConfig;
11
- readonly subagentRegistration: InputConfig;
12
- readonly subagentResult: InputConfig;
13
10
  /** Soft Pause / Steer (ADR-032) — hidden + HITL textarea. */
14
11
  readonly steerControl: InputConfig;
15
12
  /** Ordered list for `inputs: [...]` spreads. */
@@ -18,7 +15,6 @@ export type LlmInventoryInputs = {
18
15
  export type LlmInventoryOutputStreams = {
19
16
  readonly toolLog$: StatefulObservable<string, unknown, PortMeta | undefined>;
20
17
  readonly recovery$: StatefulObservable<LlmRecoveryNotice, unknown, PortMeta | undefined>;
21
- readonly subagent$: StatefulObservable<unknown, unknown, PortMeta | undefined>;
22
18
  };
23
19
  /**
24
20
  * Create the shared LLM inventory inputs. Authors may extend with role ports
@@ -26,6 +22,6 @@ export type LlmInventoryOutputStreams = {
26
22
  */
27
23
  export declare const defaultLlmInventoryInputs: (make: typeof makeInput) => LlmInventoryInputs;
28
24
  /**
29
- * Configure the shared LLM inventory outputs (`toolLog`, `recovery`, `subagent`).
25
+ * Configure the shared LLM inventory outputs (`toolLog`, `recovery`).
30
26
  */
31
27
  export declare const defaultLlmInventoryOutputs: (configure: typeof configureOutput, streams: LlmInventoryOutputStreams) => readonly OutputConfig[];
@@ -1,21 +1,12 @@
1
- import { MCP_HANDLE_WIRE_TYPE } from '../define-mcp/mcp-handle.js';
2
1
  import { TOOL_HANDLE_WIRE_TYPE } from '../define-tool-registrations/tool-handle.js';
3
- import { SUBAGENT_REGISTRATION_WIRE_TYPE, SUBAGENT_RESULT_WIRE_TYPE, SUBAGENT_SPAWN_WIRE_TYPE, } from './llm-inventory-wire.js';
4
2
  import { STEER_CONTROL_PORT_ID, } from './steer-control.js';
5
3
  import { RECOVERY_PORT_ID } from './recovery-notice.js';
6
4
  /** Port ids that every LLM-class node must expose (inventory + observability). */
7
5
  export const LLM_INVENTORY_INPUT_PORT_IDS = [
8
6
  'tools',
9
- 'mcp',
10
- 'subagentRegistration',
11
- 'subagentResult',
12
7
  STEER_CONTROL_PORT_ID,
13
8
  ];
14
- export const LLM_INVENTORY_OUTPUT_PORT_IDS = [
15
- 'toolLog',
16
- 'recovery',
17
- 'subagent',
18
- ];
9
+ export const LLM_INVENTORY_OUTPUT_PORT_IDS = ['toolLog', 'recovery'];
19
10
  /**
20
11
  * Create the shared LLM inventory inputs. Authors may extend with role ports
21
12
  * but must not omit these.
@@ -27,26 +18,6 @@ export const defaultLlmInventoryInputs = (make) => {
27
18
  multi: 'combine',
28
19
  defaultValue: [],
29
20
  });
30
- const mcp = make('mcp', {
31
- name: 'mcp',
32
- wireType: MCP_HANDLE_WIRE_TYPE,
33
- multi: 'combine',
34
- defaultValue: [],
35
- });
36
- const subagentRegistration = make('subagentRegistration', {
37
- name: 'subagentRegistration',
38
- wireType: SUBAGENT_REGISTRATION_WIRE_TYPE,
39
- multi: 'combine',
40
- defaultValue: [],
41
- });
42
- const subagentResult = make('subagentResult', {
43
- name: 'subagentResult',
44
- wireType: SUBAGENT_RESULT_WIRE_TYPE,
45
- multi: 'merge',
46
- defaultValue: null,
47
- // Protocol payload from Sub-Agent — omit from work log.
48
- feed: { role: 'none' },
49
- });
50
21
  const steerControl = make(STEER_CONTROL_PORT_ID, {
51
22
  name: 'Steer',
52
23
  wireType: 'any',
@@ -64,21 +35,12 @@ export const defaultLlmInventoryInputs = (make) => {
64
35
  });
65
36
  return {
66
37
  tools,
67
- mcp,
68
- subagentRegistration,
69
- subagentResult,
70
38
  steerControl,
71
- inputs: [
72
- tools,
73
- mcp,
74
- subagentRegistration,
75
- subagentResult,
76
- steerControl,
77
- ],
39
+ inputs: [tools, steerControl],
78
40
  };
79
41
  };
80
42
  /**
81
- * Configure the shared LLM inventory outputs (`toolLog`, `recovery`, `subagent`).
43
+ * Configure the shared LLM inventory outputs (`toolLog`, `recovery`).
82
44
  */
83
45
  export const defaultLlmInventoryOutputs = (configure, streams) => [
84
46
  configure('toolLog', streams.toolLog$, {
@@ -87,10 +49,8 @@ export const defaultLlmInventoryOutputs = (configure, streams) => [
87
49
  }),
88
50
  configure(RECOVERY_PORT_ID, streams.recovery$, {
89
51
  wireType: 'any',
52
+ // Feed-only — canvas and palette skip hidden outputs.
90
53
  hidden: true,
91
54
  feed: { role: 'recovery', streaming: true },
92
55
  }),
93
- configure('subagent', streams.subagent$, {
94
- wireType: SUBAGENT_SPAWN_WIRE_TYPE,
95
- }),
96
56
  ];
@@ -17,10 +17,9 @@ type LlmCtx<UI extends readonly UISchemaConstItem[]> = Parameters<DefinedReactiv
17
17
  export type { LlmExecutionCaps };
18
18
  /**
19
19
  * Purpose factory atop {@link defineReactiveNode}: every LLM-class node gets
20
- * the shared inventory / observability ports (`tools`, `mcp`,
21
- * `subagentRegistration`, `subagentResult`, `steerControl`, `toolLog`,
22
- * `subagent`). Authors may extend with role ports but cannot omit the
23
- * inventory set.
20
+ * the shared inventory / observability ports (`tools`, `steerControl`,
21
+ * `toolLog`, `recovery`). Authors may extend with role ports but cannot omit
22
+ * the inventory set.
24
23
  */
25
24
  export declare const defineLlmNode: <UI extends readonly UISchemaConstItem[]>(config: Omit<DefinedReactiveNodeConfig<UI, LlmExecutionCaps>, "bind"> & {
26
25
  readonly bind: (ctx: LlmCtx<UI>, helpers: ReactiveBindHelpers, inventory: LlmInventoryInputs) => LlmBindResult;
@@ -41,6 +40,5 @@ export declare const defineLlmNode: <UI extends readonly UISchemaConstItem[]>(co
41
40
  readonly icon: string | undefined;
42
41
  };
43
42
  export { LLM_INVENTORY_INPUT_PORT_IDS, LLM_INVENTORY_OUTPUT_PORT_IDS, type LlmInventoryInputs, type LlmInventoryOutputStreams, } from './default-llm-ports.js';
44
- export { SUBAGENT_REGISTRATION_WIRE_TYPE, SUBAGENT_RESULT_WIRE_TYPE, SUBAGENT_SPAWN_WIRE_TYPE, } from './llm-inventory-wire.js';
45
43
  export { STEER_CONTROL_PORT_ID, isSteerControlContinue, isSteerControlPause, isSteerControlPayload, type SteerControlPayload, type SteerControlPause, type SteerControlResume, type SteerControlSteer, } from './steer-control.js';
46
44
  export { RECOVERY_PORT_ID, isLlmRecoveryNotice, isLlmRecoverySuspended, recoveryNoticeText, toLlmRecoveryPortValue, type LlmRecoveryNotice, type LlmRecoveryNoticeCode, type LlmRecoveryRetryReason, } from './recovery-notice.js';
@@ -21,10 +21,9 @@ const assertNoInventoryOutputs = (outputs) => {
21
21
  };
22
22
  /**
23
23
  * Purpose factory atop {@link defineReactiveNode}: every LLM-class node gets
24
- * the shared inventory / observability ports (`tools`, `mcp`,
25
- * `subagentRegistration`, `subagentResult`, `steerControl`, `toolLog`,
26
- * `subagent`). Authors may extend with role ports but cannot omit the
27
- * inventory set.
24
+ * the shared inventory / observability ports (`tools`, `steerControl`,
25
+ * `toolLog`, `recovery`). Authors may extend with role ports but cannot omit
26
+ * the inventory set.
28
27
  */
29
28
  export const defineLlmNode = (config) => {
30
29
  const { bind: authorBind, ...rest } = config;
@@ -46,6 +45,5 @@ export const defineLlmNode = (config) => {
46
45
  });
47
46
  };
48
47
  export { LLM_INVENTORY_INPUT_PORT_IDS, LLM_INVENTORY_OUTPUT_PORT_IDS, } from './default-llm-ports.js';
49
- export { SUBAGENT_REGISTRATION_WIRE_TYPE, SUBAGENT_RESULT_WIRE_TYPE, SUBAGENT_SPAWN_WIRE_TYPE, } from './llm-inventory-wire.js';
50
48
  export { STEER_CONTROL_PORT_ID, isSteerControlContinue, isSteerControlPause, isSteerControlPayload, } from './steer-control.js';
51
49
  export { RECOVERY_PORT_ID, isLlmRecoveryNotice, isLlmRecoverySuspended, recoveryNoticeText, toLlmRecoveryPortValue, } from './recovery-notice.js';
@@ -2,3 +2,4 @@
2
2
  export declare const SUBAGENT_REGISTRATION_WIRE_TYPE = "subagent-registration";
3
3
  export declare const SUBAGENT_SPAWN_WIRE_TYPE = "subagent-spawn";
4
4
  export declare const SUBAGENT_RESULT_WIRE_TYPE = "subagent-result";
5
+ //# sourceMappingURL=llm-inventory-wire.d.ts.map
@@ -2,3 +2,4 @@
2
2
  export const SUBAGENT_REGISTRATION_WIRE_TYPE = 'subagent-registration';
3
3
  export const SUBAGENT_SPAWN_WIRE_TYPE = 'subagent-spawn';
4
4
  export const SUBAGENT_RESULT_WIRE_TYPE = 'subagent-result';
5
+ //# sourceMappingURL=llm-inventory-wire.js.map
@@ -1,8 +1,8 @@
1
1
  import type { ToolHandle } from '../define-tool-registrations/tool-handle.js';
2
2
  /**
3
- * Live MCP session handle on LLM `mcp` init ports.
4
- * Owned by MCP stdio/http nodes and server project MCP seed — agents only
5
- * flatten `tools`. Not JSON-serializable.
3
+ * Live MCP session handle owned by MCP stdio/http nodes and server project
4
+ * MCP seed. Agents consume `tools` only — not a canvas wire type.
5
+ * Not JSON-serializable.
6
6
  */
7
7
  export type McpHandle = {
8
8
  /** Wire: graph nodeId. System: jsonc `mcp.servers` key. */
@@ -12,4 +12,4 @@ export type McpHandle = {
12
12
  /** Tools listed+bound at connect (`tools/list`; system MCP may filter). */
13
13
  readonly tools: readonly ToolHandle[];
14
14
  };
15
- export declare const MCP_HANDLE_WIRE_TYPE = "mcp-handle";
15
+ //# sourceMappingURL=mcp-handle.d.ts.map
@@ -1 +1,2 @@
1
- export const MCP_HANDLE_WIRE_TYPE = 'mcp-handle';
1
+ export {};
2
+ //# sourceMappingURL=mcp-handle.js.map
@@ -30,5 +30,7 @@ export type DefineNodeConfig<UI extends readonly UISchemaConstItem[] = readonly
30
30
  /**
31
31
  * Simple authoring factory: sync/Promise `execute` without RxJS.
32
32
  * Adapter over {@link defineReactiveNode} (one reactive runtime path).
33
+ * Stamps `{ pending: true }` on outputs before each `execute` via
34
+ * {@link withLoading} — authors do not call it.
33
35
  */
34
36
  export declare const defineNode: <const UI extends readonly UISchemaConstItem[]>(config: DefineNodeConfig<UI>) => ReactiveNodeDefinition;
@@ -1,4 +1,5 @@
1
1
  import { from, mergeMap, of, throwError } from 'rxjs';
2
+ import { withLoading, } from '../define-reactive-node/io-helpers.js';
2
3
  import { defineReactiveNode, } from '../define-reactive-node/define-reactive-node.js';
3
4
  const inputParamsFromMeta = (portId, meta) => {
4
5
  const params = {
@@ -21,6 +22,8 @@ const inputParamsFromMeta = (portId, meta) => {
21
22
  /**
22
23
  * Simple authoring factory: sync/Promise `execute` without RxJS.
23
24
  * Adapter over {@link defineReactiveNode} (one reactive runtime path).
25
+ * Stamps `{ pending: true }` on outputs before each `execute` via
26
+ * {@link withLoading} — authors do not call it.
24
27
  */
25
28
  export const defineNode = (config) => {
26
29
  const inputEntries = Object.entries(config.inputs ?? {});
@@ -56,7 +59,7 @@ export const defineNode = (config) => {
56
59
  }
57
60
  return { ec, inputs };
58
61
  });
59
- const result$ = combined$.pipeValue(mergeMap(({ ec, inputs }) => from(Promise.resolve(config.execute(ec, inputs)).then((outputs) => outputs, (error) => {
62
+ const result$ = combined$.pipe(withLoading()).pipeValue(mergeMap(({ ec, inputs }) => from(Promise.resolve(config.execute(ec, inputs)).then((outputs) => outputs, (error) => {
60
63
  throw error instanceof Error
61
64
  ? error
62
65
  : new Error(String(error));
@@ -4,11 +4,13 @@ import type { DefinedReactiveNodeConfig, ExecutionContext, ReactiveNodeInstance
4
4
  import type { UISchemaConstItem } from './ui-schema-inference.js';
5
5
  export type { CtxError } from './ctx-error.js';
6
6
  export type { HitlButtonControl, HitlControl, HitlFileControl, HitlFileValue, HitlInputConfig, HitlPayloadTemplate, HitlTextareaControl, HitlTextValue, HitlUploadedFile, } from './hitl-config.js';
7
- export { configureOutput, DEFAULT_MULTILINE_MIN_HEIGHT_PX, InlineConfig, InlineSelectOption, InlineTextMultilineConfig, InputConfig, InputParams, InputPortMeta, makeInput, OutputConfig, OutputParams, OutputPortMeta, resolveMultilineInlineLayout, ResolvedMultilineInlineLayout, } from './io-helpers.js';
7
+ export { withLoading, configureOutput, DEFAULT_MULTILINE_MIN_HEIGHT_PX, InlineConfig, InlineSelectOption, InlineTextMultilineConfig, InputConfig, InputParams, InputPortMeta, makeInput, OutputConfig, OutputParams, OutputPortMeta, resolveMultilineInlineLayout, ResolvedMultilineInlineLayout, } from './io-helpers.js';
8
8
  export type { FeedPortMeta, FeedRole } from './io-helpers.js';
9
9
  export type { InputPortMode, MetaFromStatefulObservable, PortMeta, WireType, } from './port-meta.js';
10
10
  export type { ToolHandle, ToolHandler, ToolHandlerContext, } from '../define-tool-registrations/tool-handle.js';
11
11
  export { TOOL_HANDLE_WIRE_TYPE } from '../define-tool-registrations/tool-handle.js';
12
+ export type { EmbedHandle, EmbedTextRole, EmbedTextsOptions, } from '../define-embed/embed-handle.js';
13
+ export { EMBED_HANDLE_WIRE_TYPE, isEmbedHandle, } from '../define-embed/embed-handle.js';
12
14
  export type { DefinedReactiveNodeConfig, ExecutionContext, ReactiveNodeInstance, } from './types.js';
13
15
  export declare const contextSymbol: unique symbol;
14
16
  /**
@@ -1,7 +1,8 @@
1
1
  import { combineStatefulObservables, statefulConnection, } from '@rx-evo/stateful-observable';
2
2
  import { configureOutput, makeInput } from './io-helpers.js';
3
- export { configureOutput, DEFAULT_MULTILINE_MIN_HEIGHT_PX, makeInput, resolveMultilineInlineLayout, } from './io-helpers.js';
3
+ export { withLoading, configureOutput, DEFAULT_MULTILINE_MIN_HEIGHT_PX, makeInput, resolveMultilineInlineLayout, } from './io-helpers.js';
4
4
  export { TOOL_HANDLE_WIRE_TYPE } from '../define-tool-registrations/tool-handle.js';
5
+ export { EMBED_HANDLE_WIRE_TYPE, isEmbedHandle, } from '../define-embed/embed-handle.js';
5
6
  export const contextSymbol = Symbol('node context');
6
7
  const bindHelpers = {
7
8
  makeInput,
@@ -1,6 +1,7 @@
1
1
  import type { FeedPortMeta, MetaFromStatefulObservable, PortMeta } from './port-meta.js';
2
2
  export type { FeedPortMeta, FeedRole } from './port-meta.js';
3
3
  import { StatefulObservable } from '@rx-evo/stateful-observable';
4
+ import { type OperatorFunction } from 'rxjs';
4
5
  import type { HitlInputConfig } from './hitl-config.js';
5
6
  /** One choice for the `select` / `multiselect` / `radio` inline kinds. */
6
7
  export type InlineSelectOption = {
@@ -63,6 +64,10 @@ export type InputParams<T> = {
63
64
  readonly defaultValue?: T;
64
65
  /** On-node editor kind — unset means no on-node control at all. */
65
66
  readonly inline?: InlineConfig;
67
+ /**
68
+ * Hidden wire port — no canvas handle. With editable `inline`, still a
69
+ * visible on-node / inspector field (Chat Input `message`).
70
+ */
66
71
  readonly hidden?: boolean;
67
72
  readonly dynamic?: boolean;
68
73
  readonly hitl?: HitlInputConfig;
@@ -127,3 +132,13 @@ export declare function configureOutput<T>(portId: string, stream: StatefulObser
127
132
  export type OutputConfig = ReturnType<typeof configureOutput>;
128
133
  /** Serializable descriptor for one output port — `OutputConfig['meta']`. */
129
134
  export type OutputPortMeta = MetaFromStatefulObservable<OutputConfig>;
135
+ /**
136
+ * Stamp `{ pending: true }` on each new success, then re-emit that success.
137
+ * Use on the raw SO stream **before** async `pipeValue` work:
138
+ *
139
+ * `combineInputs(...).pipe(withLoading()).pipeValue(concatMap(delay))`
140
+ *
141
+ * `pipeValue` + `delay` / `from(Promise)` does **not** create loading.
142
+ * Do not wrap token/chunk streams (re-pends every emit through demux).
143
+ */
144
+ export declare const withLoading: <T>() => OperatorFunction<T, T>;
@@ -1,4 +1,5 @@
1
- import { statefulConnection, } from '@rx-evo/stateful-observable';
1
+ import { isSuccess, statefulConnection, } from '@rx-evo/stateful-observable';
2
+ import { concat, concatMap, of } from 'rxjs';
2
3
  /** Default floor for canvas/inspector multiline textareas (px). */
3
4
  export const DEFAULT_MULTILINE_MIN_HEIGHT_PX = 100;
4
5
  /** Resolve multiline layout; `null` when `config` is not text-multiline. */
@@ -86,3 +87,18 @@ export function configureOutput(portId, stream, meta) {
86
87
  },
87
88
  });
88
89
  }
90
+ const LOADING = {
91
+ state: Symbol.for('@rx-evo/stateful-observable/loading'),
92
+ };
93
+ /**
94
+ * Stamp `{ pending: true }` on each new success, then re-emit that success.
95
+ * Use on the raw SO stream **before** async `pipeValue` work:
96
+ *
97
+ * `combineInputs(...).pipe(withLoading()).pipeValue(concatMap(delay))`
98
+ *
99
+ * `pipeValue` + `delay` / `from(Promise)` does **not** create loading.
100
+ * Do not wrap token/chunk streams (re-pends every emit through demux).
101
+ */
102
+ export const withLoading = () => concatMap((response) => isSuccess(response)
103
+ ? concat(of(LOADING), of(response))
104
+ : of(response));
@@ -12,13 +12,26 @@ export type WireType = string & {
12
12
  __brand: 'RuntimeWireType';
13
13
  };
14
14
  export type InputPortMode = 'single' | 'merge' | 'combine' | 'zip' | 'bypass';
15
- export type FeedRole = 'none' | 'reasoning' | 'draft' | 'tool' | 'shell' | 'result' | 'recovery';
15
+ /**
16
+ * Sidebar work-log role stamped on a port's `feed.role`.
17
+ *
18
+ * - `none` — omit from the work log
19
+ * - `reasoning` — technical growing stream; caption Reasoning (LLM thinking)
20
+ * - `progress` — same layout as reasoning; caption PROGRESS (ingest/crawl/job logs)
21
+ * - `draft` — markdown draft bubble
22
+ * - `tool` / `shell` — tool/shell rows (growing when streaming)
23
+ * - `result` — conversation bubble; one row per emit (not for multi-emit logs)
24
+ * - `recovery` — amber recovery banner
25
+ */
26
+ export type FeedRole = 'none' | 'reasoning' | 'progress' | 'draft' | 'tool' | 'shell' | 'result' | 'recovery';
16
27
  /**
17
28
  * Feed projection metadata shared by input and output port contracts.
18
29
  *
19
- * `streaming: true` keeps the visit open (chunks / interleaved streams).
20
- * Omit it so the frame closes the visit; same-node frames while last still
21
- * append to that visit.
30
+ * `streaming: true` keeps the visit open and appends chunks on growing
31
+ * roles (`reasoning`, `progress`, `draft`, `tool`, `shell`). Omit
32
+ * `streaming` so the frame closes the visit.
33
+ *
34
+ * Progress logs use `{ role: 'progress', streaming: true }`.
22
35
  */
23
36
  export type FeedPortMeta = {
24
37
  readonly role?: FeedRole;
@@ -1,5 +1,5 @@
1
1
  import { concatMap, delay, of } from 'rxjs';
2
- import { defineReactiveNode } from '../../define-reactive-node.js';
2
+ import { defineReactiveNode, withLoading } from '../../define-reactive-node.js';
3
3
  /** Pass-through with async delay on `value` input. */
4
4
  export const delaySampleNode = defineReactiveNode({
5
5
  type: 'sample-delay',
@@ -12,7 +12,9 @@ export const delaySampleNode = defineReactiveNode({
12
12
  const output$ = combineInputs([value, ctx], ([inputValue, ec]) => {
13
13
  const delayMs = Math.max(0, Number(ec.params?.delayMs ?? 50));
14
14
  return { inputValue, delayMs };
15
- }).pipeValue(concatMap(({ inputValue, delayMs }) => of(inputValue).pipe(delay(delayMs))));
15
+ })
16
+ .pipe(withLoading())
17
+ .pipeValue(concatMap(({ inputValue, delayMs }) => of(inputValue).pipe(delay(delayMs))));
16
18
  return {
17
19
  inputs: [value],
18
20
  outputs: [
@@ -1,5 +1,4 @@
1
1
  import type { combineStatefulObservables, StatefulConnection, StatefulObservable } from '@rx-evo/stateful-observable';
2
- import type { McpHandle } from '../define-mcp/mcp-handle.js';
3
2
  import type { ToolHandle } from '../define-tool-registrations/tool-handle.js';
4
3
  import type { CtxError } from './ctx-error.js';
5
4
  import { configureOutput, InputConfig, makeInput, OutputConfig } from './io-helpers.js';
@@ -8,7 +7,7 @@ import type { AssertConstUISchema, ParamsFromUISchema, TypedUISchema, UISchemaCo
8
7
  /**
9
8
  * Identity + panel only. Host I/O (files/kb/crawl/…) is owned by specialized
10
9
  * common-nodes internally — not part of the author ExecutionContext API.
11
- * LLM inventory arrives via {@link LlmExecutionCaps} (`toolHandles` / `mcpHandles`).
10
+ * LLM inventory arrives via {@link LlmExecutionCaps} (`toolHandles`).
12
11
  */
13
12
  export type ExecutionContext<UI extends readonly UISchemaConstItem[] = readonly UISchemaConstItem[], Caps extends object = Record<string, never>> = {
14
13
  readonly projectDir: string;
@@ -18,10 +17,9 @@ export type ExecutionContext<UI extends readonly UISchemaConstItem[] = readonly
18
17
  readonly uiSchema: TypedUISchema<UI>;
19
18
  readonly amendInput?: (patch: Readonly<Record<string, unknown>>) => void;
20
19
  } & Caps;
21
- /** Caps for {@link defineLlmNode} — outside world via ToolHandle / MCP only. */
20
+ /** Caps for {@link defineLlmNode} — outside world via ToolHandle only. */
22
21
  export type LlmExecutionCaps = {
23
22
  readonly toolHandles?: readonly ToolHandle[];
24
- readonly mcpHandles?: readonly McpHandle[];
25
23
  };
26
24
  type ReactiveNodeBindResult = {
27
25
  readonly inputs: InputConfig[];
@@ -54,9 +52,10 @@ export type DefinedReactiveNodeConfig<UI extends readonly UISchemaConstItem[] =
54
52
  */
55
53
  readonly paletteSecondary?: boolean;
56
54
  /**
57
- * Optional markdown for the palette detail popover footer
58
- * (`renderMarkdown`). Omitted → no description block. Copied onto the
59
- * definition / `PaletteNodeDefinition` when set.
55
+ * Optional markdown for the palette detail popover and inspector.
56
+ * Omitted → no description block. Copied onto the definition /
57
+ * `PaletteNodeDefinition` when set. Write user-facing use cases, not
58
+ * author internals.
60
59
  */
61
60
  readonly description?: string;
62
61
  /**
@@ -14,7 +14,7 @@ export type UISchemaConstItem = {
14
14
  readonly optionsSource?: 'langflower.providers' | 'langflower.models' | 'langflower.tools' | 'langflower.skills' | 'langflower.mcpServers' | 'node.wiredTools';
15
15
  readonly dependsOn?: string;
16
16
  };
17
- export type DataTypeToTsType<D extends string> = D extends 'string' | 'url' | 'file-path' | 'select' | 'phase' | 'llm-message' ? string : D extends 'number' ? number : D extends 'boolean' ? boolean : D extends 'json' | 'tool-handle' | 'tool-registration' | 'mcp-handle' | 'mcp-transport' | 'tool-id-list' | 'tool-permission-table' | 'any' ? unknown : D extends 'stream' ? never : unknown;
17
+ export type DataTypeToTsType<D extends string> = D extends 'string' | 'url' | 'file-path' | 'select' | 'phase' | 'llm-message' ? string : D extends 'number' ? number : D extends 'boolean' ? boolean : D extends 'json' | 'tool-handle' | 'tool-registration' | 'tool-id-list' | 'tool-permission-table' | 'any' ? unknown : D extends 'stream' ? never : unknown;
18
18
  export type UISchemaItemValue<I extends UISchemaConstItem> = DataTypeToTsType<I['type']>;
19
19
  export type UISchemaFieldNames<UI extends readonly UISchemaConstItem[]> = UI[number]['field'];
20
20
  export type AssertConstUISchema<UI extends readonly UISchemaConstItem[]> = string extends UISchemaFieldNames<UI> ? never : UI;
@@ -0,0 +1,30 @@
1
+ import type { ReactiveNodeDefinition, ReactiveNodeInstance } from '../node-factory/define-reactive-node/define-reactive-node.js';
2
+ import { type UISchemaConstItem } from '../node-factory/define-reactive-node/ui-schema-inference.js';
3
+ type HarnessUi = readonly UISchemaConstItem[];
4
+ type HarnessInstance = ReactiveNodeInstance<HarnessUi, object>;
5
+ export type NodeHarnessOptions = {
6
+ readonly projectDir?: string;
7
+ readonly runId?: string;
8
+ readonly nodeId?: string;
9
+ readonly params?: Readonly<Record<string, unknown>>;
10
+ };
11
+ export type CollectedPort<T> = {
12
+ readonly values: readonly T[];
13
+ readonly stop: () => void;
14
+ };
15
+ export type NodeHarness = {
16
+ readonly instance: HarnessInstance;
17
+ readonly send: (portId: string, value: unknown) => void;
18
+ readonly next: <T>(portId: string) => Promise<T>;
19
+ readonly collect: <T>(portId: string) => CollectedPort<T>;
20
+ readonly dispose: () => void;
21
+ };
22
+ /**
23
+ * Drive a {@link ReactiveNodeDefinition} in unit tests: seed context,
24
+ * `send` on input ports, `next` / `collect` on outputs.
25
+ *
26
+ * Subscribe with `next` or `collect` **before** `send` when the graph can
27
+ * emit synchronously.
28
+ */
29
+ export declare const createNodeHarness: (definition: Pick<ReactiveNodeDefinition, "getInstance" | "uiSchema">, options?: NodeHarnessOptions) => NodeHarness;
30
+ export {};
@@ -0,0 +1,68 @@
1
+ import { of, firstValueFrom } from 'rxjs';
2
+ import { defaultParamsFromUiSchema, } from '../node-factory/define-reactive-node/ui-schema-inference.js';
3
+ const missingPort = (kind, portId) => new Error(`Unknown ${kind} port "${portId}"`);
4
+ /**
5
+ * Drive a {@link ReactiveNodeDefinition} in unit tests: seed context,
6
+ * `send` on input ports, `next` / `collect` on outputs.
7
+ *
8
+ * Subscribe with `next` or `collect` **before** `send` when the graph can
9
+ * emit synchronously.
10
+ */
11
+ export const createNodeHarness = (definition, options) => {
12
+ const instance = definition.getInstance();
13
+ const collectors = [];
14
+ const uiSchema = definition.uiSchema;
15
+ const params = {
16
+ ...defaultParamsFromUiSchema(uiSchema),
17
+ ...options?.params,
18
+ };
19
+ instance.ctxConnection.connect(of({
20
+ projectDir: options?.projectDir ?? '/tmp',
21
+ runId: options?.runId ?? 'test',
22
+ nodeId: options?.nodeId ?? 'node-1',
23
+ params,
24
+ uiSchema,
25
+ }));
26
+ const send = (portId, value) => {
27
+ const input = instance.inputs[portId];
28
+ if (input === undefined) {
29
+ throw missingPort('input', portId);
30
+ }
31
+ input.connect(of(value));
32
+ };
33
+ const next = (portId) => {
34
+ const output = instance.outputs[portId];
35
+ if (output === undefined) {
36
+ return Promise.reject(missingPort('output', portId));
37
+ }
38
+ return firstValueFrom(output.value$);
39
+ };
40
+ const collect = (portId) => {
41
+ const output = instance.outputs[portId];
42
+ if (output === undefined) {
43
+ throw missingPort('output', portId);
44
+ }
45
+ const values = [];
46
+ const subscription = output.value$.subscribe({
47
+ next: (value) => {
48
+ values.push(value);
49
+ },
50
+ });
51
+ collectors.push(subscription);
52
+ return {
53
+ get values() {
54
+ return values;
55
+ },
56
+ stop: () => {
57
+ subscription.unsubscribe();
58
+ },
59
+ };
60
+ };
61
+ const dispose = () => {
62
+ for (const subscription of collectors) {
63
+ subscription.unsubscribe();
64
+ }
65
+ collectors.length = 0;
66
+ };
67
+ return { instance, send, next, collect, dispose };
68
+ };
@@ -13,17 +13,17 @@
13
13
  "types": "./dist/node-factory/define-llm-node/define-llm-node.d.ts",
14
14
  "import": "./dist/node-factory/define-llm-node/define-llm-node.js"
15
15
  },
16
- "./mcp": {
17
- "types": "./dist/node-factory/define-mcp/mcp-handle.d.ts",
18
- "import": "./dist/node-factory/define-mcp/mcp-handle.js"
19
- },
20
16
  "./create-typed-ui-schema": {
21
17
  "types": "./dist/node-factory/define-reactive-node/ui-schema-inference.d.ts",
22
18
  "import": "./dist/node-factory/define-reactive-node/ui-schema-inference.js"
19
+ },
20
+ "./testing": {
21
+ "types": "./dist/testing/create-node-harness.d.ts",
22
+ "import": "./dist/testing/create-node-harness.js"
23
23
  }
24
24
  },
25
25
  "dependencies": {
26
- "@rx-evo/stateful-observable": "^0.5.2",
26
+ "@rx-evo/stateful-observable": "^0.6.0",
27
27
  "rxjs": "^7.8.1"
28
28
  },
29
29
  "files": [