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.
npm install @tanstack/ai-mistralimport { chat } from "@tanstack/ai";
import { mistralText } from "@tanstack/ai-mistral";
const stream = chat({
adapter: mistralText("mistral-large-latest"),
messages: [{ role: "user", content: "Hello!" }],
});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!" }],
});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,
);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);
}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],
});Use a vision-capable model — pixtral-large-latest, pixtral-12b-2409, mistral-medium-latest, or mistral-small-latest — to send images alongside text:
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:
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.
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:
// 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.
Generate JSON that conforms to a Zod schema using Mistral's json_schema response format:
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.
Mistral exposes provider-specific options via modelOptions:
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.
Set your API key in environment variables:
MISTRAL_API_KEY=...Get a key from the Mistral Console.
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
codestral-latest — Code-specialized model (256k context)
pixtral-large-latest — Large vision model
pixtral-12b-2409 — 12B vision model
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.
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.
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.
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.
Getting Started — Learn the basics
Tools Guide — Define and call tools
Structured Outputs — Generate typed JSON
Multimodal Content — Send images and other modalities
Other Adapters — Explore other providers
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.