Vercel AI SDK
The AI SDK reaches OpenCheap through its OpenAI-compatible provider. Create the provider once with the base URL and your key, then use it like any other model.
What you need
- Base URL
https://api.opencheap.si/v1 - API keyA
kl_live_…key from the console, kept inOPENCHEAP_API_KEY. - ModelAn id from Models, for example
claude-sonnet-5.
npm install ai @ai-sdk/openai-compatible zodThe provider
import { createOpenAICompatible } from "@ai-sdk/openai-compatible";
const opencheap = createOpenAICompatible({
name: "opencheap",
baseURL: "https://api.opencheap.si/v1",
apiKey: process.env.OPENCHEAP_API_KEY,
includeUsage: true,
supportsStructuredOutputs: true,
});
const model = opencheap("claude-sonnet-5");includeUsage asks for the usage chunk at the end of a stream, so streamText reports tokens. supportsStructuredOutputs lets Output.object send its schema as a JSON schema; without it the SDK warns and leaves the schema out of the request. The model id is any chat model from the Models page, with or without an opencheap/ in front.
generateText and streamText
import { generateText, streamText } from "ai";
const { text, usage } = await generateText({ model, prompt: "Say hello in five words." });
const result = streamText({ model, prompt: "Count from 1 to 5." });
for await (const part of result.textStream) process.stdout.write(part);
console.log((await result.usage).totalTokens);Tools
import { generateText, tool, stepCountIs } from "ai";
import { z } from "zod";
const { text, steps } = await generateText({
model,
tools: {
weather: tool({
description: "Get the weather in a city",
inputSchema: z.object({ city: z.string() }),
execute: async ({ city }) => ({ city, forecast: "sunny", celsius: 21 }),
}),
},
stopWhen: stepCountIs(3),
prompt: "What is the weather in Paris?",
});The model asks for weather, the SDK runs execute and sends the result back, and text is the final answer. steps holds both rounds. Choose a model that supports tool calls.
Structured output
import { generateText, Output } from "ai";
import { z } from "zod";
const { output } = await generateText({
model,
output: Output.object({ schema: z.object({ name: z.string(), city: z.string(), age: z.number() }) }),
prompt: "Extract: Marie Curie, 66, lived in Paris.",
});
// { name: "Marie Curie", city: "Paris", age: 66 }What was checked
Run on October 28, 2026 with ai 7.0.153, @ai-sdk/openai-compatible 3.0.78 and zod 4: all four snippets, on claude-sonnet-5, glm-4.7-flash and qwen3-coder. Output.object returned the object on all three, twice each. Left out of supportsStructuredOutputs, qwen3-coder returned a field named location instead of city, because the schema never reached it.