langflower 0.0.8 → 0.0.10

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 (221) hide show
  1. package/package.json +2 -2
  2. package/ui-dist/{chunk-Y6VMBLSJ.js → chunk-7UMVYN3A.js} +1 -1
  3. package/ui-dist/{chunk-6DQ2XSRW.js → chunk-MDGXX73Z.js} +3 -3
  4. package/ui-dist/index.html +2 -2
  5. package/ui-dist/main-Z7CPFXFA.js +313 -0
  6. package/ui-dist/styles-2TMDAUD7.css +1 -0
  7. package/vendor/common-nodes/dist/ai/chat-completion-stream.d.ts +2 -0
  8. package/vendor/common-nodes/dist/ai/critique/node.d.ts +246 -0
  9. package/vendor/common-nodes/dist/ai/critique/node.js +2 -2
  10. package/vendor/common-nodes/dist/ai/fake-llm/node.d.ts +246 -0
  11. package/vendor/common-nodes/dist/ai/features/chat-completion-stream.d.ts +53 -0
  12. package/vendor/common-nodes/dist/ai/features/chat-completion-stream.js +1 -0
  13. package/vendor/common-nodes/dist/ai/features/llm-loop/autokick-recovery.d.ts +13 -0
  14. package/vendor/common-nodes/dist/ai/features/llm-loop/autokick-recovery.js +17 -0
  15. package/vendor/common-nodes/dist/ai/features/llm-loop/classify-llm-failure.d.ts +2 -0
  16. package/vendor/common-nodes/dist/ai/features/llm-loop/classify-llm-failure.js +113 -0
  17. package/vendor/common-nodes/dist/ai/features/llm-loop/dead-loop-detector.d.ts +28 -0
  18. package/vendor/common-nodes/dist/ai/features/llm-loop/dead-loop-detector.js +194 -0
  19. package/vendor/common-nodes/dist/ai/features/llm-loop/live-get-tools.d.ts +9 -0
  20. package/vendor/common-nodes/dist/ai/features/llm-loop/live-get-tools.js +21 -0
  21. package/vendor/common-nodes/dist/ai/features/llm-loop/llm-loop-reducer.d.ts +2 -0
  22. package/vendor/common-nodes/dist/ai/features/llm-loop/llm-loop-reducer.js +204 -0
  23. package/vendor/common-nodes/dist/ai/features/llm-loop/llm-loop-types.d.ts +120 -0
  24. package/vendor/common-nodes/dist/ai/features/llm-loop/llm-loop-types.js +39 -0
  25. package/vendor/common-nodes/dist/ai/features/llm-loop/normalize-llm-recovery-policy.d.ts +2 -0
  26. package/vendor/common-nodes/dist/ai/features/llm-loop/normalize-llm-recovery-policy.js +59 -0
  27. package/vendor/common-nodes/dist/ai/features/llm-loop/operators/normalize-tool-result.d.ts +1 -0
  28. package/vendor/common-nodes/dist/ai/features/llm-loop/operators/normalize-tool-result.js +7 -0
  29. package/vendor/common-nodes/dist/ai/features/llm-loop/operators/observe-provider-stream.d.ts +43 -0
  30. package/vendor/common-nodes/dist/ai/features/llm-loop/operators/observe-provider-stream.js +96 -0
  31. package/vendor/common-nodes/dist/ai/features/llm-loop/run-agent-loop.d.ts +29 -0
  32. package/vendor/common-nodes/dist/ai/features/llm-loop/run-agent-loop.js +44 -0
  33. package/vendor/common-nodes/dist/ai/features/llm-loop/run-llm-loop.d.ts +74 -0
  34. package/vendor/common-nodes/dist/ai/features/llm-loop/run-llm-loop.js +658 -0
  35. package/vendor/common-nodes/dist/ai/features/llm-role-preset.d.ts +69 -0
  36. package/vendor/common-nodes/dist/ai/features/llm-role-preset.js +265 -0
  37. package/vendor/common-nodes/dist/ai/features/llm-session/llm-session-shell.d.ts +141 -0
  38. package/vendor/common-nodes/dist/ai/features/llm-session/llm-session-shell.js +193 -0
  39. package/vendor/common-nodes/dist/ai/features/llm-session/run-session-machine.d.ts +21 -0
  40. package/vendor/common-nodes/dist/ai/features/llm-session/run-session-machine.js +118 -0
  41. package/vendor/common-nodes/dist/ai/features/openai/context-length-error.d.ts +14 -0
  42. package/vendor/common-nodes/dist/ai/features/openai/context-length-error.js +63 -0
  43. package/vendor/common-nodes/dist/ai/features/openai/create-chat-completion-stream.d.ts +19 -0
  44. package/vendor/common-nodes/dist/ai/features/openai/create-chat-completion-stream.js +182 -0
  45. package/vendor/common-nodes/dist/ai/features/openai/list-provider-models.d.ts +28 -0
  46. package/vendor/common-nodes/dist/ai/features/openai/list-provider-models.js +52 -0
  47. package/vendor/common-nodes/dist/ai/features/openai/llm-context-compaction.d.ts +31 -0
  48. package/vendor/common-nodes/dist/ai/features/openai/llm-context-compaction.js +326 -0
  49. package/vendor/common-nodes/dist/ai/features/openai/normalize-compaction-params.d.ts +14 -0
  50. package/vendor/common-nodes/dist/ai/features/openai/normalize-compaction-params.js +21 -0
  51. package/vendor/common-nodes/dist/ai/features/openai/prepare-chat-completion.d.ts +30 -0
  52. package/vendor/common-nodes/dist/ai/features/openai/prepare-chat-completion.js +132 -0
  53. package/vendor/common-nodes/dist/ai/features/path-choice/control-tools.d.ts +20 -0
  54. package/vendor/common-nodes/dist/ai/features/path-choice/control-tools.js +70 -0
  55. package/vendor/common-nodes/dist/ai/features/path-choice/run-reactive-path-choice-loop.d.ts +32 -0
  56. package/vendor/common-nodes/dist/ai/features/path-choice/run-reactive-path-choice-loop.js +93 -0
  57. package/vendor/common-nodes/dist/ai/features/prompt/build-effective-system-prompt.d.ts +9 -0
  58. package/vendor/common-nodes/dist/ai/features/prompt/build-effective-system-prompt.js +21 -0
  59. package/vendor/common-nodes/dist/ai/features/prompt/normalize-max-iterations.d.ts +13 -0
  60. package/vendor/common-nodes/dist/ai/features/prompt/normalize-max-iterations.js +23 -0
  61. package/vendor/common-nodes/dist/ai/features/prompt/resolve-chat-provider-model.d.ts +10 -0
  62. package/vendor/common-nodes/dist/ai/features/prompt/resolve-chat-provider-model.js +8 -0
  63. package/vendor/common-nodes/dist/ai/features/run-host-services.d.ts +54 -0
  64. package/vendor/common-nodes/dist/ai/features/run-host-services.js +29 -0
  65. package/vendor/common-nodes/dist/ai/features/scripted-chat-completion-stream.d.ts +17 -0
  66. package/vendor/common-nodes/dist/ai/features/scripted-chat-completion-stream.js +61 -0
  67. package/vendor/common-nodes/dist/ai/features/sub-agent-protocol.d.ts +40 -0
  68. package/vendor/common-nodes/dist/ai/features/sub-agent-protocol.js +44 -0
  69. package/vendor/common-nodes/dist/ai/features/ui-schema/llm-compaction-ui-schema.d.ts +14 -0
  70. package/vendor/common-nodes/dist/ai/features/ui-schema/llm-compaction-ui-schema.js +18 -0
  71. package/vendor/common-nodes/dist/ai/features/ui-schema/llm-panel-ui-schema.d.ts +80 -0
  72. package/vendor/common-nodes/dist/ai/features/ui-schema/llm-panel-ui-schema.js +76 -0
  73. package/vendor/common-nodes/dist/ai/features/ui-schema/llm-recovery-ui-schema.d.ts +113 -0
  74. package/vendor/common-nodes/dist/ai/features/ui-schema/llm-recovery-ui-schema.js +131 -0
  75. package/vendor/common-nodes/dist/ai/features/wait-for-subagent-result.d.ts +7 -0
  76. package/vendor/common-nodes/dist/ai/features/wait-for-subagent-result.js +31 -0
  77. package/vendor/common-nodes/dist/ai/llm-loop/autokick-recovery.d.ts +13 -0
  78. package/vendor/common-nodes/dist/ai/llm-loop/autokick-recovery.js +17 -0
  79. package/vendor/common-nodes/dist/ai/llm-loop/dead-loop-detector.d.ts +28 -0
  80. package/vendor/common-nodes/dist/ai/llm-loop/dead-loop-detector.js +194 -0
  81. package/vendor/common-nodes/dist/ai/llm-loop/llm-loop-reducer.js +36 -0
  82. package/vendor/common-nodes/dist/ai/llm-loop/llm-loop-types.d.ts +35 -0
  83. package/vendor/common-nodes/dist/ai/llm-loop/llm-loop-types.js +19 -0
  84. package/vendor/common-nodes/dist/ai/llm-loop/normalize-llm-recovery-policy.js +52 -9
  85. package/vendor/common-nodes/dist/ai/llm-loop/operators/observe-provider-stream.d.ts +8 -2
  86. package/vendor/common-nodes/dist/ai/llm-loop/operators/observe-provider-stream.js +43 -13
  87. package/vendor/common-nodes/dist/ai/llm-loop/run-llm-loop.d.ts +3 -5
  88. package/vendor/common-nodes/dist/ai/llm-loop/run-llm-loop.js +116 -1
  89. package/vendor/common-nodes/dist/ai/llm-recovery-ui-schema.d.ts +82 -0
  90. package/vendor/common-nodes/dist/ai/llm-recovery-ui-schema.js +95 -0
  91. package/vendor/common-nodes/dist/ai/llm-session-shell.d.ts +4 -9
  92. package/vendor/common-nodes/dist/ai/llm-session-shell.js +2 -4
  93. package/vendor/common-nodes/dist/ai/nodes/critique/node.d.ts +588 -0
  94. package/vendor/common-nodes/dist/ai/nodes/critique/node.js +227 -0
  95. package/vendor/common-nodes/dist/ai/nodes/fake-llm/node.d.ts +571 -0
  96. package/vendor/common-nodes/dist/ai/nodes/fake-llm/node.js +201 -0
  97. package/vendor/common-nodes/dist/ai/nodes/openai-llm/node.d.ts +587 -0
  98. package/vendor/common-nodes/dist/ai/nodes/openai-llm/node.js +84 -0
  99. package/vendor/common-nodes/dist/ai/nodes/review/node.d.ts +593 -0
  100. package/vendor/common-nodes/dist/ai/nodes/review/node.js +227 -0
  101. package/vendor/common-nodes/dist/ai/nodes/sub-agent/node.d.ts +630 -0
  102. package/vendor/common-nodes/dist/ai/nodes/sub-agent/node.js +417 -0
  103. package/vendor/common-nodes/dist/ai/openai/create-chat-completion-stream.js +6 -0
  104. package/vendor/common-nodes/dist/ai/openai/prepare-chat-completion.d.ts +2 -0
  105. package/vendor/common-nodes/dist/ai/openai/prepare-chat-completion.js +18 -0
  106. package/vendor/common-nodes/dist/ai/openai-llm/node.d.ts +246 -0
  107. package/vendor/common-nodes/dist/ai/review/node.d.ts +246 -0
  108. package/vendor/common-nodes/dist/ai/review/node.js +2 -2
  109. package/vendor/common-nodes/dist/ai/sub-agent/node.d.ts +246 -0
  110. package/vendor/common-nodes/dist/ai/sub-agent/node.js +2 -2
  111. package/vendor/common-nodes/dist/catalog.js +9 -5
  112. package/vendor/common-nodes/dist/compile-custom-nodes/node.d.ts +21 -0
  113. package/vendor/common-nodes/dist/compile-custom-nodes/node.js +45 -0
  114. package/vendor/common-nodes/dist/crawl/crawl/node.js +1 -1
  115. package/vendor/common-nodes/dist/crawl/fetch-url/node.js +1 -1
  116. package/vendor/common-nodes/dist/flow/repeat/node.js +6 -1
  117. package/vendor/common-nodes/dist/langflower-tools/emit-registration-tools.d.ts +18 -0
  118. package/vendor/common-nodes/dist/langflower-tools/emit-registration-tools.js +29 -0
  119. package/vendor/common-nodes/dist/langflower-tools/node.d.ts +20 -0
  120. package/vendor/common-nodes/dist/langflower-tools/node.js +77 -0
  121. package/vendor/common-nodes/dist/mcp/mcp-http/node.d.ts +4 -4
  122. package/vendor/common-nodes/dist/mcp/mcp-http/node.js +9 -10
  123. package/vendor/common-nodes/dist/mcp/mcp-stdio/node.d.ts +4 -4
  124. package/vendor/common-nodes/dist/mcp/mcp-stdio/node.js +9 -10
  125. package/vendor/common-nodes/dist/text/append-file/node.js +1 -1
  126. package/vendor/common-nodes/dist/text/read-file/node.js +1 -1
  127. package/vendor/common-nodes/dist/text/write-file/node.js +1 -1
  128. package/vendor/common-nodes/dist/tools/collect-agent-tool-handles.d.ts +4 -4
  129. package/vendor/common-nodes/dist/tools/collect-agent-tool-handles.js +3 -11
  130. package/vendor/common-nodes/dist/tools/inventory-tool-round.d.ts +1 -11
  131. package/vendor/common-nodes/dist/tools/inventory-tool-round.js +0 -84
  132. package/vendor/common-nodes/dist/tools/tool-collection/node.d.ts +20 -0
  133. package/vendor/common-nodes/dist/tools/tool-collection/node.js +42 -0
  134. package/vendor/common-nodes/package.json +9 -13
  135. package/vendor/compiler/dist/compile-project-nodes.d.ts +2 -1
  136. package/vendor/compiler/dist/compile-project-nodes.js +35 -6
  137. package/vendor/compiler/dist/resolve-host-types.d.ts +0 -5
  138. package/vendor/compiler/dist/resolve-host-types.js +0 -8
  139. package/vendor/compiler/package.json +1 -1
  140. package/vendor/node-sdk/dist/node-factory/define-llm-node/default-llm-ports.d.ts +3 -7
  141. package/vendor/node-sdk/dist/node-factory/define-llm-node/default-llm-ports.js +4 -44
  142. package/vendor/node-sdk/dist/node-factory/define-llm-node/define-llm-node.d.ts +4 -6
  143. package/vendor/node-sdk/dist/node-factory/define-llm-node/define-llm-node.js +4 -6
  144. package/vendor/node-sdk/dist/node-factory/define-llm-node/llm-inventory-wire.d.ts +1 -0
  145. package/vendor/node-sdk/dist/node-factory/define-llm-node/llm-inventory-wire.js +1 -0
  146. package/vendor/node-sdk/dist/node-factory/define-llm-node/recovery-notice.d.ts +8 -0
  147. package/vendor/node-sdk/dist/node-factory/define-llm-node/recovery-notice.js +14 -0
  148. package/vendor/node-sdk/dist/node-factory/define-mcp/mcp-handle.d.ts +3 -4
  149. package/vendor/node-sdk/dist/node-factory/define-mcp/mcp-handle.js +1 -1
  150. package/vendor/node-sdk/dist/node-factory/define-reactive-node/types.d.ts +2 -4
  151. package/vendor/node-sdk/dist/node-factory/define-reactive-node/ui-schema-inference.d.ts +1 -1
  152. package/vendor/node-sdk/package.json +1 -1
  153. package/vendor/runtime/dist/port-feed-override.d.ts +13 -0
  154. package/vendor/runtime/dist/port-feed-override.js +21 -0
  155. package/vendor/runtime/dist/port-signal-from-response.d.ts +15 -0
  156. package/vendor/runtime/dist/port-signal-from-response.js +48 -0
  157. package/vendor/runtime/dist/runtime-editor.d.ts +5 -1
  158. package/vendor/runtime/dist/runtime-editor.js +19 -0
  159. package/vendor/runtime/dist/runtime-runner.d.ts +8 -3
  160. package/vendor/runtime/dist/runtime-runner.js +108 -87
  161. package/vendor/runtime/dist/runtime.d.ts +3 -1
  162. package/vendor/runtime/dist/runtime.js +1 -0
  163. package/vendor/runtime/dist/testing/workflows/workflow-events.d.ts +10 -6
  164. package/vendor/runtime/dist/testing/workflows/workflow-events.js +21 -31
  165. package/vendor/runtime/dist/types.d.ts +52 -40
  166. package/vendor/runtime/dist/types.js +5 -1
  167. package/vendor/runtime/package.json +1 -1
  168. package/vendor/server/dist/bridge/attach-langflower-bridge.js +3 -2
  169. package/vendor/server/dist/bridge/bridge-event-log.js +17 -102
  170. package/vendor/server/dist/bridge/build-execution-context.d.ts +5 -2
  171. package/vendor/server/dist/bridge/build-execution-context.js +48 -8
  172. package/vendor/server/dist/bridge/forward-runner-event.d.ts +1 -1
  173. package/vendor/server/dist/bridge/forward-runner-event.js +7 -12
  174. package/vendor/server/dist/bridge/get-live-wired-tools.d.ts +13 -0
  175. package/vendor/server/dist/bridge/get-live-wired-tools.js +83 -0
  176. package/vendor/server/dist/bridge/langflower-tools-rpc.d.ts +7 -0
  177. package/vendor/server/dist/bridge/langflower-tools-rpc.js +29 -0
  178. package/vendor/server/dist/bridge/wire-custom-palette-handlers.d.ts +2 -1
  179. package/vendor/server/dist/bridge/wire-custom-palette-handlers.js +3 -5
  180. package/vendor/server/dist/bridge/wire-runner-handlers.js +17 -10
  181. package/vendor/server/dist/bridge/wire-workflow-handlers.js +23 -9
  182. package/vendor/server/dist/checkpoint/run-checkpoint-session.d.ts +1 -1
  183. package/vendor/server/dist/checkpoint/run-checkpoint-session.js +10 -9
  184. package/vendor/server/dist/palette/compile-and-hot-swap-custom-nodes.d.ts +10 -0
  185. package/vendor/server/dist/palette/compile-and-hot-swap-custom-nodes.js +23 -0
  186. package/vendor/server/dist/session/reset-session-execution-feed.d.ts +6 -0
  187. package/vendor/server/dist/session/reset-session-execution-feed.js +8 -0
  188. package/vendor/server/dist/workflow/apply-editor-mutation.d.ts +5 -0
  189. package/vendor/server/dist/workflow/apply-editor-mutation.js +32 -0
  190. package/vendor/server/skeleton/instructions.md +9 -5
  191. package/vendor/server/skeleton/nodes/my-nodes/README.md +4 -3
  192. package/vendor/server/skeleton/nodes/my-nodes/package.json +1 -1
  193. package/vendor/server/skeleton/skills/langflower-helper/SKILL.md +82 -38
  194. package/vendor/server/skeleton/skills/langflower-helper/architecture.md +29 -10
  195. package/vendor/server/skeleton/skills/langflower-helper/layout.md +16 -15
  196. package/vendor/server/skeleton/skills/langflower-node-writer/SKILL.md +19 -9
  197. package/vendor/server/skeleton/skills/langflower-workflow-writer/SKILL.md +23 -15
  198. package/vendor/server/skeleton/workflows/kb-create.json +15 -43
  199. package/vendor/server/skeleton/workflows/kb-navigate.json +8 -22
  200. package/vendor/server/skeleton/workflows/simple-coder.json +18 -46
  201. package/vendor/server/skeleton/workflows/starter.json +35 -22
  202. package/vendor/shared/dist/execution/derive-run-settle-outcome.d.ts +1 -1
  203. package/vendor/shared/dist/execution/derive-run-settle-outcome.js +4 -3
  204. package/vendor/shared/dist/execution/derive-run-settle-outcome.test.js +18 -15
  205. package/vendor/shared/dist/langflower-bus-config.d.ts +6 -14
  206. package/vendor/shared/dist/langflower-bus-config.js +4 -12
  207. package/vendor/shared/dist/langflower-config/resolve-wired-tool-options.js +6 -0
  208. package/vendor/shared/dist/langflower-config/resolve-wired-tool-options.test.js +30 -0
  209. package/vendor/shared/dist/langflower-ws-waits.d.ts +9 -14
  210. package/vendor/shared/dist/langflower-ws-waits.js +14 -14
  211. package/vendor/websocket-bridge/dist/bridge-codec.d.ts +1 -0
  212. package/vendor/websocket-bridge/dist/bridge-codec.js +11 -11
  213. package/vendor/websocket-bridge/dist/bridge-frame.js +1 -1
  214. package/vendor/websocket-bridge/dist/bridge-subjects.d.ts +1 -1
  215. package/vendor/websocket-bridge/dist/bridge-subjects.js +2 -2
  216. package/vendor/websocket-bridge/dist/bridge-types.d.ts +13 -1
  217. package/vendor/websocket-bridge/dist/create-client.js +3 -3
  218. package/vendor/websocket-bridge/dist/create-server.js +12 -6
  219. package/vendor/websocket-bridge/package.json +8 -0
  220. package/ui-dist/main-ECEWAM6V.js +0 -311
  221. package/ui-dist/styles-EOXODOI7.css +0 -1
@@ -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
@@ -5,10 +5,18 @@
5
5
  */
6
6
  export declare const RECOVERY_PORT_ID: "recovery";
7
7
  export type LlmRecoveryNoticeCode = 'retry' | 'suspended';
8
+ export type LlmRecoveryRetryReason = 'idle' | 'dead-loop' | 'rate-limit' | 'provider-unavailable' | 'network';
8
9
  export type LlmRecoveryNotice = {
9
10
  readonly code: LlmRecoveryNoticeCode;
10
11
  readonly text: string;
12
+ readonly attempt?: number;
13
+ readonly reason?: LlmRecoveryRetryReason;
14
+ readonly lastAttemptAt?: number;
15
+ readonly nextAttemptAt?: number;
16
+ readonly backoffMs?: number;
11
17
  };
12
18
  export declare const isLlmRecoveryNotice: (value: unknown) => value is LlmRecoveryNotice;
13
19
  export declare const isLlmRecoverySuspended: (value: unknown) => boolean;
14
20
  export declare const recoveryNoticeText: (value: unknown) => string;
21
+ /** Port payload: `code` + `text` plus any additive timing fields. */
22
+ export declare const toLlmRecoveryPortValue: (notice: LlmRecoveryNotice) => LlmRecoveryNotice;
@@ -22,3 +22,17 @@ export const recoveryNoticeText = (value) => {
22
22
  }
23
23
  return '';
24
24
  };
25
+ /** Port payload: `code` + `text` plus any additive timing fields. */
26
+ export const toLlmRecoveryPortValue = (notice) => ({
27
+ code: notice.code,
28
+ text: notice.text,
29
+ ...(notice.attempt !== undefined ? { attempt: notice.attempt } : {}),
30
+ ...(notice.reason !== undefined ? { reason: notice.reason } : {}),
31
+ ...(notice.lastAttemptAt !== undefined
32
+ ? { lastAttemptAt: notice.lastAttemptAt }
33
+ : {}),
34
+ ...(notice.nextAttemptAt !== undefined
35
+ ? { nextAttemptAt: notice.nextAttemptAt }
36
+ : {}),
37
+ ...(notice.backoffMs !== undefined ? { backoffMs: notice.backoffMs } : {}),
38
+ });
@@ -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,3 @@ 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";
@@ -1 +1 @@
1
- export const MCP_HANDLE_WIRE_TYPE = 'mcp-handle';
1
+ export {};
@@ -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[];
@@ -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;
@@ -23,7 +23,7 @@
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": [
@@ -0,0 +1,13 @@
1
+ import type { RuntimeFeedPortMeta } from './types.js';
2
+ /**
3
+ * Tag one port emission with per-event feed meta. Runtime unwraps before
4
+ * telemetry and edges so the public value stays `T`.
5
+ */
6
+ export declare const withPortFeed: <T>(value: T, feed: RuntimeFeedPortMeta) => T;
7
+ export declare const readPortFeedOverride: (raw: unknown) => {
8
+ readonly value: unknown;
9
+ readonly feed: RuntimeFeedPortMeta;
10
+ } | undefined;
11
+ /** Inner value when tagged; otherwise `raw` unchanged. */
12
+ export declare const unwrapPortFeedValue: (raw: unknown) => unknown;
13
+ //# sourceMappingURL=port-feed-override.d.ts.map
@@ -0,0 +1,21 @@
1
+ const PORT_FEED_TAG = Symbol.for('langflower.portFeed');
2
+ const isPortFeedBox = (raw) => typeof raw === 'object' && raw !== null && PORT_FEED_TAG in raw;
3
+ /**
4
+ * Tag one port emission with per-event feed meta. Runtime unwraps before
5
+ * telemetry and edges so the public value stays `T`.
6
+ */
7
+ export const withPortFeed = (value, feed) => ({
8
+ [PORT_FEED_TAG]: { value, feed },
9
+ });
10
+ export const readPortFeedOverride = (raw) => {
11
+ if (!isPortFeedBox(raw)) {
12
+ return undefined;
13
+ }
14
+ return raw[PORT_FEED_TAG];
15
+ };
16
+ /** Inner value when tagged; otherwise `raw` unchanged. */
17
+ export const unwrapPortFeedValue = (raw) => {
18
+ const override = readPortFeedOverride(raw);
19
+ return override === undefined ? raw : override.value;
20
+ };
21
+ //# sourceMappingURL=port-feed-override.js.map
@@ -0,0 +1,15 @@
1
+ import { type ResponseDto } from '@rx-evo/stateful-observable';
2
+ import type { RuntimeFeedPortMeta } from './types.js';
3
+ export type PortEmission = {
4
+ readonly response: ResponseDto<unknown>;
5
+ readonly feed: RuntimeFeedPortMeta | undefined;
6
+ };
7
+ /**
8
+ * JSON-safe {@link ResponseDto} for `PortTelemetry` slot 3, plus per-emit feed.
9
+ */
10
+ export declare const toPortEmission: (response: unknown, defaultFeed: RuntimeFeedPortMeta | undefined) => PortEmission | null;
11
+ /** Drop sentinels and errors so edges only carry success values. */
12
+ export declare const isEdgeForwardable: (response: unknown) => boolean;
13
+ /** True when `raw$` is the inactive sentinel (unconnected / disconnected). */
14
+ export declare const isInactiveResponse: (response: unknown) => boolean;
15
+ //# sourceMappingURL=port-signal-from-response.d.ts.map
@@ -0,0 +1,48 @@
1
+ import { serializeResponse, } from '@rx-evo/stateful-observable';
2
+ import { normalizePortErrorValue } from './normalize-port-error-value.js';
3
+ import { readPortFeedOverride } from './port-feed-override.js';
4
+ const asResponse = (response) => response;
5
+ const toResponseDto = (response) => {
6
+ if (response === null || response === undefined) {
7
+ return null;
8
+ }
9
+ const dto = serializeResponse(asResponse(response));
10
+ if ('error' in dto) {
11
+ return { error: normalizePortErrorValue(dto.error) };
12
+ }
13
+ return dto;
14
+ };
15
+ /**
16
+ * JSON-safe {@link ResponseDto} for `PortTelemetry` slot 3, plus per-emit feed.
17
+ */
18
+ export const toPortEmission = (response, defaultFeed) => {
19
+ const dto = toResponseDto(response);
20
+ if (dto === null) {
21
+ return null;
22
+ }
23
+ if (!('value' in dto)) {
24
+ return { response: dto, feed: defaultFeed };
25
+ }
26
+ const override = readPortFeedOverride(dto.value);
27
+ if (override === undefined) {
28
+ return { response: dto, feed: defaultFeed };
29
+ }
30
+ return {
31
+ response: { value: override.value },
32
+ feed: override.feed,
33
+ };
34
+ };
35
+ /** Drop sentinels and errors so edges only carry success values. */
36
+ export const isEdgeForwardable = (response) => {
37
+ const dto = toResponseDto(response);
38
+ return dto !== null && 'value' in dto;
39
+ };
40
+ /** True when `raw$` is the inactive sentinel (unconnected / disconnected). */
41
+ export const isInactiveResponse = (response) => {
42
+ if (response === null || response === undefined) {
43
+ return true;
44
+ }
45
+ const dto = toResponseDto(response);
46
+ return dto !== null && 'inactive' in dto;
47
+ };
48
+ //# sourceMappingURL=port-signal-from-response.js.map
@@ -1,5 +1,5 @@
1
1
  import { GraphCluster } from './runtime-helpers.js';
2
- import { RuntimeEdge, RuntimeEditorApi, RuntimeNode, type EdgeId, type NodeId } from './types.js';
2
+ import { RuntimeEdge, RuntimeEditorApi, RuntimeNode, type EdgeId, type NodeId, type SwapNodeResult } from './types.js';
3
3
  export declare class RuntimeEditor implements RuntimeEditorApi {
4
4
  /** Node ID -> node definition. */
5
5
  private readonly nodes;
@@ -20,6 +20,10 @@ export declare class RuntimeEditor implements RuntimeEditorApi {
20
20
  * Composer: find occupying → prepare → swap → cleanup/rollback → refresh.
21
21
  */
22
22
  replaceEdge(edgeInput: Omit<RuntimeEdge, 'edgeId'>): RuntimeEdge | false;
23
+ /**
24
+ * Replace the live instance at `nodeId` with `next`. Allowed while locked.
25
+ */
26
+ swapNode(nodeId: NodeId, next: Omit<RuntimeNode, 'nodeId'>): SwapNodeResult | false;
23
27
  removeNode(nodeId: NodeId): RuntimeNode | false;
24
28
  removeEdge(edgeId: EdgeId): RuntimeNode[];
25
29
  getNode(nodeId: NodeId): RuntimeNode | false;
@@ -108,6 +108,25 @@ export class RuntimeEditor {
108
108
  this.refreshClusters();
109
109
  return occupying;
110
110
  }
111
+ /**
112
+ * Replace the live instance at `nodeId` with `next`. Allowed while locked.
113
+ */
114
+ swapNode(nodeId, next) {
115
+ if (this.disposed) {
116
+ return false;
117
+ }
118
+ if (!this.nodes.has(nodeId)) {
119
+ return false;
120
+ }
121
+ const runtimeNode = materializeBypassNodeOnAdd({
122
+ ...next,
123
+ nodeId,
124
+ });
125
+ this.nodes.set(nodeId, runtimeNode);
126
+ const droppedEdges = this.cleanupInvalidEdges();
127
+ this.refreshClusters();
128
+ return { node: runtimeNode, droppedEdges };
129
+ }
111
130
  removeNode(nodeId) {
112
131
  if (this.disposed) {
113
132
  return false;
@@ -9,6 +9,8 @@ export declare class RuntimeRunner implements RuntimeRunnerApi {
9
9
  private readonly logEvents;
10
10
  private readonly eventLogBuffer;
11
11
  private activeRun;
12
+ private pendingWireRunId;
13
+ private pendingWire;
12
14
  private disposed;
13
15
  readonly status$: Observable<RuntimeRunnerStatus>;
14
16
  /** Synchronous snapshot of {@link status$}. */
@@ -38,9 +40,9 @@ export declare class RuntimeRunner implements RuntimeRunnerApi {
38
40
  private pushIntoActiveRun;
39
41
  /**
40
42
  * Returns `output` wrapped with a `tap` that emits `output-emitted`
41
- * telemetry, then `filter(isEdgeForwardable)` so `ResponseError` and
42
- * loading sentinels stay visible to Observability on the source node but
43
- * are not forwarded on edges (loading must not appear as `{}` downstream).
43
+ * telemetry, then forward only success values on edges so errors and
44
+ * loading sentinels stay visible on the source node (loading must not
45
+ * appear as `{}` downstream).
44
46
  * The wrapper is the value the downstream connects to, so the event fires
45
47
  * *as part of* the dataflow delivery — there is no separate refCounted
46
48
  * subscriber, which is what previously reordered events against downstream
@@ -56,6 +58,9 @@ export declare class RuntimeRunner implements RuntimeRunnerApi {
56
58
  */
57
59
  private tapInputPort;
58
60
  private finishRun;
61
+ private assertResumeOutputSnapshots;
62
+ private cancelPendingWire;
63
+ private flushPendingWire;
59
64
  private runScope;
60
65
  private teardownRun;
61
66
  private applySeeds;
@@ -1,60 +1,24 @@
1
- import { combineStatefulObservables, isError, isInactive, isLoading, isSuccess, statefulObservable, } from '@rx-evo/stateful-observable';
1
+ import { combineStatefulObservables, serializeResponse, statefulObservable, } from '@rx-evo/stateful-observable';
2
2
  import { BehaviorSubject, filter, merge, of, Subject, Subscription, tap, zip, } from 'rxjs';
3
3
  import { checkpointPortIdForSlot, getBypassConnection, isBypassPort, } from './bypass-ports.js';
4
4
  import { normalizePortErrorValue } from './normalize-port-error-value.js';
5
5
  import { edgePortSlotKey, parseSlotKey, slotKey, } from './port-meta.js';
6
6
  import { clusterHasChatEntry, collectClusterSlotKeys, } from './runtime-helpers.js';
7
+ const toResponseDto = (response) => {
8
+ if (response === null || response === undefined) {
9
+ return null;
10
+ }
11
+ return serializeResponse(response);
12
+ };
7
13
  const isConnectionInactive = (connection) => {
8
14
  let inactive = true;
9
15
  const sub = connection.raw$.subscribe((raw) => {
10
- // Same dual-package Symbol hazard as loading (BUG-2026-07-23 /
11
- // ADR-028): CJS `isInactive` can miss an ESM inactive sentinel.
12
- inactive = isInactive(raw) || isSymbolStateSentinel(raw);
16
+ const dto = toResponseDto(raw);
17
+ inactive = dto === null || 'inactive' in dto;
13
18
  });
14
19
  sub.unsubscribe();
15
20
  return inactive;
16
21
  };
17
- /**
18
- * `@rx-evo` status sentinels are `{ state: Symbol(...) }` (loading / inactive).
19
- * When the sentinel is created by a different module instance than the
20
- * `isLoading` / `isInactive` guards (CJS/ESM dual-package hazard), identity
21
- * checks fail and `isSuccess` may return true — telemetry then emits
22
- * `state:'value'` with that object (JSON → `{}`), or `applyPortDefaults`
23
- * skips seeding and LLM `combineInputs` stalls.
24
- */
25
- const isSymbolStateSentinel = (signal) => {
26
- if (typeof signal !== 'object' ||
27
- signal === null ||
28
- Array.isArray(signal)) {
29
- return false;
30
- }
31
- const keys = Object.keys(signal);
32
- if (keys.length !== 1 || keys[0] !== 'state') {
33
- return false;
34
- }
35
- const state = signal.state;
36
- return typeof state === 'symbol';
37
- };
38
- const resolveSignalState = (response) => {
39
- const signal = response;
40
- if (isError(signal)) {
41
- return {
42
- state: 'error',
43
- value: normalizePortErrorValue(signal.error),
44
- };
45
- }
46
- if (isLoading(signal) || isSymbolStateSentinel(signal)) {
47
- return { state: 'pending', value: undefined };
48
- }
49
- if (isSuccess(signal)) {
50
- return { state: 'value', value: signal };
51
- }
52
- return null;
53
- };
54
- /** Drop errors and loading so edges only carry success values. */
55
- const isEdgeForwardable = (response) => !isError(response) &&
56
- !isLoading(response) &&
57
- !isSymbolStateSentinel(response);
58
22
  export class RuntimeRunner {
59
23
  editor;
60
24
  static EMPTY_EVENT_LOG = [];
@@ -63,6 +27,8 @@ export class RuntimeRunner {
63
27
  logEvents;
64
28
  eventLogBuffer = [];
65
29
  activeRun;
30
+ pendingWireRunId;
31
+ pendingWire;
66
32
  disposed = false;
67
33
  status$ = this.statusSubject.asObservable();
68
34
  /** Synchronous snapshot of {@link status$}. */
@@ -143,6 +109,7 @@ export class RuntimeRunner {
143
109
  this.finishRun(resolvedRunId);
144
110
  return resolvedRunId;
145
111
  }
112
+ this.assertResumeOutputSnapshots(completedNodeIds, outputSnapshots);
146
113
  return this.runScope(new Set(nodes.map((node) => node.nodeId)), new Set(edges.map((edge) => edge.edgeId)), options.initialPayload, resolvedRunId, {
147
114
  completedNodeIds,
148
115
  outputSnapshots,
@@ -169,6 +136,7 @@ export class RuntimeRunner {
169
136
  return false;
170
137
  }
171
138
  const runId = this.runScope(cluster.nodeIds, cluster.edgeIds);
139
+ this.flushPendingWire();
172
140
  const pushedRunId = this.pushIntoActiveRun(cfg);
173
141
  if (pushedRunId === false) {
174
142
  this.interrupt('cancel');
@@ -181,6 +149,7 @@ export class RuntimeRunner {
181
149
  if (this.statusSubject.value !== 'running') {
182
150
  return;
183
151
  }
152
+ this.cancelPendingWire();
184
153
  this.teardownRun();
185
154
  this.setStatus('stopped');
186
155
  }
@@ -206,6 +175,7 @@ export class RuntimeRunner {
206
175
  return;
207
176
  }
208
177
  if (this.statusSubject.value === 'running') {
178
+ this.cancelPendingWire();
209
179
  this.teardownRun();
210
180
  }
211
181
  this.disposed = true;
@@ -239,18 +209,26 @@ export class RuntimeRunner {
239
209
  }
240
210
  this.eventsSubject.next(event);
241
211
  }
242
- emitPortEvent(runId, kind, nodeId, portId, portIdx, state, value, edgeIds, feed) {
243
- this.emitRunnerEvent({
244
- kind,
245
- runId,
212
+ emitPortEvent(_runId, portDir, nodeId, portId, portIdx, raw, edgeIds, defaultFeed) {
213
+ const dto = toResponseDto(raw);
214
+ if (dto === null) {
215
+ return false;
216
+ }
217
+ const response = 'error' in dto
218
+ ? { error: normalizePortErrorValue(dto.error) }
219
+ : dto;
220
+ const feed = defaultFeed ?? null;
221
+ const portIdStr = typeof portId === 'string' ? portId : String(portId);
222
+ this.emitRunnerEvent([
223
+ portDir,
246
224
  nodeId,
247
- portId,
225
+ portIdStr,
226
+ response,
248
227
  portIdx,
249
228
  edgeIds,
250
- state,
251
- value,
252
- ...(feed !== undefined ? { feed } : {}),
253
- });
229
+ feed,
230
+ ]);
231
+ return 'value' in response;
254
232
  }
255
233
  canPreparePushedInput(node, portId) {
256
234
  const connection = node.inputs[portId];
@@ -268,6 +246,7 @@ export class RuntimeRunner {
268
246
  edge.toPort[1] === 0);
269
247
  }
270
248
  pushIntoActiveRun(cfg) {
249
+ this.flushPendingWire();
271
250
  const run = this.activeRun;
272
251
  if (run === undefined || !run.scopeNodeIds.has(cfg.nodeId)) {
273
252
  return false;
@@ -281,7 +260,7 @@ export class RuntimeRunner {
281
260
  if (existing !== undefined) {
282
261
  // Telemetry before deliver so HITL input-received precedes cascade
283
262
  // (output-emitted / downstream input-received) in the event log.
284
- this.emitPortEvent(run.runId, 'input-received', cfg.nodeId, cfg.portId, 0, 'value', cfg.payload, []);
263
+ this.emitPortEvent(run.runId, 'in', cfg.nodeId, cfg.portId, 0, cfg.payload, []);
285
264
  existing.source.next(cfg.payload);
286
265
  return run.runId;
287
266
  }
@@ -300,15 +279,15 @@ export class RuntimeRunner {
300
279
  connection,
301
280
  });
302
281
  run.pushedInputSources.set(key, { source });
303
- this.emitPortEvent(run.runId, 'input-received', cfg.nodeId, cfg.portId, 0, 'value', cfg.payload, []);
282
+ this.emitPortEvent(run.runId, 'in', cfg.nodeId, cfg.portId, 0, cfg.payload, []);
304
283
  source.next(cfg.payload);
305
284
  return run.runId;
306
285
  }
307
286
  /**
308
287
  * Returns `output` wrapped with a `tap` that emits `output-emitted`
309
- * telemetry, then `filter(isEdgeForwardable)` so `ResponseError` and
310
- * loading sentinels stay visible to Observability on the source node but
311
- * are not forwarded on edges (loading must not appear as `{}` downstream).
288
+ * telemetry, then forward only success values on edges so errors and
289
+ * loading sentinels stay visible on the source node (loading must not
290
+ * appear as `{}` downstream).
312
291
  * The wrapper is the value the downstream connects to, so the event fires
313
292
  * *as part of* the dataflow delivery — there is no separate refCounted
314
293
  * subscriber, which is what previously reordered events against downstream
@@ -322,12 +301,8 @@ export class RuntimeRunner {
322
301
  return output
323
302
  .pipe(tap({
324
303
  next: (response) => {
325
- const resolved = resolveSignalState(response);
326
- if (resolved === null) {
327
- return;
328
- }
329
- this.emitPortEvent(run.runId, 'output-emitted', nodeId, portId, 0, resolved.state, resolved.value, edgeIds, output.meta.feed);
330
- if (resolved.state === 'value' &&
304
+ const emittedValue = this.emitPortEvent(run.runId, 'out', nodeId, portId, 0, response, edgeIds, output.meta.feed);
305
+ if (emittedValue &&
331
306
  node !== false &&
332
307
  node.stopsRun === true) {
333
308
  const finishRunId = run.runId;
@@ -338,7 +313,10 @@ export class RuntimeRunner {
338
313
  });
339
314
  }
340
315
  },
341
- }), filter(isEdgeForwardable))
316
+ }), filter((response) => {
317
+ const dto = toResponseDto(response);
318
+ return dto !== null && 'value' in dto;
319
+ }))
342
320
  .with({ meta: output.meta });
343
321
  }
344
322
  /**
@@ -353,11 +331,7 @@ export class RuntimeRunner {
353
331
  return source
354
332
  .pipe(tap({
355
333
  next: (response) => {
356
- const resolved = resolveSignalState(response);
357
- if (resolved === null) {
358
- return;
359
- }
360
- this.emitPortEvent(run.runId, 'input-received', nodeId, portId, slotIndex, resolved.state, resolved.value, edgeIds);
334
+ this.emitPortEvent(run.runId, 'in', nodeId, portId, slotIndex, response, edgeIds);
361
335
  },
362
336
  }))
363
337
  .with({ meta: source.meta });
@@ -369,29 +343,80 @@ export class RuntimeRunner {
369
343
  if (this.activeRun !== undefined && this.activeRun.runId !== runId) {
370
344
  return;
371
345
  }
372
- this.emitRunnerEvent({ kind: 'done', runId });
346
+ this.emitRunnerEvent(['done', runId]);
373
347
  this.setStatus('idle');
374
348
  this.teardownRun();
375
349
  }
350
+ assertResumeOutputSnapshots(completedNodeIds, outputSnapshots) {
351
+ const nodesById = new Map(this.editor.getNodes().map((node) => [node.nodeId, node]));
352
+ for (const edge of this.editor.getEdges()) {
353
+ if (!completedNodeIds.has(edge.fromNodeId) ||
354
+ completedNodeIds.has(edge.toNodeId)) {
355
+ continue;
356
+ }
357
+ const fromNode = nodesById.get(edge.fromNodeId);
358
+ if (fromNode === undefined) {
359
+ continue;
360
+ }
361
+ const [fromPortId, fromSlotIndex] = edge.fromPort;
362
+ const snapshotPortId = checkpointPortIdForSlot(fromNode, fromPortId, fromSlotIndex);
363
+ const snapshotValue = outputSnapshots
364
+ .get(edge.fromNodeId)
365
+ ?.get(snapshotPortId);
366
+ if (snapshotValue === undefined) {
367
+ throw new Error(`Resume missing output snapshot for ${edge.fromNodeId}.${fromPortId}`);
368
+ }
369
+ }
370
+ }
371
+ cancelPendingWire() {
372
+ this.pendingWire = undefined;
373
+ this.pendingWireRunId = undefined;
374
+ }
375
+ flushPendingWire() {
376
+ const wire = this.pendingWire;
377
+ if (wire === undefined) {
378
+ return;
379
+ }
380
+ this.pendingWire = undefined;
381
+ this.pendingWireRunId = undefined;
382
+ wire();
383
+ }
376
384
  runScope(scopeNodeIds, scopeEdgeIds, initialPayload, runId, resumeOverlay) {
377
385
  this.assertNotDisposed();
378
386
  if (this.statusSubject.value === 'running') {
379
387
  return false;
380
388
  }
381
389
  const resolvedRunId = runId ?? crypto.randomUUID();
382
- this.editor.setLocked(true);
383
- try {
384
- this.activeRun = this.wireScope(resolvedRunId, scopeEdgeIds, scopeNodeIds, initialPayload, resumeOverlay);
385
- }
386
- catch (error) {
387
- this.editor.setLocked(false);
388
- throw error;
389
- }
390
390
  this.setStatus('running');
391
+ this.editor.setLocked(true);
392
+ this.pendingWireRunId = resolvedRunId;
393
+ this.pendingWire = () => {
394
+ try {
395
+ this.activeRun = this.wireScope(resolvedRunId, scopeEdgeIds, scopeNodeIds, initialPayload, resumeOverlay);
396
+ }
397
+ catch (error) {
398
+ this.editor.setLocked(false);
399
+ this.setStatus('idle');
400
+ throw error;
401
+ }
402
+ };
403
+ queueMicrotask(() => {
404
+ if (this.pendingWireRunId !== resolvedRunId) {
405
+ return;
406
+ }
407
+ try {
408
+ this.flushPendingWire();
409
+ }
410
+ catch {
411
+ // Status/lock already restored in pendingWire.
412
+ }
413
+ });
391
414
  return resolvedRunId;
392
415
  }
393
416
  teardownRun() {
417
+ this.cancelPendingWire();
394
418
  if (this.activeRun === undefined) {
419
+ this.editor.setLocked(false);
395
420
  return;
396
421
  }
397
422
  for (const wired of this.activeRun.wiredSlots) {
@@ -429,7 +454,7 @@ export class RuntimeRunner {
429
454
  connection.connect(of(seed.value).pipe(tap({
430
455
  next: (value) => {
431
456
  if (typeof seed.portId !== 'symbol') {
432
- this.emitPortEvent(runId, 'input-received', nodeId, seed.portId, seed.slotIndex, 'value', value, []);
457
+ this.emitPortEvent(runId, 'in', nodeId, seed.portId, seed.slotIndex, value, []);
433
458
  }
434
459
  },
435
460
  })));
@@ -467,7 +492,7 @@ export class RuntimeRunner {
467
492
  }
468
493
  connection.connect(of(defaultValue).pipe(tap({
469
494
  next: (value) => {
470
- this.emitPortEvent(runId, 'input-received', nodeId, portId, 0, 'value', value, []);
495
+ this.emitPortEvent(runId, 'in', nodeId, portId, 0, value, []);
471
496
  },
472
497
  })));
473
498
  wiredSlotKeys.add(key);
@@ -701,11 +726,7 @@ export class RuntimeRunner {
701
726
  }).with({ meta });
702
727
  group.connection.connect(combined.pipe(tap({
703
728
  next: (response) => {
704
- const resolved = resolveSignalState(response);
705
- if (resolved === null) {
706
- return;
707
- }
708
- this.emitPortEvent(run.runId, 'input-received', group.nodeId, group.portId, 0, resolved.state, resolved.value, group.edges.map((entry) => entry.edge.edgeId));
729
+ this.emitPortEvent(run.runId, 'in', group.nodeId, group.portId, 0, response, group.edges.map((entry) => entry.edge.edgeId));
709
730
  },
710
731
  })));
711
732
  wiredSlots.push({
@@ -6,8 +6,10 @@ export { RuntimeEditor } from './runtime-editor.js';
6
6
  export { graphHasCycle } from './runtime-helpers.js';
7
7
  export type { GraphCluster } from './runtime-helpers.js';
8
8
  export { RuntimeRunner } from './runtime-runner.js';
9
- export type { MetaFromStatefulObservable, NodeId, EdgeId, RunId, PortMeta, RuntimeEdge, RuntimeEditorApi, RuntimeFeedPortMeta, RuntimeFeedRole, RuntimeInputReceivedEvent, RuntimeNode, RuntimeOutputEmittedEvent, RuntimePortSignalState, RuntimeResumeOptions, RuntimeRunnerApi, RuntimeRunnerEvent, RuntimeRunnerStatus, RuntimeSeedPortValue, RuntimeWireType, } from './types.js';
9
+ export type { MetaFromStatefulObservable, NodeId, EdgeId, RunId, PortMeta, RuntimeEdge, RuntimeEditorApi, RuntimeFeedPortMeta, RuntimeFeedRole, PortTelemetry, RuntimeDoneTelemetry, RuntimeNode, RuntimeResumeOptions, RuntimeRunnerApi, RuntimeRunnerEvent, RuntimeRunnerStatus, RuntimeSeedPortValue, RuntimeWireType, SwapNodeResult, } from './types.js';
10
+ export { isPortErrorTelemetry, isPortPendingTelemetry, isPortTelemetry, isPortValueTelemetry, isRuntimeDone, } from './types.js';
10
11
  export type { RuntimeOptions };
12
+ export type { ResponseDto } from '@rx-evo/stateful-observable';
11
13
  export declare class RuntimeFacade {
12
14
  readonly editor: RuntimeEditor;
13
15
  readonly runner: RuntimeRunner;