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.
- package/README.md +20 -15
- package/docs/public/README.md +15 -0
- package/docs/public/configuration.md +56 -0
- package/docs/public/extending.md +58 -0
- package/docs/public/getting-started.md +61 -0
- package/docs/public/how-it-works.md +39 -0
- package/docs/public/product.md +43 -0
- package/docs/public/using-the-editor.md +53 -0
- package/docs/public/workflows.md +49 -0
- package/package.json +3 -2
- package/ui-dist/chunk-6DQ2XSRW.js +4 -0
- package/ui-dist/{chunk-2AICAC67.js → chunk-Y6VMBLSJ.js} +1 -1
- package/ui-dist/index.html +2 -2
- package/ui-dist/main-RCFTD5AZ.js +311 -0
- package/ui-dist/styles-EOXODOI7.css +1 -0
- package/vendor/common-nodes/dist/ai/critique/node.d.ts +141 -23
- package/vendor/common-nodes/dist/ai/critique/node.js +33 -31
- package/vendor/common-nodes/dist/ai/fake-llm/node.d.ts +6 -6
- package/vendor/common-nodes/dist/ai/llm-compaction-ui-schema.d.ts +1 -1
- package/vendor/common-nodes/dist/ai/llm-compaction-ui-schema.js +2 -1
- package/vendor/common-nodes/dist/ai/llm-panel-ui-schema.d.ts +7 -21
- package/vendor/common-nodes/dist/ai/llm-panel-ui-schema.js +8 -4
- package/vendor/common-nodes/dist/ai/llm-session-shell.d.ts +2 -0
- package/vendor/common-nodes/dist/ai/llm-session-shell.js +3 -3
- package/vendor/common-nodes/dist/ai/normalize-max-iterations.d.ts +4 -3
- package/vendor/common-nodes/dist/ai/normalize-max-iterations.js +4 -3
- package/vendor/common-nodes/dist/ai/openai/normalize-compaction-params.d.ts +2 -2
- package/vendor/common-nodes/dist/ai/openai/normalize-compaction-params.js +1 -1
- package/vendor/common-nodes/dist/ai/openai-llm/node.d.ts +9 -9
- package/vendor/common-nodes/dist/ai/resolve-chat-provider-model.d.ts +10 -0
- package/vendor/common-nodes/dist/ai/resolve-chat-provider-model.js +8 -0
- package/vendor/common-nodes/dist/ai/review/node.d.ts +138 -15
- package/vendor/common-nodes/dist/ai/review/node.js +29 -22
- package/vendor/common-nodes/dist/ai/run-host-services.d.ts +8 -0
- package/vendor/common-nodes/dist/ai/sub-agent/node.d.ts +9 -9
- package/vendor/common-nodes/dist/ai/sub-agent/node.js +4 -3
- package/vendor/common-nodes/dist/hitl/chat-input/node.js +1 -0
- package/vendor/common-nodes/dist/hitl/review-gate/node.js +5 -0
- package/vendor/node-sdk/dist/node-factory/define-llm-node/default-llm-ports.js +2 -0
- package/vendor/node-sdk/dist/node-factory/define-reactive-node/define-reactive-node.d.ts +1 -1
- package/vendor/node-sdk/dist/node-factory/define-reactive-node/io-helpers.d.ts +5 -12
- package/vendor/node-sdk/dist/node-factory/define-reactive-node/port-meta.d.ts +13 -0
- package/vendor/runtime/dist/runtime-runner.js +7 -4
- package/vendor/runtime/dist/runtime.d.ts +1 -1
- package/vendor/runtime/dist/types.d.ts +12 -0
- package/vendor/server/dist/bridge/attach-langflower-bridge.d.ts +4 -1
- package/vendor/server/dist/bridge/attach-langflower-bridge.js +16 -5
- package/vendor/server/dist/bridge/bridge-event-log.d.ts +12 -0
- package/vendor/server/dist/bridge/bridge-event-log.js +199 -0
- package/vendor/server/dist/bridge/build-execution-context.d.ts +1 -1
- package/vendor/server/dist/bridge/build-execution-context.js +3 -0
- package/vendor/server/dist/bridge/emit-bootstrap.d.ts +4 -2
- package/vendor/server/dist/bridge/emit-bootstrap.js +6 -2
- package/vendor/server/dist/bridge/settings-draft-controller.d.ts +14 -0
- package/vendor/server/dist/bridge/settings-draft-controller.js +178 -0
- package/vendor/server/dist/bridge/wire-config-handlers.d.ts +8 -1
- package/vendor/server/dist/bridge/wire-config-handlers.js +44 -16
- package/vendor/server/dist/bridge/wire-editor-handlers.d.ts +8 -1
- package/vendor/server/dist/bridge/wire-editor-handlers.js +40 -1
- package/vendor/server/dist/bridge/wire-runner-handlers.js +3 -1
- package/vendor/server/dist/config/langflower-config.service.d.ts +2 -0
- package/vendor/server/dist/config/langflower-config.service.js +24 -1
- package/vendor/server/dist/config/resolve-draft-provider-credentials.d.ts +18 -0
- package/vendor/server/dist/config/resolve-draft-provider-credentials.js +60 -0
- package/vendor/server/dist/create-server.js +5 -3
- package/vendor/server/dist/session/build-session-bootstrap.d.ts +3 -1
- package/vendor/server/dist/session/build-session-bootstrap.js +9 -0
- package/vendor/server/dist/session/langflower-session.d.ts +7 -2
- package/vendor/server/dist/session/langflower-session.js +9 -1
- package/vendor/server/dist/session/settings-draft-session.d.ts +24 -0
- package/vendor/server/dist/session/settings-draft-session.js +82 -0
- package/vendor/server/skeleton/schemas/langflower-config.schema.json +4 -0
- package/vendor/server/skeleton/skills/langflower-helper/SKILL.md +20 -8
- package/vendor/server/skeleton/skills/langflower-helper/architecture.md +5 -0
- package/vendor/server/skeleton/skills/langflower-helper/layout.md +18 -16
- package/vendor/server/skeleton/workflows/simple-coder.json +249 -19
- package/vendor/server/skeleton/workflows/starter.json +31 -20
- package/vendor/shared/dist/langflower-bus-config.d.ts +50 -10
- package/vendor/shared/dist/langflower-bus-config.js +52 -11
- package/vendor/shared/dist/langflower-config/merge-langflower-config-layers.test.js +4 -0
- package/vendor/shared/dist/langflower-config/parse-default-chat-model.d.ts +14 -0
- package/vendor/shared/dist/langflower-config/parse-default-chat-model.js +38 -0
- package/vendor/shared/dist/langflower-config/parse-default-chat-model.test.d.ts +1 -0
- package/vendor/shared/dist/langflower-config/parse-default-chat-model.test.js +41 -0
- package/vendor/shared/dist/langflower-config/resolve-server-logs-enabled.d.ts +6 -0
- package/vendor/shared/dist/langflower-config/resolve-server-logs-enabled.js +5 -0
- package/vendor/shared/dist/langflower-config/resolve-server-logs-enabled.test.d.ts +1 -0
- package/vendor/shared/dist/langflower-config/resolve-server-logs-enabled.test.js +11 -0
- package/vendor/shared/dist/langflower-config/settings-draft.d.ts +44 -0
- package/vendor/shared/dist/langflower-config/settings-draft.js +143 -0
- package/vendor/shared/dist/langflower.d.ts +7 -2
- package/vendor/shared/dist/langflower.js +3 -0
- package/vendor/shared/dist/types/langflower-bootstrap.d.ts +6 -1
- package/vendor/shared/dist/types/langflower-config.d.ts +65 -0
- package/vendor/shared/dist/types/langflower-editor.d.ts +19 -0
- package/ui-dist/chunk-6ZABW4JL.js +0 -4
- package/ui-dist/main-XI7IOZKZ.js +0 -311
- 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
|
-
|
|
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
|
-
|
|
10
|
-
export declare const
|
|
11
|
-
export declare const
|
|
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
|
-
|
|
20
|
-
export const
|
|
21
|
-
export const
|
|
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 `
|
|
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 =
|
|
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;
|
|
@@ -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:
|
|
73
|
+
readonly default: 50;
|
|
74
74
|
readonly min: 0;
|
|
75
|
-
readonly max:
|
|
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:
|
|
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:
|
|
181
|
+
readonly default: 50;
|
|
182
182
|
readonly min: 0;
|
|
183
|
-
readonly max:
|
|
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:
|
|
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:
|
|
289
|
+
readonly default: 50;
|
|
290
290
|
readonly min: 0;
|
|
291
|
-
readonly max:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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 {
|
|
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,
|
|
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 = (
|
|
35
|
+
const buildEffectiveReviewSystem = (input) => {
|
|
36
|
+
const merged = buildEffectiveSystemPrompt(input);
|
|
39
37
|
const parts = [FORCED_TOOL_SYSTEM];
|
|
40
|
-
|
|
41
|
-
|
|
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:
|
|
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
|
|
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
|
-
|
|
152
|
-
model: String(ec.params.model ?? ''),
|
|
151
|
+
...resolveChatProviderModel(ec.params, hostServices),
|
|
153
152
|
skillId,
|
|
154
153
|
skillMarkdown,
|
|
155
|
-
effectiveSystemPrompt: buildEffectiveReviewSystem(
|
|
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:
|
|
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:
|
|
86
|
+
readonly default: 50;
|
|
87
87
|
readonly min: 0;
|
|
88
|
-
readonly max:
|
|
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:
|
|
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:
|
|
209
|
+
readonly default: 50;
|
|
210
210
|
readonly min: 0;
|
|
211
|
-
readonly max:
|
|
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:
|
|
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:
|
|
332
|
+
readonly default: 50;
|
|
333
333
|
readonly min: 0;
|
|
334
|
-
readonly max:
|
|
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:
|
|
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
|
-
|
|
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
|
-
|
|
291
|
+
// Protocol payload for parent wiring — not work-log content.
|
|
292
|
+
feed: { role: 'none' },
|
|
292
293
|
}),
|
|
293
294
|
],
|
|
294
295
|
inventoryOutputs: {
|
|
@@ -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';
|