| 13 | * - codestral-embed-2505 (dimension: 1536) |
| 14 | */ |
| 15 | export class MistralEmbedder implements IEmbedder { |
| 16 | private readonly openAICompatibleEmbedder: OpenAICompatibleEmbedder |
| 17 | private static readonly MISTRAL_BASE_URL = "https://api.mistral.ai/v1" |
| 18 | private static readonly DEFAULT_MODEL = "codestral-embed-2505" |
| 19 | private readonly modelId: string |
| 20 | |
| 21 | /** |
| 22 | * Creates a new Mistral embedder |
| 23 | * @param apiKey The Mistral API key for authentication |
| 24 | * @param modelId The model ID to use (defaults to codestral-embed-2505) |
| 25 | */ |
| 26 | constructor(apiKey: string, modelId?: string) { |
| 27 | if (!apiKey) { |
| 28 | throw new Error(t("embeddings:validation.apiKeyRequired")) |
| 29 | } |
| 30 | |
| 31 | // Use provided model or default |
| 32 | this.modelId = modelId || MistralEmbedder.DEFAULT_MODEL |
| 33 | |
| 34 | // Create an OpenAI Compatible embedder with Mistral's configuration |
| 35 | this.openAICompatibleEmbedder = new OpenAICompatibleEmbedder( |
| 36 | MistralEmbedder.MISTRAL_BASE_URL, |
| 37 | apiKey, |
| 38 | this.modelId, |
| 39 | MAX_ITEM_TOKENS, // This is the max token limit (8191), not the embedding dimension |
| 40 | ) |
| 41 | } |
| 42 | |
| 43 | /** |
| 44 | * Creates embeddings for the given texts using Mistral's embedding API |
| 45 | * @param texts Array of text strings to embed |
| 46 | * @param model Optional model identifier (uses constructor model if not provided) |
| 47 | * @returns Promise resolving to embedding response |
| 48 | */ |
| 49 | async createEmbeddings(texts: string[], model?: string): Promise<EmbeddingResponse> { |
| 50 | try { |
| 51 | // Use the provided model or fall back to the instance's model |
| 52 | const modelToUse = model || this.modelId |
| 53 | return await this.openAICompatibleEmbedder.createEmbeddings(texts, modelToUse) |
| 54 | } catch (error) { |
| 55 | TelemetryService.instance.captureEvent(TelemetryEventName.CODE_INDEX_ERROR, { |
| 56 | error: error instanceof Error ? error.message : String(error), |
| 57 | stack: error instanceof Error ? error.stack : undefined, |
| 58 | location: "MistralEmbedder:createEmbeddings", |
| 59 | }) |
| 60 | throw error |
| 61 | } |
| 62 | } |
| 63 | |
| 64 | /** |
| 65 | * Validates the Mistral embedder configuration by delegating to the underlying OpenAI-compatible embedder |
| 66 | * @returns Promise resolving to validation result with success status and optional error message |
| 67 | */ |
| 68 | async validateConfiguration(): Promise<{ valid: boolean; error?: string }> { |
| 69 | try { |
| 70 | // Delegate validation to the OpenAI-compatible embedder |
| 71 | // The error messages will be specific to Mistral since we're using Mistral's base URL |
| 72 | return await this.openAICompatibleEmbedder.validateConfiguration() |
nothing calls this directly
no outgoing calls
no test coverage detected