Vercel AI SDK
The Vercel AI SDK connects to ai& through @ai-sdk/openai-compatible.
npm install ai @ai-sdk/openai-compatibleimport { createOpenAICompatible } from "@ai-sdk/openai-compatible";
export const aiand = createOpenAICompatible({ name: "aiand", baseURL: "https://api.aiand.com/v1", apiKey: process.env.AIAND_API_KEY, includeUsage: true,});Create an API key in the ai& console and set AIAND_API_KEY.
Generate text
Section titled “Generate text”import { generateText } from "ai";import { aiand } from "./client";
const { text } = await generateText({ model: aiand("openai/gpt-oss-120b"), prompt: "Tell me a haiku about Tokyo.",});
console.log(text);A system prompt belongs in instructions, not a { role: "system" } message.
Stream to the browser (Next.js App Router)
Section titled “Stream to the browser (Next.js App Router)”npm install @ai-sdk/reactimport { convertToModelMessages, createUIMessageStreamResponse, streamText, toUIMessageStream, type UIMessage } from "ai";import { aiand } from "@/lib/aiand";
export async function POST(req: Request) { const { messages }: { messages: UIMessage[] } = await req.json(); const result = streamText({ model: aiand("openai/gpt-oss-120b"), messages: await convertToModelMessages(messages), }); return createUIMessageStreamResponse({ stream: toUIMessageStream({ stream: result.stream }), });}"use client";import { useChat } from "@ai-sdk/react";import { useState } from "react";
export default function Page() { const { messages, sendMessage } = useChat(); const [input, setInput] = useState(""); return ( <form onSubmit={(e) => { e.preventDefault(); sendMessage({ text: input }); setInput(""); }} > {messages.map((m) => ( <div key={m.id}> {m.role}:{" "} {m.parts.map((part, i) => (part.type === "text" ? <span key={i}>{part.text}</span> : null))} </div> ))} <input value={input} onChange={(e) => setInput(e.target.value)} /> </form> );}import { generateText, tool } from "ai";import { z } from "zod";import { aiand } from "./client";
const result = await generateText({ model: aiand("openai/gpt-oss-120b"), tools: { getWeather: tool({ description: "Get current weather", inputSchema: z.object({ city: z.string() }), execute: async ({ city }) => `Sunny in ${city}, 22°C`, }), }, prompt: "What's the weather in Tokyo?",});Reasoning
Section titled “Reasoning”Reasoning models accept a level via providerOptions. Supported levels per model are in the reasoning_efforts field of the model catalog.
const { text } = await generateText({ model: aiand("zai-org/glm-5.3"), prompt: "Solve this step by step: What is 15 * 23?", providerOptions: { aiand: { reasoningEffort: "high", }, },});