ai-sdk-tool-refresh
v0.1.0
Published
Mid-conversation tool refreshing for Vercel AI SDK's generateText/streamText
Downloads
1,284
Maintainers
Readme
ai-sdk-tool-refresh
Mid-conversation tool refreshing for Vercel AI SDK's generateText and streamText.
Note: This is different from the AI SDK's built-in
dynamicTool(), which handles tools with runtime-determined schemas. This package solves a different problem: changing which tools exist between steps of a running generation.
Why
The AI SDK re-reads its tools reference on each step. This package exploits that by mutating the tools object in-place via onStepFinish, so new tools become available to the LLM without restarting the generation loop.
This is useful when a tool call (e.g. "load-skill") adds new tools that should be available in subsequent steps of the same generateText call.
Install
npm install ai-sdk-tool-refresh aiai is a peer dependency (^6.0.0).
Usage
import { generateText } from "ai";
import { toolRefresh } from "ai-sdk-tool-refresh";
const { tools, onStepFinish, prepareStep } = toolRefresh({
tools: initialTools,
refreshTools: () => fetchLatestTools(),
shouldRefresh: (step) =>
step.toolCalls.some((tc) => tc.toolName === "load-skill"),
onRefresh: (names) =>
console.log(`Now ${names.length} tools available`),
refreshMessage: (names) =>
`Tools updated. Now available: ${names.join(", ")}`,
});
const result = await generateText({ model, tools, onStepFinish, prepareStep });Composing step handlers
If you have multiple onStepFinish callbacks, use composeStepHandlers to chain them sequentially:
import { toolRefresh, composeStepHandlers } from "ai-sdk-tool-refresh";
const { tools, onStepFinish: refreshHandler } = toolRefresh({ ... });
const onStepFinish = composeStepHandlers(
refreshHandler,
(step) => console.log(`Step used ${step.toolCalls.length} tools`),
);
await generateText({ model, tools, onStepFinish });API
toolRefresh(config)
Returns { tools, onStepFinish, prepareStep? } — pass all directly to generateText or streamText.
| Config | Type | Description |
|--------|------|-------------|
| tools | ToolSet | Initial tool set |
| refreshTools | () => Promise<ToolSet> | Returns the updated tool set |
| shouldRefresh | (step: StepResult) => boolean | Predicate: refresh after this step? |
| onRefresh | (toolNames: string[]) => void | Optional callback after refresh |
| refreshMessage | string \| ((toolNames: string[]) => string) | Optional message injected into the LLM context after a refresh via prepareStep |
composeStepHandlers(...handlers)
Chains multiple onStepFinish handlers into one. Handlers run sequentially; errors short-circuit.
License
MIT
