@dxos/react-ui-canvas-compute 0.8.4-main.c4373fc → 0.8.4-main.c85a9c8dae
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/dist/lib/browser/index.mjs +778 -962
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node-esm/index.mjs +778 -962
- package/dist/lib/node-esm/index.mjs.map +3 -3
- package/dist/lib/node-esm/meta.json +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 +18 -31
- package/dist/types/src/graph/controller.d.ts.map +1 -1
- package/dist/types/src/hooks/useComputeNodeState.d.ts +2 -2
- 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/Function.d.ts.map +1 -1
- package/dist/types/src/shapes/Gpt.d.ts.map +1 -1
- package/dist/types/src/shapes/Queue.d.ts.map +1 -1
- package/dist/types/src/shapes/RNG.d.ts.map +1 -1
- package/dist/types/src/shapes/Surface.d.ts.map +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/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 +59 -54
- package/src/README.md +0 -3
- package/src/compute.stories.tsx +72 -113
- package/src/graph/controller.ts +109 -71
- package/src/graph/node-defs.ts +31 -31
- package/src/hooks/useComputeNodeState.ts +4 -3
- package/src/hooks/useGraphMonitor.ts +11 -10
- package/src/json.test.ts +3 -3
- package/src/schema.test.ts +11 -11
- package/src/shapes/Function.tsx +10 -8
- package/src/shapes/Gpt.tsx +6 -1
- package/src/shapes/Queue.tsx +15 -9
- package/src/shapes/RNG.tsx +5 -1
- package/src/shapes/Surface.tsx +9 -3
- package/src/shapes/Table.tsx +3 -3
- package/src/shapes/Thread.tsx +17 -11
- package/src/shapes/Trigger.tsx +33 -44
- package/src/shapes/common/Box.tsx +5 -6
- 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/testing/circuits.ts +5 -14
package/src/graph/controller.ts
CHANGED
|
@@ -6,14 +6,17 @@ import type * as Context from 'effect/Context';
|
|
|
6
6
|
import * as Effect from 'effect/Effect';
|
|
7
7
|
import * as Either from 'effect/Either';
|
|
8
8
|
import * as Exit from 'effect/Exit';
|
|
9
|
+
import * as Layer from 'effect/Layer';
|
|
10
|
+
import type * as ManagedRuntime from 'effect/ManagedRuntime';
|
|
9
11
|
import * as Scope from 'effect/Scope';
|
|
10
12
|
|
|
13
|
+
import type { AiService } from '@dxos/ai';
|
|
11
14
|
import { Event, synchronized } from '@dxos/async';
|
|
12
15
|
import {
|
|
13
16
|
type ComputeEdge,
|
|
14
17
|
type ComputeGraphModel,
|
|
15
|
-
type ComputeMeta,
|
|
16
18
|
type ComputeNode,
|
|
19
|
+
type ComputeNodeMeta,
|
|
17
20
|
type GptInput,
|
|
18
21
|
type GptOutput,
|
|
19
22
|
type GraphDiagnostic,
|
|
@@ -22,11 +25,19 @@ import {
|
|
|
22
25
|
isNotExecuted,
|
|
23
26
|
} from '@dxos/conductor';
|
|
24
27
|
import { Resource } from '@dxos/context';
|
|
25
|
-
import {
|
|
26
|
-
import {
|
|
28
|
+
import type { Database, Feed } from '@dxos/echo';
|
|
29
|
+
import { unwrapExit } from '@dxos/effect';
|
|
30
|
+
import {
|
|
31
|
+
ComputeEventLogger,
|
|
32
|
+
type ComputeEventPayload,
|
|
33
|
+
type CredentialsService,
|
|
34
|
+
type FunctionInvocationService,
|
|
35
|
+
type QueueService,
|
|
36
|
+
TracingService,
|
|
37
|
+
} from '@dxos/functions';
|
|
27
38
|
import { log } from '@dxos/log';
|
|
28
39
|
import { type CanvasGraphModel } from '@dxos/react-ui-canvas-editor';
|
|
29
|
-
import { type ContentBlock } from '@dxos/
|
|
40
|
+
import { type ContentBlock } from '@dxos/types';
|
|
30
41
|
|
|
31
42
|
import { createComputeGraph } from '../hooks';
|
|
32
43
|
import { type ComputeShape } from '../shapes';
|
|
@@ -72,6 +83,15 @@ type ComputeOutputEvent = {
|
|
|
72
83
|
value: RuntimeValue;
|
|
73
84
|
};
|
|
74
85
|
|
|
86
|
+
// TODO(dmaretskyi): Re-use function servies definition.
|
|
87
|
+
export type ComputeServices =
|
|
88
|
+
| AiService.AiService
|
|
89
|
+
| Database.Service
|
|
90
|
+
| Feed.Service
|
|
91
|
+
| QueueService
|
|
92
|
+
| CredentialsService
|
|
93
|
+
| FunctionInvocationService;
|
|
94
|
+
|
|
75
95
|
/**
|
|
76
96
|
* Nodes that will automatically trigger the execution of the graph on startup.
|
|
77
97
|
*/
|
|
@@ -79,10 +99,10 @@ const AUTO_TRIGGER_NODES = ['chat', 'switch', 'constant'];
|
|
|
79
99
|
|
|
80
100
|
export const createComputeGraphController = (
|
|
81
101
|
graph: CanvasGraphModel<ComputeShape>,
|
|
82
|
-
|
|
102
|
+
computeRuntime: ManagedRuntime.ManagedRuntime<ComputeServices, never>,
|
|
83
103
|
) => {
|
|
84
104
|
const computeGraph = createComputeGraph(graph);
|
|
85
|
-
const controller = new ComputeGraphController(
|
|
105
|
+
const controller = new ComputeGraphController(computeRuntime, computeGraph);
|
|
86
106
|
return { controller, graph };
|
|
87
107
|
};
|
|
88
108
|
|
|
@@ -117,7 +137,7 @@ export class ComputeGraphController extends Resource {
|
|
|
117
137
|
public readonly events = new Event<ComputeEventPayload>();
|
|
118
138
|
|
|
119
139
|
constructor(
|
|
120
|
-
private readonly
|
|
140
|
+
private readonly _computeRuntime: ManagedRuntime.ManagedRuntime<ComputeServices, never>,
|
|
121
141
|
/** Persistent compute graph. */
|
|
122
142
|
private readonly _graph: ComputeGraphModel,
|
|
123
143
|
) {
|
|
@@ -158,7 +178,14 @@ export class ComputeGraphController extends Resource {
|
|
|
158
178
|
/**
|
|
159
179
|
* Inputs and outputs for all nodes.
|
|
160
180
|
*/
|
|
161
|
-
get state()
|
|
181
|
+
get state(): Record<
|
|
182
|
+
string,
|
|
183
|
+
{
|
|
184
|
+
node: ComputeNode;
|
|
185
|
+
input: Record<string, RuntimeValue>;
|
|
186
|
+
output: Record<string, RuntimeValue>;
|
|
187
|
+
}
|
|
188
|
+
> {
|
|
162
189
|
const ids = [...new Set([...Object.keys(this._runtimeStateInputs), ...Object.keys(this._runtimeStateOutputs)])];
|
|
163
190
|
return Object.fromEntries(
|
|
164
191
|
ids.map((id) => [
|
|
@@ -205,7 +232,7 @@ export class ComputeGraphController extends Resource {
|
|
|
205
232
|
});
|
|
206
233
|
}
|
|
207
234
|
|
|
208
|
-
async getMeta(node: ComputeNode): Promise<
|
|
235
|
+
async getMeta(node: ComputeNode): Promise<ComputeNodeMeta> {
|
|
209
236
|
const { meta } = await resolveComputeNode(node);
|
|
210
237
|
return meta;
|
|
211
238
|
}
|
|
@@ -225,37 +252,41 @@ export class ComputeGraphController extends Resource {
|
|
|
225
252
|
executor.setOutputs(nodeId, Effect.succeed(ValueBag.make(outputs)));
|
|
226
253
|
}
|
|
227
254
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
255
|
+
unwrapExit(
|
|
256
|
+
await this._computeRuntime.runPromiseExit(
|
|
257
|
+
Effect.gen(this, function* () {
|
|
258
|
+
const scope = yield* Scope.make();
|
|
259
|
+
|
|
260
|
+
// TODO(dmaretskyi): Code duplication.
|
|
261
|
+
const executable = yield* Effect.promise(() => resolveComputeNode(this._graph.getNode(nodeId)));
|
|
262
|
+
const computingOutputs = executable.exec != null;
|
|
263
|
+
// TODO(dmaretskyi): Check if the node has a compute function and run computeOutputs if it does.
|
|
264
|
+
const effect = (computingOutputs ? executor.computeOutputs(nodeId) : executor.computeInputs(nodeId)).pipe(
|
|
265
|
+
Effect.withSpan('runGraph'),
|
|
266
|
+
Scope.extend(scope),
|
|
267
|
+
Effect.provide(
|
|
268
|
+
ComputeEventLogger.layerFromTracing.pipe(
|
|
269
|
+
Layer.provideMerge(TracingService.layerNoop), // TODO(dmaretskyi): Plug-in tracing events to visual feedback in the compute graph editor.
|
|
270
|
+
),
|
|
271
|
+
),
|
|
272
|
+
Effect.flatMap(computeValueBag),
|
|
273
|
+
Effect.withSpan('test'),
|
|
274
|
+
Effect.tap((values) => {
|
|
275
|
+
for (const [key, value] of Object.entries(values)) {
|
|
276
|
+
if (computingOutputs) {
|
|
277
|
+
this._onOutputComputed(nodeId, key, value);
|
|
278
|
+
} else {
|
|
279
|
+
this._onInputComputed(nodeId, key, value);
|
|
280
|
+
}
|
|
250
281
|
}
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
);
|
|
282
|
+
}),
|
|
283
|
+
);
|
|
254
284
|
|
|
255
|
-
|
|
285
|
+
yield* effect;
|
|
256
286
|
|
|
257
|
-
|
|
258
|
-
|
|
287
|
+
yield* Scope.close(scope, Exit.void);
|
|
288
|
+
}),
|
|
289
|
+
),
|
|
259
290
|
);
|
|
260
291
|
|
|
261
292
|
this.update.emit();
|
|
@@ -283,44 +314,51 @@ export class ComputeGraphController extends Resource {
|
|
|
283
314
|
: this._graph.nodes.filter((node) => node.type != null && AUTO_TRIGGER_NODES.includes(node.type));
|
|
284
315
|
const allAffectedNodes = [...new Set(triggerNodes.flatMap((node) => executor.getAllDependantNodes(node.id)))];
|
|
285
316
|
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
317
|
+
unwrapExit(
|
|
318
|
+
await this._computeRuntime.runPromiseExit(
|
|
319
|
+
Effect.gen(this, function* () {
|
|
320
|
+
const scope = yield* Scope.make();
|
|
321
|
+
|
|
322
|
+
// TODO(burdon): Return map?
|
|
323
|
+
const tasks: Effect.Effect<unknown, any, ComputeServices>[] = [];
|
|
324
|
+
for (const node of allAffectedNodes) {
|
|
325
|
+
// TODO(dmaretskyi): Code duplication.
|
|
326
|
+
const executable = yield* Effect.promise(() => resolveComputeNode(this._graph.getNode(node)));
|
|
327
|
+
const computingOutputs = executable.exec != null;
|
|
328
|
+
|
|
329
|
+
// TODO(dmaretskyi): Check if the node has a compute function and run computeOutputs if it does.
|
|
330
|
+
const effect = (computingOutputs ? executor.computeOutputs(node) : executor.computeInputs(node)).pipe(
|
|
331
|
+
Effect.withSpan('runGraph'),
|
|
332
|
+
Scope.extend(scope),
|
|
333
|
+
Effect.flatMap(computeValueBag),
|
|
334
|
+
Effect.provide(
|
|
335
|
+
ComputeEventLogger.layerFromTracing.pipe(
|
|
336
|
+
Layer.provideMerge(TracingService.layerNoop), // TODO(dmaretskyi): Plug-in tracing events to visual feedback in the compute graph editor.
|
|
337
|
+
),
|
|
338
|
+
),
|
|
339
|
+
|
|
340
|
+
Effect.withSpan('test'),
|
|
341
|
+
Effect.tap((values) => {
|
|
342
|
+
for (const [key, value] of Object.entries(values)) {
|
|
343
|
+
if (computingOutputs) {
|
|
344
|
+
this._onOutputComputed(node, key, value);
|
|
345
|
+
} else {
|
|
346
|
+
this._onInputComputed(node, key, value);
|
|
347
|
+
}
|
|
310
348
|
}
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
);
|
|
349
|
+
}),
|
|
350
|
+
);
|
|
314
351
|
|
|
315
|
-
|
|
316
|
-
|
|
352
|
+
tasks.push(effect);
|
|
353
|
+
}
|
|
317
354
|
|
|
318
|
-
|
|
319
|
-
|
|
355
|
+
//
|
|
356
|
+
yield* Effect.all(tasks);
|
|
320
357
|
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
358
|
+
//
|
|
359
|
+
yield* Scope.close(scope, Exit.void);
|
|
360
|
+
}),
|
|
361
|
+
),
|
|
324
362
|
);
|
|
325
363
|
|
|
326
364
|
this.update.emit();
|
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,7 +5,7 @@
|
|
|
5
5
|
import * as Schema from 'effect/Schema';
|
|
6
6
|
import { useCallback, useEffect, useState } from 'react';
|
|
7
7
|
|
|
8
|
-
import type {
|
|
8
|
+
import type { ComputeNode, ComputeNodeMeta } from '@dxos/conductor';
|
|
9
9
|
import type { ComputeEventPayload } from '@dxos/functions';
|
|
10
10
|
import { invariant } from '@dxos/invariant';
|
|
11
11
|
|
|
@@ -16,7 +16,7 @@ import { useComputeContext } from './compute-context';
|
|
|
16
16
|
|
|
17
17
|
export type ComputeNodeState = {
|
|
18
18
|
node: ComputeNode;
|
|
19
|
-
meta:
|
|
19
|
+
meta: ComputeNodeMeta;
|
|
20
20
|
runtime: {
|
|
21
21
|
inputs: Record<string, RuntimeValue>;
|
|
22
22
|
outputs: Record<string, RuntimeValue>;
|
|
@@ -33,7 +33,7 @@ export const useComputeNodeState = (shape: ComputeShape): ComputeNodeState => {
|
|
|
33
33
|
const { controller } = useComputeContext();
|
|
34
34
|
invariant(controller);
|
|
35
35
|
|
|
36
|
-
const [meta, setMeta] = useState<
|
|
36
|
+
const [meta, setMeta] = useState<ComputeNodeMeta>();
|
|
37
37
|
useEffect(() => {
|
|
38
38
|
let disposed = false;
|
|
39
39
|
queueMicrotask(async () => {
|
|
@@ -43,6 +43,7 @@ export const useComputeNodeState = (shape: ComputeShape): ComputeNodeState => {
|
|
|
43
43
|
if (disposed) {
|
|
44
44
|
return;
|
|
45
45
|
}
|
|
46
|
+
|
|
46
47
|
setMeta(meta);
|
|
47
48
|
});
|
|
48
49
|
|
|
@@ -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.change(functionTrigger, (t) => {
|
|
116
|
+
t.function = Ref.make(graph.root);
|
|
117
|
+
t.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/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/Function.tsx
CHANGED
|
@@ -7,7 +7,7 @@ import React, { useCallback, useRef } from 'react';
|
|
|
7
7
|
|
|
8
8
|
import { AnyOutput, FunctionInput } from '@dxos/conductor';
|
|
9
9
|
import { Ref, getSnapshot, isInstanceOf } from '@dxos/echo/internal';
|
|
10
|
-
import {
|
|
10
|
+
import { Function, Script } from '@dxos/functions';
|
|
11
11
|
import { useClient } from '@dxos/react-client';
|
|
12
12
|
import { Filter, parseId } from '@dxos/react-client/echo';
|
|
13
13
|
import {
|
|
@@ -35,7 +35,11 @@ export type FunctionShape = Schema.Schema.Type<typeof FunctionShape>;
|
|
|
35
35
|
export type CreateFunctionProps = CreateShapeProps<FunctionShape>;
|
|
36
36
|
|
|
37
37
|
export const createFunction = (props: CreateFunctionProps) =>
|
|
38
|
-
createShape<FunctionShape>({
|
|
38
|
+
createShape<FunctionShape>({
|
|
39
|
+
type: 'function',
|
|
40
|
+
size: { width: 256, height: 192 },
|
|
41
|
+
...props,
|
|
42
|
+
});
|
|
39
43
|
|
|
40
44
|
//
|
|
41
45
|
// Component
|
|
@@ -58,21 +62,19 @@ const TextInputComponent = ({ shape, title, ...props }: TextInputComponentProps)
|
|
|
58
62
|
|
|
59
63
|
const space = client.spaces.get(spaceId);
|
|
60
64
|
const object = space?.db.getObjectById(objectId);
|
|
61
|
-
if (!space || !isInstanceOf(
|
|
65
|
+
if (!space || !isInstanceOf(Script.Script, object)) {
|
|
62
66
|
return;
|
|
63
67
|
}
|
|
64
68
|
|
|
65
|
-
const {
|
|
66
|
-
objects: [fn],
|
|
67
|
-
} = await space.db.query(Filter.type(FunctionType, { source: Ref.make(object) })).run();
|
|
69
|
+
const [fn] = await space.db.query(Filter.type(Function.Function, { source: Ref.make(object) })).run();
|
|
68
70
|
if (!fn) {
|
|
69
71
|
return;
|
|
70
72
|
}
|
|
71
73
|
|
|
72
74
|
node.value = value;
|
|
73
75
|
node.function = Ref.make(fn);
|
|
74
|
-
node.inputSchema = getSnapshot(fn.inputSchema);
|
|
75
|
-
node.outputSchema = getSnapshot(fn.outputSchema);
|
|
76
|
+
node.inputSchema = fn.inputSchema ? getSnapshot(fn.inputSchema) : undefined;
|
|
77
|
+
node.outputSchema = fn.outputSchema ? getSnapshot(fn.outputSchema) : undefined;
|
|
76
78
|
},
|
|
77
79
|
[client, node],
|
|
78
80
|
);
|
package/src/shapes/Gpt.tsx
CHANGED
|
@@ -6,6 +6,7 @@ import * as Schema from 'effect/Schema';
|
|
|
6
6
|
import React, { useEffect, useState } from 'react';
|
|
7
7
|
|
|
8
8
|
import { GptInput, GptOutput } from '@dxos/conductor';
|
|
9
|
+
import { ScrollArea } from '@dxos/react-ui';
|
|
9
10
|
import { type ShapeComponentProps, type ShapeDef } from '@dxos/react-ui-canvas-editor';
|
|
10
11
|
|
|
11
12
|
import { useComputeNodeState } from '../hooks';
|
|
@@ -74,7 +75,11 @@ export const GptComponent = ({ shape }: ShapeComponentProps<GptShape>) => {
|
|
|
74
75
|
return (
|
|
75
76
|
<FunctionBody
|
|
76
77
|
shape={shape}
|
|
77
|
-
content={
|
|
78
|
+
content={
|
|
79
|
+
<ScrollArea.Root orientation='vertical' thin>
|
|
80
|
+
<ScrollArea.Viewport>{text}</ScrollArea.Viewport>
|
|
81
|
+
</ScrollArea.Root>
|
|
82
|
+
}
|
|
78
83
|
status={`${tokens} tokens`}
|
|
79
84
|
inputSchema={meta.input}
|
|
80
85
|
outputSchema={meta.output}
|
package/src/shapes/Queue.tsx
CHANGED
|
@@ -6,9 +6,9 @@ import * as Schema from 'effect/Schema';
|
|
|
6
6
|
import React, { Fragment } from 'react';
|
|
7
7
|
|
|
8
8
|
import { DEFAULT_OUTPUT, QueueInput, QueueOutput } from '@dxos/conductor';
|
|
9
|
-
import { type ThemedClassName } from '@dxos/react-ui';
|
|
9
|
+
import { ScrollArea, type ThemedClassName } from '@dxos/react-ui';
|
|
10
10
|
import { type ShapeComponentProps, type ShapeDef } from '@dxos/react-ui-canvas-editor';
|
|
11
|
-
import { mx } from '@dxos/
|
|
11
|
+
import { mx } from '@dxos/ui-theme';
|
|
12
12
|
|
|
13
13
|
import { useComputeNodeState } from '../hooks';
|
|
14
14
|
|
|
@@ -28,7 +28,11 @@ export type QueueShape = Schema.Schema.Type<typeof QueueShape>;
|
|
|
28
28
|
export type CreateQueueProps = CreateShapeProps<QueueShape>;
|
|
29
29
|
|
|
30
30
|
export const createQueue = (props: CreateQueueProps) =>
|
|
31
|
-
createShape<QueueShape>({
|
|
31
|
+
createShape<QueueShape>({
|
|
32
|
+
type: 'queue',
|
|
33
|
+
size: { width: 256, height: 512 },
|
|
34
|
+
...props,
|
|
35
|
+
});
|
|
32
36
|
|
|
33
37
|
export const QueueComponent = ({ shape }: ShapeComponentProps<QueueShape>) => {
|
|
34
38
|
const { runtime } = useComputeNodeState(shape);
|
|
@@ -42,11 +46,13 @@ export const QueueComponent = ({ shape }: ShapeComponentProps<QueueShape>) => {
|
|
|
42
46
|
|
|
43
47
|
return (
|
|
44
48
|
<Box shape={shape} status={`${items.length} items`} onAction={handleAction}>
|
|
45
|
-
<
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
49
|
+
<ScrollArea.Root orientation='vertical'>
|
|
50
|
+
<ScrollArea.Viewport classNames='divide-y divide-separator'>
|
|
51
|
+
{[...items].map((item, i) => (
|
|
52
|
+
<QueueItem key={i} classNames='p-1 px-2' item={item} />
|
|
53
|
+
))}
|
|
54
|
+
</ScrollArea.Viewport>
|
|
55
|
+
</ScrollArea.Root>
|
|
50
56
|
</Box>
|
|
51
57
|
);
|
|
52
58
|
};
|
|
@@ -57,7 +63,7 @@ export const QueueItem = ({ classNames, item }: ThemedClassName<{ item: any }>)
|
|
|
57
63
|
}
|
|
58
64
|
|
|
59
65
|
return (
|
|
60
|
-
<div className={mx('grid grid-cols-[
|
|
66
|
+
<div className={mx('grid grid-cols-[80px_1fr]', classNames)}>
|
|
61
67
|
{Object.entries(item).map(([key, value]) => (
|
|
62
68
|
<Fragment key={key}>
|
|
63
69
|
<div className='p-1 text-xs text-subdued'>{key}</div>
|
package/src/shapes/RNG.tsx
CHANGED
|
@@ -27,7 +27,11 @@ export type RandomShape = Schema.Schema.Type<typeof RandomShape>;
|
|
|
27
27
|
export type CreateRandomProps = CreateShapeProps<RandomShape>;
|
|
28
28
|
|
|
29
29
|
export const createRandom = (props: CreateRandomProps) =>
|
|
30
|
-
createShape<RandomShape>({
|
|
30
|
+
createShape<RandomShape>({
|
|
31
|
+
type: 'rng',
|
|
32
|
+
size: { width: 64, height: 64 },
|
|
33
|
+
...props,
|
|
34
|
+
});
|
|
31
35
|
|
|
32
36
|
const icons = [
|
|
33
37
|
'ph--dice-one--regular',
|