@kiberon-labs/behave-graph-flow 2.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/.storybook/manager.ts +6 -0
- package/.storybook/preview.ts +49 -1
- package/.storybook/styles.css +9 -3
- package/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +368 -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/index.css +36 -33
- package/dist/index.css.map +1 -1
- package/dist/index.d.ts +1865 -550
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +14357 -11221
- package/dist/index.js.map +1 -1
- 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/protocol.md +43 -20
- package/package.json +5 -9
- package/src/components/FloatingToolbar/index.module.css +5 -13
- package/src/components/FloatingToolbar/index.tsx +9 -9
- package/src/components/Flow.tsx +34 -23
- package/src/components/contextMenus/DynamicContextMenu.tsx +85 -0
- package/src/components/contextMenus/NodePicker.module.css +13 -13
- package/src/components/contextMenus/edge.tsx +9 -95
- package/src/components/contextMenus/node.tsx +9 -149
- package/src/components/contextMenus/selection.tsx +5 -71
- package/src/components/controls/any/AnyControlImpl.tsx +14 -0
- package/src/components/controls/any/index.tsx +13 -2
- package/src/components/edges/index.tsx +75 -69
- package/src/components/layoutController/index.module.css +3 -0
- package/src/components/layoutController/index.tsx +24 -1
- package/src/components/layoutController/utils.ts +46 -3
- package/src/components/menubar/defaults.tsx +55 -19
- package/src/components/menubar/menuItem.module.css +18 -3
- package/src/components/menubar/menuItem.tsx +34 -1
- package/src/components/nodes/behave/NodeContainer.module.css +26 -25
- package/src/components/nodes/group/index.tsx +3 -3
- package/src/components/nodes/wrapper/styles.module.css +6 -32
- package/src/components/panels/alignment/index.module.css +0 -10
- package/src/components/panels/alignment/index.tsx +4 -4
- package/src/components/panels/base/styles.module.css +2 -2
- 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 +14 -5
- package/src/components/panels/events/ManageEventsPanel.tsx +11 -8
- package/src/components/panels/events/styles.module.css +6 -64
- package/src/components/panels/graphProperties/index.tsx +125 -0
- package/src/components/panels/history/index.tsx +2 -2
- package/src/components/panels/history/styles.module.css +0 -9
- package/src/components/panels/keymaps/index.module.css +3 -13
- package/src/components/panels/keymaps/index.tsx +1 -2
- package/src/components/panels/layers/index.tsx +20 -15
- package/src/components/panels/layers/styles.module.css +9 -12
- package/src/components/panels/legend/index.tsx +1 -1
- package/src/components/panels/logs/index.module.css +25 -19
- package/src/components/panels/logs/index.tsx +7 -7
- package/src/components/panels/nodeInputs/InputsGroup.tsx +1 -0
- package/src/components/panels/nodeInputs/NodeSettings.tsx +2 -2
- package/src/components/panels/nodeInputs/NodeTitleEditor.tsx +1 -1
- package/src/components/panels/nodeInputs/OutputsGroup.tsx +2 -12
- package/src/components/panels/nodeInputs/index.module.css +99 -75
- package/src/components/panels/nodeInputs/index.tsx +21 -11
- package/src/components/panels/nodeInputs/useNodeHandlers.ts +2 -2
- package/src/components/panels/nodeInputs/useNodeInputsData.ts +23 -43
- package/src/components/panels/nodePicker/index.tsx +8 -8
- package/src/components/panels/panel/index.module.css +7 -7
- package/src/components/panels/search/index.module.css +0 -50
- package/src/components/panels/search/index.tsx +2 -2
- package/src/components/panels/systemSettings/ConversionsSettings.tsx +203 -0
- package/src/components/panels/systemSettings/index.tsx +221 -176
- package/src/components/panels/systemSettings/styles.module.css +135 -8
- package/src/components/panels/traces/GridLines.tsx +1 -1
- package/src/components/panels/traces/TimeGrid.tsx +3 -3
- package/src/components/panels/traces/TraceLane.tsx +1 -1
- package/src/components/panels/traces/index.module.css +1 -8
- package/src/components/panels/traces/index.tsx +8 -4
- package/src/components/panels/traces/useDerivedSpans.ts +241 -146
- package/src/components/panels/traces/utils.ts +8 -0
- package/src/components/panels/variables/CreateVariableScreen.tsx +3 -3
- package/src/components/panels/variables/ManageVariablesScreen.tsx +12 -9
- package/src/components/panels/variables/index.tsx +2 -2
- package/src/components/panels/variables/styles.module.css +4 -91
- package/src/components/primitives/icon.module.css +4 -4
- package/src/components/sockets/input/index.tsx +9 -2
- package/src/components/sockets/input/styles.module.css +2 -3
- package/src/components/sockets/output/index.tsx +10 -3
- package/src/components/sockets/output/styles.module.css +1 -6
- package/src/css/notes.css +135 -0
- package/src/css/prosemirror.css +3 -3
- package/src/css/rc-dock.css +143 -43
- package/src/css/rc-menu.css +56 -55
- package/src/css/themes/kiberon.css +127 -0
- package/src/css/vars.css +197 -13
- package/src/css/vscode-elements.css +124 -0
- package/src/generators/CallSubgraphGenerator.tsx +136 -0
- package/src/generators/CustomEventOnTriggeredGenerator.tsx +2 -2
- package/src/generators/GraphBoundaryGenerator.module.css +32 -0
- package/src/generators/GraphBoundaryGenerator.tsx +193 -0
- package/src/generators/SequenceGenerator.tsx +2 -2
- package/src/generators/SwitchOnIntegerGenerator.tsx +2 -2
- package/src/generators/SwitchOnStringGenerator.tsx +2 -2
- package/src/generators/callSubgraphSync.ts +126 -0
- package/src/generators/registerDefaultGenerators.ts +21 -0
- package/src/generators/registerDefaults.ts +26 -0
- package/src/hooks/useBehaveGraphFlow.ts +2 -2
- package/src/hooks/useFlowHandlers.ts +47 -9
- package/src/hooks/useWasdPan.ts +26 -4
- package/src/index.css +4 -16
- package/src/index.ts +17 -0
- 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 +22 -12
- 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 +2 -4
- package/src/plugin/docs/panel/DocumentationBrowserPanelImpl.tsx +200 -0
- package/src/plugin/docs/panel/index.tsx +15 -194
- package/src/plugin/docs/panel/styles.module.css +8 -8
- package/src/plugin/graphrunner/actions.ts +258 -185
- package/src/plugin/graphrunner/buttons.tsx +34 -26
- package/src/plugin/graphrunner/client.ts +4 -1
- package/src/plugin/graphrunner/index.tsx +29 -100
- package/src/plugin/graphrunner/panel.tsx +2 -2
- package/src/plugin/graphrunner/runController.ts +283 -0
- package/src/plugin/graphrunner/runner.ts +21 -192
- package/src/plugin/graphrunner/store.ts +14 -24
- package/src/plugin/graphrunner/styles.module.css +17 -57
- package/src/plugin/graphrunner/transport.ts +26 -0
- package/src/plugin/graphrunner/types.ts +21 -0
- package/src/plugin/graphrunner-local/execution-utils.ts +260 -80
- package/src/plugin/graphrunner-local/index.tsx +8 -2
- package/src/plugin/graphrunner-local/panel.tsx +131 -175
- package/src/plugin/graphrunner-local/styles.module.css +57 -76
- package/src/plugin/graphrunner-local/transport.ts +151 -184
- package/src/plugin/graphrunner-webworker/graph-executor.worker.ts +2 -0
- package/src/plugin/graphrunner-webworker/index.tsx +4 -10
- package/src/plugin/graphrunner-webworker/store.ts +9 -0
- package/src/plugin/kitchen-sink/index.ts +38 -0
- package/src/{layout/dagre.tsx → plugin/layout/dagre.ts} +17 -5
- package/src/{layout → plugin/layout}/elk.ts +22 -6
- 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 +58 -4
- package/src/specifics/CustomEventOnTriggeredSpecific.tsx +2 -2
- package/src/specifics/CustomEventTriggerSpecific.tsx +2 -2
- package/src/specifics/VariableGetSpecific.tsx +2 -2
- package/src/specifics/VariableSetSpecific.tsx +2 -2
- package/src/store/actions.tsx +5 -5
- package/src/store/commands.ts +278 -0
- package/src/store/contextMenu.ts +192 -0
- package/src/store/conversions.ts +47 -0
- package/src/store/flow.tsx +23 -38
- package/src/store/graphMeta.ts +39 -0
- package/src/store/hotKeys.tsx +301 -260
- package/src/store/layers.ts +3 -3
- package/src/store/registry.ts +12 -4
- package/src/store/selection.ts +3 -3
- package/src/store/settings.ts +82 -82
- package/src/store/settingsSchema.ts +210 -0
- package/src/store/tabs.ts +5 -1
- package/src/store/traces.ts +3 -3
- package/src/system/graph.ts +11 -14
- package/src/system/graphSession.ts +172 -0
- package/src/system/index.ts +3 -0
- package/src/system/notifications.ts +13 -0
- package/src/system/persistence.ts +82 -0
- package/src/system/plugin.ts +28 -0
- package/src/system/provider.tsx +64 -0
- package/src/system/system.ts +518 -88
- package/src/system/tabLoader.tsx +70 -32
- package/src/system/undoRedo.ts +1 -1
- package/src/transformers/Uigraph.ts +5 -4
- package/src/transformers/contract.ts +87 -0
- package/src/transformers/flowToBehave.ts +13 -5
- package/src/types/nodes.ts +8 -3
- package/src/types.ts +2 -0
- package/src/util/autoConvert.ts +200 -0
- package/src/util/isValidConnection.ts +23 -2
- package/stories/defaults/defaultStoryProvider.tsx +17 -14
- package/stories/defaults/systemGenerator.ts +6 -1
- package/stories/{components/nodes/comment.stories.tsx → plugins/notes.stories.tsx} +24 -30
- 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/contract.test.ts +51 -0
- package/tests/contractSerialize.test.ts +62 -0
- package/tests/deriveSpans.test.ts +71 -0
- package/tests/flowToBehave.test.ts +2 -1
- 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/persistence.test.ts +51 -0
- package/tests/saveLoad.test.ts +7 -6
- package/tests/settings.test.ts +178 -0
- package/tests/traceStore.test.ts +46 -0
- package/tests/visual/README.md +2 -2
- 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-variables-chromium-win32.png +0 -0
- package/tests/visual/panels.visual.test.tsx +3 -3
- package/tests/wasdPan.test.ts +71 -0
- package/vitest.config.ts +1 -1
- package/vitest.visual.config.ts +7 -0
- package/.storybook/vscode.css +0 -814
- package/src/components/nodes/comment/FormatToolbar.tsx +0 -118
- package/src/components/nodes/comment/comment.tsx +0 -103
- package/src/components/nodes/comment/styles.module.css +0 -150
- package/src/components/panels/conversation/index.module.css +0 -151
- package/src/components/panels/conversation/index.tsx +0 -162
- package/src/components/panels/events/CustomEventsEditor.tsx +0 -384
- package/src/css/vscode.css +0 -13
- package/src/hooks/useDetachNodes.ts +0 -39
- package/src/plugin/graphrunner-webworker/types.ts +0 -17
- package/src/specifics/registerDefaultSpecifics.ts +0 -5
- package/src/store/chat.ts +0 -73
- package/src/store/graphRunnerClient.ts +0 -110
|
@@ -2,8 +2,8 @@ import type { System } from '../../system/system';
|
|
|
2
2
|
import type { StoreApi } from 'zustand';
|
|
3
3
|
import type { GraphRunnerClientStore } from './store';
|
|
4
4
|
import { GraphRunnerClient } from './client';
|
|
5
|
-
import { buildUIGraphJSON } from '../../transformers/Uigraph';
|
|
6
5
|
import { setupClientEventListeners } from './actions';
|
|
6
|
+
import type { GraphRunController } from './runController';
|
|
7
7
|
|
|
8
8
|
declare module '@/system/system' {
|
|
9
9
|
interface System {
|
|
@@ -11,15 +11,32 @@ declare module '@/system/system' {
|
|
|
11
11
|
}
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
+
/**
|
|
15
|
+
* Shared connection to the graph runner server. Owns the client, connection
|
|
16
|
+
* lifecycle and server metadata; per-graph run state and run lifecycle live on
|
|
17
|
+
* {@link GraphRunController}. Incoming server messages are dispatched back to the
|
|
18
|
+
* owning controller via {@link GraphRunner.runIndex}, keyed by run id, so
|
|
19
|
+
* multiple graphs can run concurrently and independently.
|
|
20
|
+
*/
|
|
14
21
|
export class GraphRunner {
|
|
15
22
|
private system: System;
|
|
16
23
|
public readonly store: StoreApi<GraphRunnerClientStore>;
|
|
24
|
+
/** runId -> the controller that started it. */
|
|
25
|
+
public readonly runIndex = new Map<string, GraphRunController>();
|
|
17
26
|
|
|
18
27
|
constructor(system: System, store: StoreApi<GraphRunnerClientStore>) {
|
|
19
28
|
this.system = system;
|
|
20
29
|
this.store = store;
|
|
21
30
|
}
|
|
22
31
|
|
|
32
|
+
registerRun(runId: string, controller: GraphRunController): void {
|
|
33
|
+
this.runIndex.set(runId, controller);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
unregisterRun(runId: string): void {
|
|
37
|
+
this.runIndex.delete(runId);
|
|
38
|
+
}
|
|
39
|
+
|
|
23
40
|
/**
|
|
24
41
|
* Connect to the graph runner server
|
|
25
42
|
*/
|
|
@@ -54,8 +71,9 @@ export class GraphRunner {
|
|
|
54
71
|
|
|
55
72
|
await theClient.connect();
|
|
56
73
|
|
|
57
|
-
// Setup persistent event listeners for trace, logs, and run completion
|
|
58
|
-
|
|
74
|
+
// Setup persistent event listeners for trace, logs, and run completion.
|
|
75
|
+
// Messages are routed to the originating session by run id.
|
|
76
|
+
setupClientEventListeners(theClient, this);
|
|
59
77
|
|
|
60
78
|
setConnectionState('connected');
|
|
61
79
|
setConnectionInfo({
|
|
@@ -166,193 +184,4 @@ export class GraphRunner {
|
|
|
166
184
|
setError(error instanceof Error ? error.message : String(error));
|
|
167
185
|
}
|
|
168
186
|
}
|
|
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
187
|
}
|
|
@@ -55,13 +55,7 @@ export interface GraphRunnerClientStore {
|
|
|
55
55
|
messageActivity: MessageActivity[];
|
|
56
56
|
maxActivityMessages: number;
|
|
57
57
|
|
|
58
|
-
// Execution
|
|
59
|
-
currentRunId: string | null;
|
|
60
|
-
currentGraphId: string | null;
|
|
61
|
-
isExecuting: boolean;
|
|
62
|
-
isPaused: boolean;
|
|
63
|
-
|
|
64
|
-
// Execution preferences
|
|
58
|
+
// Execution preferences (global defaults applied to every run)
|
|
65
59
|
clearLogsOnRun: boolean;
|
|
66
60
|
clearTracesOnRun: boolean;
|
|
67
61
|
enableTracing: boolean;
|
|
@@ -83,10 +77,6 @@ export interface GraphRunnerClientStore {
|
|
|
83
77
|
message: GraphRunnerMessage
|
|
84
78
|
) => void;
|
|
85
79
|
clearMessageActivity: () => void;
|
|
86
|
-
setCurrentRunId: (runId: string | null) => void;
|
|
87
|
-
setCurrentGraphId: (graphId: string | null) => void;
|
|
88
|
-
setIsExecuting: (isExecuting: boolean) => void;
|
|
89
|
-
setIsPaused: (isPaused: boolean) => void;
|
|
90
80
|
setClearLogsOnRun: (clear: boolean) => void;
|
|
91
81
|
setClearTracesOnRun: (clear: boolean) => void;
|
|
92
82
|
setEnableTracing: (enable: boolean) => void;
|
|
@@ -117,13 +107,12 @@ export const graphRunnerClientStoreFactory = (
|
|
|
117
107
|
nodeTypes: [],
|
|
118
108
|
messageActivity: [],
|
|
119
109
|
maxActivityMessages: 50,
|
|
120
|
-
currentRunId: null,
|
|
121
|
-
currentGraphId: null,
|
|
122
|
-
isExecuting: false,
|
|
123
|
-
isPaused: false,
|
|
124
110
|
clearLogsOnRun: true,
|
|
125
111
|
clearTracesOnRun: true,
|
|
126
|
-
|
|
112
|
+
// Off by default: tracing costs two events per node execution and is the
|
|
113
|
+
// single biggest per-frame overhead for display-rate graphs. Opt in via the
|
|
114
|
+
// "Enable execution tracing" checkbox in the graph runner panel.
|
|
115
|
+
enableTracing: false,
|
|
127
116
|
|
|
128
117
|
// Actions
|
|
129
118
|
setConnectionConfig: (config) =>
|
|
@@ -174,6 +163,15 @@ export const graphRunnerClientStoreFactory = (
|
|
|
174
163
|
|
|
175
164
|
addMessageActivity: (direction, message) =>
|
|
176
165
|
set((state) => {
|
|
166
|
+
// Trace traffic is high-frequency (per node execution / per frame) and
|
|
167
|
+
// has its own dedicated panel; recording it here allocated a new
|
|
168
|
+
// activity array per event and instantly evicted every other message
|
|
169
|
+
// from the 50-entry ring. Received server messages are cast into this
|
|
170
|
+
// union by the callers, so compare the raw type string.
|
|
171
|
+
const type = (message as { type: string }).type;
|
|
172
|
+
if (type === 'trace' || type === 'traceBatch') {
|
|
173
|
+
return state;
|
|
174
|
+
}
|
|
177
175
|
const activity: MessageActivity = {
|
|
178
176
|
id: `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
|
|
179
177
|
timestamp: Date.now(),
|
|
@@ -189,14 +187,6 @@ export const graphRunnerClientStoreFactory = (
|
|
|
189
187
|
|
|
190
188
|
clearMessageActivity: () => set({ messageActivity: [] }),
|
|
191
189
|
|
|
192
|
-
setCurrentRunId: (currentRunId) => set({ currentRunId }),
|
|
193
|
-
|
|
194
|
-
setCurrentGraphId: (currentGraphId) => set({ currentGraphId }),
|
|
195
|
-
|
|
196
|
-
setIsExecuting: (isExecuting) => set({ isExecuting }),
|
|
197
|
-
|
|
198
|
-
setIsPaused: (isPaused) => set({ isPaused }),
|
|
199
|
-
|
|
200
190
|
setClearLogsOnRun: (clearLogsOnRun) => set({ clearLogsOnRun }),
|
|
201
191
|
|
|
202
192
|
setClearTracesOnRun: (clearTracesOnRun) => set({ clearTracesOnRun }),
|
|
@@ -44,18 +44,18 @@
|
|
|
44
44
|
|
|
45
45
|
.errorBox {
|
|
46
46
|
padding: 0.75rem;
|
|
47
|
-
background-color: var(--
|
|
48
|
-
border: 1px solid var(--
|
|
47
|
+
background-color: var(--ds-error-bg);
|
|
48
|
+
border: 1px solid var(--ds-error-border);
|
|
49
49
|
border-radius: 4px;
|
|
50
50
|
font-size: 0.875rem;
|
|
51
|
-
color: var(--
|
|
51
|
+
color: var(--ds-error-fg);
|
|
52
52
|
word-break: break-word;
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
.infoBox {
|
|
56
56
|
padding: 0.75rem;
|
|
57
|
-
background-color: var(--
|
|
58
|
-
border: 1px solid var(--
|
|
57
|
+
background-color: var(--ds-info-bg);
|
|
58
|
+
border: 1px solid var(--ds-info-border);
|
|
59
59
|
border-radius: 4px;
|
|
60
60
|
font-size: 0.875rem;
|
|
61
61
|
display: flex;
|
|
@@ -67,24 +67,6 @@
|
|
|
67
67
|
word-break: break-word;
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
-
.tabs {
|
|
71
|
-
border-bottom: 1px solid var(--vscode-panel-border);
|
|
72
|
-
overflow-x: auto;
|
|
73
|
-
gap: 0.25rem;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
.tabContent {
|
|
78
|
-
flex: 1;
|
|
79
|
-
min-height: 0;
|
|
80
|
-
display: flex;
|
|
81
|
-
flex-direction: column;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
.tabPanel {
|
|
85
|
-
overflow: auto;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
70
|
.tabPanelGap {
|
|
89
71
|
overflow: auto;
|
|
90
72
|
display: flex;
|
|
@@ -99,28 +81,19 @@
|
|
|
99
81
|
gap: 0.75rem;
|
|
100
82
|
}
|
|
101
83
|
|
|
102
|
-
.connectionMessage {
|
|
103
|
-
font-size: 0.875rem;
|
|
104
|
-
padding: 0.5rem 0;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
.connectionMessage p {
|
|
108
|
-
margin: 0;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
84
|
.emptyMessage {
|
|
112
85
|
font-size: 0.875rem;
|
|
113
|
-
color: var(--
|
|
86
|
+
color: var(--ds-fg-muted);
|
|
114
87
|
margin: 0;
|
|
115
88
|
}
|
|
116
89
|
|
|
117
90
|
.codeBlock {
|
|
118
91
|
font-size: 0.75rem;
|
|
119
|
-
font-family: var(--
|
|
120
|
-
color: var(--
|
|
92
|
+
font-family: var(--ds-font-mono);
|
|
93
|
+
color: var(--ds-editor-fg);
|
|
121
94
|
margin: 0;
|
|
122
95
|
padding: 0.5rem;
|
|
123
|
-
background-color: var(--
|
|
96
|
+
background-color: var(--ds-code-bg);
|
|
124
97
|
border-radius: 2px;
|
|
125
98
|
overflow: auto;
|
|
126
99
|
}
|
|
@@ -133,22 +106,22 @@
|
|
|
133
106
|
gap: 0.5rem;
|
|
134
107
|
position: sticky;
|
|
135
108
|
top: 0;
|
|
136
|
-
background-color: var(--
|
|
109
|
+
background-color: var(--ds-editor-bg);
|
|
137
110
|
padding-bottom: 0.5rem;
|
|
138
|
-
border-bottom: 1px solid var(--
|
|
111
|
+
border-bottom: 1px solid var(--ds-panel-border);
|
|
139
112
|
z-index: 1;
|
|
140
113
|
}
|
|
141
114
|
|
|
142
115
|
.messagesCount {
|
|
143
116
|
font-size: 0.875rem;
|
|
144
|
-
color: var(--
|
|
117
|
+
color: var(--ds-fg-muted);
|
|
145
118
|
}
|
|
146
119
|
|
|
147
120
|
.messageCard {
|
|
148
121
|
padding: 0.75rem;
|
|
149
|
-
border: 1px solid var(--
|
|
122
|
+
border: 1px solid var(--ds-panel-border);
|
|
150
123
|
border-radius: 4px;
|
|
151
|
-
background-color: var(--
|
|
124
|
+
background-color: var(--ds-editor-bg);
|
|
152
125
|
font-size: 0.875rem;
|
|
153
126
|
}
|
|
154
127
|
|
|
@@ -176,7 +149,7 @@
|
|
|
176
149
|
}
|
|
177
150
|
|
|
178
151
|
.messageTime {
|
|
179
|
-
color: var(--
|
|
152
|
+
color: var(--ds-fg-muted);
|
|
180
153
|
font-size: 0.75rem;
|
|
181
154
|
white-space: nowrap;
|
|
182
155
|
}
|
|
@@ -184,28 +157,15 @@
|
|
|
184
157
|
.messageContent {
|
|
185
158
|
margin: 0;
|
|
186
159
|
padding: 0.5rem;
|
|
187
|
-
background-color: var(--
|
|
160
|
+
background-color: var(--ds-code-bg);
|
|
188
161
|
border-radius: 2px;
|
|
189
162
|
font-size: 0.75rem;
|
|
190
|
-
font-family: var(--
|
|
163
|
+
font-family: var(--ds-font-mono);
|
|
191
164
|
overflow: auto;
|
|
192
165
|
max-height: 200px;
|
|
193
166
|
word-break: break-all;
|
|
194
167
|
}
|
|
195
168
|
|
|
196
|
-
.treeItemContent {
|
|
197
|
-
display: flex;
|
|
198
|
-
flex-direction: column;
|
|
199
|
-
gap: 0.25rem;
|
|
200
|
-
padding: 0.25rem 0;
|
|
201
|
-
}
|
|
202
|
-
|
|
203
169
|
.treeItemTitle {
|
|
204
170
|
font-weight: 500;
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
.treeItemDescription {
|
|
208
|
-
font-size: 0.875rem;
|
|
209
|
-
color: var(--vscode-descriptionForeground);
|
|
210
|
-
margin-top: 0.25rem;
|
|
211
171
|
}
|
|
@@ -61,6 +61,32 @@ export interface ITransport<
|
|
|
61
61
|
*/
|
|
62
62
|
removeAllHandlers(): void;
|
|
63
63
|
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Optional capability: a transport that can interactively control a run
|
|
67
|
+
* (pause / resume / step). Remote transports may not support it; the client
|
|
68
|
+
* detects support via {@link supportsExecutionControl} rather than reaching into
|
|
69
|
+
* transport internals.
|
|
70
|
+
*/
|
|
71
|
+
export interface IExecutionControl {
|
|
72
|
+
pauseExecution(runId: string): void;
|
|
73
|
+
resumeExecution(runId: string): Promise<void>;
|
|
74
|
+
stepExecution(runId: string): Promise<void>;
|
|
75
|
+
isPaused(runId: string): boolean;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/** Type guard: does this transport implement {@link IExecutionControl}? */
|
|
79
|
+
export function supportsExecutionControl(
|
|
80
|
+
transport: unknown
|
|
81
|
+
): transport is IExecutionControl {
|
|
82
|
+
return (
|
|
83
|
+
!!transport &&
|
|
84
|
+
typeof (transport as IExecutionControl).pauseExecution === 'function' &&
|
|
85
|
+
typeof (transport as IExecutionControl).resumeExecution === 'function' &&
|
|
86
|
+
typeof (transport as IExecutionControl).stepExecution === 'function'
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
|
|
64
90
|
/**
|
|
65
91
|
* WebSocket transport implementation
|
|
66
92
|
*/
|
|
@@ -184,6 +184,26 @@ export interface TraceMessage {
|
|
|
184
184
|
timestamp: number;
|
|
185
185
|
}
|
|
186
186
|
|
|
187
|
+
/** A single node-execution event inside a {@link TraceBatchMessage}. */
|
|
188
|
+
export interface TraceBatchEvent {
|
|
189
|
+
nodeId: string;
|
|
190
|
+
event: string;
|
|
191
|
+
data?: unknown;
|
|
192
|
+
timestamp: number;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Coalesced trace events for one run. Runners buffer per-node execution events
|
|
197
|
+
* and flush them roughly once per frame, so a tick that executes hundreds of
|
|
198
|
+
* nodes costs one message instead of hundreds.
|
|
199
|
+
*/
|
|
200
|
+
export interface TraceBatchMessage {
|
|
201
|
+
type: 'traceBatch';
|
|
202
|
+
runId: string;
|
|
203
|
+
graphId: string;
|
|
204
|
+
events: TraceBatchEvent[];
|
|
205
|
+
}
|
|
206
|
+
|
|
187
207
|
export interface LogMessage {
|
|
188
208
|
type: 'log';
|
|
189
209
|
runId: string;
|
|
@@ -289,6 +309,7 @@ export type ServerGraphRunnerMessage =
|
|
|
289
309
|
| ValidationResultMessage
|
|
290
310
|
// Events
|
|
291
311
|
| TraceMessage
|
|
312
|
+
| TraceBatchMessage
|
|
292
313
|
| LogMessage
|
|
293
314
|
| VariableChangedMessage
|
|
294
315
|
| CompletedMessage
|