Core Kit
This is the kit that provides the most fundamental building blocks for Breadboard. The component it provides tend to be fairly low-level. Think of these components as indivisible atoms of Breadboard universe, or as the plumbing that makes everything run. Many of the other components (all of the Agent Kit components, for example) are created by wiring using these together.
Tip
Most of these components are closer to actual programming than just dragging and dropping high-level components. Expect climbing a learning curve to get comfortable using them.
cast
component
The Takes any kind of value and forces its schema to be the given JSON Schema.
Input ports
The cast
component has two input ports:
- Value (id:
value
) — Any kind of value. - Type (id:
type
) — The JSON schema to castvalue
to.
Output ports
The cast
component has a single output port:
- Value (id
value
) — The unmodifiedvalue
input, but now withtype
as its schema.
Example
In the board above, a URL is fetched which responds with an object containing
properties foo
and bar
. Since the fetch
component doesn't intrinsically
know what the response type of any given request will be, by default it will be
typed as unknown
. By wiring the response to a cast
node, we can assert to
Breadboard what the expected response type is.
Implementation
curry
component
The Takes a board and bakes in (or curries, using the computer science term) the supplied port inputs into it. Very useful when we want to invoke a board with the same input values many times (like with map
).
Input ports
The curry
component has a single input port plus any number of additional ports.
- Board (id:
$board
) -- the board to curry the values into. This port has theboard
behavior and will accept a URL of the board or the actual BGL of the board.
Values supplied with any additional ports will be curried into the output board.
Output ports
The component has a single output port.
- Board (id:
board
) -- the resulting curried board.
Example
Let's suppose that we have this board that creates a simple greeting given a name and location, using the promptTemplate
component.
If we need to print out a set of greetings for a bunch of people visiting from the same location, we can use the curry
component to bake the Location information into the board and then call it multiple times with a different name.
Tip
The curry
component is also useful for introspecting boards: you can use it to load a board via a URL and then examine the output as BGL.
Implementation
deflate
component
The This component converts all inline data to stored data, saving memory. Useful when working with multimodal content.
Input ports
The component has a single input port.
- Data (id:
data
) -- the data to scan and convert all instances of inline base64-encoded strings to lightweight handles. Data can be of any shape.
Output ports
The component has a single output port.
- Data (id:
data
) -- the result of deflating the input data. Safely passes data through if it's already stored or no inline data is present.
Example
In the board above, a chunk of JSON is fetched. This JSON contains a base64-encoded string of an image. The deflate
component turns it into a lightweight handle and then passes it on to output.
Implementation
fetch
component
The Use this component to fetch data from the Internet. Implementation-wise, this is a wrapper around Fetch API with a few Breadboard-specific tweaks.
The tweaks are:
-
When "Content-Type" is specified as "multipart/form-data", the value passed into the Body port is treated as a key/value object representing FormData properties and their values.
-
Before sending the request, all Data store lightweight handles are converted to base64 encoded strings or multipart encoded chunks, depending on the content type.
-
After receiving the response, any blob responses are converted to Data Store lightweight handles.
Input ports
The component has the following input ports.
-
URL (id:
url
) -- required, the URL to fetch. -
Method (id:
method
) -- string (optional), the request method. Default isGET
. -
Headers (id:
headers
) -- object (optional), a set of request headers. Default is empty. -
Body (id:
body
) -- object (optional), the request body. Default is empty. -
Raw (id:
raw
) -- boolean (optional), specifies whether or not to return raw text (true
) or parse the response as JSON (false
). The default value isfalse
. -
Stream (id:
stream
) -- boolean (optional), specifies whether the response is expected to be a stream. The default value isfalse
.
Output ports
-
Content Type (id: 'contentType') -- contains response content type.
-
Response (id:
response
) -- the response from the server. Ifraw
isfalse
(which it is by default) and content type isapplication/json
, the response will be parsed as JSON. -
Response Headers (id:
responseHeaders
) -- contains response headers. -
Status (id:
status
) -- contains response status code -
Status Text (id:
statusText
) -- contains response status text.
Example
In the board above, the fetch
component makes a call to Wikipedia open search API and then passes the response to the output.
Implementation
inflate
component
The Does opposite of what the deflate
component does. Scans provided data and converts all lightweight handles to inline, base64 encoded strings.
Input ports
The component has a single input port.
- Data (id:
data
) -- the data to scan and convert all instances of lightweight handles to inline base64-encoded strings. Data can be of any shape.
Output ports
The component has a single output port.
- Data (id:
data
) -- the result of inflating the input data. Safely passes data through if it's already inline or no stored data is present.
Example
In the board above, any multimedia content supplied as input will be turned into base64-encoded strings.
Implementation
invoke
component
The Invokes (using "run as component" runtime mode) specified board, supplying remaining incoming wires as input ports for that board. Returns the outputs of the board as its own output ports.
Use this component to invoke another board from your board.
Input ports
This component has a single static input port and multiple dynamic ports.
-
Board (id:
$board
) -- required, a board to run. The board can be specified as a URL to the BGL file, or as BGL directly. -
all other wired in ports are passed as the input values for the board.
Output ports
The output ports of this component are the outputs of the invoked board.
Example
In the board above, the invoke
component is used to invoke this board:
Following the semantics of the "run as component" mode, all inputs of the invoked board are populated by the input ports of the invoke
component input ports, and all outputs of the invoked board are passed as output ports.
Tip
Note how "Name" and "Location" input ports, as well as the "Greeting" output ports pop up in the Visual Editor when the "Board" input port is populated. This is the key property of the "run as component" mode: the board API is declarative and can be statically described.
Implementation
map
component
The Given a list items and a board, runs the board in "run as component" mode for each item in the list. Similar in to JavaScript Array.prototype.map function, except boards run in parallel.
When running the board, the map
component will supply three inputs with these ids:
item
-- the item from the listindex
-- the index of the item in the listlist
-- the entire list.
This very is similar to the arguments of the JavaScript Array.prototype.map function.
Input ports
The component has two statically defined input ports:
-
Board (id:
board
) -- required, a board to run. The board can be specified as a URL to the BGL file, or as BGL directly. -
List (id:
list
) -- optional, an array of items to supply to the board as inputs.
Output ports
The component has one statically defined output port:
- List (id:
list
) -- optional, an array of results from each board's run.
Example
Given this board that creates a simple greeting given a name and location:
We can use the map
component to print out a set of greetings for a bunch of people.
Tip
The curry
component and map
component often go hand in hand, just like in the example above. Currying provides a convenient way to pass unchanging arguments to the board that is being invoked multiple times via map
.
Implementation
passthrough
component
The This is a no-op component. It takes the input port values and passes them along as output port values, unmodified. Just like any no-op statement in programming, this component comes in handy in various situations, like when the board needs an entry point, but the rest of the board forms a cycle.
Input ports
- any ports that are wired in.
Output ports
- the mirror of the ports wired in.
Implementation
reduce
component
The Given a list, an initial accumulator value, and a board, invokes a board in "run as component" mode for each item and accumulator in the list, returning the final accumulator value. Loosely, same logic as the Array.prototype.reduce
function in JavaScript.
When running the board, the reduce
component will supply input values with the following ids:
accumulator
-- the current accumulated resultitem
-- the item in the list
In the outputs, it will look for the output values with the following ids:
accumulator
-- the new accumulated result.
Input ports
The reduce
component has three static input ports:
-
Accumulator (id:
accumulator
) -- optional, the initial value of the accumulator that will be supplied along with the first item in the list. -
Board (id:
board
) -- required, a board to run. The board can be specified as a URL to the BGL file, or as BGL directly. -
List (id:
list
) -- optional, a list to reduce over.
Output ports
The component has one static output port:
- Accumulator (id:
accumulator
) -- the final accumulated value.
Example
Let's suppose we want to research a few topics on Wikipedia, and get a bunch of links for each topic. First, we'll build a board that fits the shape required by the reduce
component. This board will query Wikipedia for one topic.
Then, we can use another board that makes it run over a list of topics using the reduce
component.
Implementation
runJavascript
component
The Use this component to execute JavaScript code. It is particularly useful for manipulating data between other components or adding other kinds of logic to your boards.
Note
The code is executed in a new V8 context in component or a Web Worker in the browser, which means that it cannot access any variables or functions from outside the context in which it is run.
The key input port is Code, which contains the code to execute. The code must be a JS function. When the component is run, the function is called with a single argument, which is an object with each key holding a value of the ports that are wired in:
type PortName = string;
// Each key in this object is an input port name that is wired in,
// and the value is the value that was passed into this port.
type InputValues = Record<PortName, JsonSerializable>;
The name of the function is specified by the Function Name port and is run
by default.
Tip
Unless there's a specific need to do so, leave Function Name port value as default.
Depending on the value of the Raw Output port, the return value of the called function is interpreted in two different ways:
- When Raw Output value is
false
(default), the result of function is passed as the Result output port of therunJavascript
component. This is the most common scenario, where one or more inputs into the component are transformed into a single output port. The output value must be JSON-serializable, since it is shuttled across the Web Worker (or V8 context) boundary:
function run(inputs: InputValues): JsonSerializable {
return "This will be a `Result` port value";
}
- When Raw Output value is
true
, the result of the function is treated as an object where each key represents an output port for therunJavascript
component. The value that corresponds to that key will be passed as port's value out of the component.
// Each key is an output port name that is wired out,
// and the value is a JSON-serializable value that is
// passed out of this port.
type OutputValues = Record<PortName, JsonSerializable>;
function run(inputs: InputValues): OutputValues | Promise<OutputValues> {
return {
yes: "This will be a value of the `yes` port",
no: "This will be a value of the `no` port",
};
}
To aid with specifying the input and output ports, there are two additional configuration ports: Input Schema and Output Schema, respectively.
Input ports
The component has the following static input ports:
- Code (id:
code
) -- required, contains the function to call. - Function Name (id:
name
) -- optional, the name of the function to call (default:run
) - Raw Output (id:
raw
) -- optional, whether (true
) or not (false
) to treat the result of the function call as an object with port values (default:false
). - Input Schema (id:
inputSchema
) -- optional, defines additional input ports wired into this component instance - Output Schema (id:
outputSchema
) -- optional, defines additional output ports wired out of this component instance. Only relevant when Raw Output is set totrue
.
The component may have zero or more dynamically wired ports, each passed as part of the function argument.
Output ports
The component has either a single or no static output ports:
- Result (id:
result
) - the return value of the function call, when the Raw Output isfalse
.
When the Raw Output is true
, the output ports are all dynamic and are defined as keys of object, returned by the called function.
Example
The board above is a very simple string splitter. The body of the function is:
function run({ topics }) {
return topics.trim().split("\n");
}
The component uses the default Raw Output = false
value, and so the return value of the function becomes the Result port value.
Let's consider a bit more elaborate example. Suppose we want to create a router: a way to choose which path to take within a board. This is a very common pattern in Breadboard, because such routing enables a board to perform different actions depending on the inputs it receives.
In this example, we check to see if the list of topics we supplied has only one item, and if so, we print out an output message stating that. Otherwise, we print the list of topics.
The Raw Output port is set to true
and the body of the function is:
function run({ topics }) {
const list = topics.trim().split("\n");
if (list.length < 2) {
return {
message: "Please supply more than one topic.",
};
}
return { list };
}
Instead of returning just a value, we return an object with ports as keys and port values.
Implementation
secrets
component
The Use this component to access sensitive data, such as API keys or other valuable bits of information that you might not want to store in the board. The component takes in an array of strings as input port Keys, looks for these keys in its store and, if found, returns them as outputs.
Note
Different implementations of Breadboard will use their own strategies for retrieving secrets. The Visual Editor opts to ask the user whenever it runs into a need for a secret, and then stores these secrets in browser local storage.
The input ports
- Keys (id:
keys
) - required, must contain an array of strings that represent the keys to look up in the environment. If not supplied, an empty output is returned.
The output ports
- one output port for each key that was found.
Example
The board above makes a Gemini API call to list models. To do this, it first retrieves a GEMINI_KEY
secret and then uses the fetch
component to get the results.
Implementation
service
component
The Represents an external service that can be used by the board. Useful for integrating external services with Breadboard.
Input ports
This component a single fixed "Service URL" configuration port, The endpoint at that URL must conform to Breadboard Service Endpoint (BSE) protocol.
Once the "Service URL" port is configured, Breadboard Visual Editor will ask the service to describe itself and use that description to supply additional input and output ports.
In the example above, the "Query" input port and "News" output port is created based on this description.
Note
In addition to Breadboard Service Endpoints being able to describe themselves, they also react to configured and wired inputs, making it possible to write services whose inputs and outputs change based their configuration.
Output ports
The output ports are defined by the Breadboard Service Endpoint.
Example
For a sample implementation of a BSE protocol, see the Google News Service on Valtown, which is used in the board above.
Tip
Valtown is a quick and easy to create HTTP endpoints for Breadboard services.
Implementation
unnest
component
The Exposes all properties of a given JSON object as separate output ports.
Input ports
The unnest
component has a single input port.
- Nested (id
nested
) — the JSON object to unnest.
Output ports
The unnest
component will create one output port for each property in the
given object.