fix(chat): BYOK dialect defaults to Passthrough; dedicated Mistral dialect
C1 (decision): custom/BYOK ChatCompletions entries defaulted to the Kimi
dialect, leaking Kimi-specific body mutations (thinking:{…} control,
replayed reasoning_content, schema rewrites) to arbitrary third-party
OpenAI-compatible servers. The default is now Passthrough (vanilla
OpenAI semantics), with ONE exception mirroring Pi's base-url quirk
sniffing: entries pointed at the house/Kimi coding endpoint keep the
Kimi dialect. Registry platforms are unaffected (all declare
explicitly).
C2 (Pi mistral-conversations normalizer): Mistral requires tool-call ids
of EXACTLY nine [a-zA-Z0-9] chars; even same-session synthesized UUIDs
violate it. New ChatCompat::Mistral = StrictOpenAi behavior + the
normalizer — strip non-alphanumerics, keep exact-9 ids, else FNV-1a →
base36 (build-stable, deterministic across requests for prefix-cache
stability) with collision retry; ONE map covers tool_calls[].id and
tool_call_id so pairing survives. The mistral registry row and the
persisted 'mistral' serde value both resolve to it (pre-rename Mistral
sessions gain the contract automatically); Cerebras/NVIDIA stay on
StrictOpenAi untouched.
Verified: models+sampling-types+sampler+chat-state+shell all green,
clippy clean.
This commit is contained in:
@@ -70,9 +70,12 @@ pub enum PlatformChatCompat {
|
||||
Kimi,
|
||||
DeepSeek,
|
||||
Passthrough,
|
||||
/// Strict OpenAI-compatible validator (Mistral, Cerebras) — strips
|
||||
/// Strict OpenAI-compatible validator (Cerebras, NVIDIA) — strips
|
||||
/// `stream_options` and private fields.
|
||||
StrictOpenAi,
|
||||
/// Mistral: StrictOpenAi plus its exactly-9-alphanumeric tool-call id
|
||||
/// contract (foreign/OpenAI-style ids are deterministically remapped).
|
||||
Mistral,
|
||||
}
|
||||
|
||||
/// How a platform's API key rides requests (listing, validation, inference).
|
||||
@@ -599,10 +602,12 @@ const MISTRAL_SPEC: PlatformSpec = PlatformSpec {
|
||||
wire_serves_metadata: false,
|
||||
wire_api: PlatformWireApi::ChatCompletions,
|
||||
listing: ListingDialect::OpenAi,
|
||||
// Mistral's strict validator 422s on `stream_options`, and its reasoning
|
||||
// models return array content — the StrictOpenAi dialect strips
|
||||
// stream_options; the response deserializer handles arrays universally.
|
||||
chat_compat: PlatformChatCompat::StrictOpenAi,
|
||||
// Mistral's strict validator 422s on `stream_options`, its reasoning
|
||||
// models return array content, and tool-call ids must be EXACTLY nine
|
||||
// `[a-zA-Z0-9]` chars — the Mistral dialect strips stream_options and
|
||||
// deterministically remaps non-conforming (foreign/OpenAI-style) ids;
|
||||
// the response deserializer handles arrays universally.
|
||||
chat_compat: PlatformChatCompat::Mistral,
|
||||
key_header: PlatformKeyHeader::Bearer,
|
||||
// The listing carries embed/moderation/OCR entries; keep tool-calling
|
||||
// chat models only.
|
||||
|
||||
Reference in New Issue
Block a user