From 9d063bb0f91cb1f9a71014060ac628186bef0f53 Mon Sep 17 00:00:00 2001 From: luy <12696648@qq.com> Date: Thu, 28 Aug 2025 04:29:12 +0800 Subject: [PATCH 1/8] fix: Correctly parse Gemini reasoning for both new `thought` field and legacy `` tags. --- .../providers/geminiProvider.ts | 75 +++++++------------ 1 file changed, 27 insertions(+), 48 deletions(-) diff --git a/src/main/presenter/llmProviderPresenter/providers/geminiProvider.ts b/src/main/presenter/llmProviderPresenter/providers/geminiProvider.ts index a01420db7..a10ee538b 100644 --- a/src/main/presenter/llmProviderPresenter/providers/geminiProvider.ts +++ b/src/main/presenter/llmProviderPresenter/providers/geminiProvider.ts @@ -934,6 +934,7 @@ export class GeminiProvider extends BaseLLMProvider { let isInThinkTag = false let toolUseDetected = false let usageMetadata: GenerateContentResponseUsageMetadata | undefined + let isNewThoughtFormatDetected = false // 流处理循环 for await (const chunk of result) { @@ -987,6 +988,7 @@ export class GeminiProvider extends BaseLLMProvider { for (const part of chunk.candidates[0].content.parts) { // 检查是否是思考内容 (新格式) if ((part as any).thought === true && part.text) { + isNewThoughtFormatDetected = true thoughtContent += part.text } else if (part.text) { content += part.text @@ -1012,71 +1014,48 @@ export class GeminiProvider extends BaseLLMProvider { type: 'reasoning', reasoning_content: thoughtContent } - thoughtContent = '' // 清空已发送的思考内容 } if (!content) continue - buffer += content - - // 处理思考标签 - if (buffer.includes('') && !isInThinkTag) { - const thinkStart = buffer.indexOf('') + if (isNewThoughtFormatDetected) { + yield { + type: 'text', + content: content + } + } else { + buffer += content - // 发送标签前的文本 - if (thinkStart > 0) { - yield { - type: 'text', - content: buffer.substring(0, thinkStart) + if (buffer.includes('') && !isInThinkTag) { + const thinkStart = buffer.indexOf('') + if (thinkStart > 0) { + yield { type: 'text', content: buffer.substring(0, thinkStart) } } + buffer = buffer.substring(thinkStart + 7) + isInThinkTag = true } - buffer = buffer.substring(thinkStart + 7) - isInThinkTag = true - continue - } - - // 处理思考标签结束 - if (isInThinkTag && buffer.includes('')) { - const thinkEnd = buffer.indexOf('') - const reasoningContent = buffer.substring(0, thinkEnd) - - // 发送推理内容 - if (reasoningContent) { - yield { - type: 'reasoning', - reasoning_content: reasoningContent + if (isInThinkTag && buffer.includes('')) { + const thinkEnd = buffer.indexOf('') + const reasoningContent = buffer.substring(0, thinkEnd) + if (reasoningContent) { + yield { + type: 'reasoning', + reasoning_content: reasoningContent + } } + buffer = buffer.substring(thinkEnd + 8) + isInThinkTag = false } - buffer = buffer.substring(thinkEnd + 8) - isInThinkTag = false - - // 如果还有剩余内容,继续处理 - if (buffer) { + if (!isInThinkTag && buffer) { yield { type: 'text', content: buffer } buffer = '' } - - continue - } - - // 如果在思考标签内,不输出内容 - if (isInThinkTag) { - continue - } - - // 正常输出文本内容 - yield { - type: 'text', - content: content } - - // 内容已经发送,清空buffer避免重复 - buffer = '' } if (usageMetadata) { @@ -1091,7 +1070,7 @@ export class GeminiProvider extends BaseLLMProvider { } // 处理剩余缓冲区内容 - if (buffer) { + if (!isNewThoughtFormatDetected && buffer) { if (isInThinkTag) { yield { type: 'reasoning', From 44b518f4620d73789a85fe8288abf35db001cc7f Mon Sep 17 00:00:00 2001 From: yyhhyyyyyy Date: Thu, 28 Aug 2025 09:47:52 +0800 Subject: [PATCH 2/8] fix: correct Gemini 2.5 Flash Image Preview model capabilities and token limits (#802) --- .../configPresenter/modelDefaultSettings.ts | 11 ++++++ .../configPresenter/providerModelSettings.ts | 36 +++++++++++++++---- .../providers/geminiProvider.ts | 5 +-- 3 files changed, 43 insertions(+), 9 deletions(-) diff --git a/src/main/presenter/configPresenter/modelDefaultSettings.ts b/src/main/presenter/configPresenter/modelDefaultSettings.ts index 02fdd8e81..43391769c 100644 --- a/src/main/presenter/configPresenter/modelDefaultSettings.ts +++ b/src/main/presenter/configPresenter/modelDefaultSettings.ts @@ -348,6 +348,17 @@ export const defaultModelsSettings: DefaultModelSetting[] = [ reasoning: true, thinkingBudget: -1 // 动态思维 }, + { + id: 'google/gemini-2.5-flash-image-preview', + name: 'Gemini 2.5 Flash Image Preview', + temperature: 0.7, + maxTokens: 32768, + contextLength: 32768, + match: ['google/gemini-2.5-flash-image-preview', 'gemini-2.5-flash-image-preview'], + vision: true, + functionCall: false, + reasoning: false + }, { id: 'models/gemini-2.5-flash', name: 'Gemini 2.5 Flash', diff --git a/src/main/presenter/configPresenter/providerModelSettings.ts b/src/main/presenter/configPresenter/providerModelSettings.ts index 79b7bc37e..7f74629e1 100644 --- a/src/main/presenter/configPresenter/providerModelSettings.ts +++ b/src/main/presenter/configPresenter/providerModelSettings.ts @@ -182,15 +182,15 @@ export const providerModelSettings: Record Date: Thu, 28 Aug 2025 11:02:36 +0800 Subject: [PATCH 3/8] fix: update Gemini 2.5 Flash Lite model config --- .../configPresenter/modelDefaultSettings.ts | 14 +++++++++++++- .../configPresenter/providerModelSettings.ts | 11 +++++++++++ .../providers/geminiProvider.ts | 12 ++++++++++++ 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/src/main/presenter/configPresenter/modelDefaultSettings.ts b/src/main/presenter/configPresenter/modelDefaultSettings.ts index 43391769c..863fd7f97 100644 --- a/src/main/presenter/configPresenter/modelDefaultSettings.ts +++ b/src/main/presenter/configPresenter/modelDefaultSettings.ts @@ -371,11 +371,23 @@ export const defaultModelsSettings: DefaultModelSetting[] = [ reasoning: true, thinkingBudget: -1 // 动态思维 }, + { + id: 'models/gemini-2.5-flash-lite', + name: 'Gemini 2.5 Flash-Lite', + temperature: 0.7, + maxTokens: 65535, + contextLength: 1048576, + match: ['models/gemini-2.5-flash-lite', 'gemini-2.5-flash-lite'], + vision: true, + functionCall: true, + reasoning: true, + thinkingBudget: -1 // 动态思维 + }, { id: 'models/gemini-2.5-flash-lite-preview-06-17', name: 'Gemini 2.5 Flash-Lite Preview', temperature: 0.7, - maxTokens: 65536, + maxTokens: 65535, contextLength: 1048576, match: ['models/gemini-2.5-flash-lite-preview-06-17', 'gemini-2.5-flash-lite-preview'], vision: true, diff --git a/src/main/presenter/configPresenter/providerModelSettings.ts b/src/main/presenter/configPresenter/providerModelSettings.ts index 7f74629e1..614b111b9 100644 --- a/src/main/presenter/configPresenter/providerModelSettings.ts +++ b/src/main/presenter/configPresenter/providerModelSettings.ts @@ -214,6 +214,17 @@ export const providerModelSettings: Record Date: Thu, 28 Aug 2025 11:21:42 +0800 Subject: [PATCH 4/8] Update src/main/presenter/configPresenter/providerModelSettings.ts Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --- src/main/presenter/configPresenter/providerModelSettings.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/presenter/configPresenter/providerModelSettings.ts b/src/main/presenter/configPresenter/providerModelSettings.ts index 614b111b9..d152cf04f 100644 --- a/src/main/presenter/configPresenter/providerModelSettings.ts +++ b/src/main/presenter/configPresenter/providerModelSettings.ts @@ -196,8 +196,9 @@ export const providerModelSettings: Record Date: Thu, 28 Aug 2025 13:55:10 +0800 Subject: [PATCH 5/8] feat: add TokenFlux.ai provider support (#804) * feat: add TokenFlux.ai provider support Add comprehensive TokenFlux.ai integration with OpenAI-compatible API support: - Implement TokenFluxProvider extending OpenAICompatibleProvider - Add provider configuration with official endpoints and documentation links - Support dynamic model fetching with TokenFlux-specific format parsing - Include vision and function calling capability detection from API response - Add TokenFlux icon integration in ModelIcon component - Enable seamless UI integration with existing provider settings Resolves #613 * fix: lint --- .../presenter/configPresenter/providers.ts | 16 ++ .../presenter/llmProviderPresenter/index.ts | 4 + .../providers/tokenfluxProvider.ts | 213 ++++++++++++++++++ .../threadPresenter/contentEnricher.ts | 2 +- .../src/assets/llm-icons/tokenflux-color.svg | 93 ++++++++ .../src/components/icons/ModelIcon.vue | 2 + 6 files changed, 329 insertions(+), 1 deletion(-) create mode 100644 src/main/presenter/llmProviderPresenter/providers/tokenfluxProvider.ts create mode 100644 src/renderer/src/assets/llm-icons/tokenflux-color.svg diff --git a/src/main/presenter/configPresenter/providers.ts b/src/main/presenter/configPresenter/providers.ts index cc87c9d63..e594fea57 100644 --- a/src/main/presenter/configPresenter/providers.ts +++ b/src/main/presenter/configPresenter/providers.ts @@ -93,6 +93,22 @@ export const DEFAULT_PROVIDERS: LLM_PROVIDER_BASE[] = [ } }, + { + id: 'tokenflux', + name: 'TokenFlux', + apiType: 'openai', + apiKey: '', + baseUrl: 'https://tokenflux.ai/v1', + enable: false, + websites: { + official: 'https://tokenflux.ai/', + apiKey: 'https://tokenflux.ai/dashboard/api-keys', + docs: 'https://docs.tokenflux.ai/', + models: 'https://docs.tokenflux.ai/api-reference', + defaultBaseUrl: 'https://tokenflux.ai/v1' + } + }, + { id: 'openai-responses', name: 'OpenAI Responses', diff --git a/src/main/presenter/llmProviderPresenter/index.ts b/src/main/presenter/llmProviderPresenter/index.ts index 38ddc160a..f6e21e912 100644 --- a/src/main/presenter/llmProviderPresenter/index.ts +++ b/src/main/presenter/llmProviderPresenter/index.ts @@ -19,6 +19,7 @@ import { SiliconcloudProvider } from './providers/siliconcloudProvider' import { eventBus, SendTarget } from '@/eventbus' import { OpenAICompatibleProvider } from './providers/openAICompatibleProvider' import { PPIOProvider } from './providers/ppioProvider' +import { TokenFluxProvider } from './providers/tokenfluxProvider' import { OLLAMA_EVENTS } from '@/events' import { ConfigPresenter } from '../configPresenter' import { GeminiProvider } from './providers/geminiProvider' @@ -166,6 +167,9 @@ export class LLMProviderPresenter implements ILlmProviderPresenter { if (provider.id === 'ppio') { return new PPIOProvider(provider, this.configPresenter) } + if (provider.id === 'tokenflux') { + return new TokenFluxProvider(provider, this.configPresenter) + } if (provider.id === 'deepseek') { return new DeepseekProvider(provider, this.configPresenter) } diff --git a/src/main/presenter/llmProviderPresenter/providers/tokenfluxProvider.ts b/src/main/presenter/llmProviderPresenter/providers/tokenfluxProvider.ts new file mode 100644 index 000000000..28f44a8f5 --- /dev/null +++ b/src/main/presenter/llmProviderPresenter/providers/tokenfluxProvider.ts @@ -0,0 +1,213 @@ +import { LLM_PROVIDER, LLMResponse, ChatMessage, KeyStatus, MODEL_META } from '@shared/presenter' +import { OpenAICompatibleProvider } from './openAICompatibleProvider' +import { ConfigPresenter } from '../../configPresenter' + +// Define interface for TokenFlux API model response +interface TokenFluxModelResponse { + id: string + name: string + description: string + provider: string + pricing: { + input: number + output: number + } + context_length: number + supports_streaming: boolean + supports_vision: boolean +} + +// Define interface for TokenFlux models list response +interface TokenFluxModelsResponse { + object: string + data: TokenFluxModelResponse[] +} + +export class TokenFluxProvider extends OpenAICompatibleProvider { + constructor(provider: LLM_PROVIDER, configPresenter: ConfigPresenter) { + super(provider, configPresenter) + } + + async completions( + messages: ChatMessage[], + modelId: string, + temperature?: number, + maxTokens?: number + ): Promise { + return this.openAICompletion(messages, modelId, temperature, maxTokens) + } + + async summaries( + text: string, + modelId: string, + temperature?: number, + maxTokens?: number + ): Promise { + return this.openAICompletion( + [ + { + role: 'user', + content: `You need to summarize the user's conversation into a title of no more than 10 words, with the title language matching the user's primary language, without using punctuation or other special symbols:\n${text}` + } + ], + modelId, + temperature, + maxTokens + ) + } + + async generateText( + prompt: string, + modelId: string, + temperature?: number, + maxTokens?: number + ): Promise { + return this.openAICompletion( + [ + { + role: 'user', + content: prompt + } + ], + modelId, + temperature, + maxTokens + ) + } + + /** + * Get current API key status from TokenFlux + * @returns Promise API key status information + */ + public async getKeyStatus(): Promise { + if (!this.provider.apiKey) { + throw new Error('API key is required') + } + + // TokenFlux uses OpenAI-compatible API, so we can use the models endpoint for key validation + const response = await fetch(`${this.provider.baseUrl}/models`, { + method: 'GET', + headers: { + Authorization: `Bearer ${this.provider.apiKey}`, + 'Content-Type': 'application/json' + } + }) + + if (!response.ok) { + const errorText = await response.text() + throw new Error( + `TokenFlux API key check failed: ${response.status} ${response.statusText} - ${errorText}` + ) + } + + // TokenFlux doesn't provide quota information in the models endpoint response + // So we return a simple success status + return { + limit_remaining: 'Available', + remainNum: undefined + } + } + + /** + * Override check method to use TokenFlux's API key status endpoint + * @returns Promise<{ isOk: boolean; errorMsg: string | null }> + */ + public async check(): Promise<{ isOk: boolean; errorMsg: string | null }> { + try { + await this.getKeyStatus() + return { isOk: true, errorMsg: null } + } catch (error: unknown) { + let errorMessage = 'An unknown error occurred during TokenFlux API key check.' + if (error instanceof Error) { + errorMessage = error.message + } else if (typeof error === 'string') { + errorMessage = error + } + + console.error('TokenFlux API key check failed:', error) + return { isOk: false, errorMsg: errorMessage } + } + } + + /** + * Override fetchOpenAIModels to parse TokenFlux specific model data and update model configurations + * @param options - Request options + * @returns Promise - Array of model metadata + */ + protected async fetchOpenAIModels(options?: { timeout: number }): Promise { + try { + const response = await this.openai.models.list(options) + // console.log('TokenFlux models response:', JSON.stringify(response, null, 2)) + + const models: MODEL_META[] = [] + + // Cast response to TokenFlux format + const tokenfluxResponse = response as unknown as TokenFluxModelsResponse + + for (const model of tokenfluxResponse.data) { + // Extract model information + const modelId = model.id + const modelName = model.name || modelId + const description = model.description || '' + + // Determine capabilities based on TokenFlux model data + const hasVision = model.supports_vision || false + const hasFunctionCalling = true // Most TokenFlux models should support function calling + + // Get existing model configuration first + const existingConfig = this.configPresenter.getModelConfig(modelId, this.provider.id) + + // Extract configuration values with proper fallback priority: API -> existing config -> default + const contextLength = model.context_length || existingConfig.contextLength || 4096 + const maxTokens = existingConfig.maxTokens || Math.min(contextLength / 2, 4096) + + // Build new configuration based on API response + const newConfig = { + contextLength: contextLength, + maxTokens: maxTokens, + functionCall: hasFunctionCalling, + vision: hasVision, + reasoning: existingConfig.reasoning, // Keep existing reasoning setting + temperature: existingConfig.temperature, // Keep existing temperature + type: existingConfig.type // Keep existing type + } + + // Check if configuration has changed + const configChanged = + existingConfig.contextLength !== newConfig.contextLength || + existingConfig.maxTokens !== newConfig.maxTokens || + existingConfig.functionCall !== newConfig.functionCall || + existingConfig.vision !== newConfig.vision + + // Update configuration if changed + if (configChanged) { + this.configPresenter.setModelConfig(modelId, this.provider.id, newConfig) + } + + // Create MODEL_META object + const modelMeta: MODEL_META = { + id: modelId, + name: modelName, + group: 'default', + providerId: this.provider.id, + isCustom: false, + contextLength: contextLength, + maxTokens: maxTokens, + description: description, + vision: hasVision, + functionCall: hasFunctionCalling, + reasoning: existingConfig.reasoning || false + } + + models.push(modelMeta) + } + + console.log(`Processed ${models.length} TokenFlux models with dynamic configuration updates`) + return models + } catch (error) { + console.error('Error fetching TokenFlux models:', error) + // Fallback to parent implementation + return super.fetchOpenAIModels(options) + } + } +} diff --git a/src/main/presenter/threadPresenter/contentEnricher.ts b/src/main/presenter/threadPresenter/contentEnricher.ts index 226f16c24..dd8411b42 100644 --- a/src/main/presenter/threadPresenter/contentEnricher.ts +++ b/src/main/presenter/threadPresenter/contentEnricher.ts @@ -178,7 +178,7 @@ export class ContentEnricher { lengthLimit = configValue } } - } catch (error) { + } catch { // 忽略错误,使用默认值 } diff --git a/src/renderer/src/assets/llm-icons/tokenflux-color.svg b/src/renderer/src/assets/llm-icons/tokenflux-color.svg new file mode 100644 index 000000000..c012d7442 --- /dev/null +++ b/src/renderer/src/assets/llm-icons/tokenflux-color.svg @@ -0,0 +1,93 @@ + + + + + + + + + + + diff --git a/src/renderer/src/components/icons/ModelIcon.vue b/src/renderer/src/components/icons/ModelIcon.vue index 28bbe5757..782b78f52 100644 --- a/src/renderer/src/components/icons/ModelIcon.vue +++ b/src/renderer/src/components/icons/ModelIcon.vue @@ -40,6 +40,7 @@ import sunoColorIcon from '@/assets/llm-icons/suno.svg?url' import syncColorIcon from '@/assets/llm-icons/sync.svg?url' import rwkvColorIcon from '@/assets/llm-icons/rwkv.svg?url' import ppioColorIcon from '@/assets/llm-icons/ppio-color.svg?url' +import tokenfluxColorIcon from '@/assets/llm-icons/tokenflux-color.svg?url' import moonshotColorIcon from '@/assets/llm-icons/moonshot.svg?url' import openrouterColorIcon from '@/assets/llm-icons/openrouter.svg?url' import geminiColorIcon from '@/assets/llm-icons/gemini-color.svg?url' @@ -111,6 +112,7 @@ const icons = { spark: sparkColorIcon, stability: stabilityColorIcon, ppio: ppioColorIcon, + tokenflux: tokenfluxColorIcon, qingyan: qingyanColorIcon, qwen: qwenColorIcon, moonshot: moonshotColorIcon, From 860aec4c13134b48a640d1a3327ea0d493cc6eeb Mon Sep 17 00:00:00 2001 From: luy <12696648@qq.com> Date: Thu, 28 Aug 2025 14:15:18 +0800 Subject: [PATCH 6/8] fix: markdown rendering of fixed --- .../src/components/markdown/MarkdownRenderer.vue | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/renderer/src/components/markdown/MarkdownRenderer.vue b/src/renderer/src/components/markdown/MarkdownRenderer.vue index d3f765d37..b1308c11a 100644 --- a/src/renderer/src/components/markdown/MarkdownRenderer.vue +++ b/src/renderer/src/components/markdown/MarkdownRenderer.vue @@ -9,6 +9,7 @@ /> + + From 96cecd3d94341c510a6a5ef515122e039b9f3ee5 Mon Sep 17 00:00:00 2001 From: luy <12696648@qq.com> Date: Thu, 28 Aug 2025 14:25:24 +0800 Subject: [PATCH 7/8] chore: update all gemini model-configs --- .../configPresenter/modelDefaultSettings.ts | 66 +++++++++++-------- .../configPresenter/providerModelSettings.ts | 15 ++--- .../providers/geminiProvider.ts | 52 +++++++++------ 3 files changed, 79 insertions(+), 54 deletions(-) diff --git a/src/main/presenter/configPresenter/modelDefaultSettings.ts b/src/main/presenter/configPresenter/modelDefaultSettings.ts index 863fd7f97..23deb1b94 100644 --- a/src/main/presenter/configPresenter/modelDefaultSettings.ts +++ b/src/main/presenter/configPresenter/modelDefaultSettings.ts @@ -336,6 +336,7 @@ export const defaultModelsSettings: DefaultModelSetting[] = [ }, // Gemini 系列模型 + // ref: https://ai.google.dev/gemini-api/docs/models { id: 'gemini-2.5-pro', name: 'Gemini 2.5 Pro', @@ -349,23 +350,24 @@ export const defaultModelsSettings: DefaultModelSetting[] = [ thinkingBudget: -1 // 动态思维 }, { - id: 'google/gemini-2.5-flash-image-preview', - name: 'Gemini 2.5 Flash Image Preview', + id: 'models/gemini-2.5-flash', + name: 'Gemini 2.5 Flash', temperature: 0.7, - maxTokens: 32768, - contextLength: 32768, - match: ['google/gemini-2.5-flash-image-preview', 'gemini-2.5-flash-image-preview'], + maxTokens: 65535, + contextLength: 1048576, + match: ['models/gemini-2.5-flash', 'gemini-2.5-flash'], vision: true, - functionCall: false, - reasoning: false + functionCall: true, + reasoning: true, + thinkingBudget: -1 // 动态思维 }, { - id: 'models/gemini-2.5-flash', - name: 'Gemini 2.5 Flash', + id: 'models/gemini-2.5-flash-lite', + name: 'Gemini 2.5 Flash-Lite', temperature: 0.7, maxTokens: 65535, contextLength: 1048576, - match: ['models/gemini-2.5-flash', 'gemini-2.5-flash'], + match: ['models/gemini-2.5-flash-lite', 'gemini-2.5-flash-lite'], vision: true, functionCall: true, reasoning: true, @@ -393,30 +395,53 @@ export const defaultModelsSettings: DefaultModelSetting[] = [ vision: true, functionCall: true, reasoning: true, - thinkingBudget: 0 // 默认不思考 + thinkingBudget: -1 // 动态思维 }, { id: 'models/gemini-2.0-flash', name: 'Gemini 2.0 Flash', temperature: 0.7, - maxTokens: 8192, + maxTokens: 8191, contextLength: 1048576, match: ['models/gemini-2.0-flash', 'gemini-2.0-flash'], vision: true, functionCall: true, - reasoning: true + reasoning: true //Experimental }, { id: 'models/gemini-2.0-flash-lite', name: 'Gemini 2.0 Flash Lite', temperature: 0.7, - maxTokens: 8192, + maxTokens: 8191, contextLength: 1048576, match: ['models/gemini-2.0-flash-lite', 'gemini-2.0-flash-lite'], vision: true, functionCall: true, reasoning: false }, + { + id: 'models/gemini-1.5-flash', + name: 'Gemini 1.5 Flash', + temperature: 0.7, + maxTokens: 8191, + contextLength: 1048576, + match: ['models/gemini-1.5-flash', 'gemini-1.5-flash'], + vision: true, + functionCall: true, + reasoning: false + }, + { + id: 'google/gemini-2.5-flash-image-preview', + name: 'Gemini 2.5 Flash Image Preview', + temperature: 0.7, + maxTokens: 32768, + contextLength: 32768, + match: ['google/gemini-2.5-flash-image-preview', 'gemini-2.5-flash-image-preview'], + vision: true, + functionCall: false, + reasoning: false, + type: ModelType.ImageGeneration + }, { id: 'models/gemini-2.0-flash-preview-image-generation', name: 'Gemini 2.0 Flash Preview Image Generation', @@ -428,21 +453,10 @@ export const defaultModelsSettings: DefaultModelSetting[] = [ 'gemini-2.0-flash-preview-image-generation' ], vision: true, - functionCall: true, + functionCall: false, reasoning: false, type: ModelType.ImageGeneration }, - { - id: 'models/gemini-1.5-flash', - name: 'Gemini 1.5 Flash', - temperature: 0.7, - maxTokens: 8192, - contextLength: 1048576, - match: ['models/gemini-1.5-flash', 'gemini-1.5-flash'], - vision: true, - functionCall: true, - reasoning: false - }, // DeepSeek系列模型配置 { id: 'deepseek-prover-v2-671b', diff --git a/src/main/presenter/configPresenter/providerModelSettings.ts b/src/main/presenter/configPresenter/providerModelSettings.ts index d152cf04f..03a43bb58 100644 --- a/src/main/presenter/configPresenter/providerModelSettings.ts +++ b/src/main/presenter/configPresenter/providerModelSettings.ts @@ -174,7 +174,7 @@ export const providerModelSettings: Record Date: Thu, 28 Aug 2025 14:27:45 +0800 Subject: [PATCH 8/8] Update src/renderer/src/components/markdown/MarkdownRenderer.vue Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --- src/renderer/src/components/markdown/MarkdownRenderer.vue | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/renderer/src/components/markdown/MarkdownRenderer.vue b/src/renderer/src/components/markdown/MarkdownRenderer.vue index b1308c11a..283db62f3 100644 --- a/src/renderer/src/components/markdown/MarkdownRenderer.vue +++ b/src/renderer/src/components/markdown/MarkdownRenderer.vue @@ -41,8 +41,8 @@ const nodeComponents = { id: v.id, type: v.artifactType, title: v.artifactTitle, - language: v.node.code, - content: v.node.code, + language: v.language ?? v.node?.lang ?? v.node?.language ?? 'plaintext', + content: v.node.code, status: 'loaded' }, messageId,