@@ -142,11 +142,33 @@ export const useSettings = () => {
142142 useEffect ( ( ) => {
143143 if ( ! isStorageLoaded ) return ;
144144
145+ const customModelsList = settings . customModels
146+ ? settings . customModels . split ( / [ \n , ] + / ) . map ( m => m . trim ( ) ) . filter ( Boolean )
147+ : [ ] ;
148+
149+ // 先展示用户手填的模型,避免接口拉取卡住时选择器一直为空。
150+ if ( customModelsList . length > 0 ) {
151+ setAvailableModels ( currentModels => {
152+ const mergedModels = [ ...new Set ( [ ...currentModels , ...customModelsList ] ) ] ;
153+ return mergedModels . length === currentModels . length &&
154+ mergedModels . every ( ( model , index ) => model === currentModels [ index ] )
155+ ? currentModels
156+ : mergedModels ;
157+ } ) ;
158+ } else {
159+ setAvailableModels ( currentModels => {
160+ if ( currentModels . length === 0 ) return currentModels ;
161+ return [ ] ;
162+ } ) ;
163+ }
164+
145165 // 获取实际使用的 API Key 和 Base URL
146166 let actualApiKey = '' ;
147167 let actualApiBaseUrl = '' ;
148168
149- if ( settings . useCustomApi ) {
169+ const shouldUseManualConfig = settings . useCustomApi || ! envConfig ;
170+
171+ if ( shouldUseManualConfig ) {
150172 // 用户启用了自定义配置
151173 const apiKeys = settings . apiKey || [ ] ;
152174 actualApiKey = apiKeys . length > 0 ? apiKeys [ 0 ] : '' ;
@@ -157,39 +179,40 @@ export const useSettings = () => {
157179 actualApiBaseUrl = envConfig . apiBaseUrl ;
158180 }
159181
160- if ( actualApiKey ) {
161- const llmService = createLLMService ( settings ) ;
162- llmService . getAvailableModels ( actualApiKey , actualApiBaseUrl ) . then ( fetchedModels => {
163- // 解析用户自定义的模型列表
164- const customModelsList = settings . customModels
165- ? settings . customModels . split ( / [ \n , ] + / ) . map ( m => m . trim ( ) ) . filter ( Boolean )
166- : [ ] ;
167-
168- // 合并 fetch 到的模型和用户自定义的模型(去重)
169- const allModels = [ ...new Set ( [ ...fetchedModels , ...customModelsList ] ) ] ;
170-
171- if ( allModels . length === 0 ) return ;
172-
173- setAvailableModels ( allModels ) ;
174- setSettings ( current => {
175- const newDefaults : Partial < Settings > = { } ;
176- // 如果 lastSelectedModel 不在模型列表中,清空它(会自动使用第一个模型)
177- if ( current . lastSelectedModel && ! allModels . includes ( current . lastSelectedModel ) ) {
178- newDefaults . lastSelectedModel = undefined ;
179- }
180- // 标题生成模型逻辑:优先使用环境变量,否则取列表最后一位
181- const envTitleModel = process . env . TITLE_MODEL_NAME ?. trim ( ) ;
182- if ( envTitleModel ) {
183- // 环境变量有配置,使用环境变量
184- newDefaults . titleGenerationModel = envTitleModel ;
185- } else if ( ! allModels . includes ( current . titleGenerationModel ) ) {
186- // 环境变量没有配置,取列表最后一位
187- newDefaults . titleGenerationModel = allModels [ allModels . length - 1 ] || '' ;
188- }
189- return Object . keys ( newDefaults ) . length > 0 ? { ...current , ...newDefaults } : current ;
190- } ) ;
182+ const applyModels = ( fetchedModels : string [ ] ) => {
183+ const allModels = [ ...new Set ( [ ...fetchedModels , ...customModelsList ] ) ] ;
184+
185+ if ( allModels . length === 0 ) return ;
186+
187+ setAvailableModels ( allModels ) ;
188+ setSettings ( current => {
189+ const newDefaults : Partial < Settings > = { } ;
190+ // 如果 lastSelectedModel 不在模型列表中,清空它(会自动使用第一个模型)
191+ if ( current . lastSelectedModel && ! allModels . includes ( current . lastSelectedModel ) ) {
192+ newDefaults . lastSelectedModel = undefined ;
193+ }
194+ // 标题生成模型逻辑:优先使用环境变量,否则取列表最后一位
195+ const envTitleModel = process . env . TITLE_MODEL_NAME ?. trim ( ) ;
196+ if ( envTitleModel ) {
197+ // 环境变量有配置,使用环境变量
198+ newDefaults . titleGenerationModel = envTitleModel ;
199+ } else if ( ! allModels . includes ( current . titleGenerationModel ) ) {
200+ // 环境变量没有配置,取列表最后一位
201+ newDefaults . titleGenerationModel = allModels [ allModels . length - 1 ] || '' ;
202+ }
203+ return Object . keys ( newDefaults ) . length > 0 ? { ...current , ...newDefaults } : current ;
191204 } ) ;
205+ } ;
206+
207+ if ( ! actualApiKey ) {
208+ applyModels ( [ ] ) ;
209+ return ;
192210 }
211+
212+ const llmService = createLLMService ( settings ) ;
213+ llmService . getAvailableModels ( actualApiKey , actualApiBaseUrl )
214+ . then ( applyModels )
215+ . catch ( ( ) => applyModels ( [ ] ) ) ;
193216 } , [ isStorageLoaded , settings . apiKey , settings . apiBaseUrl , settings . llmProvider , settings . useCustomApi , settings . customModels ] ) ;
194217
195218 return { settings, setSettings, availableModels, isStorageLoaded } ;
0 commit comments