@@ -118,12 +118,16 @@ function isLocalBaseUrl(baseUrl: string): boolean {
118118}
119119
120120const GEMINI_DEFAULT_BASE_URL = 'https://generativelanguage.googleapis.com/v1beta/openai'
121+ const MISTRAL_DEFAULT_BASE_URL = 'https://api.mistral.ai/v1'
121122const GITHUB_COPILOT_BASE = 'https://api.githubcopilot.com'
122123
123124function currentBaseUrl ( ) : string {
124125 if ( isTruthy ( process . env . CLAUDE_CODE_USE_GEMINI ) ) {
125126 return process . env . GEMINI_BASE_URL ?? GEMINI_DEFAULT_BASE_URL
126127 }
128+ if ( isTruthy ( process . env . CLAUDE_CODE_USE_MISTRAL ) ) {
129+ return process . env . MISTRAL_BASE_URL ?? process . env . MISTRAL_DEFAULT_BASE_URL
130+ }
127131 if ( isTruthy ( process . env . CLAUDE_CODE_USE_GITHUB ) ) {
128132 return process . env . OPENAI_BASE_URL ?? GITHUB_COPILOT_BASE
129133 }
@@ -155,6 +159,31 @@ function checkGeminiEnv(): CheckResult[] {
155159 return results
156160}
157161
162+ function checkMistralEnv ( ) : CheckResult [ ] {
163+ const results : CheckResult [ ] = [ ]
164+ const model = process . env . MISTRAL_MODEL
165+ const key = process . env . MISTRAL_API_KEY
166+ const baseUrl = process . env . MISTRAL_BASE_URL ?? MISTRAL_DEFAULT_BASE_URL
167+
168+ results . push ( pass ( 'Provider mode' , 'Mistral provider enabled.' ) )
169+
170+ if ( ! model ) {
171+ results . push ( pass ( 'MISTRAL_MODEL' , 'Not set. Default will be used at runtime.' ) )
172+ } else {
173+ results . push ( pass ( 'MISTRAL_MODEL' , model ) )
174+ }
175+
176+ results . push ( pass ( 'MISTRAL_BASE_URL' , baseUrl ) )
177+
178+ if ( ! key ) {
179+ results . push ( fail ( 'MISTRAL_API_KEY' , 'Missing. Set MISTRAL_API_KEY.' ) )
180+ } else {
181+ results . push ( pass ( 'MISTRAL_API_KEY' , 'Configured.' ) )
182+ }
183+
184+ return results
185+ }
186+
158187function checkGithubEnv ( ) : CheckResult [ ] {
159188 const results : CheckResult [ ] = [ ]
160189 const baseUrl = process . env . OPENAI_BASE_URL ?? GITHUB_COPILOT_BASE
@@ -186,12 +215,17 @@ function checkOpenAIEnv(): CheckResult[] {
186215 const results : CheckResult [ ] = [ ]
187216 const useGemini = isTruthy ( process . env . CLAUDE_CODE_USE_GEMINI )
188217 const useGithub = isTruthy ( process . env . CLAUDE_CODE_USE_GITHUB )
218+ const useMistral = isTruthy ( process . env . CLAUDE_CODE_USE_MISTRAL )
189219 const useOpenAI = isTruthy ( process . env . CLAUDE_CODE_USE_OPENAI )
190220
191221 if ( useGemini ) {
192222 return checkGeminiEnv ( )
193223 }
194224
225+ if ( useMistral ) {
226+ return checkMistralEnv ( )
227+ }
228+
195229 if ( useGithub && ! useOpenAI ) {
196230 return checkGithubEnv ( )
197231 }
@@ -268,8 +302,9 @@ async function checkBaseUrlReachability(): Promise<CheckResult> {
268302 const useGemini = isTruthy ( process . env . CLAUDE_CODE_USE_GEMINI )
269303 const useOpenAI = isTruthy ( process . env . CLAUDE_CODE_USE_OPENAI )
270304 const useGithub = isTruthy ( process . env . CLAUDE_CODE_USE_GITHUB )
305+ const useMistral = isTruthy ( process . env . CLAUDE_CODE_USE_MISTRAL )
271306
272- if ( ! useGemini && ! useOpenAI && ! useGithub ) {
307+ if ( ! useGemini && ! useOpenAI && ! useGithub && ! useMistral ) {
273308 return pass ( 'Provider reachability' , 'Skipped (OpenAI-compatible mode disabled).' )
274309 }
275310
@@ -326,6 +361,8 @@ async function checkBaseUrlReachability(): Promise<CheckResult> {
326361 } )
327362 } else if ( useGemini && ( process . env . GEMINI_API_KEY ?? process . env . GOOGLE_API_KEY ) ) {
328363 headers . Authorization = `Bearer ${ process . env . GEMINI_API_KEY ?? process . env . GOOGLE_API_KEY } `
364+ } else if ( useMistral && process . env . MISTRAL_API_KEY ) {
365+ headers . Authorization = `Bearer ${ process . env . MISTRAL_API_KEY } `
329366 } else if ( process . env . OPENAI_API_KEY ) {
330367 headers . Authorization = `Bearer ${ process . env . OPENAI_API_KEY } `
331368 }
@@ -373,7 +410,8 @@ function checkOllamaProcessorMode(): CheckResult {
373410 if (
374411 ! isTruthy ( process . env . CLAUDE_CODE_USE_OPENAI ) ||
375412 isTruthy ( process . env . CLAUDE_CODE_USE_GEMINI ) ||
376- isTruthy ( process . env . CLAUDE_CODE_USE_GITHUB )
413+ isTruthy ( process . env . CLAUDE_CODE_USE_GITHUB ) ||
414+ isTruthy ( process . env . CLAUDE_CODE_USE_MISTRAL )
377415 ) {
378416 return pass ( 'Ollama processor mode' , 'Skipped (OpenAI-compatible mode disabled).' )
379417 }
@@ -425,6 +463,14 @@ function serializeSafeEnvSummary(): Record<string, string | boolean> {
425463 GEMINI_API_KEY_SET : Boolean ( process . env . GEMINI_API_KEY ?? process . env . GOOGLE_API_KEY ) ,
426464 }
427465 }
466+ if ( isTruthy ( process . env . CLAUDE_CODE_USE_MISTRAL ) ) {
467+ return {
468+ CLAUDE_CODE_USE_MISTRAL : true ,
469+ MISTRAL_MODEL : process . env . MISTRAL_MODEL ?? '(unset, default: devstral-latest)' ,
470+ MISTRAL_BASE_URL : process . env . MISTRAL_BASE_URL ?? 'https://api.mistral.ai/v1' ,
471+ MISTRAL_API_KEY_SET : Boolean ( process . env . MISTRAL_API_KEY ) ,
472+ }
473+ }
428474 if (
429475 isTruthy ( process . env . CLAUDE_CODE_USE_GITHUB ) &&
430476 ! isTruthy ( process . env . CLAUDE_CODE_USE_OPENAI )
0 commit comments