Test DemoDocs
GuidesModelsAPI referenceApps
SDKs and frameworks

Vercel AI SDK

Use the AI SDK with this API through its OpenAI Compatible provider.

The AI SDK talks to this API through its OpenAI Compatible provider, @ai-sdk/openai-compatible. You get generateText, streamText, tools and generateImage on every model on Models.

Install

npm install ai @ai-sdk/openai-compatible zod
pnpm add ai @ai-sdk/openai-compatible zod
bun add ai @ai-sdk/openai-compatible zod

Configure API keys

.env
API_KEY=sk-...

Load it with node --env-file=.env or your framework's own .env support. Keep the key out of your code.

Run

Create the provider once:

ai.ts
import { createOpenAICompatible } from "@ai-sdk/openai-compatible";

export const ai = createOpenAICompatible({
  name: "ai",
  baseURL: "https://test-demo.pinerouter.ai/v1",
  apiKey: process.env.API_KEY,
  includeUsage: true, // token usage on streams
});

Text

import { generateText } from "ai";
import { ai } from "./ai";

const { text } = await generateText({ model: ai("gpt-6-luna"), prompt: "Name three rivers in Europe." });
console.log(text);

Stream

import { streamText } from "ai";
import { ai } from "./ai";

const result = streamText({ model: ai("gpt-6-luna"), prompt: "Write a haiku about rivers." });
for await (const part of result.textStream) {
  process.stdout.write(part);
}

Tool calling

import { generateText, tool, isStepCount } from "ai";
import { z } from "zod";
import { ai } from "./ai";

const { text } = await generateText({
  model: ai("gpt-6-luna"),
  tools: {
    weather: tool({
      description: "Current weather for a city",
      inputSchema: z.object({ city: z.string() }),
      execute: async ({ city }) => ({ city, forecast: "Sunny, 21 C" }),
    }),
  },
  stopWhen: isStepCount(5),
  prompt: "What is the weather in Paris?",
});
console.log(text);

stopWhen lets the SDK send the tool result back and continue, up to 5 steps.

Images

import { generateImage } from "ai";
import { ai } from "./ai";

const { images } = await generateImage({
  model: ai.imageModel("z-image"),
  prompt: "A red paper boat on a calm lake",
  size: "1024x1024",
});
console.log(images[0].base64.slice(0, 40));

The provider downloads the image for you, so images[0].base64 and images[0].uint8Array hold the file.

Specifics

  • name is your own label. It is also the key for extra request fields under providerOptions.
  • streamText does not throw on errors, so pass onError to log them.
  • For video, music, speech or a model's own settings, call Jobs with the HTTP helper from the same server code.
  • Tool calling depends on the model. Test with the model you plan to use.

Next