local adapter = {} adapter.name = "mistral" adapter.version = "2.0.0" adapter.endpoint = "/v1/chat/completions" adapter.headers = {} -- Mistral API is OpenAI-compatible, just passes through function adapter.transform_request(raw_body) local ok, req = pcall(json.decode, raw_body) if not ok then return raw_body end req.model = req.model or "mistral-large-latest" req.temperature = req.temperature or 0.7 req.max_tokens = req.max_tokens or 4096 req.stream = req.stream or false -- The gateway's private control fields are GONE from the body (v2): the -- neutral `thinking` field carries that intent and each adapter maps it in -- its own protocol terms. These upstreams have no thinking switch at all, -- so the field is simply dropped here — which is what the nil-ing below -- used to do, except the field being dropped is no longer the kernel's -- private one. req.thinking = nil req.extra_body = nil return json.encode(req) end function adapter.transform_response(raw_body) -- 非流式 OpenAI 响应 → 统一信封。此前在 openai/groq/kimicode/mistral/github -- 五个适配器里**逐字节相同**(各 2206B,diff 为空),已抽到共享前导。 return __prelude.openai_response(raw_body) end function adapter.transform_stream_chunk(raw_chunk) -- 标准 OpenAI SSE → 统一信封。该实现此前在 groq/kimicode/mistral/github -- 四个适配器里**逐字节重复**(各 2211B),已抽到共享前导。 return __prelude.openai_stream_chunk(raw_chunk) end -- 错误收敛:Mistral 用顶层 {message="...", type="..."}(非嵌套 error) function adapter.transform_error(status, body) local ok, resp = pcall(json.decode, body) if not ok or type(resp) ~= "table" then return nil end if type(resp.message) == "string" then return resp.message end return nil end return adapter