> ## Documentation Index
> Fetch the complete documentation index at: https://docs.venice.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Vercel AI SDK

> Streamez les chat completions Venice dans vos applis Next.js et React via le fournisseur compatible OpenAI du Vercel AI SDK pour la production.

Le [Vercel AI SDK](https://sdk.vercel.ai/) est la manière la plus populaire de construire des fonctionnalités IA dans des applications Next.js, React, Svelte et Vue. Venice fonctionne immédiatement comme fournisseur compatible OpenAI.

## Installation

```bash theme={"system"}
npm install ai @ai-sdk/openai
```

## Configuration du provider

Créez un provider Venice à l'aide de l'adaptateur compatible OpenAI :

```typescript theme={"system"}
// lib/venice.ts
import { createOpenAI } from '@ai-sdk/openai';

const openai = createOpenAI({
  apiKey: process.env.VENICE_API_KEY!,
  baseURL: 'https://api.venice.ai/api/v1',
});

// Utilisez .chat() pour garantir la compatibilité avec l'endpoint chat completions de Venice
export const venice = (modelId: string) => openai.chat(modelId);
```

<Note>
  L'utilisation de `.chat()` garantit que les requêtes vont vers l'endpoint `/chat/completions` de Venice. La syntaxe par défaut `openai('model')` peut utiliser des endpoints OpenAI plus récents que Venice ne prend pas encore en charge.
</Note>

## Streaming chat (Next.js App Router)

### Route API

```typescript theme={"system"}
// app/api/chat/route.ts
import { streamText } from 'ai';
import { venice } from '@/lib/venice';

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

  const result = streamText({
    model: venice('venice-uncensored'),
    system: 'You are a helpful, privacy-respecting AI assistant.',
    messages,
  });

  return result.toDataStreamResponse();
}
```

### Composant React

```tsx theme={"system"}
// app/page.tsx
'use client';

import { useChat } from '@ai-sdk/react';

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

  return (
    <div className="max-w-2xl mx-auto p-4">
      <div className="space-y-4 mb-4">
        {messages.map((m) => (
          <div key={m.id} className={m.role === 'user' ? 'text-right' : 'text-left'}>
            <span className="font-bold">{m.role === 'user' ? 'You' : 'Venice'}:</span>
            <p className="whitespace-pre-wrap">{m.content}</p>
          </div>
        ))}
      </div>

      <form onSubmit={handleSubmit} className="flex gap-2">
        <input
          value={input}
          onChange={handleInputChange}
          placeholder="Ask anything..."
          className="flex-1 border rounded px-3 py-2"
          disabled={isLoading}
        />
        <button type="submit" disabled={isLoading} className="bg-red-600 text-white px-4 py-2 rounded">
          Send
        </button>
      </form>
    </div>
  );
}
```

## Génération de texte (non-streaming)

```typescript theme={"system"}
import { generateText } from 'ai';
import { venice } from '@/lib/venice';

const { text } = await generateText({
  model: venice('zai-org-glm-5-1'),
  prompt: 'Explain zero-knowledge proofs in simple terms.',
});

console.log(text);
```

## Sortie structurée

```typescript theme={"system"}
import { generateObject } from 'ai';
import { venice } from '@/lib/venice';
import { z } from 'zod';

const { object } = await generateObject({
  model: venice('venice-uncensored'),
  schema: z.object({
    recipe: z.object({
      name: z.string(),
      ingredients: z.array(z.string()),
      steps: z.array(z.string()),
      prepTimeMinutes: z.number(),
    }),
  }),
  prompt: 'Generate a recipe for chocolate chip cookies.',
});

console.log(object.recipe.name);
console.log(`Prep time: ${object.recipe.prepTimeMinutes} minutes`);
```

## Appel d'outils (tool calling)

```typescript theme={"system"}
import { streamText, tool } from 'ai';
import { venice } from '@/lib/venice';
import { z } from 'zod';

const result = streamText({
  model: venice('zai-org-glm-5-1'),
  messages: [{ role: 'user', content: 'What is the weather in Tokyo?' }],
  tools: {
    getWeather: tool({
      description: 'Get current weather for a location',
      parameters: z.object({
        location: z.string().describe('City name'),
      }),
      execute: async ({ location }) => {
        // Votre appel d'API météo ici
        return { temperature: 22, condition: 'Sunny', location };
      },
    }),
  },
});

for await (const part of result.fullStream) {
  if (part.type === 'text-delta') {
    process.stdout.write(part.textDelta);
  } else if (part.type === 'tool-result') {
    console.log('Tool result:', part.result);
  }
}
```

## Génération d'images

La génération d'images Venice peut être appelée directement aux côtés du AI SDK :

```typescript theme={"system"}
// app/api/image/route.ts
export async function POST(req: Request) {
  const { prompt } = await req.json();

  const response = await fetch('https://api.venice.ai/api/v1/image/generate', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${process.env.VENICE_API_KEY}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      model: 'qwen-image',
      prompt,
      width: 1024,
      height: 1024,
    }),
  });

  const data = await response.json();
  return Response.json({ image: data.images[0] });
}
```

## Chat multi-modèles (sélecteur de modèle)

Laissez les utilisateurs choisir parmi les modèles Venice :

```typescript theme={"system"}
// app/api/chat/route.ts
import { streamText } from 'ai';
import { venice } from '@/lib/venice';

const ALLOWED_MODELS = [
  'venice-uncensored',
  'zai-org-glm-5-1',
  'qwen3-vl-235b-a22b',
  'qwen3-5-9b',
];

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

  if (!ALLOWED_MODELS.includes(modelId)) {
    return new Response('Invalid model', { status: 400 });
  }

  const result = streamText({
    model: venice(modelId),
    messages,
  });

  return result.toDataStreamResponse();
}
```

```tsx theme={"system"}
// Composant client avec sélecteur de modèle
'use client';

import { useChat } from '@ai-sdk/react';
import { useState } from 'react';

const MODELS = [
  { id: 'venice-uncensored', name: 'Venice Uncensored', desc: 'Fast & uncensored' },
  { id: 'zai-org-glm-5-1', name: 'GLM 5.1', desc: 'Most intelligent (private)' },
  { id: 'qwen3-vl-235b-a22b', name: 'Qwen Vision', desc: 'Advanced vision + text' },
  { id: 'qwen3-5-9b', name: 'Qwen 3.5 9B', desc: 'Fastest & cheapest' },
];

export default function Chat() {
  const [model, setModel] = useState('venice-uncensored');
  const { messages, input, handleInputChange, handleSubmit } = useChat({
    body: { model },
  });

  return (
    <div>
      <select value={model} onChange={(e) => setModel(e.target.value)}>
        {MODELS.map((m) => (
          <option key={m.id} value={m.id}>{m.name} — {m.desc}</option>
        ))}
      </select>
      {/* ... UI du chat ... */}
    </div>
  );
}
```

## Intégration de la recherche web

Passez les paramètres Venice pour la recherche web :

```typescript theme={"system"}
import { streamText } from 'ai';
import { venice } from '@/lib/venice';

const result = streamText({
  model: venice('venice-uncensored'),
  messages: [{ role: 'user', content: 'What happened in AI news today?' }],
  // Paramètres spécifiques à Venice
  experimental_providerMetadata: {
    venice_parameters: {
      enable_web_search: 'auto',
    },
  },
});
```

<Note>
  Si `experimental_providerMetadata` n'est pas transmis, vous pouvez utiliser un wrapper fetch personnalisé ou appeler l'API Venice directement pour les fonctionnalités de recherche web.
</Note>

## Embeddings

Pour les embeddings, utilisez `textEmbeddingModel()` directement sur le provider :

```typescript theme={"system"}
import { embed, embedMany } from 'ai';
import { createOpenAI } from '@ai-sdk/openai';

const openai = createOpenAI({
  apiKey: process.env.VENICE_API_KEY!,
  baseURL: 'https://api.venice.ai/api/v1',
});

// Embedding unique
const { embedding } = await embed({
  model: openai.textEmbeddingModel('text-embedding-bge-m3'),
  value: 'Privacy-first AI infrastructure',
});

// Embeddings par lot
const { embeddings } = await embedMany({
  model: openai.textEmbeddingModel('text-embedding-bge-m3'),
  values: [
    'Venice AI provides private inference.',
    'Zero data retention guaranteed.',
    'OpenAI SDK compatible.',
  ],
});
```

## Variables d'environnement

```bash theme={"system"}
# .env.local
VENICE_API_KEY=your-venice-api-key
```

## Modèles recommandés

| Cas d'usage      | Modèle               | Pourquoi                                               |
| ---------------- | -------------------- | ------------------------------------------------------ |
| Applis de chat   | `venice-uncensored`  | Rapide, économique, sans filtrage                      |
| Tâches complexes | `zai-org-glm-5-1`    | Raisonnement phare privé                               |
| Applis vision    | `qwen3-vl-235b-a22b` | Compréhension d'images avancée                         |
| Fort volume      | `qwen3-5-9b`         | Le moins cher à 0,10 \$/1 M entrée, 0,15 \$/1 M sortie |
| Tool calling     | `zai-org-glm-5-1`    | Function calling fiable                                |

<CardGroup cols={2}>
  <Card title="Docs du Vercel AI SDK" icon="book" href="https://sdk.vercel.ai/docs">
    Documentation officielle du Vercel AI SDK
  </Card>

  <Card title="Modèles Venice" icon="database" href="/models/overview">
    Parcourir tous les modèles Venice
  </Card>
</CardGroup>
