diff --git a/seeds/breadboard/src/core.ts b/seeds/breadboard/src/core.ts deleted file mode 100644 index 8e46b567..00000000 --- a/seeds/breadboard/src/core.ts +++ /dev/null @@ -1,18 +0,0 @@ -/** - * @license - * Copyright 2023 Google LLC - * SPDX-License-Identifier: Apache-2.0 - */ - -import type { NodeHandlers } from "./types.js"; -import lambda from "./nodes/lambda.js"; - -export class Core { - handlers: NodeHandlers; - - constructor() { - this.handlers = { - lambda, - }; - } -} diff --git a/seeds/breadboard/src/index.ts b/seeds/breadboard/src/index.ts index 1078c7ac..b5636b59 100644 --- a/seeds/breadboard/src/index.ts +++ b/seeds/breadboard/src/index.ts @@ -7,6 +7,7 @@ export { Board } from "./board.js"; export { BoardRunner } from "./runner.js"; export { Node } from "./node.js"; +export { SchemaBuilder } from "./schema.js"; export { LogProbe } from "./log.js"; export { DebugProbe } from "./debug.js"; export { RunResult } from "./run.js"; @@ -40,15 +41,17 @@ export type { BreadboardSlotSpec, BreadboardNode, BreadboardCapability, + BreadboardRunner, NodeHandlerContext, OptionalIdConfiguration, NodeConfigurationConstructor, LambdaFunction, + LambdaNodeInputs, ConfigOrLambda, RunResultType, KitConstructor, GenericKit, - LambdaNodeOutputs, + LambdaNodeOutputs } from "./types.js"; export { TraversalMachine } from "./traversal/machine.js"; export { MachineResult } from "./traversal/result.js"; diff --git a/seeds/breadboard/src/nodes/lambda.ts b/seeds/breadboard/src/nodes/lambda.ts deleted file mode 100644 index 51049b27..00000000 --- a/seeds/breadboard/src/nodes/lambda.ts +++ /dev/null @@ -1,50 +0,0 @@ -/** - * @license - * Copyright 2023 Google LLC - * SPDX-License-Identifier: Apache-2.0 - */ - -import { - GraphDescriptor, - InputValues, - LambdaNodeInputs, - LambdaNodeOutputs, -} from "../types.js"; -import { Board } from "../board.js"; -import { SchemaBuilder } from "../schema.js"; - -export default { - describe: async (inputs?: InputValues) => ({ - inputSchema: new SchemaBuilder() - .setAdditionalProperties(true) - .addInputs(inputs) - .addProperty("board", { - title: "board", - description: "The board to run.", - type: "object", - }) - .build(), - outputSchema: new SchemaBuilder() - .addProperty("board", { - title: "board", - description: "The now-runnable board.", - type: "object", - }) - .build(), - }), - invoke: async (inputs: InputValues): Promise => { - const { board, ...args } = inputs as LambdaNodeInputs; - if (!board || board.kind !== "board" || !board.board) - throw new Error( - `Lambda node requires a BoardCapability as "board" input` - ); - const runnableBoard = { - ...(await Board.fromBreadboardCapability(board)), - args, - }; - - return { - board: { ...board, board: runnableBoard as GraphDescriptor }, - }; - }, -}; diff --git a/seeds/breadboard/src/runner.ts b/seeds/breadboard/src/runner.ts index 63f29839..5bec4046 100644 --- a/seeds/breadboard/src/runner.ts +++ b/seeds/breadboard/src/runner.ts @@ -20,10 +20,11 @@ import type { NodeHandlerContext, ProbeDetails, BreadboardCapability, + LambdaNodeInputs, + LambdaNodeOutputs, } from "./types.js"; import { TraversalMachine } from "./traversal/machine.js"; -import { Core } from "./core.js"; import { BeforeHandlerStageResult, InputStageResult, @@ -34,6 +35,7 @@ import { BoardLoader } from "./loader.js"; import { runRemote } from "./remote.js"; import { callHandler } from "./handler.js"; import { toMermaid } from "./mermaid.js"; +import { SchemaBuilder } from "./schema.js"; class ProbeEvent extends CustomEvent { constructor(type: string, detail: ProbeDetails) { @@ -184,8 +186,8 @@ export class BoardRunner implements BreadboardRunner { shouldInvokeHandler ? callHandler(handler, inputs, newContext) : beforehandlerDetail.outputs instanceof Promise - ? beforehandlerDetail.outputs - : Promise.resolve(beforehandlerDetail.outputs) + ? beforehandlerDetail.outputs + : Promise.resolve(beforehandlerDetail.outputs) ) as Promise; outputsPromise.then((outputs) => { @@ -354,13 +356,14 @@ export class BoardRunner implements BreadboardRunner { return runnableBoard; } - static async handlersFromBoard( board: BoardRunner, upstreamKits: Kit[] = [] ): Promise { - const core = new Core(); + + const core = new Core() const kits = [core, ...upstreamKits, ...board.kits]; + return kits.reduce((handlers, kit) => { // If multiple kits have the same handler, the kit earlier in the list // gets precedence, including upstream kits getting precedence over kits @@ -373,3 +376,49 @@ export class BoardRunner implements BreadboardRunner { static runRemote = runRemote; } + +// HACK: Move the Core and Lambda logic into the same file as the BoardRunner to remove the cyclic module dependency (Lambda needs BoardRunner, BoardRunner needs Core). +class Core { + handlers: NodeHandlers; + + constructor() { + this.handlers = + { + "lambda": { + describe: async (inputs?: InputValues) => ({ + inputSchema: new SchemaBuilder() + .setAdditionalProperties(true) + .addInputs(inputs) + .addProperty("board", { + title: "board", + description: "The board to run.", + type: "object", + }) + .build(), + outputSchema: new SchemaBuilder() + .addProperty("board", { + title: "board", + description: "The now-runnable board.", + type: "object", + }) + .build(), + }), + invoke: async (inputs: InputValues): Promise => { + const { board, ...args } = inputs as LambdaNodeInputs; + if (!board || board.kind !== "board" || !board.board) + throw new Error( + `Lambda node requires a BoardCapability as "board" input` + ); + const runnableBoard = { + ...(await BoardRunner.fromBreadboardCapability(board)), + args, + }; + + return { + board: { ...board, board: runnableBoard as GraphDescriptor }, + }; + }, + } + }; + } +}