Adapters

Mistral

The Mistral adapter provides access to Mistral's chat models, including Mistral Large, the multimodal Pixtral family, the Magistral reasoning models, and the Codestral code-specialized model.

Installation

shell
npm install @tanstack/ai-mistral

Basic Usage

ts
import { chat } from "@tanstack/ai";
import { mistralText } from "@tanstack/ai-mistral";

const stream = chat({
  adapter: mistralText("mistral-large-latest"),
  messages: [{ role: "user", content: "Hello!" }],
});

Basic Usage - Custom API Key

ts
import { chat } from "@tanstack/ai";
import { createMistralText } from "@tanstack/ai-mistral";

const adapter = createMistralText(
  "mistral-large-latest",
  process.env.MISTRAL_API_KEY!,
);

const stream = chat({
  adapter,
  messages: [{ role: "user", content: "Hello!" }],
});

Configuration

ts
import {
  createMistralText,
  type MistralTextConfig,
} from "@tanstack/ai-mistral";

const config: Omit<MistralTextConfig, "apiKey"> = {
  serverURL: "https://api.mistral.ai", // Optional, this is the default
  defaultHeaders: {
    "X-Custom-Header": "value",
  },
};

const adapter = createMistralText(
  "mistral-large-latest",
  process.env.MISTRAL_API_KEY!,
  config,
);

Example: Chat Completion

ts
import { chat, toServerSentEventsResponse } from "@tanstack/ai";
import { mistralText } from "@tanstack/ai-mistral";

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

  const stream = chat({
    adapter: mistralText("mistral-large-latest"),
    messages,
  });

  return toServerSentEventsResponse(stream);
}

Example: With Tools

ts
import { chat, toolDefinition } from "@tanstack/ai";
import { mistralText } from "@tanstack/ai-mistral";
import { z } from "zod";

const getWeatherDef = toolDefinition({
  name: "get_weather",
  description: "Get the current weather for a location",
  inputSchema: z.object({
    location: z.string(),
  }),
});

const getWeather = getWeatherDef.server(async ({ location }) => {
  return { temperature: 72, conditions: "sunny" };
});

const stream = chat({
  adapter: mistralText("mistral-large-latest"),
  messages: [{ role: "user", content: "What's the weather in Paris?" }],
  tools: [getWeather],
});

Example: Multimodal (Vision)

Use a vision-capable model — pixtral-large-latest, pixtral-12b-2409, mistral-medium-latest, or mistral-small-latest — to send images alongside text:

ts
import { chat } from "@tanstack/ai";
import { mistralText } from "@tanstack/ai-mistral";

const stream = chat({
  adapter: mistralText("pixtral-large-latest"),
  messages: [
    {
      role: "user",
      content: [
        { type: "text", content: "What's in this image?" },
        {
          type: "image",
          source: {
            type: "url",
            value: "https://example.com/photo.jpg",
          },
        },
      ],
    },
  ],
});

For data-URL or base64 images, set source.type to "data" and provide mimeType:

ts
import { chat } from "@tanstack/ai";
import { mistralText } from "@tanstack/ai-mistral";

const base64String = "..."; // your base64-encoded image bytes

const stream = chat({
  adapter: mistralText("pixtral-large-latest"),
  messages: [
    {
      role: "user",
      content: [
        { type: "text", content: "What's in this image?" },
        {
          type: "image",
          source: {
            type: "data",
            mimeType: "image/png",
            value: base64String,
          },
        },
      ],
    },
  ],
});

See Multimodal Content for the full content-part shape.

Example: Reasoning (Magistral)

Magistral models (magistral-medium-latest, magistral-small-latest) stream their reasoning as separate events before the final answer. The adapter emits AG-UI REASONING_* chunks for the thinking content and TEXT_MESSAGE_* chunks for the answer:

ts
// ignore: narrowing the raw AG-UI stream by `chunk.type` relies on @ag-ui/core's
// discriminated-union `type` field, which kiira can't resolve in a source-only
// check. The runtime behaviour is exactly as shown.
import { chat } from "@tanstack/ai";
import { mistralText } from "@tanstack/ai-mistral";

const stream = chat({
  adapter: mistralText("magistral-medium-latest"),
  messages: [{ role: "user", content: "Why is the sky blue?" }],
});

for await (const chunk of stream) {
  if (chunk.type === "REASONING_MESSAGE_CONTENT") {
    process.stdout.write(`[thinking] ${chunk.delta}`);
  } else if (chunk.type === "TEXT_MESSAGE_CONTENT") {
    process.stdout.write(chunk.delta);
  }
}

Reasoning events are always closed before any text or tool output begins, so consumers see a complete REASONING_START → REASONING_MESSAGE_START → REASONING_MESSAGE_CONTENT* → REASONING_MESSAGE_END → REASONING_END sequence first.

See Thinking & Reasoning for the cross-provider event spec.

Example: Structured Output

Generate JSON that conforms to a Zod schema using Mistral's json_schema response format:

ts
import { chat } from "@tanstack/ai";
import { mistralText } from "@tanstack/ai-mistral";
import { z } from "zod";

const recipeSchema = z.object({
  name: z.string(),
  ingredients: z.array(z.string()),
  steps: z.array(z.string()),
});

const recipe = await chat({
  adapter: mistralText("mistral-large-latest"),
  messages: [
    { role: "user", content: "Give me a chocolate chip cookie recipe." },
  ],
  outputSchema: recipeSchema,
});

console.log(recipe.name); // typed as z.infer<typeof recipeSchema>

See Structured Outputs for the full guide.

Model Options

Mistral exposes provider-specific options via modelOptions:

ts
import { chat } from "@tanstack/ai";
import { mistralText } from "@tanstack/ai-mistral";

const stream = chat({
  adapter: mistralText("mistral-large-latest"),
  messages: [{ role: "user", content: "Hello!" }],
  modelOptions: {
    temperature: 0.7,
    top_p: 0.9,
    max_tokens: 1024,
    random_seed: 42,
    stop: ["END"],
    safe_prompt: true,
    frequency_penalty: 0.5,
    presence_penalty: 0.5,
    parallel_tool_calls: true,
    tool_choice: "auto",
  },
});

All sampling parameters — including temperature, top_p, and max_tokens — go inside modelOptions using Mistral's native (snake_case) names.

Environment Variables

Set your API key in environment variables:

shell
MISTRAL_API_KEY=...

Get a key from the Mistral Console.

Supported Models

Chat

  • mistral-large-latest — Flagship general-purpose model (128k context)

  • mistral-medium-latest — Multimodal mid-tier model with vision

  • mistral-small-latest — Fast, affordable multimodal model with vision

  • ministral-8b-latest — 8B edge model

  • ministral-3b-latest — 3B edge model

  • open-mistral-nemo — Open 12B model

Code

  • codestral-latest — Code-specialized model (256k context)

Vision

  • pixtral-large-latest — Large vision model

  • pixtral-12b-2409 — 12B vision model

Reasoning

Reasoning content is streamed as REASONING_* events before the final answer.

  • magistral-medium-latest — Mid-tier reasoning model

  • magistral-small-latest — Small reasoning model

    See Mistral's model comparison for full details.

API Reference

mistralText(model, config?)

Creates a Mistral text adapter using the MISTRAL_API_KEY environment variable.

Parameters:

  • model — The model name (e.g., 'mistral-large-latest')

  • config.serverURL? — Custom base URL (optional)

  • config.defaultHeaders? — Headers to attach to every request (optional)

    Returns: A Mistral text adapter instance.

createMistralText(model, apiKey, config?)

Creates a Mistral text adapter with an explicit API key.

Parameters:

  • model — The model name

  • apiKey — Your Mistral API key

  • config.serverURL? — Custom base URL (optional)

  • config.defaultHeaders? — Headers to attach to every request (optional)

    Returns: A Mistral text adapter instance.

Limitations

  • Embeddings: Use the Mistral SDK directly for mistral-embed.

  • Image / Audio / Video Generation: Mistral does not provide these endpoints. Use OpenAI, Gemini, or fal.ai.

  • Text-to-Speech / Transcription: Not supported. Use OpenAI or ElevenLabs.

Next Steps

Provider Tools

Mistral does not currently expose provider-specific tool factories. Define your own tools with toolDefinition() from @tanstack/ai.

See Tools for the general tool-definition flow, or Provider Tools for other providers' native-tool offerings.