langflower 0.0.7 → 0.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- 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 +1 -1
- package/ui-dist/main-2JJGCNTD.js +313 -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 +216 -0
- package/vendor/common-nodes/dist/ai/features/llm-loop/llm-loop-types.d.ts +125 -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 +32 -0
- package/vendor/common-nodes/dist/ai/features/llm-loop/run-agent-loop.js +58 -0
- package/vendor/common-nodes/dist/ai/features/llm-loop/run-llm-loop.d.ts +80 -0
- package/vendor/common-nodes/dist/ai/features/llm-loop/run-llm-loop.js +681 -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 +148 -0
- package/vendor/common-nodes/dist/ai/features/llm-session/llm-session-shell.js +198 -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 +35 -0
- package/vendor/common-nodes/dist/ai/features/path-choice/run-reactive-path-choice-loop.js +106 -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 +39 -0
- package/vendor/common-nodes/dist/ai/features/sub-agent-protocol.js +43 -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 +6 -0
- package/vendor/common-nodes/dist/ai/features/wait-for-subagent-result.js +30 -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 +240 -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 +208 -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 +91 -0
- package/vendor/common-nodes/dist/ai/nodes/review/node.d.ts +593 -0
- package/vendor/common-nodes/dist/ai/nodes/review/node.js +240 -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 +302 -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 +7 -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/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/inventory-tool-round.d.ts +2 -2
- package/vendor/common-nodes/package.json +10 -10
- 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/node-sdk/dist/node-factory/define-llm-node/define-llm-node.d.ts +1 -1
- package/vendor/node-sdk/dist/node-factory/define-llm-node/define-llm-node.js +1 -1
- 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/runtime/dist/runtime-editor.d.ts +5 -1
- package/vendor/runtime/dist/runtime-editor.js +19 -0
- package/vendor/runtime/dist/runtime-runner.js +17 -17
- package/vendor/runtime/dist/runtime.d.ts +2 -1
- package/vendor/runtime/dist/runtime.js +1 -0
- package/vendor/runtime/dist/testing/workflows/workflow-events.d.ts +8 -6
- package/vendor/runtime/dist/testing/workflows/workflow-events.js +19 -31
- package/vendor/runtime/dist/types.d.ts +33 -38
- package/vendor/runtime/dist/types.js +2 -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 +45 -5
- 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 +12 -0
- package/vendor/server/dist/bridge/get-live-wired-tools.js +80 -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/settings-draft-controller.js +26 -3
- 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 +15 -8
- 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/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/schemas/langflower-config.schema.json +11 -1
- package/vendor/server/skeleton/skills/langflower-helper/SKILL.md +49 -19
- package/vendor/server/skeleton/skills/langflower-helper/architecture.md +22 -9
- package/vendor/server/skeleton/skills/langflower-helper/layout.md +15 -15
- package/vendor/server/skeleton/skills/langflower-node-writer/SKILL.md +19 -9
- package/vendor/server/skeleton/skills/langflower-workflow-writer/SKILL.md +14 -10
- package/vendor/server/skeleton/workflows/starter.json +30 -3
- 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 +9 -9
- 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 +7 -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-SMO3L7U5.js +0 -311
|
@@ -36,10 +36,11 @@ export const repeatNode = defineReactiveNode({
|
|
|
36
36
|
return of({ kind: 'done' });
|
|
37
37
|
}
|
|
38
38
|
return trigger.value$.pipe(startWith(undefined), take(n + 1), observeOn(asapScheduler), map((_, index) => index < n
|
|
39
|
-
? { kind: 'value', value: v }
|
|
39
|
+
? { kind: 'value', value: v, index }
|
|
40
40
|
: { kind: 'done' }));
|
|
41
41
|
}));
|
|
42
42
|
const valueOut$ = session$.pipeValue(filter((e) => e.kind === 'value'), map((e) => e.value));
|
|
43
|
+
const indexOut$ = session$.pipeValue(filter((e) => e.kind === 'value'), map((e) => e.index));
|
|
43
44
|
const doneOut$ = session$.pipeValue(filter((e) => e.kind === 'done'), map(() => true));
|
|
44
45
|
return {
|
|
45
46
|
inputs: [value, count, trigger],
|
|
@@ -47,8 +48,12 @@ export const repeatNode = defineReactiveNode({
|
|
|
47
48
|
configureOutput('value', valueOut$, {
|
|
48
49
|
inferTypeFrom: value,
|
|
49
50
|
}),
|
|
51
|
+
configureOutput('index', indexOut$, {
|
|
52
|
+
wireType: 'number',
|
|
53
|
+
}),
|
|
50
54
|
configureOutput('done', doneOut$, {
|
|
51
55
|
wireType: 'boolean',
|
|
56
|
+
feed: { role: 'none' },
|
|
52
57
|
}),
|
|
53
58
|
],
|
|
54
59
|
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { type ToolHandle, type ToolHandler } from '@langflower/node-sdk';
|
|
2
|
+
import { type Observable } from 'rxjs';
|
|
3
|
+
type RegistrationTool = {
|
|
4
|
+
readonly toolId: string;
|
|
5
|
+
readonly name?: string;
|
|
6
|
+
readonly description: string;
|
|
7
|
+
readonly inputSchema: object;
|
|
8
|
+
readonly handler: ToolHandler;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Emit a `tools` pack, peeking **this** node's EC at invoke so bus RPC
|
|
12
|
+
* stays on the pack instance (not agent `toolCtx`). Local to this folder —
|
|
13
|
+
* not the author SDK factory.
|
|
14
|
+
*/
|
|
15
|
+
export declare const emitRegistrationTools: (ctx: {
|
|
16
|
+
readonly value$: Observable<unknown>;
|
|
17
|
+
}, tools: readonly RegistrationTool[]) => import("@rx-evo/stateful-observable").StatefulObservable<ToolHandle[], unknown, undefined>;
|
|
18
|
+
export {};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { statefulObservable } from '@rx-evo/stateful-observable';
|
|
2
|
+
import { of } from 'rxjs';
|
|
3
|
+
const peekNodeContext = (source) => {
|
|
4
|
+
let peeked;
|
|
5
|
+
const sub = source.value$.subscribe((value) => {
|
|
6
|
+
peeked = value;
|
|
7
|
+
});
|
|
8
|
+
sub.unsubscribe();
|
|
9
|
+
return typeof peeked === 'object' && peeked !== null
|
|
10
|
+
? peeked
|
|
11
|
+
: undefined;
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Emit a `tools` pack, peeking **this** node's EC at invoke so bus RPC
|
|
15
|
+
* stays on the pack instance (not agent `toolCtx`). Local to this folder —
|
|
16
|
+
* not the author SDK factory.
|
|
17
|
+
*/
|
|
18
|
+
export const emitRegistrationTools = (ctx, tools) => statefulObservable({
|
|
19
|
+
loader: () => of(tools.map((tool) => ({
|
|
20
|
+
toolId: tool.toolId,
|
|
21
|
+
name: tool.name ?? tool.toolId,
|
|
22
|
+
description: tool.description,
|
|
23
|
+
inputSchema: tool.inputSchema,
|
|
24
|
+
invoke: (args, agentCtx) => {
|
|
25
|
+
const nodeCtx = peekNodeContext(ctx);
|
|
26
|
+
return tool.handler(args, nodeCtx ?? agentCtx);
|
|
27
|
+
},
|
|
28
|
+
}))),
|
|
29
|
+
});
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Emits Langflower bus tools for agent inventory. Recompile is unsafe:
|
|
3
|
+
* wire this node’s `tools` into the agent (starter Helper / Writer).
|
|
4
|
+
*/
|
|
5
|
+
export declare const langflowerToolsNode: {
|
|
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,77 @@
|
|
|
1
|
+
import { defineReactiveNode, TOOL_HANDLE_WIRE_TYPE, } from '@langflower/node-sdk';
|
|
2
|
+
import { getRunHostServices } from '../ai/features/run-host-services.js';
|
|
3
|
+
import { emitRegistrationTools } from './emit-registration-tools.js';
|
|
4
|
+
const MISSING_RPC_TEXT = '{ ok: false }\ncompile_custom_nodes unavailable (no bus RPC)';
|
|
5
|
+
const isRecord = (value) => typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
6
|
+
/** Format `customPalette.snapshot` (RPC wait skips `compiling`). */
|
|
7
|
+
const formatPaletteSnapshot = (value) => {
|
|
8
|
+
if (!isRecord(value)) {
|
|
9
|
+
return `{ ok: false }\nUnexpected compile result`;
|
|
10
|
+
}
|
|
11
|
+
const status = typeof value.status === 'string' ? value.status : 'error';
|
|
12
|
+
const lines = [`status: ${status}`];
|
|
13
|
+
const nodes = Array.isArray(value.nodes) ? value.nodes : [];
|
|
14
|
+
const nodeTypes = nodes.flatMap((node) => isRecord(node) && typeof node.type === 'string' ? [node.type] : []);
|
|
15
|
+
if (nodeTypes.length > 0) {
|
|
16
|
+
lines.push(`nodeTypes: ${nodeTypes.join(', ')}`);
|
|
17
|
+
}
|
|
18
|
+
const errors = Array.isArray(value.errors) ? value.errors : [];
|
|
19
|
+
if (errors.length > 0) {
|
|
20
|
+
lines.push('errors:');
|
|
21
|
+
for (const error of errors) {
|
|
22
|
+
if (!isRecord(error)) {
|
|
23
|
+
continue;
|
|
24
|
+
}
|
|
25
|
+
const pack = typeof error.packageName === 'string'
|
|
26
|
+
? error.packageName
|
|
27
|
+
: 'unknown';
|
|
28
|
+
const message = typeof error.message === 'string' ? error.message : '';
|
|
29
|
+
lines.push(`- ${pack}: ${message}`);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return lines.join('\n');
|
|
33
|
+
};
|
|
34
|
+
const LANGFLOWER_BUS_TOOL_CONFIGS = [
|
|
35
|
+
{
|
|
36
|
+
toolId: 'compile_custom_nodes',
|
|
37
|
+
description: 'Recompile `.langflower/nodes/` packs, hot-swap live custom instances, and refresh the Custom palette (same intent as Custom → Update). No arguments. Pack failures also write COMPILATION_ERRORS.md.',
|
|
38
|
+
inputSchema: {
|
|
39
|
+
type: 'object',
|
|
40
|
+
properties: {},
|
|
41
|
+
additionalProperties: false,
|
|
42
|
+
},
|
|
43
|
+
handler: (async (_args, ctx) => {
|
|
44
|
+
const request = getRunHostServices(ctx)?.requestLangflowerBus;
|
|
45
|
+
if (request === undefined) {
|
|
46
|
+
return MISSING_RPC_TEXT;
|
|
47
|
+
}
|
|
48
|
+
try {
|
|
49
|
+
const snapshot = await request('customPalette.update.requested', {});
|
|
50
|
+
return formatPaletteSnapshot(snapshot);
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
54
|
+
return `{ ok: false }\n${message}`;
|
|
55
|
+
}
|
|
56
|
+
}),
|
|
57
|
+
},
|
|
58
|
+
];
|
|
59
|
+
/**
|
|
60
|
+
* Emits Langflower bus tools for agent inventory. Recompile is unsafe:
|
|
61
|
+
* wire this node’s `tools` into the agent (starter Helper / Writer).
|
|
62
|
+
*/
|
|
63
|
+
export const langflowerToolsNode = defineReactiveNode({
|
|
64
|
+
type: 'common-langflower-tools',
|
|
65
|
+
displayName: 'Langflower Tools',
|
|
66
|
+
category: 'Tools',
|
|
67
|
+
description: 'Emits compile_custom_nodes (Custom → Update over the bus). Wire tools to opt in; later bus actions may be added to this pack.',
|
|
68
|
+
uiSchema: [],
|
|
69
|
+
bind(ctx, { configureOutput }) {
|
|
70
|
+
return {
|
|
71
|
+
inputs: [],
|
|
72
|
+
outputs: [
|
|
73
|
+
configureOutput('tools', emitRegistrationTools(ctx, LANGFLOWER_BUS_TOOL_CONFIGS), { wireType: TOOL_HANDLE_WIRE_TYPE }),
|
|
74
|
+
],
|
|
75
|
+
};
|
|
76
|
+
},
|
|
77
|
+
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { defineReactiveNode } from '@langflower/node-sdk';
|
|
2
2
|
import { createProjectFilesContext } from '@langflower/tools/create-project-files-context';
|
|
3
3
|
import { from, map, mergeMap, throwError } from 'rxjs';
|
|
4
|
-
import { getRunHostServices } from '../../ai/run-host-services.js';
|
|
4
|
+
import { getRunHostServices } from '../../ai/features/run-host-services.js';
|
|
5
5
|
/**
|
|
6
6
|
* Append to a project-relative text file via `createProjectFilesContext` (no permission ask).
|
|
7
7
|
* Non-empty files get `delimiter` between existing text and `content`.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { defineReactiveNode } from '@langflower/node-sdk';
|
|
2
2
|
import { createProjectFilesContext } from '@langflower/tools/create-project-files-context';
|
|
3
3
|
import { from, mergeMap, throwError } from 'rxjs';
|
|
4
|
-
import { getRunHostServices } from '../../ai/run-host-services.js';
|
|
4
|
+
import { getRunHostServices } from '../../ai/features/run-host-services.js';
|
|
5
5
|
/**
|
|
6
6
|
* Read a project-relative text file via `createProjectFilesContext` (no permission ask).
|
|
7
7
|
* Wire `update` (dynamic) to re-read when the path is unchanged.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { defineReactiveNode } from '@langflower/node-sdk';
|
|
2
2
|
import { createProjectFilesContext } from '@langflower/tools/create-project-files-context';
|
|
3
3
|
import { from, map, mergeMap, throwError } from 'rxjs';
|
|
4
|
-
import { getRunHostServices } from '../../ai/run-host-services.js';
|
|
4
|
+
import { getRunHostServices } from '../../ai/features/run-host-services.js';
|
|
5
5
|
/**
|
|
6
6
|
* Overwrite a project-relative text file via `createProjectFilesContext` (no permission ask).
|
|
7
7
|
*/
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { ToolHandle } from '@langflower/node-sdk';
|
|
2
2
|
import { type Harness } from '@langflower/tools/create-project-harness';
|
|
3
3
|
import type { ToolHandlerContext } from '@langflower/tools/domain-tool-configs';
|
|
4
|
-
import type { ChatCompletionToolCall, ChatCompletionToolDefinition } from '../ai/chat-completion-stream.js';
|
|
5
|
-
import type { SubAgentRegistration, SubAgentSpawnPayload } from '../ai/sub-agent-protocol.js';
|
|
4
|
+
import type { ChatCompletionToolCall, ChatCompletionToolDefinition } from '../ai/features/chat-completion-stream.js';
|
|
5
|
+
import type { SubAgentRegistration, SubAgentSpawnPayload } from '../ai/features/sub-agent-protocol.js';
|
|
6
6
|
export declare const SPAWN_SUBAGENT_TOOL = "spawn_subagent";
|
|
7
7
|
export declare const previewToolLogText: (text: string) => string;
|
|
8
8
|
export declare const toChatToolDefinitions: (tools: readonly ToolHandle[]) => readonly ChatCompletionToolDefinition[];
|
|
@@ -14,24 +14,24 @@
|
|
|
14
14
|
"import": "./dist/test-nodes/test-index.js"
|
|
15
15
|
},
|
|
16
16
|
"./ai/llm-role-preset": {
|
|
17
|
-
"types": "./dist/ai/llm-role-preset.d.ts",
|
|
18
|
-
"import": "./dist/ai/llm-role-preset.js"
|
|
17
|
+
"types": "./dist/ai/features/llm-role-preset.d.ts",
|
|
18
|
+
"import": "./dist/ai/features/llm-role-preset.js"
|
|
19
19
|
},
|
|
20
20
|
"./ai/sub-agent-protocol": {
|
|
21
|
-
"types": "./dist/ai/sub-agent-protocol.d.ts",
|
|
22
|
-
"import": "./dist/ai/sub-agent-protocol.js"
|
|
21
|
+
"types": "./dist/ai/features/sub-agent-protocol.d.ts",
|
|
22
|
+
"import": "./dist/ai/features/sub-agent-protocol.js"
|
|
23
23
|
},
|
|
24
24
|
"./ai/run-host-services": {
|
|
25
|
-
"types": "./dist/ai/run-host-services.d.ts",
|
|
26
|
-
"import": "./dist/ai/run-host-services.js"
|
|
25
|
+
"types": "./dist/ai/features/run-host-services.d.ts",
|
|
26
|
+
"import": "./dist/ai/features/run-host-services.js"
|
|
27
27
|
},
|
|
28
28
|
"./ai/openai/create-chat-completion-stream": {
|
|
29
|
-
"types": "./dist/ai/openai/create-chat-completion-stream.d.ts",
|
|
30
|
-
"import": "./dist/ai/openai/create-chat-completion-stream.js"
|
|
29
|
+
"types": "./dist/ai/features/openai/create-chat-completion-stream.d.ts",
|
|
30
|
+
"import": "./dist/ai/features/openai/create-chat-completion-stream.js"
|
|
31
31
|
},
|
|
32
32
|
"./ai/openai/list-provider-models": {
|
|
33
|
-
"types": "./dist/ai/openai/list-provider-models.d.ts",
|
|
34
|
-
"import": "./dist/ai/openai/list-provider-models.js"
|
|
33
|
+
"types": "./dist/ai/features/openai/list-provider-models.d.ts",
|
|
34
|
+
"import": "./dist/ai/features/openai/list-provider-models.js"
|
|
35
35
|
}
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
@@ -7,7 +7,8 @@ export declare const hasCustomNodePacks: (projectDir: string) => Promise<boolean
|
|
|
7
7
|
* Scan `.langflower/nodes/`. Each pack runs independently; within a pack each
|
|
8
8
|
* `export default` entry is typechecked then esbuilt only if clean.
|
|
9
9
|
* Returns all successful definitions plus all failures (partial success OK).
|
|
10
|
-
* Empty / missing `nodes/`
|
|
10
|
+
* Always deletes `.langflower/.cache/nodes/` first. Empty / missing `nodes/`
|
|
11
|
+
* does not recreate the cache dir.
|
|
11
12
|
*/
|
|
12
13
|
export declare const compileProjectNodes: (projectDir: string) => Promise<CompileProjectNodesResult>;
|
|
13
14
|
export type { CompileDiagnostic, CompilePackError, CompileProjectNodesResult, } from './compile-types.js';
|
|
@@ -1,17 +1,39 @@
|
|
|
1
1
|
import fs from 'node:fs/promises';
|
|
2
|
+
import os from 'node:os';
|
|
2
3
|
import path from 'node:path';
|
|
3
4
|
import { pathToFileURL } from 'node:url';
|
|
4
5
|
import { bundleEntry } from './bundle-pack.js';
|
|
5
|
-
import { computePackCacheKey } from './cache-key.js';
|
|
6
6
|
import { discoverPacks } from './discover-packs.js';
|
|
7
7
|
import { diagnosticsForEntry, typecheckPack } from './typecheck-pack.js';
|
|
8
8
|
import { formatCompilePackError } from './format-compilation-errors.js';
|
|
9
9
|
import { parseDefaultExport } from './validate-default-export.js';
|
|
10
10
|
import { deleteCompilationErrorsFile, writeCompilationErrorsFile, } from './write-compilation-errors.js';
|
|
11
11
|
const cacheRoot = (projectDir) => path.join(projectDir, '.langflower', '.cache', 'nodes');
|
|
12
|
+
const wipeCacheRoot = async (projectDir) => {
|
|
13
|
+
try {
|
|
14
|
+
await fs.rm(cacheRoot(projectDir), { recursive: true, force: true });
|
|
15
|
+
return { ok: true };
|
|
16
|
+
}
|
|
17
|
+
catch (error) {
|
|
18
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
19
|
+
return {
|
|
20
|
+
ok: false,
|
|
21
|
+
error: formatCompilePackError('.cache/nodes', [
|
|
22
|
+
{
|
|
23
|
+
message: `Failed to delete custom-node cache: ${message}`,
|
|
24
|
+
},
|
|
25
|
+
], projectDir),
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
};
|
|
12
29
|
const loadBundledDefault = async (outfile, entryPath, packageName, projectDir) => {
|
|
13
|
-
const
|
|
30
|
+
const loadFile = path.join(os.tmpdir(), `lf-node-load-${process.hrtime.bigint()}.mjs`);
|
|
14
31
|
try {
|
|
32
|
+
// Stable outfile stays at `<pack>/<entry>.mjs` for git diff. Import a
|
|
33
|
+
// unique temp copy so Node / Vitest ESM cache cannot reuse the previous
|
|
34
|
+
// module for that path (query strings are not enough under Vitest).
|
|
35
|
+
await fs.copyFile(outfile, loadFile);
|
|
36
|
+
const href = `${pathToFileURL(loadFile).href}?t=${Date.now()}`;
|
|
15
37
|
const mod = await import(href);
|
|
16
38
|
const defaultExport = typeof mod === 'object' && mod !== null && 'default' in mod
|
|
17
39
|
? mod.default
|
|
@@ -40,9 +62,11 @@ const loadBundledDefault = async (outfile, entryPath, packageName, projectDir) =
|
|
|
40
62
|
};
|
|
41
63
|
const relativeEntry = (packDir, entryPath) => path.relative(packDir, entryPath).split(path.sep).join('/');
|
|
42
64
|
const compileEntry = async (projectDir, pack, entryPath) => {
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
|
|
65
|
+
const relative = relativeEntry(pack.packDir, entryPath)
|
|
66
|
+
.replace(/[\\/]/g, '__')
|
|
67
|
+
.replace(/\.tsx$/u, '')
|
|
68
|
+
.replace(/\.ts$/u, '');
|
|
69
|
+
const outfile = path.join(cacheRoot(projectDir), pack.packageName.replace(/[^\w.-]+/g, '_'), `${relative}.mjs`);
|
|
46
70
|
const bundled = await bundleEntry({
|
|
47
71
|
entryPath,
|
|
48
72
|
packDir: pack.packDir,
|
|
@@ -95,10 +119,15 @@ export const hasCustomNodePacks = async (projectDir) => {
|
|
|
95
119
|
* Scan `.langflower/nodes/`. Each pack runs independently; within a pack each
|
|
96
120
|
* `export default` entry is typechecked then esbuilt only if clean.
|
|
97
121
|
* Returns all successful definitions plus all failures (partial success OK).
|
|
98
|
-
* Empty / missing `nodes/`
|
|
122
|
+
* Always deletes `.langflower/.cache/nodes/` first. Empty / missing `nodes/`
|
|
123
|
+
* does not recreate the cache dir.
|
|
99
124
|
*/
|
|
100
125
|
export const compileProjectNodes = async (projectDir) => {
|
|
101
126
|
const packs = await discoverPacks(projectDir);
|
|
127
|
+
const wiped = await wipeCacheRoot(projectDir);
|
|
128
|
+
if (!wiped.ok) {
|
|
129
|
+
return { nodes: [], errors: [wiped.error] };
|
|
130
|
+
}
|
|
102
131
|
if (packs.length === 0) {
|
|
103
132
|
return { nodes: [], errors: [] };
|
|
104
133
|
}
|
|
@@ -8,11 +8,6 @@ export declare const isHostPeerSpecifier: (id: string) => boolean;
|
|
|
8
8
|
* compiler's install tree. Works with `npm i -g` and an empty project.
|
|
9
9
|
*/
|
|
10
10
|
export declare const resolveHostPackageEntry: (specifier: string) => string | undefined;
|
|
11
|
-
/**
|
|
12
|
-
* Stable stamp of resolved host peer roots for cache invalidation when the
|
|
13
|
-
* Langflower install tree moves or upgrades.
|
|
14
|
-
*/
|
|
15
|
-
export declare const hostRuntimeEntryStamp: () => string;
|
|
16
11
|
/**
|
|
17
12
|
* Resolve declaration entry for a host package installed next to the
|
|
18
13
|
* compiler (global Langflower tree), using package.json `types` /
|
|
@@ -64,14 +64,6 @@ export const isHostPeerSpecifier = (id) => {
|
|
|
64
64
|
* compiler's install tree. Works with `npm i -g` and an empty project.
|
|
65
65
|
*/
|
|
66
66
|
export const resolveHostPackageEntry = (specifier) => resolvePackageEntry(specifier);
|
|
67
|
-
/**
|
|
68
|
-
* Stable stamp of resolved host peer roots for cache invalidation when the
|
|
69
|
-
* Langflower install tree moves or upgrades.
|
|
70
|
-
*/
|
|
71
|
-
export const hostRuntimeEntryStamp = () => HOST_PEER_PACKAGES.map((name) => {
|
|
72
|
-
const entry = resolveHostPackageEntry(name);
|
|
73
|
-
return `${name}=${entry === undefined ? '' : toPosix(entry)}`;
|
|
74
|
-
}).join('\n');
|
|
75
67
|
/**
|
|
76
68
|
* Prefer `exports` types conditions (import → require → default), then
|
|
77
69
|
* top-level `types` / `typings`.
|
|
@@ -43,4 +43,4 @@ export declare const defineLlmNode: <UI extends readonly UISchemaConstItem[]>(co
|
|
|
43
43
|
export { LLM_INVENTORY_INPUT_PORT_IDS, LLM_INVENTORY_OUTPUT_PORT_IDS, type LlmInventoryInputs, type LlmInventoryOutputStreams, } from './default-llm-ports.js';
|
|
44
44
|
export { SUBAGENT_REGISTRATION_WIRE_TYPE, SUBAGENT_RESULT_WIRE_TYPE, SUBAGENT_SPAWN_WIRE_TYPE, } from './llm-inventory-wire.js';
|
|
45
45
|
export { STEER_CONTROL_PORT_ID, isSteerControlContinue, isSteerControlPause, isSteerControlPayload, type SteerControlPayload, type SteerControlPause, type SteerControlResume, type SteerControlSteer, } from './steer-control.js';
|
|
46
|
-
export { RECOVERY_PORT_ID, isLlmRecoveryNotice, isLlmRecoverySuspended, recoveryNoticeText, type LlmRecoveryNotice, type LlmRecoveryNoticeCode, } from './recovery-notice.js';
|
|
46
|
+
export { RECOVERY_PORT_ID, isLlmRecoveryNotice, isLlmRecoverySuspended, recoveryNoticeText, toLlmRecoveryPortValue, type LlmRecoveryNotice, type LlmRecoveryNoticeCode, type LlmRecoveryRetryReason, } from './recovery-notice.js';
|
|
@@ -48,4 +48,4 @@ export const defineLlmNode = (config) => {
|
|
|
48
48
|
export { LLM_INVENTORY_INPUT_PORT_IDS, LLM_INVENTORY_OUTPUT_PORT_IDS, } from './default-llm-ports.js';
|
|
49
49
|
export { SUBAGENT_REGISTRATION_WIRE_TYPE, SUBAGENT_RESULT_WIRE_TYPE, SUBAGENT_SPAWN_WIRE_TYPE, } from './llm-inventory-wire.js';
|
|
50
50
|
export { STEER_CONTROL_PORT_ID, isSteerControlContinue, isSteerControlPause, isSteerControlPayload, } from './steer-control.js';
|
|
51
|
-
export { RECOVERY_PORT_ID, isLlmRecoveryNotice, isLlmRecoverySuspended, recoveryNoticeText, } from './recovery-notice.js';
|
|
51
|
+
export { RECOVERY_PORT_ID, isLlmRecoveryNotice, isLlmRecoverySuspended, recoveryNoticeText, toLlmRecoveryPortValue, } from './recovery-notice.js';
|
|
@@ -5,10 +5,18 @@
|
|
|
5
5
|
*/
|
|
6
6
|
export declare const RECOVERY_PORT_ID: "recovery";
|
|
7
7
|
export type LlmRecoveryNoticeCode = 'retry' | 'suspended';
|
|
8
|
+
export type LlmRecoveryRetryReason = 'idle' | 'dead-loop' | 'rate-limit' | 'provider-unavailable' | 'network';
|
|
8
9
|
export type LlmRecoveryNotice = {
|
|
9
10
|
readonly code: LlmRecoveryNoticeCode;
|
|
10
11
|
readonly text: string;
|
|
12
|
+
readonly attempt?: number;
|
|
13
|
+
readonly reason?: LlmRecoveryRetryReason;
|
|
14
|
+
readonly lastAttemptAt?: number;
|
|
15
|
+
readonly nextAttemptAt?: number;
|
|
16
|
+
readonly backoffMs?: number;
|
|
11
17
|
};
|
|
12
18
|
export declare const isLlmRecoveryNotice: (value: unknown) => value is LlmRecoveryNotice;
|
|
13
19
|
export declare const isLlmRecoverySuspended: (value: unknown) => boolean;
|
|
14
20
|
export declare const recoveryNoticeText: (value: unknown) => string;
|
|
21
|
+
/** Port payload: `code` + `text` plus any additive timing fields. */
|
|
22
|
+
export declare const toLlmRecoveryPortValue: (notice: LlmRecoveryNotice) => LlmRecoveryNotice;
|
|
@@ -22,3 +22,17 @@ export const recoveryNoticeText = (value) => {
|
|
|
22
22
|
}
|
|
23
23
|
return '';
|
|
24
24
|
};
|
|
25
|
+
/** Port payload: `code` + `text` plus any additive timing fields. */
|
|
26
|
+
export const toLlmRecoveryPortValue = (notice) => ({
|
|
27
|
+
code: notice.code,
|
|
28
|
+
text: notice.text,
|
|
29
|
+
...(notice.attempt !== undefined ? { attempt: notice.attempt } : {}),
|
|
30
|
+
...(notice.reason !== undefined ? { reason: notice.reason } : {}),
|
|
31
|
+
...(notice.lastAttemptAt !== undefined
|
|
32
|
+
? { lastAttemptAt: notice.lastAttemptAt }
|
|
33
|
+
: {}),
|
|
34
|
+
...(notice.nextAttemptAt !== undefined
|
|
35
|
+
? { nextAttemptAt: notice.nextAttemptAt }
|
|
36
|
+
: {}),
|
|
37
|
+
...(notice.backoffMs !== undefined ? { backoffMs: notice.backoffMs } : {}),
|
|
38
|
+
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { GraphCluster } from './runtime-helpers.js';
|
|
2
|
-
import { RuntimeEdge, RuntimeEditorApi, RuntimeNode, type EdgeId, type NodeId } from './types.js';
|
|
2
|
+
import { RuntimeEdge, RuntimeEditorApi, RuntimeNode, type EdgeId, type NodeId, type SwapNodeResult } from './types.js';
|
|
3
3
|
export declare class RuntimeEditor implements RuntimeEditorApi {
|
|
4
4
|
/** Node ID -> node definition. */
|
|
5
5
|
private readonly nodes;
|
|
@@ -20,6 +20,10 @@ export declare class RuntimeEditor implements RuntimeEditorApi {
|
|
|
20
20
|
* Composer: find occupying → prepare → swap → cleanup/rollback → refresh.
|
|
21
21
|
*/
|
|
22
22
|
replaceEdge(edgeInput: Omit<RuntimeEdge, 'edgeId'>): RuntimeEdge | false;
|
|
23
|
+
/**
|
|
24
|
+
* Replace the live instance at `nodeId` with `next`. Allowed while locked.
|
|
25
|
+
*/
|
|
26
|
+
swapNode(nodeId: NodeId, next: Omit<RuntimeNode, 'nodeId'>): SwapNodeResult | false;
|
|
23
27
|
removeNode(nodeId: NodeId): RuntimeNode | false;
|
|
24
28
|
removeEdge(edgeId: EdgeId): RuntimeNode[];
|
|
25
29
|
getNode(nodeId: NodeId): RuntimeNode | false;
|
|
@@ -108,6 +108,25 @@ export class RuntimeEditor {
|
|
|
108
108
|
this.refreshClusters();
|
|
109
109
|
return occupying;
|
|
110
110
|
}
|
|
111
|
+
/**
|
|
112
|
+
* Replace the live instance at `nodeId` with `next`. Allowed while locked.
|
|
113
|
+
*/
|
|
114
|
+
swapNode(nodeId, next) {
|
|
115
|
+
if (this.disposed) {
|
|
116
|
+
return false;
|
|
117
|
+
}
|
|
118
|
+
if (!this.nodes.has(nodeId)) {
|
|
119
|
+
return false;
|
|
120
|
+
}
|
|
121
|
+
const runtimeNode = materializeBypassNodeOnAdd({
|
|
122
|
+
...next,
|
|
123
|
+
nodeId,
|
|
124
|
+
});
|
|
125
|
+
this.nodes.set(nodeId, runtimeNode);
|
|
126
|
+
const droppedEdges = this.cleanupInvalidEdges();
|
|
127
|
+
this.refreshClusters();
|
|
128
|
+
return { node: runtimeNode, droppedEdges };
|
|
129
|
+
}
|
|
111
130
|
removeNode(nodeId) {
|
|
112
131
|
if (this.disposed) {
|
|
113
132
|
return false;
|
|
@@ -239,18 +239,18 @@ export class RuntimeRunner {
|
|
|
239
239
|
}
|
|
240
240
|
this.eventsSubject.next(event);
|
|
241
241
|
}
|
|
242
|
-
emitPortEvent(
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
242
|
+
emitPortEvent(_runId, portDir, nodeId, portId, portIdx, state, value, edgeIds, feed) {
|
|
243
|
+
const portIdStr = typeof portId === 'string' ? portId : String(portId);
|
|
244
|
+
this.emitRunnerEvent([
|
|
245
|
+
portDir,
|
|
246
246
|
nodeId,
|
|
247
|
-
|
|
248
|
-
portIdx,
|
|
249
|
-
edgeIds,
|
|
247
|
+
portIdStr,
|
|
250
248
|
state,
|
|
251
249
|
value,
|
|
252
|
-
|
|
253
|
-
|
|
250
|
+
portIdx,
|
|
251
|
+
edgeIds,
|
|
252
|
+
feed ?? null,
|
|
253
|
+
]);
|
|
254
254
|
}
|
|
255
255
|
canPreparePushedInput(node, portId) {
|
|
256
256
|
const connection = node.inputs[portId];
|
|
@@ -281,7 +281,7 @@ export class RuntimeRunner {
|
|
|
281
281
|
if (existing !== undefined) {
|
|
282
282
|
// Telemetry before deliver so HITL input-received precedes cascade
|
|
283
283
|
// (output-emitted / downstream input-received) in the event log.
|
|
284
|
-
this.emitPortEvent(run.runId, '
|
|
284
|
+
this.emitPortEvent(run.runId, 'in', cfg.nodeId, cfg.portId, 0, 'value', cfg.payload, []);
|
|
285
285
|
existing.source.next(cfg.payload);
|
|
286
286
|
return run.runId;
|
|
287
287
|
}
|
|
@@ -300,7 +300,7 @@ export class RuntimeRunner {
|
|
|
300
300
|
connection,
|
|
301
301
|
});
|
|
302
302
|
run.pushedInputSources.set(key, { source });
|
|
303
|
-
this.emitPortEvent(run.runId, '
|
|
303
|
+
this.emitPortEvent(run.runId, 'in', cfg.nodeId, cfg.portId, 0, 'value', cfg.payload, []);
|
|
304
304
|
source.next(cfg.payload);
|
|
305
305
|
return run.runId;
|
|
306
306
|
}
|
|
@@ -326,7 +326,7 @@ export class RuntimeRunner {
|
|
|
326
326
|
if (resolved === null) {
|
|
327
327
|
return;
|
|
328
328
|
}
|
|
329
|
-
this.emitPortEvent(run.runId, '
|
|
329
|
+
this.emitPortEvent(run.runId, 'out', nodeId, portId, 0, resolved.state, resolved.value, edgeIds, output.meta.feed);
|
|
330
330
|
if (resolved.state === 'value' &&
|
|
331
331
|
node !== false &&
|
|
332
332
|
node.stopsRun === true) {
|
|
@@ -357,7 +357,7 @@ export class RuntimeRunner {
|
|
|
357
357
|
if (resolved === null) {
|
|
358
358
|
return;
|
|
359
359
|
}
|
|
360
|
-
this.emitPortEvent(run.runId, '
|
|
360
|
+
this.emitPortEvent(run.runId, 'in', nodeId, portId, slotIndex, resolved.state, resolved.value, edgeIds);
|
|
361
361
|
},
|
|
362
362
|
}))
|
|
363
363
|
.with({ meta: source.meta });
|
|
@@ -369,7 +369,7 @@ export class RuntimeRunner {
|
|
|
369
369
|
if (this.activeRun !== undefined && this.activeRun.runId !== runId) {
|
|
370
370
|
return;
|
|
371
371
|
}
|
|
372
|
-
this.emitRunnerEvent(
|
|
372
|
+
this.emitRunnerEvent(['done', runId]);
|
|
373
373
|
this.setStatus('idle');
|
|
374
374
|
this.teardownRun();
|
|
375
375
|
}
|
|
@@ -429,7 +429,7 @@ export class RuntimeRunner {
|
|
|
429
429
|
connection.connect(of(seed.value).pipe(tap({
|
|
430
430
|
next: (value) => {
|
|
431
431
|
if (typeof seed.portId !== 'symbol') {
|
|
432
|
-
this.emitPortEvent(runId, '
|
|
432
|
+
this.emitPortEvent(runId, 'in', nodeId, seed.portId, seed.slotIndex, 'value', value, []);
|
|
433
433
|
}
|
|
434
434
|
},
|
|
435
435
|
})));
|
|
@@ -467,7 +467,7 @@ export class RuntimeRunner {
|
|
|
467
467
|
}
|
|
468
468
|
connection.connect(of(defaultValue).pipe(tap({
|
|
469
469
|
next: (value) => {
|
|
470
|
-
this.emitPortEvent(runId, '
|
|
470
|
+
this.emitPortEvent(runId, 'in', nodeId, portId, 0, 'value', value, []);
|
|
471
471
|
},
|
|
472
472
|
})));
|
|
473
473
|
wiredSlotKeys.add(key);
|
|
@@ -705,7 +705,7 @@ export class RuntimeRunner {
|
|
|
705
705
|
if (resolved === null) {
|
|
706
706
|
return;
|
|
707
707
|
}
|
|
708
|
-
this.emitPortEvent(run.runId, '
|
|
708
|
+
this.emitPortEvent(run.runId, 'in', group.nodeId, group.portId, 0, resolved.state, resolved.value, group.edges.map((entry) => entry.edge.edgeId));
|
|
709
709
|
},
|
|
710
710
|
})));
|
|
711
711
|
wiredSlots.push({
|
|
@@ -6,7 +6,8 @@ export { RuntimeEditor } from './runtime-editor.js';
|
|
|
6
6
|
export { graphHasCycle } from './runtime-helpers.js';
|
|
7
7
|
export type { GraphCluster } from './runtime-helpers.js';
|
|
8
8
|
export { RuntimeRunner } from './runtime-runner.js';
|
|
9
|
-
export type { MetaFromStatefulObservable, NodeId, EdgeId, RunId, PortMeta, RuntimeEdge, RuntimeEditorApi, RuntimeFeedPortMeta, RuntimeFeedRole,
|
|
9
|
+
export type { MetaFromStatefulObservable, NodeId, EdgeId, RunId, PortMeta, RuntimeEdge, RuntimeEditorApi, RuntimeFeedPortMeta, RuntimeFeedRole, PortTelemetry, RuntimeDoneTelemetry, RuntimeNode, RuntimePortSignalState, RuntimeResumeOptions, RuntimeRunnerApi, RuntimeRunnerEvent, RuntimeRunnerStatus, RuntimeSeedPortValue, RuntimeWireType, SwapNodeResult, } from './types.js';
|
|
10
|
+
export { isPortTelemetry, isRuntimeDone } from './types.js';
|
|
10
11
|
export type { RuntimeOptions };
|
|
11
12
|
export declare class RuntimeFacade {
|
|
12
13
|
readonly editor: RuntimeEditor;
|
|
@@ -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 { isPortTelemetry, isRuntimeDone } from './types.js';
|
|
7
8
|
export class RuntimeFacade {
|
|
8
9
|
editor;
|
|
9
10
|
runner;
|
|
@@ -1,20 +1,22 @@
|
|
|
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";
|