"""Mistral La Plateforme provider. Implements both LLMProvider (codestral-latest for SQL, mistral-large-latest for NL) and EmbeddingProvider (mistral-embed). All three models go through the OpenAI- compatible /v1 endpoint at api.mistral.ai. """ from __future__ import annotations from openai import APIError, OpenAI from nl_sql.llm.providers._openai_compat import chat_complete from nl_sql.llm.providers.base import ( EmbedRequest, EmbedResponse, GenerateRequest, GenerateResponse, ProviderError, ) class MistralProvider: name: str = "mistral" def __init__( self, api_key: str, gen_model: str = "codestral-latest", embed_model: str = "mistral-embed", base_url: str = "https://api.mistral.ai/v1", ) -> None: if not api_key: raise ProviderError("MistralProvider requires non-empty api_key") self.model = gen_model self.embed_model = embed_model self._client = OpenAI(api_key=api_key, base_url=base_url) def generate(self, req: GenerateRequest) -> GenerateResponse: return chat_complete(self._client, self.model, req) def embed(self, req: EmbedRequest) -> EmbedResponse: try: response = self._client.embeddings.create( model=self.embed_model, input=req.texts, ) except APIError as exc: raise ProviderError( f"embeddings.create failed for model={self.embed_model}: {exc}" ) from exc vectors = [item.embedding for item in response.data] return EmbedResponse(vectors=vectors, model=response.model or self.embed_model)