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
- Python:
agentping.instrument_mistral()in agent-ping-python - TypeScript:
instrumentMistralin agent-ping-typescript
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.