@dxos/react-ui-canvas-compute 0.8.4-main.ae835ea → 0.8.4-main.bc2380dfbc
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/LICENSE +102 -5
- package/dist/lib/browser/index.mjs +916 -1158
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node-esm/index.mjs +916 -1158
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/types/src/components/DiagnosticOverlay.d.ts.map +1 -1
- package/dist/types/src/compute-layout.d.ts.map +1 -1
- package/dist/types/src/compute.stories.d.ts +22 -1
- package/dist/types/src/compute.stories.d.ts.map +1 -1
- package/dist/types/src/graph/controller.d.ts +40 -35
- package/dist/types/src/graph/controller.d.ts.map +1 -1
- package/dist/types/src/graph/node-defs.d.ts.map +1 -1
- package/dist/types/src/hooks/useComputeGraphController.d.ts.map +1 -1
- package/dist/types/src/hooks/useComputeNodeState.d.ts +4 -5
- package/dist/types/src/hooks/useComputeNodeState.d.ts.map +1 -1
- package/dist/types/src/hooks/useGraphMonitor.d.ts +2 -2
- package/dist/types/src/hooks/useGraphMonitor.d.ts.map +1 -1
- package/dist/types/src/shapes/Append.d.ts +1 -1
- package/dist/types/src/shapes/Append.d.ts.map +1 -1
- package/dist/types/src/shapes/Array.d.ts +1 -1
- package/dist/types/src/shapes/Array.d.ts.map +1 -1
- package/dist/types/src/shapes/Audio.d.ts +1 -1
- package/dist/types/src/shapes/Audio.d.ts.map +1 -1
- package/dist/types/src/shapes/Beacon.d.ts +1 -1
- package/dist/types/src/shapes/Beacon.d.ts.map +1 -1
- package/dist/types/src/shapes/Boolean.d.ts +7 -7
- package/dist/types/src/shapes/Boolean.d.ts.map +1 -1
- package/dist/types/src/shapes/Chat.d.ts +1 -1
- package/dist/types/src/shapes/Chat.d.ts.map +1 -1
- package/dist/types/src/shapes/Constant.d.ts +1 -1
- package/dist/types/src/shapes/Constant.d.ts.map +1 -1
- package/dist/types/src/shapes/Database.d.ts +1 -1
- package/dist/types/src/shapes/Database.d.ts.map +1 -1
- package/dist/types/src/shapes/{Queue.d.ts → Feed.d.ts} +9 -9
- package/dist/types/src/shapes/Feed.d.ts.map +1 -0
- package/dist/types/src/shapes/Function.d.ts +1 -1
- package/dist/types/src/shapes/Function.d.ts.map +1 -1
- package/dist/types/src/shapes/Gpt.d.ts +1 -1
- package/dist/types/src/shapes/Gpt.d.ts.map +1 -1
- package/dist/types/src/shapes/GptRealtime.d.ts +1 -1
- package/dist/types/src/shapes/GptRealtime.d.ts.map +1 -1
- package/dist/types/src/shapes/Json.d.ts +2 -2
- package/dist/types/src/shapes/Json.d.ts.map +1 -1
- package/dist/types/src/shapes/Logic.d.ts +2 -2
- package/dist/types/src/shapes/Logic.d.ts.map +1 -1
- package/dist/types/src/shapes/RNG.d.ts +2 -2
- package/dist/types/src/shapes/RNG.d.ts.map +1 -1
- package/dist/types/src/shapes/Scope.d.ts +1 -1
- package/dist/types/src/shapes/Scope.d.ts.map +1 -1
- package/dist/types/src/shapes/Surface.d.ts +1 -1
- package/dist/types/src/shapes/Surface.d.ts.map +1 -1
- package/dist/types/src/shapes/Switch.d.ts +1 -1
- package/dist/types/src/shapes/Switch.d.ts.map +1 -1
- package/dist/types/src/shapes/Table.d.ts +1 -1
- package/dist/types/src/shapes/Table.d.ts.map +1 -1
- package/dist/types/src/shapes/Template.d.ts +2 -2
- package/dist/types/src/shapes/Template.d.ts.map +1 -1
- package/dist/types/src/shapes/Text.d.ts +1 -1
- package/dist/types/src/shapes/Text.d.ts.map +1 -1
- package/dist/types/src/shapes/TextToImage.d.ts +1 -1
- package/dist/types/src/shapes/TextToImage.d.ts.map +1 -1
- package/dist/types/src/shapes/Thread.d.ts +1 -1
- package/dist/types/src/shapes/Thread.d.ts.map +1 -1
- package/dist/types/src/shapes/Trigger.d.ts +6 -4
- package/dist/types/src/shapes/Trigger.d.ts.map +1 -1
- package/dist/types/src/shapes/common/Box.d.ts +4 -4
- package/dist/types/src/shapes/common/Box.d.ts.map +1 -1
- package/dist/types/src/shapes/common/FunctionBody.d.ts +2 -2
- package/dist/types/src/shapes/common/FunctionBody.d.ts.map +1 -1
- package/dist/types/src/shapes/common/TypeSelect.d.ts +1 -1
- package/dist/types/src/shapes/common/TypeSelect.d.ts.map +1 -1
- package/dist/types/src/shapes/defs.d.ts +1 -1
- package/dist/types/src/shapes/defs.d.ts.map +1 -1
- package/dist/types/src/shapes/index.d.ts +2 -2
- package/dist/types/src/shapes/index.d.ts.map +1 -1
- package/dist/types/src/testing/circuits.d.ts +18 -24
- package/dist/types/src/testing/circuits.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +61 -58
- package/src/README.md +0 -3
- package/src/compute.stories.tsx +89 -114
- package/src/graph/controller.ts +139 -78
- package/src/graph/node-defs.ts +31 -31
- package/src/hooks/useComputeNodeState.ts +7 -8
- package/src/hooks/useGraphMonitor.ts +11 -10
- package/src/json.test.ts +3 -3
- package/src/registry.ts +2 -2
- package/src/schema.test.ts +11 -11
- package/src/shapes/Audio.tsx +1 -2
- package/src/shapes/Beacon.tsx +0 -1
- package/src/shapes/Boolean.tsx +1 -1
- package/src/shapes/Chat.tsx +0 -1
- package/src/shapes/Constant.tsx +0 -1
- package/src/shapes/{Queue.tsx → Feed.tsx} +26 -21
- package/src/shapes/Function.tsx +12 -9
- package/src/shapes/Gpt.tsx +6 -2
- package/src/shapes/Json.tsx +9 -3
- package/src/shapes/RNG.tsx +5 -2
- package/src/shapes/Scope.tsx +0 -1
- package/src/shapes/Surface.tsx +12 -4
- package/src/shapes/Switch.tsx +0 -1
- package/src/shapes/Table.tsx +3 -3
- package/src/shapes/Template.tsx +0 -1
- package/src/shapes/Text.tsx +0 -1
- package/src/shapes/Thread.tsx +12 -10
- package/src/shapes/Trigger.tsx +21 -21
- package/src/shapes/common/Box.tsx +5 -8
- package/src/shapes/common/FunctionBody.tsx +2 -2
- package/src/shapes/common/TypeSelect.tsx +1 -1
- package/src/shapes/defs.ts +3 -3
- package/src/shapes/index.ts +2 -2
- package/src/testing/circuits.ts +7 -16
- package/dist/types/src/shapes/Queue.d.ts.map +0 -1
package/src/graph/controller.ts
CHANGED
|
@@ -2,18 +2,27 @@
|
|
|
2
2
|
// Copyright 2024 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import type * as Context from 'effect/Context';
|
|
6
5
|
import * as Effect from 'effect/Effect';
|
|
7
6
|
import * as Either from 'effect/Either';
|
|
8
7
|
import * as Exit from 'effect/Exit';
|
|
8
|
+
import * as Layer from 'effect/Layer';
|
|
9
|
+
import type * as ManagedRuntime from 'effect/ManagedRuntime';
|
|
9
10
|
import * as Scope from 'effect/Scope';
|
|
10
11
|
|
|
12
|
+
import type { AiService } from '@dxos/ai';
|
|
11
13
|
import { Event, synchronized } from '@dxos/async';
|
|
14
|
+
import { type Credential, type Operation, type OperationRegistry, Trace } from '@dxos/compute';
|
|
12
15
|
import {
|
|
16
|
+
ComputeBeginEvent,
|
|
17
|
+
ComputeCustomEvent,
|
|
18
|
+
ComputeEndEvent,
|
|
19
|
+
ComputeInputEvent,
|
|
20
|
+
ComputeNodeContext,
|
|
21
|
+
ComputeOutputEvent,
|
|
13
22
|
type ComputeEdge,
|
|
14
23
|
type ComputeGraphModel,
|
|
15
|
-
type ComputeMeta,
|
|
16
24
|
type ComputeNode,
|
|
25
|
+
type ComputeNodeMeta,
|
|
17
26
|
type GptInput,
|
|
18
27
|
type GptOutput,
|
|
19
28
|
type GraphDiagnostic,
|
|
@@ -22,15 +31,15 @@ import {
|
|
|
22
31
|
isNotExecuted,
|
|
23
32
|
} from '@dxos/conductor';
|
|
24
33
|
import { Resource } from '@dxos/context';
|
|
25
|
-
import {
|
|
26
|
-
import {
|
|
34
|
+
import type { Database, Feed } from '@dxos/echo';
|
|
35
|
+
import { unwrapExit } from '@dxos/effect';
|
|
36
|
+
import { type QueueService } from '@dxos/functions';
|
|
27
37
|
import { log } from '@dxos/log';
|
|
28
38
|
import { type CanvasGraphModel } from '@dxos/react-ui-canvas-editor';
|
|
29
|
-
import { type ContentBlock } from '@dxos/
|
|
39
|
+
import { type ContentBlock } from '@dxos/types';
|
|
30
40
|
|
|
31
41
|
import { createComputeGraph } from '../hooks';
|
|
32
42
|
import { type ComputeShape } from '../shapes';
|
|
33
|
-
|
|
34
43
|
import { resolveComputeNode } from './node-defs';
|
|
35
44
|
|
|
36
45
|
// TODO(burdon): API package for conductor.
|
|
@@ -72,6 +81,26 @@ type ComputeOutputEvent = {
|
|
|
72
81
|
value: RuntimeValue;
|
|
73
82
|
};
|
|
74
83
|
|
|
84
|
+
/**
|
|
85
|
+
* Event emitted by the compute graph during execution.
|
|
86
|
+
*/
|
|
87
|
+
export type ComputeEvent =
|
|
88
|
+
| { type: 'begin-compute'; nodeId: string; inputs: ReadonlyArray<string> }
|
|
89
|
+
| { type: 'end-compute'; nodeId: string; outputs: ReadonlyArray<string> }
|
|
90
|
+
| { type: 'compute-input'; nodeId: string; property: string; value: any }
|
|
91
|
+
| { type: 'compute-output'; nodeId: string; property: string; value: any }
|
|
92
|
+
| { type: 'custom'; nodeId: string; event: any };
|
|
93
|
+
|
|
94
|
+
// TODO(dmaretskyi): Re-use function servies definition.
|
|
95
|
+
export type ComputeServices =
|
|
96
|
+
| AiService.AiService
|
|
97
|
+
| Database.Service
|
|
98
|
+
| Feed.FeedService
|
|
99
|
+
| QueueService
|
|
100
|
+
| Credential.CredentialsService
|
|
101
|
+
| Operation.Service
|
|
102
|
+
| OperationRegistry.Service;
|
|
103
|
+
|
|
75
104
|
/**
|
|
76
105
|
* Nodes that will automatically trigger the execution of the graph on startup.
|
|
77
106
|
*/
|
|
@@ -79,10 +108,10 @@ const AUTO_TRIGGER_NODES = ['chat', 'switch', 'constant'];
|
|
|
79
108
|
|
|
80
109
|
export const createComputeGraphController = (
|
|
81
110
|
graph: CanvasGraphModel<ComputeShape>,
|
|
82
|
-
|
|
111
|
+
computeRuntime: ManagedRuntime.ManagedRuntime<ComputeServices, never>,
|
|
83
112
|
) => {
|
|
84
113
|
const computeGraph = createComputeGraph(graph);
|
|
85
|
-
const controller = new ComputeGraphController(
|
|
114
|
+
const controller = new ComputeGraphController(computeRuntime, computeGraph);
|
|
86
115
|
return { controller, graph };
|
|
87
116
|
};
|
|
88
117
|
|
|
@@ -114,10 +143,10 @@ export class ComputeGraphController extends Resource {
|
|
|
114
143
|
/** Computed result. */
|
|
115
144
|
public readonly output = new Event<ComputeOutputEvent>();
|
|
116
145
|
|
|
117
|
-
public readonly events = new Event<
|
|
146
|
+
public readonly events = new Event<ComputeEvent>();
|
|
118
147
|
|
|
119
148
|
constructor(
|
|
120
|
-
private readonly
|
|
149
|
+
private readonly _computeRuntime: ManagedRuntime.ManagedRuntime<ComputeServices, never>,
|
|
121
150
|
/** Persistent compute graph. */
|
|
122
151
|
private readonly _graph: ComputeGraphModel,
|
|
123
152
|
) {
|
|
@@ -212,7 +241,7 @@ export class ComputeGraphController extends Resource {
|
|
|
212
241
|
});
|
|
213
242
|
}
|
|
214
243
|
|
|
215
|
-
async getMeta(node: ComputeNode): Promise<
|
|
244
|
+
async getMeta(node: ComputeNode): Promise<ComputeNodeMeta> {
|
|
216
245
|
const { meta } = await resolveComputeNode(node);
|
|
217
246
|
return meta;
|
|
218
247
|
}
|
|
@@ -232,37 +261,42 @@ export class ComputeGraphController extends Resource {
|
|
|
232
261
|
executor.setOutputs(nodeId, Effect.succeed(ValueBag.make(outputs)));
|
|
233
262
|
}
|
|
234
263
|
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
264
|
+
unwrapExit(
|
|
265
|
+
await this._computeRuntime.runPromiseExit(
|
|
266
|
+
Effect.gen(this, function* () {
|
|
267
|
+
const scope = yield* Scope.make();
|
|
268
|
+
|
|
269
|
+
// TODO(dmaretskyi): Code duplication.
|
|
270
|
+
const executable = yield* Effect.promise(() => resolveComputeNode(this._graph.getNode(nodeId)));
|
|
271
|
+
const computingOutputs = executable.exec != null;
|
|
272
|
+
// TODO(dmaretskyi): Check if the node has a compute function and run computeOutputs if it does.
|
|
273
|
+
const effect = (computingOutputs ? executor.computeOutputs(nodeId) : executor.computeInputs(nodeId)).pipe(
|
|
274
|
+
Effect.withSpan('runGraph'),
|
|
275
|
+
Scope.extend(scope),
|
|
276
|
+
Effect.provide(
|
|
277
|
+
Layer.mergeAll(
|
|
278
|
+
Layer.succeed(Trace.TraceService, this._createTraceWriter()),
|
|
279
|
+
ComputeNodeContext.layerNoop,
|
|
280
|
+
),
|
|
281
|
+
),
|
|
282
|
+
Effect.flatMap(computeValueBag),
|
|
283
|
+
Effect.withSpan('test'),
|
|
284
|
+
Effect.tap((values) => {
|
|
285
|
+
for (const [key, value] of Object.entries(values)) {
|
|
286
|
+
if (computingOutputs) {
|
|
287
|
+
this._onOutputComputed(nodeId, key, value);
|
|
288
|
+
} else {
|
|
289
|
+
this._onInputComputed(nodeId, key, value);
|
|
290
|
+
}
|
|
257
291
|
}
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
);
|
|
292
|
+
}),
|
|
293
|
+
);
|
|
261
294
|
|
|
262
|
-
|
|
295
|
+
yield* effect;
|
|
263
296
|
|
|
264
|
-
|
|
265
|
-
|
|
297
|
+
yield* Scope.close(scope, Exit.void);
|
|
298
|
+
}),
|
|
299
|
+
),
|
|
266
300
|
);
|
|
267
301
|
|
|
268
302
|
this.update.emit();
|
|
@@ -290,59 +324,69 @@ export class ComputeGraphController extends Resource {
|
|
|
290
324
|
: this._graph.nodes.filter((node) => node.type != null && AUTO_TRIGGER_NODES.includes(node.type));
|
|
291
325
|
const allAffectedNodes = [...new Set(triggerNodes.flatMap((node) => executor.getAllDependantNodes(node.id)))];
|
|
292
326
|
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
327
|
+
unwrapExit(
|
|
328
|
+
await this._computeRuntime.runPromiseExit(
|
|
329
|
+
Effect.gen(this, function* () {
|
|
330
|
+
const scope = yield* Scope.make();
|
|
331
|
+
|
|
332
|
+
// TODO(burdon): Return map?
|
|
333
|
+
const tasks: Effect.Effect<unknown, any, ComputeServices>[] = [];
|
|
334
|
+
for (const node of allAffectedNodes) {
|
|
335
|
+
// TODO(dmaretskyi): Code duplication.
|
|
336
|
+
const executable = yield* Effect.promise(() => resolveComputeNode(this._graph.getNode(node)));
|
|
337
|
+
const computingOutputs = executable.exec != null;
|
|
338
|
+
|
|
339
|
+
// TODO(dmaretskyi): Check if the node has a compute function and run computeOutputs if it does.
|
|
340
|
+
const effect = (computingOutputs ? executor.computeOutputs(node) : executor.computeInputs(node)).pipe(
|
|
341
|
+
Effect.withSpan('runGraph'),
|
|
342
|
+
Scope.extend(scope),
|
|
343
|
+
Effect.flatMap(computeValueBag),
|
|
344
|
+
Effect.provide(
|
|
345
|
+
Layer.mergeAll(
|
|
346
|
+
Layer.succeed(Trace.TraceService, this._createTraceWriter()),
|
|
347
|
+
ComputeNodeContext.layerNoop,
|
|
348
|
+
),
|
|
349
|
+
),
|
|
350
|
+
|
|
351
|
+
Effect.withSpan('test'),
|
|
352
|
+
Effect.tap((values) => {
|
|
353
|
+
for (const [key, value] of Object.entries(values)) {
|
|
354
|
+
if (computingOutputs) {
|
|
355
|
+
this._onOutputComputed(node, key, value);
|
|
356
|
+
} else {
|
|
357
|
+
this._onInputComputed(node, key, value);
|
|
358
|
+
}
|
|
317
359
|
}
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
);
|
|
360
|
+
}),
|
|
361
|
+
);
|
|
321
362
|
|
|
322
|
-
|
|
323
|
-
|
|
363
|
+
tasks.push(effect);
|
|
364
|
+
}
|
|
324
365
|
|
|
325
|
-
|
|
326
|
-
|
|
366
|
+
//
|
|
367
|
+
yield* Effect.all(tasks);
|
|
327
368
|
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
369
|
+
//
|
|
370
|
+
yield* Scope.close(scope, Exit.void);
|
|
371
|
+
}),
|
|
372
|
+
),
|
|
331
373
|
);
|
|
332
374
|
|
|
333
375
|
this.update.emit();
|
|
334
376
|
}
|
|
335
377
|
|
|
336
|
-
private
|
|
378
|
+
private _createTraceWriter(): Trace.TraceWriter {
|
|
337
379
|
return {
|
|
338
|
-
|
|
339
|
-
|
|
380
|
+
write: (eventType, payload) => {
|
|
381
|
+
const event = traceEventToComputeEvent(eventType.key, payload);
|
|
382
|
+
if (event) {
|
|
383
|
+
this._handleEvent(event);
|
|
384
|
+
}
|
|
340
385
|
},
|
|
341
|
-
nodeId: undefined, // Not in a context of a specific node.
|
|
342
386
|
};
|
|
343
387
|
}
|
|
344
388
|
|
|
345
|
-
private _handleEvent(event:
|
|
389
|
+
private _handleEvent(event: ComputeEvent): void {
|
|
346
390
|
log('handleEvent', { event });
|
|
347
391
|
switch (event.type) {
|
|
348
392
|
case 'compute-input': {
|
|
@@ -372,6 +416,23 @@ export class ComputeGraphController extends Resource {
|
|
|
372
416
|
}
|
|
373
417
|
}
|
|
374
418
|
|
|
419
|
+
const traceEventToComputeEvent = (key: string, payload: unknown): ComputeEvent | undefined => {
|
|
420
|
+
switch (key) {
|
|
421
|
+
case ComputeBeginEvent.key:
|
|
422
|
+
return { type: 'begin-compute', ...(payload as { nodeId: string; inputs: ReadonlyArray<string> }) };
|
|
423
|
+
case ComputeEndEvent.key:
|
|
424
|
+
return { type: 'end-compute', ...(payload as { nodeId: string; outputs: ReadonlyArray<string> }) };
|
|
425
|
+
case ComputeInputEvent.key:
|
|
426
|
+
return { type: 'compute-input', ...(payload as { nodeId: string; property: string; value: any }) };
|
|
427
|
+
case ComputeOutputEvent.key:
|
|
428
|
+
return { type: 'compute-output', ...(payload as { nodeId: string; property: string; value: any }) };
|
|
429
|
+
case ComputeCustomEvent.key:
|
|
430
|
+
return { type: 'custom', ...(payload as { nodeId: string; event: any }) };
|
|
431
|
+
default:
|
|
432
|
+
return undefined;
|
|
433
|
+
}
|
|
434
|
+
};
|
|
435
|
+
|
|
375
436
|
/**
|
|
376
437
|
* Waits for all effects in the bag to complete and returns the `RuntimeValue` for each property.
|
|
377
438
|
*/
|
package/src/graph/node-defs.ts
CHANGED
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
registry,
|
|
13
13
|
} from '@dxos/conductor';
|
|
14
14
|
import { raise } from '@dxos/debug';
|
|
15
|
-
import {
|
|
15
|
+
import { JsonSchema, Obj } from '@dxos/echo';
|
|
16
16
|
import { invariant } from '@dxos/invariant';
|
|
17
17
|
|
|
18
18
|
import { type ComputeShape, type ConstantShape, type TemplateShape } from '../shapes';
|
|
@@ -39,45 +39,45 @@ const nodeFactory: Record<NodeType | 'trigger', (shape: ComputeShape) => Compute
|
|
|
39
39
|
[NODE_OUTPUT]: () => createNode(NODE_OUTPUT),
|
|
40
40
|
|
|
41
41
|
// Extensions.
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
42
|
+
'text-to-image': () => createNode('text-to-image'), // TODO(burdon): Rename ai-impage-tool
|
|
43
|
+
and: () => createNode('and'),
|
|
44
|
+
append: () => createNode('append'),
|
|
45
|
+
audio: () => createNode('audio'),
|
|
46
|
+
beacon: () => createNode('beacon'),
|
|
47
|
+
chat: () => createNode('chat'),
|
|
48
|
+
constant: (shape) =>
|
|
49
49
|
createNode('constant', {
|
|
50
50
|
value: (shape as ConstantShape).value,
|
|
51
51
|
}),
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
52
|
+
'make-queue': () => createNode('make-queue'),
|
|
53
|
+
database: () => createNode('database'),
|
|
54
|
+
gpt: () => createNode('gpt'),
|
|
55
|
+
'gpt-realtime': () => createNode('gpt-realtime'),
|
|
56
|
+
if: () => createNode('if'),
|
|
57
|
+
'if-else': () => createNode('if-else'),
|
|
58
|
+
function: () => createNode('function'),
|
|
59
|
+
json: () => createNode('json'),
|
|
60
|
+
'json-transform': () => createNode('json-transform'),
|
|
61
|
+
not: () => createNode('not'),
|
|
62
|
+
or: () => createNode('or'),
|
|
63
|
+
queue: () => createNode('queue'),
|
|
64
|
+
rng: () => createNode('rng'),
|
|
65
|
+
reducer: () => createNode('reducer'),
|
|
66
|
+
scope: () => createNode('scope'),
|
|
67
|
+
surface: () => createNode('surface'),
|
|
68
|
+
switch: () => createNode('switch'),
|
|
69
|
+
template: (shape) => {
|
|
70
70
|
const node = createNode('template', { valueType: (shape as TemplateShape).valueType, value: shape.text });
|
|
71
|
-
node.inputSchema = toJsonSchema(getTemplateInputSchema(node));
|
|
71
|
+
node.inputSchema = JsonSchema.toJsonSchema(getTemplateInputSchema(node));
|
|
72
72
|
return node;
|
|
73
73
|
},
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
74
|
+
text: () => createNode('text'),
|
|
75
|
+
thread: () => createNode('thread'),
|
|
76
|
+
trigger: () => createNode(NODE_INPUT),
|
|
77
77
|
};
|
|
78
78
|
|
|
79
79
|
const createNode = (type: string, props?: Partial<ComputeNode>): ComputeNode => ({
|
|
80
|
-
id:
|
|
80
|
+
id: Obj.ID.random(),
|
|
81
81
|
type,
|
|
82
82
|
...props,
|
|
83
83
|
});
|
|
@@ -5,24 +5,22 @@
|
|
|
5
5
|
import * as Schema from 'effect/Schema';
|
|
6
6
|
import { useCallback, useEffect, useState } from 'react';
|
|
7
7
|
|
|
8
|
-
import type {
|
|
9
|
-
import type { ComputeEventPayload } from '@dxos/functions';
|
|
8
|
+
import type { ComputeNode, ComputeNodeMeta } from '@dxos/conductor';
|
|
10
9
|
import { invariant } from '@dxos/invariant';
|
|
11
10
|
|
|
12
|
-
import { type RuntimeValue } from '../graph';
|
|
11
|
+
import { type ComputeEvent, type RuntimeValue } from '../graph';
|
|
13
12
|
import { type ComputeShape } from '../shapes';
|
|
14
|
-
|
|
15
13
|
import { useComputeContext } from './compute-context';
|
|
16
14
|
|
|
17
15
|
export type ComputeNodeState = {
|
|
18
16
|
node: ComputeNode;
|
|
19
|
-
meta:
|
|
17
|
+
meta: ComputeNodeMeta;
|
|
20
18
|
runtime: {
|
|
21
19
|
inputs: Record<string, RuntimeValue>;
|
|
22
20
|
outputs: Record<string, RuntimeValue>;
|
|
23
21
|
setOutput: (property: string, value: any) => void;
|
|
24
22
|
evalNode: () => void;
|
|
25
|
-
subscribeToEventLog: (cb: (event:
|
|
23
|
+
subscribeToEventLog: (cb: (event: ComputeEvent) => void) => () => void;
|
|
26
24
|
};
|
|
27
25
|
};
|
|
28
26
|
|
|
@@ -33,7 +31,7 @@ export const useComputeNodeState = (shape: ComputeShape): ComputeNodeState => {
|
|
|
33
31
|
const { controller } = useComputeContext();
|
|
34
32
|
invariant(controller);
|
|
35
33
|
|
|
36
|
-
const [meta, setMeta] = useState<
|
|
34
|
+
const [meta, setMeta] = useState<ComputeNodeMeta>();
|
|
37
35
|
useEffect(() => {
|
|
38
36
|
let disposed = false;
|
|
39
37
|
queueMicrotask(async () => {
|
|
@@ -43,6 +41,7 @@ export const useComputeNodeState = (shape: ComputeShape): ComputeNodeState => {
|
|
|
43
41
|
if (disposed) {
|
|
44
42
|
return;
|
|
45
43
|
}
|
|
44
|
+
|
|
46
45
|
setMeta(meta);
|
|
47
46
|
});
|
|
48
47
|
|
|
@@ -56,7 +55,7 @@ export const useComputeNodeState = (shape: ComputeShape): ComputeNodeState => {
|
|
|
56
55
|
}, [shape.node]);
|
|
57
56
|
|
|
58
57
|
const subscribeToEventLog = useCallback(
|
|
59
|
-
(cb: (event:
|
|
58
|
+
(cb: (event: ComputeEvent) => void): (() => void) => {
|
|
60
59
|
return controller.events.on((ev) => {
|
|
61
60
|
if (ev.nodeId === shape.node) {
|
|
62
61
|
cb(ev);
|
|
@@ -5,10 +5,9 @@
|
|
|
5
5
|
import { useMemo } from 'react';
|
|
6
6
|
|
|
7
7
|
import { type ComputeEdge, ComputeGraphModel, type ComputeNode, DEFAULT_INPUT, DEFAULT_OUTPUT } from '@dxos/conductor';
|
|
8
|
-
import {
|
|
8
|
+
import { Obj, Ref } from '@dxos/echo';
|
|
9
9
|
import { invariant } from '@dxos/invariant';
|
|
10
|
-
import {
|
|
11
|
-
import { type CanvasGraphModel, type Connection, type GraphMonitor } from '@dxos/react-ui-canvas-editor';
|
|
10
|
+
import { type CanvasBoard, type CanvasGraphModel, type GraphMonitor } from '@dxos/react-ui-canvas-editor';
|
|
12
11
|
import { isNonNullable } from '@dxos/util';
|
|
13
12
|
|
|
14
13
|
import { createComputeNode, isValidComputeNode } from '../graph';
|
|
@@ -19,7 +18,7 @@ import { type ComputeShape, type TriggerShape } from '../shapes';
|
|
|
19
18
|
*/
|
|
20
19
|
export const mapEdge = (
|
|
21
20
|
graph: CanvasGraphModel,
|
|
22
|
-
{ source, target, output = DEFAULT_OUTPUT, input = DEFAULT_INPUT }: Connection,
|
|
21
|
+
{ source, target, output = DEFAULT_OUTPUT, input = DEFAULT_INPUT }: CanvasBoard.Connection,
|
|
23
22
|
): ComputeEdge => {
|
|
24
23
|
const sourceNode = graph.findNode(source) as ComputeShape;
|
|
25
24
|
const targetNode = graph.findNode(target) as ComputeShape;
|
|
@@ -27,7 +26,7 @@ export const mapEdge = (
|
|
|
27
26
|
invariant(targetNode?.node);
|
|
28
27
|
|
|
29
28
|
return {
|
|
30
|
-
id:
|
|
29
|
+
id: Obj.ID.random(),
|
|
31
30
|
source: sourceNode.node,
|
|
32
31
|
target: targetNode.node,
|
|
33
32
|
output,
|
|
@@ -113,19 +112,21 @@ export const createComputeGraph = (graph?: CanvasGraphModel<ComputeShape>) => {
|
|
|
113
112
|
const linkTriggerToCompute = (graph: ComputeGraphModel, computeNode: ComputeNode, triggerData: TriggerShape) => {
|
|
114
113
|
const functionTrigger = triggerData.functionTrigger?.target;
|
|
115
114
|
invariant(functionTrigger);
|
|
116
|
-
functionTrigger
|
|
117
|
-
|
|
115
|
+
Obj.update(functionTrigger, (functionTrigger) => {
|
|
116
|
+
functionTrigger.function = Ref.make(graph.root);
|
|
117
|
+
functionTrigger.inputNodeId = computeNode.id;
|
|
118
|
+
});
|
|
118
119
|
};
|
|
119
120
|
|
|
120
121
|
const deleteTriggerObjects = (computeGraph: ComputeGraphModel, deleted: CanvasGraphModel) => {
|
|
121
|
-
const
|
|
122
|
-
if (!
|
|
122
|
+
const db = Obj.getDatabase(computeGraph.root);
|
|
123
|
+
if (!db) {
|
|
123
124
|
return;
|
|
124
125
|
}
|
|
125
126
|
for (const node of deleted.nodes) {
|
|
126
127
|
if (node.type === 'trigger') {
|
|
127
128
|
const trigger = node as TriggerShape;
|
|
128
|
-
|
|
129
|
+
db.remove(trigger.functionTrigger!.target!);
|
|
129
130
|
}
|
|
130
131
|
}
|
|
131
132
|
};
|
package/src/json.test.ts
CHANGED
|
@@ -5,12 +5,12 @@
|
|
|
5
5
|
import * as Schema from 'effect/Schema';
|
|
6
6
|
import { describe, test } from 'vitest';
|
|
7
7
|
|
|
8
|
-
import {
|
|
8
|
+
import { Graph } from '@dxos/graph';
|
|
9
9
|
|
|
10
10
|
import { createGptCircuit } from './testing';
|
|
11
11
|
|
|
12
12
|
export const Shape = Schema.extend(
|
|
13
|
-
|
|
13
|
+
Graph.Node,
|
|
14
14
|
Schema.Struct({
|
|
15
15
|
text: Schema.optional(Schema.String),
|
|
16
16
|
guide: Schema.optional(Schema.Boolean),
|
|
@@ -19,7 +19,7 @@ export const Shape = Schema.extend(
|
|
|
19
19
|
);
|
|
20
20
|
|
|
21
21
|
export const Connection = Schema.extend(
|
|
22
|
-
|
|
22
|
+
Graph.Edge,
|
|
23
23
|
Schema.Struct({
|
|
24
24
|
input: Schema.optional(Schema.String),
|
|
25
25
|
output: Schema.optional(Schema.String),
|
package/src/registry.ts
CHANGED
|
@@ -22,7 +22,7 @@ import {
|
|
|
22
22
|
jsonTransformShape,
|
|
23
23
|
notShape,
|
|
24
24
|
orShape,
|
|
25
|
-
|
|
25
|
+
feedShape,
|
|
26
26
|
randomShape,
|
|
27
27
|
reducerShape,
|
|
28
28
|
scopeShape,
|
|
@@ -82,7 +82,7 @@ export const computeShapes: { title: string; shapes: ShapeDef[] }[] = [
|
|
|
82
82
|
shapes: [
|
|
83
83
|
//
|
|
84
84
|
jsonShape,
|
|
85
|
-
|
|
85
|
+
feedShape,
|
|
86
86
|
threadShape,
|
|
87
87
|
textShape,
|
|
88
88
|
surfaceShape,
|
package/src/schema.test.ts
CHANGED
|
@@ -5,11 +5,11 @@
|
|
|
5
5
|
import * as Schema from 'effect/Schema';
|
|
6
6
|
import { describe, test } from 'vitest';
|
|
7
7
|
|
|
8
|
-
import {
|
|
9
|
-
import { BaseGraphNode, Graph } from '@dxos/graph';
|
|
8
|
+
import { Graph } from '@dxos/graph';
|
|
10
9
|
import {
|
|
10
|
+
CanvasBoard,
|
|
11
|
+
CanvasGraphModel,
|
|
11
12
|
Polygon,
|
|
12
|
-
Shape,
|
|
13
13
|
createEllipse,
|
|
14
14
|
createPath,
|
|
15
15
|
createRectangle,
|
|
@@ -21,25 +21,25 @@ import { ComputeShape, createFunction, createSwitch } from './shapes';
|
|
|
21
21
|
|
|
22
22
|
describe('compute', () => {
|
|
23
23
|
test('model', ({ expect }) => {
|
|
24
|
-
|
|
24
|
+
const model = CanvasGraphModel.create<ComputeShape>();
|
|
25
25
|
const node = createSwitch({ id: 'x', center: { x: 0, y: 0 }, size: { width: 80, height: 80 } });
|
|
26
26
|
console.log(JSON.stringify(node, null, 2));
|
|
27
27
|
expect(Schema.is(ComputeShape)(node)).toBe(true);
|
|
28
28
|
expect(Schema.is(Polygon)(node)).toBe(true);
|
|
29
|
-
expect(Schema.is(Shape)(node)).toBe(true);
|
|
30
|
-
expect(Schema.is(
|
|
29
|
+
expect(Schema.is(CanvasBoard.Shape)(node)).toBe(true);
|
|
30
|
+
expect(Schema.is(Graph.Node)(node)).toBe(true);
|
|
31
31
|
|
|
32
|
-
const graph =
|
|
33
|
-
graph.nodes.push(node);
|
|
32
|
+
const graph: Graph.Any = { nodes: [], edges: [] };
|
|
33
|
+
graph.nodes.push(node);
|
|
34
34
|
|
|
35
|
-
|
|
36
|
-
|
|
35
|
+
model.createNode(node);
|
|
36
|
+
console.log(JSON.stringify(model, null, 2));
|
|
37
37
|
});
|
|
38
38
|
});
|
|
39
39
|
|
|
40
40
|
describe('schema', () => {
|
|
41
41
|
test('basic types', ({ expect }) => {
|
|
42
|
-
const shapes: Shape[] = [];
|
|
42
|
+
const shapes: CanvasBoard.Shape[] = [];
|
|
43
43
|
shapes.push(createRectangle({ id: 'shape-1', center: { x: 0, y: 0 }, size: { width: 80, height: 80 } }));
|
|
44
44
|
shapes.push(createEllipse({ id: 'shape-2', center: { x: 0, y: 0 }, size: { width: 80, height: 80 } }));
|
|
45
45
|
shapes.push(createFunction({ id: 'shape-3', center: { x: 0, y: 0 } }));
|
package/src/shapes/Audio.tsx
CHANGED
|
@@ -9,7 +9,6 @@ import { Icon } from '@dxos/react-ui';
|
|
|
9
9
|
import { type ShapeComponentProps, type ShapeDef, createAnchorMap } from '@dxos/react-ui-canvas-editor';
|
|
10
10
|
|
|
11
11
|
import { useComputeNodeState } from '../hooks';
|
|
12
|
-
|
|
13
12
|
import { ComputeShape, type CreateShapeProps, createAnchorId, createShape } from './defs';
|
|
14
13
|
|
|
15
14
|
export const AudioShape = Schema.extend(
|
|
@@ -38,7 +37,7 @@ export const AudioComponent = ({ shape }: ShapeComponentProps<AudioShape>) => {
|
|
|
38
37
|
<div className='flex w-full justify-center items-center'>
|
|
39
38
|
<Icon
|
|
40
39
|
icon={active ? 'ph--microphone--regular' : 'ph--microphone-slash--regular'}
|
|
41
|
-
classNames={['transition opacity-20 duration-1000', active && 'opacity-100 text-
|
|
40
|
+
classNames={['transition opacity-20 duration-1000', active && 'opacity-100 text-error-text']}
|
|
42
41
|
size={8}
|
|
43
42
|
onClick={() => setActive(!active)}
|
|
44
43
|
/>
|
package/src/shapes/Beacon.tsx
CHANGED
|
@@ -10,7 +10,6 @@ import { Icon } from '@dxos/react-ui';
|
|
|
10
10
|
import { type ShapeComponentProps, type ShapeDef, createAnchorMap } from '@dxos/react-ui-canvas-editor';
|
|
11
11
|
|
|
12
12
|
import { useComputeNodeState } from '../hooks';
|
|
13
|
-
|
|
14
13
|
import { ComputeShape, type CreateShapeProps, createAnchorId, createShape } from './defs';
|
|
15
14
|
|
|
16
15
|
export const BeaconShape = Schema.extend(
|
package/src/shapes/Boolean.tsx
CHANGED
|
@@ -95,7 +95,7 @@ const createSymbol =
|
|
|
95
95
|
const paths = pathConstructor({ startX, endX, height });
|
|
96
96
|
|
|
97
97
|
return (
|
|
98
|
-
<svg viewBox={`0 0 ${width} ${height}`} className='
|
|
98
|
+
<svg viewBox={`0 0 ${width} ${height}`} className='h-full w-full'>
|
|
99
99
|
{/* Input line. */}
|
|
100
100
|
{getAnchorPoints({ x: 0, y: centerY }, inputs).map(({ x, y }, i) => (
|
|
101
101
|
<line key={i} x1={x} y1={y} x2={startX * 1.3} y2={y} strokeWidth={strokeWidth} className={className} />
|
package/src/shapes/Chat.tsx
CHANGED
|
@@ -16,7 +16,6 @@ import {
|
|
|
16
16
|
import { createAnchorMap } from '@dxos/react-ui-canvas-editor';
|
|
17
17
|
|
|
18
18
|
import { useComputeNodeState } from '../hooks';
|
|
19
|
-
|
|
20
19
|
import { Box } from './common';
|
|
21
20
|
import { ComputeShape, type CreateShapeProps, createAnchorId, createShape } from './defs';
|
|
22
21
|
|
package/src/shapes/Constant.tsx
CHANGED
|
@@ -18,7 +18,6 @@ import { createAnchorMap } from '@dxos/react-ui-canvas-editor';
|
|
|
18
18
|
import { safeParseJson } from '@dxos/util';
|
|
19
19
|
|
|
20
20
|
import { useComputeNodeState } from '../hooks';
|
|
21
|
-
|
|
22
21
|
import { Box, TypeSelect } from './common';
|
|
23
22
|
import { ComputeShape, type CreateShapeProps, createAnchorId, createShape } from './defs';
|
|
24
23
|
|