langflower 0.0.7 → 0.0.9

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 (189) hide show
  1. package/package.json +1 -1
  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 +1 -1
  5. package/ui-dist/main-2JJGCNTD.js +313 -0
  6. package/vendor/common-nodes/dist/ai/chat-completion-stream.d.ts +2 -0
  7. package/vendor/common-nodes/dist/ai/critique/node.d.ts +246 -0
  8. package/vendor/common-nodes/dist/ai/critique/node.js +2 -2
  9. package/vendor/common-nodes/dist/ai/fake-llm/node.d.ts +246 -0
  10. package/vendor/common-nodes/dist/ai/features/chat-completion-stream.d.ts +53 -0
  11. package/vendor/common-nodes/dist/ai/features/chat-completion-stream.js +1 -0
  12. package/vendor/common-nodes/dist/ai/features/llm-loop/autokick-recovery.d.ts +13 -0
  13. package/vendor/common-nodes/dist/ai/features/llm-loop/autokick-recovery.js +17 -0
  14. package/vendor/common-nodes/dist/ai/features/llm-loop/classify-llm-failure.d.ts +2 -0
  15. package/vendor/common-nodes/dist/ai/features/llm-loop/classify-llm-failure.js +113 -0
  16. package/vendor/common-nodes/dist/ai/features/llm-loop/dead-loop-detector.d.ts +28 -0
  17. package/vendor/common-nodes/dist/ai/features/llm-loop/dead-loop-detector.js +194 -0
  18. package/vendor/common-nodes/dist/ai/features/llm-loop/live-get-tools.d.ts +9 -0
  19. package/vendor/common-nodes/dist/ai/features/llm-loop/live-get-tools.js +21 -0
  20. package/vendor/common-nodes/dist/ai/features/llm-loop/llm-loop-reducer.d.ts +2 -0
  21. package/vendor/common-nodes/dist/ai/features/llm-loop/llm-loop-reducer.js +216 -0
  22. package/vendor/common-nodes/dist/ai/features/llm-loop/llm-loop-types.d.ts +125 -0
  23. package/vendor/common-nodes/dist/ai/features/llm-loop/llm-loop-types.js +39 -0
  24. package/vendor/common-nodes/dist/ai/features/llm-loop/normalize-llm-recovery-policy.d.ts +2 -0
  25. package/vendor/common-nodes/dist/ai/features/llm-loop/normalize-llm-recovery-policy.js +59 -0
  26. package/vendor/common-nodes/dist/ai/features/llm-loop/operators/normalize-tool-result.d.ts +1 -0
  27. package/vendor/common-nodes/dist/ai/features/llm-loop/operators/normalize-tool-result.js +7 -0
  28. package/vendor/common-nodes/dist/ai/features/llm-loop/operators/observe-provider-stream.d.ts +43 -0
  29. package/vendor/common-nodes/dist/ai/features/llm-loop/operators/observe-provider-stream.js +96 -0
  30. package/vendor/common-nodes/dist/ai/features/llm-loop/run-agent-loop.d.ts +32 -0
  31. package/vendor/common-nodes/dist/ai/features/llm-loop/run-agent-loop.js +58 -0
  32. package/vendor/common-nodes/dist/ai/features/llm-loop/run-llm-loop.d.ts +80 -0
  33. package/vendor/common-nodes/dist/ai/features/llm-loop/run-llm-loop.js +681 -0
  34. package/vendor/common-nodes/dist/ai/features/llm-role-preset.d.ts +69 -0
  35. package/vendor/common-nodes/dist/ai/features/llm-role-preset.js +265 -0
  36. package/vendor/common-nodes/dist/ai/features/llm-session/llm-session-shell.d.ts +148 -0
  37. package/vendor/common-nodes/dist/ai/features/llm-session/llm-session-shell.js +198 -0
  38. package/vendor/common-nodes/dist/ai/features/llm-session/run-session-machine.d.ts +21 -0
  39. package/vendor/common-nodes/dist/ai/features/llm-session/run-session-machine.js +118 -0
  40. package/vendor/common-nodes/dist/ai/features/openai/context-length-error.d.ts +14 -0
  41. package/vendor/common-nodes/dist/ai/features/openai/context-length-error.js +63 -0
  42. package/vendor/common-nodes/dist/ai/features/openai/create-chat-completion-stream.d.ts +19 -0
  43. package/vendor/common-nodes/dist/ai/features/openai/create-chat-completion-stream.js +182 -0
  44. package/vendor/common-nodes/dist/ai/features/openai/list-provider-models.d.ts +28 -0
  45. package/vendor/common-nodes/dist/ai/features/openai/list-provider-models.js +52 -0
  46. package/vendor/common-nodes/dist/ai/features/openai/llm-context-compaction.d.ts +31 -0
  47. package/vendor/common-nodes/dist/ai/features/openai/llm-context-compaction.js +326 -0
  48. package/vendor/common-nodes/dist/ai/features/openai/normalize-compaction-params.d.ts +14 -0
  49. package/vendor/common-nodes/dist/ai/features/openai/normalize-compaction-params.js +21 -0
  50. package/vendor/common-nodes/dist/ai/features/openai/prepare-chat-completion.d.ts +30 -0
  51. package/vendor/common-nodes/dist/ai/features/openai/prepare-chat-completion.js +132 -0
  52. package/vendor/common-nodes/dist/ai/features/path-choice/control-tools.d.ts +20 -0
  53. package/vendor/common-nodes/dist/ai/features/path-choice/control-tools.js +70 -0
  54. package/vendor/common-nodes/dist/ai/features/path-choice/run-reactive-path-choice-loop.d.ts +35 -0
  55. package/vendor/common-nodes/dist/ai/features/path-choice/run-reactive-path-choice-loop.js +106 -0
  56. package/vendor/common-nodes/dist/ai/features/prompt/build-effective-system-prompt.d.ts +9 -0
  57. package/vendor/common-nodes/dist/ai/features/prompt/build-effective-system-prompt.js +21 -0
  58. package/vendor/common-nodes/dist/ai/features/prompt/normalize-max-iterations.d.ts +13 -0
  59. package/vendor/common-nodes/dist/ai/features/prompt/normalize-max-iterations.js +23 -0
  60. package/vendor/common-nodes/dist/ai/features/prompt/resolve-chat-provider-model.d.ts +10 -0
  61. package/vendor/common-nodes/dist/ai/features/prompt/resolve-chat-provider-model.js +8 -0
  62. package/vendor/common-nodes/dist/ai/features/run-host-services.d.ts +54 -0
  63. package/vendor/common-nodes/dist/ai/features/run-host-services.js +29 -0
  64. package/vendor/common-nodes/dist/ai/features/scripted-chat-completion-stream.d.ts +17 -0
  65. package/vendor/common-nodes/dist/ai/features/scripted-chat-completion-stream.js +61 -0
  66. package/vendor/common-nodes/dist/ai/features/sub-agent-protocol.d.ts +39 -0
  67. package/vendor/common-nodes/dist/ai/features/sub-agent-protocol.js +43 -0
  68. package/vendor/common-nodes/dist/ai/features/ui-schema/llm-compaction-ui-schema.d.ts +14 -0
  69. package/vendor/common-nodes/dist/ai/features/ui-schema/llm-compaction-ui-schema.js +18 -0
  70. package/vendor/common-nodes/dist/ai/features/ui-schema/llm-panel-ui-schema.d.ts +80 -0
  71. package/vendor/common-nodes/dist/ai/features/ui-schema/llm-panel-ui-schema.js +76 -0
  72. package/vendor/common-nodes/dist/ai/features/ui-schema/llm-recovery-ui-schema.d.ts +113 -0
  73. package/vendor/common-nodes/dist/ai/features/ui-schema/llm-recovery-ui-schema.js +131 -0
  74. package/vendor/common-nodes/dist/ai/features/wait-for-subagent-result.d.ts +6 -0
  75. package/vendor/common-nodes/dist/ai/features/wait-for-subagent-result.js +30 -0
  76. package/vendor/common-nodes/dist/ai/llm-loop/autokick-recovery.d.ts +13 -0
  77. package/vendor/common-nodes/dist/ai/llm-loop/autokick-recovery.js +17 -0
  78. package/vendor/common-nodes/dist/ai/llm-loop/dead-loop-detector.d.ts +28 -0
  79. package/vendor/common-nodes/dist/ai/llm-loop/dead-loop-detector.js +194 -0
  80. package/vendor/common-nodes/dist/ai/llm-loop/llm-loop-reducer.js +36 -0
  81. package/vendor/common-nodes/dist/ai/llm-loop/llm-loop-types.d.ts +35 -0
  82. package/vendor/common-nodes/dist/ai/llm-loop/llm-loop-types.js +19 -0
  83. package/vendor/common-nodes/dist/ai/llm-loop/normalize-llm-recovery-policy.js +52 -9
  84. package/vendor/common-nodes/dist/ai/llm-loop/operators/observe-provider-stream.d.ts +8 -2
  85. package/vendor/common-nodes/dist/ai/llm-loop/operators/observe-provider-stream.js +43 -13
  86. package/vendor/common-nodes/dist/ai/llm-loop/run-llm-loop.d.ts +3 -5
  87. package/vendor/common-nodes/dist/ai/llm-loop/run-llm-loop.js +116 -1
  88. package/vendor/common-nodes/dist/ai/llm-recovery-ui-schema.d.ts +82 -0
  89. package/vendor/common-nodes/dist/ai/llm-recovery-ui-schema.js +95 -0
  90. package/vendor/common-nodes/dist/ai/llm-session-shell.d.ts +4 -9
  91. package/vendor/common-nodes/dist/ai/llm-session-shell.js +2 -4
  92. package/vendor/common-nodes/dist/ai/nodes/critique/node.d.ts +588 -0
  93. package/vendor/common-nodes/dist/ai/nodes/critique/node.js +240 -0
  94. package/vendor/common-nodes/dist/ai/nodes/fake-llm/node.d.ts +571 -0
  95. package/vendor/common-nodes/dist/ai/nodes/fake-llm/node.js +208 -0
  96. package/vendor/common-nodes/dist/ai/nodes/openai-llm/node.d.ts +587 -0
  97. package/vendor/common-nodes/dist/ai/nodes/openai-llm/node.js +91 -0
  98. package/vendor/common-nodes/dist/ai/nodes/review/node.d.ts +593 -0
  99. package/vendor/common-nodes/dist/ai/nodes/review/node.js +240 -0
  100. package/vendor/common-nodes/dist/ai/nodes/sub-agent/node.d.ts +630 -0
  101. package/vendor/common-nodes/dist/ai/nodes/sub-agent/node.js +302 -0
  102. package/vendor/common-nodes/dist/ai/openai/create-chat-completion-stream.js +6 -0
  103. package/vendor/common-nodes/dist/ai/openai/prepare-chat-completion.d.ts +2 -0
  104. package/vendor/common-nodes/dist/ai/openai/prepare-chat-completion.js +18 -0
  105. package/vendor/common-nodes/dist/ai/openai-llm/node.d.ts +246 -0
  106. package/vendor/common-nodes/dist/ai/review/node.d.ts +246 -0
  107. package/vendor/common-nodes/dist/ai/review/node.js +2 -2
  108. package/vendor/common-nodes/dist/ai/sub-agent/node.d.ts +246 -0
  109. package/vendor/common-nodes/dist/ai/sub-agent/node.js +2 -2
  110. package/vendor/common-nodes/dist/catalog.js +7 -5
  111. package/vendor/common-nodes/dist/compile-custom-nodes/node.d.ts +21 -0
  112. package/vendor/common-nodes/dist/compile-custom-nodes/node.js +45 -0
  113. package/vendor/common-nodes/dist/crawl/crawl/node.js +1 -1
  114. package/vendor/common-nodes/dist/crawl/fetch-url/node.js +1 -1
  115. package/vendor/common-nodes/dist/flow/repeat/node.js +6 -1
  116. package/vendor/common-nodes/dist/langflower-tools/emit-registration-tools.d.ts +18 -0
  117. package/vendor/common-nodes/dist/langflower-tools/emit-registration-tools.js +29 -0
  118. package/vendor/common-nodes/dist/langflower-tools/node.d.ts +20 -0
  119. package/vendor/common-nodes/dist/langflower-tools/node.js +77 -0
  120. package/vendor/common-nodes/dist/text/append-file/node.js +1 -1
  121. package/vendor/common-nodes/dist/text/read-file/node.js +1 -1
  122. package/vendor/common-nodes/dist/text/write-file/node.js +1 -1
  123. package/vendor/common-nodes/dist/tools/inventory-tool-round.d.ts +2 -2
  124. package/vendor/common-nodes/package.json +10 -10
  125. package/vendor/compiler/dist/compile-project-nodes.d.ts +2 -1
  126. package/vendor/compiler/dist/compile-project-nodes.js +35 -6
  127. package/vendor/compiler/dist/resolve-host-types.d.ts +0 -5
  128. package/vendor/compiler/dist/resolve-host-types.js +0 -8
  129. package/vendor/node-sdk/dist/node-factory/define-llm-node/define-llm-node.d.ts +1 -1
  130. package/vendor/node-sdk/dist/node-factory/define-llm-node/define-llm-node.js +1 -1
  131. package/vendor/node-sdk/dist/node-factory/define-llm-node/recovery-notice.d.ts +8 -0
  132. package/vendor/node-sdk/dist/node-factory/define-llm-node/recovery-notice.js +14 -0
  133. package/vendor/runtime/dist/runtime-editor.d.ts +5 -1
  134. package/vendor/runtime/dist/runtime-editor.js +19 -0
  135. package/vendor/runtime/dist/runtime-runner.js +17 -17
  136. package/vendor/runtime/dist/runtime.d.ts +2 -1
  137. package/vendor/runtime/dist/runtime.js +1 -0
  138. package/vendor/runtime/dist/testing/workflows/workflow-events.d.ts +8 -6
  139. package/vendor/runtime/dist/testing/workflows/workflow-events.js +19 -31
  140. package/vendor/runtime/dist/types.d.ts +33 -38
  141. package/vendor/runtime/dist/types.js +2 -1
  142. package/vendor/server/dist/bridge/attach-langflower-bridge.js +3 -2
  143. package/vendor/server/dist/bridge/bridge-event-log.js +17 -102
  144. package/vendor/server/dist/bridge/build-execution-context.d.ts +5 -2
  145. package/vendor/server/dist/bridge/build-execution-context.js +45 -5
  146. package/vendor/server/dist/bridge/forward-runner-event.d.ts +1 -1
  147. package/vendor/server/dist/bridge/forward-runner-event.js +7 -12
  148. package/vendor/server/dist/bridge/get-live-wired-tools.d.ts +12 -0
  149. package/vendor/server/dist/bridge/get-live-wired-tools.js +80 -0
  150. package/vendor/server/dist/bridge/langflower-tools-rpc.d.ts +7 -0
  151. package/vendor/server/dist/bridge/langflower-tools-rpc.js +29 -0
  152. package/vendor/server/dist/bridge/settings-draft-controller.js +26 -3
  153. package/vendor/server/dist/bridge/wire-custom-palette-handlers.d.ts +2 -1
  154. package/vendor/server/dist/bridge/wire-custom-palette-handlers.js +3 -5
  155. package/vendor/server/dist/bridge/wire-runner-handlers.js +15 -8
  156. package/vendor/server/dist/checkpoint/run-checkpoint-session.d.ts +1 -1
  157. package/vendor/server/dist/checkpoint/run-checkpoint-session.js +10 -9
  158. package/vendor/server/dist/palette/compile-and-hot-swap-custom-nodes.d.ts +10 -0
  159. package/vendor/server/dist/palette/compile-and-hot-swap-custom-nodes.js +23 -0
  160. package/vendor/server/dist/workflow/apply-editor-mutation.d.ts +5 -0
  161. package/vendor/server/dist/workflow/apply-editor-mutation.js +32 -0
  162. package/vendor/server/skeleton/instructions.md +9 -5
  163. package/vendor/server/skeleton/nodes/my-nodes/README.md +4 -3
  164. package/vendor/server/skeleton/schemas/langflower-config.schema.json +11 -1
  165. package/vendor/server/skeleton/skills/langflower-helper/SKILL.md +49 -19
  166. package/vendor/server/skeleton/skills/langflower-helper/architecture.md +22 -9
  167. package/vendor/server/skeleton/skills/langflower-helper/layout.md +15 -15
  168. package/vendor/server/skeleton/skills/langflower-node-writer/SKILL.md +19 -9
  169. package/vendor/server/skeleton/skills/langflower-workflow-writer/SKILL.md +14 -10
  170. package/vendor/server/skeleton/workflows/starter.json +30 -3
  171. package/vendor/shared/dist/execution/derive-run-settle-outcome.d.ts +1 -1
  172. package/vendor/shared/dist/execution/derive-run-settle-outcome.js +4 -3
  173. package/vendor/shared/dist/execution/derive-run-settle-outcome.test.js +9 -9
  174. package/vendor/shared/dist/langflower-bus-config.d.ts +6 -14
  175. package/vendor/shared/dist/langflower-bus-config.js +4 -12
  176. package/vendor/shared/dist/langflower-config/resolve-wired-tool-options.js +6 -0
  177. package/vendor/shared/dist/langflower-config/resolve-wired-tool-options.test.js +30 -0
  178. package/vendor/shared/dist/langflower-ws-waits.d.ts +7 -14
  179. package/vendor/shared/dist/langflower-ws-waits.js +14 -14
  180. package/vendor/websocket-bridge/dist/bridge-codec.d.ts +1 -0
  181. package/vendor/websocket-bridge/dist/bridge-codec.js +11 -11
  182. package/vendor/websocket-bridge/dist/bridge-frame.js +1 -1
  183. package/vendor/websocket-bridge/dist/bridge-subjects.d.ts +1 -1
  184. package/vendor/websocket-bridge/dist/bridge-subjects.js +2 -2
  185. package/vendor/websocket-bridge/dist/bridge-types.d.ts +13 -1
  186. package/vendor/websocket-bridge/dist/create-client.js +3 -3
  187. package/vendor/websocket-bridge/dist/create-server.js +12 -6
  188. package/vendor/websocket-bridge/package.json +8 -0
  189. package/ui-dist/main-SMO3L7U5.js +0 -311
@@ -0,0 +1,240 @@
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 { flattenSubAgentRegistrations, } from '../../features/sub-agent-protocol.js';
15
+ import { waitForSubagentResult } from '../../features/wait-for-subagent-result.js';
16
+ import { REVIEW_ACCEPT_TOOL, REVIEW_FEEDBACK_TOOL, } from '../../features/path-choice/control-tools.js';
17
+ import { runPathChoiceToolLoop, } from '../../features/path-choice/run-reactive-path-choice-loop.js';
18
+ import { getRunHostServices } from '../../features/run-host-services.js';
19
+ const FORCED_TOOL_SYSTEM = [
20
+ 'You are a strict Review node.',
21
+ `Finish by calling exactly one control tool: ${REVIEW_ACCEPT_TOOL} or ${REVIEW_FEEDBACK_TOOL}.`,
22
+ 'You may call optional inventory tools first when they help verify the artifact.',
23
+ 'Do not write free-form accept/reject essays.',
24
+ `Call ${REVIEW_ACCEPT_TOOL} when the result meets the task criteria.`,
25
+ `Call ${REVIEW_FEEDBACK_TOOL} with revision notes when it does not.`,
26
+ ].join(' ');
27
+ const requireChatConfig = (providerId, model) => {
28
+ if (providerId.trim().length === 0) {
29
+ throw new Error('Provider is required for Review chat');
30
+ }
31
+ if (model.trim().length === 0) {
32
+ throw new Error('Model is required for Review chat');
33
+ }
34
+ };
35
+ const buildEffectiveReviewSystem = (input) => {
36
+ const merged = buildEffectiveSystemPrompt(input);
37
+ const parts = [FORCED_TOOL_SYSTEM];
38
+ if (merged.trim().length > 0) {
39
+ parts.push(merged);
40
+ }
41
+ return parts.join('\n\n---\n\n');
42
+ };
43
+ const buildUserContent = (task, result) => [
44
+ '## Task / criteria',
45
+ task.trim().length > 0 ? task : '(empty task)',
46
+ '',
47
+ '## Result under review',
48
+ result.trim().length > 0 ? result : '(empty result)',
49
+ ].join('\n');
50
+ const buildRevisedResultUserContent = (result) => [
51
+ '## Revised result under review',
52
+ result.trim().length > 0 ? result : '(empty result)',
53
+ ].join('\n');
54
+ const hasUserMessage = (history) => history.some((message) => message.role === 'user');
55
+ const runReviewTurn = (context, result, history, subagentResult$) => {
56
+ const factory = context.factory;
57
+ if (factory === undefined) {
58
+ return new Observable((subscriber) => {
59
+ subscriber.error(new Error('Review chat is only available during server workflow runs'));
60
+ });
61
+ }
62
+ requireChatConfig(context.providerId, context.model);
63
+ const userContent = hasUserMessage(history)
64
+ ? buildRevisedResultUserContent(result)
65
+ : buildUserContent(context.task, result);
66
+ const messages = [
67
+ ...history,
68
+ { role: 'user', content: userContent },
69
+ ];
70
+ return runPathChoiceToolLoop({
71
+ factory,
72
+ providerId: context.providerId,
73
+ model: context.model,
74
+ messages,
75
+ maxIterations: context.maxIterations,
76
+ tools: context.tools,
77
+ compaction: context.compaction,
78
+ recovery: context.recovery,
79
+ steerControl$: context.steerControl$,
80
+ subagentRegistrations: context.subagentRegistrations,
81
+ toolCtx: context.toolCtx,
82
+ ...(context.subagentRegistrations.length > 0
83
+ ? {
84
+ waitForSubagentResult: (callId, signal) => waitForSubagentResult(subagentResult$, callId, signal, context.recovery.subagentTimeoutMs),
85
+ }
86
+ : {}),
87
+ }).pipe(map((chunk) => {
88
+ if (chunk.kind === 'accept') {
89
+ return {
90
+ kind: 'accept',
91
+ notes: chunk.notes,
92
+ result,
93
+ };
94
+ }
95
+ return chunk;
96
+ }));
97
+ };
98
+ /**
99
+ * Dedicated Review node: path choice via **Review-private** control tools
100
+ * (`accept` / `feedback` in `path-choice/control-tools.ts`). Those chat tools are
101
+ * ephemeral on completion calls only — they must not leak into shared
102
+ * inventory / other LLM nodes. Tool payloads demux to `response` / `feedback`
103
+ * ports; free-form replies get a reminder. Optional inventory / MCP /
104
+ * Sub-Agents use shared LLM inventory ports.
105
+ *
106
+ * Session history uses the shared {@link createLlmSessionCycle$} (ADR-016):
107
+ * init = task / system / inventory; turn driver = `result`.
108
+ * @see docs/DONE/EPICS/03-review-node.md
109
+ * @see docs/DONE/EPICS/MECHANICS-tool-execution.md
110
+ */
111
+ export const reviewNode = defineLlmNode({
112
+ type: 'common-review',
113
+ displayName: 'Review',
114
+ category: 'AI',
115
+ 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.',
116
+ uiSchema: [
117
+ ...llmPanelUiSchema.filter((item) => item.field !== 'maxIterations'),
118
+ llmMaxIterationsUiField(DEFAULT_PATH_CHOICE_MAX_ITERATIONS, PATH_CHOICE_MAX_ITERATIONS_CAP),
119
+ ...llmCompactionUiSchema,
120
+ ...llmRecoveryUiSchema,
121
+ ],
122
+ bind(ctx, { makeInput, configureOutput, combineInputs }, inventory) {
123
+ const { tools, mcp, subagentRegistration, subagentResult, steerControl, } = inventory;
124
+ const task = makeInput('task', {
125
+ name: 'task',
126
+ wireType: 'string',
127
+ inline: 'text-multiline',
128
+ required: true,
129
+ });
130
+ const result = makeInput('result', {
131
+ name: 'result',
132
+ wireType: 'string',
133
+ inline: 'text-multiline',
134
+ required: true,
135
+ });
136
+ const systemPrompt = makeInput('systemPrompt', {
137
+ name: 'systemPrompt',
138
+ wireType: 'string',
139
+ inline: 'text-multiline',
140
+ defaultValue: '',
141
+ });
142
+ // Init peers only — result is the session turn driver (ADR-016).
143
+ const context$ = combineInputs([task, systemPrompt, tools, subagentRegistration, mcp, ctx], ([taskValue, systemPromptValue, toolList, subagentList, mcpList, ec,]) => {
144
+ const rolePreset = parseLlmRolePreset(ec.params.rolePreset);
145
+ const skillId = resolveEffectiveSkillId(rolePreset, ec.params.skillId);
146
+ const hostServices = getRunHostServices(ec);
147
+ const skillMarkdown = hostServices?.skillMarkdown ?? '';
148
+ const agentsMarkdown = hostServices?.agentsMarkdown ?? '';
149
+ return {
150
+ task: String(taskValue ?? ''),
151
+ ...resolveChatProviderModel(ec.params, hostServices),
152
+ skillId,
153
+ skillMarkdown,
154
+ effectiveSystemPrompt: buildEffectiveReviewSystem({
155
+ rolePreset,
156
+ systemPromptInput: String(systemPromptValue ?? ''),
157
+ agentsMarkdown,
158
+ skillMarkdown,
159
+ }),
160
+ factory: hostServices?.createChatCompletionStream,
161
+ maxIterations: normalizeMaxIterations(ec.params.maxIterations, {
162
+ fallback: DEFAULT_PATH_CHOICE_MAX_ITERATIONS,
163
+ maxCap: PATH_CHOICE_MAX_ITERATIONS_CAP,
164
+ }),
165
+ maxFeedbackTurns: normalizeMaxFeedbackTurns(ec.params.maxFeedbackTurns),
166
+ ...(hostServices?.requestPermission !== undefined
167
+ ? { requestPermission: hostServices.requestPermission }
168
+ : {}),
169
+ compaction: normalizeCompactionConfig(ec.params),
170
+ recovery: normalizeLlmRecoveryPolicy(ec.params),
171
+ steerControl$: steerControl.value$.pipe(filter(isSteerControlPayload)),
172
+ tools: collectAgentToolHandles({
173
+ toolHandles: ec.toolHandles,
174
+ toolsPort: toolList,
175
+ mcpHandles: ec.mcpHandles,
176
+ mcpPort: mcpList,
177
+ }),
178
+ subagentRegistrations: flattenSubAgentRegistrations(subagentList),
179
+ toolCtx: {
180
+ projectDir: ec.projectDir,
181
+ runId: ec.runId,
182
+ ...(hostServices?.authorize !== undefined
183
+ ? { authorize: hostServices.authorize }
184
+ : {}),
185
+ ...(hostServices?.denyPaths !== undefined
186
+ ? { denyPaths: hostServices.denyPaths }
187
+ : {}),
188
+ ...(hostServices?.allowedHosts !== undefined
189
+ ? { allowedHosts: hostServices.allowedHosts }
190
+ : {}),
191
+ },
192
+ };
193
+ });
194
+ const cycle$ = createLlmSessionCycle$(context$, result.value$, (context) => ({
195
+ history: [
196
+ {
197
+ role: 'system',
198
+ content: context.effectiveSystemPrompt,
199
+ },
200
+ ],
201
+ trackAssistantHistory: false,
202
+ appendUserFeedbackToHistory: false,
203
+ session: undefined,
204
+ }), (context, turnPayload, history) => runReviewTurn(context, String(turnPayload ?? ''), history, subagentResult.value$), { primeTurn0: false });
205
+ const reasoning$ = cycle$.pipeValue(demuxByKind('reasoning', (chunk) => chunk.text));
206
+ const draftResponse$ = cycle$.pipeValue(demuxByKind('draftResponse', (chunk) => chunk
207
+ .text));
208
+ const toolLog$ = cycle$.pipeValue(demuxByKind('toolLog', (chunk) => chunk.text));
209
+ const recovery$ = cycle$.pipeValue(demuxByKind('recoveryNotice', (chunk) => {
210
+ const notice = chunk;
211
+ return toLlmRecoveryPortValue(notice);
212
+ }));
213
+ const response$ = cycle$.pipeValue(demuxByKind('accept', (chunk) => chunk.result));
214
+ const feedback$ = cycle$.pipeValue(demuxByKind('feedback', (chunk) => chunk.notes));
215
+ const subagent$ = cycle$.pipeValue(demuxByKind('subagentSpawn', (chunk) => chunk
216
+ .payload));
217
+ return {
218
+ inputs: [task, result, systemPrompt],
219
+ outputs: [
220
+ configureOutput('reasoning', reasoning$, {
221
+ wireType: 'string',
222
+ feed: { role: 'reasoning', streaming: true },
223
+ }),
224
+ configureOutput('draftResponse', draftResponse$, {
225
+ wireType: 'string',
226
+ feed: { role: 'draft', streaming: true },
227
+ }),
228
+ configureOutput('response', response$, {
229
+ wireType: 'string',
230
+ feed: { role: 'result' },
231
+ }),
232
+ configureOutput('feedback', feedback$, {
233
+ wireType: 'string',
234
+ feed: { role: 'result' },
235
+ }),
236
+ ],
237
+ inventoryOutputs: { toolLog$, recovery$, subagent$ },
238
+ };
239
+ },
240
+ });