Gap
Mistral's chat completion API supports prompt caching, and reports it via a nested usage.prompt_tokens_details.cached_tokens field. The Braintrust Mistral integration's usage-metrics parser only handles flat numeric fields on the usage object and silently drops any nested *_details dict, so cached_tokens never reaches a span's metrics — even though the provider is reporting it.
What is missing
_parse_usage_metrics (py/src/braintrust/integrations/mistral/tracing.py:415-429) does:
def _parse_usage_metrics(usage: Any) -> dict[str, float]:
usage_data = _normalized_mistral_dict(usage)
if usage_data is None:
return {}
metrics = {}
for key, value in usage_data.items():
if not _is_supported_metric_value(value):
continue
metrics[_TOKEN_NAME_MAP.get(key, _camel_to_snake(key))] = float(value)
...
_is_supported_metric_value rejects non-numeric values, so when usage_data["prompt_tokens_details"] is itself a dict (e.g. {"cached_tokens": 128}), the whole prompt_tokens_details entry is skipped — there is no recursive/nested-details handling. _normalized_mistral_dict (tracing.py:250) just type-checks/normalizes to a plain dict; it does not flatten nested detail objects either.
This is a materially lower level of detail than comparable usage-metric parsing elsewhere in this repo. The shared OpenAI-shape helper _parse_openai_usage_metrics (py/src/braintrust/integrations/utils.py:649-690) explicitly walks any *_tokens_details dict and emits {prefix}_{nested_name} metrics (e.g. prompt_cached_tokens), and providers that reuse it (LiteLLM, OpenRouter) capture cached/reasoning token details generically. Mistral's parser has no equivalent path.
Braintrust docs status
unclear/docs-drift — the Mistral integration page documents the TypeScript SDK as capturing "cached and reasoning tokens when the provider reports them," but the Python section only lists "Token usage metrics (prompt, completion, total) and request metadata" — no mention of cached or reasoning tokens for Python. This matches the code: the TS side has parity for this field, the Python parser does not.
Upstream sources
Braintrust docs sources
Local repo files inspected
py/src/braintrust/integrations/mistral/tracing.py:39-41 — _TOKEN_NAME_MAP = {"total_tokens": "tokens"}, no details-prefix map
py/src/braintrust/integrations/mistral/tracing.py:250-252 — _normalized_mistral_dict, does not recurse into nested dict values
py/src/braintrust/integrations/mistral/tracing.py:415-429 — _parse_usage_metrics, drops any non-numeric (dict) usage entry, including prompt_tokens_details
py/src/braintrust/integrations/utils.py:649-690 — _parse_openai_usage_metrics, the comparable helper other integrations reuse that does walk *_tokens_details dicts
py/src/braintrust/integrations/litellm/tracing.py — imports/uses _parse_openai_usage_metrics (aliased _parse_metrics_from_usage), confirming nested detail capture works generically elsewhere
py/src/braintrust/integrations/openrouter/tracing.py:33-52 — explicit prompt_tokens_details/completion_tokens_details prefix mapping, another working comparable
Gap
Mistral's chat completion API supports prompt caching, and reports it via a nested
usage.prompt_tokens_details.cached_tokensfield. The Braintrust Mistral integration's usage-metrics parser only handles flat numeric fields on theusageobject and silently drops any nested*_detailsdict, socached_tokensnever reaches a span's metrics — even though the provider is reporting it.What is missing
_parse_usage_metrics(py/src/braintrust/integrations/mistral/tracing.py:415-429) does:_is_supported_metric_valuerejects non-numeric values, so whenusage_data["prompt_tokens_details"]is itself a dict (e.g.{"cached_tokens": 128}), the wholeprompt_tokens_detailsentry is skipped — there is no recursive/nested-details handling._normalized_mistral_dict(tracing.py:250) just type-checks/normalizes to a plain dict; it does not flatten nested detail objects either.This is a materially lower level of detail than comparable usage-metric parsing elsewhere in this repo. The shared OpenAI-shape helper
_parse_openai_usage_metrics(py/src/braintrust/integrations/utils.py:649-690) explicitly walks any*_tokens_detailsdict and emits{prefix}_{nested_name}metrics (e.g.prompt_cached_tokens), and providers that reuse it (LiteLLM, OpenRouter) capture cached/reasoning token details generically. Mistral's parser has no equivalent path.Braintrust docs status
unclear/docs-drift — the Mistral integration page documents the TypeScript SDK as capturing "cached and reasoning tokens when the provider reports them," but the Python section only lists "Token usage metrics (prompt, completion, total) and request metadata" — no mention of cached or reasoning tokens for Python. This matches the code: the TS side has parity for this field, the Python parser does not.Upstream sources
usage.prompt_tokens_details.cached_tokenson chat completion responses): https://docs.mistral.ai/studio-api/conversations/advanced/prompt-cachingBraintrust docs sources
Local repo files inspected
py/src/braintrust/integrations/mistral/tracing.py:39-41—_TOKEN_NAME_MAP = {"total_tokens": "tokens"}, no details-prefix mappy/src/braintrust/integrations/mistral/tracing.py:250-252—_normalized_mistral_dict, does not recurse into nested dict valuespy/src/braintrust/integrations/mistral/tracing.py:415-429—_parse_usage_metrics, drops any non-numeric (dict)usageentry, includingprompt_tokens_detailspy/src/braintrust/integrations/utils.py:649-690—_parse_openai_usage_metrics, the comparable helper other integrations reuse that does walk*_tokens_detailsdictspy/src/braintrust/integrations/litellm/tracing.py— imports/uses_parse_openai_usage_metrics(aliased_parse_metrics_from_usage), confirming nested detail capture works generically elsewherepy/src/braintrust/integrations/openrouter/tracing.py:33-52— explicitprompt_tokens_details/completion_tokens_detailsprefix mapping, another working comparable