codai docs
Integrations

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-compatible

Create the provider

lib/codai.ts
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: true asks for the final usage chunk on streams, so token counts reach onEnd / usage.
  • Use codai.chatModel('codai'). The gateway speaks Chat Completions natively; codai is the default model, other aliases are on models.

Generate text

generate.ts
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

app/api/chat/route.ts
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 exactly https://ai.codai.ro/v1.
  • 401 invalid_api_key — CODAI_API_KEY is not set where the code runs (server env, not the browser).
  • Usage is empty on streams — add includeUsage: true to the provider.
  • 429 — read error.code; see limits and pricing. The SDK retries failed calls twice by default (maxRetries).

Sources

Checked 2026-10-18.

On this page