@dxos/react-ui-canvas-compute 0.8.4-main.f9ba587 → 0.8.4-main.fcfe5033a5
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 +1026 -1177
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node-esm/index.mjs +1026 -1177
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/types/src/compute.stories.d.ts +33 -5
- package/dist/types/src/compute.stories.d.ts.map +1 -1
- package/dist/types/src/graph/controller.d.ts +41 -27
- 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 +2 -2
- package/dist/types/src/hooks/useComputeGraphController.d.ts.map +1 -1
- package/dist/types/src/hooks/useComputeNodeState.d.ts +4 -3
- 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/json.test.d.ts +1 -1
- package/dist/types/src/json.test.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 +1 -1
- 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 +1 -1
- package/dist/types/src/shapes/Json.d.ts.map +1 -1
- package/dist/types/src/shapes/Logic.d.ts +1 -1
- package/dist/types/src/shapes/Logic.d.ts.map +1 -1
- package/dist/types/src/shapes/RNG.d.ts +1 -1
- 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 +1 -1
- 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 +7 -34
- 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 +3 -3
- package/dist/types/src/shapes/common/FunctionBody.d.ts.map +1 -1
- package/dist/types/src/shapes/defs.d.ts +2 -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 +62 -53
- package/src/README.md +0 -3
- package/src/compute-layout.ts +1 -1
- package/src/compute.stories.tsx +102 -140
- package/src/graph/controller.ts +114 -80
- package/src/graph/node-defs.ts +34 -34
- package/src/hooks/useComputeGraphController.ts +2 -2
- package/src/hooks/useComputeNodeState.ts +9 -7
- package/src/hooks/useGraphMonitor.ts +11 -10
- package/src/json.test.ts +4 -4
- package/src/registry.ts +4 -4
- package/src/schema.test.ts +13 -13
- package/src/shapes/Append.tsx +3 -3
- package/src/shapes/Array.tsx +3 -3
- package/src/shapes/Audio.tsx +4 -4
- package/src/shapes/Beacon.tsx +4 -5
- package/src/shapes/Boolean.tsx +4 -4
- package/src/shapes/Chat.tsx +3 -3
- package/src/shapes/Constant.tsx +3 -3
- package/src/shapes/Database.tsx +2 -2
- package/src/shapes/{Queue.tsx → Feed.tsx} +29 -23
- package/src/shapes/Function.tsx +17 -14
- package/src/shapes/Gpt.tsx +12 -6
- package/src/shapes/GptRealtime.tsx +2 -2
- package/src/shapes/Json.tsx +10 -5
- package/src/shapes/Logic.tsx +3 -3
- package/src/shapes/RNG.tsx +9 -6
- package/src/shapes/Scope.tsx +4 -4
- package/src/shapes/Surface.tsx +15 -6
- package/src/shapes/Switch.tsx +3 -3
- package/src/shapes/Table.tsx +6 -6
- package/src/shapes/Template.tsx +5 -5
- package/src/shapes/Text.tsx +4 -4
- package/src/shapes/TextToImage.tsx +2 -2
- package/src/shapes/Thread.tsx +20 -14
- package/src/shapes/Trigger.tsx +46 -58
- package/src/shapes/common/Box.tsx +7 -10
- package/src/shapes/common/FunctionBody.tsx +5 -4
- package/src/shapes/common/TypeSelect.tsx +1 -1
- package/src/shapes/defs.ts +5 -4
- package/src/shapes/index.ts +2 -2
- package/src/testing/circuits.ts +10 -19
- package/dist/types/src/shapes/Queue.d.ts.map +0 -1
package/src/graph/controller.ts
CHANGED
|
@@ -2,32 +2,46 @@
|
|
|
2
2
|
// Copyright 2024 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import
|
|
6
|
-
|
|
7
|
-
import
|
|
5
|
+
import type * as Context from 'effect/Context';
|
|
6
|
+
import * as Effect from 'effect/Effect';
|
|
7
|
+
import * as Either from 'effect/Either';
|
|
8
|
+
import * as Exit from 'effect/Exit';
|
|
9
|
+
import * as Layer from 'effect/Layer';
|
|
10
|
+
import type * as ManagedRuntime from 'effect/ManagedRuntime';
|
|
11
|
+
import * as Scope from 'effect/Scope';
|
|
12
|
+
|
|
13
|
+
import type { AiService } from '@dxos/ai';
|
|
8
14
|
import { Event, synchronized } from '@dxos/async';
|
|
9
15
|
import {
|
|
10
16
|
type ComputeEdge,
|
|
11
|
-
type ComputeEvent,
|
|
12
17
|
type ComputeGraphModel,
|
|
13
|
-
type ComputeMeta,
|
|
14
18
|
type ComputeNode,
|
|
15
|
-
type
|
|
19
|
+
type ComputeNodeMeta,
|
|
16
20
|
type GptInput,
|
|
17
21
|
type GptOutput,
|
|
18
22
|
type GraphDiagnostic,
|
|
19
23
|
GraphExecutor,
|
|
20
|
-
isNotExecuted,
|
|
21
24
|
ValueBag,
|
|
25
|
+
isNotExecuted,
|
|
22
26
|
} from '@dxos/conductor';
|
|
23
27
|
import { Resource } from '@dxos/context';
|
|
24
|
-
import type {
|
|
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 QueueService,
|
|
35
|
+
Trace,
|
|
36
|
+
} from '@dxos/functions';
|
|
25
37
|
import { log } from '@dxos/log';
|
|
38
|
+
import type { Operation, OperationRegistry } from '@dxos/operation';
|
|
26
39
|
import { type CanvasGraphModel } from '@dxos/react-ui-canvas-editor';
|
|
40
|
+
import { type ContentBlock } from '@dxos/types';
|
|
27
41
|
|
|
28
|
-
import { resolveComputeNode } from './node-defs';
|
|
29
42
|
import { createComputeGraph } from '../hooks';
|
|
30
43
|
import { type ComputeShape } from '../shapes';
|
|
44
|
+
import { resolveComputeNode } from './node-defs';
|
|
31
45
|
|
|
32
46
|
// TODO(burdon): API package for conductor.
|
|
33
47
|
export const InvalidStateError = Error;
|
|
@@ -43,7 +57,7 @@ export interface GptExecutor {
|
|
|
43
57
|
invoke: FunctionCallback<GptInput, GptOutput>;
|
|
44
58
|
|
|
45
59
|
// TODO(dmaretskyi): A hack to get image artifacts working. Rework into querying images from the ai-service store.
|
|
46
|
-
imageCache: Map<string,
|
|
60
|
+
imageCache: Map<string, ContentBlock.Image>;
|
|
47
61
|
}
|
|
48
62
|
|
|
49
63
|
export type RuntimeValue =
|
|
@@ -68,6 +82,16 @@ type ComputeOutputEvent = {
|
|
|
68
82
|
value: RuntimeValue;
|
|
69
83
|
};
|
|
70
84
|
|
|
85
|
+
// TODO(dmaretskyi): Re-use function servies definition.
|
|
86
|
+
export type ComputeServices =
|
|
87
|
+
| AiService.AiService
|
|
88
|
+
| Database.Service
|
|
89
|
+
| Feed.FeedService
|
|
90
|
+
| QueueService
|
|
91
|
+
| CredentialsService
|
|
92
|
+
| Operation.Service
|
|
93
|
+
| OperationRegistry.Service;
|
|
94
|
+
|
|
71
95
|
/**
|
|
72
96
|
* Nodes that will automatically trigger the execution of the graph on startup.
|
|
73
97
|
*/
|
|
@@ -75,10 +99,10 @@ const AUTO_TRIGGER_NODES = ['chat', 'switch', 'constant'];
|
|
|
75
99
|
|
|
76
100
|
export const createComputeGraphController = (
|
|
77
101
|
graph: CanvasGraphModel<ComputeShape>,
|
|
78
|
-
|
|
102
|
+
computeRuntime: ManagedRuntime.ManagedRuntime<ComputeServices, never>,
|
|
79
103
|
) => {
|
|
80
104
|
const computeGraph = createComputeGraph(graph);
|
|
81
|
-
const controller = new ComputeGraphController(
|
|
105
|
+
const controller = new ComputeGraphController(computeRuntime, computeGraph);
|
|
82
106
|
return { controller, graph };
|
|
83
107
|
};
|
|
84
108
|
|
|
@@ -110,10 +134,10 @@ export class ComputeGraphController extends Resource {
|
|
|
110
134
|
/** Computed result. */
|
|
111
135
|
public readonly output = new Event<ComputeOutputEvent>();
|
|
112
136
|
|
|
113
|
-
public readonly events = new Event<
|
|
137
|
+
public readonly events = new Event<ComputeEventPayload>();
|
|
114
138
|
|
|
115
139
|
constructor(
|
|
116
|
-
private readonly
|
|
140
|
+
private readonly _computeRuntime: ManagedRuntime.ManagedRuntime<ComputeServices, never>,
|
|
117
141
|
/** Persistent compute graph. */
|
|
118
142
|
private readonly _graph: ComputeGraphModel,
|
|
119
143
|
) {
|
|
@@ -154,7 +178,14 @@ export class ComputeGraphController extends Resource {
|
|
|
154
178
|
/**
|
|
155
179
|
* Inputs and outputs for all nodes.
|
|
156
180
|
*/
|
|
157
|
-
get state()
|
|
181
|
+
get state(): Record<
|
|
182
|
+
string,
|
|
183
|
+
{
|
|
184
|
+
node: ComputeNode;
|
|
185
|
+
input: Record<string, RuntimeValue>;
|
|
186
|
+
output: Record<string, RuntimeValue>;
|
|
187
|
+
}
|
|
188
|
+
> {
|
|
158
189
|
const ids = [...new Set([...Object.keys(this._runtimeStateInputs), ...Object.keys(this._runtimeStateOutputs)])];
|
|
159
190
|
return Object.fromEntries(
|
|
160
191
|
ids.map((id) => [
|
|
@@ -201,7 +232,7 @@ export class ComputeGraphController extends Resource {
|
|
|
201
232
|
});
|
|
202
233
|
}
|
|
203
234
|
|
|
204
|
-
async getMeta(node: ComputeNode): Promise<
|
|
235
|
+
async getMeta(node: ComputeNode): Promise<ComputeNodeMeta> {
|
|
205
236
|
const { meta } = await resolveComputeNode(node);
|
|
206
237
|
return meta;
|
|
207
238
|
}
|
|
@@ -221,37 +252,37 @@ export class ComputeGraphController extends Resource {
|
|
|
221
252
|
executor.setOutputs(nodeId, Effect.succeed(ValueBag.make(outputs)));
|
|
222
253
|
}
|
|
223
254
|
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
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(Layer.mergeAll(ComputeEventLogger.layerNoop, Trace.writerLayerNoop)),
|
|
268
|
+
Effect.flatMap(computeValueBag),
|
|
269
|
+
Effect.withSpan('test'),
|
|
270
|
+
Effect.tap((values) => {
|
|
271
|
+
for (const [key, value] of Object.entries(values)) {
|
|
272
|
+
if (computingOutputs) {
|
|
273
|
+
this._onOutputComputed(nodeId, key, value);
|
|
274
|
+
} else {
|
|
275
|
+
this._onInputComputed(nodeId, key, value);
|
|
276
|
+
}
|
|
246
277
|
}
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
);
|
|
278
|
+
}),
|
|
279
|
+
);
|
|
250
280
|
|
|
251
|
-
|
|
281
|
+
yield* effect;
|
|
252
282
|
|
|
253
|
-
|
|
254
|
-
|
|
283
|
+
yield* Scope.close(scope, Exit.void);
|
|
284
|
+
}),
|
|
285
|
+
),
|
|
255
286
|
);
|
|
256
287
|
|
|
257
288
|
this.update.emit();
|
|
@@ -279,50 +310,53 @@ export class ComputeGraphController extends Resource {
|
|
|
279
310
|
: this._graph.nodes.filter((node) => node.type != null && AUTO_TRIGGER_NODES.includes(node.type));
|
|
280
311
|
const allAffectedNodes = [...new Set(triggerNodes.flatMap((node) => executor.getAllDependantNodes(node.id)))];
|
|
281
312
|
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
313
|
+
unwrapExit(
|
|
314
|
+
await this._computeRuntime.runPromiseExit(
|
|
315
|
+
Effect.gen(this, function* () {
|
|
316
|
+
const scope = yield* Scope.make();
|
|
317
|
+
|
|
318
|
+
// TODO(burdon): Return map?
|
|
319
|
+
const tasks: Effect.Effect<unknown, any, ComputeServices>[] = [];
|
|
320
|
+
for (const node of allAffectedNodes) {
|
|
321
|
+
// TODO(dmaretskyi): Code duplication.
|
|
322
|
+
const executable = yield* Effect.promise(() => resolveComputeNode(this._graph.getNode(node)));
|
|
323
|
+
const computingOutputs = executable.exec != null;
|
|
324
|
+
|
|
325
|
+
// TODO(dmaretskyi): Check if the node has a compute function and run computeOutputs if it does.
|
|
326
|
+
const effect = (computingOutputs ? executor.computeOutputs(node) : executor.computeInputs(node)).pipe(
|
|
327
|
+
Effect.withSpan('runGraph'),
|
|
328
|
+
Scope.extend(scope),
|
|
329
|
+
Effect.flatMap(computeValueBag),
|
|
330
|
+
Effect.provide(Layer.mergeAll(ComputeEventLogger.layerNoop, Trace.writerLayerNoop)),
|
|
331
|
+
|
|
332
|
+
Effect.withSpan('test'),
|
|
333
|
+
Effect.tap((values) => {
|
|
334
|
+
for (const [key, value] of Object.entries(values)) {
|
|
335
|
+
if (computingOutputs) {
|
|
336
|
+
this._onOutputComputed(node, key, value);
|
|
337
|
+
} else {
|
|
338
|
+
this._onInputComputed(node, key, value);
|
|
339
|
+
}
|
|
306
340
|
}
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
);
|
|
341
|
+
}),
|
|
342
|
+
);
|
|
310
343
|
|
|
311
|
-
|
|
312
|
-
|
|
344
|
+
tasks.push(effect);
|
|
345
|
+
}
|
|
313
346
|
|
|
314
|
-
|
|
315
|
-
|
|
347
|
+
//
|
|
348
|
+
yield* Effect.all(tasks);
|
|
316
349
|
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
350
|
+
//
|
|
351
|
+
yield* Scope.close(scope, Exit.void);
|
|
352
|
+
}),
|
|
353
|
+
),
|
|
320
354
|
);
|
|
321
355
|
|
|
322
356
|
this.update.emit();
|
|
323
357
|
}
|
|
324
358
|
|
|
325
|
-
private _createLogger(): Context.Tag.Service<
|
|
359
|
+
private _createLogger(): Context.Tag.Service<ComputeEventLogger> {
|
|
326
360
|
return {
|
|
327
361
|
log: (event) => {
|
|
328
362
|
this._handleEvent(event);
|
|
@@ -331,7 +365,7 @@ export class ComputeGraphController extends Resource {
|
|
|
331
365
|
};
|
|
332
366
|
}
|
|
333
367
|
|
|
334
|
-
private _handleEvent(event:
|
|
368
|
+
private _handleEvent(event: ComputeEventPayload): void {
|
|
335
369
|
log('handleEvent', { event });
|
|
336
370
|
switch (event.type) {
|
|
337
371
|
case 'compute-input': {
|
package/src/graph/node-defs.ts
CHANGED
|
@@ -3,16 +3,16 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
import {
|
|
6
|
-
NODE_INPUT,
|
|
7
|
-
NODE_OUTPUT,
|
|
8
6
|
type ComputeNode,
|
|
9
7
|
type Executable,
|
|
8
|
+
NODE_INPUT,
|
|
9
|
+
NODE_OUTPUT,
|
|
10
10
|
type NodeType,
|
|
11
|
-
registry,
|
|
12
11
|
getTemplateInputSchema,
|
|
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 { type RefObject, useEffect, useState } from 'react';
|
|
6
6
|
|
|
7
7
|
import { type CleanupFn } from '@dxos/async';
|
|
8
|
-
import { type
|
|
8
|
+
import { type EditorController, type EditorRootProps } from '@dxos/react-ui-canvas-editor';
|
|
9
9
|
|
|
10
10
|
import { type ComputeGraphController } from '../graph';
|
|
11
11
|
import { type ComputeShape } from '../shapes';
|
|
@@ -21,7 +21,7 @@ const combine = (...cbs: CleanupFn[]) => {
|
|
|
21
21
|
|
|
22
22
|
export type UseComputeGraphControllerOptions = Pick<EditorRootProps<ComputeShape>, 'graph'> & {
|
|
23
23
|
controller: ComputeGraphController | null;
|
|
24
|
-
editorRef: RefObject<EditorController>;
|
|
24
|
+
editorRef: RefObject<EditorController | null>;
|
|
25
25
|
};
|
|
26
26
|
|
|
27
27
|
export const useComputeGraphController = ({ controller, graph, editorRef }: UseComputeGraphControllerOptions) => {
|
|
@@ -2,25 +2,26 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import
|
|
5
|
+
import * as Schema from 'effect/Schema';
|
|
6
6
|
import { useCallback, useEffect, useState } from 'react';
|
|
7
7
|
|
|
8
|
-
import type { ComputeNode,
|
|
8
|
+
import type { ComputeNode, ComputeNodeMeta } from '@dxos/conductor';
|
|
9
|
+
import type { ComputeEventPayload } from '@dxos/functions';
|
|
9
10
|
import { invariant } from '@dxos/invariant';
|
|
10
11
|
|
|
11
|
-
import { useComputeContext } from './compute-context';
|
|
12
12
|
import { type RuntimeValue } from '../graph';
|
|
13
13
|
import { type ComputeShape } from '../shapes';
|
|
14
|
+
import { useComputeContext } from './compute-context';
|
|
14
15
|
|
|
15
16
|
export type ComputeNodeState = {
|
|
16
17
|
node: ComputeNode;
|
|
17
|
-
meta:
|
|
18
|
+
meta: ComputeNodeMeta;
|
|
18
19
|
runtime: {
|
|
19
20
|
inputs: Record<string, RuntimeValue>;
|
|
20
21
|
outputs: Record<string, RuntimeValue>;
|
|
21
22
|
setOutput: (property: string, value: any) => void;
|
|
22
23
|
evalNode: () => void;
|
|
23
|
-
subscribeToEventLog: (cb: (event:
|
|
24
|
+
subscribeToEventLog: (cb: (event: ComputeEventPayload) => void) => void;
|
|
24
25
|
};
|
|
25
26
|
};
|
|
26
27
|
|
|
@@ -31,7 +32,7 @@ export const useComputeNodeState = (shape: ComputeShape): ComputeNodeState => {
|
|
|
31
32
|
const { controller } = useComputeContext();
|
|
32
33
|
invariant(controller);
|
|
33
34
|
|
|
34
|
-
const [meta, setMeta] = useState<
|
|
35
|
+
const [meta, setMeta] = useState<ComputeNodeMeta>();
|
|
35
36
|
useEffect(() => {
|
|
36
37
|
let disposed = false;
|
|
37
38
|
queueMicrotask(async () => {
|
|
@@ -41,6 +42,7 @@ export const useComputeNodeState = (shape: ComputeShape): ComputeNodeState => {
|
|
|
41
42
|
if (disposed) {
|
|
42
43
|
return;
|
|
43
44
|
}
|
|
45
|
+
|
|
44
46
|
setMeta(meta);
|
|
45
47
|
});
|
|
46
48
|
|
|
@@ -54,7 +56,7 @@ export const useComputeNodeState = (shape: ComputeShape): ComputeNodeState => {
|
|
|
54
56
|
}, [shape.node]);
|
|
55
57
|
|
|
56
58
|
const subscribeToEventLog = useCallback(
|
|
57
|
-
(cb: (event:
|
|
59
|
+
(cb: (event: ComputeEventPayload) => void) => {
|
|
58
60
|
return controller.events.on((ev) => {
|
|
59
61
|
if (ev.nodeId === shape.node) {
|
|
60
62
|
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 GraphMonitor, type CanvasGraphModel, type Connection } 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, (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
|
@@ -2,15 +2,15 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import
|
|
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,17 +22,17 @@ import {
|
|
|
22
22
|
jsonTransformShape,
|
|
23
23
|
notShape,
|
|
24
24
|
orShape,
|
|
25
|
-
|
|
25
|
+
feedShape,
|
|
26
26
|
randomShape,
|
|
27
27
|
reducerShape,
|
|
28
28
|
scopeShape,
|
|
29
29
|
surfaceShape,
|
|
30
30
|
switchShape,
|
|
31
31
|
templateShape,
|
|
32
|
-
|
|
32
|
+
textShape,
|
|
33
33
|
textToImageShape,
|
|
34
|
+
threadShape,
|
|
34
35
|
triggerShape,
|
|
35
|
-
textShape,
|
|
36
36
|
} from './shapes';
|
|
37
37
|
|
|
38
38
|
/**
|
|
@@ -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
|
@@ -2,44 +2,44 @@
|
|
|
2
2
|
// Copyright 2024 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import
|
|
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
13
|
createEllipse,
|
|
13
14
|
createPath,
|
|
14
15
|
createRectangle,
|
|
15
16
|
isPath,
|
|
16
17
|
isPolygon,
|
|
17
|
-
Shape,
|
|
18
18
|
} from '@dxos/react-ui-canvas-editor';
|
|
19
19
|
|
|
20
|
-
import {
|
|
20
|
+
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/Append.tsx
CHANGED
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
// Copyright 2024 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import
|
|
5
|
+
import * as Schema from 'effect/Schema';
|
|
6
6
|
import React from 'react';
|
|
7
7
|
|
|
8
8
|
import { AppendInput } from '@dxos/conductor';
|
|
9
9
|
import { type ShapeComponentProps, type ShapeDef } from '@dxos/react-ui-canvas-editor';
|
|
10
10
|
|
|
11
|
-
import {
|
|
12
|
-
import { ComputeShape,
|
|
11
|
+
import { FunctionBody, createFunctionAnchors, getHeight } from './common';
|
|
12
|
+
import { ComputeShape, type CreateShapeProps, createShape } from './defs';
|
|
13
13
|
|
|
14
14
|
export const AppendShape = Schema.extend(
|
|
15
15
|
ComputeShape,
|