FrameworksVercel AI SDK

Vercel AI SDK

Use Nemo Router with the Vercel AI SDK — Next.js, React, streamText, useChat

Last updated

The Vercel AI SDK's @ai-sdk/openai adapter works directly with Nemo Router. Build it with a custom baseURL — guardrails, caching, and rate-limits auto-apply server-side.

Installation

npm install ai @ai-sdk/openai

Setup

import { createOpenAI } from "@ai-sdk/openai";

const nemo = createOpenAI({
  apiKey: process.env.NEMOROUTER_API_KEY,
  baseURL: "https://api.nemorouter.ai/v1",
});

Generate Text (Route Handler)

// app/api/chat/route.ts
import { createOpenAI } from "@ai-sdk/openai";
import { generateText } from "ai";

const nemo = createOpenAI({
  apiKey: process.env.NEMOROUTER_API_KEY!,
  baseURL: "https://api.nemorouter.ai/v1",
});

export async function POST(req: Request) {
  const { messages } = await req.json();

  const { text } = await generateText({
    model: nemo("claude-sonnet-4-20250514"),
    messages,
  });

  return Response.json({ text });
}

Streaming with useChat

// app/api/chat/route.ts
import { streamText } from "ai";

export async function POST(req: Request) {
  const { messages } = await req.json();

  const result = streamText({
    model: nemo("gpt-4o"),
    messages,
  });

  return result.toDataStreamResponse();
}
// app/chat/page.tsx
"use client";
import { useChat } from "ai/react";

export default function ChatPage() {
  const { messages, input, handleInputChange, handleSubmit } = useChat();

  return (
    <form onSubmit={handleSubmit}>
      {messages.map((m) => (
        <div key={m.id}>{m.role}: {m.content}</div>
      ))}
      <input value={input} onChange={handleInputChange} />
    </form>
  );
}

Per-Request Overrides

Vercel AI forwards unknown fields via providerOptions.openai:

const { text } = await generateText({
  model: nemo("gpt-4o"),
  messages: [{ role: "user", content: "Summarize Q1 earnings..." }],
  providerOptions: {
    openai: {
      nemo_prompt_template_id: "your-summarizer-id",
      nemo_prompt_variables: { language: "Spanish" },
      nemo_guardrail_ids: ["guardrail-uuid-1"],
      nemo_cache: false,
    },
  },
});

Tool Calling

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

const { text } = await generateText({
  model: nemo("gpt-4o"),
  prompt: "What's the weather in Tokyo?",
  tools: {
    weather: tool({
      description: "Get the weather in a city",
      parameters: z.object({ city: z.string() }),
      execute: async ({ city }) => `72°F and sunny in ${city}`,
    }),
  },
});

Guardrails check the input before any tool executes — prompt injection in tool-calling flows is blocked at the gateway.

Next Steps

Was this page helpful?