@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.
Files changed (158) hide show
  1. package/CHANGELOG.md +5 -0
  2. package/dist/breadboard/data/common.d.ts +35 -0
  3. package/dist/breadboard/engine/loader/capability.d.ts +21 -0
  4. package/dist/breadboard/engine/loader/loader.d.ts +29 -0
  5. package/dist/breadboard/engine/loader/resolve-graph-urls.d.ts +16 -0
  6. package/dist/breadboard/engine/runtime/bubble.d.ts +23 -0
  7. package/dist/breadboard/engine/runtime/graph-based-node-handler.d.ts +16 -0
  8. package/dist/breadboard/engine/runtime/handler.d.ts +27 -0
  9. package/dist/breadboard/engine/runtime/harness/events.d.ts +145 -0
  10. package/dist/breadboard/engine/runtime/harness/local.d.ts +10 -0
  11. package/dist/breadboard/engine/runtime/harness/plan-runner.d.ts +25 -0
  12. package/dist/breadboard/engine/runtime/run/invoke-graph.d.ts +12 -0
  13. package/dist/breadboard/engine/runtime/run/node-invoker.d.ts +12 -0
  14. package/dist/breadboard/engine/runtime/run/run-graph.d.ts +12 -0
  15. package/dist/breadboard/engine/runtime/run.d.ts +29 -0
  16. package/dist/breadboard/engine/runtime/sandbox/capabilities-manager.d.ts +15 -0
  17. package/dist/breadboard/engine/runtime/sandbox/file-system-handler-factory.d.ts +15 -0
  18. package/dist/breadboard/engine/runtime/sandbox/invoke-describer.d.ts +10 -0
  19. package/dist/breadboard/engine/runtime/static/create-plan.d.ts +14 -0
  20. package/dist/breadboard/engine/runtime/static/orchestrator.d.ts +72 -0
  21. package/dist/breadboard/engine/runtime/traversal/index.d.ts +20 -0
  22. package/dist/breadboard/engine/runtime/traversal/iterator.d.ts +12 -0
  23. package/dist/breadboard/engine/runtime/traversal/machine.d.ts +14 -0
  24. package/dist/breadboard/engine/runtime/traversal/representation.d.ts +27 -0
  25. package/dist/breadboard/engine/runtime/traversal/result.d.ts +24 -0
  26. package/dist/breadboard/engine/runtime/traversal/state.d.ts +34 -0
  27. package/dist/breadboard/lit-flow-runner.d.ts +13 -0
  28. package/dist/breadboard/lit-flow-runner.test.d.ts +1 -0
  29. package/dist/breadboard/runner.d.ts +13 -0
  30. package/dist/index.d.ts +2 -0
  31. package/dist/lit-chiclet.d.ts +9 -0
  32. package/dist/lit-schema-node.d.ts +13 -0
  33. package/dist/lit-schema-node.test.d.ts +1 -0
  34. package/dist/litflow.js +708 -442
  35. package/dist/litflow.js.map +1 -1
  36. package/package.json +15 -3
  37. package/src/breadboard/data/common.ts +450 -0
  38. package/src/breadboard/data/file-system.ts +54 -0
  39. package/src/breadboard/data/inline-all-content.ts +126 -0
  40. package/src/breadboard/data/recent-boards.ts +118 -0
  41. package/src/breadboard/data/save-outputs-as-file.ts +104 -0
  42. package/src/breadboard/engine/add-run-module.ts +168 -0
  43. package/src/breadboard/engine/editor/blank.ts +65 -0
  44. package/src/breadboard/engine/editor/edge.ts +27 -0
  45. package/src/breadboard/engine/editor/events.ts +64 -0
  46. package/src/breadboard/engine/editor/graph.ts +383 -0
  47. package/src/breadboard/engine/editor/history.ts +98 -0
  48. package/src/breadboard/engine/editor/index.ts +8 -0
  49. package/src/breadboard/engine/editor/operations/add-asset.ts +45 -0
  50. package/src/breadboard/engine/editor/operations/add-edge.ts +142 -0
  51. package/src/breadboard/engine/editor/operations/add-graph.ts +47 -0
  52. package/src/breadboard/engine/editor/operations/add-module.ts +64 -0
  53. package/src/breadboard/engine/editor/operations/add-node.ts +86 -0
  54. package/src/breadboard/engine/editor/operations/change-asset-metadata.ts +70 -0
  55. package/src/breadboard/engine/editor/operations/change-configuration.ts +82 -0
  56. package/src/breadboard/engine/editor/operations/change-edge-metadata.ts +58 -0
  57. package/src/breadboard/engine/editor/operations/change-edge.ts +111 -0
  58. package/src/breadboard/engine/editor/operations/change-graph-metadata.ts +52 -0
  59. package/src/breadboard/engine/editor/operations/change-metadata.ts +92 -0
  60. package/src/breadboard/engine/editor/operations/change-module.ts +64 -0
  61. package/src/breadboard/engine/editor/operations/error.ts +21 -0
  62. package/src/breadboard/engine/editor/operations/remove-asset.ts +48 -0
  63. package/src/breadboard/engine/editor/operations/remove-edge.ts +89 -0
  64. package/src/breadboard/engine/editor/operations/remove-graph.ts +49 -0
  65. package/src/breadboard/engine/editor/operations/remove-integration.ts +54 -0
  66. package/src/breadboard/engine/editor/operations/remove-module.ts +69 -0
  67. package/src/breadboard/engine/editor/operations/remove-node.ts +86 -0
  68. package/src/breadboard/engine/editor/operations/replace-graph.ts +52 -0
  69. package/src/breadboard/engine/editor/operations/toggle-export.ts +72 -0
  70. package/src/breadboard/engine/editor/operations/upsert-integration.ts +43 -0
  71. package/src/breadboard/engine/editor/selection.ts +58 -0
  72. package/src/breadboard/engine/editor/transforms/configure-sidewire.ts +73 -0
  73. package/src/breadboard/engine/editor/transforms/isolate-selection.ts +54 -0
  74. package/src/breadboard/engine/editor/transforms/merge-graph.ts +58 -0
  75. package/src/breadboard/engine/editor/transforms/move-to-graph.ts +102 -0
  76. package/src/breadboard/engine/editor/transforms/move-to-new-graph.ts +72 -0
  77. package/src/breadboard/engine/editor/transforms/sidewire-to-new-graph.ts +82 -0
  78. package/src/breadboard/engine/file-system/blob-transform.ts +44 -0
  79. package/src/breadboard/engine/file-system/composed-peristent-backend.ts +140 -0
  80. package/src/breadboard/engine/file-system/ephemeral-blob-store.ts +46 -0
  81. package/src/breadboard/engine/file-system/in-memory-blob-store.ts +87 -0
  82. package/src/breadboard/engine/file-system/index.ts +723 -0
  83. package/src/breadboard/engine/file-system/partial-persistent-backend.ts +109 -0
  84. package/src/breadboard/engine/file-system/path.ts +125 -0
  85. package/src/breadboard/engine/file-system/persistent-file.ts +66 -0
  86. package/src/breadboard/engine/file-system/readable-stream-file.ts +61 -0
  87. package/src/breadboard/engine/file-system/stub-file-system.ts +47 -0
  88. package/src/breadboard/engine/file-system/utils.ts +40 -0
  89. package/src/breadboard/engine/inspector/graph/bubbled-node.ts +162 -0
  90. package/src/breadboard/engine/inspector/graph/describe-cache.ts +78 -0
  91. package/src/breadboard/engine/inspector/graph/describe-type-cache.ts +48 -0
  92. package/src/breadboard/engine/inspector/graph/edge-cache.ts +118 -0
  93. package/src/breadboard/engine/inspector/graph/edge.ts +133 -0
  94. package/src/breadboard/engine/inspector/graph/event.ts +35 -0
  95. package/src/breadboard/engine/inspector/graph/exports-describer.ts +45 -0
  96. package/src/breadboard/engine/inspector/graph/graph-cache.ts +54 -0
  97. package/src/breadboard/engine/inspector/graph/graph-describer-manager.ts +338 -0
  98. package/src/breadboard/engine/inspector/graph/graph-descriptor-handle.ts +73 -0
  99. package/src/breadboard/engine/inspector/graph/graph-node-type.ts +111 -0
  100. package/src/breadboard/engine/inspector/graph/graph-queries.ts +256 -0
  101. package/src/breadboard/engine/inspector/graph/graph.ts +163 -0
  102. package/src/breadboard/engine/inspector/graph/inspectable-asset.ts +36 -0
  103. package/src/breadboard/engine/inspector/graph/kits.ts +208 -0
  104. package/src/breadboard/engine/inspector/graph/module.ts +69 -0
  105. package/src/breadboard/engine/inspector/graph/mutable-graph.ts +150 -0
  106. package/src/breadboard/engine/inspector/graph/node-cache.ts +123 -0
  107. package/src/breadboard/engine/inspector/graph/node-describer-manager.ts +279 -0
  108. package/src/breadboard/engine/inspector/graph/node-type-describer-manager.ts +122 -0
  109. package/src/breadboard/engine/inspector/graph/node.ts +149 -0
  110. package/src/breadboard/engine/inspector/graph/port-cache.ts +80 -0
  111. package/src/breadboard/engine/inspector/graph/ports.ts +292 -0
  112. package/src/breadboard/engine/inspector/graph/schemas.ts +131 -0
  113. package/src/breadboard/engine/inspector/graph/virtual-node.ts +184 -0
  114. package/src/breadboard/engine/inspector/graph-store.ts +629 -0
  115. package/src/breadboard/engine/inspector/index.ts +13 -0
  116. package/src/breadboard/engine/inspector/utils.ts +20 -0
  117. package/src/breadboard/engine/loader/capability.ts +184 -0
  118. package/src/breadboard/engine/loader/index.ts +14 -0
  119. package/src/breadboard/engine/loader/loader.ts +244 -0
  120. package/src/breadboard/engine/loader/resolve-graph-urls.ts +111 -0
  121. package/src/breadboard/engine/runtime/bubble.ts +269 -0
  122. package/src/breadboard/engine/runtime/graph-based-node-handler.ts +174 -0
  123. package/src/breadboard/engine/runtime/handler.ts +166 -0
  124. package/src/breadboard/engine/runtime/harness/diagnostics.ts +22 -0
  125. package/src/breadboard/engine/runtime/harness/events.ts +217 -0
  126. package/src/breadboard/engine/runtime/harness/index.ts +14 -0
  127. package/src/breadboard/engine/runtime/harness/local.ts +48 -0
  128. package/src/breadboard/engine/runtime/harness/plan-runner.ts +759 -0
  129. package/src/breadboard/engine/runtime/index.ts +8 -0
  130. package/src/breadboard/engine/runtime/legacy.ts +28 -0
  131. package/src/breadboard/engine/runtime/run/invoke-graph.ts +79 -0
  132. package/src/breadboard/engine/runtime/run/node-invoker.ts +137 -0
  133. package/src/breadboard/engine/runtime/run/run-graph.ts +186 -0
  134. package/src/breadboard/engine/runtime/run.ts +111 -0
  135. package/src/breadboard/engine/runtime/sandbox/capabilities-manager.ts +253 -0
  136. package/src/breadboard/engine/runtime/sandbox/file-system-handler-factory.ts +53 -0
  137. package/src/breadboard/engine/runtime/sandbox/invoke-describer.ts +125 -0
  138. package/src/breadboard/engine/runtime/static/condense.ts +155 -0
  139. package/src/breadboard/engine/runtime/static/create-plan.ts +134 -0
  140. package/src/breadboard/engine/runtime/static/nodes-to-subgraph.ts +168 -0
  141. package/src/breadboard/engine/runtime/static/orchestrator.ts +664 -0
  142. package/src/breadboard/engine/runtime/static/types.ts +77 -0
  143. package/src/breadboard/engine/runtime/traversal/index.ts +58 -0
  144. package/src/breadboard/engine/runtime/traversal/iterator.ts +124 -0
  145. package/src/breadboard/engine/runtime/traversal/machine.ts +58 -0
  146. package/src/breadboard/engine/runtime/traversal/representation.ts +115 -0
  147. package/src/breadboard/engine/runtime/traversal/result.ts +72 -0
  148. package/src/breadboard/engine/runtime/traversal/state.ts +115 -0
  149. package/src/breadboard/engine/telemetry.ts +121 -0
  150. package/src/breadboard/engine/types.ts +32 -0
  151. package/src/breadboard/lit-flow-runner.test.ts +44 -0
  152. package/src/breadboard/lit-flow-runner.ts +98 -0
  153. package/src/breadboard/runner.ts +80 -0
  154. package/src/index.ts +2 -0
  155. package/src/lit-chiclet.ts +69 -0
  156. package/src/lit-flow.ts +17 -7
  157. package/src/lit-schema-node.test.ts +65 -0
  158. package/src/lit-schema-node.ts +194 -0
@@ -0,0 +1,269 @@
1
+ // @ts-nocheck
2
+ /**
3
+ * @license
4
+ * Copyright 2023 Google LLC
5
+ * SPDX-License-Identifier: Apache-2.0
6
+ */
7
+
8
+ import type {
9
+ GraphInlineMetadata,
10
+ InputValues,
11
+ NodeDescriptor,
12
+ NodeHandlerContext,
13
+ NodeValue,
14
+ OutputValues,
15
+ RunArguments,
16
+ Schema,
17
+ TraversalResult,
18
+ } from "@breadboard-ai/types";
19
+ import { InputStageResult, OutputStageResult, RunResult } from "./run.js";
20
+
21
+ export const createErrorMessage = (
22
+ inputName: string | string[],
23
+ metadata: GraphInlineMetadata = {},
24
+ required: boolean
25
+ ): string => {
26
+ const boardTitle = metadata.title ?? metadata?.url;
27
+ const inputNames = typeof inputName === "string" ? [inputName] : inputName;
28
+ const requiredText = required ? "required " : "";
29
+ return `Missing ${requiredText}input ${inputNames.map((name) => `"${name}"`).join(", ")}${
30
+ boardTitle ? ` for board "${boardTitle}".` : "."
31
+ }`;
32
+ };
33
+
34
+ export const bubbleUpInputsIfNeeded = async (
35
+ metadata: GraphInlineMetadata,
36
+ context: NodeHandlerContext,
37
+ descriptor: NodeDescriptor,
38
+ result: TraversalResult,
39
+ path: number[]
40
+ ): Promise<void> => {
41
+ // If we have no way to bubble up inputs, we just return and not
42
+ // enforce required inputs.
43
+ if (!context.requestInput) return;
44
+
45
+ const outputs = result.outputs ?? {};
46
+ const reader = new InputSchemaReader(outputs, result.inputs, path);
47
+ result.outputs = await reader.read(
48
+ createBubbleHandler(metadata, context, descriptor)
49
+ );
50
+ };
51
+
52
+ export const createBubbleHandler = (
53
+ metadata: GraphInlineMetadata,
54
+ context: NodeHandlerContext,
55
+ descriptor: NodeDescriptor
56
+ ) => {
57
+ return (async (propertiesSchema, path) => {
58
+ const entries = Object.entries(propertiesSchema.properties || {});
59
+ const defaultOutputs: OutputValues = {};
60
+ const propertiesToRequest: [string, Schema][] = [];
61
+ // Pre-process the entries and prepare to request input.
62
+ for (const [name, schema] of entries) {
63
+ const required = propertiesSchema.required?.includes(name) ?? false;
64
+
65
+ if (required) {
66
+ throw new Error(createErrorMessage(name, metadata, required));
67
+ }
68
+ if (schema.default !== undefined) {
69
+ if ("type" in schema && schema.type !== "string") {
70
+ defaultOutputs[name] = JSON.parse(schema.default);
71
+ } else {
72
+ defaultOutputs[name] = schema.default;
73
+ }
74
+ continue;
75
+ }
76
+ propertiesToRequest.push([name, schema]);
77
+ }
78
+ // Exit early if we already have all properties.
79
+ if (propertiesToRequest.length === 0) {
80
+ return defaultOutputs;
81
+ }
82
+ // Request properties that did not have default values.
83
+ const inputRequestSchema: Schema = {
84
+ properties: Object.fromEntries(propertiesToRequest),
85
+ };
86
+ const outputs = await context.requestInput?.(
87
+ inputRequestSchema,
88
+ descriptor,
89
+ path
90
+ );
91
+ // If the run was aborted, let's bail
92
+ if (context?.signal?.aborted) {
93
+ throw context.signal.throwIfAborted();
94
+ }
95
+ // Finally, let's make sure we have all values and if not, throw an error.
96
+ if (!outputs || Object.keys(outputs).length === 0) {
97
+ throw new Error(
98
+ createErrorMessage(
99
+ propertiesToRequest.map(([name]) => name),
100
+ metadata,
101
+ false
102
+ )
103
+ );
104
+ }
105
+ return { ...defaultOutputs, ...outputs };
106
+ }) satisfies InputSchemaHandler;
107
+ };
108
+
109
+ export type InputSchemaHandler = (
110
+ schema: Schema,
111
+ path: number[]
112
+ ) => Promise<OutputValues>;
113
+
114
+ export class InputSchemaReader {
115
+ #currentOutputs: OutputValues;
116
+ #inputs: InputValues;
117
+ #path: number[];
118
+
119
+ constructor(
120
+ currentOutputs: OutputValues,
121
+ inputs: InputValues,
122
+ path: number[]
123
+ ) {
124
+ this.#currentOutputs = currentOutputs;
125
+ this.#inputs = inputs;
126
+ this.#path = path;
127
+ }
128
+
129
+ async read(handler: InputSchemaHandler): Promise<OutputValues> {
130
+ if (!("schema" in this.#inputs)) return this.#currentOutputs;
131
+
132
+ const schema = this.#inputs.schema as Schema;
133
+
134
+ if (!schema.properties) return this.#currentOutputs;
135
+
136
+ const unfulfilled = structuredClone(schema);
137
+ for (const name of Object.keys(schema.properties)) {
138
+ if (name in this.#currentOutputs) {
139
+ delete unfulfilled.properties?.[name];
140
+ }
141
+ }
142
+
143
+ const willAsk = Object.keys(unfulfilled.properties || {}).length > 0;
144
+
145
+ const newOutputs = willAsk ? await handler(unfulfilled, this.#path) : {};
146
+
147
+ return { ...this.#currentOutputs, ...newOutputs };
148
+ }
149
+ }
150
+
151
+ export class RequestedInputsManager {
152
+ #context: NodeHandlerContext;
153
+ #cache: Map<string, NodeValue> = new Map();
154
+
155
+ constructor(args: RunArguments) {
156
+ const { inputs, ...context } = args;
157
+ this.#context = context;
158
+ this.#cache = new Map(inputs ? Object.entries(inputs) : []);
159
+ }
160
+
161
+ createHandler(
162
+ next: (result: RunResult) => Promise<void>,
163
+ result: TraversalResult
164
+ ): NodeHandlerContext["requestInput"] {
165
+ return async (schema: Schema, node: NodeDescriptor, path: number[]) => {
166
+ // Retrieve all cached values
167
+ const propertiesToRequest = Object.entries(schema.properties || {});
168
+ const cachedValues: OutputValues = {};
169
+ const uncachedProperties = propertiesToRequest.filter(([name]) => {
170
+ const cachedValue = this.#cache.get(name);
171
+ if (cachedValue !== undefined) {
172
+ cachedValues[name] = cachedValue;
173
+ return false;
174
+ }
175
+ return true;
176
+ });
177
+ // Early return when all properties are cached
178
+ if (uncachedProperties.length === 0) return cachedValues;
179
+
180
+ const configuration = node.configuration?.schema
181
+ ? {
182
+ configuration: { schema: node.configuration.schema },
183
+ }
184
+ : {};
185
+ const descriptor = { id: node.id, type: node.type, ...configuration };
186
+ const requestInputResult = {
187
+ ...result,
188
+ descriptor,
189
+ inputs: {
190
+ schema: {
191
+ type: "object",
192
+ properties: Object.fromEntries(uncachedProperties),
193
+ } satisfies Schema,
194
+ },
195
+ };
196
+ await next(new InputStageResult(requestInputResult, -1, path));
197
+ const outputs = requestInputResult.outputs;
198
+ const requestedProperties = schema.properties || {};
199
+ const remainingProperties = outputs
200
+ ? Object.fromEntries(
201
+ Object.entries(requestedProperties).filter(([name]) => {
202
+ return !(name in outputs);
203
+ })
204
+ )
205
+ : requestedProperties;
206
+ if (Object.keys(remainingProperties).length === 0) {
207
+ return outputs;
208
+ }
209
+ // Bubble up: request outer context to request input
210
+ const bubbledOutputs: OutputValues =
211
+ (await this.#context.requestInput?.(
212
+ { properties: remainingProperties },
213
+ descriptor,
214
+ path
215
+ )) || {};
216
+ // Cache all non-transient properties.
217
+ for (const [name, propertySchema] of uncachedProperties) {
218
+ if (!isTransient(propertySchema)) {
219
+ const value = bubbledOutputs[name];
220
+ if (value) {
221
+ this.#cache.set(name, bubbledOutputs[name]);
222
+ }
223
+ }
224
+ }
225
+ return { ...outputs, ...bubbledOutputs };
226
+ };
227
+ }
228
+ }
229
+
230
+ function isTransient(schema: Schema): boolean {
231
+ return schema.behavior?.includes("transient") ?? false;
232
+ }
233
+
234
+ export const bubbleUpOutputsIfNeeded = async (
235
+ outputs: OutputValues,
236
+ descriptor: NodeDescriptor,
237
+ context: NodeHandlerContext,
238
+ path: number[]
239
+ ): Promise<boolean> => {
240
+ if (!context.provideOutput) return false;
241
+ const schema = descriptor.configuration?.schema as Schema;
242
+ const shouldBubble = schema?.behavior?.includes("bubble");
243
+ if (!shouldBubble) return false;
244
+
245
+ await context.provideOutput(outputs, descriptor, path);
246
+ return true;
247
+ };
248
+
249
+ export const createOutputProvider = (
250
+ next: (result: RunResult) => Promise<void>,
251
+ result: TraversalResult,
252
+ context: NodeHandlerContext
253
+ ) => {
254
+ if (context.provideOutput) {
255
+ return context.provideOutput;
256
+ }
257
+ return async (
258
+ outputs: OutputValues,
259
+ descriptor: NodeDescriptor,
260
+ path: number[]
261
+ ) => {
262
+ const provideOutputResult = {
263
+ ...result,
264
+ descriptor,
265
+ inputs: outputs,
266
+ };
267
+ await next(new OutputStageResult(provideOutputResult, -1, path));
268
+ };
269
+ };
@@ -0,0 +1,174 @@
1
+ // @ts-nocheck
2
+ /**
3
+ * @license
4
+ * Copyright 2024 Google LLC
5
+ * SPDX-License-Identifier: Apache-2.0
6
+ */
7
+
8
+ import {
9
+ GraphToRun,
10
+ InputValues,
11
+ MutableGraph,
12
+ NodeDescriberContext,
13
+ NodeDescriberResult,
14
+ NodeHandlerContext,
15
+ NodeHandlerMetadata,
16
+ NodeHandlerObject,
17
+ NodeTypeIdentifier,
18
+ Schema,
19
+ } from "@breadboard-ai/types";
20
+ import { emptyDescriberResult, filterEmptyValues } from "@breadboard-ai/utils";
21
+ import { invokeGraph } from "./run/invoke-graph.js";
22
+ import { CapabilitiesManagerImpl } from "./sandbox/capabilities-manager.js";
23
+ import { invokeDescriber } from "./sandbox/invoke-describer.js";
24
+
25
+ export {
26
+ describerResultToNodeHandlerMetadata,
27
+ GraphBasedNodeHandler,
28
+ toNodeHandlerMetadata,
29
+ };
30
+
31
+ class GraphBasedNodeHandler implements NodeHandlerObject {
32
+ #graph: GraphToRun;
33
+ #type: NodeTypeIdentifier;
34
+
35
+ constructor(graph: GraphToRun, type: NodeTypeIdentifier) {
36
+ this.#graph = graph;
37
+ this.#type = type;
38
+ this.invoke = this.invoke.bind(this);
39
+ this.describe = this.describe.bind(this);
40
+ }
41
+
42
+ async invoke(inputs: InputValues, context: NodeHandlerContext) {
43
+ const base = context.board?.url && new URL(context.board?.url);
44
+ const invocationContext = base
45
+ ? {
46
+ ...context,
47
+ base,
48
+ }
49
+ : { ...context };
50
+
51
+ return await invokeGraph(this.#graph, inputs, invocationContext);
52
+ }
53
+
54
+ async describe(
55
+ inputs?: InputValues,
56
+ inputSchema?: Schema,
57
+ outputSchema?: Schema,
58
+ context?: NodeDescriberContext
59
+ ) {
60
+ if (!context) {
61
+ return { inputSchema: {}, outputSchema: {} };
62
+ }
63
+
64
+ const graphStore = context?.graphStore;
65
+ if (!graphStore) {
66
+ return emptyDescriberResult();
67
+ }
68
+ const url = this.#graph.graph.url;
69
+ let mutable: MutableGraph;
70
+ if (url) {
71
+ // In the most common case, just use the URL of the graph.
72
+ const adding = graphStore.addByURL(url, [], context);
73
+ mutable = adding.mutable;
74
+ } else {
75
+ const adding = graphStore.addByDescriptor(this.#graph.graph);
76
+ if (!adding.success) {
77
+ return emptyDescriberResult();
78
+ }
79
+ mutable = graphStore.get(adding.result)!;
80
+ }
81
+ mutable = await graphStore.getLatest(mutable);
82
+ if (this.#graph.moduleId) {
83
+ const moduleId = this.#graph.moduleId;
84
+ const graph = this.#graph.graph;
85
+ const sandbox = context.graphStore?.sandbox;
86
+ if (!sandbox) {
87
+ console.warn("Sandbox was not supplied to describe node type");
88
+ return emptyDescriberResult();
89
+ }
90
+ const result = await invokeDescriber(
91
+ context,
92
+ moduleId,
93
+ mutable,
94
+ graph,
95
+ inputs || {},
96
+ inputSchema,
97
+ outputSchema,
98
+ new CapabilitiesManagerImpl(context),
99
+ context.asType || false
100
+ );
101
+ if (!result) {
102
+ return emptyDescriberResult();
103
+ }
104
+ return result;
105
+ } else {
106
+ const inspectableGraph = graphStore.inspect(
107
+ mutable.id,
108
+ this.#graph.subGraphId || ""
109
+ );
110
+ if (!inspectableGraph) {
111
+ return emptyDescriberResult();
112
+ }
113
+ const result = await inspectableGraph.describe(inputs, context);
114
+ return result;
115
+ }
116
+ }
117
+
118
+ get metadata() {
119
+ return toNodeHandlerMetadata(this.#graph, this.#type, false);
120
+ }
121
+ }
122
+
123
+ function describerResultToNodeHandlerMetadata(
124
+ result: NodeDescriberResult,
125
+ updating: boolean
126
+ ): NodeHandlerMetadata {
127
+ return filterEmptyValues({
128
+ title: result.title,
129
+ description: result.description,
130
+ url: result.url,
131
+ icon: result.metadata?.icon,
132
+ help: result.metadata?.help,
133
+ updating,
134
+ });
135
+ }
136
+
137
+ function toNodeHandlerMetadata(
138
+ graphToRun: GraphToRun,
139
+ url: NodeTypeIdentifier,
140
+ updating: boolean
141
+ ): NodeHandlerMetadata | undefined {
142
+ const graph = graphToRun.graph;
143
+ if (graphToRun.moduleId) {
144
+ const module = graph.modules?.[graphToRun.moduleId];
145
+ if (!module) return undefined;
146
+ const {
147
+ title = graphToRun.moduleId,
148
+ description,
149
+ icon,
150
+ help,
151
+ } = module.metadata || {};
152
+ return filterEmptyValues({ title, description, url, icon, help, updating });
153
+ } else if (graphToRun.subGraphId) {
154
+ const descriptor = graph.graphs?.[graphToRun.subGraphId];
155
+ if (!descriptor) return undefined;
156
+ return filterEmptyValues({
157
+ title: descriptor.title,
158
+ description: descriptor.description,
159
+ url,
160
+ icon: descriptor.metadata?.icon,
161
+ help: descriptor.metadata?.help,
162
+ updating,
163
+ });
164
+ } else {
165
+ return filterEmptyValues({
166
+ title: graph.title,
167
+ description: graph.description,
168
+ url: graph.url,
169
+ icon: graph.metadata?.icon,
170
+ help: graph.metadata?.help,
171
+ updating,
172
+ });
173
+ }
174
+ }
@@ -0,0 +1,166 @@
1
+ // @ts-nocheck
2
+ /**
3
+ * @license
4
+ * Copyright 2023 Google LLC
5
+ * SPDX-License-Identifier: Apache-2.0
6
+ */
7
+
8
+ import type {
9
+ InputValues,
10
+ Kit,
11
+ MutableGraph,
12
+ NodeHandler,
13
+ NodeHandlerContext,
14
+ NodeHandlerFunction,
15
+ NodeHandlerObject,
16
+ NodeHandlers,
17
+ NodeTypeIdentifier,
18
+ OutputValues,
19
+ } from "@breadboard-ai/types";
20
+ import { graphUrlLike } from "@breadboard-ai/utils";
21
+ import { GraphBasedNodeHandler } from "./graph-based-node-handler.js";
22
+ import { getGraphUrl } from "../loader/loader.js";
23
+
24
+ // TODO: Deduplicate.
25
+ function contextFromMutableGraph(mutable: MutableGraph): NodeHandlerContext {
26
+ const store = mutable.store;
27
+ return {
28
+ kits: [...store.kits],
29
+ loader: store.loader,
30
+ sandbox: store.sandbox,
31
+ graphStore: store,
32
+ outerGraph: mutable.graph,
33
+ };
34
+ }
35
+
36
+ const getHandlerFunction = (handler: NodeHandler): NodeHandlerFunction => {
37
+ if ("invoke" in handler && handler.invoke) return handler.invoke;
38
+ if (handler instanceof Function) return handler;
39
+ throw new Error("Invalid handler");
40
+ };
41
+
42
+ export const callHandler = async (
43
+ handler: NodeHandler,
44
+ inputs: InputValues,
45
+ context: NodeHandlerContext
46
+ ): Promise<OutputValues | void> => {
47
+ // if (handler instanceof Function) return handler(inputs, context);
48
+ // if (handler.invoke) return handler.invoke(inputs, context);
49
+ const handlerFunction = getHandlerFunction(handler);
50
+ return new Promise((resolve) => {
51
+ handlerFunction(inputs, context)
52
+ .then(resolve)
53
+ .catch((error) => {
54
+ resolve({ $error: { error } });
55
+ });
56
+ });
57
+ };
58
+
59
+ export const handlersFromKits = (kits: Kit[]): NodeHandlers => {
60
+ return kits.reduce((handlers, kit) => {
61
+ // If multiple kits have the same handler, the kit earlier in the list
62
+ // gets precedence, including upstream kits getting precedence over kits
63
+ // defined in the graph.
64
+ //
65
+ // TODO: This means kits are fallback, consider non-fallback as well.
66
+ return { ...kit.handlers, ...handlers };
67
+ }, {} as NodeHandlers);
68
+ };
69
+
70
+ /**
71
+ * The single entry point for getting a handler for a node type.
72
+ * The handler can be one of the two types:
73
+ * - A graph-based handler, where the `type` is actually a
74
+ * URL-like string that points to a graph.
75
+ * - A kit-based handler, where the `type` is a string that
76
+ * corresponds to a node type in a kit.
77
+ *
78
+ * The function throws an error if no handler is found for the
79
+ * given node type.
80
+ *
81
+ * @param type -- The node type to get a handler for.
82
+ * @param context -- The context in which the handler is
83
+ * being requested.
84
+ * @returns -- The handler for the node type.
85
+ */
86
+ export async function getHandler(
87
+ type: NodeTypeIdentifier,
88
+ context: NodeHandlerContext
89
+ ): Promise<NodeHandler> {
90
+ if (graphUrlLike(type)) {
91
+ const graphHandler = await getGraphHandler(type, context);
92
+ if (graphHandler) {
93
+ return graphHandler;
94
+ }
95
+ }
96
+ const handlers = handlersFromKits(context.kits ?? []);
97
+ const kitHandler = handlers[type];
98
+ if (kitHandler) {
99
+ return kitHandler;
100
+ }
101
+ throw new Error(`No handler for node type "${type}"`);
102
+ }
103
+
104
+ export async function getGraphHandlerFromMutableGraph(
105
+ type: NodeTypeIdentifier,
106
+ mutable: MutableGraph
107
+ ): Promise<NodeHandlerObject | undefined> {
108
+ const nodeTypeUrl = graphUrlLike(type)
109
+ ? getGraphUrl(type, contextFromMutableGraph(mutable))
110
+ : undefined;
111
+ if (!nodeTypeUrl) {
112
+ return undefined;
113
+ }
114
+ const store = mutable.store;
115
+ const result = store.addByURL(type, [], {
116
+ outerGraph: mutable.graph,
117
+ });
118
+ const latest = await store.getLatest(result.mutable);
119
+ return new GraphBasedNodeHandler(
120
+ {
121
+ graph: latest.graph,
122
+ subGraphId: result.graphId,
123
+ moduleId: result.moduleId,
124
+ },
125
+ type
126
+ );
127
+ }
128
+
129
+ export async function getGraphHandler(
130
+ type: NodeTypeIdentifier,
131
+ context: NodeHandlerContext,
132
+ allow3PModules = false
133
+ ): Promise<NodeHandlerObject | undefined> {
134
+ if (is3pModule(type) && !allow3PModules) {
135
+ return undefined;
136
+ }
137
+ const nodeTypeUrl = graphUrlLike(type)
138
+ ? getGraphUrl(type, context)
139
+ : undefined;
140
+ if (!nodeTypeUrl) {
141
+ return undefined;
142
+ }
143
+ const { graphStore } = context;
144
+ if (!graphStore) {
145
+ throw new Error(
146
+ `Cannot load graph for type "${type}" without a graph store.`
147
+ );
148
+ }
149
+
150
+ const loadResult = await graphStore.load(type, context);
151
+ if (!loadResult.success) {
152
+ throw new Error(
153
+ `Loading graph for type "${type}" failed: ${loadResult.error}`
154
+ );
155
+ }
156
+ return new GraphBasedNodeHandler(loadResult, type);
157
+ }
158
+
159
+ /**
160
+ * This is a somewhat hacky module invocation filter.
161
+ * TODO: Instead of hard-coding the type, plumb the invocationFilter from
162
+ * the configuration here.
163
+ */
164
+ function is3pModule(type: NodeTypeIdentifier) {
165
+ return !type.startsWith("embed://");
166
+ }
@@ -0,0 +1,22 @@
1
+ // @ts-nocheck
2
+ /**
3
+ * @license
4
+ * Copyright 2023 Google LLC
5
+ * SPDX-License-Identifier: Apache-2.0
6
+ */
7
+
8
+ import type { Probe, ProbeMessage } from "@breadboard-ai/types";
9
+
10
+ export type DiagnosticsCallback = (message: ProbeMessage) => Promise<void>;
11
+
12
+ export class Diagnostics implements Probe {
13
+ #callback: DiagnosticsCallback;
14
+
15
+ constructor(callback: DiagnosticsCallback) {
16
+ this.#callback = callback;
17
+ }
18
+
19
+ async report(message: ProbeMessage): Promise<void> {
20
+ return this.#callback(message);
21
+ }
22
+ }