@kiberon-labs/behave-graph-flow 1.0.0 → 2.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/preview.ts +16 -0
- package/.storybook/styles.css +10 -0
- package/.storybook/vscode.css +814 -0
- package/.turbo/turbo-build.log +7 -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/entry.css +4 -0
- package/dist/index.css +39 -0
- package/dist/index.css.map +1 -0
- package/dist/index.d.ts +2282 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +14873 -0
- package/dist/index.js.map +1 -0
- package/docs/notifications.md +246 -0
- package/docs/protocol.md +679 -0
- package/docs/specifics.md +191 -0
- package/package.json +85 -21
- package/postcss.config.ts +3 -4
- package/src/annotations/index.ts +32 -0
- package/src/components/FloatingToolbar/index.module.css +45 -0
- package/src/components/FloatingToolbar/index.tsx +256 -0
- package/src/components/Flow.tsx +276 -75
- package/src/components/contextMenus/NodePicker.module.css +274 -0
- package/src/components/contextMenus/NodePicker.tsx +481 -0
- package/src/components/contextMenus/edge.tsx +108 -0
- package/src/components/contextMenus/node.tsx +155 -0
- package/src/components/contextMenus/selection.tsx +77 -0
- package/src/components/controls/any/index.tsx +8 -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 +469 -0
- package/src/components/edges/offsetBezier.ts +134 -0
- package/src/components/hotKeys.tsx +20 -0
- package/src/components/layoutController/index.module.css +10 -0
- package/src/components/layoutController/index.tsx +117 -0
- package/src/components/layoutController/utils.ts +205 -0
- package/src/components/menubar/defaults.tsx +480 -0
- package/src/components/menubar/index.tsx +49 -0
- package/src/components/menubar/menuItem.module.css +16 -0
- package/src/components/menubar/menuItem.tsx +32 -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 +87 -0
- package/src/components/nodes/behave/NodeContainer.tsx +46 -0
- package/src/components/nodes/behave/index.tsx +14 -0
- package/src/components/nodes/comment/FormatToolbar.tsx +118 -0
- package/src/components/nodes/comment/comment.tsx +103 -0
- package/src/components/nodes/comment/styles.module.css +150 -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 +113 -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 +20 -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/conversation/index.module.css +151 -0
- package/src/components/panels/conversation/index.tsx +162 -0
- package/src/components/panels/events/CustomEventsEditor.tsx +384 -0
- package/src/components/panels/events/EditEventPanel.tsx +315 -0
- package/src/components/panels/events/ManageEventsPanel.tsx +98 -0
- package/src/components/panels/events/index.tsx +23 -0
- package/src/components/panels/events/styles.module.css +236 -0
- package/src/components/panels/history/index.tsx +92 -0
- package/src/components/panels/history/styles.module.css +106 -0
- package/src/components/panels/keymaps/index.module.css +78 -0
- package/src/components/panels/keymaps/index.tsx +167 -0
- package/src/components/panels/layers/index.tsx +240 -0
- package/src/components/panels/layers/styles.module.css +110 -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 +212 -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 +64 -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 +65 -0
- package/src/components/panels/nodeInputs/SocketGenerators.tsx +32 -0
- package/src/components/panels/nodeInputs/index.module.css +284 -0
- package/src/components/panels/nodeInputs/index.tsx +339 -0
- package/src/components/panels/nodeInputs/useNodeHandlers.ts +76 -0
- package/src/components/panels/nodeInputs/useNodeInputsData.ts +173 -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 +66 -0
- package/src/components/panels/search/index.tsx +215 -0
- package/src/components/panels/systemSettings/index.tsx +206 -0
- package/src/components/panels/systemSettings/styles.module.css +11 -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 +166 -0
- package/src/components/panels/traces/index.tsx +294 -0
- package/src/components/panels/traces/types.ts +48 -0
- package/src/components/panels/traces/useDerivedSpans.ts +212 -0
- package/src/components/panels/traces/utils.ts +25 -0
- package/src/components/panels/variables/CreateVariableScreen.tsx +162 -0
- package/src/components/panels/variables/ManageVariablesScreen.tsx +144 -0
- package/src/components/panels/variables/index.tsx +125 -0
- package/src/components/panels/variables/styles.module.css +236 -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 +76 -0
- package/src/components/sockets/input/styles.module.css +27 -0
- package/src/components/sockets/output/index.tsx +61 -0
- package/src/components/sockets/output/styles.module.css +27 -0
- package/src/css/prosemirror.css +57 -0
- package/src/css/rc-dock.css +112 -0
- package/src/css/rc-menu.css +100 -0
- package/src/css/vars.css +14 -0
- package/src/css/vscode.css +13 -0
- package/src/entry.css +4 -0
- package/src/generators/CustomEventOnTriggeredGenerator.tsx +85 -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/registerDefaultGenerators.ts +34 -0
- package/src/hooks/useBehaveGraphFlow.ts +17 -16
- package/src/hooks/useDetachNodes.ts +39 -0
- package/src/hooks/useFlowHandlers.ts +115 -29
- package/src/hooks/useWasdPan.ts +188 -0
- package/src/index.css +146 -0
- package/src/index.ts +36 -18
- package/src/layout/dagre.tsx +119 -0
- package/src/layout/elk.ts +200 -0
- package/src/plugin/alignment/index.ts +81 -0
- package/src/plugin/docs/index.tsx +299 -0
- package/src/plugin/docs/panel/index.tsx +200 -0
- package/src/plugin/docs/panel/styles.module.css +174 -0
- package/src/plugin/graphrunner/actions.ts +253 -0
- package/src/plugin/graphrunner/buttons.tsx +87 -0
- package/src/plugin/graphrunner/client.ts +704 -0
- package/src/plugin/graphrunner/index.tsx +255 -0
- package/src/plugin/graphrunner/panel.tsx +386 -0
- package/src/plugin/graphrunner/runner.ts +358 -0
- package/src/plugin/graphrunner/session.ts +243 -0
- package/src/plugin/graphrunner/store.ts +206 -0
- package/src/plugin/graphrunner/styles.module.css +211 -0
- package/src/plugin/graphrunner/transport.ts +224 -0
- package/src/plugin/graphrunner/types.ts +672 -0
- package/src/plugin/graphrunner-local/execution-utils.ts +457 -0
- package/src/plugin/graphrunner-local/index.tsx +166 -0
- package/src/plugin/graphrunner-local/panel.tsx +231 -0
- package/src/plugin/graphrunner-local/store.ts +41 -0
- package/src/plugin/graphrunner-local/styles.module.css +101 -0
- package/src/plugin/graphrunner-local/transport.ts +1372 -0
- package/src/plugin/graphrunner-local/types.ts +10 -0
- package/src/plugin/graphrunner-webworker/graph-executor.worker.ts +633 -0
- package/src/plugin/graphrunner-webworker/index.tsx +146 -0
- package/src/plugin/graphrunner-webworker/panel.tsx +173 -0
- package/src/plugin/graphrunner-webworker/store.ts +89 -0
- package/src/plugin/graphrunner-webworker/types.ts +17 -0
- package/src/plugin/graphrunner-webworker/worker-transport.ts +123 -0
- package/src/plugin/realtime/realtimeRunner.ts +570 -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/specifics/registerDefaultSpecifics.ts +5 -0
- package/src/store/actions.tsx +698 -0
- package/src/store/chat.ts +73 -0
- package/src/store/controls.tsx +62 -0
- package/src/store/documentation.tsx +69 -0
- package/src/store/events.tsx +116 -0
- package/src/store/flow.tsx +245 -0
- package/src/store/graphRunnerClient.ts +110 -0
- package/src/store/hotKeys.tsx +323 -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 +43 -0
- package/src/store/selection.ts +22 -0
- package/src/store/settings.ts +99 -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 +278 -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 +134 -0
- package/src/system/index.ts +3 -0
- package/src/system/notifications.ts +98 -0
- package/src/system/plugin.ts +27 -0
- package/src/system/provider.tsx +22 -0
- package/src/system/pubsub.ts +323 -0
- package/src/system/system.ts +223 -0
- package/src/system/tabLoader.tsx +265 -0
- package/src/system/undoRedo.ts +103 -0
- package/src/transformers/Uigraph.ts +60 -0
- package/src/transformers/behaveToFlow.ts +16 -4
- package/src/transformers/flowToBehave.ts +32 -12
- package/src/types/NodeMetadata.ts +27 -0
- package/src/types/graph.ts +49 -0
- package/src/types/nodes.ts +45 -0
- package/src/types.ts +16 -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 +28 -15
- 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/nodes/comment.stories.tsx +106 -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 +167 -0
- package/stories/defaults/systemGenerator.ts +38 -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/flowToBehave.test.ts +26 -4
- package/tests/notifications.test.ts +87 -0
- package/tests/saveLoad.test.ts +372 -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-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/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 +48 -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,358 @@
|
|
|
1
|
+
import type { System } from '../../system/system';
|
|
2
|
+
import type { StoreApi } from 'zustand';
|
|
3
|
+
import type { GraphRunnerClientStore } from './store';
|
|
4
|
+
import { GraphRunnerClient } from './client';
|
|
5
|
+
import { buildUIGraphJSON } from '../../transformers/Uigraph';
|
|
6
|
+
import { setupClientEventListeners } from './actions';
|
|
7
|
+
|
|
8
|
+
declare module '@/system/system' {
|
|
9
|
+
interface System {
|
|
10
|
+
runner: GraphRunner;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export class GraphRunner {
|
|
15
|
+
private system: System;
|
|
16
|
+
public readonly store: StoreApi<GraphRunnerClientStore>;
|
|
17
|
+
|
|
18
|
+
constructor(system: System, store: StoreApi<GraphRunnerClientStore>) {
|
|
19
|
+
this.system = system;
|
|
20
|
+
this.store = store;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Connect to the graph runner server
|
|
25
|
+
*/
|
|
26
|
+
async connect(): Promise<void> {
|
|
27
|
+
const {
|
|
28
|
+
client,
|
|
29
|
+
connectionConfig,
|
|
30
|
+
setClient,
|
|
31
|
+
setConnectionState,
|
|
32
|
+
setConnectionInfo,
|
|
33
|
+
setError,
|
|
34
|
+
clearServerMetadata,
|
|
35
|
+
addMessageActivity
|
|
36
|
+
} = this.store.getState();
|
|
37
|
+
|
|
38
|
+
try {
|
|
39
|
+
setError(null);
|
|
40
|
+
setConnectionState('connecting');
|
|
41
|
+
|
|
42
|
+
const theClient =
|
|
43
|
+
client ??
|
|
44
|
+
new GraphRunnerClient({
|
|
45
|
+
url: connectionConfig.url,
|
|
46
|
+
auth: connectionConfig.auth,
|
|
47
|
+
autoReconnect: connectionConfig.autoReconnect,
|
|
48
|
+
onMessageActivity: (direction, message) => {
|
|
49
|
+
addMessageActivity(direction, message);
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
setClient(theClient);
|
|
54
|
+
|
|
55
|
+
await theClient.connect();
|
|
56
|
+
|
|
57
|
+
// Setup persistent event listeners for trace, logs, and run completion
|
|
58
|
+
setupClientEventListeners(theClient, this.system, this.store);
|
|
59
|
+
|
|
60
|
+
setConnectionState('connected');
|
|
61
|
+
setConnectionInfo({
|
|
62
|
+
serverId: theClient.getServerId(),
|
|
63
|
+
userId: theClient.getUserId(),
|
|
64
|
+
sessionId: null,
|
|
65
|
+
authenticated: theClient.isAuthenticated(),
|
|
66
|
+
capabilities: null
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
// Create session
|
|
70
|
+
const sessionId = await theClient.createSession();
|
|
71
|
+
setConnectionInfo({ sessionId });
|
|
72
|
+
|
|
73
|
+
// Get capabilities
|
|
74
|
+
const capabilities = await theClient.getCapabilities();
|
|
75
|
+
setConnectionInfo({ capabilities });
|
|
76
|
+
|
|
77
|
+
// Fetch metadata if supported
|
|
78
|
+
if (capabilities.runtimeMetadata) {
|
|
79
|
+
await this.refreshMetadata();
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Notify successful connection
|
|
83
|
+
this.system.notifications.success(
|
|
84
|
+
`Connected to ${theClient.getServerId() || 'graph runner server'}`
|
|
85
|
+
);
|
|
86
|
+
} catch (error) {
|
|
87
|
+
setConnectionState('disconnected');
|
|
88
|
+
const errorMessage =
|
|
89
|
+
error instanceof Error ? error.message : String(error);
|
|
90
|
+
setError(errorMessage);
|
|
91
|
+
setClient(null);
|
|
92
|
+
clearServerMetadata();
|
|
93
|
+
|
|
94
|
+
// Notify connection error
|
|
95
|
+
this.system.notifications.error(`Failed to connect: ${errorMessage}`);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Disconnect from the graph runner server
|
|
101
|
+
*/
|
|
102
|
+
async disconnect(): Promise<void> {
|
|
103
|
+
const {
|
|
104
|
+
client,
|
|
105
|
+
setClient,
|
|
106
|
+
setConnectionState,
|
|
107
|
+
setConnectionInfo,
|
|
108
|
+
clearServerMetadata
|
|
109
|
+
} = this.store.getState();
|
|
110
|
+
|
|
111
|
+
console.log('Disconnecting from graph runner server...');
|
|
112
|
+
if (client) {
|
|
113
|
+
try {
|
|
114
|
+
await client.closeSession();
|
|
115
|
+
client.disconnect();
|
|
116
|
+
} catch (error) {
|
|
117
|
+
console.error('Error disconnecting:', error);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
setClient(null);
|
|
122
|
+
setConnectionState('disconnected');
|
|
123
|
+
setConnectionInfo({
|
|
124
|
+
serverId: null,
|
|
125
|
+
userId: null,
|
|
126
|
+
sessionId: null,
|
|
127
|
+
authenticated: false,
|
|
128
|
+
capabilities: null
|
|
129
|
+
});
|
|
130
|
+
clearServerMetadata();
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Refresh server metadata (variables, events, node types)
|
|
135
|
+
*/
|
|
136
|
+
async refreshMetadata(): Promise<void> {
|
|
137
|
+
const {
|
|
138
|
+
client,
|
|
139
|
+
setServerVariables,
|
|
140
|
+
setServerEvents,
|
|
141
|
+
setNodeTypes,
|
|
142
|
+
setError
|
|
143
|
+
} = this.store.getState();
|
|
144
|
+
if (!client) {
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
try {
|
|
149
|
+
const capabilities = client.getCachedCapabilities();
|
|
150
|
+
if (!capabilities?.runtimeMetadata) {
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
const [variables, events, nodeTypes] = await Promise.all([
|
|
155
|
+
client.getServerVariables(),
|
|
156
|
+
client.getServerEvents(),
|
|
157
|
+
client.getNodeTypes()
|
|
158
|
+
]);
|
|
159
|
+
|
|
160
|
+
setServerVariables(variables);
|
|
161
|
+
setServerEvents(events);
|
|
162
|
+
setNodeTypes(nodeTypes);
|
|
163
|
+
|
|
164
|
+
setError(null);
|
|
165
|
+
} catch (error) {
|
|
166
|
+
setError(error instanceof Error ? error.message : String(error));
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Run a graph remotely
|
|
172
|
+
*/
|
|
173
|
+
async runRemotely(
|
|
174
|
+
graphId: string,
|
|
175
|
+
options?: { graph?: unknown; inputs?: unknown }
|
|
176
|
+
): Promise<void> {
|
|
177
|
+
const {
|
|
178
|
+
client,
|
|
179
|
+
setCurrentRunId,
|
|
180
|
+
setCurrentGraphId,
|
|
181
|
+
setIsExecuting,
|
|
182
|
+
setIsPaused,
|
|
183
|
+
isExecuting,
|
|
184
|
+
enableTracing
|
|
185
|
+
} = this.store.getState();
|
|
186
|
+
|
|
187
|
+
if (!client) {
|
|
188
|
+
this.system.notifications.error('No graph runner connection');
|
|
189
|
+
throw new Error('No graph runner connection');
|
|
190
|
+
}
|
|
191
|
+
//already running
|
|
192
|
+
if (isExecuting) {
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
try {
|
|
197
|
+
const runId = await client.runGraph(graphId, {
|
|
198
|
+
...options,
|
|
199
|
+
trace: enableTracing
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
setCurrentRunId(runId);
|
|
203
|
+
setCurrentGraphId(graphId);
|
|
204
|
+
setIsExecuting(true);
|
|
205
|
+
setIsPaused(false);
|
|
206
|
+
|
|
207
|
+
this.system.notifications.info(`Graph execution started: ${graphId}`);
|
|
208
|
+
} catch (error) {
|
|
209
|
+
const errorMessage =
|
|
210
|
+
error instanceof Error ? error.message : String(error);
|
|
211
|
+
setIsPaused(false);
|
|
212
|
+
this.system.notifications.error(`Failed to run graph: ${errorMessage}`);
|
|
213
|
+
setIsExecuting(false);
|
|
214
|
+
setCurrentRunId(null);
|
|
215
|
+
setCurrentGraphId(null);
|
|
216
|
+
throw error;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* Stop the current graph execution
|
|
222
|
+
*/
|
|
223
|
+
async stop(): Promise<void> {
|
|
224
|
+
const {
|
|
225
|
+
client,
|
|
226
|
+
currentRunId,
|
|
227
|
+
setIsExecuting,
|
|
228
|
+
setCurrentRunId,
|
|
229
|
+
setCurrentGraphId,
|
|
230
|
+
setIsPaused
|
|
231
|
+
} = this.store.getState();
|
|
232
|
+
|
|
233
|
+
if (!client || !currentRunId) {
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
try {
|
|
238
|
+
await client.stopGraph(currentRunId);
|
|
239
|
+
this.system.notifications.info('Stopping graph execution');
|
|
240
|
+
setIsExecuting(false);
|
|
241
|
+
setCurrentRunId(null);
|
|
242
|
+
setCurrentGraphId(null);
|
|
243
|
+
setIsPaused(false);
|
|
244
|
+
} catch (error) {
|
|
245
|
+
const errorMessage =
|
|
246
|
+
error instanceof Error ? error.message : String(error);
|
|
247
|
+
this.system.notifications.error(`Failed to stop graph: ${errorMessage}`);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Play the current graph
|
|
253
|
+
*/
|
|
254
|
+
async play(): Promise<void> {
|
|
255
|
+
const { clearLogsOnRun, clearTracesOnRun } = this.store.getState();
|
|
256
|
+
|
|
257
|
+
// Clear logs if enabled
|
|
258
|
+
if (clearLogsOnRun) {
|
|
259
|
+
this.system.logsStore.getState().clear();
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
// Clear traces if enabled
|
|
263
|
+
if (clearTracesOnRun) {
|
|
264
|
+
this.system.traceStore.getState().clear();
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
const graphId = 'current';
|
|
268
|
+
const uiGraphData = buildUIGraphJSON(this.system);
|
|
269
|
+
const graphData = uiGraphData.flow;
|
|
270
|
+
|
|
271
|
+
try {
|
|
272
|
+
await this.runRemotely(graphId, { graph: graphData });
|
|
273
|
+
} catch {
|
|
274
|
+
// Error already handled in runRemotely
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* Pause the current graph execution
|
|
280
|
+
*/
|
|
281
|
+
async pause(): Promise<void> {
|
|
282
|
+
const { client, currentRunId, setIsPaused } = this.store.getState();
|
|
283
|
+
|
|
284
|
+
if (!client || !currentRunId) {
|
|
285
|
+
return;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
try {
|
|
289
|
+
// Check if the client's transport is LocalTransport with pause support
|
|
290
|
+
const transport = (client as any).transport;
|
|
291
|
+
if (transport && typeof transport.pauseExecution === 'function') {
|
|
292
|
+
transport.pauseExecution(currentRunId);
|
|
293
|
+
setIsPaused(true);
|
|
294
|
+
this.system.notifications.info('Execution paused');
|
|
295
|
+
} else {
|
|
296
|
+
// Fallback to stop for remote transports
|
|
297
|
+
await this.stop();
|
|
298
|
+
}
|
|
299
|
+
} catch (error) {
|
|
300
|
+
const errorMessage =
|
|
301
|
+
error instanceof Error ? error.message : String(error);
|
|
302
|
+
this.system.notifications.error(`Failed to pause graph: ${errorMessage}`);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* Resume paused execution
|
|
308
|
+
*/
|
|
309
|
+
async resume(): Promise<void> {
|
|
310
|
+
const { client, currentRunId, setIsPaused } = this.store.getState();
|
|
311
|
+
|
|
312
|
+
if (!client || !currentRunId) {
|
|
313
|
+
return;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
try {
|
|
317
|
+
const transport = (client as any).transport;
|
|
318
|
+
if (transport && typeof transport.resumeExecution === 'function') {
|
|
319
|
+
setIsPaused(false);
|
|
320
|
+
this.system.notifications.info('Resuming execution');
|
|
321
|
+
await transport.resumeExecution(currentRunId);
|
|
322
|
+
}
|
|
323
|
+
} catch (error) {
|
|
324
|
+
const errorMessage =
|
|
325
|
+
error instanceof Error ? error.message : String(error);
|
|
326
|
+
this.system.notifications.error(
|
|
327
|
+
`Failed to resume graph: ${errorMessage}`
|
|
328
|
+
);
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
/**
|
|
333
|
+
* Execute one step forward
|
|
334
|
+
*/
|
|
335
|
+
async step(): Promise<void> {
|
|
336
|
+
const { client, currentRunId, setIsPaused } = this.store.getState();
|
|
337
|
+
|
|
338
|
+
if (!client || !currentRunId) {
|
|
339
|
+
return;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
try {
|
|
343
|
+
const transport = (client as any).transport;
|
|
344
|
+
if (transport && typeof transport.stepExecution === 'function') {
|
|
345
|
+
setIsPaused(true); // Ensure we stay paused after stepping
|
|
346
|
+
await transport.stepExecution(currentRunId);
|
|
347
|
+
} else {
|
|
348
|
+
this.system.notifications.info(
|
|
349
|
+
'Step execution not supported for this transport'
|
|
350
|
+
);
|
|
351
|
+
}
|
|
352
|
+
} catch (error) {
|
|
353
|
+
const errorMessage =
|
|
354
|
+
error instanceof Error ? error.message : String(error);
|
|
355
|
+
this.system.notifications.error(`Failed to step graph: ${errorMessage}`);
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
}
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session management for local graph runner
|
|
3
|
+
* Allows customization of execution context and configuration per session
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { IRegistry } from '@kiberon-labs/behave-graph';
|
|
7
|
+
import type {
|
|
8
|
+
GraphRunnerCapabilities,
|
|
9
|
+
EventFilter
|
|
10
|
+
} from '../graphrunner/types.js';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Session configuration for graph execution
|
|
14
|
+
*/
|
|
15
|
+
export interface SessionConfig {
|
|
16
|
+
/** Custom metadata attached to the session */
|
|
17
|
+
metadata?: Record<string, unknown>;
|
|
18
|
+
/** Default execution options for all runs in this session */
|
|
19
|
+
defaultExecutionOptions?: {
|
|
20
|
+
autoEnd?: boolean;
|
|
21
|
+
trace?: boolean;
|
|
22
|
+
eventFilter?: EventFilter;
|
|
23
|
+
maxExecutionTimeMs?: number;
|
|
24
|
+
};
|
|
25
|
+
/** Session-level execution settings */
|
|
26
|
+
executionSettings?: {
|
|
27
|
+
/** Delay between execution steps in milliseconds */
|
|
28
|
+
stepDelay?: number;
|
|
29
|
+
/** Execution speed multiplier (0.1 to 2.0) */
|
|
30
|
+
executionSpeed?: number;
|
|
31
|
+
/** Interval between tick events in milliseconds */
|
|
32
|
+
tickInterval?: number;
|
|
33
|
+
/** Maximum number of concurrent runs allowed */
|
|
34
|
+
maxConcurrentRuns?: number;
|
|
35
|
+
};
|
|
36
|
+
/** Custom hook for handling tick timing/delays */
|
|
37
|
+
tickStrategy?: () => Promise<void>;
|
|
38
|
+
/** Custom registry overrides for this session */
|
|
39
|
+
registryOverrides?: Partial<IRegistry>;
|
|
40
|
+
/** Session lifecycle hooks */
|
|
41
|
+
hooks?: SessionHooks;
|
|
42
|
+
/** Session-specific capabilities override */
|
|
43
|
+
capabilities?: Partial<GraphRunnerCapabilities>;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Lifecycle hooks for session events
|
|
48
|
+
*/
|
|
49
|
+
export interface SessionHooks {
|
|
50
|
+
/** Called when the session is created */
|
|
51
|
+
onSessionCreated?: (session: Session) => void | Promise<void>;
|
|
52
|
+
/** Called when a run starts in this session */
|
|
53
|
+
onRunStarted?: (
|
|
54
|
+
session: Session,
|
|
55
|
+
runId: string,
|
|
56
|
+
graphId: string
|
|
57
|
+
) => void | Promise<void>;
|
|
58
|
+
/** Called when a run completes in this session */
|
|
59
|
+
onRunCompleted?: (
|
|
60
|
+
session: Session,
|
|
61
|
+
runId: string,
|
|
62
|
+
graphId: string,
|
|
63
|
+
result: unknown
|
|
64
|
+
) => void | Promise<void>;
|
|
65
|
+
/** Called when a run fails in this session */
|
|
66
|
+
onRunError?: (
|
|
67
|
+
session: Session,
|
|
68
|
+
runId: string,
|
|
69
|
+
graphId: string,
|
|
70
|
+
error: Error
|
|
71
|
+
) => void | Promise<void>;
|
|
72
|
+
/** Called when the session is closed */
|
|
73
|
+
onSessionClosed?: (session: Session) => void | Promise<void>;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Session state
|
|
78
|
+
*/
|
|
79
|
+
export interface Session {
|
|
80
|
+
/** Unique session identifier */
|
|
81
|
+
readonly sessionId: string;
|
|
82
|
+
/** Session expiration timestamp */
|
|
83
|
+
readonly expiresAt: number;
|
|
84
|
+
/** Session creation timestamp */
|
|
85
|
+
readonly createdAt: number;
|
|
86
|
+
/** Session configuration */
|
|
87
|
+
readonly config: SessionConfig;
|
|
88
|
+
/** Active run IDs in this session */
|
|
89
|
+
readonly activeRuns: Set<string>;
|
|
90
|
+
/** Custom session state (user-definable) */
|
|
91
|
+
state: Record<string, unknown>;
|
|
92
|
+
/** Session metadata */
|
|
93
|
+
metadata: Record<string, unknown>;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Factory for creating sessions with custom configuration
|
|
98
|
+
*/
|
|
99
|
+
export interface SessionFactory {
|
|
100
|
+
/**
|
|
101
|
+
* Create a new session with optional configuration
|
|
102
|
+
*/
|
|
103
|
+
createSession(sessionId: string, config?: SessionConfig): Session;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Default session factory implementation
|
|
108
|
+
*/
|
|
109
|
+
export class DefaultSessionFactory implements SessionFactory {
|
|
110
|
+
private defaultConfig?: SessionConfig;
|
|
111
|
+
|
|
112
|
+
constructor(defaultConfig?: SessionConfig) {
|
|
113
|
+
this.defaultConfig = defaultConfig;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
createSession(sessionId: string, config?: SessionConfig): Session {
|
|
117
|
+
const mergedConfig: SessionConfig = {
|
|
118
|
+
...this.defaultConfig,
|
|
119
|
+
...config,
|
|
120
|
+
metadata: {
|
|
121
|
+
...this.defaultConfig?.metadata,
|
|
122
|
+
...config?.metadata
|
|
123
|
+
},
|
|
124
|
+
defaultExecutionOptions: {
|
|
125
|
+
...this.defaultConfig?.defaultExecutionOptions,
|
|
126
|
+
...config?.defaultExecutionOptions
|
|
127
|
+
},
|
|
128
|
+
executionSettings: {
|
|
129
|
+
...this.defaultConfig?.executionSettings,
|
|
130
|
+
...config?.executionSettings
|
|
131
|
+
},
|
|
132
|
+
hooks: {
|
|
133
|
+
...this.defaultConfig?.hooks,
|
|
134
|
+
...config?.hooks
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
const session: Session = {
|
|
139
|
+
sessionId,
|
|
140
|
+
expiresAt: Date.now() + 24 * 60 * 60 * 1000, // 24 hours default
|
|
141
|
+
createdAt: Date.now(),
|
|
142
|
+
config: mergedConfig,
|
|
143
|
+
activeRuns: new Set(),
|
|
144
|
+
state: {},
|
|
145
|
+
metadata: mergedConfig.metadata ?? {}
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
// Call creation hook
|
|
149
|
+
if (mergedConfig.hooks?.onSessionCreated) {
|
|
150
|
+
void mergedConfig.hooks.onSessionCreated(session);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
return session;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Session manager to track and manage multiple sessions
|
|
159
|
+
*/
|
|
160
|
+
export class SessionManager {
|
|
161
|
+
private sessions = new Map<string, Session>();
|
|
162
|
+
private sessionFactory: SessionFactory;
|
|
163
|
+
|
|
164
|
+
constructor(sessionFactory?: SessionFactory) {
|
|
165
|
+
this.sessionFactory = sessionFactory ?? new DefaultSessionFactory();
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Create a new session
|
|
170
|
+
*/
|
|
171
|
+
createSession(sessionId: string, config?: SessionConfig): Session {
|
|
172
|
+
const session = this.sessionFactory.createSession(sessionId, config);
|
|
173
|
+
this.sessions.set(sessionId, session);
|
|
174
|
+
return session;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Get an existing session
|
|
179
|
+
*/
|
|
180
|
+
getSession(sessionId: string): Session | undefined {
|
|
181
|
+
return this.sessions.get(sessionId);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Check if a session exists
|
|
186
|
+
*/
|
|
187
|
+
hasSession(sessionId: string): boolean {
|
|
188
|
+
return this.sessions.has(sessionId);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Close and remove a session
|
|
193
|
+
*/
|
|
194
|
+
async closeSession(sessionId: string): Promise<void> {
|
|
195
|
+
const session = this.sessions.get(sessionId);
|
|
196
|
+
if (session) {
|
|
197
|
+
// Call close hook
|
|
198
|
+
if (session.config.hooks?.onSessionClosed) {
|
|
199
|
+
await session.config.hooks.onSessionClosed(session);
|
|
200
|
+
}
|
|
201
|
+
this.sessions.delete(sessionId);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Add a run to a session
|
|
207
|
+
*/
|
|
208
|
+
addRunToSession(sessionId: string, runId: string): void {
|
|
209
|
+
const session = this.sessions.get(sessionId);
|
|
210
|
+
if (session) {
|
|
211
|
+
session.activeRuns.add(runId);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Remove a run from a session
|
|
217
|
+
*/
|
|
218
|
+
removeRunFromSession(sessionId: string, runId: string): void {
|
|
219
|
+
const session = this.sessions.get(sessionId);
|
|
220
|
+
if (session) {
|
|
221
|
+
session.activeRuns.delete(runId);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* Get all active sessions
|
|
227
|
+
*/
|
|
228
|
+
getActiveSessions(): Session[] {
|
|
229
|
+
return Array.from(this.sessions.values());
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* Clean up expired sessions
|
|
234
|
+
*/
|
|
235
|
+
cleanupExpiredSessions(): void {
|
|
236
|
+
const now = Date.now();
|
|
237
|
+
for (const [sessionId, session] of this.sessions.entries()) {
|
|
238
|
+
if (session.expiresAt < now) {
|
|
239
|
+
void this.closeSession(sessionId);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|