@ghchinoy/litflow 0.2.8 → 0.3.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/CHANGELOG.md +5 -0
- package/dist/breadboard/data/common.d.ts +35 -0
- package/dist/breadboard/engine/loader/capability.d.ts +21 -0
- package/dist/breadboard/engine/loader/loader.d.ts +29 -0
- package/dist/breadboard/engine/loader/resolve-graph-urls.d.ts +16 -0
- package/dist/breadboard/engine/runtime/bubble.d.ts +23 -0
- package/dist/breadboard/engine/runtime/graph-based-node-handler.d.ts +16 -0
- package/dist/breadboard/engine/runtime/handler.d.ts +27 -0
- package/dist/breadboard/engine/runtime/harness/events.d.ts +145 -0
- package/dist/breadboard/engine/runtime/harness/local.d.ts +10 -0
- package/dist/breadboard/engine/runtime/harness/plan-runner.d.ts +25 -0
- package/dist/breadboard/engine/runtime/run/invoke-graph.d.ts +12 -0
- package/dist/breadboard/engine/runtime/run/node-invoker.d.ts +12 -0
- package/dist/breadboard/engine/runtime/run/run-graph.d.ts +12 -0
- package/dist/breadboard/engine/runtime/run.d.ts +29 -0
- package/dist/breadboard/engine/runtime/sandbox/capabilities-manager.d.ts +15 -0
- package/dist/breadboard/engine/runtime/sandbox/file-system-handler-factory.d.ts +15 -0
- package/dist/breadboard/engine/runtime/sandbox/invoke-describer.d.ts +10 -0
- package/dist/breadboard/engine/runtime/static/create-plan.d.ts +14 -0
- package/dist/breadboard/engine/runtime/static/orchestrator.d.ts +72 -0
- package/dist/breadboard/engine/runtime/traversal/index.d.ts +20 -0
- package/dist/breadboard/engine/runtime/traversal/iterator.d.ts +12 -0
- package/dist/breadboard/engine/runtime/traversal/machine.d.ts +14 -0
- package/dist/breadboard/engine/runtime/traversal/representation.d.ts +27 -0
- package/dist/breadboard/engine/runtime/traversal/result.d.ts +24 -0
- package/dist/breadboard/engine/runtime/traversal/state.d.ts +34 -0
- package/dist/breadboard/lit-flow-runner.d.ts +13 -0
- package/dist/breadboard/lit-flow-runner.test.d.ts +1 -0
- package/dist/breadboard/runner.d.ts +13 -0
- package/dist/index.d.ts +2 -0
- package/dist/lit-chiclet.d.ts +9 -0
- package/dist/lit-schema-node.d.ts +13 -0
- package/dist/lit-schema-node.test.d.ts +1 -0
- package/dist/litflow.js +708 -442
- package/dist/litflow.js.map +1 -1
- package/package.json +15 -3
- package/src/breadboard/data/common.ts +450 -0
- package/src/breadboard/data/file-system.ts +54 -0
- package/src/breadboard/data/inline-all-content.ts +126 -0
- package/src/breadboard/data/recent-boards.ts +118 -0
- package/src/breadboard/data/save-outputs-as-file.ts +104 -0
- package/src/breadboard/engine/add-run-module.ts +168 -0
- package/src/breadboard/engine/editor/blank.ts +65 -0
- package/src/breadboard/engine/editor/edge.ts +27 -0
- package/src/breadboard/engine/editor/events.ts +64 -0
- package/src/breadboard/engine/editor/graph.ts +383 -0
- package/src/breadboard/engine/editor/history.ts +98 -0
- package/src/breadboard/engine/editor/index.ts +8 -0
- package/src/breadboard/engine/editor/operations/add-asset.ts +45 -0
- package/src/breadboard/engine/editor/operations/add-edge.ts +142 -0
- package/src/breadboard/engine/editor/operations/add-graph.ts +47 -0
- package/src/breadboard/engine/editor/operations/add-module.ts +64 -0
- package/src/breadboard/engine/editor/operations/add-node.ts +86 -0
- package/src/breadboard/engine/editor/operations/change-asset-metadata.ts +70 -0
- package/src/breadboard/engine/editor/operations/change-configuration.ts +82 -0
- package/src/breadboard/engine/editor/operations/change-edge-metadata.ts +58 -0
- package/src/breadboard/engine/editor/operations/change-edge.ts +111 -0
- package/src/breadboard/engine/editor/operations/change-graph-metadata.ts +52 -0
- package/src/breadboard/engine/editor/operations/change-metadata.ts +92 -0
- package/src/breadboard/engine/editor/operations/change-module.ts +64 -0
- package/src/breadboard/engine/editor/operations/error.ts +21 -0
- package/src/breadboard/engine/editor/operations/remove-asset.ts +48 -0
- package/src/breadboard/engine/editor/operations/remove-edge.ts +89 -0
- package/src/breadboard/engine/editor/operations/remove-graph.ts +49 -0
- package/src/breadboard/engine/editor/operations/remove-integration.ts +54 -0
- package/src/breadboard/engine/editor/operations/remove-module.ts +69 -0
- package/src/breadboard/engine/editor/operations/remove-node.ts +86 -0
- package/src/breadboard/engine/editor/operations/replace-graph.ts +52 -0
- package/src/breadboard/engine/editor/operations/toggle-export.ts +72 -0
- package/src/breadboard/engine/editor/operations/upsert-integration.ts +43 -0
- package/src/breadboard/engine/editor/selection.ts +58 -0
- package/src/breadboard/engine/editor/transforms/configure-sidewire.ts +73 -0
- package/src/breadboard/engine/editor/transforms/isolate-selection.ts +54 -0
- package/src/breadboard/engine/editor/transforms/merge-graph.ts +58 -0
- package/src/breadboard/engine/editor/transforms/move-to-graph.ts +102 -0
- package/src/breadboard/engine/editor/transforms/move-to-new-graph.ts +72 -0
- package/src/breadboard/engine/editor/transforms/sidewire-to-new-graph.ts +82 -0
- package/src/breadboard/engine/file-system/blob-transform.ts +44 -0
- package/src/breadboard/engine/file-system/composed-peristent-backend.ts +140 -0
- package/src/breadboard/engine/file-system/ephemeral-blob-store.ts +46 -0
- package/src/breadboard/engine/file-system/in-memory-blob-store.ts +87 -0
- package/src/breadboard/engine/file-system/index.ts +723 -0
- package/src/breadboard/engine/file-system/partial-persistent-backend.ts +109 -0
- package/src/breadboard/engine/file-system/path.ts +125 -0
- package/src/breadboard/engine/file-system/persistent-file.ts +66 -0
- package/src/breadboard/engine/file-system/readable-stream-file.ts +61 -0
- package/src/breadboard/engine/file-system/stub-file-system.ts +47 -0
- package/src/breadboard/engine/file-system/utils.ts +40 -0
- package/src/breadboard/engine/inspector/graph/bubbled-node.ts +162 -0
- package/src/breadboard/engine/inspector/graph/describe-cache.ts +78 -0
- package/src/breadboard/engine/inspector/graph/describe-type-cache.ts +48 -0
- package/src/breadboard/engine/inspector/graph/edge-cache.ts +118 -0
- package/src/breadboard/engine/inspector/graph/edge.ts +133 -0
- package/src/breadboard/engine/inspector/graph/event.ts +35 -0
- package/src/breadboard/engine/inspector/graph/exports-describer.ts +45 -0
- package/src/breadboard/engine/inspector/graph/graph-cache.ts +54 -0
- package/src/breadboard/engine/inspector/graph/graph-describer-manager.ts +338 -0
- package/src/breadboard/engine/inspector/graph/graph-descriptor-handle.ts +73 -0
- package/src/breadboard/engine/inspector/graph/graph-node-type.ts +111 -0
- package/src/breadboard/engine/inspector/graph/graph-queries.ts +256 -0
- package/src/breadboard/engine/inspector/graph/graph.ts +163 -0
- package/src/breadboard/engine/inspector/graph/inspectable-asset.ts +36 -0
- package/src/breadboard/engine/inspector/graph/kits.ts +208 -0
- package/src/breadboard/engine/inspector/graph/module.ts +69 -0
- package/src/breadboard/engine/inspector/graph/mutable-graph.ts +150 -0
- package/src/breadboard/engine/inspector/graph/node-cache.ts +123 -0
- package/src/breadboard/engine/inspector/graph/node-describer-manager.ts +279 -0
- package/src/breadboard/engine/inspector/graph/node-type-describer-manager.ts +122 -0
- package/src/breadboard/engine/inspector/graph/node.ts +149 -0
- package/src/breadboard/engine/inspector/graph/port-cache.ts +80 -0
- package/src/breadboard/engine/inspector/graph/ports.ts +292 -0
- package/src/breadboard/engine/inspector/graph/schemas.ts +131 -0
- package/src/breadboard/engine/inspector/graph/virtual-node.ts +184 -0
- package/src/breadboard/engine/inspector/graph-store.ts +629 -0
- package/src/breadboard/engine/inspector/index.ts +13 -0
- package/src/breadboard/engine/inspector/utils.ts +20 -0
- package/src/breadboard/engine/loader/capability.ts +184 -0
- package/src/breadboard/engine/loader/index.ts +14 -0
- package/src/breadboard/engine/loader/loader.ts +244 -0
- package/src/breadboard/engine/loader/resolve-graph-urls.ts +111 -0
- package/src/breadboard/engine/runtime/bubble.ts +269 -0
- package/src/breadboard/engine/runtime/graph-based-node-handler.ts +174 -0
- package/src/breadboard/engine/runtime/handler.ts +166 -0
- package/src/breadboard/engine/runtime/harness/diagnostics.ts +22 -0
- package/src/breadboard/engine/runtime/harness/events.ts +217 -0
- package/src/breadboard/engine/runtime/harness/index.ts +14 -0
- package/src/breadboard/engine/runtime/harness/local.ts +48 -0
- package/src/breadboard/engine/runtime/harness/plan-runner.ts +759 -0
- package/src/breadboard/engine/runtime/index.ts +8 -0
- package/src/breadboard/engine/runtime/legacy.ts +28 -0
- package/src/breadboard/engine/runtime/run/invoke-graph.ts +79 -0
- package/src/breadboard/engine/runtime/run/node-invoker.ts +137 -0
- package/src/breadboard/engine/runtime/run/run-graph.ts +186 -0
- package/src/breadboard/engine/runtime/run.ts +111 -0
- package/src/breadboard/engine/runtime/sandbox/capabilities-manager.ts +253 -0
- package/src/breadboard/engine/runtime/sandbox/file-system-handler-factory.ts +53 -0
- package/src/breadboard/engine/runtime/sandbox/invoke-describer.ts +125 -0
- package/src/breadboard/engine/runtime/static/condense.ts +155 -0
- package/src/breadboard/engine/runtime/static/create-plan.ts +134 -0
- package/src/breadboard/engine/runtime/static/nodes-to-subgraph.ts +168 -0
- package/src/breadboard/engine/runtime/static/orchestrator.ts +664 -0
- package/src/breadboard/engine/runtime/static/types.ts +77 -0
- package/src/breadboard/engine/runtime/traversal/index.ts +58 -0
- package/src/breadboard/engine/runtime/traversal/iterator.ts +124 -0
- package/src/breadboard/engine/runtime/traversal/machine.ts +58 -0
- package/src/breadboard/engine/runtime/traversal/representation.ts +115 -0
- package/src/breadboard/engine/runtime/traversal/result.ts +72 -0
- package/src/breadboard/engine/runtime/traversal/state.ts +115 -0
- package/src/breadboard/engine/telemetry.ts +121 -0
- package/src/breadboard/engine/types.ts +32 -0
- package/src/breadboard/lit-flow-runner.test.ts +44 -0
- package/src/breadboard/lit-flow-runner.ts +98 -0
- package/src/breadboard/runner.ts +80 -0
- package/src/index.ts +2 -0
- package/src/lit-chiclet.ts +69 -0
- package/src/lit-flow.ts +17 -7
- package/src/lit-schema-node.test.ts +65 -0
- package/src/lit-schema-node.ts +194 -0
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
/**
|
|
3
|
+
* @license
|
|
4
|
+
* Copyright 2025 Google LLC
|
|
5
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type {
|
|
9
|
+
DescribeResultTypeCacheArgs,
|
|
10
|
+
GraphDescriptor,
|
|
11
|
+
MutableGraphStore,
|
|
12
|
+
NodeDescriberContext,
|
|
13
|
+
NodeDescriberFunction,
|
|
14
|
+
NodeDescriberResult,
|
|
15
|
+
NodeHandler,
|
|
16
|
+
NodeTypeIdentifier,
|
|
17
|
+
} from "@breadboard-ai/types";
|
|
18
|
+
import { createLoader } from "../../loader/index.js";
|
|
19
|
+
import { SENTINEL_BASE_URL } from "../../loader/loader.js";
|
|
20
|
+
import { getHandler } from "../../runtime/legacy.js";
|
|
21
|
+
import { contextFromMutableGraphStore } from "../graph-store.js";
|
|
22
|
+
import { UpdateEvent } from "./event.js";
|
|
23
|
+
import { emptyResult, NodeDescriberManager } from "./node-describer-manager.js";
|
|
24
|
+
import { describeInput, describeOutput } from "./schemas.js";
|
|
25
|
+
import {
|
|
26
|
+
assetsFromGraphDescriptor,
|
|
27
|
+
envFromGraphDescriptor,
|
|
28
|
+
} from "../../../data/file-system.js";
|
|
29
|
+
|
|
30
|
+
export { NodeTypeDescriberManager };
|
|
31
|
+
|
|
32
|
+
const PLACEHOLDER_ID = crypto.randomUUID();
|
|
33
|
+
|
|
34
|
+
const TYPE_DESCRIPTOR_GRAPH_URL = SENTINEL_BASE_URL.href;
|
|
35
|
+
|
|
36
|
+
class NodeTypeDescriberManager implements DescribeResultTypeCacheArgs {
|
|
37
|
+
constructor(public readonly store: MutableGraphStore) {}
|
|
38
|
+
|
|
39
|
+
initial(): NodeDescriberResult {
|
|
40
|
+
return emptyResult();
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
updated(): void {
|
|
44
|
+
this.store.dispatchEvent(
|
|
45
|
+
new UpdateEvent(PLACEHOLDER_ID, "", "", [], false)
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
latest(type: NodeTypeIdentifier): Promise<NodeDescriberResult> {
|
|
50
|
+
return this.getLatestDescription(type);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
async getLatestDescription(type: NodeTypeIdentifier) {
|
|
54
|
+
// The schema of an input or an output is defined by their
|
|
55
|
+
// configuration schema or their incoming/outgoing edges.
|
|
56
|
+
if (type === "input") {
|
|
57
|
+
return describeInput({});
|
|
58
|
+
}
|
|
59
|
+
if (type === "output") {
|
|
60
|
+
return describeOutput({});
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const kits = [...this.store.kits];
|
|
64
|
+
const describer = await this.#getDescriber(type);
|
|
65
|
+
const asWired = NodeDescriberManager.asWired();
|
|
66
|
+
if (!describer) {
|
|
67
|
+
return asWired;
|
|
68
|
+
}
|
|
69
|
+
const loader = this.store.loader || createLoader();
|
|
70
|
+
// When describing types, we provide a weird empty graph with a special URL
|
|
71
|
+
// because we're not actually inside of any graph, and that is ok.
|
|
72
|
+
const outerGraph: GraphDescriptor = {
|
|
73
|
+
nodes: [],
|
|
74
|
+
edges: [],
|
|
75
|
+
url: TYPE_DESCRIPTOR_GRAPH_URL,
|
|
76
|
+
};
|
|
77
|
+
const context: NodeDescriberContext = {
|
|
78
|
+
outerGraph,
|
|
79
|
+
loader,
|
|
80
|
+
kits,
|
|
81
|
+
sandbox: this.store.sandbox,
|
|
82
|
+
graphStore: this.store,
|
|
83
|
+
fileSystem: this.store.fileSystem.createRunFileSystem({
|
|
84
|
+
graphUrl: TYPE_DESCRIPTOR_GRAPH_URL,
|
|
85
|
+
env: envFromGraphDescriptor(this.store.fileSystem.env()),
|
|
86
|
+
assets: assetsFromGraphDescriptor(),
|
|
87
|
+
}),
|
|
88
|
+
wires: { incoming: {}, outgoing: {} },
|
|
89
|
+
asType: true,
|
|
90
|
+
flags: this.store.flags,
|
|
91
|
+
};
|
|
92
|
+
try {
|
|
93
|
+
return describer(
|
|
94
|
+
undefined,
|
|
95
|
+
asWired.inputSchema,
|
|
96
|
+
asWired.outputSchema,
|
|
97
|
+
context
|
|
98
|
+
);
|
|
99
|
+
} catch (e) {
|
|
100
|
+
console.warn(`Error describing node type ${type}`, e);
|
|
101
|
+
return asWired;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
async #getDescriber(
|
|
106
|
+
type: NodeTypeIdentifier
|
|
107
|
+
): Promise<NodeDescriberFunction | undefined> {
|
|
108
|
+
let handler: NodeHandler | undefined;
|
|
109
|
+
try {
|
|
110
|
+
handler = await getHandler(
|
|
111
|
+
type,
|
|
112
|
+
contextFromMutableGraphStore(this.store)
|
|
113
|
+
);
|
|
114
|
+
} catch (e) {
|
|
115
|
+
console.warn(`Error getting describer for node type ${type}`, e);
|
|
116
|
+
}
|
|
117
|
+
if (!handler || !("describe" in handler) || !handler.describe) {
|
|
118
|
+
return undefined;
|
|
119
|
+
}
|
|
120
|
+
return handler.describe;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
/**
|
|
3
|
+
* @license
|
|
4
|
+
* Copyright 2024 Google LLC
|
|
5
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type {
|
|
9
|
+
GraphIdentifier,
|
|
10
|
+
InputValues,
|
|
11
|
+
InspectableEdge,
|
|
12
|
+
InspectableNode,
|
|
13
|
+
InspectableNodePorts,
|
|
14
|
+
InspectableNodeType,
|
|
15
|
+
MutableGraph,
|
|
16
|
+
NodeConfiguration,
|
|
17
|
+
NodeDescriberResult,
|
|
18
|
+
NodeDescriptor,
|
|
19
|
+
NodeMetadata,
|
|
20
|
+
OutputValues,
|
|
21
|
+
} from "@breadboard-ai/types";
|
|
22
|
+
import { GraphQueries } from "./graph-queries.js";
|
|
23
|
+
import { describerResultToPorts } from "./ports.js";
|
|
24
|
+
|
|
25
|
+
export class Node implements InspectableNode {
|
|
26
|
+
descriptor: NodeDescriptor;
|
|
27
|
+
#graph: MutableGraph;
|
|
28
|
+
#graphId: GraphIdentifier;
|
|
29
|
+
#deleted = false;
|
|
30
|
+
|
|
31
|
+
constructor(
|
|
32
|
+
descriptor: NodeDescriptor,
|
|
33
|
+
graph: MutableGraph,
|
|
34
|
+
graphId: GraphIdentifier
|
|
35
|
+
) {
|
|
36
|
+
this.descriptor = descriptor;
|
|
37
|
+
this.#graph = graph;
|
|
38
|
+
this.#graphId = graphId;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
title(): string {
|
|
42
|
+
return this.descriptor.metadata?.title || this.descriptor.id;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
description(): string {
|
|
46
|
+
return this.descriptor.metadata?.description || this.title();
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
incoming(): InspectableEdge[] {
|
|
50
|
+
return new GraphQueries(this.#graph, this.#graphId).incoming(
|
|
51
|
+
this.descriptor.id
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
outgoing(): InspectableEdge[] {
|
|
56
|
+
return new GraphQueries(this.#graph, this.#graphId).outgoing(
|
|
57
|
+
this.descriptor.id
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
isEntry(): boolean {
|
|
62
|
+
return this.incoming().length === 0;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
isExit(): boolean {
|
|
66
|
+
return this.outgoing().length === 0;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
isStart(): boolean {
|
|
70
|
+
return new GraphQueries(this.#graph, this.#graphId).isStart(
|
|
71
|
+
this.descriptor.id
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
type(): InspectableNodeType {
|
|
76
|
+
const type = new GraphQueries(this.#graph, this.#graphId).typeForNode(
|
|
77
|
+
this.descriptor.id
|
|
78
|
+
);
|
|
79
|
+
if (!type) {
|
|
80
|
+
throw new Error(
|
|
81
|
+
`Possible integrity error: node ${this.descriptor.id} does not have a type`
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
return type;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
configuration(): NodeConfiguration {
|
|
88
|
+
return this.descriptor.configuration || {};
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
metadata(): NodeMetadata {
|
|
92
|
+
return this.descriptor.metadata || {};
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
async describe(): Promise<NodeDescriberResult> {
|
|
96
|
+
const describeEntry = this.#graph.describe.get(
|
|
97
|
+
this.descriptor.id,
|
|
98
|
+
this.#graphId
|
|
99
|
+
);
|
|
100
|
+
return describeEntry.latest;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
currentDescribe(): NodeDescriberResult {
|
|
104
|
+
const describeEntry = this.#graph.describe.get(
|
|
105
|
+
this.descriptor.id,
|
|
106
|
+
this.#graphId
|
|
107
|
+
);
|
|
108
|
+
return describeEntry.current;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
currentPorts(
|
|
112
|
+
inputValues?: InputValues,
|
|
113
|
+
outputValues?: OutputValues
|
|
114
|
+
): InspectableNodePorts {
|
|
115
|
+
const snapshot = this.#graph.describe.get(
|
|
116
|
+
this.descriptor.id,
|
|
117
|
+
this.#graphId
|
|
118
|
+
);
|
|
119
|
+
return describerResultToPorts(
|
|
120
|
+
this,
|
|
121
|
+
snapshot.current,
|
|
122
|
+
snapshot.updating,
|
|
123
|
+
inputValues,
|
|
124
|
+
outputValues
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
async ports(
|
|
129
|
+
inputValues?: InputValues,
|
|
130
|
+
outputValues?: OutputValues
|
|
131
|
+
): Promise<InspectableNodePorts> {
|
|
132
|
+
const described = await this.describe();
|
|
133
|
+
return describerResultToPorts(
|
|
134
|
+
this,
|
|
135
|
+
described,
|
|
136
|
+
false,
|
|
137
|
+
inputValues,
|
|
138
|
+
outputValues
|
|
139
|
+
);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
setDeleted() {
|
|
143
|
+
this.#deleted = true;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
deleted() {
|
|
147
|
+
return this.#deleted;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
/**
|
|
3
|
+
* @license
|
|
4
|
+
* Copyright 2024 Google LLC
|
|
5
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type {
|
|
9
|
+
GraphIdentifier,
|
|
10
|
+
InspectableNodePorts,
|
|
11
|
+
InspectablePortList,
|
|
12
|
+
NodeIdentifier,
|
|
13
|
+
NodePortChanges,
|
|
14
|
+
} from "@breadboard-ai/types";
|
|
15
|
+
|
|
16
|
+
export { PortCache };
|
|
17
|
+
|
|
18
|
+
type NodePortMap = Map<NodeIdentifier, InspectableNodePorts>;
|
|
19
|
+
|
|
20
|
+
type PortsUpdate = {
|
|
21
|
+
updated: InspectableNodePorts;
|
|
22
|
+
changes: NodePortChanges;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
class PortCache {
|
|
26
|
+
#map: Map<GraphIdentifier, NodePortMap> = new Map();
|
|
27
|
+
|
|
28
|
+
reconcilePorts(
|
|
29
|
+
incoming: InspectableNodePorts,
|
|
30
|
+
existing?: InspectableNodePorts
|
|
31
|
+
): PortsUpdate {
|
|
32
|
+
if (!existing) {
|
|
33
|
+
return this.createNewSnapshot(incoming);
|
|
34
|
+
}
|
|
35
|
+
throw new Error("Not implemented");
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
createNewSnapshot(incoming: InspectableNodePorts): PortsUpdate {
|
|
39
|
+
return {
|
|
40
|
+
updated: incoming,
|
|
41
|
+
changes: {
|
|
42
|
+
input: toUpdates(incoming.inputs),
|
|
43
|
+
output: toUpdates(incoming.outputs),
|
|
44
|
+
side: toUpdates(incoming.side),
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
function toUpdates(ports: InspectablePortList) {
|
|
49
|
+
return {
|
|
50
|
+
fixedChanged: ports.fixed,
|
|
51
|
+
deleted: [],
|
|
52
|
+
added: ports.ports,
|
|
53
|
+
updated: [],
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
current(
|
|
59
|
+
graphId: GraphIdentifier,
|
|
60
|
+
nodeId: NodeIdentifier
|
|
61
|
+
): InspectableNodePorts | undefined {
|
|
62
|
+
return this.#map.get(graphId)?.get(nodeId);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
getChanges(
|
|
66
|
+
graphId: GraphIdentifier,
|
|
67
|
+
nodeId: NodeIdentifier,
|
|
68
|
+
ports: InspectableNodePorts
|
|
69
|
+
): NodePortChanges {
|
|
70
|
+
let graphPorts = this.#map.get(graphId);
|
|
71
|
+
if (!graphPorts) {
|
|
72
|
+
graphPorts = new Map();
|
|
73
|
+
this.#map.set(graphId, graphPorts);
|
|
74
|
+
}
|
|
75
|
+
const nodePorts = graphPorts.get(nodeId);
|
|
76
|
+
const { updated, changes } = this.reconcilePorts(ports, nodePorts);
|
|
77
|
+
graphPorts.set(nodeId, updated);
|
|
78
|
+
return changes;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
/**
|
|
3
|
+
* @license
|
|
4
|
+
* Copyright 2024 Google LLC
|
|
5
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type {
|
|
9
|
+
BehaviorSchema,
|
|
10
|
+
InputValues,
|
|
11
|
+
InspectableEdge,
|
|
12
|
+
InspectableNode,
|
|
13
|
+
InspectableNodePorts,
|
|
14
|
+
InspectablePort,
|
|
15
|
+
InspectablePortList,
|
|
16
|
+
InspectablePortType,
|
|
17
|
+
NodeConfiguration,
|
|
18
|
+
NodeDescriberResult,
|
|
19
|
+
NodeHandler,
|
|
20
|
+
NodeTypeIdentifier,
|
|
21
|
+
OutputValues,
|
|
22
|
+
Schema,
|
|
23
|
+
} from "@breadboard-ai/types";
|
|
24
|
+
import { PortStatus } from "@breadboard-ai/types";
|
|
25
|
+
import { DEFAULT_SCHEMA, EdgeType } from "./schemas.js";
|
|
26
|
+
|
|
27
|
+
export { describerResultToPorts };
|
|
28
|
+
|
|
29
|
+
const title = (schema: Schema, key: string) => {
|
|
30
|
+
return schema.properties?.[key]?.title || key;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const computePortStatus = (
|
|
34
|
+
wired: boolean,
|
|
35
|
+
expected: boolean,
|
|
36
|
+
required: boolean,
|
|
37
|
+
wiredContainsStar: boolean
|
|
38
|
+
): PortStatus => {
|
|
39
|
+
if (wired) {
|
|
40
|
+
if (expected) return PortStatus.Connected;
|
|
41
|
+
return wiredContainsStar ? PortStatus.Indeterminate : PortStatus.Dangling;
|
|
42
|
+
}
|
|
43
|
+
if (required) {
|
|
44
|
+
return wiredContainsStar ? PortStatus.Indeterminate : PortStatus.Missing;
|
|
45
|
+
}
|
|
46
|
+
return PortStatus.Ready;
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
export const collectPorts = (
|
|
50
|
+
type: EdgeType,
|
|
51
|
+
edges: InspectableEdge[],
|
|
52
|
+
schema: Schema,
|
|
53
|
+
addErrorPort: boolean,
|
|
54
|
+
allowRequired: boolean,
|
|
55
|
+
values?: NodeConfiguration
|
|
56
|
+
) => {
|
|
57
|
+
let wiredContainsStar = false;
|
|
58
|
+
// Get the list of all ports wired to this node.
|
|
59
|
+
const wiredPortNames = edges.map((edge) => {
|
|
60
|
+
if (edge.out === "*") {
|
|
61
|
+
wiredContainsStar = true;
|
|
62
|
+
return "*";
|
|
63
|
+
}
|
|
64
|
+
return type === EdgeType.In ? edge.in : edge.out;
|
|
65
|
+
});
|
|
66
|
+
schema ??= {};
|
|
67
|
+
const fixed = schema.additionalProperties === false;
|
|
68
|
+
const schemaPortNames = Object.keys(schema.properties || {});
|
|
69
|
+
if (addErrorPort) {
|
|
70
|
+
// Even if not specified in the schema, all non-built-in nodes always have
|
|
71
|
+
// an optional `$error` port.
|
|
72
|
+
schemaPortNames.push("$error");
|
|
73
|
+
}
|
|
74
|
+
const schemaContainsStar = schemaPortNames.includes("*");
|
|
75
|
+
const requiredPortNames = schema.required || [];
|
|
76
|
+
const valuePortNames = Object.keys(values || {});
|
|
77
|
+
const portNames = [
|
|
78
|
+
...new Set([
|
|
79
|
+
...wiredPortNames,
|
|
80
|
+
...schemaPortNames,
|
|
81
|
+
...valuePortNames,
|
|
82
|
+
"*", // Always include the star port.
|
|
83
|
+
"", // Always include the control port.
|
|
84
|
+
]),
|
|
85
|
+
];
|
|
86
|
+
portNames.sort();
|
|
87
|
+
return portNames
|
|
88
|
+
.map((port) => {
|
|
89
|
+
const star = port === "*" || port === "";
|
|
90
|
+
const configured = valuePortNames.includes(port);
|
|
91
|
+
const wired = wiredPortNames.includes(port);
|
|
92
|
+
const expected = schemaPortNames.includes(port) || star;
|
|
93
|
+
const required = requiredPortNames.includes(port);
|
|
94
|
+
const portSchema = schema.properties?.[port] || DEFAULT_SCHEMA;
|
|
95
|
+
const kind = computeKind(type, portSchema);
|
|
96
|
+
if (portSchema.behavior?.includes("deprecated") && !wired) return null;
|
|
97
|
+
return {
|
|
98
|
+
name: port,
|
|
99
|
+
title: title(schema, port),
|
|
100
|
+
configured,
|
|
101
|
+
value: values?.[port],
|
|
102
|
+
star,
|
|
103
|
+
get edges() {
|
|
104
|
+
if (!wired) return [];
|
|
105
|
+
return edges.filter((edge) => {
|
|
106
|
+
if (edge.out === "*" && star) return true;
|
|
107
|
+
return type === EdgeType.In ? edge.in === port : edge.out === port;
|
|
108
|
+
});
|
|
109
|
+
},
|
|
110
|
+
status: computePortStatus(
|
|
111
|
+
wired || configured,
|
|
112
|
+
!fixed || expected || schemaContainsStar,
|
|
113
|
+
allowRequired && required,
|
|
114
|
+
wiredContainsStar
|
|
115
|
+
),
|
|
116
|
+
schema: portSchema,
|
|
117
|
+
type: new PortType(portSchema),
|
|
118
|
+
kind,
|
|
119
|
+
} satisfies InspectablePort;
|
|
120
|
+
})
|
|
121
|
+
.filter(Boolean) as InspectablePort[];
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
function computeKind(
|
|
125
|
+
type: EdgeType,
|
|
126
|
+
portSchema: Schema
|
|
127
|
+
): "input" | "output" | "side" {
|
|
128
|
+
const behaviors: BehaviorSchema[] =
|
|
129
|
+
(portSchema.type === "array"
|
|
130
|
+
? behaviorFromArray(portSchema.items)
|
|
131
|
+
: portSchema.behavior) || [];
|
|
132
|
+
if (type === EdgeType.Out) return "output";
|
|
133
|
+
const match: Set<BehaviorSchema> = new Set(["config", "board", "side"]);
|
|
134
|
+
let count = 0;
|
|
135
|
+
behaviors.forEach((behavior) => {
|
|
136
|
+
if (match.has(behavior)) ++count;
|
|
137
|
+
});
|
|
138
|
+
if (count == 3) return "side";
|
|
139
|
+
return "input";
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
function behaviorFromArray(
|
|
143
|
+
items: Schema | Schema[] | undefined
|
|
144
|
+
): BehaviorSchema[] {
|
|
145
|
+
if (!items) return [];
|
|
146
|
+
if (Array.isArray(items)) {
|
|
147
|
+
return items.flatMap((item) => item.behavior || []) || [];
|
|
148
|
+
}
|
|
149
|
+
return items.behavior || [];
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
export class PortType implements InspectablePortType {
|
|
153
|
+
constructor(public schema: Schema) {}
|
|
154
|
+
|
|
155
|
+
hasBehavior(behavior: BehaviorSchema): boolean {
|
|
156
|
+
return !!this.schema.behavior?.includes(behavior);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
const collectPortsForType = (
|
|
161
|
+
schema: Schema,
|
|
162
|
+
kind: "input" | "output"
|
|
163
|
+
): InspectablePort[] => {
|
|
164
|
+
const portNames = Object.keys(schema.properties || {});
|
|
165
|
+
const requiredPortNames = schema.required || [];
|
|
166
|
+
portNames.sort();
|
|
167
|
+
return portNames.map((port) => {
|
|
168
|
+
const portSchema: Schema = schema.properties?.[port] || DEFAULT_SCHEMA;
|
|
169
|
+
return {
|
|
170
|
+
name: port,
|
|
171
|
+
title: title(schema, port),
|
|
172
|
+
configured: false,
|
|
173
|
+
star: false,
|
|
174
|
+
edges: [],
|
|
175
|
+
value: null,
|
|
176
|
+
status: computePortStatus(
|
|
177
|
+
false,
|
|
178
|
+
true,
|
|
179
|
+
requiredPortNames.includes(port),
|
|
180
|
+
false
|
|
181
|
+
),
|
|
182
|
+
schema: portSchema,
|
|
183
|
+
type: new PortType(portSchema),
|
|
184
|
+
kind,
|
|
185
|
+
} satisfies InspectablePort;
|
|
186
|
+
});
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* CAUTION: Side-effectey. Will remove side-wire ports from `inputs`.
|
|
191
|
+
*/
|
|
192
|
+
function filterSidePorts(inputs: InspectablePortList) {
|
|
193
|
+
const sidePorts: InspectablePort[] = [];
|
|
194
|
+
const inputPorts = inputs.ports.filter((port) => {
|
|
195
|
+
if (port.kind === "side") {
|
|
196
|
+
sidePorts.push(port);
|
|
197
|
+
return false;
|
|
198
|
+
}
|
|
199
|
+
return true;
|
|
200
|
+
});
|
|
201
|
+
inputs.ports = inputPorts;
|
|
202
|
+
return sidePorts;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
function describerResultToPorts(
|
|
206
|
+
node: InspectableNode,
|
|
207
|
+
described: NodeDescriberResult,
|
|
208
|
+
updating: boolean,
|
|
209
|
+
inputValues?: InputValues,
|
|
210
|
+
outputValues?: OutputValues
|
|
211
|
+
): InspectableNodePorts {
|
|
212
|
+
const incoming = node.incoming();
|
|
213
|
+
const outgoing = node.outgoing();
|
|
214
|
+
const inputs: InspectablePortList = {
|
|
215
|
+
fixed: described.inputSchema?.additionalProperties === false,
|
|
216
|
+
behavior: described.inputSchema.behavior,
|
|
217
|
+
ports: collectPorts(
|
|
218
|
+
EdgeType.In,
|
|
219
|
+
incoming,
|
|
220
|
+
described.inputSchema,
|
|
221
|
+
false,
|
|
222
|
+
true,
|
|
223
|
+
{ ...node.configuration(), ...inputValues }
|
|
224
|
+
),
|
|
225
|
+
};
|
|
226
|
+
const side: InspectablePortList = {
|
|
227
|
+
fixed: true,
|
|
228
|
+
ports: filterSidePorts(inputs),
|
|
229
|
+
};
|
|
230
|
+
const addErrorPort =
|
|
231
|
+
node.descriptor.type !== "input" && node.descriptor.type !== "output";
|
|
232
|
+
const outputs: InspectablePortList = {
|
|
233
|
+
fixed: described.outputSchema?.additionalProperties === false,
|
|
234
|
+
ports: collectPorts(
|
|
235
|
+
EdgeType.Out,
|
|
236
|
+
outgoing,
|
|
237
|
+
described.outputSchema,
|
|
238
|
+
addErrorPort,
|
|
239
|
+
false,
|
|
240
|
+
outputValues
|
|
241
|
+
),
|
|
242
|
+
};
|
|
243
|
+
return { inputs, outputs, side, updating };
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
const emptyPorts = (): InspectableNodePorts => ({
|
|
247
|
+
inputs: {
|
|
248
|
+
ports: [],
|
|
249
|
+
fixed: false,
|
|
250
|
+
},
|
|
251
|
+
outputs: {
|
|
252
|
+
ports: [],
|
|
253
|
+
fixed: false,
|
|
254
|
+
},
|
|
255
|
+
side: {
|
|
256
|
+
ports: [],
|
|
257
|
+
fixed: true,
|
|
258
|
+
},
|
|
259
|
+
updating: false,
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
export const portsFromHandler = async (
|
|
263
|
+
type: NodeTypeIdentifier,
|
|
264
|
+
handler: NodeHandler | undefined
|
|
265
|
+
): Promise<InspectableNodePorts> => {
|
|
266
|
+
if (!handler || typeof handler === "function" || !handler.describe) {
|
|
267
|
+
return emptyPorts();
|
|
268
|
+
}
|
|
269
|
+
try {
|
|
270
|
+
const described = await handler.describe();
|
|
271
|
+
const inputs = {
|
|
272
|
+
fixed: described.inputSchema.additionalProperties === false,
|
|
273
|
+
ports: collectPortsForType(described.inputSchema, "input"),
|
|
274
|
+
};
|
|
275
|
+
const side = {
|
|
276
|
+
fixed: true,
|
|
277
|
+
ports: filterSidePorts(inputs),
|
|
278
|
+
};
|
|
279
|
+
return {
|
|
280
|
+
inputs,
|
|
281
|
+
outputs: {
|
|
282
|
+
fixed: described.outputSchema.additionalProperties === false,
|
|
283
|
+
ports: collectPortsForType(described.outputSchema, "output"),
|
|
284
|
+
},
|
|
285
|
+
side,
|
|
286
|
+
updating: false,
|
|
287
|
+
};
|
|
288
|
+
} catch (e) {
|
|
289
|
+
console.warn(`Error describing node type ${type}:`, e);
|
|
290
|
+
return emptyPorts();
|
|
291
|
+
}
|
|
292
|
+
};
|