langflower 0.0.9 → 0.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +2 -2
- package/ui-dist/index.html +2 -2
- package/ui-dist/main-Z7CPFXFA.js +313 -0
- package/ui-dist/styles-2TMDAUD7.css +1 -0
- package/vendor/common-nodes/dist/ai/features/llm-loop/llm-loop-reducer.js +0 -12
- package/vendor/common-nodes/dist/ai/features/llm-loop/llm-loop-types.d.ts +2 -7
- package/vendor/common-nodes/dist/ai/features/llm-loop/llm-loop-types.js +1 -1
- package/vendor/common-nodes/dist/ai/features/llm-loop/run-agent-loop.d.ts +0 -3
- package/vendor/common-nodes/dist/ai/features/llm-loop/run-agent-loop.js +22 -36
- package/vendor/common-nodes/dist/ai/features/llm-loop/run-llm-loop.d.ts +1 -7
- package/vendor/common-nodes/dist/ai/features/llm-loop/run-llm-loop.js +12 -35
- package/vendor/common-nodes/dist/ai/features/llm-session/llm-session-shell.d.ts +3 -10
- package/vendor/common-nodes/dist/ai/features/llm-session/llm-session-shell.js +9 -14
- package/vendor/common-nodes/dist/ai/features/path-choice/run-reactive-path-choice-loop.d.ts +0 -3
- package/vendor/common-nodes/dist/ai/features/path-choice/run-reactive-path-choice-loop.js +2 -15
- package/vendor/common-nodes/dist/ai/features/sub-agent-protocol.d.ts +1 -0
- package/vendor/common-nodes/dist/ai/features/sub-agent-protocol.js +1 -0
- package/vendor/common-nodes/dist/ai/features/ui-schema/llm-recovery-ui-schema.d.ts +1 -1
- package/vendor/common-nodes/dist/ai/features/ui-schema/llm-recovery-ui-schema.js +1 -1
- package/vendor/common-nodes/dist/ai/features/wait-for-subagent-result.d.ts +1 -0
- package/vendor/common-nodes/dist/ai/features/wait-for-subagent-result.js +1 -0
- package/vendor/common-nodes/dist/ai/nodes/critique/node.d.ts +3 -3
- package/vendor/common-nodes/dist/ai/nodes/critique/node.js +5 -18
- package/vendor/common-nodes/dist/ai/nodes/fake-llm/node.d.ts +3 -3
- package/vendor/common-nodes/dist/ai/nodes/fake-llm/node.js +3 -10
- package/vendor/common-nodes/dist/ai/nodes/openai-llm/node.d.ts +3 -3
- package/vendor/common-nodes/dist/ai/nodes/openai-llm/node.js +2 -9
- package/vendor/common-nodes/dist/ai/nodes/review/node.d.ts +3 -3
- package/vendor/common-nodes/dist/ai/nodes/review/node.js +5 -18
- package/vendor/common-nodes/dist/ai/nodes/sub-agent/node.d.ts +5 -5
- package/vendor/common-nodes/dist/ai/nodes/sub-agent/node.js +211 -96
- package/vendor/common-nodes/dist/catalog.js +2 -0
- package/vendor/common-nodes/dist/mcp/mcp-http/node.d.ts +4 -4
- package/vendor/common-nodes/dist/mcp/mcp-http/node.js +9 -10
- package/vendor/common-nodes/dist/mcp/mcp-stdio/node.d.ts +4 -4
- package/vendor/common-nodes/dist/mcp/mcp-stdio/node.js +9 -10
- package/vendor/common-nodes/dist/tools/collect-agent-tool-handles.d.ts +4 -4
- package/vendor/common-nodes/dist/tools/collect-agent-tool-handles.js +3 -11
- package/vendor/common-nodes/dist/tools/inventory-tool-round.d.ts +0 -10
- package/vendor/common-nodes/dist/tools/inventory-tool-round.js +0 -84
- package/vendor/common-nodes/dist/tools/tool-collection/node.d.ts +20 -0
- package/vendor/common-nodes/dist/tools/tool-collection/node.js +42 -0
- package/vendor/common-nodes/package.json +1 -5
- package/vendor/compiler/package.json +1 -1
- package/vendor/node-sdk/dist/node-factory/define-llm-node/default-llm-ports.d.ts +3 -7
- package/vendor/node-sdk/dist/node-factory/define-llm-node/default-llm-ports.js +4 -44
- package/vendor/node-sdk/dist/node-factory/define-llm-node/define-llm-node.d.ts +3 -5
- package/vendor/node-sdk/dist/node-factory/define-llm-node/define-llm-node.js +3 -5
- package/vendor/node-sdk/dist/node-factory/define-llm-node/llm-inventory-wire.d.ts +1 -0
- package/vendor/node-sdk/dist/node-factory/define-llm-node/llm-inventory-wire.js +1 -0
- package/vendor/node-sdk/dist/node-factory/define-mcp/mcp-handle.d.ts +3 -4
- package/vendor/node-sdk/dist/node-factory/define-mcp/mcp-handle.js +1 -1
- package/vendor/node-sdk/dist/node-factory/define-reactive-node/types.d.ts +2 -4
- package/vendor/node-sdk/dist/node-factory/define-reactive-node/ui-schema-inference.d.ts +1 -1
- package/vendor/node-sdk/package.json +1 -1
- package/vendor/runtime/dist/port-feed-override.d.ts +13 -0
- package/vendor/runtime/dist/port-feed-override.js +21 -0
- package/vendor/runtime/dist/port-signal-from-response.d.ts +15 -0
- package/vendor/runtime/dist/port-signal-from-response.js +48 -0
- package/vendor/runtime/dist/runtime-runner.d.ts +8 -3
- package/vendor/runtime/dist/runtime-runner.js +102 -81
- package/vendor/runtime/dist/runtime.d.ts +3 -2
- package/vendor/runtime/dist/runtime.js +1 -1
- package/vendor/runtime/dist/testing/workflows/workflow-events.d.ts +2 -0
- package/vendor/runtime/dist/testing/workflows/workflow-events.js +7 -5
- package/vendor/runtime/dist/types.d.ts +25 -8
- package/vendor/runtime/dist/types.js +3 -0
- package/vendor/runtime/package.json +1 -1
- package/vendor/server/dist/bridge/build-execution-context.js +3 -3
- package/vendor/server/dist/bridge/get-live-wired-tools.d.ts +3 -2
- package/vendor/server/dist/bridge/get-live-wired-tools.js +8 -5
- package/vendor/server/dist/bridge/wire-runner-handlers.js +2 -2
- package/vendor/server/dist/bridge/wire-workflow-handlers.js +23 -9
- package/vendor/server/dist/checkpoint/run-checkpoint-session.js +3 -3
- package/vendor/server/dist/session/reset-session-execution-feed.d.ts +6 -0
- package/vendor/server/dist/session/reset-session-execution-feed.js +8 -0
- package/vendor/server/skeleton/nodes/my-nodes/package.json +1 -1
- package/vendor/server/skeleton/skills/langflower-helper/SKILL.md +36 -22
- package/vendor/server/skeleton/skills/langflower-helper/architecture.md +7 -1
- package/vendor/server/skeleton/skills/langflower-helper/layout.md +3 -2
- package/vendor/server/skeleton/skills/langflower-workflow-writer/SKILL.md +12 -8
- package/vendor/server/skeleton/workflows/kb-create.json +15 -43
- package/vendor/server/skeleton/workflows/kb-navigate.json +8 -22
- package/vendor/server/skeleton/workflows/simple-coder.json +18 -46
- package/vendor/server/skeleton/workflows/starter.json +8 -22
- package/vendor/shared/dist/execution/derive-run-settle-outcome.js +2 -2
- package/vendor/shared/dist/execution/derive-run-settle-outcome.test.js +11 -8
- package/vendor/shared/dist/langflower-ws-waits.d.ts +3 -1
- package/vendor/shared/dist/langflower-ws-waits.js +2 -2
- package/ui-dist/main-2JJGCNTD.js +0 -313
- package/ui-dist/styles-EOXODOI7.css +0 -1
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { isBuiltinToolId, } from '@langflower/tools/create-project-harness';
|
|
2
2
|
import { formatPermissionDeniedText } from '@langflower/tools/permission';
|
|
3
|
-
export const SPAWN_SUBAGENT_TOOL = 'spawn_subagent';
|
|
4
3
|
const TOOL_LOG_PREVIEW = 400;
|
|
5
4
|
export const previewToolLogText = (text) => {
|
|
6
5
|
const trimmed = text.trim();
|
|
@@ -90,86 +89,3 @@ export const invokeInventoryTool = async (harness, tools, call, toolCtx, options
|
|
|
90
89
|
};
|
|
91
90
|
}
|
|
92
91
|
};
|
|
93
|
-
export const buildSpawnSubagentChatTool = (registrations) => {
|
|
94
|
-
const catalog = registrations
|
|
95
|
-
.map((reg) => {
|
|
96
|
-
const skills = reg.skills.length === 0
|
|
97
|
-
? 'none'
|
|
98
|
-
: reg.skills
|
|
99
|
-
.map((skill) => `${skill.skillId}${skill.description.length > 0 ? ` (${skill.description})` : ''}`)
|
|
100
|
-
.join(', ');
|
|
101
|
-
return `- nodeId=${reg.targetNodeId} name=${reg.name}: ${reg.description} skills=[${skills}]`;
|
|
102
|
-
})
|
|
103
|
-
.join('\n');
|
|
104
|
-
return {
|
|
105
|
-
type: 'function',
|
|
106
|
-
function: {
|
|
107
|
-
name: SPAWN_SUBAGENT_TOOL,
|
|
108
|
-
description: [
|
|
109
|
-
'Spawn one Sub-Agent on the canvas (sequential — wait for its result before another spawn).',
|
|
110
|
-
'Pick nodeId from the catalog. skillId may be empty if unused.',
|
|
111
|
-
'Catalog:',
|
|
112
|
-
catalog.length > 0 ? catalog : '(no Sub-Agents registered)',
|
|
113
|
-
].join('\n'),
|
|
114
|
-
parameters: {
|
|
115
|
-
type: 'object',
|
|
116
|
-
properties: {
|
|
117
|
-
nodeId: {
|
|
118
|
-
type: 'string',
|
|
119
|
-
description: 'targetNodeId of the Sub-Agent to spawn',
|
|
120
|
-
},
|
|
121
|
-
skillId: {
|
|
122
|
-
type: 'string',
|
|
123
|
-
description: 'Optional skill id announced by that Sub-Agent; empty if none',
|
|
124
|
-
},
|
|
125
|
-
task: {
|
|
126
|
-
type: 'string',
|
|
127
|
-
description: 'Task text for the Sub-Agent body',
|
|
128
|
-
},
|
|
129
|
-
},
|
|
130
|
-
required: ['nodeId', 'task'],
|
|
131
|
-
},
|
|
132
|
-
},
|
|
133
|
-
};
|
|
134
|
-
};
|
|
135
|
-
export const resolveSpawnPayload = (call, registrations, openCallId) => {
|
|
136
|
-
if (openCallId !== undefined) {
|
|
137
|
-
return {
|
|
138
|
-
ok: false,
|
|
139
|
-
text: `Serial spawn only: already waiting for callId=${openCallId}.`,
|
|
140
|
-
};
|
|
141
|
-
}
|
|
142
|
-
const args = parseToolArgs(call.arguments);
|
|
143
|
-
const nodeId = typeof args.nodeId === 'string' ? args.nodeId.trim() : '';
|
|
144
|
-
const task = typeof args.task === 'string' ? args.task : '';
|
|
145
|
-
const skillId = typeof args.skillId === 'string' ? args.skillId.trim() : '';
|
|
146
|
-
if (nodeId.length === 0) {
|
|
147
|
-
return { ok: false, text: 'spawn_subagent requires nodeId.' };
|
|
148
|
-
}
|
|
149
|
-
if (task.trim().length === 0) {
|
|
150
|
-
return { ok: false, text: 'spawn_subagent requires a non-empty task.' };
|
|
151
|
-
}
|
|
152
|
-
const target = registrations.find((reg) => reg.targetNodeId === nodeId);
|
|
153
|
-
if (target === undefined) {
|
|
154
|
-
return {
|
|
155
|
-
ok: false,
|
|
156
|
-
text: `Unknown Sub-Agent nodeId «${nodeId}» (not in subagentRegistration).`,
|
|
157
|
-
};
|
|
158
|
-
}
|
|
159
|
-
if (skillId.length > 0 &&
|
|
160
|
-
!target.skills.some((skill) => skill.skillId === skillId)) {
|
|
161
|
-
return {
|
|
162
|
-
ok: false,
|
|
163
|
-
text: `Skill «${skillId}» is not announced by Sub-Agent «${nodeId}».`,
|
|
164
|
-
};
|
|
165
|
-
}
|
|
166
|
-
return {
|
|
167
|
-
ok: true,
|
|
168
|
-
payload: {
|
|
169
|
-
callId: call.id,
|
|
170
|
-
nodeId,
|
|
171
|
-
skillId,
|
|
172
|
-
task,
|
|
173
|
-
},
|
|
174
|
-
};
|
|
175
|
-
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Optional hub: combine many `tools` wires into one `ToolHandle[]`.
|
|
3
|
+
* Duplicate `toolId` last-wins (later slot). Empty / unwired → `[]`.
|
|
4
|
+
*/
|
|
5
|
+
export declare const toolCollectionNode: {
|
|
6
|
+
readonly emitOncePerActivation: boolean;
|
|
7
|
+
readonly stopsRun: boolean;
|
|
8
|
+
readonly chatEntry: boolean;
|
|
9
|
+
readonly uiSchema: readonly [];
|
|
10
|
+
readonly bypassPorts: Record<string, import("@langflower/node-sdk").WireType>;
|
|
11
|
+
readonly inputsConfigs: readonly [import("@langflower/node-sdk").InputPortMeta<import("@langflower/node-sdk").ExecutionContext<readonly [], Record<string, never>>>, ...import("@langflower/node-sdk").InputPortMeta<unknown>[]];
|
|
12
|
+
readonly outputsConfigs: (import("@langflower/node-sdk").OutputParams & import("@langflower/node-sdk").PortMeta)[];
|
|
13
|
+
readonly getInstance: () => import("@langflower/node-sdk").ReactiveNodeInstance<readonly [], Record<string, never>>;
|
|
14
|
+
readonly paletteSecondary?: true;
|
|
15
|
+
readonly description?: string;
|
|
16
|
+
readonly type: string;
|
|
17
|
+
readonly displayName: string;
|
|
18
|
+
readonly category: string | undefined;
|
|
19
|
+
readonly icon: string | undefined;
|
|
20
|
+
};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { defineReactiveNode, TOOL_HANDLE_WIRE_TYPE, } from '@langflower/node-sdk';
|
|
2
|
+
import { map } from 'rxjs';
|
|
3
|
+
import { flattenToolHandles } from '../collect-agent-tool-handles.js';
|
|
4
|
+
const mergeToolHandlesLastWins = (wired) => {
|
|
5
|
+
const flattened = Array.isArray(wired)
|
|
6
|
+
? flattenToolHandles(wired)
|
|
7
|
+
: flattenToolHandles(wired === undefined || wired === null ? [] : [wired]);
|
|
8
|
+
const byId = new Map();
|
|
9
|
+
for (const handle of flattened) {
|
|
10
|
+
byId.set(handle.toolId, handle);
|
|
11
|
+
}
|
|
12
|
+
return [...byId.values()];
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Optional hub: combine many `tools` wires into one `ToolHandle[]`.
|
|
16
|
+
* Duplicate `toolId` last-wins (later slot). Empty / unwired → `[]`.
|
|
17
|
+
*/
|
|
18
|
+
export const toolCollectionNode = defineReactiveNode({
|
|
19
|
+
type: 'common-tool-collection',
|
|
20
|
+
displayName: 'Tool collection',
|
|
21
|
+
category: 'Tools',
|
|
22
|
+
description: 'Merges many `tools` wires into one `ToolHandle[]`. ' +
|
|
23
|
+
'Duplicate toolId last-wins. Optional — agents still accept multi combine.',
|
|
24
|
+
uiSchema: [],
|
|
25
|
+
bind(_ctx, { makeInput, configureOutput }) {
|
|
26
|
+
const tools = makeInput('tools', {
|
|
27
|
+
name: 'tools',
|
|
28
|
+
wireType: TOOL_HANDLE_WIRE_TYPE,
|
|
29
|
+
multi: 'combine',
|
|
30
|
+
defaultValue: [],
|
|
31
|
+
});
|
|
32
|
+
const merged$ = tools.pipeValue(map((wired) => mergeToolHandlesLastWins(wired)));
|
|
33
|
+
return {
|
|
34
|
+
inputs: [tools],
|
|
35
|
+
outputs: [
|
|
36
|
+
configureOutput('tools', merged$, {
|
|
37
|
+
wireType: TOOL_HANDLE_WIRE_TYPE,
|
|
38
|
+
}),
|
|
39
|
+
],
|
|
40
|
+
};
|
|
41
|
+
},
|
|
42
|
+
});
|
|
@@ -17,10 +17,6 @@
|
|
|
17
17
|
"types": "./dist/ai/features/llm-role-preset.d.ts",
|
|
18
18
|
"import": "./dist/ai/features/llm-role-preset.js"
|
|
19
19
|
},
|
|
20
|
-
"./ai/sub-agent-protocol": {
|
|
21
|
-
"types": "./dist/ai/features/sub-agent-protocol.d.ts",
|
|
22
|
-
"import": "./dist/ai/features/sub-agent-protocol.js"
|
|
23
|
-
},
|
|
24
20
|
"./ai/run-host-services": {
|
|
25
21
|
"types": "./dist/ai/features/run-host-services.d.ts",
|
|
26
22
|
"import": "./dist/ai/features/run-host-services.js"
|
|
@@ -38,7 +34,7 @@
|
|
|
38
34
|
"@langflower/node-sdk": "file:../node-sdk",
|
|
39
35
|
"@langflower/runtime": "file:../runtime",
|
|
40
36
|
"@langflower/tools": "file:../tools",
|
|
41
|
-
"@rx-evo/stateful-observable": "^0.
|
|
37
|
+
"@rx-evo/stateful-observable": "^0.6.0",
|
|
42
38
|
"openai": "^4.104.0",
|
|
43
39
|
"rxjs": "^7.8.1"
|
|
44
40
|
},
|
|
@@ -3,13 +3,10 @@ import type { StatefulObservable } from '@rx-evo/stateful-observable';
|
|
|
3
3
|
import type { configureOutput, InputConfig, makeInput, OutputConfig } from '../define-reactive-node/io-helpers.js';
|
|
4
4
|
import type { LlmRecoveryNotice } from './recovery-notice.js';
|
|
5
5
|
/** Port ids that every LLM-class node must expose (inventory + observability). */
|
|
6
|
-
export declare const LLM_INVENTORY_INPUT_PORT_IDS: readonly ["tools", "
|
|
7
|
-
export declare const LLM_INVENTORY_OUTPUT_PORT_IDS: readonly ["toolLog", "recovery"
|
|
6
|
+
export declare const LLM_INVENTORY_INPUT_PORT_IDS: readonly ["tools", "steerControl"];
|
|
7
|
+
export declare const LLM_INVENTORY_OUTPUT_PORT_IDS: readonly ["toolLog", "recovery"];
|
|
8
8
|
export type LlmInventoryInputs = {
|
|
9
9
|
readonly tools: InputConfig;
|
|
10
|
-
readonly mcp: InputConfig;
|
|
11
|
-
readonly subagentRegistration: InputConfig;
|
|
12
|
-
readonly subagentResult: InputConfig;
|
|
13
10
|
/** Soft Pause / Steer (ADR-032) — hidden + HITL textarea. */
|
|
14
11
|
readonly steerControl: InputConfig;
|
|
15
12
|
/** Ordered list for `inputs: [...]` spreads. */
|
|
@@ -18,7 +15,6 @@ export type LlmInventoryInputs = {
|
|
|
18
15
|
export type LlmInventoryOutputStreams = {
|
|
19
16
|
readonly toolLog$: StatefulObservable<string, unknown, PortMeta | undefined>;
|
|
20
17
|
readonly recovery$: StatefulObservable<LlmRecoveryNotice, unknown, PortMeta | undefined>;
|
|
21
|
-
readonly subagent$: StatefulObservable<unknown, unknown, PortMeta | undefined>;
|
|
22
18
|
};
|
|
23
19
|
/**
|
|
24
20
|
* Create the shared LLM inventory inputs. Authors may extend with role ports
|
|
@@ -26,6 +22,6 @@ export type LlmInventoryOutputStreams = {
|
|
|
26
22
|
*/
|
|
27
23
|
export declare const defaultLlmInventoryInputs: (make: typeof makeInput) => LlmInventoryInputs;
|
|
28
24
|
/**
|
|
29
|
-
* Configure the shared LLM inventory outputs (`toolLog`, `recovery
|
|
25
|
+
* Configure the shared LLM inventory outputs (`toolLog`, `recovery`).
|
|
30
26
|
*/
|
|
31
27
|
export declare const defaultLlmInventoryOutputs: (configure: typeof configureOutput, streams: LlmInventoryOutputStreams) => readonly OutputConfig[];
|
|
@@ -1,21 +1,12 @@
|
|
|
1
|
-
import { MCP_HANDLE_WIRE_TYPE } from '../define-mcp/mcp-handle.js';
|
|
2
1
|
import { TOOL_HANDLE_WIRE_TYPE } from '../define-tool-registrations/tool-handle.js';
|
|
3
|
-
import { SUBAGENT_REGISTRATION_WIRE_TYPE, SUBAGENT_RESULT_WIRE_TYPE, SUBAGENT_SPAWN_WIRE_TYPE, } from './llm-inventory-wire.js';
|
|
4
2
|
import { STEER_CONTROL_PORT_ID, } from './steer-control.js';
|
|
5
3
|
import { RECOVERY_PORT_ID } from './recovery-notice.js';
|
|
6
4
|
/** Port ids that every LLM-class node must expose (inventory + observability). */
|
|
7
5
|
export const LLM_INVENTORY_INPUT_PORT_IDS = [
|
|
8
6
|
'tools',
|
|
9
|
-
'mcp',
|
|
10
|
-
'subagentRegistration',
|
|
11
|
-
'subagentResult',
|
|
12
7
|
STEER_CONTROL_PORT_ID,
|
|
13
8
|
];
|
|
14
|
-
export const LLM_INVENTORY_OUTPUT_PORT_IDS = [
|
|
15
|
-
'toolLog',
|
|
16
|
-
'recovery',
|
|
17
|
-
'subagent',
|
|
18
|
-
];
|
|
9
|
+
export const LLM_INVENTORY_OUTPUT_PORT_IDS = ['toolLog', 'recovery'];
|
|
19
10
|
/**
|
|
20
11
|
* Create the shared LLM inventory inputs. Authors may extend with role ports
|
|
21
12
|
* but must not omit these.
|
|
@@ -27,26 +18,6 @@ export const defaultLlmInventoryInputs = (make) => {
|
|
|
27
18
|
multi: 'combine',
|
|
28
19
|
defaultValue: [],
|
|
29
20
|
});
|
|
30
|
-
const mcp = make('mcp', {
|
|
31
|
-
name: 'mcp',
|
|
32
|
-
wireType: MCP_HANDLE_WIRE_TYPE,
|
|
33
|
-
multi: 'combine',
|
|
34
|
-
defaultValue: [],
|
|
35
|
-
});
|
|
36
|
-
const subagentRegistration = make('subagentRegistration', {
|
|
37
|
-
name: 'subagentRegistration',
|
|
38
|
-
wireType: SUBAGENT_REGISTRATION_WIRE_TYPE,
|
|
39
|
-
multi: 'combine',
|
|
40
|
-
defaultValue: [],
|
|
41
|
-
});
|
|
42
|
-
const subagentResult = make('subagentResult', {
|
|
43
|
-
name: 'subagentResult',
|
|
44
|
-
wireType: SUBAGENT_RESULT_WIRE_TYPE,
|
|
45
|
-
multi: 'merge',
|
|
46
|
-
defaultValue: null,
|
|
47
|
-
// Protocol payload from Sub-Agent — omit from work log.
|
|
48
|
-
feed: { role: 'none' },
|
|
49
|
-
});
|
|
50
21
|
const steerControl = make(STEER_CONTROL_PORT_ID, {
|
|
51
22
|
name: 'Steer',
|
|
52
23
|
wireType: 'any',
|
|
@@ -64,21 +35,12 @@ export const defaultLlmInventoryInputs = (make) => {
|
|
|
64
35
|
});
|
|
65
36
|
return {
|
|
66
37
|
tools,
|
|
67
|
-
mcp,
|
|
68
|
-
subagentRegistration,
|
|
69
|
-
subagentResult,
|
|
70
38
|
steerControl,
|
|
71
|
-
inputs: [
|
|
72
|
-
tools,
|
|
73
|
-
mcp,
|
|
74
|
-
subagentRegistration,
|
|
75
|
-
subagentResult,
|
|
76
|
-
steerControl,
|
|
77
|
-
],
|
|
39
|
+
inputs: [tools, steerControl],
|
|
78
40
|
};
|
|
79
41
|
};
|
|
80
42
|
/**
|
|
81
|
-
* Configure the shared LLM inventory outputs (`toolLog`, `recovery
|
|
43
|
+
* Configure the shared LLM inventory outputs (`toolLog`, `recovery`).
|
|
82
44
|
*/
|
|
83
45
|
export const defaultLlmInventoryOutputs = (configure, streams) => [
|
|
84
46
|
configure('toolLog', streams.toolLog$, {
|
|
@@ -87,10 +49,8 @@ export const defaultLlmInventoryOutputs = (configure, streams) => [
|
|
|
87
49
|
}),
|
|
88
50
|
configure(RECOVERY_PORT_ID, streams.recovery$, {
|
|
89
51
|
wireType: 'any',
|
|
52
|
+
// Feed-only — canvas and palette skip hidden outputs.
|
|
90
53
|
hidden: true,
|
|
91
54
|
feed: { role: 'recovery', streaming: true },
|
|
92
55
|
}),
|
|
93
|
-
configure('subagent', streams.subagent$, {
|
|
94
|
-
wireType: SUBAGENT_SPAWN_WIRE_TYPE,
|
|
95
|
-
}),
|
|
96
56
|
];
|
|
@@ -17,10 +17,9 @@ type LlmCtx<UI extends readonly UISchemaConstItem[]> = Parameters<DefinedReactiv
|
|
|
17
17
|
export type { LlmExecutionCaps };
|
|
18
18
|
/**
|
|
19
19
|
* Purpose factory atop {@link defineReactiveNode}: every LLM-class node gets
|
|
20
|
-
* the shared inventory / observability ports (`tools`, `
|
|
21
|
-
* `
|
|
22
|
-
*
|
|
23
|
-
* inventory set.
|
|
20
|
+
* the shared inventory / observability ports (`tools`, `steerControl`,
|
|
21
|
+
* `toolLog`, `recovery`). Authors may extend with role ports but cannot omit
|
|
22
|
+
* the inventory set.
|
|
24
23
|
*/
|
|
25
24
|
export declare const defineLlmNode: <UI extends readonly UISchemaConstItem[]>(config: Omit<DefinedReactiveNodeConfig<UI, LlmExecutionCaps>, "bind"> & {
|
|
26
25
|
readonly bind: (ctx: LlmCtx<UI>, helpers: ReactiveBindHelpers, inventory: LlmInventoryInputs) => LlmBindResult;
|
|
@@ -41,6 +40,5 @@ export declare const defineLlmNode: <UI extends readonly UISchemaConstItem[]>(co
|
|
|
41
40
|
readonly icon: string | undefined;
|
|
42
41
|
};
|
|
43
42
|
export { LLM_INVENTORY_INPUT_PORT_IDS, LLM_INVENTORY_OUTPUT_PORT_IDS, type LlmInventoryInputs, type LlmInventoryOutputStreams, } from './default-llm-ports.js';
|
|
44
|
-
export { SUBAGENT_REGISTRATION_WIRE_TYPE, SUBAGENT_RESULT_WIRE_TYPE, SUBAGENT_SPAWN_WIRE_TYPE, } from './llm-inventory-wire.js';
|
|
45
43
|
export { STEER_CONTROL_PORT_ID, isSteerControlContinue, isSteerControlPause, isSteerControlPayload, type SteerControlPayload, type SteerControlPause, type SteerControlResume, type SteerControlSteer, } from './steer-control.js';
|
|
46
44
|
export { RECOVERY_PORT_ID, isLlmRecoveryNotice, isLlmRecoverySuspended, recoveryNoticeText, toLlmRecoveryPortValue, type LlmRecoveryNotice, type LlmRecoveryNoticeCode, type LlmRecoveryRetryReason, } from './recovery-notice.js';
|
|
@@ -21,10 +21,9 @@ const assertNoInventoryOutputs = (outputs) => {
|
|
|
21
21
|
};
|
|
22
22
|
/**
|
|
23
23
|
* Purpose factory atop {@link defineReactiveNode}: every LLM-class node gets
|
|
24
|
-
* the shared inventory / observability ports (`tools`, `
|
|
25
|
-
* `
|
|
26
|
-
*
|
|
27
|
-
* inventory set.
|
|
24
|
+
* the shared inventory / observability ports (`tools`, `steerControl`,
|
|
25
|
+
* `toolLog`, `recovery`). Authors may extend with role ports but cannot omit
|
|
26
|
+
* the inventory set.
|
|
28
27
|
*/
|
|
29
28
|
export const defineLlmNode = (config) => {
|
|
30
29
|
const { bind: authorBind, ...rest } = config;
|
|
@@ -46,6 +45,5 @@ export const defineLlmNode = (config) => {
|
|
|
46
45
|
});
|
|
47
46
|
};
|
|
48
47
|
export { LLM_INVENTORY_INPUT_PORT_IDS, LLM_INVENTORY_OUTPUT_PORT_IDS, } from './default-llm-ports.js';
|
|
49
|
-
export { SUBAGENT_REGISTRATION_WIRE_TYPE, SUBAGENT_RESULT_WIRE_TYPE, SUBAGENT_SPAWN_WIRE_TYPE, } from './llm-inventory-wire.js';
|
|
50
48
|
export { STEER_CONTROL_PORT_ID, isSteerControlContinue, isSteerControlPause, isSteerControlPayload, } from './steer-control.js';
|
|
51
49
|
export { RECOVERY_PORT_ID, isLlmRecoveryNotice, isLlmRecoverySuspended, recoveryNoticeText, toLlmRecoveryPortValue, } from './recovery-notice.js';
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { ToolHandle } from '../define-tool-registrations/tool-handle.js';
|
|
2
2
|
/**
|
|
3
|
-
* Live MCP session handle
|
|
4
|
-
*
|
|
5
|
-
*
|
|
3
|
+
* Live MCP session handle owned by MCP stdio/http nodes and server project
|
|
4
|
+
* MCP seed. Agents consume `tools` only — not a canvas wire type.
|
|
5
|
+
* Not JSON-serializable.
|
|
6
6
|
*/
|
|
7
7
|
export type McpHandle = {
|
|
8
8
|
/** Wire: graph nodeId. System: jsonc `mcp.servers` key. */
|
|
@@ -12,4 +12,3 @@ export type McpHandle = {
|
|
|
12
12
|
/** Tools listed+bound at connect (`tools/list`; system MCP may filter). */
|
|
13
13
|
readonly tools: readonly ToolHandle[];
|
|
14
14
|
};
|
|
15
|
-
export declare const MCP_HANDLE_WIRE_TYPE = "mcp-handle";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export
|
|
1
|
+
export {};
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import type { combineStatefulObservables, StatefulConnection, StatefulObservable } from '@rx-evo/stateful-observable';
|
|
2
|
-
import type { McpHandle } from '../define-mcp/mcp-handle.js';
|
|
3
2
|
import type { ToolHandle } from '../define-tool-registrations/tool-handle.js';
|
|
4
3
|
import type { CtxError } from './ctx-error.js';
|
|
5
4
|
import { configureOutput, InputConfig, makeInput, OutputConfig } from './io-helpers.js';
|
|
@@ -8,7 +7,7 @@ import type { AssertConstUISchema, ParamsFromUISchema, TypedUISchema, UISchemaCo
|
|
|
8
7
|
/**
|
|
9
8
|
* Identity + panel only. Host I/O (files/kb/crawl/…) is owned by specialized
|
|
10
9
|
* common-nodes internally — not part of the author ExecutionContext API.
|
|
11
|
-
* LLM inventory arrives via {@link LlmExecutionCaps} (`toolHandles`
|
|
10
|
+
* LLM inventory arrives via {@link LlmExecutionCaps} (`toolHandles`).
|
|
12
11
|
*/
|
|
13
12
|
export type ExecutionContext<UI extends readonly UISchemaConstItem[] = readonly UISchemaConstItem[], Caps extends object = Record<string, never>> = {
|
|
14
13
|
readonly projectDir: string;
|
|
@@ -18,10 +17,9 @@ export type ExecutionContext<UI extends readonly UISchemaConstItem[] = readonly
|
|
|
18
17
|
readonly uiSchema: TypedUISchema<UI>;
|
|
19
18
|
readonly amendInput?: (patch: Readonly<Record<string, unknown>>) => void;
|
|
20
19
|
} & Caps;
|
|
21
|
-
/** Caps for {@link defineLlmNode} — outside world via ToolHandle
|
|
20
|
+
/** Caps for {@link defineLlmNode} — outside world via ToolHandle only. */
|
|
22
21
|
export type LlmExecutionCaps = {
|
|
23
22
|
readonly toolHandles?: readonly ToolHandle[];
|
|
24
|
-
readonly mcpHandles?: readonly McpHandle[];
|
|
25
23
|
};
|
|
26
24
|
type ReactiveNodeBindResult = {
|
|
27
25
|
readonly inputs: InputConfig[];
|
|
@@ -14,7 +14,7 @@ export type UISchemaConstItem = {
|
|
|
14
14
|
readonly optionsSource?: 'langflower.providers' | 'langflower.models' | 'langflower.tools' | 'langflower.skills' | 'langflower.mcpServers' | 'node.wiredTools';
|
|
15
15
|
readonly dependsOn?: string;
|
|
16
16
|
};
|
|
17
|
-
export type DataTypeToTsType<D extends string> = D extends 'string' | 'url' | 'file-path' | 'select' | 'phase' | 'llm-message' ? string : D extends 'number' ? number : D extends 'boolean' ? boolean : D extends 'json' | 'tool-handle' | 'tool-registration' | '
|
|
17
|
+
export type DataTypeToTsType<D extends string> = D extends 'string' | 'url' | 'file-path' | 'select' | 'phase' | 'llm-message' ? string : D extends 'number' ? number : D extends 'boolean' ? boolean : D extends 'json' | 'tool-handle' | 'tool-registration' | 'tool-id-list' | 'tool-permission-table' | 'any' ? unknown : D extends 'stream' ? never : unknown;
|
|
18
18
|
export type UISchemaItemValue<I extends UISchemaConstItem> = DataTypeToTsType<I['type']>;
|
|
19
19
|
export type UISchemaFieldNames<UI extends readonly UISchemaConstItem[]> = UI[number]['field'];
|
|
20
20
|
export type AssertConstUISchema<UI extends readonly UISchemaConstItem[]> = string extends UISchemaFieldNames<UI> ? never : UI;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { RuntimeFeedPortMeta } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Tag one port emission with per-event feed meta. Runtime unwraps before
|
|
4
|
+
* telemetry and edges so the public value stays `T`.
|
|
5
|
+
*/
|
|
6
|
+
export declare const withPortFeed: <T>(value: T, feed: RuntimeFeedPortMeta) => T;
|
|
7
|
+
export declare const readPortFeedOverride: (raw: unknown) => {
|
|
8
|
+
readonly value: unknown;
|
|
9
|
+
readonly feed: RuntimeFeedPortMeta;
|
|
10
|
+
} | undefined;
|
|
11
|
+
/** Inner value when tagged; otherwise `raw` unchanged. */
|
|
12
|
+
export declare const unwrapPortFeedValue: (raw: unknown) => unknown;
|
|
13
|
+
//# sourceMappingURL=port-feed-override.d.ts.map
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
const PORT_FEED_TAG = Symbol.for('langflower.portFeed');
|
|
2
|
+
const isPortFeedBox = (raw) => typeof raw === 'object' && raw !== null && PORT_FEED_TAG in raw;
|
|
3
|
+
/**
|
|
4
|
+
* Tag one port emission with per-event feed meta. Runtime unwraps before
|
|
5
|
+
* telemetry and edges so the public value stays `T`.
|
|
6
|
+
*/
|
|
7
|
+
export const withPortFeed = (value, feed) => ({
|
|
8
|
+
[PORT_FEED_TAG]: { value, feed },
|
|
9
|
+
});
|
|
10
|
+
export const readPortFeedOverride = (raw) => {
|
|
11
|
+
if (!isPortFeedBox(raw)) {
|
|
12
|
+
return undefined;
|
|
13
|
+
}
|
|
14
|
+
return raw[PORT_FEED_TAG];
|
|
15
|
+
};
|
|
16
|
+
/** Inner value when tagged; otherwise `raw` unchanged. */
|
|
17
|
+
export const unwrapPortFeedValue = (raw) => {
|
|
18
|
+
const override = readPortFeedOverride(raw);
|
|
19
|
+
return override === undefined ? raw : override.value;
|
|
20
|
+
};
|
|
21
|
+
//# sourceMappingURL=port-feed-override.js.map
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type ResponseDto } from '@rx-evo/stateful-observable';
|
|
2
|
+
import type { RuntimeFeedPortMeta } from './types.js';
|
|
3
|
+
export type PortEmission = {
|
|
4
|
+
readonly response: ResponseDto<unknown>;
|
|
5
|
+
readonly feed: RuntimeFeedPortMeta | undefined;
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* JSON-safe {@link ResponseDto} for `PortTelemetry` slot 3, plus per-emit feed.
|
|
9
|
+
*/
|
|
10
|
+
export declare const toPortEmission: (response: unknown, defaultFeed: RuntimeFeedPortMeta | undefined) => PortEmission | null;
|
|
11
|
+
/** Drop sentinels and errors so edges only carry success values. */
|
|
12
|
+
export declare const isEdgeForwardable: (response: unknown) => boolean;
|
|
13
|
+
/** True when `raw$` is the inactive sentinel (unconnected / disconnected). */
|
|
14
|
+
export declare const isInactiveResponse: (response: unknown) => boolean;
|
|
15
|
+
//# sourceMappingURL=port-signal-from-response.d.ts.map
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { serializeResponse, } from '@rx-evo/stateful-observable';
|
|
2
|
+
import { normalizePortErrorValue } from './normalize-port-error-value.js';
|
|
3
|
+
import { readPortFeedOverride } from './port-feed-override.js';
|
|
4
|
+
const asResponse = (response) => response;
|
|
5
|
+
const toResponseDto = (response) => {
|
|
6
|
+
if (response === null || response === undefined) {
|
|
7
|
+
return null;
|
|
8
|
+
}
|
|
9
|
+
const dto = serializeResponse(asResponse(response));
|
|
10
|
+
if ('error' in dto) {
|
|
11
|
+
return { error: normalizePortErrorValue(dto.error) };
|
|
12
|
+
}
|
|
13
|
+
return dto;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* JSON-safe {@link ResponseDto} for `PortTelemetry` slot 3, plus per-emit feed.
|
|
17
|
+
*/
|
|
18
|
+
export const toPortEmission = (response, defaultFeed) => {
|
|
19
|
+
const dto = toResponseDto(response);
|
|
20
|
+
if (dto === null) {
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
if (!('value' in dto)) {
|
|
24
|
+
return { response: dto, feed: defaultFeed };
|
|
25
|
+
}
|
|
26
|
+
const override = readPortFeedOverride(dto.value);
|
|
27
|
+
if (override === undefined) {
|
|
28
|
+
return { response: dto, feed: defaultFeed };
|
|
29
|
+
}
|
|
30
|
+
return {
|
|
31
|
+
response: { value: override.value },
|
|
32
|
+
feed: override.feed,
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
/** Drop sentinels and errors so edges only carry success values. */
|
|
36
|
+
export const isEdgeForwardable = (response) => {
|
|
37
|
+
const dto = toResponseDto(response);
|
|
38
|
+
return dto !== null && 'value' in dto;
|
|
39
|
+
};
|
|
40
|
+
/** True when `raw$` is the inactive sentinel (unconnected / disconnected). */
|
|
41
|
+
export const isInactiveResponse = (response) => {
|
|
42
|
+
if (response === null || response === undefined) {
|
|
43
|
+
return true;
|
|
44
|
+
}
|
|
45
|
+
const dto = toResponseDto(response);
|
|
46
|
+
return dto !== null && 'inactive' in dto;
|
|
47
|
+
};
|
|
48
|
+
//# sourceMappingURL=port-signal-from-response.js.map
|
|
@@ -9,6 +9,8 @@ export declare class RuntimeRunner implements RuntimeRunnerApi {
|
|
|
9
9
|
private readonly logEvents;
|
|
10
10
|
private readonly eventLogBuffer;
|
|
11
11
|
private activeRun;
|
|
12
|
+
private pendingWireRunId;
|
|
13
|
+
private pendingWire;
|
|
12
14
|
private disposed;
|
|
13
15
|
readonly status$: Observable<RuntimeRunnerStatus>;
|
|
14
16
|
/** Synchronous snapshot of {@link status$}. */
|
|
@@ -38,9 +40,9 @@ export declare class RuntimeRunner implements RuntimeRunnerApi {
|
|
|
38
40
|
private pushIntoActiveRun;
|
|
39
41
|
/**
|
|
40
42
|
* Returns `output` wrapped with a `tap` that emits `output-emitted`
|
|
41
|
-
* telemetry, then
|
|
42
|
-
* loading sentinels stay visible
|
|
43
|
-
*
|
|
43
|
+
* telemetry, then forward only success values on edges so errors and
|
|
44
|
+
* loading sentinels stay visible on the source node (loading must not
|
|
45
|
+
* appear as `{}` downstream).
|
|
44
46
|
* The wrapper is the value the downstream connects to, so the event fires
|
|
45
47
|
* *as part of* the dataflow delivery — there is no separate refCounted
|
|
46
48
|
* subscriber, which is what previously reordered events against downstream
|
|
@@ -56,6 +58,9 @@ export declare class RuntimeRunner implements RuntimeRunnerApi {
|
|
|
56
58
|
*/
|
|
57
59
|
private tapInputPort;
|
|
58
60
|
private finishRun;
|
|
61
|
+
private assertResumeOutputSnapshots;
|
|
62
|
+
private cancelPendingWire;
|
|
63
|
+
private flushPendingWire;
|
|
59
64
|
private runScope;
|
|
60
65
|
private teardownRun;
|
|
61
66
|
private applySeeds;
|