The setup function
The setup function is where you compose your chain
In the defineChain
method, you create your chain logic in the setup
function.
The setup function allows you to declare the chain’s steps and their order. It provides context such as params
, step
, runIf
, forEach
and code
.
At the end of the setup
function, you should return your chain’s output.
Example:
const chain = defineChain({
params: {
foo: {
type: 'string',
},
},
setup({ params, step }) {
const { chunks } = step('split_text', {
text: params.foo,
num_tokens: 200,
});
return {
foo: params.foo,
chunkedFoo: chunks,
};
},
});
params
The params
property contains the inputs you define in the params
key of defineChain
. They are typed based on your JSONSchema, meaning Typescript will get upset if you try to pass a param of type “string” into a transformation that wants an array.
step
The step
function is how you define steps in your chain. It accepts as its first parameter the ID of the chain. The second parameter is an object containing the inputs to the transformation.
View all transformations with their IDs and inputs.
For example:
const { chunks } = step('split_text', {
text: params.foo,
num_tokens: 200,
});
code
No Javascript you write in your setup
function will be executed, except for defining primitive variables and returning your output.
For example, you can not do this:
const { chunks } = step('split_text', {
text: params.foo,
num_tokens: 200,
});
const capitalisedChunks = chunks.map((chunk) => chunk.toUpperCase()); // this will not work
return {
capitalisedChunks,
};
To accomodate this, we provide a code
helper function that wraps the js_code_transformation
step (which outputs a param called transformed
). This allows you to write arbitrary Javascript code that will be executed in the cloud.
It receives as its first parameter all dependencies that the code block will need. The second parameter is a function that receives the dependencies as its first parameter, and returns the code that will be executed.
This will work!
const { chunks } = step('split_text', {
text: params.foo,
num_tokens: 200,
});
const { transformed: capitalisedChunks } = code({ chunks }, ({ chunks }) => {
return chunks.map((chunk) => chunk.toUpperCase()); // this works!
});
return {
capitalisedChunks,
};
runIf
Another common use case is to run a step conditionally. For this, we provide the runIf
helper function.
It receives as its first parameter a variable that determines whether to run the nested code or not.
The second parameter it receives is a function, where steps can be defined and then variables returned. These steps will only be run if the first parameter is truthy.
const { chunks, capitalisedChunks } = runIf(params.shouldChunkText, () => {
const { chunks } = step('split_text', {
text: params.foo,
num_tokens: 200,
});
const { transformed: capitalisedChunks } = code(
{ chunks },
({ chunks }) => {
return chunks.map((chunk) => chunk.toUpperCase()); // this works!
}
);
return {
chunks,
capitalisedChunks,
};
});
forEach
We allow you to loop over arrays to run steps multiple times. You can do this with the forEach
utility, passed in to setup.
In the first argument, you pass the iterator. Then you pass a callback that receives each iterated item. This callback should return a step
or `code.
defineChain({
...restOfChain,
setup({ params, step, foreach }) {
const { pdf_url } = params;
const { text } = step('pdf_to_text', {
pdf_url,
});
const { chunks } = step('split_text', {
method: 'tokens',
num_tokens: 200,
text,
});
const results = foreach(chunks, ({ item }) =>
step('prompt_completion', {
prompt: `${item}. Summarise this text.`,
})
);
const { text: summary } = step('join_array', {
array: results['*'].answer,
sep: '\n',
});
return { summary };
},
});
Was this page helpful?