28 Oct 2026 · LangGraph & Agents
Tool Calling with the Vercel AI SDK in Next.js 15
Dynamic model routing across OpenAI and Anthropic, tools the model can call, and the same client stream you already use for chat.
Tool calling is how a chat route becomes useful: search, fetch a thread, create a brief. The Vercel AI SDK can do that without a graph. LangGraph is the next step when you need a supervisor and durable state. Do not start with both.
AgenticPacks OSS uses the AI SDK for GPT-4o-mini streaming chat: Agentic-Packs/agenticpacks-oss. Pro adds a model picker (OpenAI, Anthropic, Google) on the same stream, plus LangGraph for the research workflow. Try the production demo if you want the UI before the code.
One route, many models
import { openai } from "@ai-sdk/openai";
import { anthropic } from "@ai-sdk/anthropic";
import { streamText, tool } from "ai";
import { z } from "zod";
const models = {
openai: openai("gpt-4o"),
anthropic: anthropic("claude-sonnet-4"),
};
export async function POST(request: Request) {
const { messages, modelId } = await request.json();
const model = models[modelId as keyof typeof models] ?? models.openai;
const result = streamText({
model,
messages,
tools: {
searchDocs: tool({
description: "Search tenant documents",
parameters: z.object({ query: z.string() }),
execute: async ({ query }) => {
return await searchPgvector(query);
},
}),
},
});
return result.toDataStreamResponse();
}
Pin model ids in your own map. Do not take a free-form model string from the client. That is how you get surprise bills.
searchPgvector is the retrieve step from pgvector vs Pinecone. It must enforce organizationId. Same rule as Server Actions.
Tools vs a graph
| Need | Use |
|---|---|
| Model picks a tool, you run it, model continues | AI SDK tools |
| Fixed supervisor, researcher, summarizer | LangGraph |
| Pause for a human | Graph checkpoint, HITL |
| One-shot chat | streamText with no tools |
Pro uses both: SDK tools and model picker in chat, LangGraph on the agent route. AgenticPacks OSS is chat without tools so the MIT repo stays small.
Streaming and billing
Return the data stream the AgenticPacks OSS client already consumes. Do not buffer tools server-side then send one blob. Proxy setup: Caddy SSE.
Debit the team credit pool before streamText. Count prompt, completion, and any paid search in the ledger. Prometheus scrape is Grafana token tracking.
Secrets (OPENAI_API_KEY, ANTHROPIC_API_KEY) are runtime env, never NEXT_PUBLIC_*. See Docker env.
Tired of a hard-coded model and a chat route that cannot search?
AgenticPacks OSS is the stream without tools: Agentic-Packs/agenticpacks-oss.
Multi-model chat plus LangGraph is in multi-model chat and tools in Pro.
Client
The default useChat hook already renders tool parts if you pass the same schema. Keep one message list. A second websocket for tools is how UIs drift.
Where to Go From Here
You do not have to fork the chat route once per provider.
Option A: Free open-source baseline (MIT)
- GitHub: github.com/Agentic-Packs/agenticpacks-oss
- What is included: AI SDK streaming chat, Auth.js, Postgres, Compose, single-plan Stripe. One model. No tool calling.
- Cost: free, MIT.
Option B: Ship with AgenticPacks Pro ($149 one-time)
If users pick a model and agents call tools:
- Automated Hetzner provisioning: Terraform, Caddy, Compose.
- Production multi-agent core: Model picker, LangGraph, pgvector tools, Redis.
- Usage & Unit Economics: Stripe, team pools, token-to-dollar including tool fees.
