Vercel AI SDK Provider
@llmrelai/ai-sdk-provider plugs Relai into the Vercel AI SDK. Use generateText, streamText, useChat, and the rest of the AI SDK ecosystem with Relai as your model provider.
Installation
npm install @llmrelai/ai-sdk-provider aiQuick Start
import { createRelai } from "@llmrelai/ai-sdk-provider";
import { generateText, streamText } from "ai";
const relai = createRelai({ apiKey: process.env.RELAI_API_KEY! });
// Generate text
const { text } = await generateText({
model: relai("reasoning/cheapest"),
prompt: "What is the capital of France?",
});
// Stream text
const result = await streamText({
model: relai("reasoning/cheapest"),
prompt: "Write a haiku about coding.",
});
for await (const chunk of result.textStream) {
process.stdout.write(chunk);
}Multi-Region Support
Regional Keys
const relai = createRelai({
keys: {
eu: process.env.RELAI_KEY_EU!,
us: process.env.RELAI_KEY_US!,
},
});
const euModel = relai.forRegion("eu")("reasoning/cheapest");
const usModel = relai.forRegion("us")("reasoning/cheapest");
await generateText({ model: euModel, prompt: "Hello from EU!" });
await generateText({ model: usModel, prompt: "Hello from US!" });Global Keys
const relai = createRelai({
apiKey: process.env.RELAI_GLOBAL_KEY!, // relai_sk_gbl_eu_live_...
});
// Default routing
await generateText({
model: relai("reasoning/cheapest"),
prompt: "Hello!",
});
// Per-call region
await generateText({
model: relai.forRegion("eu")("reasoning/cheapest"),
prompt: "Hello from EU!",
});Next.js Route Handler
// app/api/chat/route.ts
import { createRelai } from "@llmrelai/ai-sdk-provider";
import { streamText, convertToModelMessages } from "ai";
const relai = createRelai({ apiKey: process.env.RELAI_API_KEY! });
export async function POST(req: Request) {
const { messages } = await req.json();
const result = streamText({
model: relai("reasoning/cheapest"),
messages: await convertToModelMessages(messages),
});
return result.toUIMessageStreamResponse();
}React Chat UI
"use client";
import { useChat } from "@ai-sdk/react";
import { DefaultChatTransport } from "ai";
export function Chat() {
const { messages, sendMessage, status } = useChat({
transport: new DefaultChatTransport({ api: "/api/chat" }),
});
return (
<div>
{messages.map((m) => (
<div key={m.id}>{/* render m.parts */}</div>
))}
<form
onSubmit={(e) => {
e.preventDefault();
const input = (e.target as HTMLFormElement).elements.namedItem(
"msg"
) as HTMLInputElement;
sendMessage({ text: input.value });
input.value = "";
}}
>
<input name="msg" />
<button type="submit" disabled={status === "streaming"}>
Send
</button>
</form>
</div>
);
}Native Relai Resources
The provider exposes the underlying @llmrelai/sdk client for native API access (balance, usage, end-user quotas, etc.):
const relai = createRelai({ apiKey: process.env.RELAI_API_KEY! });
const balance = await relai.client.balance.get();
await relai.client.users.create({
external_id: "user_123",
monthly_quota_dollars: 10.0,
});
const usage = await relai.client.usage.list({
from: "2024-01-01T00:00:00Z",
to: "2024-01-31T23:59:59Z",
});Error Handling
import { RelaiAPIError } from "@llmrelai/ai-sdk-provider";
import { generateText } from "ai";
try {
await generateText({
model: relai("reasoning/cheapest"),
prompt: "...",
});
} catch (error) {
if (error instanceof RelaiAPIError) {
console.error(error.message);
console.error(error.relaiCode);
console.error(error.region);
console.error(error.isRetryable);
}
}API Reference
createRelai(options)
| Option | Type | Description |
|---|---|---|
apiKey | string | Single API key |
keys | { eu?: string, us?: string } | Multi-region keys |
defaultRegion | "eu" | "us" | Default region |
name | string | Provider name (default: "relai") |
Provider Methods
| Method | Description |
|---|---|
provider(modelId) | Returns a language model for the given ID |
provider.forRegion(region) | Returns a region-specific provider function |
provider.client | Access to the underlying @llmrelai/sdk client |