langflower 0.0.4 → 0.0.6

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 (98) hide show
  1. package/README.md +20 -15
  2. package/docs/public/README.md +15 -0
  3. package/docs/public/configuration.md +56 -0
  4. package/docs/public/extending.md +58 -0
  5. package/docs/public/getting-started.md +61 -0
  6. package/docs/public/how-it-works.md +39 -0
  7. package/docs/public/product.md +43 -0
  8. package/docs/public/using-the-editor.md +53 -0
  9. package/docs/public/workflows.md +49 -0
  10. package/package.json +3 -2
  11. package/ui-dist/chunk-6DQ2XSRW.js +4 -0
  12. package/ui-dist/{chunk-2AICAC67.js → chunk-Y6VMBLSJ.js} +1 -1
  13. package/ui-dist/index.html +2 -2
  14. package/ui-dist/main-RCFTD5AZ.js +311 -0
  15. package/ui-dist/styles-EOXODOI7.css +1 -0
  16. package/vendor/common-nodes/dist/ai/critique/node.d.ts +141 -23
  17. package/vendor/common-nodes/dist/ai/critique/node.js +33 -31
  18. package/vendor/common-nodes/dist/ai/fake-llm/node.d.ts +6 -6
  19. package/vendor/common-nodes/dist/ai/llm-compaction-ui-schema.d.ts +1 -1
  20. package/vendor/common-nodes/dist/ai/llm-compaction-ui-schema.js +2 -1
  21. package/vendor/common-nodes/dist/ai/llm-panel-ui-schema.d.ts +7 -21
  22. package/vendor/common-nodes/dist/ai/llm-panel-ui-schema.js +8 -4
  23. package/vendor/common-nodes/dist/ai/llm-session-shell.d.ts +2 -0
  24. package/vendor/common-nodes/dist/ai/llm-session-shell.js +3 -3
  25. package/vendor/common-nodes/dist/ai/normalize-max-iterations.d.ts +4 -3
  26. package/vendor/common-nodes/dist/ai/normalize-max-iterations.js +4 -3
  27. package/vendor/common-nodes/dist/ai/openai/normalize-compaction-params.d.ts +2 -2
  28. package/vendor/common-nodes/dist/ai/openai/normalize-compaction-params.js +1 -1
  29. package/vendor/common-nodes/dist/ai/openai-llm/node.d.ts +9 -9
  30. package/vendor/common-nodes/dist/ai/resolve-chat-provider-model.d.ts +10 -0
  31. package/vendor/common-nodes/dist/ai/resolve-chat-provider-model.js +8 -0
  32. package/vendor/common-nodes/dist/ai/review/node.d.ts +138 -15
  33. package/vendor/common-nodes/dist/ai/review/node.js +29 -22
  34. package/vendor/common-nodes/dist/ai/run-host-services.d.ts +8 -0
  35. package/vendor/common-nodes/dist/ai/sub-agent/node.d.ts +9 -9
  36. package/vendor/common-nodes/dist/ai/sub-agent/node.js +4 -3
  37. package/vendor/common-nodes/dist/hitl/chat-input/node.js +1 -0
  38. package/vendor/common-nodes/dist/hitl/review-gate/node.js +5 -0
  39. package/vendor/node-sdk/dist/node-factory/define-llm-node/default-llm-ports.js +2 -0
  40. package/vendor/node-sdk/dist/node-factory/define-reactive-node/define-reactive-node.d.ts +1 -1
  41. package/vendor/node-sdk/dist/node-factory/define-reactive-node/io-helpers.d.ts +5 -12
  42. package/vendor/node-sdk/dist/node-factory/define-reactive-node/port-meta.d.ts +13 -0
  43. package/vendor/runtime/dist/runtime-runner.js +7 -4
  44. package/vendor/runtime/dist/runtime.d.ts +1 -1
  45. package/vendor/runtime/dist/types.d.ts +12 -0
  46. package/vendor/server/dist/bridge/attach-langflower-bridge.d.ts +4 -1
  47. package/vendor/server/dist/bridge/attach-langflower-bridge.js +16 -5
  48. package/vendor/server/dist/bridge/bridge-event-log.d.ts +12 -0
  49. package/vendor/server/dist/bridge/bridge-event-log.js +199 -0
  50. package/vendor/server/dist/bridge/build-execution-context.d.ts +1 -1
  51. package/vendor/server/dist/bridge/build-execution-context.js +3 -0
  52. package/vendor/server/dist/bridge/emit-bootstrap.d.ts +4 -2
  53. package/vendor/server/dist/bridge/emit-bootstrap.js +6 -2
  54. package/vendor/server/dist/bridge/settings-draft-controller.d.ts +14 -0
  55. package/vendor/server/dist/bridge/settings-draft-controller.js +178 -0
  56. package/vendor/server/dist/bridge/wire-config-handlers.d.ts +8 -1
  57. package/vendor/server/dist/bridge/wire-config-handlers.js +44 -16
  58. package/vendor/server/dist/bridge/wire-editor-handlers.d.ts +8 -1
  59. package/vendor/server/dist/bridge/wire-editor-handlers.js +40 -1
  60. package/vendor/server/dist/bridge/wire-runner-handlers.js +3 -1
  61. package/vendor/server/dist/config/langflower-config.service.d.ts +2 -0
  62. package/vendor/server/dist/config/langflower-config.service.js +24 -1
  63. package/vendor/server/dist/config/resolve-draft-provider-credentials.d.ts +18 -0
  64. package/vendor/server/dist/config/resolve-draft-provider-credentials.js +60 -0
  65. package/vendor/server/dist/create-server.js +5 -3
  66. package/vendor/server/dist/session/build-session-bootstrap.d.ts +3 -1
  67. package/vendor/server/dist/session/build-session-bootstrap.js +9 -0
  68. package/vendor/server/dist/session/langflower-session.d.ts +7 -2
  69. package/vendor/server/dist/session/langflower-session.js +9 -1
  70. package/vendor/server/dist/session/settings-draft-session.d.ts +24 -0
  71. package/vendor/server/dist/session/settings-draft-session.js +82 -0
  72. package/vendor/server/skeleton/schemas/langflower-config.schema.json +4 -0
  73. package/vendor/server/skeleton/skills/langflower-helper/SKILL.md +20 -8
  74. package/vendor/server/skeleton/skills/langflower-helper/architecture.md +5 -0
  75. package/vendor/server/skeleton/skills/langflower-helper/layout.md +18 -16
  76. package/vendor/server/skeleton/workflows/simple-coder.json +249 -19
  77. package/vendor/server/skeleton/workflows/starter.json +31 -20
  78. package/vendor/shared/dist/langflower-bus-config.d.ts +50 -10
  79. package/vendor/shared/dist/langflower-bus-config.js +52 -11
  80. package/vendor/shared/dist/langflower-config/merge-langflower-config-layers.test.js +4 -0
  81. package/vendor/shared/dist/langflower-config/parse-default-chat-model.d.ts +14 -0
  82. package/vendor/shared/dist/langflower-config/parse-default-chat-model.js +38 -0
  83. package/vendor/shared/dist/langflower-config/parse-default-chat-model.test.d.ts +1 -0
  84. package/vendor/shared/dist/langflower-config/parse-default-chat-model.test.js +41 -0
  85. package/vendor/shared/dist/langflower-config/resolve-server-logs-enabled.d.ts +6 -0
  86. package/vendor/shared/dist/langflower-config/resolve-server-logs-enabled.js +5 -0
  87. package/vendor/shared/dist/langflower-config/resolve-server-logs-enabled.test.d.ts +1 -0
  88. package/vendor/shared/dist/langflower-config/resolve-server-logs-enabled.test.js +11 -0
  89. package/vendor/shared/dist/langflower-config/settings-draft.d.ts +44 -0
  90. package/vendor/shared/dist/langflower-config/settings-draft.js +143 -0
  91. package/vendor/shared/dist/langflower.d.ts +7 -2
  92. package/vendor/shared/dist/langflower.js +3 -0
  93. package/vendor/shared/dist/types/langflower-bootstrap.d.ts +6 -1
  94. package/vendor/shared/dist/types/langflower-config.d.ts +65 -0
  95. package/vendor/shared/dist/types/langflower-editor.d.ts +19 -0
  96. package/ui-dist/chunk-6ZABW4JL.js +0 -4
  97. package/ui-dist/main-XI7IOZKZ.js +0 -311
  98. package/ui-dist/styles-TQGRAC7Q.css +0 -1
@@ -4,6 +4,7 @@ import { collectAgentToolHandles } from '../tools/collect-agent-tool-handles.js'
4
4
  import { parseLlmRolePreset, resolveEffectiveSkillId, } from './llm-role-preset.js';
5
5
  import { flattenSubAgentRegistrations, } from './sub-agent-protocol.js';
6
6
  import { normalizeCompactionConfig } from './openai/normalize-compaction-params.js';
7
+ import { resolveChatProviderModel } from './resolve-chat-provider-model.js';
7
8
  import { getRunHostServices } from './run-host-services.js';
8
9
  import { AGENT_MAX_ITERATIONS_CAP, DEFAULT_AGENT_MAX_ITERATIONS, normalizeMaxIterations as normalizeMaxIterationsParam, } from './normalize-max-iterations.js';
9
10
  import { normalizeLlmRecoveryPolicy } from './llm-loop/normalize-llm-recovery-policy.js';
@@ -11,7 +12,7 @@ import { runLlmSessionMachine } from './llm-session/run-session-machine.js';
11
12
  const toolLabel = (tool) => tool.name.length > 0 ? tool.name : tool.toolId || 'unknown';
12
13
  const formatList = (items, labelOf) => (items.length === 0 ? 'none' : items.map(labelOf).join(', '));
13
14
  /** 0 = unlimited; positive = max feedback turns after turn 0. */
14
- const normalizeMaxFeedbackTurns = (value) => {
15
+ export const normalizeMaxFeedbackTurns = (value) => {
15
16
  const n = typeof value === 'number' ? value : Number(value);
16
17
  if (!Number.isFinite(n) || n < 1) {
17
18
  return 0;
@@ -47,8 +48,7 @@ const assembleLlmAgentInventoryContext = (prompt, toolList, subagentList, mcpLis
47
48
  mcpPort: mcpList,
48
49
  }),
49
50
  subagentRegistrations: flattenSubAgentRegistrations(subagentList),
50
- providerId: String(ec.params.providerId ?? ''),
51
- model: String(ec.params.model ?? ''),
51
+ ...resolveChatProviderModel(ec.params, hostServices),
52
52
  skillId,
53
53
  rolePreset,
54
54
  skillMarkdown,
@@ -6,7 +6,8 @@ export declare const normalizeMaxIterations: (value: unknown, options: {
6
6
  readonly fallback: number;
7
7
  readonly maxCap: number;
8
8
  }) => number;
9
- export declare const AGENT_MAX_ITERATIONS_CAP = 64;
10
- export declare const PATH_CHOICE_MAX_ITERATIONS_CAP = 32;
11
- export declare const DEFAULT_AGENT_MAX_ITERATIONS = 64;
9
+ /** Soft upper bound only — Inspector lets users raise freely. */
10
+ export declare const AGENT_MAX_ITERATIONS_CAP: number;
11
+ export declare const PATH_CHOICE_MAX_ITERATIONS_CAP: number;
12
+ export declare const DEFAULT_AGENT_MAX_ITERATIONS = 100;
12
13
  export declare const DEFAULT_PATH_CHOICE_MAX_ITERATIONS = 5;
@@ -16,7 +16,8 @@ export const normalizeMaxIterations = (value, options) => {
16
16
  }
17
17
  return Math.min(options.maxCap, floored);
18
18
  };
19
- export const AGENT_MAX_ITERATIONS_CAP = 64;
20
- export const PATH_CHOICE_MAX_ITERATIONS_CAP = 32;
21
- export const DEFAULT_AGENT_MAX_ITERATIONS = 64;
19
+ /** Soft upper bound only — Inspector lets users raise freely. */
20
+ export const AGENT_MAX_ITERATIONS_CAP = Number.MAX_SAFE_INTEGER;
21
+ export const PATH_CHOICE_MAX_ITERATIONS_CAP = Number.MAX_SAFE_INTEGER;
22
+ export const DEFAULT_AGENT_MAX_ITERATIONS = 100;
22
23
  export const DEFAULT_PATH_CHOICE_MAX_ITERATIONS = 5;
@@ -1,13 +1,13 @@
1
1
  export type LlmCompactionConfig = {
2
2
  /**
3
3
  * Approx input token budget. `0` disables proactive compaction.
4
- * Invalid values coerce to the Inspector default `32768`.
4
+ * Invalid values coerce to the Inspector default `200000`.
5
5
  */
6
6
  readonly contextSize: number;
7
7
  /** Retry once after a typed context-length error by force-compacting. */
8
8
  readonly compactOnError: boolean;
9
9
  };
10
- export declare const DEFAULT_CONTEXT_SIZE = 32768;
10
+ export declare const DEFAULT_CONTEXT_SIZE = 200000;
11
11
  export declare const DISABLED_COMPACTION_CONFIG: LlmCompactionConfig;
12
12
  export declare const normalizeContextSize: (value: unknown) => number;
13
13
  export declare const normalizeCompactOnError: (value: unknown) => boolean;
@@ -1,4 +1,4 @@
1
- export const DEFAULT_CONTEXT_SIZE = 32768;
1
+ export const DEFAULT_CONTEXT_SIZE = 200000;
2
2
  const MAX_CONTEXT_SIZE = 1_000_000;
3
3
  export const DISABLED_COMPACTION_CONFIG = {
4
4
  contextSize: 0,
@@ -70,15 +70,15 @@ export declare const openAiLlmNode: {
70
70
  readonly field: "maxFeedbackTurns";
71
71
  readonly type: "number";
72
72
  readonly label: "Max feedback turns (0 = unlimited)";
73
- readonly default: 0;
73
+ readonly default: 50;
74
74
  readonly min: 0;
75
- readonly max: 64;
75
+ readonly max: number;
76
76
  readonly step: 1;
77
77
  }, {
78
78
  readonly field: "contextSize";
79
79
  readonly type: "number";
80
80
  readonly label: "Context size (approx tokens)";
81
- readonly default: 32768;
81
+ readonly default: 200000;
82
82
  readonly min: 0;
83
83
  readonly step: 1;
84
84
  }, {
@@ -178,15 +178,15 @@ export declare const openAiLlmNode: {
178
178
  readonly field: "maxFeedbackTurns";
179
179
  readonly type: "number";
180
180
  readonly label: "Max feedback turns (0 = unlimited)";
181
- readonly default: 0;
181
+ readonly default: 50;
182
182
  readonly min: 0;
183
- readonly max: 64;
183
+ readonly max: number;
184
184
  readonly step: 1;
185
185
  }, {
186
186
  readonly field: "contextSize";
187
187
  readonly type: "number";
188
188
  readonly label: "Context size (approx tokens)";
189
- readonly default: 32768;
189
+ readonly default: 200000;
190
190
  readonly min: 0;
191
191
  readonly step: 1;
192
192
  }, {
@@ -286,15 +286,15 @@ export declare const openAiLlmNode: {
286
286
  readonly field: "maxFeedbackTurns";
287
287
  readonly type: "number";
288
288
  readonly label: "Max feedback turns (0 = unlimited)";
289
- readonly default: 0;
289
+ readonly default: 50;
290
290
  readonly min: 0;
291
- readonly max: 64;
291
+ readonly max: number;
292
292
  readonly step: 1;
293
293
  }, {
294
294
  readonly field: "contextSize";
295
295
  readonly type: "number";
296
296
  readonly label: "Context size (approx tokens)";
297
- readonly default: 32768;
297
+ readonly default: 200000;
298
298
  readonly min: 0;
299
299
  readonly step: 1;
300
300
  }, {
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Resolve chat provider/model from node params with optional host default
3
+ * (`LangflowerConfig.model` parsed into {@link RunHostServices.defaultChat}).
4
+ */
5
+ import type { RunHostServices } from './run-host-services.js';
6
+ export type ResolvedChatProviderModel = {
7
+ readonly providerId: string;
8
+ readonly model: string;
9
+ };
10
+ export declare const resolveChatProviderModel: (params: Readonly<Record<string, unknown>>, host: RunHostServices | undefined) => ResolvedChatProviderModel;
@@ -0,0 +1,8 @@
1
+ export const resolveChatProviderModel = (params, host) => {
2
+ const fromParamsProvider = String(params['providerId'] ?? '').trim();
3
+ const fromParamsModel = String(params['model'] ?? '').trim();
4
+ return {
5
+ providerId: fromParamsProvider || host?.defaultChat?.providerId || '',
6
+ model: fromParamsModel || host?.defaultChat?.model || '',
7
+ };
8
+ };
@@ -15,23 +15,64 @@ export declare const reviewNode: {
15
15
  readonly emitOncePerActivation: boolean;
16
16
  readonly stopsRun: boolean;
17
17
  readonly chatEntry: boolean;
18
- readonly uiSchema: readonly [{
18
+ readonly uiSchema: readonly [...({
19
19
  readonly field: "providerId";
20
20
  readonly type: "select";
21
21
  readonly label: "Provider";
22
22
  readonly optionsSource: "langflower.providers";
23
- }, {
23
+ } | {
24
24
  readonly field: "model";
25
25
  readonly type: "select";
26
26
  readonly label: "Model";
27
27
  readonly optionsSource: "langflower.models";
28
28
  readonly dependsOn: "providerId";
29
- }, {
29
+ } | {
30
30
  readonly field: "skillId";
31
31
  readonly type: "select";
32
32
  readonly label: "Skill";
33
33
  readonly optionsSource: "langflower.skills";
34
- }, {
34
+ } | {
35
+ readonly field: "rolePreset";
36
+ readonly type: "select";
37
+ readonly label: "Role preset";
38
+ readonly default: "custom";
39
+ readonly options: readonly [{
40
+ readonly value: "custom";
41
+ readonly title: "Custom";
42
+ }, {
43
+ readonly value: "plan";
44
+ readonly title: "Plan";
45
+ }, {
46
+ readonly value: "coder";
47
+ readonly title: "Coder";
48
+ }, {
49
+ readonly value: "explorer";
50
+ readonly title: "Explorer";
51
+ }];
52
+ } | {
53
+ readonly field: "includeAgentsMd";
54
+ readonly type: "boolean";
55
+ readonly label: "Include root AGENTS.md";
56
+ readonly default: false;
57
+ } | {
58
+ readonly field: "toolPermissions";
59
+ readonly type: "tool-permission-table";
60
+ readonly label: "Tool permissions";
61
+ readonly optionsSource: "node.wiredTools";
62
+ } | {
63
+ readonly field: "enabledMcpIds";
64
+ readonly type: "tool-id-list";
65
+ readonly label: "Enabled MCP";
66
+ readonly optionsSource: "langflower.mcpServers";
67
+ } | {
68
+ readonly field: "maxFeedbackTurns";
69
+ readonly type: "number";
70
+ readonly label: "Max feedback turns (0 = unlimited)";
71
+ readonly default: 50;
72
+ readonly min: 0;
73
+ readonly max: number;
74
+ readonly step: 1;
75
+ })[], {
35
76
  readonly field: "maxIterations";
36
77
  readonly type: "number";
37
78
  readonly label: "Tool-loop max iterations per feedback turn (0 = unlimited)";
@@ -43,7 +84,7 @@ export declare const reviewNode: {
43
84
  readonly field: "contextSize";
44
85
  readonly type: "number";
45
86
  readonly label: "Context size (approx tokens)";
46
- readonly default: 32768;
87
+ readonly default: 200000;
47
88
  readonly min: 0;
48
89
  readonly step: 1;
49
90
  }, {
@@ -82,23 +123,64 @@ export declare const reviewNode: {
82
123
  readonly step: 1;
83
124
  }];
84
125
  readonly bypassPorts: Record<string, import("@langflower/node-sdk").WireType>;
85
- readonly inputsConfigs: readonly [import("@langflower/node-sdk").InputPortMeta<import("@langflower/node-sdk").ExecutionContext<readonly [{
126
+ readonly inputsConfigs: readonly [import("@langflower/node-sdk").InputPortMeta<import("@langflower/node-sdk").ExecutionContext<readonly [...({
86
127
  readonly field: "providerId";
87
128
  readonly type: "select";
88
129
  readonly label: "Provider";
89
130
  readonly optionsSource: "langflower.providers";
90
- }, {
131
+ } | {
91
132
  readonly field: "model";
92
133
  readonly type: "select";
93
134
  readonly label: "Model";
94
135
  readonly optionsSource: "langflower.models";
95
136
  readonly dependsOn: "providerId";
96
- }, {
137
+ } | {
97
138
  readonly field: "skillId";
98
139
  readonly type: "select";
99
140
  readonly label: "Skill";
100
141
  readonly optionsSource: "langflower.skills";
101
- }, {
142
+ } | {
143
+ readonly field: "rolePreset";
144
+ readonly type: "select";
145
+ readonly label: "Role preset";
146
+ readonly default: "custom";
147
+ readonly options: readonly [{
148
+ readonly value: "custom";
149
+ readonly title: "Custom";
150
+ }, {
151
+ readonly value: "plan";
152
+ readonly title: "Plan";
153
+ }, {
154
+ readonly value: "coder";
155
+ readonly title: "Coder";
156
+ }, {
157
+ readonly value: "explorer";
158
+ readonly title: "Explorer";
159
+ }];
160
+ } | {
161
+ readonly field: "includeAgentsMd";
162
+ readonly type: "boolean";
163
+ readonly label: "Include root AGENTS.md";
164
+ readonly default: false;
165
+ } | {
166
+ readonly field: "toolPermissions";
167
+ readonly type: "tool-permission-table";
168
+ readonly label: "Tool permissions";
169
+ readonly optionsSource: "node.wiredTools";
170
+ } | {
171
+ readonly field: "enabledMcpIds";
172
+ readonly type: "tool-id-list";
173
+ readonly label: "Enabled MCP";
174
+ readonly optionsSource: "langflower.mcpServers";
175
+ } | {
176
+ readonly field: "maxFeedbackTurns";
177
+ readonly type: "number";
178
+ readonly label: "Max feedback turns (0 = unlimited)";
179
+ readonly default: 50;
180
+ readonly min: 0;
181
+ readonly max: number;
182
+ readonly step: 1;
183
+ })[], {
102
184
  readonly field: "maxIterations";
103
185
  readonly type: "number";
104
186
  readonly label: "Tool-loop max iterations per feedback turn (0 = unlimited)";
@@ -110,7 +192,7 @@ export declare const reviewNode: {
110
192
  readonly field: "contextSize";
111
193
  readonly type: "number";
112
194
  readonly label: "Context size (approx tokens)";
113
- readonly default: 32768;
195
+ readonly default: 200000;
114
196
  readonly min: 0;
115
197
  readonly step: 1;
116
198
  }, {
@@ -149,23 +231,64 @@ export declare const reviewNode: {
149
231
  readonly step: 1;
150
232
  }], import("@langflower/node-sdk/llm").LlmExecutionCaps>>, ...import("@langflower/node-sdk").InputPortMeta<unknown>[]];
151
233
  readonly outputsConfigs: (import("@langflower/node-sdk").OutputParams & import("@langflower/node-sdk").PortMeta)[];
152
- readonly getInstance: () => import("@langflower/node-sdk").ReactiveNodeInstance<readonly [{
234
+ readonly getInstance: () => import("@langflower/node-sdk").ReactiveNodeInstance<readonly [...({
153
235
  readonly field: "providerId";
154
236
  readonly type: "select";
155
237
  readonly label: "Provider";
156
238
  readonly optionsSource: "langflower.providers";
157
- }, {
239
+ } | {
158
240
  readonly field: "model";
159
241
  readonly type: "select";
160
242
  readonly label: "Model";
161
243
  readonly optionsSource: "langflower.models";
162
244
  readonly dependsOn: "providerId";
163
- }, {
245
+ } | {
164
246
  readonly field: "skillId";
165
247
  readonly type: "select";
166
248
  readonly label: "Skill";
167
249
  readonly optionsSource: "langflower.skills";
168
- }, {
250
+ } | {
251
+ readonly field: "rolePreset";
252
+ readonly type: "select";
253
+ readonly label: "Role preset";
254
+ readonly default: "custom";
255
+ readonly options: readonly [{
256
+ readonly value: "custom";
257
+ readonly title: "Custom";
258
+ }, {
259
+ readonly value: "plan";
260
+ readonly title: "Plan";
261
+ }, {
262
+ readonly value: "coder";
263
+ readonly title: "Coder";
264
+ }, {
265
+ readonly value: "explorer";
266
+ readonly title: "Explorer";
267
+ }];
268
+ } | {
269
+ readonly field: "includeAgentsMd";
270
+ readonly type: "boolean";
271
+ readonly label: "Include root AGENTS.md";
272
+ readonly default: false;
273
+ } | {
274
+ readonly field: "toolPermissions";
275
+ readonly type: "tool-permission-table";
276
+ readonly label: "Tool permissions";
277
+ readonly optionsSource: "node.wiredTools";
278
+ } | {
279
+ readonly field: "enabledMcpIds";
280
+ readonly type: "tool-id-list";
281
+ readonly label: "Enabled MCP";
282
+ readonly optionsSource: "langflower.mcpServers";
283
+ } | {
284
+ readonly field: "maxFeedbackTurns";
285
+ readonly type: "number";
286
+ readonly label: "Max feedback turns (0 = unlimited)";
287
+ readonly default: 50;
288
+ readonly min: 0;
289
+ readonly max: number;
290
+ readonly step: 1;
291
+ })[], {
169
292
  readonly field: "maxIterations";
170
293
  readonly type: "number";
171
294
  readonly label: "Tool-loop max iterations per feedback turn (0 = unlimited)";
@@ -177,7 +300,7 @@ export declare const reviewNode: {
177
300
  readonly field: "contextSize";
178
301
  readonly type: "number";
179
302
  readonly label: "Context size (approx tokens)";
180
- readonly default: 32768;
303
+ readonly default: 200000;
181
304
  readonly min: 0;
182
305
  readonly step: 1;
183
306
  }, {
@@ -1,10 +1,13 @@
1
1
  import { filter, map, Observable } from 'rxjs';
2
2
  import { defineLlmNode, isSteerControlPayload, } from '@langflower/node-sdk/llm';
3
3
  import { collectAgentToolHandles } from '../../tools/collect-agent-tool-handles.js';
4
- import { createLlmSessionCycle$, demuxByKind } from '../llm-session-shell.js';
4
+ import { buildEffectiveSystemPrompt } from '../build-effective-system-prompt.js';
5
+ import { resolveChatProviderModel } from '../resolve-chat-provider-model.js';
6
+ import { createLlmSessionCycle$, demuxByKind, normalizeMaxFeedbackTurns, } from '../llm-session-shell.js';
5
7
  import { llmCompactionUiSchema } from '../llm-compaction-ui-schema.js';
6
8
  import { llmRecoveryUiSchema } from '../llm-recovery-ui-schema.js';
7
- import { llmMaxIterationsUiField, llmProviderModelSkillUiSchema, } from '../llm-panel-ui-schema.js';
9
+ import { llmMaxIterationsUiField, llmPanelUiSchema, } from '../llm-panel-ui-schema.js';
10
+ import { parseLlmRolePreset, resolveEffectiveSkillId, } from '../llm-role-preset.js';
8
11
  import { DEFAULT_PATH_CHOICE_MAX_ITERATIONS, PATH_CHOICE_MAX_ITERATIONS_CAP, normalizeMaxIterations, } from '../normalize-max-iterations.js';
9
12
  import { normalizeLlmRecoveryPolicy } from '../llm-loop/normalize-llm-recovery-policy.js';
10
13
  import { normalizeCompactionConfig } from '../openai/normalize-compaction-params.js';
@@ -21,12 +24,6 @@ const FORCED_TOOL_SYSTEM = [
21
24
  `Call ${REVIEW_ACCEPT_TOOL} when the result meets the task criteria.`,
22
25
  `Call ${REVIEW_FEEDBACK_TOOL} with revision notes when it does not.`,
23
26
  ].join(' ');
24
- const reviewPanelUiSchema = [
25
- ...llmProviderModelSkillUiSchema,
26
- llmMaxIterationsUiField(DEFAULT_PATH_CHOICE_MAX_ITERATIONS, PATH_CHOICE_MAX_ITERATIONS_CAP),
27
- ...llmCompactionUiSchema,
28
- ...llmRecoveryUiSchema,
29
- ];
30
27
  const requireChatConfig = (providerId, model) => {
31
28
  if (providerId.trim().length === 0) {
32
29
  throw new Error('Provider is required for Review chat');
@@ -35,15 +32,11 @@ const requireChatConfig = (providerId, model) => {
35
32
  throw new Error('Model is required for Review chat');
36
33
  }
37
34
  };
38
- const buildEffectiveReviewSystem = (systemPromptInput, skillMarkdown) => {
35
+ const buildEffectiveReviewSystem = (input) => {
36
+ const merged = buildEffectiveSystemPrompt(input);
39
37
  const parts = [FORCED_TOOL_SYSTEM];
40
- const author = systemPromptInput.trim();
41
- if (author.length > 0) {
42
- parts.push(author);
43
- }
44
- const skill = skillMarkdown.trim();
45
- if (skill.length > 0) {
46
- parts.push(skill);
38
+ if (merged.trim().length > 0) {
39
+ parts.push(merged);
47
40
  }
48
41
  return parts.join('\n\n---\n\n');
49
42
  };
@@ -120,7 +113,12 @@ export const reviewNode = defineLlmNode({
120
113
  displayName: 'Review',
121
114
  category: 'AI',
122
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.',
123
- uiSchema: reviewPanelUiSchema,
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
+ ],
124
122
  bind(ctx, { makeInput, configureOutput, combineInputs }, inventory) {
125
123
  const { tools, mcp, subagentRegistration, subagentResult, steerControl, } = inventory;
126
124
  const task = makeInput('task', {
@@ -143,22 +141,31 @@ export const reviewNode = defineLlmNode({
143
141
  });
144
142
  // Init peers only — result is the session turn driver (ADR-016).
145
143
  const context$ = combineInputs([task, systemPrompt, tools, subagentRegistration, mcp, ctx], ([taskValue, systemPromptValue, toolList, subagentList, mcpList, ec,]) => {
146
- const skillId = String(ec.params.skillId ?? '');
144
+ const rolePreset = parseLlmRolePreset(ec.params.rolePreset);
145
+ const skillId = resolveEffectiveSkillId(rolePreset, ec.params.skillId);
147
146
  const hostServices = getRunHostServices(ec);
148
147
  const skillMarkdown = hostServices?.skillMarkdown ?? '';
148
+ const agentsMarkdown = hostServices?.agentsMarkdown ?? '';
149
149
  return {
150
150
  task: String(taskValue ?? ''),
151
- providerId: String(ec.params.providerId ?? ''),
152
- model: String(ec.params.model ?? ''),
151
+ ...resolveChatProviderModel(ec.params, hostServices),
153
152
  skillId,
154
153
  skillMarkdown,
155
- effectiveSystemPrompt: buildEffectiveReviewSystem(String(systemPromptValue ?? ''), skillMarkdown),
154
+ effectiveSystemPrompt: buildEffectiveReviewSystem({
155
+ rolePreset,
156
+ systemPromptInput: String(systemPromptValue ?? ''),
157
+ agentsMarkdown,
158
+ skillMarkdown,
159
+ }),
156
160
  factory: hostServices?.createChatCompletionStream,
157
161
  maxIterations: normalizeMaxIterations(ec.params.maxIterations, {
158
162
  fallback: DEFAULT_PATH_CHOICE_MAX_ITERATIONS,
159
163
  maxCap: PATH_CHOICE_MAX_ITERATIONS_CAP,
160
164
  }),
161
- maxFeedbackTurns: 0,
165
+ maxFeedbackTurns: normalizeMaxFeedbackTurns(ec.params.maxFeedbackTurns),
166
+ ...(hostServices?.requestPermission !== undefined
167
+ ? { requestPermission: hostServices.requestPermission }
168
+ : {}),
162
169
  compaction: normalizeCompactionConfig(ec.params),
163
170
  recovery: normalizeLlmRecoveryPolicy(ec.params),
164
171
  steerControl$: steerControl.value$.pipe(filter(isSteerControlPayload)),
@@ -11,6 +11,14 @@ export type RunHostServices = {
11
11
  readonly createChatCompletionStream?: CreateChatCompletionStream;
12
12
  readonly skillMarkdown?: string;
13
13
  readonly agentsMarkdown?: string;
14
+ /**
15
+ * Parsed effective `LangflowerConfig.model` (`providerId/modelId`).
16
+ * Empty node `providerId` / `model` params fall back to these at run time.
17
+ */
18
+ readonly defaultChat?: {
19
+ readonly providerId: string;
20
+ readonly model: string;
21
+ };
14
22
  readonly authorize?: (call: ToolInvokeCall) => Promise<'allow' | 'deny'>;
15
23
  /**
16
24
  * Direct HITL ask (tool gates + agent limit continue). Bypasses permission
@@ -83,15 +83,15 @@ export declare const subAgentNode: {
83
83
  readonly field: "maxFeedbackTurns";
84
84
  readonly type: "number";
85
85
  readonly label: "Max feedback turns (0 = unlimited)";
86
- readonly default: 0;
86
+ readonly default: 50;
87
87
  readonly min: 0;
88
- readonly max: 64;
88
+ readonly max: number;
89
89
  readonly step: 1;
90
90
  }, {
91
91
  readonly field: "contextSize";
92
92
  readonly type: "number";
93
93
  readonly label: "Context size (approx tokens)";
94
- readonly default: 32768;
94
+ readonly default: 200000;
95
95
  readonly min: 0;
96
96
  readonly step: 1;
97
97
  }, {
@@ -206,15 +206,15 @@ export declare const subAgentNode: {
206
206
  readonly field: "maxFeedbackTurns";
207
207
  readonly type: "number";
208
208
  readonly label: "Max feedback turns (0 = unlimited)";
209
- readonly default: 0;
209
+ readonly default: 50;
210
210
  readonly min: 0;
211
- readonly max: 64;
211
+ readonly max: number;
212
212
  readonly step: 1;
213
213
  }, {
214
214
  readonly field: "contextSize";
215
215
  readonly type: "number";
216
216
  readonly label: "Context size (approx tokens)";
217
- readonly default: 32768;
217
+ readonly default: 200000;
218
218
  readonly min: 0;
219
219
  readonly step: 1;
220
220
  }, {
@@ -329,15 +329,15 @@ export declare const subAgentNode: {
329
329
  readonly field: "maxFeedbackTurns";
330
330
  readonly type: "number";
331
331
  readonly label: "Max feedback turns (0 = unlimited)";
332
- readonly default: 0;
332
+ readonly default: 50;
333
333
  readonly min: 0;
334
- readonly max: 64;
334
+ readonly max: number;
335
335
  readonly step: 1;
336
336
  }, {
337
337
  readonly field: "contextSize";
338
338
  readonly type: "number";
339
339
  readonly label: "Context size (approx tokens)";
340
- readonly default: 32768;
340
+ readonly default: 200000;
341
341
  readonly min: 0;
342
342
  readonly step: 1;
343
343
  }, {
@@ -10,6 +10,7 @@ import { waitForSubagentResult } from '../wait-for-subagent-result.js';
10
10
  import { flattenSubAgentRegistrations, isSubAgentSpawnPayload, SUBAGENT_REGISTRATION_WIRE_TYPE, SUBAGENT_RESULT_WIRE_TYPE, SUBAGENT_SPAWN_WIRE_TYPE, } from '../sub-agent-protocol.js';
11
11
  import { collectAgentToolHandles } from '../../tools/collect-agent-tool-handles.js';
12
12
  import { parseLlmRolePreset, resolveEffectiveSkillId, } from '../llm-role-preset.js';
13
+ import { resolveChatProviderModel } from '../resolve-chat-provider-model.js';
13
14
  import { getRunHostServices } from '../run-host-services.js';
14
15
  import { buildEffectiveSystemPrompt } from '../build-effective-system-prompt.js';
15
16
  import { normalizeCompactionConfig } from '../openai/normalize-compaction-params.js';
@@ -193,8 +194,7 @@ export const subAgentNode = defineLlmNode({
193
194
  mcpPort: mcpList,
194
195
  }),
195
196
  subagentRegistrations: flattenSubAgentRegistrations(subagentList),
196
- providerId: String(ec.params.providerId ?? ''),
197
- model: String(ec.params.model ?? ''),
197
+ ...resolveChatProviderModel(ec.params, hostServices),
198
198
  skillId,
199
199
  rolePreset,
200
200
  skillMarkdown,
@@ -288,7 +288,8 @@ export const subAgentNode = defineLlmNode({
288
288
  }),
289
289
  configureOutput('result', result$, {
290
290
  wireType: SUBAGENT_RESULT_WIRE_TYPE,
291
- feed: { role: 'result' },
291
+ // Protocol payload for parent wiring — not work-log content.
292
+ feed: { role: 'none' },
292
293
  }),
293
294
  ],
294
295
  inventoryOutputs: {
@@ -31,6 +31,7 @@ export const chatInputNode = defineReactiveNode({
31
31
  outputs: [
32
32
  configureOutput('message', messageOut$, {
33
33
  wireType: 'string',
34
+ feed: { role: 'none' },
34
35
  }),
35
36
  ],
36
37
  };
@@ -40,6 +40,7 @@ export const hitlReviewGateNode = defineReactiveNode({
40
40
  // Passthrough pulls `result` (upstream edges stay live) and feeds HITL promptFrom.
41
41
  const preview = configureOutput('preview', result, {
42
42
  inferTypeFrom: result,
43
+ feed: { role: 'none' },
43
44
  });
44
45
  const response$ = approve.pipeValue(pipe(filter((approved) => approved === true), switchMap(() => result.value$.pipe(take(1))), map((reviewed) => reviewed ?? '')));
45
46
  const feedback$ = requestChanges.pipeValue(map((text) => text ?? ''));
@@ -47,11 +48,15 @@ export const hitlReviewGateNode = defineReactiveNode({
47
48
  inputs: [result, approve, requestChanges],
48
49
  outputs: [
49
50
  preview,
51
+ // User answer is tracked by the HITL-configured inputs (approve /
52
+ // requestChanges → hitl-user). Protocol outs stay wired but omit from feed.
50
53
  configureOutput('response', response$, {
51
54
  wireType: 'string',
55
+ feed: { role: 'none' },
52
56
  }),
53
57
  configureOutput('feedback', feedback$, {
54
58
  wireType: 'string',
59
+ feed: { role: 'none' },
55
60
  }),
56
61
  ],
57
62
  };
@@ -44,6 +44,8 @@ export const defaultLlmInventoryInputs = (make) => {
44
44
  wireType: SUBAGENT_RESULT_WIRE_TYPE,
45
45
  multi: 'merge',
46
46
  defaultValue: null,
47
+ // Protocol payload from Sub-Agent — omit from work log.
48
+ feed: { role: 'none' },
47
49
  });
48
50
  const steerControl = make(STEER_CONTROL_PORT_ID, {
49
51
  name: 'Steer',
@@ -5,7 +5,7 @@ import type { UISchemaConstItem } from './ui-schema-inference.js';
5
5
  export type { CtxError } from './ctx-error.js';
6
6
  export type { HitlButtonControl, HitlControl, HitlFileControl, HitlFileValue, HitlInputConfig, HitlPayloadTemplate, HitlTextareaControl, HitlTextValue, HitlUploadedFile, } from './hitl-config.js';
7
7
  export { configureOutput, DEFAULT_MULTILINE_MIN_HEIGHT_PX, InlineConfig, InlineSelectOption, InlineTextMultilineConfig, InputConfig, InputParams, InputPortMeta, makeInput, OutputConfig, OutputParams, OutputPortMeta, resolveMultilineInlineLayout, ResolvedMultilineInlineLayout, } from './io-helpers.js';
8
- export type { FeedRole } from './io-helpers.js';
8
+ export type { FeedPortMeta, FeedRole } from './io-helpers.js';
9
9
  export type { InputPortMode, MetaFromStatefulObservable, PortMeta, WireType, } from './port-meta.js';
10
10
  export type { ToolHandle, ToolHandler, ToolHandlerContext, } from '../define-tool-registrations/tool-handle.js';
11
11
  export { TOOL_HANDLE_WIRE_TYPE } from '../define-tool-registrations/tool-handle.js';