Adds an EU-hosted provider covering embedding, expansion and chat on one
OpenAI-compatible endpoint (https://api.mistral.ai/v1), so a brain that must
stay inside EU jurisdiction does not need a US hop for any AI touchpoint.
Every field is measured against the live API, not copied from docs:
- mistral-embed is fixed 1024 dims and accepts no dimension parameter.
Both spellings are rejected: {"dimensions": N} returns 400 extra_forbidden,
{"output_dimension": N} returns 400 "does not support output_dimension".
The generic openai-compatible branch of dimsProviderOptions() already falls
through to `return undefined` for these model ids, so nothing is emitted.
Same contract as voyage-4-nano, pinned by a negative assertion in the test.
- max_batch_tokens 65536: a 65,286-token batch is accepted, 66,960 returns
400 code 3210 "Too many tokens overall, split into more batches."
- chars_per_token 2: the value is a DIVISOR in splitByTokenBudget()
(estTokens = text.length / charsPerToken), so lower is the conservative
direction. The module default of 4 assumes English prose; a German-language
corpus measured 3.58 chars/token, which the default overshoots toward
overflow.
codestral-embed is deliberately left out: it returns 1536 dims, and a
touchpoint carries a single default_dims. Listing it under a 1024 declaration
is the mixed-dim case embedding-dim-check.ts exists to catch.
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>