Skip to content

Commit

Permalink
Merge branch 'google:main' into add-lint-fix-and-format-scripts
Browse files Browse the repository at this point in the history
  • Loading branch information
Mearman authored Nov 9, 2023
2 parents dda32cc + 57cae64 commit 538cdf2
Show file tree
Hide file tree
Showing 29 changed files with 640 additions and 206 deletions.
4 changes: 1 addition & 3 deletions DEVELOPING.md
Original file line number Diff line number Diff line change
Expand Up @@ -225,9 +225,7 @@ Currently, to publish an NPM package, you have to be a Googler. This is unlikely

```bash
git pull
npm run clean:build
npm i
npx turbo build
npm run sync
```

2. Change directory to the package to be published. For example:
Expand Down
15 changes: 8 additions & 7 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion seeds/breadboard-server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,6 @@
},
"dependencies": {
"@google-cloud/firestore": "^6.7.0",
"@google-labs/breadboard": "^0.4.1"
"@google-labs/breadboard": "^0.5.0"
}
}
2 changes: 0 additions & 2 deletions seeds/breadboard-web/tests/async-gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,9 @@
import { expect, test } from "vitest";
import {
LastMessageKeeper,
PatchedReadableStream,
asyncGen,
streamFromAsyncGen,
} from "../src/async-gen";
import { Readable } from "stream";

test("async-gen", async () => {
const results = [];
Expand Down
14 changes: 14 additions & 0 deletions seeds/breadboard/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
# Changelog

## [0.5.0] - 2023-11-08

- The `/ui` submodule changes:
- supports multiple simultaneous inputs
- does not ask for keys more than once per session
- if you specify `type: "object"` for an input, it will try to parse it as JSON data and pass as an object.
- draw Mermaid diagrams of the boards
- there's now a link to the running board in the UI.
- The `/worker` submodule changes:
- bug fixes (will actually queue received messages and not drop them on the floor)
- The following nodes moved out into the Core Kit: `passthrough`, `reflect`, `slot`, `include`, `import`, and `invoke`.
- The `run` method now takes a `NodeHandlerContext` object as its argument, rather than a list of arguments.
- Kits are no longer implicitly imported by Breadboard. Instead, supply loaded Kits as part `NodeHandlerContext` to `run`.

## [0.4.1] - 2023-10-20

- Moved the `mermaid` method to `BoardRunner`.
Expand Down
150 changes: 0 additions & 150 deletions seeds/breadboard/docs/nodes.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,59 +68,6 @@ result { say: 'Hello, world!' }
- none.
## The `passthrough` node
This is a no-op node. It takes the input property bag and passes it along as output, unmodified. This node can be useful when the board needs an entry point, but the rest of the board forms a cycle.
### Example:
```js
board.input().wire("say->", board.passthrough().wire("say->", board.output()));

board.runOnce({
say: "Hello, world!",
});

console.log("result", result);
```
Will produce this output:
```sh
result { say: 'Hello, world!' }
```
See [Chapter 9: Let's build a chatbot](https://github.com/google/labs-prototypes/tree/main/seeds/breadboard/docs/tutorial#chapter-9-lets-build-a-chat-bot) of Breadboard tutorial to see another example of usage.
### Inputs
- any properties
### Outputs
- the properties that were passed as inputs
## The `invoke` node
Use this node to invoke another board from this board.
It recognizes `path`, `graph`, and `board` properties that specify, respectively, a file path or URL to the serialized board, directly the serialized-as-JSON board, and a `BoardCapability` (returned by `lambda` or `import`).
The rest of the inputs in the property bag are passed along to the invoked board as its inputs. If other inputs were bound to the board via wires into the `lambda` or `import` node, then those have precedence over inputs passed here.
The outputs of the invoked board will be passed along as outputs of the `invoke` node.
### Inputs
- `path`, which specifes the file path or URL to the serialized board to be included.
- `graph`, which is a serialized board
- `board`, a `BoardCapability` representing a board, created by `lambda` or `import`.
- any other properties are passed as inputs for the invoked board.
### Outputs
- the outputs of the invoked board
## The `lambda` node
Use this node to create a lambda board that can be passed around and eventually invoked by e.g. the `invoke` node.
Expand Down Expand Up @@ -185,100 +132,3 @@ board.invoke({ board: lambda })
### Outputs
- `board`, a `BoardCapability`, which can be passed to `invoke` and other nodes that can invoke boards.
## The `import` node
Creates a lambda board from a pre-existing board, either loaded from `path` or passed as JSON via `graph`. All other inputs are bound to the board, which is returned as `board`.
### Inputs
- `path`, which specifes the file path or URL to the serialized board to be included.
- `graph`, which is a serialized board
- all other inputs are bound to the board
### Outputs
- `board`, a `BoardCapability`, which can be passed to `invoke` and other nodes that can invoke boards.
## The `include` node (DEPRECATED)
DEPRECATED: Use `invoke` instead
Use this node to include other board into the current board. It recognizes `path` or `$ref` properties that specify, respectively, file path or URL to the serialized-as-JSON board to be included. It also accepts the `slotted` property that must contain the serialized-as-JSON boards that will be slotted into the included board.
The rest of the inputs in the property bag are passed along to the included board as its inputs. The outputs of the included board will be passed along as outputs of the `include` node.
This enables treating the included board as a kind of a node: it takes inputs and provides outputs.
### Example
For an example of how to use the `include` property, see [Chapter 5: Including other boards](https://github.com/google/labs-prototypes/tree/main/seeds/breadboard/docs/tutorial#chapter-5-including-other-boards) of Breadboard tutorial.
### Inputs
- `path`, which specifes the file path to the serialized board to be included. Either this or `$ref` property is required.
- `$ref`, which specifes the URL of the serialized board to be included. Ether this or `path` property is required.
- `slotted`, which specifies slotted boards that will be used to populate `slot` nodes in the included board. This property is optional.
- any other properties are passed as inputs for the included board.
### Outputs
- the outputs of the included board
## The `slot` node (DEPRECATED)
DEPRECATED. Instead pass boards either as URLs or as Boards from `lambda` and `invoke` them.
Use this node to make a slot in a board. Adding a `slot` node turns a board into a sort of a template: each slot represents a placeholder that must be filled in when the node is included into another board.
The node takes a `slot` property, which specifies the name of the slot, and passes the rest of arguments to the slotted board. The value of the `slot` property is used to match the slot with one of the slotted board that is passed to the `include` node.
### Example
For an example of how to use the `slot` node, see [Chapter 6: Boards with slots](https://github.com/google/labs-prototypes/tree/main/seeds/breadboard/docs/tutorial#chapter-6-boards-with-slots) of Breadboard tutorial.
### Inputs
- `slot` - the name of the slot
- any other properties are passed as inputs for the slotted board
### Outputs
- the outputs of the included board
## The `reflect` node
This node is used to reflect the board itself. It has no required inputs and provides a JSON representation of the board as a `graph` output property. This node can be used for getting information that might be stored in the structure of the board.
### Example
```js
import { Board } from "@google-labs/breadboard";
const board = new Board();
board.input().wire("", board.reflect().wire("graph->", board.output()));
const result = await board.runOnce({});
console.log("result", result);
```
will print:
```sh
result {
graph: {
edges: [ [Object], [Object] ],
nodes: [ [Object], [Object], [Object] ],
kits: []
}
}
```
### Inputs
- ignored
### Outputs
- `graph` -- JSON representation of the board
2 changes: 1 addition & 1 deletion seeds/breadboard/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@google-labs/breadboard",
"version": "0.4.1",
"version": "0.5.0",
"description": "A library for rapid generative AI application prototyping",
"main": "./dist/src/index.js",
"exports": {
Expand Down
5 changes: 5 additions & 0 deletions seeds/breadboard/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,8 @@ export { toMermaid } from "./mermaid.js";
export type { Schema } from "jsonschema";
export { callHandler } from "./handler.js";
export { asRuntimeKit } from "./kits/ctors.js";
export {
StreamCapability,
isStreamCapability,
type StreamCapabilityType,
} from "./stream.js";
2 changes: 1 addition & 1 deletion seeds/breadboard/src/kits/graph-to-kit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
*/

import { callHandler } from "../handler.js";
import { KitBuilderOptions } from "./index.js";
import { KitBuilderOptions } from "./builder.js";
import { BoardRunner } from "../runner.js";
import {
GraphDescriptor,
Expand Down
57 changes: 57 additions & 0 deletions seeds/breadboard/src/stream.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/**
* @license
* Copyright 2023 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/

import type { Capability, NodeValue } from "./types.js";

const STREAM_KIND = "stream" as const;

export interface StreamCapabilityType<ChunkType = object> extends Capability {
kind: typeof STREAM_KIND;
stream: ReadableStream<ChunkType>;
}

export class StreamCapability<ChunkType>
implements StreamCapabilityType<ChunkType>
{
kind = STREAM_KIND;
stream: ReadableStream<ChunkType>;

constructor(stream: ReadableStream<ChunkType>) {
this.stream = stream;
}
}

export const isStreamCapability = (object: unknown) => {
const maybeStream = object as StreamCapabilityType;
return (
maybeStream.kind &&
maybeStream.kind === STREAM_KIND &&
maybeStream.stream instanceof ReadableStream
);
};

const findStreams = (value: NodeValue, foundStreams: ReadableStream[]) => {
if (Array.isArray(value)) {
value.forEach((item: NodeValue) => {
findStreams(item, foundStreams);
});
} else if (typeof value === "object") {
const maybeCapability = value as StreamCapabilityType;
if (maybeCapability.kind && maybeCapability.kind === STREAM_KIND) {
foundStreams.push(maybeCapability.stream);
} else {
Object.values(value as object).forEach((item) => {
findStreams(item, foundStreams);
});
}
}
};

export const getStreams = (value: NodeValue) => {
const foundStreams: ReadableStream[] = [];
findStreams(value, foundStreams);
return foundStreams;
};
21 changes: 21 additions & 0 deletions seeds/breadboard/src/ui/output.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
*/

import { type Schema } from "jsonschema";
import { StreamCapabilityType } from "../stream.js";

export type OutputArgs = Record<string, unknown> & {
schema: Schema;
Expand All @@ -30,9 +31,29 @@ export class Output extends HTMLElement {
return;
}
Object.entries(schema.properties).forEach(([key, property]) => {
if (property.type === "object" && property.format === "stream") {
this.appendStream(
property,
(values[key] as StreamCapabilityType).stream
);
return;
}
const html = document.createElement("pre");
html.innerHTML = `${values[key]}`;
root.append(`${property.title}: `, html, "\n");
});
}

appendStream(property: Schema, stream: ReadableStream) {
const root = this.shadowRoot;
if (!root) return;
root.append(`${property.title}: `);
stream.pipeThrough(new TextDecoderStream()).pipeTo(
new WritableStream({
write(chunk) {
root.append(chunk);
},
})
);
}
}
Loading

0 comments on commit 538cdf2

Please sign in to comment.