2424 @test-openrouter =" testOpenRouterKey"
2525 @test-zai =" testZAIKey"
2626 @test-minimax =" testMiniMaxKey"
27+ @test-deepseek =" testDeepSeekKey"
2728 @test-ollama =" testOllamaConnection"
2829 @test-lmstudio =" testLMStudioConnection"
2930 @reset-tests =" resetTestResults"
@@ -66,11 +67,13 @@ import VoiceModelsStep from './steps/VoiceModelsStep.vue'
6667import FinalSetupStep from ' ./steps/FinalSetupStep.vue'
6768import OpenAI from ' openai'
6869import {
70+ DEEPSEEK_OPENAI_BASE_URL ,
6971 MINIMAX_OPENAI_BASE_URL ,
7072 PROVIDER_CONFIGS ,
7173 ZAI_CODING_BASE_URL ,
7274 type AIProviderKey ,
7375} from ' ../../services/llmProviders/providerCatalog'
76+ import { listDeepSeekModelsForConfig } from ' ../../services/llmProviders/deepseek'
7477import { listMiniMaxModelsForConfig } from ' ../../services/llmProviders/minimax'
7578import { listOpenAIModelsForConfig } from ' ../../services/llmProviders/openai'
7679import { listOpenRouterModelsForConfig } from ' ../../services/llmProviders/openrouter'
@@ -111,6 +114,7 @@ const formData = reactive({
111114 VITE_OPENROUTER_API_KEY: ' ' ,
112115 VITE_ZAI_API_KEY: ' ' ,
113116 VITE_MINIMAX_API_KEY: ' ' ,
117+ VITE_DEEPSEEK_API_KEY: ' ' ,
114118 aiProvider: ' openai' as AIProviderKey ,
115119 assistantModel: openaiDefaults .assistantModel as string ,
116120 summarizationModel: openaiDefaults .summarizationModel as string ,
@@ -123,6 +127,7 @@ const formData = reactive({
123127 lmStudioBaseUrl: ' http://localhost:1234' ,
124128 zaiBaseUrl: ZAI_CODING_BASE_URL ,
125129 minimaxBaseUrl: MINIMAX_OPENAI_BASE_URL ,
130+ deepseekBaseUrl: DEEPSEEK_OPENAI_BASE_URL ,
126131 useLocalModels: false ,
127132 availableModels: [] as string [],
128133 localSttLanguage: ' auto' ,
@@ -133,6 +138,7 @@ const isTesting = reactive({
133138 openrouter: false ,
134139 zai: false ,
135140 minimax: false ,
141+ deepseek: false ,
136142 ollama: false ,
137143 lmStudio: false ,
138144})
@@ -142,6 +148,7 @@ const testResult = reactive({
142148 openrouter: { success: false , error: ' ' },
143149 zai: { success: false , error: ' ' },
144150 minimax: { success: false , error: ' ' },
151+ deepseek: { success: false , error: ' ' },
145152 ollama: { success: false , error: ' ' },
146153 lmStudio: { success: false , error: ' ' },
147154})
@@ -173,7 +180,8 @@ const canContinue = computed(() => {
173180 formData .aiProvider === ' lm-studio' ||
174181 formData .aiProvider === ' openrouter' ||
175182 formData .aiProvider === ' zai' ||
176- formData .aiProvider === ' minimax' ) &&
183+ formData .aiProvider === ' minimax' ||
184+ formData .aiProvider === ' deepseek' ) &&
177185 ! formData .VITE_OPENAI_API_KEY .trim ()
178186 ) {
179187 return false
@@ -245,6 +253,8 @@ const fetchAvailableModels = async () => {
245253 baseURL = formData .zaiBaseUrl
246254 } else if (formData .aiProvider === ' minimax' ) {
247255 baseURL = formData .minimaxBaseUrl
256+ } else if (formData .aiProvider === ' deepseek' ) {
257+ baseURL = formData .deepseekBaseUrl
248258 } else {
249259 return
250260 }
@@ -263,6 +273,20 @@ const fetchAvailableModels = async () => {
263273 return
264274 }
265275
276+ if (formData .aiProvider === ' deepseek' ) {
277+ const models = await listDeepSeekModelsForConfig (
278+ formData .VITE_DEEPSEEK_API_KEY ,
279+ baseURL
280+ )
281+ formData .availableModels = models .map (model => model .id )
282+
283+ if (formData .availableModels .length > 0 ) {
284+ formData .assistantModel = formData .availableModels [0 ]
285+ formData .summarizationModel = formData .availableModels [0 ]
286+ }
287+ return
288+ }
289+
266290 if (formData .aiProvider === ' zai' ) {
267291 const models = await listZAIModelsForConfig (
268292 formData .VITE_ZAI_API_KEY ,
@@ -414,6 +438,39 @@ const testMiniMaxKey = async () => {
414438 }
415439}
416440
441+ const testDeepSeekKey = async () => {
442+ if (! formData .VITE_DEEPSEEK_API_KEY .trim ()) {
443+ testResult .deepseek .error = ' API Key cannot be empty.'
444+ testResult .deepseek .success = false
445+ return
446+ }
447+ if (! formData .deepseekBaseUrl .trim ()) {
448+ testResult .deepseek .error = ' Base URL cannot be empty.'
449+ testResult .deepseek .success = false
450+ return
451+ }
452+
453+ isTesting .deepseek = true
454+ testResult .deepseek .error = ' '
455+ testResult .deepseek .success = false
456+
457+ try {
458+ await fetchAvailableModels ()
459+ testResult .deepseek .success = true
460+ } catch (e : any ) {
461+ testResult .deepseek .error =
462+ ' API key or OpenAI-compatible endpoint is invalid or has no permissions.'
463+ if (e .message ?.includes (' 401' )) {
464+ testResult .deepseek .error = ' Invalid API key - please check your key.'
465+ } else if (e .message ?.includes (' 429' )) {
466+ testResult .deepseek .error =
467+ ' Rate limit exceeded - please try again later.'
468+ }
469+ } finally {
470+ isTesting .deepseek = false
471+ }
472+ }
473+
417474const testOllamaConnection = async () => {
418475 if (! formData .ollamaBaseUrl .trim ()) {
419476 testResult .ollama .error = ' Ollama Base URL cannot be empty.'
@@ -499,6 +556,8 @@ const resetTestResults = () => {
499556 testResult .zai .error = ' '
500557 testResult .minimax .success = false
501558 testResult .minimax .error = ' '
559+ testResult .deepseek .success = false
560+ testResult .deepseek .error = ' '
502561 testResult .ollama .success = false
503562 testResult .ollama .error = ' '
504563 testResult .lmStudio .success = false
@@ -522,6 +581,12 @@ const isCurrentProviderTested = () => {
522581 Boolean (formData .assistantModel ) &&
523582 Boolean (formData .summarizationModel )
524583 )
584+ } else if (formData .aiProvider === ' deepseek' ) {
585+ return (
586+ testResult .deepseek .success &&
587+ Boolean (formData .assistantModel ) &&
588+ Boolean (formData .summarizationModel )
589+ )
525590 } else if (formData .aiProvider === ' ollama' ) {
526591 return (
527592 testResult .ollama .success &&
0 commit comments