cl-pipelines use the Vercel AI SDK v6 tool() factory. A tool has a description the model reads to decide when to call it, a Zod inputSchema that constrains its arguments, and an async execute function that runs the actual logic. The library handles everything else: calling execute, collecting the result, appending it to the message history, and persisting it in the checkpoint.
Defining a tool
Passing tools to runAgent
Pass your tools as a record keyed by the name the model will use to call them:lookupPolicy, getClientInfo, sendEmail) become the tool names in the model’s context. Choose names that are descriptive — the model uses them alongside description to decide when and how to call each tool.
How tool results flow through the checkpoint
When the model calls a tool, the following happens within a single turn:- The model returns
finishReason: "tool-calls"with one or more tool call objects - The AI SDK calls each tool’s
executefunction with the parsed arguments - The SDK wraps each return value in a
role: "tool"message - Those messages are included in
result.response.messages cl-pipelinesappends the fullresult.response.messagesarray tocheckpoint.messages- The checkpoint is written to storage
- The next turn runs with the complete history (including tool results) as context
generateText call — a crash between turns will not cause a tool to be called twice.
Schema tips
Describe every field
Use
.describe() on every field in your inputSchema. The model reads these descriptions to understand what value to pass. Undescribed fields lead to hallucinated or missing arguments.Keep schemas focused
Each tool should do one thing. Fewer fields in
inputSchema means less chance of the model hallucinating arguments or calling the tool incorrectly.Return structured objects
Return plain objects rather than raw strings. Structured responses give the model richer context and make it easier to write deterministic tests for your tools.
Handle not-found gracefully
Return a
{ found: false } object rather than throwing when a record doesn’t exist. The model can then decide how to handle the missing data rather than triggering an error phase.Multiple tools example
Long-running tools
In v0.1, all tool execution is synchronous within a single phase invocation. If a tool call takes longer than your scheduler’s action timeout, the phase will time out and be retried from the last checkpoint — which means the tool call will run again. For expensive tools (e.g. calling an external ML service, processing a large file), extract the work into a dedicated pipeline phase that runs before the agent phase and stores its result inTState. Then pass the result to the agent via the initial messages or system prompt.
v0.2 will introduce
pendingToolCalls support, allowing long-running tools to be modeled as pipeline phases that feed results back into the agent loop.