All posts

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

NeedUse
Model picks a tool, you run it, model continuesAI SDK tools
Fixed supervisor, researcher, summarizerLangGraph
Pause for a humanGraph checkpoint, HITL
One-shot chatstreamText 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)


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.