diff --git a/src/renderer/src/aiCore/clients/openai/OpenAIApiClient.ts b/src/renderer/src/aiCore/clients/openai/OpenAIApiClient.ts index eeaa1c7bad..199868e2d4 100644 --- a/src/renderer/src/aiCore/clients/openai/OpenAIApiClient.ts +++ b/src/renderer/src/aiCore/clients/openai/OpenAIApiClient.ts @@ -10,7 +10,6 @@ import { isQwenMTModel, isQwenReasoningModel, isReasoningModel, - isSupportedReasoningEffortGrokModel, isSupportedReasoningEffortModel, isSupportedReasoningEffortOpenAIModel, isSupportedThinkingTokenClaudeModel, @@ -199,15 +198,8 @@ export class OpenAIAPIClient extends OpenAIBaseClient< } } - // Grok models - if (isSupportedReasoningEffortGrokModel(model)) { - return { - reasoning_effort: reasoningEffort - } - } - - // OpenAI models - if (isSupportedReasoningEffortOpenAIModel(model)) { + // Grok models/Perplexity models/OpenAI models + if (isSupportedReasoningEffortModel(model)) { return { reasoning_effort: reasoningEffort } diff --git a/src/renderer/src/config/models.ts b/src/renderer/src/config/models.ts index 02b89cb938..aa124002ad 100644 --- a/src/renderer/src/config/models.ts +++ b/src/renderer/src/config/models.ts @@ -1975,6 +1975,12 @@ export const SYSTEM_MODELS: Record = { provider: 'perplexity', name: 'sonar', group: 'Sonar' + }, + { + id: 'sonar-deep-research', + provider: 'perplexity', + name: 'sonar-deep-research', + group: 'Sonar' } ], infini: [ @@ -2406,7 +2412,13 @@ export const GEMINI_SEARCH_REGEX = new RegExp('gemini-2\\..*', 'i') export const OPENAI_NO_SUPPORT_DEV_ROLE_MODELS = ['o1-preview', 'o1-mini'] -export const PERPLEXITY_SEARCH_MODELS = ['sonar-pro', 'sonar', 'sonar-reasoning', 'sonar-reasoning-pro'] +export const PERPLEXITY_SEARCH_MODELS = [ + 'sonar-pro', + 'sonar', + 'sonar-reasoning', + 'sonar-reasoning-pro', + 'sonar-deep-research' +] export function isTextToImageModel(model: Model): boolean { return TEXT_TO_IMAGE_REGEX.test(model.id) @@ -2547,7 +2559,11 @@ export function isSupportedReasoningEffortModel(model?: Model): boolean { return false } - return isSupportedReasoningEffortOpenAIModel(model) || isSupportedReasoningEffortGrokModel(model) + return ( + isSupportedReasoningEffortOpenAIModel(model) || + isSupportedReasoningEffortGrokModel(model) || + isSupportedReasoningEffortPerplexityModel(model) + ) } export function isGrokModel(model?: Model): boolean { @@ -2683,6 +2699,20 @@ export const isHunyuanReasoningModel = (model?: Model): boolean => { return isSupportedThinkingTokenHunyuanModel(model) || model.id.toLowerCase().includes('hunyuan-t1') } +export const isPerplexityReasoningModel = (model?: Model): boolean => { + if (!model) { + return false + } + + const baseName = getLowerBaseModelName(model.id, '/') + return isSupportedReasoningEffortPerplexityModel(model) || baseName.includes('reasoning') +} + +export const isSupportedReasoningEffortPerplexityModel = (model: Model): boolean => { + const baseName = getLowerBaseModelName(model.id, '/') + return baseName.includes('sonar-deep-research') +} + export function isReasoningModel(model?: Model): boolean { if (!model || isEmbeddingModel(model) || isRerankModel(model) || isTextToImageModel(model)) { return false @@ -2708,6 +2738,7 @@ export function isReasoningModel(model?: Model): boolean { isQwenReasoningModel(model) || isGrokReasoningModel(model) || isHunyuanReasoningModel(model) || + isPerplexityReasoningModel(model) || model.id.toLowerCase().includes('glm-z1') || model.id.toLowerCase().includes('magistral') || model.id.toLowerCase().includes('minimax-m1') diff --git a/src/renderer/src/pages/home/Inputbar/ThinkingButton.tsx b/src/renderer/src/pages/home/Inputbar/ThinkingButton.tsx index a23a34d27a..2dd4ea960d 100644 --- a/src/renderer/src/pages/home/Inputbar/ThinkingButton.tsx +++ b/src/renderer/src/pages/home/Inputbar/ThinkingButton.tsx @@ -10,6 +10,7 @@ import { GEMINI_FLASH_MODEL_REGEX, isDoubaoThinkingAutoModel, isSupportedReasoningEffortGrokModel, + isSupportedReasoningEffortPerplexityModel, isSupportedThinkingTokenDoubaoModel, isSupportedThinkingTokenGeminiModel, isSupportedThinkingTokenHunyuanModel, @@ -44,7 +45,8 @@ const MODEL_SUPPORTED_OPTIONS: Record = { qwen: ['off', 'low', 'medium', 'high'], qwen_3235ba22b_thinking: ['low', 'medium', 'high'], doubao: ['off', 'auto', 'high'], - hunyuan: ['off', 'auto'] + hunyuan: ['off', 'auto'], + perplexity: ['low', 'medium', 'high'] } // 选项转换映射表:当选项不支持时使用的替代选项 @@ -68,6 +70,7 @@ const ThinkingButton: FC = ({ ref, model, assistant, ToolbarButton }): Re const isQwen3235BA22BThinkingModel = model.id.includes('qwen3-235b-a22b-thinking') const isDoubaoModel = isSupportedThinkingTokenDoubaoModel(model) const isHunyuanModel = isSupportedThinkingTokenHunyuanModel(model) + const isPerplexityModel = isSupportedReasoningEffortPerplexityModel(model) const currentReasoningEffort = useMemo(() => { return assistant.settings?.reasoning_effort || 'off' @@ -91,14 +94,16 @@ const ThinkingButton: FC = ({ ref, model, assistant, ToolbarButton }): Re } if (isDoubaoModel) return 'doubao' if (isHunyuanModel) return 'hunyuan' + if (isPerplexityModel) return 'perplexity' return 'default' }, [ isGeminiModel, isGrokModel, isQwenModel, isDoubaoModel, - isHunyuanModel, isGeminiFlashModel, + isHunyuanModel, + isPerplexityModel, isQwen3235BA22BThinkingModel ])