@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,118 @@
1
+ // @ts-nocheck
2
+ /**
3
+ * @license
4
+ * Copyright 2024 Google LLC
5
+ * SPDX-License-Identifier: Apache-2.0
6
+ */
7
+
8
+ import * as idb from "idb";
9
+ import * as BreadboardUI from "../ui/index.js";
10
+ import { SignalArray } from "signal-utils/array";
11
+ import { SignalObject } from "signal-utils/object";
12
+ import { RecentBoard } from "../ui/types/types.js";
13
+
14
+ interface RecentBoardsDB extends idb.DBSchema {
15
+ boards: {
16
+ key: "recent";
17
+ value: BreadboardUI.Types.RecentBoard[];
18
+ };
19
+ }
20
+
21
+ const RECENT_BOARDS_NAME = "recent-boards";
22
+ const RECENT_BOARDS_VERSION = 3;
23
+
24
+ export class RecentBoardStore {
25
+ static #instance: RecentBoardStore;
26
+ static instance() {
27
+ if (!this.#instance) {
28
+ this.#instance = new RecentBoardStore();
29
+ }
30
+ return this.#instance;
31
+ }
32
+
33
+ readonly boards = new SignalArray<RecentBoard>();
34
+
35
+ // Not instantiated directly.
36
+ private constructor() {}
37
+
38
+ async add(board: RecentBoard) {
39
+ const index = this.boards.findIndex((b) => b.url === board.url);
40
+ if (index !== -1) {
41
+ const [existing] = this.boards.splice(index, 1);
42
+ if (board.title) {
43
+ existing.title = board.title;
44
+ }
45
+ this.boards.unshift(existing);
46
+ } else {
47
+ this.boards.unshift(board);
48
+ }
49
+
50
+ if (this.boards.length > 50) {
51
+ this.boards.length = 50;
52
+ }
53
+
54
+ await this.#store();
55
+ }
56
+
57
+ async remove(url: string) {
58
+ const index = this.boards.findIndex((b) => b.url === url);
59
+ if (index !== -1) {
60
+ this.boards.splice(index, 1);
61
+ await this.#store();
62
+ }
63
+ }
64
+
65
+ async setPin(url: string, pinned: boolean) {
66
+ const board = this.boards.find((b) => b.url === url);
67
+ if (board) {
68
+ board.pinned = pinned;
69
+ await this.#store();
70
+ }
71
+ }
72
+
73
+ async #store() {
74
+ const recentBoardsDb = await idb.openDB<RecentBoardsDB>(
75
+ RECENT_BOARDS_NAME,
76
+ RECENT_BOARDS_VERSION
77
+ );
78
+
79
+ // Flatten the SignalArray back down so that it can be stored in IDB.
80
+ const storeBoards = [];
81
+ for (const board of this.boards) {
82
+ storeBoards.push({
83
+ title: board.title,
84
+ url: board.url,
85
+ pinned: board.pinned ?? false,
86
+ });
87
+ }
88
+ recentBoardsDb.put("boards", storeBoards, "recent");
89
+ }
90
+
91
+ async restore(): Promise<void> {
92
+ const recentBoardsDb = await idb.openDB<RecentBoardsDB>(
93
+ RECENT_BOARDS_NAME,
94
+ RECENT_BOARDS_VERSION,
95
+ {
96
+ upgrade(db) {
97
+ if (db.objectStoreNames.contains("boards")) return;
98
+ db.createObjectStore("boards");
99
+ },
100
+ }
101
+ );
102
+
103
+ const boards = await recentBoardsDb.get("boards", "recent");
104
+ if (!boards) {
105
+ return;
106
+ }
107
+
108
+ for (const board of boards) {
109
+ this.boards.push(
110
+ new SignalObject({
111
+ url: board.url,
112
+ title: board.title,
113
+ pinned: board.pinned ?? false,
114
+ })
115
+ );
116
+ }
117
+ }
118
+ }
@@ -0,0 +1,104 @@
1
+ // @ts-nocheck
2
+ /**
3
+ * @license
4
+ * Copyright 2025 Google LLC
5
+ * SPDX-License-Identifier: Apache-2.0
6
+ */
7
+
8
+ import {
9
+ DataPart,
10
+ InlineDataCapabilityPart,
11
+ Outcome,
12
+ OutputValues,
13
+ } from "@breadboard-ai/types";
14
+ import { isLLMContentArray } from "./common.js";
15
+ import { createZip } from "littlezipper";
16
+
17
+ export { saveOutputsAsFile, extensionFromMimeType };
18
+
19
+ const COMMON_FILE_EXTENSIONS: ReadonlyMap<string, string> = new Map([
20
+ ["text/plain", "txt"],
21
+ ["text/html", "html"],
22
+ ["text/css", "css"],
23
+ ["text/javascript", "js"],
24
+ ["text/csv", "csv"],
25
+ ["text/xml", "xml"],
26
+ ["text/markdown", "md"],
27
+ ["application/json", "json"],
28
+ ["application/ld+json", "jsonld"],
29
+ ["image/jpeg", "jpg"],
30
+ ["image/png", "png"],
31
+ ["audio/mpeg", "mp3"],
32
+ ["video/mp4", "mp4"],
33
+ ["video/webm", "webm"],
34
+ ["application/pdf", "pdf"],
35
+ ]);
36
+
37
+ function extensionFromMimeType(mimeType: string): string {
38
+ if (!mimeType) {
39
+ return "";
40
+ }
41
+ const normalizedMimeType = mimeType.toLowerCase().split(";")[0].trim();
42
+ return COMMON_FILE_EXTENSIONS.get(normalizedMimeType) || "";
43
+ }
44
+
45
+ type FileData = InlineDataCapabilityPart["inlineData"];
46
+
47
+ async function saveOutputsAsFile(
48
+ outputs: OutputValues
49
+ ): Promise<Outcome<Blob>> {
50
+ const parts: DataPart[] = [];
51
+ for (const value of Object.values(outputs)) {
52
+ if (isLLMContentArray(value)) {
53
+ for (const content of value) {
54
+ parts.push(...content.parts);
55
+ }
56
+ } else {
57
+ parts.push({ text: JSON.stringify(value) });
58
+ }
59
+ }
60
+ const files: FileData[] = [];
61
+ for (const part of parts) {
62
+ if ("text" in part) {
63
+ files.push({ mimeType: "text/markdown", data: part.text });
64
+ } else if ("inlineData" in part) {
65
+ files.push(part.inlineData);
66
+ }
67
+ }
68
+ if (files.length === 1) {
69
+ // just save one file
70
+ const file = files[0];
71
+ return new Blob([encode(file)], { type: file.mimeType });
72
+ }
73
+ const zip = await createZip(
74
+ files.map((file, index) => ({
75
+ path: getFilename(file.mimeType, index + 1),
76
+ data: encode(file),
77
+ }))
78
+ );
79
+ return new Blob([new Uint8Array(zip.buffer as ArrayBuffer)], {
80
+ type: "application/zip",
81
+ });
82
+ }
83
+
84
+ function getFilename(mimeType: string, index: number) {
85
+ return `file-${index}.${extensionFromMimeType(mimeType)}`;
86
+ }
87
+
88
+ function encode(file: FileData) {
89
+ const { mimeType: type, data } = file;
90
+ if (type.startsWith("text/")) {
91
+ return data;
92
+ }
93
+ return b64toBlob(data);
94
+ }
95
+
96
+ function b64toBlob(s: string) {
97
+ const binaryString = atob(s);
98
+ const len = binaryString.length;
99
+ const bytes = new Uint8Array(len);
100
+ for (let i = 0; i < len; i++) {
101
+ bytes[i] = binaryString.charCodeAt(i);
102
+ }
103
+ return bytes;
104
+ }
@@ -0,0 +1,168 @@
1
+ // @ts-nocheck
2
+ /**
3
+ * @license
4
+ * Copyright 2024 Google LLC
5
+ * SPDX-License-Identifier: Apache-2.0
6
+ */
7
+
8
+ import { CapabilitiesManagerImpl } from "./runtime/legacy.js";
9
+ import type {
10
+ InputValues,
11
+ Kit,
12
+ MutableGraph,
13
+ NodeDescriberContext,
14
+ NodeDescriberResult,
15
+ NodeHandlerContext,
16
+ NodeHandlerObject,
17
+ Schema,
18
+ } from "@breadboard-ai/types";
19
+ import { err, ok } from "@breadboard-ai/utils";
20
+ import { RunnableModuleFactory } from "@breadboard-ai/types/sandbox.js";
21
+ import { Telemetry } from "./telemetry.js";
22
+
23
+ export { addRunModule };
24
+
25
+ /**
26
+ * This is likely too limiting and crude for the long term, but it works well
27
+ * for the specific use case we need right now.
28
+ *
29
+ * In the future, I am imagining something like a capability attenuator, which
30
+ * allows tuning capabilities for each invoked module, including module
31
+ * invocation itself.
32
+ */
33
+
34
+ function findHandler(handlerName: string, kits?: Kit[]) {
35
+ const handler = kits
36
+ ?.flatMap((kit) => Object.entries(kit.handlers))
37
+ .find(([name]) => name === handlerName)
38
+ ?.at(1);
39
+
40
+ return handler;
41
+ }
42
+
43
+ function addRunModule(factory: RunnableModuleFactory, kits: Kit[]): Kit[] {
44
+ const existingRunModule = findHandler("runModule", kits);
45
+ const originalDescriber =
46
+ (existingRunModule &&
47
+ typeof existingRunModule !== "string" &&
48
+ "describe" in existingRunModule
49
+ ? existingRunModule.describe
50
+ : undefined) ??
51
+ (() => ({
52
+ outputSchema: {},
53
+ inputSchema: {},
54
+ }));
55
+
56
+ return [
57
+ {
58
+ url: import.meta.url,
59
+ handlers: {
60
+ runModule: {
61
+ invoke: async ({ $module, ...inputs }, context) => {
62
+ const graph = context.outerGraph;
63
+
64
+ const moduleDeclaration = graph?.modules;
65
+ if (!moduleDeclaration) {
66
+ return {
67
+ $error: `Unable to run module: no modules found within board ${context.board?.url || "uknown board"}`,
68
+ };
69
+ }
70
+ const telemetry = Telemetry.create(context);
71
+ const mutable = await getMutableGraph(context);
72
+ if (!mutable) {
73
+ return err(`Unable to create runnable module: invalid graph`);
74
+ }
75
+
76
+ const module = await factory.createRunnableModule(
77
+ mutable,
78
+ graph,
79
+ context,
80
+ new CapabilitiesManagerImpl(context)
81
+ );
82
+ if (!ok(module)) {
83
+ return err(`Unable to create runnable module: ${module.$error}`);
84
+ }
85
+
86
+ const result = await module.invoke(
87
+ $module as string,
88
+ inputs,
89
+ telemetry
90
+ );
91
+ return result as InputValues;
92
+ },
93
+ describe: async (
94
+ inputs?: InputValues,
95
+ inputSchema?: Schema,
96
+ outputSchema?: Schema,
97
+ /**
98
+ * The context in which the node is described.
99
+ */
100
+ context?: NodeDescriberContext
101
+ ) => {
102
+ const { $module } = inputs || {};
103
+ if (context) {
104
+ const graph = context.outerGraph;
105
+ const moduleDeclaration = graph?.modules;
106
+ if ($module && moduleDeclaration) {
107
+ const mutable = await getMutableGraph(context);
108
+ if (mutable) {
109
+ const module = await factory.createRunnableModule(
110
+ mutable,
111
+ graph,
112
+ context
113
+ );
114
+ if (ok(module)) {
115
+ try {
116
+ const result = (await module.describe($module as string, {
117
+ inputs,
118
+ inputSchema,
119
+ outputSchema,
120
+ })) as NodeDescriberResult;
121
+ return {
122
+ inputSchema: {
123
+ type: "object",
124
+ properties: {
125
+ $module: {
126
+ type: "string",
127
+ title: "Module ID",
128
+ behavior: ["config", "module"],
129
+ },
130
+ ...result.inputSchema.properties,
131
+ },
132
+ },
133
+ outputSchema: result.outputSchema,
134
+ };
135
+ } catch {
136
+ // swallow the error. It's okay that some modules don't have
137
+ // custom describers.
138
+ }
139
+ }
140
+ }
141
+ }
142
+ }
143
+
144
+ return originalDescriber(
145
+ inputs,
146
+ inputSchema,
147
+ outputSchema,
148
+ context
149
+ );
150
+ },
151
+ } satisfies NodeHandlerObject,
152
+ },
153
+ },
154
+ ...kits,
155
+ ];
156
+ }
157
+
158
+ async function getMutableGraph(
159
+ context: NodeHandlerContext
160
+ ): Promise<MutableGraph | undefined> {
161
+ if (!context.graphStore) return;
162
+ const { graphStore, outerGraph } = context;
163
+ if (!outerGraph) return;
164
+ const mainGraphId = graphStore.getByDescriptor(outerGraph);
165
+ if (!mainGraphId.success) return;
166
+
167
+ return graphStore.getLatest(graphStore.get(mainGraphId.result)!);
168
+ }
@@ -0,0 +1,65 @@
1
+ // @ts-nocheck
2
+ /**
3
+ * @license
4
+ * Copyright 2024 Google LLC
5
+ * SPDX-License-Identifier: Apache-2.0
6
+ */
7
+
8
+ import type { GraphDescriptor, GraphTag, Schema } from "@breadboard-ai/types";
9
+
10
+ const llmContentConfig = (type: string) => ({
11
+ schema: {
12
+ properties: {
13
+ context: {
14
+ type: "array",
15
+ title: "Context",
16
+ items: {
17
+ type: "object",
18
+ behavior: ["llm-content"],
19
+ },
20
+ default:
21
+ type === "input" ? '[{"role":"user","parts":[{"text":""}]}]' : "null",
22
+ },
23
+ },
24
+ type: "object",
25
+ required: [],
26
+ } satisfies Schema,
27
+ });
28
+
29
+ const BLANK_GRAPH: GraphDescriptor = {
30
+ title: "Untitled Flow",
31
+ description: "",
32
+ version: "0.0.1",
33
+ nodes: [],
34
+ edges: [],
35
+ };
36
+
37
+ const BLANK_LLM_CONTENT_GRAPH: GraphDescriptor = {
38
+ title: "Untitled Flow",
39
+ description: "",
40
+ version: "0.0.1",
41
+ nodes: [
42
+ { type: "input", id: "input", configuration: llmContentConfig("input") },
43
+ { type: "output", id: "output", configuration: llmContentConfig("output") },
44
+ ],
45
+ edges: [{ from: "input", out: "context", to: "output", in: "context" }],
46
+ };
47
+
48
+ /**
49
+ * Creates a `GraphDescriptor` of a blank graph.
50
+ */
51
+ export const blank = (): GraphDescriptor => {
52
+ return structuredClone(BLANK_GRAPH);
53
+ };
54
+
55
+ /**
56
+ * Creates a `GraphDescriptor` of a blank graph with inputs/outputs pre-set
57
+ * to the LLM content array schema.
58
+ */
59
+ export const blankLLMContent = (...tags: GraphTag[]): GraphDescriptor => {
60
+ const graph = structuredClone(BLANK_LLM_CONTENT_GRAPH);
61
+ if (tags.length) {
62
+ graph.metadata = { tags };
63
+ }
64
+ return graph;
65
+ };
@@ -0,0 +1,27 @@
1
+ // @ts-nocheck
2
+ /**
3
+ * @license
4
+ * Copyright 2024 Google LLC
5
+ * SPDX-License-Identifier: Apache-2.0
6
+ */
7
+
8
+ import type { EditableEdgeSpec, GraphDescriptor } from "@breadboard-ai/types";
9
+
10
+ export const findEdgeIndex = (
11
+ graph: GraphDescriptor,
12
+ spec: EditableEdgeSpec
13
+ ) => {
14
+ return graph.edges.findIndex((edge) => {
15
+ return edgesEqual(spec, edge);
16
+ });
17
+ };
18
+
19
+ export const edgesEqual = (a: EditableEdgeSpec, b: EditableEdgeSpec) => {
20
+ return (
21
+ a.from === b.from &&
22
+ a.to === b.to &&
23
+ a.out === b.out &&
24
+ a.in === b.in &&
25
+ b.constant === b.constant
26
+ );
27
+ };
@@ -0,0 +1,64 @@
1
+ // @ts-nocheck
2
+ /**
3
+ * @license
4
+ * Copyright 2024 Google LLC
5
+ * SPDX-License-Identifier: Apache-2.0
6
+ */
7
+
8
+ import type {
9
+ AffectedNode,
10
+ ChangeEventType,
11
+ ErrorRejection,
12
+ GraphChangeEvent,
13
+ GraphChangeRejectEvent,
14
+ GraphDescriptor,
15
+ GraphIdentifier,
16
+ NoChangeRejection,
17
+ NodeIdentifier,
18
+ } from "@breadboard-ai/types";
19
+
20
+ /**
21
+ * This event is dispatched whenever the graph changes due to edits.
22
+ */
23
+ export class ChangeEvent extends Event implements GraphChangeEvent {
24
+ static eventName = "graphchange";
25
+
26
+ constructor(
27
+ public readonly graph: GraphDescriptor,
28
+ public readonly visualOnly: boolean,
29
+ public readonly changeType: ChangeEventType,
30
+ public readonly affectedNodes: AffectedNode[],
31
+ public readonly affectedModules: NodeIdentifier[],
32
+ public readonly affectedGraphs: GraphIdentifier[],
33
+ public readonly topologyChange: boolean,
34
+ public readonly integrationsChange: boolean,
35
+ public readonly label: string | null
36
+ ) {
37
+ super(ChangeEvent.eventName, {
38
+ bubbles: false,
39
+ cancelable: true,
40
+ composed: true,
41
+ });
42
+ }
43
+ }
44
+
45
+ /**
46
+ * This event is dispatched whenever a proposed change to the graph is
47
+ * rejected. The rejection may happen for two reasons
48
+ * - error: the change would create an invalid graph. For instance, adding an edge to a non-existent node.
49
+ * - nochange: the change is unnecessary, because it results in no actual change to the graph. For example, adding an edge that already exists.
50
+ */
51
+ export class ChangeRejectEvent extends Event implements GraphChangeRejectEvent {
52
+ static eventName = "graphchangereject";
53
+
54
+ constructor(
55
+ public graph: GraphDescriptor,
56
+ public reason: ErrorRejection | NoChangeRejection
57
+ ) {
58
+ super(ChangeRejectEvent.eventName, {
59
+ bubbles: false,
60
+ cancelable: true,
61
+ composed: true,
62
+ });
63
+ }
64
+ }