Vercel AI SDK
Call codai from the Vercel AI SDK 7 through the OpenAI-compatible provider, with streaming, tools and the cost receipt.
The AI SDK reaches codai through @ai-sdk/openai-compatible: base URL https://ai.codai.ro/v1, your codai_… key and the model codai. This is the same setup the Ask-the-docs assistant on this site runs in production.
Before you start
- A codai key from hub.codai.ro → Keys → Create key (details in the quickstart), stored as
CODAI_API_KEY. - AI SDK 7 (
ai) and the OpenAI-compatible provider. The SDK is ESM-only.
pnpm add ai @ai-sdk/openai-compatibleCreate the provider
import { createOpenAICompatible } from '@ai-sdk/openai-compatible';
export const codai = createOpenAICompatible({
name: 'codai',
baseURL: 'https://ai.codai.ro/v1',
apiKey: process.env.CODAI_API_KEY,
// Optional codai headers — see the request headers page.
headers: { 'X-Codai-Effort': 'medium' },
includeUsage: true,
});includeUsage: trueasks for the final usage chunk on streams, so token counts reachonEnd/usage.- Use
codai.chatModel('codai'). The gateway speaks Chat Completions natively;codaiis the default model, other aliases are on models.
Generate text
import { generateText } from 'ai';
import { codai } from './lib/codai';
const result = await generateText({
model: codai.chatModel('codai'),
instructions: 'You are a terse senior engineer.',
prompt: 'Explain Promise.all in three sentences.',
});
console.log(result.text);
console.log(result.usage);
// What actually served the call, and what it cost (micro-USD) when known before the first byte:
console.log(result.response.headers?.['x-codai-routed-to']);
console.log(result.response.headers?.['x-codai-cost-micro-usd']);AI SDK 7 uses instructions for the system prompt (it replaced system).
Stream, with tools
import { createTextStreamResponse, isStepCount, streamText, toTextStream, tool } from 'ai';
import { z } from 'zod';
import { codai } from '@/lib/codai';
export async function POST(req: Request) {
const { prompt } = (await req.json()) as { prompt: string };
const result = streamText({
model: codai.chatModel('codai'),
prompt,
stopWhen: isStepCount(3),
tools: {
weather: tool({
description: 'Current temperature for a city.',
inputSchema: z.object({ city: z.string() }),
execute: async ({ city }) => ({ city, celsius: 18 }),
}),
},
});
return createTextStreamResponse({ stream: toTextStream({ stream: result.stream }) });
}In AI SDK 7 the stream helpers are stateless top-level exports; result.toTextStreamResponse() still works but is deprecated. Function tools are forwarded as OpenAI tools and come back as tool_calls; the SDK runs them and continues the loop. On streams the cost is not known at header time: the gateway sends x-codai-cost-estimate: pending and the exact figure is in GET /v1/receipt.
Troubleshooting
404— the base URL lacks/v1. It must be exactlyhttps://ai.codai.ro/v1.401 invalid_api_key—CODAI_API_KEYis not set where the code runs (server env, not the browser).- Usage is empty on streams — add
includeUsage: trueto the provider. 429— readerror.code; see limits and pricing. The SDK retries failed calls twice by default (maxRetries).
Sources
Checked 2026-10-18.