Mistral

Auto-instrument the Mistral SDK (mistralai on PyPI, @mistralai/mistralai on npm). Every chat completion inside an active run emits an llm_call event with model, token usage, latency, finish reason, and tool calls. Cost is computed server-side from the rate card.

Install / enable

Python:

pip install "agentping-io[mistral]"
import agentping
from mistralai import Mistral

agentping.init()
agentping.instrument_mistral()

client = Mistral(api_key=os.environ["MISTRAL_API_KEY"])

with agentping.run("support-triage", customer_id="acme-corp"):
    reply = client.chat.complete(
        model="mistral-small-latest",
        messages=[{"role": "user", "content": "classify this ticket"}],
    )

instrument_mistral() patches chat.complete, chat.complete_async, chat.stream and chat.stream_async on the Chat resource class. Idempotent and global; call it once at module load. Supported mistralai versions: 2.x. The 0.x and 1.x clients have a different layout and are skipped with a single warning.

TypeScript:

npm install @agentping/sdk @mistralai/mistralai
import { Mistral } from "@mistralai/mistralai";
import * as agentping from "@agentping/sdk";

agentping.init({ apiKey: process.env.AGENTPING_API_KEY });

const run = agentping.run("answer-bot");
const mistral = agentping.instrumentMistral(
  new Mistral({ apiKey: process.env.MISTRAL_API_KEY }),
  { run },
);

const reply = await mistral.chat.complete({
  model: "mistral-small-latest",
  messages: [{ role: "user", content: "hi" }],
});

await run.finish({ status: "success" });

instrumentMistral returns a wrapped client covering chat.complete and chat.stream.

What's captured

Field Source
provider mistral
model The requested model, falling back to response.model
input_tokens usage.prompt_tokens
output_tokens usage.completion_tokens
finish_reason choices[0].finish_reason
tool_calls Number of message.tool_calls
latency_ms Wall-clock time of the call
stream true on chat.stream

Mistral's usage block carries no cache or reasoning breakdown, so cached_input_tokens, cache_creation_input_tokens and reasoning_tokens are never set. Embeddings (client.embeddings) and the Agents API are not instrumented; report those yourself with run.event("llm_call", {...}).

A call that raises is recorded as an llm_call with status: "error", error and exception, then re-raised.

Streaming

Both SDKs capture chat.stream (Python also chat.stream_async). Mistral yields CompletionEvent objects; the wrapper reads usage from the final event's data and emits one llm_call with stream: true once the stream is fully consumed or closed.

with agentping.run("answer-bot"):
    for event in client.chat.stream(
        model="mistral-small-latest",
        messages=[{"role": "user", "content": "explain briefly"}],
    ):
        print(event.data.choices[0].delta.content or "", end="", flush=True)
    # llm_call is emitted here

Prompt capture and time to first token

Streamed calls also report ttft_ms, the time from the request to the first delta carrying content or a tool call. Pulse charts its p95 per agent.

Prompt and completion text are off by default. Turn them on once at init, with an optional cap per piece (default 4000 characters):

agentping.init(capture_llm_content=True, llm_content_max_chars=4000)
agentping.init({ captureLlmContent: true, llmContentMaxChars: 4000 });

Each chat.complete / chat.stream call then carries input (the messages list, system message included, as the API takes it) and output (the first choice's content; text chunks joined, other chunks as markers such as [reference]). Each piece is clipped at the cap. The run page renders them as messages; see events for the wire shape.

Source / notes

Default rates ship for current Mistral models; the full list is on the LLM API pricing page. A Mistral model that is not on the default card lands with its token counts and appears in the unpriced-models list until you add its per-million rates under Spend, Rate cards; from then on every new call is priced. See Spend.