@kiberon-labs/behave-graph-flow 1.0.0 → 3.0.0
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/.fallowrc.json +16 -0
- package/.storybook/main.ts +32 -0
- package/.storybook/manager.ts +6 -0
- package/.storybook/preview.ts +64 -0
- package/.storybook/styles.css +16 -0
- package/.turbo/turbo-build.log +7 -0
- package/CHANGELOG.md +368 -0
- package/LICENSE +6 -0
- package/README.md +2 -2
- package/data/Polynomial.json +510 -0
- package/data/sequence.json +337 -0
- package/data/trigger-event.json +241 -0
- package/data/variable-change.json +210 -0
- package/dist/AnyControlImpl-Ds-CShIB.js +20 -0
- package/dist/AnyControlImpl-Ds-CShIB.js.map +1 -0
- package/dist/DocumentationBrowserPanelImpl-deZNzFX8.js +166 -0
- package/dist/DocumentationBrowserPanelImpl-deZNzFX8.js.map +1 -0
- package/dist/entry.css +4 -0
- package/dist/index.css +42 -0
- package/dist/index.css.map +1 -0
- package/dist/index.d.ts +3597 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +18009 -0
- package/dist/index.js.map +1 -0
- package/dist/noteImpl-KkrrWgJd.js +242 -0
- package/dist/noteImpl-KkrrWgJd.js.map +1 -0
- package/dist/styles.module-CvmpDkZj.css +3 -0
- package/dist/styles.module-CvmpDkZj.css.map +1 -0
- package/dist/styles.module-DZxg8aW9.js +271 -0
- package/dist/styles.module-DZxg8aW9.js.map +1 -0
- package/dist/useChangeNodeData-ChQGK7AI.js +23 -0
- package/dist/useChangeNodeData-ChQGK7AI.js.map +1 -0
- package/docs/notifications.md +246 -0
- package/docs/protocol.md +702 -0
- package/docs/specifics.md +191 -0
- package/package.json +82 -22
- package/postcss.config.ts +3 -4
- package/src/annotations/index.ts +32 -0
- package/src/components/FloatingToolbar/index.module.css +37 -0
- package/src/components/FloatingToolbar/index.tsx +256 -0
- package/src/components/Flow.tsx +287 -75
- package/src/components/contextMenus/DynamicContextMenu.tsx +85 -0
- package/src/components/contextMenus/NodePicker.module.css +274 -0
- package/src/components/contextMenus/NodePicker.tsx +481 -0
- package/src/components/contextMenus/edge.tsx +22 -0
- package/src/components/contextMenus/node.tsx +15 -0
- package/src/components/contextMenus/selection.tsx +11 -0
- package/src/components/controls/any/AnyControlImpl.tsx +14 -0
- package/src/components/controls/any/index.tsx +19 -0
- package/src/components/controls/boolean/index.tsx +13 -0
- package/src/components/controls/colorPicker/InputPopover.module.css +100 -0
- package/src/components/controls/colorPicker/InputPopover.tsx +31 -0
- package/src/components/controls/colorPicker/index.module.css +18 -0
- package/src/components/controls/colorPicker/index.tsx +61 -0
- package/src/components/controls/number/index.tsx +35 -0
- package/src/components/controls/string/index.tsx +16 -0
- package/src/components/edges/index.tsx +475 -0
- package/src/components/edges/offsetBezier.ts +134 -0
- package/src/components/hotKeys.tsx +20 -0
- package/src/components/layoutController/index.module.css +13 -0
- package/src/components/layoutController/index.tsx +140 -0
- package/src/components/layoutController/utils.ts +248 -0
- package/src/components/menubar/defaults.tsx +516 -0
- package/src/components/menubar/index.tsx +49 -0
- package/src/components/menubar/menuItem.module.css +31 -0
- package/src/components/menubar/menuItem.tsx +65 -0
- package/src/components/nodes/behave/Node.module.css +23 -0
- package/src/components/nodes/behave/Node.tsx +176 -0
- package/src/components/nodes/behave/NodeContainer.module.css +88 -0
- package/src/components/nodes/behave/NodeContainer.tsx +46 -0
- package/src/components/nodes/behave/index.tsx +14 -0
- package/src/components/nodes/group/index.tsx +109 -0
- package/src/components/nodes/wrapper/index.tsx +73 -0
- package/src/components/nodes/wrapper/styles.module.css +87 -0
- package/src/components/notifications/NotificationProvider.tsx +81 -0
- package/src/components/notifications/index.ts +2 -0
- package/src/components/notifications/utils.ts +71 -0
- package/src/components/panels/alignment/index.module.css +10 -0
- package/src/components/panels/alignment/index.tsx +244 -0
- package/src/components/panels/base/index.tsx +5 -0
- package/src/components/panels/base/styles.module.css +12 -0
- package/src/components/panels/common/PanelHeader.module.css +24 -0
- package/src/components/panels/common/PanelHeader.tsx +22 -0
- package/src/components/panels/common/SectionTitle.module.css +13 -0
- package/src/components/panels/common/SectionTitle.tsx +10 -0
- package/src/components/panels/events/EditEventPanel.tsx +324 -0
- package/src/components/panels/events/ManageEventsPanel.tsx +101 -0
- package/src/components/panels/events/index.tsx +23 -0
- package/src/components/panels/events/styles.module.css +178 -0
- package/src/components/panels/graphProperties/index.tsx +125 -0
- package/src/components/panels/history/index.tsx +92 -0
- package/src/components/panels/history/styles.module.css +97 -0
- package/src/components/panels/keymaps/index.module.css +68 -0
- package/src/components/panels/keymaps/index.tsx +166 -0
- package/src/components/panels/layers/index.tsx +245 -0
- package/src/components/panels/layers/styles.module.css +107 -0
- package/src/components/panels/legend/index.module.css +6 -0
- package/src/components/panels/legend/index.tsx +76 -0
- package/src/components/panels/logs/index.module.css +218 -0
- package/src/components/panels/logs/index.tsx +288 -0
- package/src/components/panels/nodeInputs/InputControl.tsx +63 -0
- package/src/components/panels/nodeInputs/InputsGroup.tsx +65 -0
- package/src/components/panels/nodeInputs/MultipleNodesView.tsx +37 -0
- package/src/components/panels/nodeInputs/NodeSettings.tsx +92 -0
- package/src/components/panels/nodeInputs/NodeTitleEditor.tsx +125 -0
- package/src/components/panels/nodeInputs/OutputsGroup.tsx +55 -0
- package/src/components/panels/nodeInputs/SocketGenerators.tsx +32 -0
- package/src/components/panels/nodeInputs/index.module.css +308 -0
- package/src/components/panels/nodeInputs/index.tsx +349 -0
- package/src/components/panels/nodeInputs/useNodeHandlers.ts +76 -0
- package/src/components/panels/nodeInputs/useNodeInputsData.ts +153 -0
- package/src/components/panels/nodePicker/index.tsx +115 -0
- package/src/components/panels/panel/index.module.css +66 -0
- package/src/components/panels/panel/index.tsx +88 -0
- package/src/components/panels/search/index.module.css +16 -0
- package/src/components/panels/search/index.tsx +215 -0
- package/src/components/panels/systemSettings/ConversionsSettings.tsx +203 -0
- package/src/components/panels/systemSettings/index.tsx +251 -0
- package/src/components/panels/systemSettings/styles.module.css +138 -0
- package/src/components/panels/traces/GridLines.tsx +38 -0
- package/src/components/panels/traces/TimeGrid.tsx +48 -0
- package/src/components/panels/traces/TraceLane.tsx +62 -0
- package/src/components/panels/traces/TraceTooltip.tsx +22 -0
- package/src/components/panels/traces/TracesHeader.tsx +56 -0
- package/src/components/panels/traces/index.module.css +159 -0
- package/src/components/panels/traces/index.tsx +298 -0
- package/src/components/panels/traces/types.ts +48 -0
- package/src/components/panels/traces/useDerivedSpans.ts +307 -0
- package/src/components/panels/traces/utils.ts +33 -0
- package/src/components/panels/variables/CreateVariableScreen.tsx +162 -0
- package/src/components/panels/variables/ManageVariablesScreen.tsx +147 -0
- package/src/components/panels/variables/index.tsx +125 -0
- package/src/components/panels/variables/styles.module.css +149 -0
- package/src/components/primitives/icon.module.css +45 -0
- package/src/components/primitives/icon.tsx +38 -0
- package/src/components/sockets/input/index.tsx +83 -0
- package/src/components/sockets/input/styles.module.css +26 -0
- package/src/components/sockets/output/index.tsx +68 -0
- package/src/components/sockets/output/styles.module.css +22 -0
- package/src/css/notes.css +135 -0
- package/src/css/prosemirror.css +57 -0
- package/src/css/rc-dock.css +212 -0
- package/src/css/rc-menu.css +101 -0
- package/src/css/themes/kiberon.css +127 -0
- package/src/css/vars.css +198 -0
- package/src/css/vscode-elements.css +124 -0
- package/src/entry.css +4 -0
- package/src/generators/CallSubgraphGenerator.tsx +136 -0
- package/src/generators/CustomEventOnTriggeredGenerator.tsx +85 -0
- package/src/generators/GraphBoundaryGenerator.module.css +32 -0
- package/src/generators/GraphBoundaryGenerator.tsx +193 -0
- package/src/generators/SequenceGenerator.tsx +104 -0
- package/src/generators/SwitchOnIntegerGenerator.tsx +256 -0
- package/src/generators/SwitchOnStringGenerator.tsx +263 -0
- package/src/generators/callSubgraphSync.ts +126 -0
- package/src/generators/registerDefaultGenerators.ts +55 -0
- package/src/generators/registerDefaults.ts +26 -0
- package/src/hooks/useBehaveGraphFlow.ts +17 -16
- package/src/hooks/useFlowHandlers.ts +154 -30
- package/src/hooks/useWasdPan.ts +210 -0
- package/src/index.css +134 -0
- package/src/index.ts +53 -18
- package/src/manifest/contributionRegistry.ts +93 -0
- package/src/manifest/index.ts +4 -0
- package/src/manifest/loadManifest.ts +82 -0
- package/src/manifest/manifestPlugin.ts +29 -0
- package/src/manifest/passthroughValueType.ts +40 -0
- package/src/plugin/alignment/index.ts +91 -0
- package/src/plugin/autosave/controller.ts +366 -0
- package/src/plugin/autosave/index.tsx +114 -0
- package/src/plugin/autosave/panel/BackupPanel.tsx +141 -0
- package/src/plugin/autosave/panel/index.tsx +1 -0
- package/src/plugin/autosave/panel/styles.module.css +56 -0
- package/src/plugin/autosave/settings.ts +65 -0
- package/src/plugin/autosave/storage.ts +147 -0
- package/src/plugin/docs/index.tsx +297 -0
- package/src/plugin/docs/panel/DocumentationBrowserPanelImpl.tsx +200 -0
- package/src/plugin/docs/panel/index.tsx +21 -0
- package/src/plugin/docs/panel/styles.module.css +174 -0
- package/src/plugin/graphrunner/actions.ts +326 -0
- package/src/plugin/graphrunner/buttons.tsx +95 -0
- package/src/plugin/graphrunner/client.ts +707 -0
- package/src/plugin/graphrunner/index.tsx +184 -0
- package/src/plugin/graphrunner/panel.tsx +386 -0
- package/src/plugin/graphrunner/runController.ts +283 -0
- package/src/plugin/graphrunner/runner.ts +187 -0
- package/src/plugin/graphrunner/session.ts +243 -0
- package/src/plugin/graphrunner/store.ts +196 -0
- package/src/plugin/graphrunner/styles.module.css +171 -0
- package/src/plugin/graphrunner/transport.ts +250 -0
- package/src/plugin/graphrunner/types.ts +693 -0
- package/src/plugin/graphrunner-local/execution-utils.ts +637 -0
- package/src/plugin/graphrunner-local/index.tsx +172 -0
- package/src/plugin/graphrunner-local/panel.tsx +187 -0
- package/src/plugin/graphrunner-local/store.ts +41 -0
- package/src/plugin/graphrunner-local/styles.module.css +82 -0
- package/src/plugin/graphrunner-local/transport.ts +1339 -0
- package/src/plugin/graphrunner-local/types.ts +10 -0
- package/src/plugin/graphrunner-webworker/graph-executor.worker.ts +635 -0
- package/src/plugin/graphrunner-webworker/index.tsx +140 -0
- package/src/plugin/graphrunner-webworker/panel.tsx +173 -0
- package/src/plugin/graphrunner-webworker/store.ts +98 -0
- package/src/plugin/graphrunner-webworker/worker-transport.ts +123 -0
- package/src/plugin/kitchen-sink/index.ts +38 -0
- package/src/plugin/layout/dagre.ts +131 -0
- package/src/plugin/layout/elk.ts +216 -0
- package/src/plugin/layout/index.ts +80 -0
- package/src/plugin/notes/FormatToolbar.tsx +200 -0
- package/src/plugin/notes/index.tsx +191 -0
- package/src/plugin/notes/nodeActions.ts +100 -0
- package/src/plugin/notes/note.tsx +20 -0
- package/src/plugin/notes/noteImpl.tsx +89 -0
- package/src/plugin/realtime/realtimeRunner.ts +624 -0
- package/src/specifics/CustomEventOnTriggeredSpecific.tsx +92 -0
- package/src/specifics/CustomEventTriggerSpecific.tsx +141 -0
- package/src/specifics/VariableGetSpecific.tsx +110 -0
- package/src/specifics/VariableSetSpecific.tsx +110 -0
- package/src/store/actions.tsx +698 -0
- package/src/store/commands.ts +278 -0
- package/src/store/contextMenu.ts +192 -0
- package/src/store/controls.tsx +62 -0
- package/src/store/conversions.ts +47 -0
- package/src/store/documentation.tsx +69 -0
- package/src/store/events.tsx +116 -0
- package/src/store/flow.tsx +230 -0
- package/src/store/graphMeta.ts +39 -0
- package/src/store/hotKeys.tsx +364 -0
- package/src/store/layers.ts +259 -0
- package/src/store/legend.tsx +76 -0
- package/src/store/logs.ts +28 -0
- package/src/store/menubar.ts +41 -0
- package/src/store/refs.ts +84 -0
- package/src/store/registry.ts +51 -0
- package/src/store/selection.ts +22 -0
- package/src/store/settings.ts +99 -0
- package/src/store/settingsSchema.ts +210 -0
- package/src/store/socketGenerator.tsx +54 -0
- package/src/store/specific.tsx +75 -0
- package/src/store/specs.tsx +35 -0
- package/src/store/tabs.ts +282 -0
- package/src/store/toolbar.tsx +45 -0
- package/src/store/traces.ts +240 -0
- package/src/store/variables.ts +37 -0
- package/src/system/graph.ts +131 -0
- package/src/system/graphSession.ts +172 -0
- package/src/system/index.ts +6 -0
- package/src/system/notifications.ts +111 -0
- package/src/system/persistence.ts +82 -0
- package/src/system/plugin.ts +55 -0
- package/src/system/provider.tsx +86 -0
- package/src/system/pubsub.ts +323 -0
- package/src/system/system.ts +653 -0
- package/src/system/tabLoader.tsx +303 -0
- package/src/system/undoRedo.ts +103 -0
- package/src/transformers/Uigraph.ts +61 -0
- package/src/transformers/behaveToFlow.ts +16 -4
- package/src/transformers/contract.ts +87 -0
- package/src/transformers/flowToBehave.ts +40 -12
- package/src/types/NodeMetadata.ts +27 -0
- package/src/types/graph.ts +49 -0
- package/src/types/nodes.ts +50 -0
- package/src/types.ts +18 -0
- package/src/util/autoConvert.ts +200 -0
- package/src/util/colors.ts +1 -29
- package/src/util/downloadJson.ts +18 -0
- package/src/util/extractNodeMetadata.ts +16 -0
- package/src/util/getPickerFilters.ts +1 -1
- package/src/util/isBehaveNode.ts +6 -0
- package/src/util/isValidConnection.ts +51 -17
- package/src/util/mergeSockets.ts +29 -0
- package/src/util/serializeVariables.ts +66 -0
- package/src/util/sockets.ts +43 -0
- package/stories/apex/layoutController/example-graph.worker.ts +39 -0
- package/stories/apex/layoutController/index.stories.tsx +48 -0
- package/stories/apex/layoutController/webworker.stories.tsx +103 -0
- package/stories/apex/menubar/menubar.stories.tsx +19 -0
- package/stories/components/colorpicker/index.stories.tsx +20 -0
- package/stories/components/contextMenus/edge.stories.tsx +32 -0
- package/stories/components/contextMenus/node.stories.tsx +26 -0
- package/stories/components/contextMenus/nodePicker.stories.tsx +115 -0
- package/stories/components/controls/any/index.stories.tsx +19 -0
- package/stories/components/controls/boolean/index.stories.tsx +19 -0
- package/stories/components/controls/colorPicker/index.stories.tsx +49 -0
- package/stories/components/controls/number/index.stories.tsx +19 -0
- package/stories/components/controls/string/index.stories.tsx +19 -0
- package/stories/components/nodes/behaveNode.stories.tsx +108 -0
- package/stories/components/panels/alignment.stories.tsx +24 -0
- package/stories/components/panels/events.stories.tsx +38 -0
- package/stories/components/panels/graphRunner.stories.tsx +317 -0
- package/stories/components/panels/history.stories.tsx +37 -0
- package/stories/components/panels/keymaps.stories.tsx +21 -0
- package/stories/components/panels/legend.stories.tsx +37 -0
- package/stories/components/panels/logs.stories.tsx +24 -0
- package/stories/components/panels/nodeInputs.stories.tsx +21 -0
- package/stories/components/panels/nodePicker.stories.tsx +37 -0
- package/stories/components/panels/panel.stories.tsx +39 -0
- package/stories/components/panels/search.stories.tsx +24 -0
- package/stories/components/panels/systemSettings.stories.tsx +26 -0
- package/stories/components/panels/traces.stories.tsx +225 -0
- package/stories/components/panels/variables.stories.tsx +24 -0
- package/stories/defaults/defaultStoryProvider.tsx +170 -0
- package/stories/defaults/systemGenerator.ts +43 -0
- package/stories/plugins/notes.stories.tsx +100 -0
- package/tests/autoConvert.test.ts +329 -0
- package/tests/autosavePlugin.test.ts +204 -0
- package/tests/callSubgraphSync.test.ts +148 -0
- package/tests/commandRegistry.test.ts +137 -0
- package/tests/components/edges/offsetBezier.test.ts +51 -0
- package/tests/components/layoutController/utils.test.ts +68 -0
- package/tests/components/panels/traces/utils.test.ts +52 -0
- package/tests/contract.test.ts +51 -0
- package/tests/contractSerialize.test.ts +62 -0
- package/tests/deriveSpans.test.ts +71 -0
- package/tests/flowToBehave.test.ts +27 -4
- package/tests/hotkeys.test.ts +79 -0
- package/tests/keepAliveLifecycle.test.ts +167 -0
- package/tests/loadManifest.test.ts +113 -0
- package/tests/noteMarkdown.test.ts +65 -0
- package/tests/notesPlugin.test.ts +162 -0
- package/tests/notifications.test.ts +87 -0
- package/tests/persistence.test.ts +51 -0
- package/tests/saveLoad.test.ts +373 -0
- package/tests/settings.test.ts +178 -0
- package/tests/traceStore.test.ts +46 -0
- package/tests/util/calculateNewEdge.test.ts +98 -0
- package/tests/util/getSocketsByNodeTypeAndHandleType.test.ts +31 -0
- package/tests/util/hasPositionMetaData.test.ts +33 -0
- package/tests/util/isBehaveNode.test.ts +22 -0
- package/tests/util/isHandleConnected.test.ts +37 -0
- package/tests/util/mergeSockets.test.ts +43 -0
- package/tests/visual/README.md +64 -0
- package/tests/visual/__screenshots__/panels.visual.test.tsx/panel-alignment-chromium-win32.png +0 -0
- package/tests/visual/__screenshots__/panels.visual.test.tsx/panel-conversation-chromium-win32.png +0 -0
- package/tests/visual/__screenshots__/panels.visual.test.tsx/panel-events-chromium-win32.png +0 -0
- package/tests/visual/__screenshots__/panels.visual.test.tsx/panel-history-chromium-win32.png +0 -0
- package/tests/visual/__screenshots__/panels.visual.test.tsx/panel-keymaps-chromium-win32.png +0 -0
- package/tests/visual/__screenshots__/panels.visual.test.tsx/panel-layers-chromium-win32.png +0 -0
- package/tests/visual/__screenshots__/panels.visual.test.tsx/panel-legend-chromium-win32.png +0 -0
- package/tests/visual/__screenshots__/panels.visual.test.tsx/panel-localGraphRunner-chromium-win32.png +0 -0
- package/tests/visual/__screenshots__/panels.visual.test.tsx/panel-logs-chromium-win32.png +0 -0
- package/tests/visual/__screenshots__/panels.visual.test.tsx/panel-nodeInputs-chromium-win32.png +0 -0
- package/tests/visual/__screenshots__/panels.visual.test.tsx/panel-nodePicker-chromium-win32.png +0 -0
- package/tests/visual/__screenshots__/panels.visual.test.tsx/panel-panel-chromium-win32.png +0 -0
- package/tests/visual/__screenshots__/panels.visual.test.tsx/panel-search-chromium-win32.png +0 -0
- package/tests/visual/__screenshots__/panels.visual.test.tsx/panel-systemSettings-chromium-win32.png +0 -0
- package/tests/visual/__screenshots__/panels.visual.test.tsx/panel-traces-chromium-win32.png +0 -0
- package/tests/visual/__screenshots__/panels.visual.test.tsx/panel-variables-chromium-win32.png +0 -0
- package/tests/visual/panels.visual.test.tsx +76 -0
- package/tests/wasdPan.test.ts +71 -0
- package/tsconfig.base.json +39 -0
- package/tsconfig.json +18 -59
- package/tsconfig.prod.json +23 -0
- package/tsdown.config.ts +15 -3
- package/typedoc.json +7 -7
- package/vite.config.js +7 -0
- package/vitest.config.ts +5 -2
- package/vitest.visual.config.ts +55 -0
- package/src/components/AutoSizeInput.tsx +0 -65
- package/src/components/Controls.tsx +0 -87
- package/src/components/InputSocket.tsx +0 -142
- package/src/components/Node.tsx +0 -68
- package/src/components/NodeContainer.tsx +0 -46
- package/src/components/NodePicker.tsx +0 -77
- package/src/components/OutputSocket.tsx +0 -58
- package/src/components/modals/ClearModal.tsx +0 -40
- package/src/components/modals/HelpModal.tsx +0 -36
- package/src/components/modals/LoadModal.tsx +0 -96
- package/src/components/modals/Modal.tsx +0 -64
- package/src/components/modals/SaveModal.tsx +0 -60
- package/src/hooks/useCustomNodeTypes.tsx +0 -31
- package/src/hooks/useGraphRunner.ts +0 -104
- package/src/hooks/useMergeMap.ts +0 -14
- package/src/hooks/useNodeSpecJson.ts +0 -20
- package/src/hooks/useQueriableDefinitions.ts +0 -22
- package/src/styles.css +0 -8
- package/tailwind.config.ts +0 -19
- package/tests/tsconfig.json +0 -10
- /package/src/{types.d.ts → types-declarations.d.ts} +0 -0
|
@@ -0,0 +1,637 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared graph execution utilities for both local and worker runners
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import {
|
|
6
|
+
Engine,
|
|
7
|
+
type GraphInstance,
|
|
8
|
+
type ILifecycleEventEmitter,
|
|
9
|
+
readGraphFromJSON,
|
|
10
|
+
validateGraph,
|
|
11
|
+
ManualLifecycleEventEmitter,
|
|
12
|
+
DefaultLogger,
|
|
13
|
+
type ILogger,
|
|
14
|
+
type IRegistry,
|
|
15
|
+
writeNodeSpecsToJSON,
|
|
16
|
+
type NodeSpecJSON,
|
|
17
|
+
type GraphJSON
|
|
18
|
+
} from '@kiberon-labs/behave-graph';
|
|
19
|
+
import type {
|
|
20
|
+
GraphRunnerCapabilities,
|
|
21
|
+
RunStatus,
|
|
22
|
+
ServerGraphRunnerMessage,
|
|
23
|
+
ServerVariable,
|
|
24
|
+
ServerEvent,
|
|
25
|
+
TraceBatchEvent
|
|
26
|
+
} from '../graphrunner/types.js';
|
|
27
|
+
import { sleep } from '@kiberon-labs/behave-graph';
|
|
28
|
+
|
|
29
|
+
export interface ActiveRun {
|
|
30
|
+
runId: string;
|
|
31
|
+
graphId: string;
|
|
32
|
+
engine: Engine;
|
|
33
|
+
graphInstance: GraphInstance;
|
|
34
|
+
registry: IRegistry;
|
|
35
|
+
status: RunStatus;
|
|
36
|
+
startedAt: number;
|
|
37
|
+
performance: {
|
|
38
|
+
nodesExecuted: number;
|
|
39
|
+
eventsEmitted: number;
|
|
40
|
+
variableChanges: number;
|
|
41
|
+
};
|
|
42
|
+
isPaused: boolean;
|
|
43
|
+
executionPhase: 'start' | 'tick' | 'end' | 'completed';
|
|
44
|
+
currentTick: number;
|
|
45
|
+
/**
|
|
46
|
+
* Flushes any trace events still buffered by {@link setupTracing}. Set when
|
|
47
|
+
* tracing is enabled; call before emitting `completed`/`stopped` so the
|
|
48
|
+
* client receives the tail of the trace while the run id is still routable.
|
|
49
|
+
*/
|
|
50
|
+
flushTracing?: () => void;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export interface MessageContext {
|
|
54
|
+
sendMessage: (message: ServerGraphRunnerMessage) => void;
|
|
55
|
+
sendError: (
|
|
56
|
+
code: string,
|
|
57
|
+
message: string,
|
|
58
|
+
details?: Record<string, unknown>
|
|
59
|
+
) => void;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Create a logger that forwards messages through a callback
|
|
64
|
+
*/
|
|
65
|
+
export function createForwardingLogger(
|
|
66
|
+
runId: string,
|
|
67
|
+
graphId: string,
|
|
68
|
+
onLog: (message: ServerGraphRunnerMessage) => void
|
|
69
|
+
): ILogger {
|
|
70
|
+
const baseLogger = new DefaultLogger();
|
|
71
|
+
|
|
72
|
+
return {
|
|
73
|
+
log: (severity: string, text: string) => {
|
|
74
|
+
baseLogger.log(severity as any, text);
|
|
75
|
+
onLog({
|
|
76
|
+
type: 'log',
|
|
77
|
+
runId,
|
|
78
|
+
graphId,
|
|
79
|
+
level: severity,
|
|
80
|
+
message: text
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Prepare a registry with required dependencies injected
|
|
88
|
+
*/
|
|
89
|
+
export function prepareRegistryWithDependencies(
|
|
90
|
+
registry: IRegistry,
|
|
91
|
+
logger: ILogger
|
|
92
|
+
): IRegistry {
|
|
93
|
+
// Ensure lifecycle event emitter and logger are available in registry
|
|
94
|
+
if (
|
|
95
|
+
!registry.dependencies?.ILifecycleEventEmitter ||
|
|
96
|
+
!registry.dependencies?.ILogger
|
|
97
|
+
) {
|
|
98
|
+
// Create a new registry with required dependencies injected
|
|
99
|
+
return {
|
|
100
|
+
...registry,
|
|
101
|
+
dependencies: {
|
|
102
|
+
...registry.dependencies,
|
|
103
|
+
ILifecycleEventEmitter:
|
|
104
|
+
registry.dependencies?.ILifecycleEventEmitter ||
|
|
105
|
+
new ManualLifecycleEventEmitter(),
|
|
106
|
+
ILogger: logger
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
} else {
|
|
110
|
+
// Replace the existing logger
|
|
111
|
+
return {
|
|
112
|
+
...registry,
|
|
113
|
+
dependencies: {
|
|
114
|
+
...registry.dependencies,
|
|
115
|
+
ILogger: logger
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Parse and validate a graph
|
|
123
|
+
*/
|
|
124
|
+
export function parseAndValidateGraph(
|
|
125
|
+
graphData: GraphJSON,
|
|
126
|
+
registry: IRegistry
|
|
127
|
+
): { graphInstance: GraphInstance; errors: string[] } {
|
|
128
|
+
const graphInstance = readGraphFromJSON({
|
|
129
|
+
graphJson: graphData,
|
|
130
|
+
registry
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
const errors = validateGraph(graphInstance);
|
|
134
|
+
return { graphInstance, errors };
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Generate a unique ID
|
|
139
|
+
*/
|
|
140
|
+
export function generateId(prefix: string): string {
|
|
141
|
+
return `${prefix}-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Handle hello message
|
|
146
|
+
*/
|
|
147
|
+
export function handleHello(
|
|
148
|
+
message: { type: 'hello'; protocolVersion: string },
|
|
149
|
+
serverId: string,
|
|
150
|
+
ctx: MessageContext
|
|
151
|
+
): void {
|
|
152
|
+
ctx.sendMessage({
|
|
153
|
+
type: 'welcome',
|
|
154
|
+
protocolVersion: message.protocolVersion,
|
|
155
|
+
serverId,
|
|
156
|
+
authenticated: true,
|
|
157
|
+
userId: 'local-user'
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Handle createSession message
|
|
163
|
+
*/
|
|
164
|
+
export function handleCreateSession(
|
|
165
|
+
_message: { type: 'createSession'; metadata?: Record<string, unknown> },
|
|
166
|
+
ctx: MessageContext
|
|
167
|
+
): string {
|
|
168
|
+
const sessionId = generateId('session');
|
|
169
|
+
ctx.sendMessage({
|
|
170
|
+
type: 'sessionCreated',
|
|
171
|
+
sessionId,
|
|
172
|
+
expiresAt: Date.now() + 24 * 60 * 60 * 1000
|
|
173
|
+
});
|
|
174
|
+
return sessionId;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Handle getCapabilities message
|
|
179
|
+
*/
|
|
180
|
+
export function handleGetCapabilities(ctx: MessageContext): void {
|
|
181
|
+
const capabilities: GraphRunnerCapabilities = {
|
|
182
|
+
trace: true,
|
|
183
|
+
validation: true,
|
|
184
|
+
graphRegistry: false,
|
|
185
|
+
eventFiltering: false,
|
|
186
|
+
batchOperations: false,
|
|
187
|
+
runHistory: false,
|
|
188
|
+
runtimeMetadata: true,
|
|
189
|
+
maxConcurrentRuns: 10
|
|
190
|
+
};
|
|
191
|
+
|
|
192
|
+
ctx.sendMessage({
|
|
193
|
+
type: 'capabilities',
|
|
194
|
+
capabilities
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/** Flush buffered trace events roughly once per frame. */
|
|
199
|
+
const TRACE_FLUSH_INTERVAL_MS = 16;
|
|
200
|
+
/** Safety valve: flush early if a single window buffers this many events. */
|
|
201
|
+
const TRACE_FLUSH_MAX_EVENTS = 2048;
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Setup tracing for a run.
|
|
205
|
+
*
|
|
206
|
+
* Node execution events are buffered and flushed as a single `traceBatch`
|
|
207
|
+
* message per flush window instead of one `trace` message per event. A graph
|
|
208
|
+
* ticking at display rate executes every node twice per frame (start + end);
|
|
209
|
+
* sending each event individually made the message pipeline (store updates,
|
|
210
|
+
* postMessage for the worker runner) the dominant per-frame cost.
|
|
211
|
+
*/
|
|
212
|
+
export function setupTracing(
|
|
213
|
+
run: ActiveRun,
|
|
214
|
+
graphId: string,
|
|
215
|
+
ctx: MessageContext
|
|
216
|
+
): void {
|
|
217
|
+
let buffer: TraceBatchEvent[] = [];
|
|
218
|
+
let flushTimer: ReturnType<typeof setTimeout> | undefined;
|
|
219
|
+
|
|
220
|
+
const flush = () => {
|
|
221
|
+
if (flushTimer !== undefined) {
|
|
222
|
+
clearTimeout(flushTimer);
|
|
223
|
+
flushTimer = undefined;
|
|
224
|
+
}
|
|
225
|
+
if (buffer.length === 0) return;
|
|
226
|
+
const events = buffer;
|
|
227
|
+
buffer = [];
|
|
228
|
+
ctx.sendMessage({
|
|
229
|
+
type: 'traceBatch',
|
|
230
|
+
runId: run.runId,
|
|
231
|
+
graphId,
|
|
232
|
+
events
|
|
233
|
+
});
|
|
234
|
+
};
|
|
235
|
+
run.flushTracing = flush;
|
|
236
|
+
|
|
237
|
+
const push = (event: TraceBatchEvent) => {
|
|
238
|
+
buffer.push(event);
|
|
239
|
+
if (buffer.length >= TRACE_FLUSH_MAX_EVENTS) {
|
|
240
|
+
flush();
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
if (flushTimer === undefined) {
|
|
244
|
+
flushTimer = setTimeout(flush, TRACE_FLUSH_INTERVAL_MS);
|
|
245
|
+
}
|
|
246
|
+
};
|
|
247
|
+
|
|
248
|
+
run.engine.onNodeExecutionStart.addListener((node) => {
|
|
249
|
+
run.performance.nodesExecuted++;
|
|
250
|
+
push({
|
|
251
|
+
nodeId: node.id,
|
|
252
|
+
event: 'start',
|
|
253
|
+
data: { typeName: node.description.typeName },
|
|
254
|
+
timestamp: Date.now() - run.startedAt
|
|
255
|
+
});
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
run.engine.onNodeExecutionEnd.addListener((node) => {
|
|
259
|
+
push({
|
|
260
|
+
nodeId: node.id,
|
|
261
|
+
event: 'end',
|
|
262
|
+
data: { typeName: node.description.typeName },
|
|
263
|
+
timestamp: Date.now() - run.startedAt
|
|
264
|
+
});
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* Setup variable change tracking for a run
|
|
270
|
+
*/
|
|
271
|
+
export function setupVariableChangeTracking(
|
|
272
|
+
run: ActiveRun,
|
|
273
|
+
graphId: string,
|
|
274
|
+
ctx: MessageContext
|
|
275
|
+
): void {
|
|
276
|
+
// Track old values so we can report them in the change event
|
|
277
|
+
const variableOldValues = new Map<string, unknown>();
|
|
278
|
+
|
|
279
|
+
const variables = Object.values(run.graphInstance.variables);
|
|
280
|
+
|
|
281
|
+
for (const variable of variables) {
|
|
282
|
+
// Store initial value as the "old" value
|
|
283
|
+
variableOldValues.set(variable.id, variable.get());
|
|
284
|
+
|
|
285
|
+
variable.onChanged.addListener(() => {
|
|
286
|
+
run.performance.variableChanges++;
|
|
287
|
+
const oldValue = variableOldValues.get(variable.id);
|
|
288
|
+
const newValue = variable.get();
|
|
289
|
+
|
|
290
|
+
// Update tracked value for next change
|
|
291
|
+
variableOldValues.set(variable.id, newValue);
|
|
292
|
+
|
|
293
|
+
ctx.sendMessage({
|
|
294
|
+
type: 'variableChanged',
|
|
295
|
+
runId: run.runId,
|
|
296
|
+
graphId,
|
|
297
|
+
variableName: variable.name,
|
|
298
|
+
oldValue,
|
|
299
|
+
newValue
|
|
300
|
+
});
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* Execute a graph through its lifecycle phases
|
|
307
|
+
*/
|
|
308
|
+
/**
|
|
309
|
+
* The single graph-execution lifecycle shared by both runners (the in-browser
|
|
310
|
+
* local transport and the web-worker runner). It drives the start → tick → end →
|
|
311
|
+
* completed phase machine and emits the `completed` / error messages; runner-
|
|
312
|
+
* specific behaviour (how fibers are stepped, tick timing, and what to do on
|
|
313
|
+
* completion/error) is injected via {@link ExecuteGraphLifecycleOptions} hooks so
|
|
314
|
+
* neither runner keeps its own copy of this logic.
|
|
315
|
+
*/
|
|
316
|
+
export interface ExecuteGraphLifecycleOptions {
|
|
317
|
+
/** Tick timing when no {@link tickStrategy} is given. Defaults to 50ms. */
|
|
318
|
+
tickInterval?: number;
|
|
319
|
+
/**
|
|
320
|
+
* When true, the run finalizes (end phase, `completed` message, engine
|
|
321
|
+
* dispose) once its flows drain. Defaults to false: the run idles in the
|
|
322
|
+
* tick phase, keeping event-node subscriptions live and draining any fibers
|
|
323
|
+
* they commit, until it is explicitly stopped.
|
|
324
|
+
*/
|
|
325
|
+
autoEnd?: boolean;
|
|
326
|
+
/**
|
|
327
|
+
* Run the engine's pending fibers for the current phase. Defaults to
|
|
328
|
+
* `run.engine.executeAllAsync()`; the local runner injects a pause-aware
|
|
329
|
+
* executor that also honours its step-delay / speed settings.
|
|
330
|
+
*/
|
|
331
|
+
executeStep?: () => Promise<void>;
|
|
332
|
+
/** Timing between tick iterations. Defaults to `sleep(tickInterval)`. */
|
|
333
|
+
tickStrategy?: () => Promise<void>;
|
|
334
|
+
/** Invoked after each tick iteration. */
|
|
335
|
+
onStepComplete?: () => Promise<void>;
|
|
336
|
+
/**
|
|
337
|
+
* Invoked after a natural completion — the run is marked completed, the
|
|
338
|
+
* `completed` message has been sent, and the engine disposed. Lets a runner
|
|
339
|
+
* run session hooks and sync its own state (e.g. the local panel's status).
|
|
340
|
+
*/
|
|
341
|
+
onComplete?: () => void | Promise<void>;
|
|
342
|
+
/**
|
|
343
|
+
* Invoked on error (after the run is marked errored, before the engine is
|
|
344
|
+
* disposed and the error rethrown). Replaces the default `sendError`.
|
|
345
|
+
*/
|
|
346
|
+
onError?: (error: Error) => void | Promise<void>;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
/** True when a lifecycle event has at least one listener attached. */
|
|
350
|
+
function hasListeners(event?: { listenerCount: number }): boolean {
|
|
351
|
+
return !!event && event.listenerCount > 0;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
/**
|
|
355
|
+
* Run the `start` lifecycle phase: emit the start event (if anyone is
|
|
356
|
+
* listening) and drain the fibers it commits, then advance to the tick phase.
|
|
357
|
+
*/
|
|
358
|
+
async function runStartPhase(
|
|
359
|
+
run: ActiveRun,
|
|
360
|
+
eventEmitter: ILifecycleEventEmitter | undefined,
|
|
361
|
+
executeStep: () => Promise<unknown>
|
|
362
|
+
): Promise<void> {
|
|
363
|
+
if (run.executionPhase !== 'start') return;
|
|
364
|
+
if (hasListeners(eventEmitter?.startEvent)) {
|
|
365
|
+
eventEmitter!.startEvent.emit();
|
|
366
|
+
await executeStep();
|
|
367
|
+
}
|
|
368
|
+
run.executionPhase = 'tick';
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
/**
|
|
372
|
+
* Run the `tick` phase until the run is paused or stopped. Returns `true` when
|
|
373
|
+
* the loop yielded control mid-tick (paused/stopped) so the caller should bail
|
|
374
|
+
* out without finalizing.
|
|
375
|
+
*
|
|
376
|
+
* A run stays alive here even with no tick listeners: completing it would
|
|
377
|
+
* dispose the engine and tear down event-node subscriptions (ai/onToolCall,
|
|
378
|
+
* ai/onMessage, custom triggers) that fire out-of-band, after the start flow has
|
|
379
|
+
* drained. The loop keeps draining fibers those events commit. Pass
|
|
380
|
+
* `autoEnd: true` to restore the finalize-when-drained behaviour for
|
|
381
|
+
* fire-and-forget runs.
|
|
382
|
+
*/
|
|
383
|
+
async function runTickPhase(
|
|
384
|
+
run: ActiveRun,
|
|
385
|
+
eventEmitter: ILifecycleEventEmitter | undefined,
|
|
386
|
+
executeStep: () => Promise<unknown>,
|
|
387
|
+
tickStrategy: () => Promise<unknown>,
|
|
388
|
+
options?: ExecuteGraphLifecycleOptions
|
|
389
|
+
): Promise<boolean> {
|
|
390
|
+
if (run.executionPhase !== 'tick') return false;
|
|
391
|
+
|
|
392
|
+
const hasTickListeners = hasListeners(eventEmitter?.tickEvent);
|
|
393
|
+
const autoEnd = options?.autoEnd ?? false;
|
|
394
|
+
if (!hasTickListeners && autoEnd) {
|
|
395
|
+
run.executionPhase = 'end';
|
|
396
|
+
return false;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
while (!run.isPaused && run.status === 'running') {
|
|
400
|
+
if (hasTickListeners) {
|
|
401
|
+
eventEmitter!.tickEvent.emit();
|
|
402
|
+
run.currentTick++;
|
|
403
|
+
}
|
|
404
|
+
await executeStep();
|
|
405
|
+
|
|
406
|
+
if (options?.onStepComplete) {
|
|
407
|
+
await options.onStepComplete();
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
if (run.isPaused || run.status !== 'running') {
|
|
411
|
+
return true;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
await tickStrategy();
|
|
415
|
+
}
|
|
416
|
+
return false;
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
/**
|
|
420
|
+
* Run the `end` lifecycle phase: emit the end event (if listened) and drain,
|
|
421
|
+
* then mark the run as reaching the `completed` phase.
|
|
422
|
+
*/
|
|
423
|
+
async function runEndPhase(
|
|
424
|
+
run: ActiveRun,
|
|
425
|
+
eventEmitter: ILifecycleEventEmitter | undefined,
|
|
426
|
+
executeStep: () => Promise<unknown>
|
|
427
|
+
): Promise<void> {
|
|
428
|
+
if (run.executionPhase !== 'end' || run.isPaused) return;
|
|
429
|
+
if (hasListeners(eventEmitter?.endEvent)) {
|
|
430
|
+
eventEmitter!.endEvent.emit();
|
|
431
|
+
await executeStep();
|
|
432
|
+
}
|
|
433
|
+
run.executionPhase = 'completed';
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
/**
|
|
437
|
+
* Finalize a run that ran out of fibers and isn't paused. Only autoEnd runs
|
|
438
|
+
* advance this far; by default a run idles in the tick phase until stopped.
|
|
439
|
+
*/
|
|
440
|
+
async function finalizeCompletedRun(
|
|
441
|
+
run: ActiveRun,
|
|
442
|
+
graphId: string,
|
|
443
|
+
ctx: MessageContext,
|
|
444
|
+
options?: ExecuteGraphLifecycleOptions
|
|
445
|
+
): Promise<void> {
|
|
446
|
+
if (
|
|
447
|
+
run.executionPhase !== 'completed' ||
|
|
448
|
+
run.isPaused ||
|
|
449
|
+
!(options?.autoEnd ?? false)
|
|
450
|
+
) {
|
|
451
|
+
return;
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
run.status = 'completed';
|
|
455
|
+
const elapsedMs = Date.now() - run.startedAt;
|
|
456
|
+
|
|
457
|
+
// Deliver any buffered trace events before `completed` , the client
|
|
458
|
+
// unregisters the run id on completion and would drop a late batch.
|
|
459
|
+
run.flushTracing?.();
|
|
460
|
+
|
|
461
|
+
ctx.sendMessage({
|
|
462
|
+
type: 'completed',
|
|
463
|
+
runId: run.runId,
|
|
464
|
+
graphId,
|
|
465
|
+
completedAt: Date.now(),
|
|
466
|
+
elapsedMs,
|
|
467
|
+
result: null,
|
|
468
|
+
performance: run.performance
|
|
469
|
+
});
|
|
470
|
+
|
|
471
|
+
run.engine.dispose();
|
|
472
|
+
await options?.onComplete?.();
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
/** Mark the run errored, notify, dispose the engine, and rethrow. */
|
|
476
|
+
async function handleLifecycleError(
|
|
477
|
+
run: ActiveRun,
|
|
478
|
+
graphId: string,
|
|
479
|
+
ctx: MessageContext,
|
|
480
|
+
error: unknown,
|
|
481
|
+
options?: ExecuteGraphLifecycleOptions
|
|
482
|
+
): Promise<never> {
|
|
483
|
+
run.status = 'error';
|
|
484
|
+
run.flushTracing?.();
|
|
485
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
486
|
+
if (options?.onError) {
|
|
487
|
+
await options.onError(err);
|
|
488
|
+
} else {
|
|
489
|
+
ctx.sendError('NODE_EXECUTION_ERROR', err.message, {
|
|
490
|
+
runId: run.runId,
|
|
491
|
+
graphId
|
|
492
|
+
});
|
|
493
|
+
}
|
|
494
|
+
run.engine.dispose();
|
|
495
|
+
throw error;
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
export async function executeGraphLifecycle(
|
|
499
|
+
run: ActiveRun,
|
|
500
|
+
graphId: string,
|
|
501
|
+
ctx: MessageContext,
|
|
502
|
+
options?: ExecuteGraphLifecycleOptions
|
|
503
|
+
): Promise<void> {
|
|
504
|
+
const executeStep =
|
|
505
|
+
options?.executeStep ?? (() => run.engine.executeAllAsync());
|
|
506
|
+
const tickStrategy =
|
|
507
|
+
options?.tickStrategy ??
|
|
508
|
+
(() => sleep((options?.tickInterval ?? 50) / 1000));
|
|
509
|
+
|
|
510
|
+
try {
|
|
511
|
+
const eventEmitter = run.registry.dependencies?.ILifecycleEventEmitter as
|
|
512
|
+
| ILifecycleEventEmitter
|
|
513
|
+
| undefined;
|
|
514
|
+
|
|
515
|
+
await runStartPhase(run, eventEmitter, executeStep);
|
|
516
|
+
|
|
517
|
+
const yielded = await runTickPhase(
|
|
518
|
+
run,
|
|
519
|
+
eventEmitter,
|
|
520
|
+
executeStep,
|
|
521
|
+
tickStrategy,
|
|
522
|
+
options
|
|
523
|
+
);
|
|
524
|
+
if (yielded) return;
|
|
525
|
+
|
|
526
|
+
await runEndPhase(run, eventEmitter, executeStep);
|
|
527
|
+
await finalizeCompletedRun(run, graphId, ctx, options);
|
|
528
|
+
} catch (error) {
|
|
529
|
+
await handleLifecycleError(run, graphId, ctx, error, options);
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
/**
|
|
534
|
+
* Handle getServerVariables message
|
|
535
|
+
*/
|
|
536
|
+
export function handleGetServerVariables(
|
|
537
|
+
variables: ServerVariable[],
|
|
538
|
+
ctx: MessageContext
|
|
539
|
+
): void {
|
|
540
|
+
ctx.sendMessage({
|
|
541
|
+
type: 'serverVariables',
|
|
542
|
+
variables
|
|
543
|
+
});
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
/**
|
|
547
|
+
* Handle getServerEvents message
|
|
548
|
+
*/
|
|
549
|
+
export function handleGetServerEvents(
|
|
550
|
+
events: ServerEvent[],
|
|
551
|
+
ctx: MessageContext
|
|
552
|
+
): void {
|
|
553
|
+
ctx.sendMessage({
|
|
554
|
+
type: 'serverEvents',
|
|
555
|
+
events
|
|
556
|
+
});
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
/**
|
|
560
|
+
* Handle getSocketConstraints message
|
|
561
|
+
*/
|
|
562
|
+
export function handleGetSocketConstraints(
|
|
563
|
+
message: {
|
|
564
|
+
nodeType: string;
|
|
565
|
+
socketName: string;
|
|
566
|
+
},
|
|
567
|
+
registry: IRegistry,
|
|
568
|
+
ctx: MessageContext
|
|
569
|
+
): void {
|
|
570
|
+
const nodeSpec = writeNodeSpecsToJSON(registry).find(
|
|
571
|
+
(spec) => spec.type === message.nodeType
|
|
572
|
+
);
|
|
573
|
+
if (!nodeSpec) {
|
|
574
|
+
ctx.sendError('INVALID_GRAPH', `Node type not found: ${message.nodeType}`);
|
|
575
|
+
return;
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
const socket = [...nodeSpec.inputs, ...nodeSpec.outputs].find(
|
|
579
|
+
(s) => s.name === message.socketName
|
|
580
|
+
);
|
|
581
|
+
|
|
582
|
+
if (!socket) {
|
|
583
|
+
ctx.sendError(
|
|
584
|
+
'INVALID_GRAPH',
|
|
585
|
+
`Socket not found: ${message.socketName} on node ${message.nodeType}`
|
|
586
|
+
);
|
|
587
|
+
return;
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
const constraints: {
|
|
591
|
+
type: 'enum' | 'range' | 'pattern' | 'custom';
|
|
592
|
+
choices?: Array<{ value: unknown; label: string }>;
|
|
593
|
+
min?: number;
|
|
594
|
+
max?: number;
|
|
595
|
+
pattern?: string;
|
|
596
|
+
validator?: string;
|
|
597
|
+
} = {
|
|
598
|
+
type: 'custom'
|
|
599
|
+
};
|
|
600
|
+
|
|
601
|
+
if ('choices' in socket && Array.isArray(socket.choices)) {
|
|
602
|
+
constraints.type = 'enum';
|
|
603
|
+
constraints.choices = socket.choices.map(
|
|
604
|
+
(choice: { text: string; value: unknown } | string) =>
|
|
605
|
+
typeof choice === 'string'
|
|
606
|
+
? { value: choice, label: choice }
|
|
607
|
+
: { value: choice.value, label: choice.text }
|
|
608
|
+
);
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
ctx.sendMessage({
|
|
612
|
+
type: 'socketConstraints',
|
|
613
|
+
nodeType: message.nodeType,
|
|
614
|
+
socketName: message.socketName,
|
|
615
|
+
valueType: socket.valueType,
|
|
616
|
+
constraints
|
|
617
|
+
});
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
/**
|
|
621
|
+
* Handle getNodeTypes message
|
|
622
|
+
*/
|
|
623
|
+
export function handleGetNodeTypes(
|
|
624
|
+
registry: IRegistry,
|
|
625
|
+
ctx: MessageContext
|
|
626
|
+
): void {
|
|
627
|
+
let nodes: NodeSpecJSON[] = [];
|
|
628
|
+
|
|
629
|
+
if (registry.nodes) {
|
|
630
|
+
nodes = writeNodeSpecsToJSON(registry);
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
ctx.sendMessage({
|
|
634
|
+
type: 'nodeTypes',
|
|
635
|
+
nodes
|
|
636
|
+
});
|
|
637
|
+
}
|