langflower 0.0.8 → 0.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +2 -2
- package/ui-dist/{chunk-Y6VMBLSJ.js → chunk-7UMVYN3A.js} +1 -1
- package/ui-dist/{chunk-6DQ2XSRW.js → chunk-MDGXX73Z.js} +3 -3
- 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/chat-completion-stream.d.ts +2 -0
- package/vendor/common-nodes/dist/ai/critique/node.d.ts +246 -0
- package/vendor/common-nodes/dist/ai/critique/node.js +2 -2
- package/vendor/common-nodes/dist/ai/fake-llm/node.d.ts +246 -0
- package/vendor/common-nodes/dist/ai/features/chat-completion-stream.d.ts +53 -0
- package/vendor/common-nodes/dist/ai/features/chat-completion-stream.js +1 -0
- package/vendor/common-nodes/dist/ai/features/llm-loop/autokick-recovery.d.ts +13 -0
- package/vendor/common-nodes/dist/ai/features/llm-loop/autokick-recovery.js +17 -0
- package/vendor/common-nodes/dist/ai/features/llm-loop/classify-llm-failure.d.ts +2 -0
- package/vendor/common-nodes/dist/ai/features/llm-loop/classify-llm-failure.js +113 -0
- package/vendor/common-nodes/dist/ai/features/llm-loop/dead-loop-detector.d.ts +28 -0
- package/vendor/common-nodes/dist/ai/features/llm-loop/dead-loop-detector.js +194 -0
- package/vendor/common-nodes/dist/ai/features/llm-loop/live-get-tools.d.ts +9 -0
- package/vendor/common-nodes/dist/ai/features/llm-loop/live-get-tools.js +21 -0
- package/vendor/common-nodes/dist/ai/features/llm-loop/llm-loop-reducer.d.ts +2 -0
- package/vendor/common-nodes/dist/ai/features/llm-loop/llm-loop-reducer.js +204 -0
- package/vendor/common-nodes/dist/ai/features/llm-loop/llm-loop-types.d.ts +120 -0
- package/vendor/common-nodes/dist/ai/features/llm-loop/llm-loop-types.js +39 -0
- package/vendor/common-nodes/dist/ai/features/llm-loop/normalize-llm-recovery-policy.d.ts +2 -0
- package/vendor/common-nodes/dist/ai/features/llm-loop/normalize-llm-recovery-policy.js +59 -0
- package/vendor/common-nodes/dist/ai/features/llm-loop/operators/normalize-tool-result.d.ts +1 -0
- package/vendor/common-nodes/dist/ai/features/llm-loop/operators/normalize-tool-result.js +7 -0
- package/vendor/common-nodes/dist/ai/features/llm-loop/operators/observe-provider-stream.d.ts +43 -0
- package/vendor/common-nodes/dist/ai/features/llm-loop/operators/observe-provider-stream.js +96 -0
- package/vendor/common-nodes/dist/ai/features/llm-loop/run-agent-loop.d.ts +29 -0
- package/vendor/common-nodes/dist/ai/features/llm-loop/run-agent-loop.js +44 -0
- package/vendor/common-nodes/dist/ai/features/llm-loop/run-llm-loop.d.ts +74 -0
- package/vendor/common-nodes/dist/ai/features/llm-loop/run-llm-loop.js +658 -0
- package/vendor/common-nodes/dist/ai/features/llm-role-preset.d.ts +69 -0
- package/vendor/common-nodes/dist/ai/features/llm-role-preset.js +265 -0
- package/vendor/common-nodes/dist/ai/features/llm-session/llm-session-shell.d.ts +141 -0
- package/vendor/common-nodes/dist/ai/features/llm-session/llm-session-shell.js +193 -0
- package/vendor/common-nodes/dist/ai/features/llm-session/run-session-machine.d.ts +21 -0
- package/vendor/common-nodes/dist/ai/features/llm-session/run-session-machine.js +118 -0
- package/vendor/common-nodes/dist/ai/features/openai/context-length-error.d.ts +14 -0
- package/vendor/common-nodes/dist/ai/features/openai/context-length-error.js +63 -0
- package/vendor/common-nodes/dist/ai/features/openai/create-chat-completion-stream.d.ts +19 -0
- package/vendor/common-nodes/dist/ai/features/openai/create-chat-completion-stream.js +182 -0
- package/vendor/common-nodes/dist/ai/features/openai/list-provider-models.d.ts +28 -0
- package/vendor/common-nodes/dist/ai/features/openai/list-provider-models.js +52 -0
- package/vendor/common-nodes/dist/ai/features/openai/llm-context-compaction.d.ts +31 -0
- package/vendor/common-nodes/dist/ai/features/openai/llm-context-compaction.js +326 -0
- package/vendor/common-nodes/dist/ai/features/openai/normalize-compaction-params.d.ts +14 -0
- package/vendor/common-nodes/dist/ai/features/openai/normalize-compaction-params.js +21 -0
- package/vendor/common-nodes/dist/ai/features/openai/prepare-chat-completion.d.ts +30 -0
- package/vendor/common-nodes/dist/ai/features/openai/prepare-chat-completion.js +132 -0
- package/vendor/common-nodes/dist/ai/features/path-choice/control-tools.d.ts +20 -0
- package/vendor/common-nodes/dist/ai/features/path-choice/control-tools.js +70 -0
- package/vendor/common-nodes/dist/ai/features/path-choice/run-reactive-path-choice-loop.d.ts +32 -0
- package/vendor/common-nodes/dist/ai/features/path-choice/run-reactive-path-choice-loop.js +93 -0
- package/vendor/common-nodes/dist/ai/features/prompt/build-effective-system-prompt.d.ts +9 -0
- package/vendor/common-nodes/dist/ai/features/prompt/build-effective-system-prompt.js +21 -0
- package/vendor/common-nodes/dist/ai/features/prompt/normalize-max-iterations.d.ts +13 -0
- package/vendor/common-nodes/dist/ai/features/prompt/normalize-max-iterations.js +23 -0
- package/vendor/common-nodes/dist/ai/features/prompt/resolve-chat-provider-model.d.ts +10 -0
- package/vendor/common-nodes/dist/ai/features/prompt/resolve-chat-provider-model.js +8 -0
- package/vendor/common-nodes/dist/ai/features/run-host-services.d.ts +54 -0
- package/vendor/common-nodes/dist/ai/features/run-host-services.js +29 -0
- package/vendor/common-nodes/dist/ai/features/scripted-chat-completion-stream.d.ts +17 -0
- package/vendor/common-nodes/dist/ai/features/scripted-chat-completion-stream.js +61 -0
- package/vendor/common-nodes/dist/ai/features/sub-agent-protocol.d.ts +40 -0
- package/vendor/common-nodes/dist/ai/features/sub-agent-protocol.js +44 -0
- package/vendor/common-nodes/dist/ai/features/ui-schema/llm-compaction-ui-schema.d.ts +14 -0
- package/vendor/common-nodes/dist/ai/features/ui-schema/llm-compaction-ui-schema.js +18 -0
- package/vendor/common-nodes/dist/ai/features/ui-schema/llm-panel-ui-schema.d.ts +80 -0
- package/vendor/common-nodes/dist/ai/features/ui-schema/llm-panel-ui-schema.js +76 -0
- package/vendor/common-nodes/dist/ai/features/ui-schema/llm-recovery-ui-schema.d.ts +113 -0
- package/vendor/common-nodes/dist/ai/features/ui-schema/llm-recovery-ui-schema.js +131 -0
- package/vendor/common-nodes/dist/ai/features/wait-for-subagent-result.d.ts +7 -0
- package/vendor/common-nodes/dist/ai/features/wait-for-subagent-result.js +31 -0
- package/vendor/common-nodes/dist/ai/llm-loop/autokick-recovery.d.ts +13 -0
- package/vendor/common-nodes/dist/ai/llm-loop/autokick-recovery.js +17 -0
- package/vendor/common-nodes/dist/ai/llm-loop/dead-loop-detector.d.ts +28 -0
- package/vendor/common-nodes/dist/ai/llm-loop/dead-loop-detector.js +194 -0
- package/vendor/common-nodes/dist/ai/llm-loop/llm-loop-reducer.js +36 -0
- package/vendor/common-nodes/dist/ai/llm-loop/llm-loop-types.d.ts +35 -0
- package/vendor/common-nodes/dist/ai/llm-loop/llm-loop-types.js +19 -0
- package/vendor/common-nodes/dist/ai/llm-loop/normalize-llm-recovery-policy.js +52 -9
- package/vendor/common-nodes/dist/ai/llm-loop/operators/observe-provider-stream.d.ts +8 -2
- package/vendor/common-nodes/dist/ai/llm-loop/operators/observe-provider-stream.js +43 -13
- package/vendor/common-nodes/dist/ai/llm-loop/run-llm-loop.d.ts +3 -5
- package/vendor/common-nodes/dist/ai/llm-loop/run-llm-loop.js +116 -1
- package/vendor/common-nodes/dist/ai/llm-recovery-ui-schema.d.ts +82 -0
- package/vendor/common-nodes/dist/ai/llm-recovery-ui-schema.js +95 -0
- package/vendor/common-nodes/dist/ai/llm-session-shell.d.ts +4 -9
- package/vendor/common-nodes/dist/ai/llm-session-shell.js +2 -4
- package/vendor/common-nodes/dist/ai/nodes/critique/node.d.ts +588 -0
- package/vendor/common-nodes/dist/ai/nodes/critique/node.js +227 -0
- package/vendor/common-nodes/dist/ai/nodes/fake-llm/node.d.ts +571 -0
- package/vendor/common-nodes/dist/ai/nodes/fake-llm/node.js +201 -0
- package/vendor/common-nodes/dist/ai/nodes/openai-llm/node.d.ts +587 -0
- package/vendor/common-nodes/dist/ai/nodes/openai-llm/node.js +84 -0
- package/vendor/common-nodes/dist/ai/nodes/review/node.d.ts +593 -0
- package/vendor/common-nodes/dist/ai/nodes/review/node.js +227 -0
- package/vendor/common-nodes/dist/ai/nodes/sub-agent/node.d.ts +630 -0
- package/vendor/common-nodes/dist/ai/nodes/sub-agent/node.js +417 -0
- package/vendor/common-nodes/dist/ai/openai/create-chat-completion-stream.js +6 -0
- package/vendor/common-nodes/dist/ai/openai/prepare-chat-completion.d.ts +2 -0
- package/vendor/common-nodes/dist/ai/openai/prepare-chat-completion.js +18 -0
- package/vendor/common-nodes/dist/ai/openai-llm/node.d.ts +246 -0
- package/vendor/common-nodes/dist/ai/review/node.d.ts +246 -0
- package/vendor/common-nodes/dist/ai/review/node.js +2 -2
- package/vendor/common-nodes/dist/ai/sub-agent/node.d.ts +246 -0
- package/vendor/common-nodes/dist/ai/sub-agent/node.js +2 -2
- package/vendor/common-nodes/dist/catalog.js +9 -5
- package/vendor/common-nodes/dist/compile-custom-nodes/node.d.ts +21 -0
- package/vendor/common-nodes/dist/compile-custom-nodes/node.js +45 -0
- package/vendor/common-nodes/dist/crawl/crawl/node.js +1 -1
- package/vendor/common-nodes/dist/crawl/fetch-url/node.js +1 -1
- package/vendor/common-nodes/dist/flow/repeat/node.js +6 -1
- package/vendor/common-nodes/dist/langflower-tools/emit-registration-tools.d.ts +18 -0
- package/vendor/common-nodes/dist/langflower-tools/emit-registration-tools.js +29 -0
- package/vendor/common-nodes/dist/langflower-tools/node.d.ts +20 -0
- package/vendor/common-nodes/dist/langflower-tools/node.js +77 -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/text/append-file/node.js +1 -1
- package/vendor/common-nodes/dist/text/read-file/node.js +1 -1
- package/vendor/common-nodes/dist/text/write-file/node.js +1 -1
- 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 +1 -11
- 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 +9 -13
- package/vendor/compiler/dist/compile-project-nodes.d.ts +2 -1
- package/vendor/compiler/dist/compile-project-nodes.js +35 -6
- package/vendor/compiler/dist/resolve-host-types.d.ts +0 -5
- package/vendor/compiler/dist/resolve-host-types.js +0 -8
- 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 +4 -6
- package/vendor/node-sdk/dist/node-factory/define-llm-node/define-llm-node.js +4 -6
- 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-llm-node/recovery-notice.d.ts +8 -0
- package/vendor/node-sdk/dist/node-factory/define-llm-node/recovery-notice.js +14 -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-editor.d.ts +5 -1
- package/vendor/runtime/dist/runtime-editor.js +19 -0
- package/vendor/runtime/dist/runtime-runner.d.ts +8 -3
- package/vendor/runtime/dist/runtime-runner.js +108 -87
- package/vendor/runtime/dist/runtime.d.ts +3 -1
- package/vendor/runtime/dist/runtime.js +1 -0
- package/vendor/runtime/dist/testing/workflows/workflow-events.d.ts +10 -6
- package/vendor/runtime/dist/testing/workflows/workflow-events.js +21 -31
- package/vendor/runtime/dist/types.d.ts +52 -40
- package/vendor/runtime/dist/types.js +5 -1
- package/vendor/runtime/package.json +1 -1
- package/vendor/server/dist/bridge/attach-langflower-bridge.js +3 -2
- package/vendor/server/dist/bridge/bridge-event-log.js +17 -102
- package/vendor/server/dist/bridge/build-execution-context.d.ts +5 -2
- package/vendor/server/dist/bridge/build-execution-context.js +48 -8
- package/vendor/server/dist/bridge/forward-runner-event.d.ts +1 -1
- package/vendor/server/dist/bridge/forward-runner-event.js +7 -12
- package/vendor/server/dist/bridge/get-live-wired-tools.d.ts +13 -0
- package/vendor/server/dist/bridge/get-live-wired-tools.js +83 -0
- package/vendor/server/dist/bridge/langflower-tools-rpc.d.ts +7 -0
- package/vendor/server/dist/bridge/langflower-tools-rpc.js +29 -0
- package/vendor/server/dist/bridge/wire-custom-palette-handlers.d.ts +2 -1
- package/vendor/server/dist/bridge/wire-custom-palette-handlers.js +3 -5
- package/vendor/server/dist/bridge/wire-runner-handlers.js +17 -10
- package/vendor/server/dist/bridge/wire-workflow-handlers.js +23 -9
- package/vendor/server/dist/checkpoint/run-checkpoint-session.d.ts +1 -1
- package/vendor/server/dist/checkpoint/run-checkpoint-session.js +10 -9
- package/vendor/server/dist/palette/compile-and-hot-swap-custom-nodes.d.ts +10 -0
- package/vendor/server/dist/palette/compile-and-hot-swap-custom-nodes.js +23 -0
- 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/dist/workflow/apply-editor-mutation.d.ts +5 -0
- package/vendor/server/dist/workflow/apply-editor-mutation.js +32 -0
- package/vendor/server/skeleton/instructions.md +9 -5
- package/vendor/server/skeleton/nodes/my-nodes/README.md +4 -3
- package/vendor/server/skeleton/nodes/my-nodes/package.json +1 -1
- package/vendor/server/skeleton/skills/langflower-helper/SKILL.md +82 -38
- package/vendor/server/skeleton/skills/langflower-helper/architecture.md +29 -10
- package/vendor/server/skeleton/skills/langflower-helper/layout.md +16 -15
- package/vendor/server/skeleton/skills/langflower-node-writer/SKILL.md +19 -9
- package/vendor/server/skeleton/skills/langflower-workflow-writer/SKILL.md +23 -15
- 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 +35 -22
- package/vendor/shared/dist/execution/derive-run-settle-outcome.d.ts +1 -1
- package/vendor/shared/dist/execution/derive-run-settle-outcome.js +4 -3
- package/vendor/shared/dist/execution/derive-run-settle-outcome.test.js +18 -15
- package/vendor/shared/dist/langflower-bus-config.d.ts +6 -14
- package/vendor/shared/dist/langflower-bus-config.js +4 -12
- package/vendor/shared/dist/langflower-config/resolve-wired-tool-options.js +6 -0
- package/vendor/shared/dist/langflower-config/resolve-wired-tool-options.test.js +30 -0
- package/vendor/shared/dist/langflower-ws-waits.d.ts +9 -14
- package/vendor/shared/dist/langflower-ws-waits.js +14 -14
- package/vendor/websocket-bridge/dist/bridge-codec.d.ts +1 -0
- package/vendor/websocket-bridge/dist/bridge-codec.js +11 -11
- package/vendor/websocket-bridge/dist/bridge-frame.js +1 -1
- package/vendor/websocket-bridge/dist/bridge-subjects.d.ts +1 -1
- package/vendor/websocket-bridge/dist/bridge-subjects.js +2 -2
- package/vendor/websocket-bridge/dist/bridge-types.d.ts +13 -1
- package/vendor/websocket-bridge/dist/create-client.js +3 -3
- package/vendor/websocket-bridge/dist/create-server.js +12 -6
- package/vendor/websocket-bridge/package.json +8 -0
- package/ui-dist/main-ECEWAM6V.js +0 -311
- package/ui-dist/styles-EOXODOI7.css +0 -1
|
@@ -4,6 +4,7 @@ export { bypassOutputPortId, parseBypassOutputPortId } from './bypass-ports.js';
|
|
|
4
4
|
export { RuntimeEditor } from './runtime-editor.js';
|
|
5
5
|
export { graphHasCycle } from './runtime-helpers.js';
|
|
6
6
|
export { RuntimeRunner } from './runtime-runner.js';
|
|
7
|
+
export { isPortErrorTelemetry, isPortPendingTelemetry, isPortTelemetry, isPortValueTelemetry, isRuntimeDone, } from './types.js';
|
|
7
8
|
export class RuntimeFacade {
|
|
8
9
|
editor;
|
|
9
10
|
runner;
|
|
@@ -1,20 +1,24 @@
|
|
|
1
|
+
import { type EdgeId, type PortTelemetry, type RunId, type RuntimeEdge, type RuntimeRunnerEvent } from '../../types.js';
|
|
1
2
|
import { RuntimeEditor } from '../../runtime-editor.js';
|
|
2
3
|
import { RuntimeRunner } from '../../runtime-runner.js';
|
|
3
4
|
import { type RuntimeOptions } from '../../runtime.js';
|
|
4
|
-
import type { RunId, RuntimeEdge, RuntimeRunnerEvent } from '../../types.js';
|
|
5
5
|
export type RuntimeHarness = {
|
|
6
6
|
readonly editor: RuntimeEditor;
|
|
7
7
|
readonly runner: RuntimeRunner;
|
|
8
8
|
};
|
|
9
9
|
export declare function createRuntimeHarness(options?: RuntimeOptions): RuntimeHarness;
|
|
10
10
|
export declare function wireEdge(editor: RuntimeEditor, edge: Omit<RuntimeEdge, 'edgeId'>): void;
|
|
11
|
-
export type OutputEmittedEvent =
|
|
12
|
-
|
|
13
|
-
}
|
|
14
|
-
export declare function outputValues(events: readonly RuntimeRunnerEvent[], nodeId: string, portId: string,
|
|
15
|
-
export declare function waitForOutput(runtime: RuntimeRunner | RuntimeHarness, nodeId: string, portId: string,
|
|
11
|
+
export type OutputEmittedEvent = PortTelemetry & {
|
|
12
|
+
readonly 0: 'out';
|
|
13
|
+
};
|
|
14
|
+
export declare function outputValues(events: readonly RuntimeRunnerEvent[], nodeId: string, portId: string, _runId?: string): unknown[];
|
|
15
|
+
export declare function waitForOutput(runtime: RuntimeRunner | RuntimeHarness, nodeId: string, portId: string, _runId?: string): Promise<OutputEmittedEvent>;
|
|
16
16
|
export declare function runAndCollectEvents(runtime: RuntimeRunner | RuntimeHarness, startRun: () => string, settleMs?: number): Promise<{
|
|
17
17
|
readonly runId: string;
|
|
18
18
|
readonly events: readonly RuntimeRunnerEvent[];
|
|
19
19
|
}>;
|
|
20
20
|
export declare function noDoneWithin(runtime: RuntimeRunner | RuntimeHarness, ms: number, runId?: RunId): Promise<boolean>;
|
|
21
|
+
export declare const edgeIdsFromPortEvent: (event: PortTelemetry) => readonly EdgeId[];
|
|
22
|
+
export declare const portDirLabel: (event: PortTelemetry) => "input-received" | "output-emitted";
|
|
23
|
+
export declare const dtoHas: (dtos: readonly unknown[], key: "pending" | "value" | "error" | "inactive") => boolean;
|
|
24
|
+
export declare const dtoIndex: (dtos: readonly unknown[], key: "pending" | "value" | "error" | "inactive") => number;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { filter, firstValueFrom } from 'rxjs';
|
|
2
|
+
import { isPortValueTelemetry, isRuntimeDone, } from '../../types.js';
|
|
2
3
|
import { RuntimeEditor } from '../../runtime-editor.js';
|
|
3
4
|
import { RuntimeRunner } from '../../runtime-runner.js';
|
|
4
5
|
export function createRuntimeHarness(options) {
|
|
@@ -17,27 +18,23 @@ export function wireEdge(editor, edge) {
|
|
|
17
18
|
throw new Error(`Failed to wire ${edge.fromNodeId}.${edge.fromPort[0]} → ${edge.toNodeId}.${edge.toPort[0]}`);
|
|
18
19
|
}
|
|
19
20
|
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
}
|
|
23
|
-
export function outputValues(events, nodeId, portId, runId) {
|
|
21
|
+
const isOutputValue = (event) => isPortValueTelemetry(event) && event[0] === 'out';
|
|
22
|
+
export function outputValues(events, nodeId, portId, _runId) {
|
|
24
23
|
return events
|
|
25
|
-
.filter((event) =>
|
|
26
|
-
event
|
|
27
|
-
event
|
|
28
|
-
(
|
|
29
|
-
.map((event) => event.value);
|
|
24
|
+
.filter((event) => isOutputValue(event) &&
|
|
25
|
+
event[1] === nodeId &&
|
|
26
|
+
event[2] === portId)
|
|
27
|
+
.map((event) => event[3].value);
|
|
30
28
|
}
|
|
31
|
-
export async function waitForOutput(runtime, nodeId, portId,
|
|
32
|
-
return waitForOutputMatching(runtime, nodeId, portId, () => true,
|
|
29
|
+
export async function waitForOutput(runtime, nodeId, portId, _runId) {
|
|
30
|
+
return waitForOutputMatching(runtime, nodeId, portId, () => true, _runId);
|
|
33
31
|
}
|
|
34
|
-
async function waitForOutputMatching(runtime, nodeId, portId, predicate,
|
|
32
|
+
async function waitForOutputMatching(runtime, nodeId, portId, predicate, _runId) {
|
|
35
33
|
const runner = resolveRunner(runtime);
|
|
36
|
-
return firstValueFrom(runner.events$.pipe(filter((event) =>
|
|
37
|
-
event
|
|
38
|
-
event
|
|
39
|
-
(
|
|
40
|
-
predicate(event.value))));
|
|
34
|
+
return firstValueFrom(runner.events$.pipe(filter((event) => isOutputValue(event) &&
|
|
35
|
+
event[1] === nodeId &&
|
|
36
|
+
event[2] === portId &&
|
|
37
|
+
predicate(event[3].value))));
|
|
41
38
|
}
|
|
42
39
|
export async function runAndCollectEvents(runtime, startRun, settleMs = 50) {
|
|
43
40
|
const events = [];
|
|
@@ -52,26 +49,19 @@ export async function runAndCollectEvents(runtime, startRun, settleMs = 50) {
|
|
|
52
49
|
subscription.unsubscribe();
|
|
53
50
|
return { runId, events };
|
|
54
51
|
}
|
|
55
|
-
async function collectEventsForMs(runtime, ms) {
|
|
56
|
-
const events = [];
|
|
57
|
-
const runner = resolveRunner(runtime);
|
|
58
|
-
const subscription = runner.events$.subscribe((event) => {
|
|
59
|
-
events.push(event);
|
|
60
|
-
});
|
|
61
|
-
await new Promise((resolve) => {
|
|
62
|
-
setTimeout(resolve, ms);
|
|
63
|
-
});
|
|
64
|
-
subscription.unsubscribe();
|
|
65
|
-
return events;
|
|
66
|
-
}
|
|
67
52
|
export async function noDoneWithin(runtime, ms, runId) {
|
|
68
53
|
const runner = resolveRunner(runtime);
|
|
69
54
|
const result = await Promise.race([
|
|
70
|
-
firstValueFrom(runner.events$.pipe(filter((event) => event
|
|
71
|
-
|
|
55
|
+
firstValueFrom(runner.events$.pipe(filter((event) => isRuntimeDone(event) &&
|
|
56
|
+
event.length === 2 &&
|
|
57
|
+
(runId === undefined || event[1] === runId)))).then(() => 'done'),
|
|
72
58
|
new Promise((resolve) => {
|
|
73
59
|
setTimeout(() => resolve('timeout'), ms);
|
|
74
60
|
}),
|
|
75
61
|
]);
|
|
76
62
|
return result === 'timeout';
|
|
77
63
|
}
|
|
64
|
+
export const edgeIdsFromPortEvent = (event) => event[5];
|
|
65
|
+
export const portDirLabel = (event) => event[0] === 'out' ? 'output-emitted' : 'input-received';
|
|
66
|
+
export const dtoHas = (dtos, key) => dtos.some((dto) => typeof dto === 'object' && dto !== null && key in dto);
|
|
67
|
+
export const dtoIndex = (dtos, key) => dtos.findIndex((dto) => typeof dto === 'object' && dto !== null && key in dto);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { StatefulConnection, StatefulObservable } from '@rx-evo/stateful-observable';
|
|
1
|
+
import type { ResponseDto, StatefulConnection, StatefulObservable } from '@rx-evo/stateful-observable';
|
|
2
2
|
import type { Observable } from 'rxjs';
|
|
3
3
|
import type { GraphCluster } from './runtime-helpers.js';
|
|
4
4
|
export type RuntimeWireType = string & {
|
|
@@ -83,7 +83,7 @@ export type MetaFromStatefulObservable<T extends StatefulObservable<unknown, unk
|
|
|
83
83
|
*
|
|
84
84
|
* ## Errors
|
|
85
85
|
* Node handlers surface failures via RxJS / `StatefulObservable` (`catchError`,
|
|
86
|
-
* port `error$`). Runner telemetry emits `
|
|
86
|
+
* port `error$`). Runner telemetry emits `ResponseDto` `{ error }`
|
|
87
87
|
* on the source; wiring then drops `ResponseError` so edges do not cascade
|
|
88
88
|
* error chrome to downstream nodes.
|
|
89
89
|
*
|
|
@@ -118,45 +118,41 @@ export type MetaFromStatefulObservable<T extends StatefulObservable<unknown, unk
|
|
|
118
118
|
* optional {@link RuntimeNode.stopsRun} completion.
|
|
119
119
|
*/
|
|
120
120
|
export type RuntimeRunnerStatus = 'idle' | 'running' | 'stopped';
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
readonly
|
|
121
|
+
/**
|
|
122
|
+
* Port signal tuple — `portDir` `'out'` = output emitted, `'in'` = input received.
|
|
123
|
+
* Slot 3 is `@rx-evo` {@link ResponseDto} (JSON-safe pending / inactive / error /
|
|
124
|
+
* value). No per-frame `runId`; session snapshots own run correlation.
|
|
125
|
+
*/
|
|
126
|
+
export type PortTelemetry = readonly [
|
|
127
|
+
portDir: 'in' | 'out',
|
|
128
|
+
nodeId: NodeId,
|
|
129
|
+
portId: string,
|
|
130
|
+
response: ResponseDto<unknown>,
|
|
131
|
+
portIdx: number,
|
|
132
|
+
edgeIds: readonly EdgeId[],
|
|
133
|
+
/** Absent feed meta — use `null` (never `undefined`; JSON arrays drop undefined). */
|
|
134
|
+
feed: RuntimeFeedPortMeta | null
|
|
135
|
+
];
|
|
136
|
+
/** Run ended — `runId` at index 1 when replay needs explicit correlation. */
|
|
137
|
+
export type RuntimeDoneTelemetry = readonly ['done'] | readonly ['done', RunId];
|
|
138
|
+
export type RuntimeRunnerEvent = PortTelemetry | RuntimeDoneTelemetry;
|
|
139
|
+
export declare const isPortTelemetry: (event: RuntimeRunnerEvent) => event is PortTelemetry;
|
|
140
|
+
export declare const isPortValueTelemetry: (event: RuntimeRunnerEvent) => event is PortTelemetry & {
|
|
141
|
+
readonly 3: Extract<ResponseDto<unknown>, {
|
|
142
|
+
value: unknown;
|
|
143
|
+
}>;
|
|
133
144
|
};
|
|
134
|
-
export
|
|
135
|
-
readonly
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
readonly portId: string | symbol;
|
|
139
|
-
readonly portIdx: number;
|
|
140
|
-
readonly edgeIds: EdgeId[];
|
|
141
|
-
readonly state: RuntimePortSignalState;
|
|
142
|
-
readonly value: unknown;
|
|
143
|
-
/** Resolved author feed contract carried with the runtime fact. */
|
|
144
|
-
readonly feed?: RuntimeFeedPortMeta;
|
|
145
|
+
export declare const isPortErrorTelemetry: (event: RuntimeRunnerEvent) => event is PortTelemetry & {
|
|
146
|
+
readonly 3: Extract<ResponseDto<unknown>, {
|
|
147
|
+
error: unknown;
|
|
148
|
+
}>;
|
|
145
149
|
};
|
|
146
|
-
export
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
* Emitted when:
|
|
151
|
-
* - the graph is **empty** on {@link RuntimeRunner.start}, or
|
|
152
|
-
* - a node with {@link RuntimeNode.stopsRun} emits on a watched output.
|
|
153
|
-
*
|
|
154
|
-
* Otherwise the run stays `'running'` until
|
|
155
|
-
* {@link RuntimeRunner.interrupt}.
|
|
156
|
-
*/
|
|
157
|
-
readonly kind: 'done';
|
|
158
|
-
readonly runId: RunId;
|
|
150
|
+
export declare const isPortPendingTelemetry: (event: RuntimeRunnerEvent) => event is PortTelemetry & {
|
|
151
|
+
readonly 3: {
|
|
152
|
+
readonly pending: true;
|
|
153
|
+
};
|
|
159
154
|
};
|
|
155
|
+
export declare const isRuntimeDone: (event: RuntimeRunnerEvent) => event is RuntimeDoneTelemetry;
|
|
160
156
|
/** Seed value pushed into an input port slot on {@link RuntimeRunner.start}. */
|
|
161
157
|
export type RuntimeSeedPortValue = {
|
|
162
158
|
readonly portId: string | symbol;
|
|
@@ -255,6 +251,10 @@ export type RuntimeOptions = {
|
|
|
255
251
|
*/
|
|
256
252
|
readonly log?: boolean;
|
|
257
253
|
};
|
|
254
|
+
export type SwapNodeResult = {
|
|
255
|
+
readonly node: RuntimeNode;
|
|
256
|
+
readonly droppedEdges: readonly RuntimeEdge[];
|
|
257
|
+
};
|
|
258
258
|
export type RuntimeEditorApi = {
|
|
259
259
|
/**
|
|
260
260
|
* Register a node and its port observables (handler already bound).
|
|
@@ -288,6 +288,15 @@ export type RuntimeEditorApi = {
|
|
|
288
288
|
* graph is locked. Does not cascade-remove other edges.
|
|
289
289
|
*/
|
|
290
290
|
replaceEdge(edge: Omit<RuntimeEdge, 'edgeId'>): RuntimeEdge | false;
|
|
291
|
+
/**
|
|
292
|
+
* Replace the live instance at `nodeId` with `next`. Keeps `nodeId`.
|
|
293
|
+
* Drops incident edges whose ports vanished or whose wire types are no
|
|
294
|
+
* longer compatible (same rules as {@link addEdge}).
|
|
295
|
+
*
|
|
296
|
+
* Allowed while the graph is locked. Does not call {@link addNode} /
|
|
297
|
+
* {@link removeNode}. Returns `false` when disposed or `nodeId` is missing.
|
|
298
|
+
*/
|
|
299
|
+
swapNode(nodeId: NodeId, next: Omit<RuntimeNode, 'nodeId'>): SwapNodeResult | false;
|
|
291
300
|
/** Must fail while runner status is `'running'`.
|
|
292
301
|
*
|
|
293
302
|
* return false while running or node not found
|
|
@@ -314,7 +323,9 @@ export type RuntimeEditorApi = {
|
|
|
314
323
|
export type RuntimeRunnerApi = {
|
|
315
324
|
/**
|
|
316
325
|
* Wire every cluster that does not contain a {@link RuntimeNode.chatEntry}
|
|
317
|
-
* node
|
|
326
|
+
* node. Assigns `runId` and sets `'running'` **synchronously**, then wires
|
|
327
|
+
* ports on a microtask so callers (WS `runner.started`) can fence before
|
|
328
|
+
* any `runner.port` telemetry.
|
|
318
329
|
*
|
|
319
330
|
* Chat-entry clusters are omitted — start them via
|
|
320
331
|
* {@link RuntimeRunnerApi.pushIntoInput}. When every cluster is chat-entry
|
|
@@ -331,7 +342,8 @@ export type RuntimeRunnerApi = {
|
|
|
331
342
|
start(initialPayload?: Readonly<Record<string, ReadonlyArray<RuntimeSeedPortValue>>>, runId?: RunId): RunId | false;
|
|
332
343
|
/**
|
|
333
344
|
* Run-from-node: wire the weakly connected cluster containing `nodeId`
|
|
334
|
-
* (orphan nodes elsewhere on the canvas are not wired).
|
|
345
|
+
* (orphan nodes elsewhere on the canvas are not wired). Same runId /
|
|
346
|
+
* `'running'` sync + microtask wiring as {@link RuntimeRunnerApi.start}.
|
|
335
347
|
*
|
|
336
348
|
* Run stays `'running'` until {@link RuntimeRunnerApi.interrupt} or a
|
|
337
349
|
* {@link RuntimeNode.stopsRun} node in scope emits.
|
|
@@ -1 +1,5 @@
|
|
|
1
|
-
export
|
|
1
|
+
export const isPortTelemetry = (event) => Array.isArray(event) && (event[0] === 'in' || event[0] === 'out');
|
|
2
|
+
export const isPortValueTelemetry = (event) => isPortTelemetry(event) && 'value' in event[3];
|
|
3
|
+
export const isPortErrorTelemetry = (event) => isPortTelemetry(event) && 'error' in event[3];
|
|
4
|
+
export const isPortPendingTelemetry = (event) => isPortTelemetry(event) && 'pending' in event[3];
|
|
5
|
+
export const isRuntimeDone = (event) => Array.isArray(event) && event[0] === 'done';
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { isRuntimeDone } from '@langflower/runtime';
|
|
1
2
|
import { deriveExecutionProgressStatus, terminalExecutionProgressStatus, } from '@langflower/shared/langflower.js';
|
|
2
3
|
import { Subscription } from 'rxjs';
|
|
3
4
|
import { RunCheckpointSession } from '../checkpoint/run-checkpoint-session.js';
|
|
@@ -36,7 +37,7 @@ export const attachLangflowerBridge = (bridge, context, options = {}) => {
|
|
|
36
37
|
// miss them (`events$` is a non-replaying Subject). Late clients get the
|
|
37
38
|
// backlog via `executionFeed.snapshot`. See FOUND_BUGS pending race.
|
|
38
39
|
rootSubscription.add(session.runtime.runner.events$.subscribe((event) => {
|
|
39
|
-
if (event
|
|
40
|
+
if (isRuntimeDone(event) && onRunSettled !== undefined) {
|
|
40
41
|
const progress = deriveExecutionProgressStatus('idle', session.runtime.runner.eventLog);
|
|
41
42
|
const status = terminalExecutionProgressStatus(progress);
|
|
42
43
|
if (status !== null) {
|
|
@@ -59,7 +60,7 @@ export const attachLangflowerBridge = (bridge, context, options = {}) => {
|
|
|
59
60
|
// 3. Intent handlers (bus namespaces)
|
|
60
61
|
rootSubscription.add(wireWorkflowHandlers(bridge, context, session));
|
|
61
62
|
rootSubscription.add(wirePaletteHandlers(bridge, context));
|
|
62
|
-
rootSubscription.add(wireCustomPaletteHandlers(bridge, context));
|
|
63
|
+
rootSubscription.add(wireCustomPaletteHandlers(bridge, context, session));
|
|
63
64
|
rootSubscription.add(wireConfigHandlers(bridge, context, session, draftController, {
|
|
64
65
|
onEffectiveConfig: (config) => {
|
|
65
66
|
applyServerLogsGate(diagnosticLog.setEnabled, config);
|
|
@@ -2,67 +2,22 @@ import { randomUUID } from 'node:crypto';
|
|
|
2
2
|
import { promises as fs } from 'node:fs';
|
|
3
3
|
import path from 'node:path';
|
|
4
4
|
import { langflowerWsConfig } from '@langflower/shared/langflower.js';
|
|
5
|
+
import { encodeBridgeFrame } from '@langflower/websocket-bridge/bridge-codec';
|
|
5
6
|
import { Subscription } from 'rxjs';
|
|
6
|
-
const REDACTED = '[REDACTED]';
|
|
7
|
-
const isRecord = (value) => typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
8
|
-
const isSecretKey = (key) => {
|
|
9
|
-
const normalized = key.toLowerCase();
|
|
10
|
-
return (normalized.includes('apikey') ||
|
|
11
|
-
normalized.includes('authorization') ||
|
|
12
|
-
normalized.includes('cookie') ||
|
|
13
|
-
normalized.includes('token') ||
|
|
14
|
-
normalized.includes('password') ||
|
|
15
|
-
normalized.includes('secret') ||
|
|
16
|
-
normalized.includes('credential'));
|
|
17
|
-
};
|
|
18
|
-
const sanitize = (value, seen = new WeakSet()) => {
|
|
19
|
-
if (value === null ||
|
|
20
|
-
typeof value === 'string' ||
|
|
21
|
-
typeof value === 'number' ||
|
|
22
|
-
typeof value === 'boolean') {
|
|
23
|
-
return value;
|
|
24
|
-
}
|
|
25
|
-
if (typeof value === 'bigint') {
|
|
26
|
-
return `${value}n`;
|
|
27
|
-
}
|
|
28
|
-
if (typeof value === 'undefined') {
|
|
29
|
-
return '[undefined]';
|
|
30
|
-
}
|
|
31
|
-
if (typeof value === 'symbol' || typeof value === 'function') {
|
|
32
|
-
return `[${typeof value}]`;
|
|
33
|
-
}
|
|
34
|
-
if (value instanceof Error) {
|
|
35
|
-
return {
|
|
36
|
-
name: value.name,
|
|
37
|
-
message: value.message,
|
|
38
|
-
};
|
|
39
|
-
}
|
|
40
|
-
if (value instanceof Date) {
|
|
41
|
-
return value.toISOString();
|
|
42
|
-
}
|
|
43
|
-
if (typeof value === 'object') {
|
|
44
|
-
if (seen.has(value)) {
|
|
45
|
-
return '[circular]';
|
|
46
|
-
}
|
|
47
|
-
seen.add(value);
|
|
48
|
-
}
|
|
49
|
-
if (Array.isArray(value)) {
|
|
50
|
-
return value.map((entry) => sanitize(entry, seen));
|
|
51
|
-
}
|
|
52
|
-
if (isRecord(value)) {
|
|
53
|
-
return Object.fromEntries(Object.entries(value).map(([key, entry]) => [
|
|
54
|
-
key,
|
|
55
|
-
isSecretKey(key) ? REDACTED : sanitize(entry, seen),
|
|
56
|
-
]));
|
|
57
|
-
}
|
|
58
|
-
return String(value);
|
|
59
|
-
};
|
|
60
7
|
const toSafeTimestamp = (date) => date.toISOString().replaceAll(':', '-').replaceAll('.', '-');
|
|
61
|
-
const asObservable = (value) =>
|
|
8
|
+
const asObservable = (value) => typeof value === 'object' &&
|
|
9
|
+
value !== null &&
|
|
10
|
+
typeof value.subscribe === 'function'
|
|
62
11
|
? value
|
|
63
12
|
: undefined;
|
|
64
|
-
const asInboundEvent = (value) =>
|
|
65
|
-
|
|
13
|
+
const asInboundEvent = (value) => typeof value === 'object' &&
|
|
14
|
+
value !== null &&
|
|
15
|
+
typeof value.clientId === 'string' &&
|
|
16
|
+
'payload' in value
|
|
17
|
+
? {
|
|
18
|
+
clientId: value.clientId,
|
|
19
|
+
payload: value.payload,
|
|
20
|
+
}
|
|
66
21
|
: undefined;
|
|
67
22
|
const logPath = (projectDir) => path.join(projectDir, '.langflower', 'logs', `${toSafeTimestamp(new Date())}-${process.pid}-${randomUUID()}.log`);
|
|
68
23
|
export const attachBridgeEventLog = (bridge, projectDir, subscriptions, options = {}) => {
|
|
@@ -81,15 +36,11 @@ export const attachBridgeEventLog = (bridge, projectDir, subscriptions, options
|
|
|
81
36
|
const message = error instanceof Error ? error.message : String(error);
|
|
82
37
|
process.stderr.write(`Langflower diagnostic logging disabled: ${message}\n`);
|
|
83
38
|
};
|
|
84
|
-
const
|
|
39
|
+
const writeFrame = (transportDir, busType, payload) => {
|
|
85
40
|
if (!enabled || !acceptingWrites || closed) {
|
|
86
41
|
return;
|
|
87
42
|
}
|
|
88
|
-
const line = `${
|
|
89
|
-
schemaVersion: 1,
|
|
90
|
-
timestamp: new Date().toISOString(),
|
|
91
|
-
...record,
|
|
92
|
-
}))}\n`;
|
|
43
|
+
const line = `${encodeBridgeFrame(transportDir, busType, payload)}\n`;
|
|
93
44
|
writeQueue = writeQueue.then(async () => {
|
|
94
45
|
if (!enabled || !acceptingWrites) {
|
|
95
46
|
return;
|
|
@@ -118,13 +69,7 @@ export const attachBridgeEventLog = (bridge, projectDir, subscriptions, options
|
|
|
118
69
|
subscriptions.add(channel.subscribe((value) => {
|
|
119
70
|
const event = asInboundEvent(value);
|
|
120
71
|
if (event !== undefined) {
|
|
121
|
-
|
|
122
|
-
kind: 'frame',
|
|
123
|
-
direction: 'inbound',
|
|
124
|
-
clientId: event.clientId,
|
|
125
|
-
type,
|
|
126
|
-
payload: event.payload,
|
|
127
|
-
});
|
|
72
|
+
writeFrame('in', type, event.payload);
|
|
128
73
|
}
|
|
129
74
|
}));
|
|
130
75
|
}
|
|
@@ -134,30 +79,10 @@ export const attachBridgeEventLog = (bridge, projectDir, subscriptions, options
|
|
|
134
79
|
continue;
|
|
135
80
|
}
|
|
136
81
|
subscriptions.add(channel.subscribe((payload) => {
|
|
137
|
-
|
|
138
|
-
kind: 'frame',
|
|
139
|
-
direction: 'outbound',
|
|
140
|
-
scope: 'broadcast',
|
|
141
|
-
type,
|
|
142
|
-
payload,
|
|
143
|
-
});
|
|
82
|
+
writeFrame('out', type, payload);
|
|
144
83
|
}));
|
|
145
84
|
}
|
|
146
|
-
subscriptions.add(bridge.status$.subscribe((status) => {
|
|
147
|
-
write({ kind: 'status', status });
|
|
148
|
-
}));
|
|
149
|
-
subscriptions.add(bridge.errors$.subscribe((error) => {
|
|
150
|
-
write({
|
|
151
|
-
kind: 'error',
|
|
152
|
-
error: {
|
|
153
|
-
code: error.code,
|
|
154
|
-
message: error.message,
|
|
155
|
-
...('cause' in error ? { cause: error.cause } : {}),
|
|
156
|
-
},
|
|
157
|
-
});
|
|
158
|
-
}));
|
|
159
85
|
subscriptions.add(bridge.connections$.subscribe((client) => {
|
|
160
|
-
write({ kind: 'connection', clientId: client.id });
|
|
161
86
|
const clientSubscriptions = new Subscription();
|
|
162
87
|
subscriptions.add(clientSubscriptions);
|
|
163
88
|
const clientChannels = client;
|
|
@@ -167,29 +92,19 @@ export const attachBridgeEventLog = (bridge, projectDir, subscriptions, options
|
|
|
167
92
|
continue;
|
|
168
93
|
}
|
|
169
94
|
clientSubscriptions.add(channel.subscribe((payload) => {
|
|
170
|
-
|
|
171
|
-
kind: 'frame',
|
|
172
|
-
direction: 'outbound',
|
|
173
|
-
scope: 'client',
|
|
174
|
-
clientId: client.id,
|
|
175
|
-
type,
|
|
176
|
-
payload,
|
|
177
|
-
});
|
|
95
|
+
writeFrame('out', type, payload);
|
|
178
96
|
}));
|
|
179
97
|
}
|
|
180
98
|
clientSubscriptions.add(client.disconnected$.subscribe(() => {
|
|
181
|
-
write({ kind: 'disconnection', clientId: client.id });
|
|
182
99
|
clientSubscriptions.unsubscribe();
|
|
183
100
|
}));
|
|
184
101
|
}));
|
|
185
|
-
write({ kind: 'server-started' });
|
|
186
102
|
return {
|
|
187
103
|
filePath,
|
|
188
104
|
setEnabled: (nextEnabled) => {
|
|
189
105
|
enabled = nextEnabled;
|
|
190
106
|
},
|
|
191
107
|
writeServerClosing: () => {
|
|
192
|
-
write({ kind: 'server-closing' });
|
|
193
108
|
closed = true;
|
|
194
109
|
},
|
|
195
110
|
flush: async () => {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { LangflowerBusRequest } from '@langflower/common-nodes/ai/run-host-services';
|
|
2
|
+
import { type ExecutionContext, type ToolHandle } from '@langflower/node-sdk';
|
|
2
3
|
import type { LlmExecutionCaps } from '@langflower/node-sdk/llm';
|
|
3
4
|
import type { McpHandle } from '@langflower/node-sdk/mcp';
|
|
4
5
|
import type { RuntimeSeedPortValue } from '@langflower/runtime';
|
|
@@ -16,6 +17,8 @@ type BuildHarnessHooks = {
|
|
|
16
17
|
readonly nodeId: string;
|
|
17
18
|
readonly requestPermission: LangflowerSession['permissionAsks']['requestPermission'];
|
|
18
19
|
readonly emitPermissionAsk: (payload: RunnerPermissionAskPayload) => void;
|
|
20
|
+
readonly requestLangflowerBus?: LangflowerBusRequest;
|
|
21
|
+
readonly getLiveWiredTools?: (agentNodeId: string) => readonly ToolHandle[];
|
|
19
22
|
};
|
|
20
23
|
export declare const buildExecutionContext: (context: ExecutionContextDeps, runId: string, node: WorkflowGraphNode, hooks?: BuildHarnessHooks, preloadedConfig?: LangflowerConfig, runMcpHandles?: readonly McpHandle[]) => Promise<ExecutionContext<never, LlmExecutionCaps>>;
|
|
21
24
|
/**
|
|
@@ -24,5 +27,5 @@ export declare const buildExecutionContext: (context: ExecutionContextDeps, runI
|
|
|
24
27
|
* which would put the Observable in value$ instead of error$.
|
|
25
28
|
*/
|
|
26
29
|
export declare const applyObservableContextSeeds: (session: LangflowerSession, seeds: Readonly<Record<string, ReadonlyArray<RuntimeSeedPortValue>>>) => Record<string, ReadonlyArray<RuntimeSeedPortValue>>;
|
|
27
|
-
export declare const buildContextSeeds: (session: LangflowerSession, context: ExecutionContextDeps, runId: string, emitPermissionAsk: (payload: RunnerPermissionAskPayload) => void) => Promise<Record<string, ReadonlyArray<RuntimeSeedPortValue>>>;
|
|
30
|
+
export declare const buildContextSeeds: (session: LangflowerSession, context: ExecutionContextDeps, runId: string, emitPermissionAsk: (payload: RunnerPermissionAskPayload) => void, requestLangflowerBus?: LangflowerBusRequest, getLiveWiredTools?: (agentNodeId: string) => readonly ToolHandle[]) => Promise<Record<string, ReadonlyArray<RuntimeSeedPortValue>>>;
|
|
28
31
|
export {};
|
|
@@ -28,6 +28,13 @@ const createToolHarness = (options) => {
|
|
|
28
28
|
: {}),
|
|
29
29
|
});
|
|
30
30
|
};
|
|
31
|
+
const LIVE_WIRED_TOOLS_NODE_TYPES = new Set([
|
|
32
|
+
'common-openai-llm',
|
|
33
|
+
'common-fake-llm',
|
|
34
|
+
'common-review',
|
|
35
|
+
'common-critique',
|
|
36
|
+
'common-sub-agent',
|
|
37
|
+
]);
|
|
31
38
|
export const buildExecutionContext = async (context, runId, node, hooks, preloadedConfig, runMcpHandles) => {
|
|
32
39
|
const rolePreset = parseLlmRolePreset(node.params.rolePreset);
|
|
33
40
|
const skillId = resolveEffectiveSkillId(rolePreset, node.params.skillId);
|
|
@@ -66,8 +73,9 @@ export const buildExecutionContext = async (context, runId, node, hooks, preload
|
|
|
66
73
|
webFetch,
|
|
67
74
|
};
|
|
68
75
|
const enabledToolIds = toolPermissionsToEnabledIds(toolPermissions);
|
|
69
|
-
const
|
|
70
|
-
const
|
|
76
|
+
const builtinHandles = wrapBuiltinToolHandles(harness, enabledToolIds, permission);
|
|
77
|
+
const mcpTools = filterMcpHandlesByIds(runMcpHandles ?? [], parseEnabledMcpIds(node.params.enabledMcpIds)).flatMap((handle) => handle.tools);
|
|
78
|
+
const toolHandles = [...builtinHandles, ...mcpTools];
|
|
71
79
|
const base = {
|
|
72
80
|
projectDir: context.projectDir,
|
|
73
81
|
runId,
|
|
@@ -78,7 +86,6 @@ export const buildExecutionContext = async (context, runId, node, hooks, preload
|
|
|
78
86
|
params: node.params,
|
|
79
87
|
})?.uiSchema ?? []),
|
|
80
88
|
...(toolHandles.length > 0 ? { toolHandles } : {}),
|
|
81
|
-
...(mcpHandles.length > 0 ? { mcpHandles } : {}),
|
|
82
89
|
};
|
|
83
90
|
const defaultChat = parseDefaultChatModel(config.model);
|
|
84
91
|
return attachRunHostServices(base, {
|
|
@@ -104,8 +111,28 @@ export const buildExecutionContext = async (context, runId, node, hooks, preload
|
|
|
104
111
|
...(config.harness?.allowedHosts !== undefined
|
|
105
112
|
? { allowedHosts: config.harness.allowedHosts }
|
|
106
113
|
: {}),
|
|
114
|
+
...(hooks?.requestLangflowerBus !== undefined &&
|
|
115
|
+
node.type === 'common-langflower-tools'
|
|
116
|
+
? { requestLangflowerBus: hooks.requestLangflowerBus }
|
|
117
|
+
: {}),
|
|
118
|
+
...(hooks?.getLiveWiredTools !== undefined &&
|
|
119
|
+
LIVE_WIRED_TOOLS_NODE_TYPES.has(node.type)
|
|
120
|
+
? { getLiveWiredTools: hooks.getLiveWiredTools }
|
|
121
|
+
: {}),
|
|
107
122
|
});
|
|
108
123
|
};
|
|
124
|
+
/** Host `contextSymbol` vs compiled-pack duplicate (`file://` / Vitest alias). */
|
|
125
|
+
const contextPortLabel = String(contextSymbol);
|
|
126
|
+
const resolveLiveContextPortId = (session, nodeId) => {
|
|
127
|
+
const node = session.runtime.editor.getNode(nodeId);
|
|
128
|
+
if (node === false || node.inputs[contextSymbol] !== undefined) {
|
|
129
|
+
return contextSymbol;
|
|
130
|
+
}
|
|
131
|
+
const match = Object.getOwnPropertySymbols(node.inputs).find((portId) => String(portId) === contextPortLabel);
|
|
132
|
+
return match ?? contextSymbol;
|
|
133
|
+
};
|
|
134
|
+
const isContextSeedPort = (portId) => portId === contextSymbol ||
|
|
135
|
+
(typeof portId === 'symbol' && String(portId) === contextPortLabel);
|
|
109
136
|
const ctxErrorFromFailures = (failures) => ({
|
|
110
137
|
message: failures.map((failure) => failure.message).join('\n'),
|
|
111
138
|
});
|
|
@@ -119,9 +146,10 @@ export const applyObservableContextSeeds = (session, seeds) => {
|
|
|
119
146
|
for (const [nodeId, list] of Object.entries(seeds)) {
|
|
120
147
|
const kept = [];
|
|
121
148
|
for (const seed of list) {
|
|
122
|
-
if (seed.portId
|
|
149
|
+
if (isContextSeedPort(seed.portId) && isObservable(seed.value)) {
|
|
123
150
|
const node = session.runtime.editor.getNode(nodeId);
|
|
124
|
-
const
|
|
151
|
+
const portId = resolveLiveContextPortId(session, nodeId);
|
|
152
|
+
const connection = node === false ? undefined : node.inputs[portId];
|
|
125
153
|
if (connection !== undefined) {
|
|
126
154
|
connection.connect(seed.value);
|
|
127
155
|
}
|
|
@@ -135,7 +163,7 @@ export const applyObservableContextSeeds = (session, seeds) => {
|
|
|
135
163
|
}
|
|
136
164
|
return valueSeeds;
|
|
137
165
|
};
|
|
138
|
-
export const buildContextSeeds = async (session, context, runId, emitPermissionAsk) => {
|
|
166
|
+
export const buildContextSeeds = async (session, context, runId, emitPermissionAsk, requestLangflowerBus, getLiveWiredTools) => {
|
|
139
167
|
const workflow = session.activeWorkflow;
|
|
140
168
|
if (workflow === null) {
|
|
141
169
|
return {};
|
|
@@ -160,7 +188,7 @@ export const buildContextSeeds = async (session, context, runId, emitPermissionA
|
|
|
160
188
|
const error = ctxErrorFromFailures(nodeFailures);
|
|
161
189
|
seeds[node.id] = [
|
|
162
190
|
{
|
|
163
|
-
portId:
|
|
191
|
+
portId: resolveLiveContextPortId(session, node.id),
|
|
164
192
|
slotIndex: 0,
|
|
165
193
|
value: throwError(() => error),
|
|
166
194
|
},
|
|
@@ -172,8 +200,20 @@ export const buildContextSeeds = async (session, context, runId, emitPermissionA
|
|
|
172
200
|
nodeId: node.id,
|
|
173
201
|
requestPermission: session.permissionAsks.requestPermission,
|
|
174
202
|
emitPermissionAsk,
|
|
203
|
+
...(requestLangflowerBus !== undefined
|
|
204
|
+
? { requestLangflowerBus }
|
|
205
|
+
: {}),
|
|
206
|
+
...(getLiveWiredTools !== undefined
|
|
207
|
+
? { getLiveWiredTools }
|
|
208
|
+
: {}),
|
|
175
209
|
}, config, runMcp?.handles);
|
|
176
|
-
seeds[node.id] = [
|
|
210
|
+
seeds[node.id] = [
|
|
211
|
+
{
|
|
212
|
+
portId: resolveLiveContextPortId(session, node.id),
|
|
213
|
+
slotIndex: 0,
|
|
214
|
+
value: ctx,
|
|
215
|
+
},
|
|
216
|
+
];
|
|
177
217
|
}
|
|
178
218
|
return seeds;
|
|
179
219
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type RuntimeRunnerEvent } from '@langflower/runtime';
|
|
2
2
|
import type { LangflowerBridge } from './langflower-bridge.types.js';
|
|
3
3
|
/** Fan-out runner telemetry to every connected tab (session-shared). */
|
|
4
4
|
export declare const forwardRunnerEvent: (bridge: LangflowerBridge, event: RuntimeRunnerEvent) => void;
|
|
@@ -1,17 +1,12 @@
|
|
|
1
|
+
import { isPortTelemetry, isRuntimeDone, } from '@langflower/runtime';
|
|
1
2
|
import { bridgeEmit } from './bridge-outbound.js';
|
|
2
3
|
/** Fan-out runner telemetry to every connected tab (session-shared). */
|
|
3
4
|
export const forwardRunnerEvent = (bridge, event) => {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
break;
|
|
11
|
-
case 'done':
|
|
12
|
-
bridgeEmit(bridge, 'runner.done', event);
|
|
13
|
-
break;
|
|
14
|
-
default:
|
|
15
|
-
break;
|
|
5
|
+
if (isPortTelemetry(event)) {
|
|
6
|
+
bridgeEmit(bridge, 'runner.port', event);
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
if (isRuntimeDone(event)) {
|
|
10
|
+
bridgeEmit(bridge, 'runner.done', event);
|
|
16
11
|
}
|
|
17
12
|
};
|