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
@@ -0,0 +1,227 @@
1
+ import { filter, map, Observable } from 'rxjs';
2
+ import { defineLlmNode, isSteerControlPayload, toLlmRecoveryPortValue, } from '@langflower/node-sdk/llm';
3
+ import { collectAgentToolHandles } from '../../../tools/collect-agent-tool-handles.js';
4
+ import { buildEffectiveSystemPrompt } from '../../features/prompt/build-effective-system-prompt.js';
5
+ import { resolveChatProviderModel } from '../../features/prompt/resolve-chat-provider-model.js';
6
+ import { createLlmSessionCycle$, demuxByKind, normalizeMaxFeedbackTurns, } from '../../features/llm-session/llm-session-shell.js';
7
+ import { llmCompactionUiSchema } from '../../features/ui-schema/llm-compaction-ui-schema.js';
8
+ import { llmRecoveryUiSchema } from '../../features/ui-schema/llm-recovery-ui-schema.js';
9
+ import { llmMaxIterationsUiField, llmPanelUiSchema, } from '../../features/ui-schema/llm-panel-ui-schema.js';
10
+ import { parseLlmRolePreset, resolveEffectiveSkillId, } from '../../features/llm-role-preset.js';
11
+ import { DEFAULT_PATH_CHOICE_MAX_ITERATIONS, PATH_CHOICE_MAX_ITERATIONS_CAP, normalizeMaxIterations, } from '../../features/prompt/normalize-max-iterations.js';
12
+ import { normalizeLlmRecoveryPolicy } from '../../features/llm-loop/normalize-llm-recovery-policy.js';
13
+ import { normalizeCompactionConfig } from '../../features/openai/normalize-compaction-params.js';
14
+ import { REVIEW_ACCEPT_TOOL, REVIEW_FEEDBACK_TOOL, } from '../../features/path-choice/control-tools.js';
15
+ import { runPathChoiceToolLoop, } from '../../features/path-choice/run-reactive-path-choice-loop.js';
16
+ import { getRunHostServices } from '../../features/run-host-services.js';
17
+ const FORCED_TOOL_SYSTEM = [
18
+ 'You are a strict Review node.',
19
+ `Finish by calling exactly one control tool: ${REVIEW_ACCEPT_TOOL} or ${REVIEW_FEEDBACK_TOOL}.`,
20
+ 'You may call optional inventory tools first when they help verify the artifact.',
21
+ 'Do not write free-form accept/reject essays.',
22
+ `Call ${REVIEW_ACCEPT_TOOL} when the result meets the task criteria.`,
23
+ `Call ${REVIEW_FEEDBACK_TOOL} with revision notes when it does not.`,
24
+ ].join(' ');
25
+ const requireChatConfig = (providerId, model) => {
26
+ if (providerId.trim().length === 0) {
27
+ throw new Error('Provider is required for Review chat');
28
+ }
29
+ if (model.trim().length === 0) {
30
+ throw new Error('Model is required for Review chat');
31
+ }
32
+ };
33
+ const buildEffectiveReviewSystem = (input) => {
34
+ const merged = buildEffectiveSystemPrompt(input);
35
+ const parts = [FORCED_TOOL_SYSTEM];
36
+ if (merged.trim().length > 0) {
37
+ parts.push(merged);
38
+ }
39
+ return parts.join('\n\n---\n\n');
40
+ };
41
+ const buildUserContent = (task, result) => [
42
+ '## Task / criteria',
43
+ task.trim().length > 0 ? task : '(empty task)',
44
+ '',
45
+ '## Result under review',
46
+ result.trim().length > 0 ? result : '(empty result)',
47
+ ].join('\n');
48
+ const buildRevisedResultUserContent = (result) => [
49
+ '## Revised result under review',
50
+ result.trim().length > 0 ? result : '(empty result)',
51
+ ].join('\n');
52
+ const hasUserMessage = (history) => history.some((message) => message.role === 'user');
53
+ const runReviewTurn = (context, result, history) => {
54
+ const factory = context.factory;
55
+ if (factory === undefined) {
56
+ return new Observable((subscriber) => {
57
+ subscriber.error(new Error('Review chat is only available during server workflow runs'));
58
+ });
59
+ }
60
+ requireChatConfig(context.providerId, context.model);
61
+ const userContent = hasUserMessage(history)
62
+ ? buildRevisedResultUserContent(result)
63
+ : buildUserContent(context.task, result);
64
+ const messages = [
65
+ ...history,
66
+ { role: 'user', content: userContent },
67
+ ];
68
+ return runPathChoiceToolLoop({
69
+ factory,
70
+ providerId: context.providerId,
71
+ model: context.model,
72
+ messages,
73
+ maxIterations: context.maxIterations,
74
+ tools: context.tools,
75
+ compaction: context.compaction,
76
+ recovery: context.recovery,
77
+ steerControl$: context.steerControl$,
78
+ toolCtx: context.toolCtx,
79
+ }).pipe(map((chunk) => {
80
+ if (chunk.kind === 'accept') {
81
+ return {
82
+ kind: 'accept',
83
+ notes: chunk.notes,
84
+ result,
85
+ };
86
+ }
87
+ return chunk;
88
+ }));
89
+ };
90
+ /**
91
+ * Dedicated Review node: path choice via **Review-private** control tools
92
+ * (`accept` / `feedback` in `path-choice/control-tools.ts`). Those chat tools are
93
+ * ephemeral on completion calls only — they must not leak into shared
94
+ * inventory / other LLM nodes. Tool payloads demux to `response` / `feedback`
95
+ * ports; free-form replies get a reminder. Optional inventory / MCP /
96
+ * Sub-Agents use shared LLM inventory ports.
97
+ *
98
+ * Session history uses the shared {@link createLlmSessionCycle$} (ADR-016):
99
+ * init = task / system / inventory; turn driver = `result`.
100
+ * @see docs/DONE/EPICS/03-review-node.md
101
+ * @see docs/DONE/EPICS/MECHANICS-tool-execution.md
102
+ */
103
+ export const reviewNode = defineLlmNode({
104
+ type: 'common-review',
105
+ displayName: 'Review',
106
+ category: 'AI',
107
+ description: 'Forced-tool Review: finish with accept or feedback (requires a model with native tool / function calling — prose or markdown tool_code will not route). Optional wired tools / MCP / Sub-Agents may run via harness first.',
108
+ uiSchema: [
109
+ ...llmPanelUiSchema.filter((item) => item.field !== 'maxIterations'),
110
+ llmMaxIterationsUiField(DEFAULT_PATH_CHOICE_MAX_ITERATIONS, PATH_CHOICE_MAX_ITERATIONS_CAP),
111
+ ...llmCompactionUiSchema,
112
+ ...llmRecoveryUiSchema,
113
+ ],
114
+ bind(ctx, { makeInput, configureOutput, combineInputs }, inventory) {
115
+ const { tools, steerControl } = inventory;
116
+ const task = makeInput('task', {
117
+ name: 'task',
118
+ wireType: 'string',
119
+ inline: 'text-multiline',
120
+ required: true,
121
+ });
122
+ const result = makeInput('result', {
123
+ name: 'result',
124
+ wireType: 'string',
125
+ inline: 'text-multiline',
126
+ required: true,
127
+ });
128
+ const systemPrompt = makeInput('systemPrompt', {
129
+ name: 'systemPrompt',
130
+ wireType: 'string',
131
+ inline: 'text-multiline',
132
+ defaultValue: '',
133
+ });
134
+ // Init peers only — result is the session turn driver (ADR-016).
135
+ const context$ = combineInputs([task, systemPrompt, tools, ctx], ([taskValue, systemPromptValue, toolList, ec]) => {
136
+ const rolePreset = parseLlmRolePreset(ec.params.rolePreset);
137
+ const skillId = resolveEffectiveSkillId(rolePreset, ec.params.skillId);
138
+ const hostServices = getRunHostServices(ec);
139
+ const skillMarkdown = hostServices?.skillMarkdown ?? '';
140
+ const agentsMarkdown = hostServices?.agentsMarkdown ?? '';
141
+ return {
142
+ task: String(taskValue ?? ''),
143
+ ...resolveChatProviderModel(ec.params, hostServices),
144
+ skillId,
145
+ skillMarkdown,
146
+ effectiveSystemPrompt: buildEffectiveReviewSystem({
147
+ rolePreset,
148
+ systemPromptInput: String(systemPromptValue ?? ''),
149
+ agentsMarkdown,
150
+ skillMarkdown,
151
+ }),
152
+ factory: hostServices?.createChatCompletionStream,
153
+ maxIterations: normalizeMaxIterations(ec.params.maxIterations, {
154
+ fallback: DEFAULT_PATH_CHOICE_MAX_ITERATIONS,
155
+ maxCap: PATH_CHOICE_MAX_ITERATIONS_CAP,
156
+ }),
157
+ maxFeedbackTurns: normalizeMaxFeedbackTurns(ec.params.maxFeedbackTurns),
158
+ ...(hostServices?.requestPermission !== undefined
159
+ ? { requestPermission: hostServices.requestPermission }
160
+ : {}),
161
+ compaction: normalizeCompactionConfig(ec.params),
162
+ recovery: normalizeLlmRecoveryPolicy(ec.params),
163
+ steerControl$: steerControl.value$.pipe(filter(isSteerControlPayload)),
164
+ tools: collectAgentToolHandles({
165
+ toolHandles: ec.toolHandles,
166
+ toolsPort: toolList,
167
+ }),
168
+ toolCtx: {
169
+ projectDir: ec.projectDir,
170
+ runId: ec.runId,
171
+ ...(hostServices?.authorize !== undefined
172
+ ? { authorize: hostServices.authorize }
173
+ : {}),
174
+ ...(hostServices?.denyPaths !== undefined
175
+ ? { denyPaths: hostServices.denyPaths }
176
+ : {}),
177
+ ...(hostServices?.allowedHosts !== undefined
178
+ ? { allowedHosts: hostServices.allowedHosts }
179
+ : {}),
180
+ },
181
+ };
182
+ });
183
+ const cycle$ = createLlmSessionCycle$(context$, result.value$, (context) => ({
184
+ history: [
185
+ {
186
+ role: 'system',
187
+ content: context.effectiveSystemPrompt,
188
+ },
189
+ ],
190
+ trackAssistantHistory: false,
191
+ appendUserFeedbackToHistory: false,
192
+ session: undefined,
193
+ }), (context, turnPayload, history) => runReviewTurn(context, String(turnPayload ?? ''), history), { primeTurn0: false });
194
+ const reasoning$ = cycle$.pipeValue(demuxByKind('reasoning', (chunk) => chunk.text));
195
+ const draftResponse$ = cycle$.pipeValue(demuxByKind('draftResponse', (chunk) => chunk
196
+ .text));
197
+ const toolLog$ = cycle$.pipeValue(demuxByKind('toolLog', (chunk) => chunk.text));
198
+ const recovery$ = cycle$.pipeValue(demuxByKind('recoveryNotice', (chunk) => {
199
+ const notice = chunk;
200
+ return toLlmRecoveryPortValue(notice);
201
+ }));
202
+ const response$ = cycle$.pipeValue(demuxByKind('accept', (chunk) => chunk.result));
203
+ const feedback$ = cycle$.pipeValue(demuxByKind('feedback', (chunk) => chunk.notes));
204
+ return {
205
+ inputs: [task, result, systemPrompt],
206
+ outputs: [
207
+ configureOutput('reasoning', reasoning$, {
208
+ wireType: 'string',
209
+ feed: { role: 'reasoning', streaming: true },
210
+ }),
211
+ configureOutput('draftResponse', draftResponse$, {
212
+ wireType: 'string',
213
+ feed: { role: 'draft', streaming: true },
214
+ }),
215
+ configureOutput('response', response$, {
216
+ wireType: 'string',
217
+ feed: { role: 'result' },
218
+ }),
219
+ configureOutput('feedback', feedback$, {
220
+ wireType: 'string',
221
+ feed: { role: 'result' },
222
+ }),
223
+ ],
224
+ inventoryOutputs: { toolLog$, recovery$ },
225
+ };
226
+ },
227
+ });