Skip to content

Integrations

Vercel AI SDK

The Vercel AI SDK in TypeScript with AI Tokens: the OpenAI-compatible provider, a tool loop with generateText, and streamText.

Last updated: 2026-10-11

bash
npm install ai @ai-sdk/openai-compatible zod
export API_KEY="sk-at-…"

Use @ai-sdk/openai-compatible, not @ai-sdk/openai: the second targets OpenAI's own API and its newer features.

A tool loop and a stream

typescript
import { createOpenAICompatible } from "@ai-sdk/openai-compatible";
import { generateText, stepCountIs, streamText, tool } from "ai";
import { z } from "zod";

const provider = createOpenAICompatible({
  name: "aitokens",
  baseURL: "https://api.aitokens.ch/v1",
  apiKey: process.env.API_KEY,
  includeUsage: true, // token counts in streams too
});

const { text, steps } = await generateText({
  model: provider("qwen3.8-27b"),
  maxOutputTokens: 2048,
  tools: {
    getWeather: tool({
      description: "Current weather for a city",
      inputSchema: z.object({ city: z.string() }),
      execute: async ({ city }) => ({ city, tempC: 14, sky: "light rain" }),
    }),
  },
  stopWhen: stepCountIs(3),
  prompt: "What is the weather in Lugano?",
});
console.log(steps.length, "steps:", text);

const result = streamText({
  model: provider("qwen3.8-27b"),
  maxOutputTokens: 1024,
  prompt: "Write one sentence about Lake Lugano.",
});
for await (const part of result.textStream) process.stdout.write(part);
console.log("\nusage:", await result.usage);

What came back on qwen3.8-27b, shortened:

text
2 steps: The current weather in Lugano is **14°C** with **light rain**. …
Lake Lugano, a glacial lake nestled in the Italian-speaking Ticino region of Switzerland, …
usage: { inputTokens: 18, outputTokens: 134, … reasoningTokens: 0 … }

Two steps: the model called getWeather, the SDK ran it and sent the result back, and the model answered with it.

Limits

  • maxOutputTokens up to 8192. A higher value is refused with 422.
  • reasoningTokens reads 0 on qwen3.8-27b and gpt-oss-120b. The API does not count the reasoning apart: it is inside outputTokens.
  • Context windows are not read from the API. They are in Which model.

Search the docs

Type to search…