A lightweight, type-safe AI workflow orchestrator inspired by Anthropic's agent patterns. Built on top of Vercel AI SDK.
npm install flows-ai
This is not yet another AI agent framework. We're building on top of Vercel AI SDK. If you use it already, you will feel right at home.
This library is aworkflow orchestrator. It provides simple, composable and extensible primitives to compose agents together in order to complete complex tasks.
The core architecture is built around the concept of a Flow - a simple, composable structure that can be infinitely nested.
Each flow has:
agent
- what to executeinput
- what to processname
- optional name of the flow
The input
can be a string with instructions (if the agent is a simple LLM call). If you're using control flow agents provided by our library, you will notice input can also be another flow or an array of flows.
This flexibility allows for infinite composition.
When a flow is executed, each agent receives its complete configuration as a payload and can decide how to handle it.
To define your agents, we provide an agent
helper function that takes same props as Vercel AI SDK's generateText
.
The only difference with Vercel AI SDK's is that we take care of the prompt
, that is provided during runtime, depending on where and how your agent is run.
const translationAgent = agent({
model: openai('gpt-4o'),
system: 'You are a translation agent...',
})
const summaryAgent = agent({
model: openai('gpt-4o'),
system: 'You are a summary agent...',
})
Next, you can define your flow. You can use any of the built-in flows or define your own. In the following example, we will run two agents in sequence.
const translateFlow = sequence([
{
agent: 'translationAgent',
input: 'Translate this text to English',
},
{
agent: 'summaryAgent',
input: 'Now summarize the translated text',
}
])
When running in a sequence, the output of the first agent becomes the input for the next.
To execute your flow, you can use the execute
function. It takes your flow and a context object with agents.
execute(translateFlow, {
agents: {
translationAgent,
summaryAgent
}
})
In this example, we will first translate the text to English and then summarize it.
Agent is a simple function that gets called with agent's input and context.
type Props = {
// this agent accepts a single flow as input
input: Flow
// and additional configuration parameter
repeat?: number
}
const repeatAgent = ({ input, repeat = 3}, context) => {
// call an LLM, perform function call, etc.
}
This abstraction allows you to define not just agents that call tools, but also agents that control the execution flow. This is what we use under the hood to provide built-in flows.
When using agent
helper, you're building on top of this abstraction.