Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export class DashscopeProvider extends OpenAICompatibleProvider {

// List of models that support enable_search parameter (internet search)
private static readonly ENABLE_SEARCH_MODELS: string[] = [
'qwen3-max-preview',
'qwen-max',
'qwen-plus',
'qwen-plus-latest',
Expand All @@ -44,8 +45,7 @@ export class DashscopeProvider extends OpenAICompatibleProvider {
'qwen-turbo',
'qwen-turbo-latest',
'qwen-turbo-2025-07-15',
'qwq-plus',
'qwen3-max-preview'
'qwq-plus'
]

constructor(provider: LLM_PROVIDER, configPresenter: IConfigPresenter) {
Expand Down
50 changes: 45 additions & 5 deletions src/renderer/src/components/ChatConfig.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<script setup lang="ts">
import { useI18n } from 'vue-i18n'
import { computed, watch } from 'vue'
import { computed, watch, ref } from 'vue'
import { useSettingsStore } from '@/stores/settings'
import { Label } from '@/components/ui/label'
import { Slider } from '@/components/ui/slider'
import { Icon } from '@iconify/vue'
Expand Down Expand Up @@ -68,6 +69,26 @@ const emit = defineEmits<{

const { t } = useI18n()
const langStore = useLanguageStore()
const settingsStore = useSettingsStore()
const modelReasoning = ref(false)

const getModelReasoning = async () => {
if (!props.modelId || !props.providerId) return false
try {
const modelConfig = await settingsStore.getModelConfig(props.modelId, props.providerId)
return modelConfig.reasoning || false
} catch (error) {
return false
}
}

watch(
() => [props.modelId, props.providerId],
async () => {
modelReasoning.value = await getModelReasoning()
},
{ immediate: true }
)
// Create computed properties for slider values (which expect arrays)
const temperatureValue = computed({
get: () => [props.temperature],
Expand Down Expand Up @@ -105,11 +126,29 @@ const showThinkingBudget = computed(() => {
const isGemini = props.providerId === 'gemini'
const isGemini25 = props.modelId?.includes('gemini-2.5')

// Qwen3 系列
// DashScope
const isDashscope = props.providerId === 'dashscope'
const isQwen3 = props.modelId?.includes('qwen3')
const modelId = props.modelId?.toLowerCase() || ''
const supportedQwenThinkingModels = [
// Open source versions
'qwen3-235b-a22b',
'qwen3-32b',
'qwen3-30b-a3b',
'qwen3-14b',
'qwen3-8b',
'qwen3-4b',
'qwen3-1.7b',
'qwen3-0.6b',
// Commercial versions
'qwen-plus',
'qwen-flash',
'qwen-turbo'
]
const isQwenThinking = supportedQwenThinkingModels.some((supportedModel) =>
modelId.includes(supportedModel)
)

return (isGemini && isGemini25) || (isDashscope && isQwen3)
return (isGemini && isGemini25) || (isDashscope && isQwenThinking && modelReasoning.value)
Comment on lines +129 to +151
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Qwen thinking-budget range is inconsistent with ModelConfigDialog (caps too low for qwen-plus/turbo/flash).

Here you gate Qwen commercial models, but getQwen3MaxBudget() below only returns OS caps; UI cap becomes 81,920 vs 500,000 in ModelConfigDialog. Unify ranges.

Apply this diff to extend the cap used by the chat config:

 const getQwen3MaxBudget = (): number => {
   const modelId = props.modelId?.toLowerCase() || ''

   // 根据不同的 Qwen3 模型返回不同的最大值
   if (modelId.includes('qwen3-235b-a22b') || modelId.includes('qwen3-30b-a3b')) {
     return 81920
   } else if (
     modelId.includes('qwen3-32b') ||
     modelId.includes('qwen3-14b') ||
     modelId.includes('qwen3-8b') ||
     modelId.includes('qwen3-4b')
   ) {
     return 38912
   } else if (modelId.includes('qwen3-1.7b') || modelId.includes('qwen3-0.6b')) {
     return 20000
+  } else if (
+    modelId.includes('qwen-plus') ||
+    modelId.includes('qwen-turbo') ||
+    modelId.includes('qwen-flash')
+  ) {
+    // Align with ModelConfigDialog thinking budget for commercial Qwen models
+    return 500000
   }

   // 默认值
   return 81920
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// DashScope
const isDashscope = props.providerId === 'dashscope'
const isQwen3 = props.modelId?.includes('qwen3')
const modelId = props.modelId?.toLowerCase() || ''
const supportedQwenThinkingModels = [
// Open source versions
'qwen3-235b-a22b',
'qwen3-32b',
'qwen3-30b-a3b',
'qwen3-14b',
'qwen3-8b',
'qwen3-4b',
'qwen3-1.7b',
'qwen3-0.6b',
// Commercial versions
'qwen-plus',
'qwen-flash',
'qwen-turbo'
]
const isQwenThinking = supportedQwenThinkingModels.some((supportedModel) =>
modelId.includes(supportedModel)
)
return (isGemini && isGemini25) || (isDashscope && isQwen3)
return (isGemini && isGemini25) || (isDashscope && isQwenThinking && modelReasoning.value)
const getQwen3MaxBudget = (): number => {
const modelId = props.modelId?.toLowerCase() || ''
// 根据不同的 Qwen3 模型返回不同的最大值
if (modelId.includes('qwen3-235b-a22b') || modelId.includes('qwen3-30b-a3b')) {
return 81920
} else if (
modelId.includes('qwen3-32b') ||
modelId.includes('qwen3-14b') ||
modelId.includes('qwen3-8b') ||
modelId.includes('qwen3-4b')
) {
return 38912
} else if (modelId.includes('qwen3-1.7b') || modelId.includes('qwen3-0.6b')) {
return 20000
} else if (
modelId.includes('qwen-plus') ||
modelId.includes('qwen-turbo') ||
modelId.includes('qwen-flash')
) {
// Align with ModelConfigDialog thinking budget for commercial Qwen models
return 500000
}
// 默认值
return 81920
}

})

// 是否显示搜索配置 - 支持 Dashscope 的特定模型
Expand All @@ -118,8 +157,9 @@ const showSearchConfig = computed(() => {

if (!isDashscope || !props.modelId) return false

// 支持搜索的模型列表
// Dashscope - ENABLE_SEARCH_MODELS
const enableSearchModels = [
'qwen3-max-preview',
'qwen3-max',
'qwen-max',
'qwen-plus',
Expand Down
53 changes: 42 additions & 11 deletions src/renderer/src/components/settings/ModelConfigDialog.vue
Original file line number Diff line number Diff line change
Expand Up @@ -544,11 +544,7 @@ const loadConfig = async () => {
}
}

if (
props.providerId === 'dashscope' &&
props.modelId.includes('qwen3') &&
config.value.thinkingBudget === undefined
) {
if (props.providerId === 'dashscope' && config.value.thinkingBudget === undefined) {
const thinkingConfig = getThinkingBudgetConfig(props.modelId)
if (thinkingConfig) {
config.value.thinkingBudget = thinkingConfig.defaultValue
Expand Down Expand Up @@ -707,6 +703,19 @@ const getThinkingBudgetConfig = (modelId: string) => {
}
}

if (
modelId.includes('qwen-plus') ||
modelId.includes('qwen-turbo') ||
modelId.includes('qwen-flash')
) {
return {
min: 0,
max: 500000,
defaultValue: 500000,
canDisable: true
}
}

return null // 不支持的模型
}

Expand Down Expand Up @@ -737,26 +746,48 @@ const showGeminiThinkingBudget = computed(() => {
const showQwen3ThinkingBudget = computed(() => {
const isDashscope = props.providerId === 'dashscope'
const hasReasoning = config.value.reasoning
const isQwen3Model = props.modelId.includes('qwen3')
const modelId = props.modelId.toLowerCase()
// DashScope - ENABLE_THINKING_MODELS
const supportedThinkingModels = [
// Open source versions
'qwen3-235b-a22b',
'qwen3-32b',
'qwen3-30b-a3b',
'qwen3-14b',
'qwen3-8b',
'qwen3-4b',
'qwen3-1.7b',
'qwen3-0.6b',
// Commercial versions
'qwen-plus',
'qwen-flash',
'qwen-turbo'
]
const isSupported = supportedThinkingModels.some((supportedModel) =>
modelId.includes(supportedModel)
)
const modelConfig = getThinkingBudgetConfig(props.modelId)
const isSupported = modelConfig !== null
return isDashscope && hasReasoning && isQwen3Model && isSupported
const hasValidConfig = modelConfig !== null
return isDashscope && hasReasoning && isSupported && hasValidConfig
})

// 是否显示DashScope搜索配置
const showDashScopeSearch = computed(() => {
const isDashscope = props.providerId === 'dashscope'
const modelId = props.modelId.toLowerCase()
// DashScope 支持搜索的模型列表
const supportedModels = [
// DashScope - ENABLE_SEARCH_MODELS
const supportedSearchModels = [
'qwen3-max-preview',
'qwen3-max',
'qwen-max',
'qwen-plus',
'qwen-flash',
'qwen-turbo',
'qwq-plus'
]
const isSupported = supportedModels.some((supportedModel) => modelId.includes(supportedModel))
const isSupported = supportedSearchModels.some((supportedModel) =>
modelId.includes(supportedModel)
)
return isDashscope && isSupported
})
Comment on lines +779 to 792
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

FE/BE mismatch: qwen3-max listed here but not in provider.

Same alignment issue as ChatConfig.vue; prefer adding qwen3-max to the provider allowlist.

Run to confirm:


🏁 Script executed:

#!/bin/bash
rg -n "qwen3-max" src/main src/renderer | sed 's/^/>> /'

Length of output: 624


Add ‘qwen3-max’ to backend provider allowlists
Add the pure 'qwen3-max' entry alongside 'qwen3-max-preview' in both
src/main/presenter/configPresenter/providerModelSettings.ts
src/main/presenter/llmProviderPresenter/providers/dashscopeProvider.ts

🤖 Prompt for AI Agents
src/renderer/src/components/settings/ModelConfigDialog.vue lines 779-792: the
renderer already checks for 'qwen3-max' but the backend allowlists are missing
the pure 'qwen3-max'; open
src/main/presenter/configPresenter/providerModelSettings.ts and
src/main/presenter/llmProviderPresenter/providers/dashscopeProvider.ts and add
'qwen3-max' (exact string) alongside 'qwen3-max-preview' in the provider/model
allowlist arrays, ensure formatting matches surrounding entries and update any
related type unions or checks if present.


Expand Down