Skip to content

feat: support default model setting#1315

Merged
zerob13 merged 3 commits intodevfrom
feat/default-model-setting
Feb 14, 2026
Merged

feat: support default model setting#1315
zerob13 merged 3 commits intodevfrom
feat/default-model-setting

Conversation

@zerob13
Copy link
Collaborator

@zerob13 zerob13 commented Feb 14, 2026

finish #1174

Summary by CodeRabbit

  • New Features

    • Add global Default Model and Default Vision Model settings and a new "Default Models" settings section in the UI.
    • Option to set a preferred vision model used for image analysis.
  • Bug Fixes / Reliability

    • Improved fallback and retry behavior for model-driven title generation and model selection.
  • Documentation

    • Detailed implementation plan, spec, and task checklists for default-model rollout.
  • Tests

    • Unit tests for defaultModel and defaultVisionModel config behavior.
  • Localization

    • Added translation keys for default model settings in multiple locales.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 14, 2026

📝 Walkthrough

Walkthrough

Adds global defaultModel and defaultVisionModel settings, presenter APIs to get/set them, UI to manage defaults, renderer/main flows to apply defaults for new conversations (excluding ACP), and refactors ImageServer to resolve vision models at runtime from config. Includes docs, tests, and i18n updates.

Changes

Cohort / File(s) Summary
Documentation & Planning
docs/specs/default-model-settings/plan.md, docs/specs/default-model-settings/spec.md, docs/specs/default-model-settings/tasks.md
New spec, implementation plan, task breakdown, rollout phases, tests, and acceptance criteria for defaultModel & defaultVisionModel.
Config & Types
src/main/presenter/configPresenter/index.ts, src/shared/types/presenters/legacy.presenters.d.ts
Adds defaultModel and defaultVisionModel to IAppSettings and new ConfigPresenter methods: getDefaultModel/setDefaultModel, getDefaultVisionModel/setDefaultVisionModel.
Session & Title Fallbacks
src/main/presenter/sessionPresenter/index.ts, src/main/presenter/sessionPresenter/managers/conversationManager.ts, src/main/presenter/agentPresenter/utility/utilityHandler.ts
Wires ConfigPresenter into SessionPresenter; conversationManager applies global defaultModel when no provider/model supplied; utilityHandler/session title generation gains preferred-model attempt with fallback and retry logging.
ImageServer & In-memory Builder
src/main/presenter/mcpPresenter/inMemoryServers/imageServer.ts, src/main/presenter/mcpPresenter/inMemoryServers/builder.ts
ImageServer constructor args made optional; adds getEffectiveModel() to resolve provider/model from instance or global defaultVisionModel; builder ensures undefined passed for missing args.
Renderer Settings UI
src/renderer/settings/components/CommonSettings.vue, src/renderer/settings/components/common/DefaultModelSettingsSection.vue
Adds DefaultModelSettingsSection component and mounts it in CommonSettings to manage assistant/chat/vision default selections and persist via configPresenter.
Model Selection & New Thread Init
src/renderer/src/components/ModelSelect.vue, src/renderer/src/components/NewThread.vue
ModelSelect gains visionOnly prop and filters by vision capability; NewThread.initActiveModel reads and applies non-ACP defaultModel early.
MCP Server Form
src/renderer/src/components/mcp-config/mcpServerForm.vue
Removes interactive ModelSelect for imageServer, shows read-only default vision model display, derives model from config, updates parsing and watchers.
i18n
src/renderer/src/i18n/.../settings.json (11 locales)
Adds defaultModel translation block (title, chatModel, visionModel) and shortens imageModel label across locales.
Tests
test/main/presenter/configPresenter/defaultModelSettings.test.ts
Adds tests for get/set defaultModel and defaultVisionModel behavior via mocked config proxy.

Sequence Diagram(s)

sequenceDiagram
    participant User as User
    participant NewThread as NewThread.vue
    participant ConfigPresenter as ConfigPresenter
    participant ConversationManager as ConversationManager
    participant SessionPresenter as SessionPresenter

    User->>NewThread: open new chat
    NewThread->>NewThread: initActiveModel()
    alt Not ACP
        NewThread->>ConfigPresenter: getSetting('defaultModel')
        ConfigPresenter-->>NewThread: {providerId, modelId}
        NewThread->>NewThread: resolve & set active model
        NewThread->>NewThread: return early
    else ACP
        NewThread->>NewThread: fallback existing init flow
    end

    NewThread->>ConversationManager: createConversation(request)
    alt no provider/model in request
        ConversationManager->>ConfigPresenter: getDefaultModel()
        ConfigPresenter-->>ConversationManager: {providerId, modelId}
        ConversationManager->>ConversationManager: apply to defaultSettings
    end

    ConversationManager-->>SessionPresenter: conversation created
    SessionPresenter->>ConfigPresenter: getSetting('assistantModel') for titles
    SessionPresenter-->>User: display conversation
Loading
sequenceDiagram
    participant App as App
    participant ImageServer as ImageServer
    participant ConfigPresenter as ConfigPresenter
    participant LLMProvider as LLMProvider

    App->>ImageServer: new ImageServer(undefined, undefined)
    App->>ImageServer: request vision operation
    ImageServer->>ImageServer: getEffectiveModel()
    ImageServer->>ConfigPresenter: getDefaultVisionModel()
    ConfigPresenter-->>ImageServer: {providerId, modelId}
    ImageServer->>LLMProvider: call completion(resolvedProvider, resolvedModel)
    LLMProvider-->>ImageServer: result
    ImageServer-->>App: vision result
Loading
sequenceDiagram
    participant UI as DefaultModelSettingsSection
    participant ModelStore as ModelStore
    participant ConfigPresenter as ConfigPresenter

    UI->>UI: mounted() -> syncModelSelections()
    par sync selections
        UI->>ConfigPresenter: getSetting('assistantModel')
        ConfigPresenter-->>UI: assistantModel
        UI->>ModelStore: find matching assistant model
        UI->>UI: set selectedAssistantModel
    and
        UI->>ConfigPresenter: getSetting('defaultModel')
        ConfigPresenter-->>UI: defaultModel
        UI->>ModelStore: find matching chat model
        UI->>UI: set selectedChatModel
    and
        UI->>ConfigPresenter: getSetting('defaultVisionModel')
        ConfigPresenter-->>UI: defaultVisionModel
        UI->>ModelStore: filter vision-capable models
        UI->>UI: set selectedVisionModel
    end

    User->>UI: selects model
    UI->>ConfigPresenter: setSetting('defaultModel' or 'defaultVisionModel')
    ConfigPresenter->>ConfigPresenter: persist
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

  • PR #973: Adds/changes ConfigPresenter APIs and types; directly overlaps with new getDefault*/setDefault* presenter methods.
  • PR #914: Adjusts NewThread.vue initActiveModel logic; overlaps with defaultModel early-load behavior.
  • PR #1006: Refactors renderer settings into modular sections; overlaps with the addition of DefaultModelSettingsSection in CommonSettings.

Suggested labels

codex

🐇
I munched the settings carrot bright,
Picked chat and vision, set them right.
A twitch, a hop, defaults in place—
New threads start with a smiling face. 🥕

🚥 Pre-merge checks | ✅ 3 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the primary change: adding support for default model settings across the application.
Merge Conflict Detection ✅ Passed ✅ No merge conflicts detected when merging into dev

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/default-model-setting

No actionable comments were generated in the recent review. 🎉

🧹 Recent nitpick comments
src/renderer/settings/components/common/DefaultModelSettingsSection.vue (2)

281-287: Deep watch on enabledModels may fire frequently — consider debouncing.

The watcher uses { deep: true } on the entire enabledModels array, which triggers syncModelSelections (with 3 async getSetting + up to 3 setSetting calls) on every deep mutation. Consider using useDebounceFn from VueUse to avoid redundant IPC round-trips when models are being bulk-enabled/disabled.


1-107: Fixed-width w-[320px] buttons may not adapt well to all locales and screen sizes.

The model selector buttons use a hardcoded w-[320px]. Translations in some locales (e.g., German, Russian) tend to be longer and may overflow or truncate. Consider using a responsive width like w-full or min-w-[320px] max-w-full for better adaptability.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 7

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/main/presenter/mcpPresenter/inMemoryServers/imageServer.ts (1)

49-87: ⚠️ Potential issue | 🟠 Major

Default vision model is effectively hard-coded and won’t re-resolve.

The constructor pre-fills provider/model with openai/gpt-4o, so getEffectiveModel() never re-reads defaultVisionModel and never throws when it’s missing. This breaks runtime updates and the “missing default should error” requirement.

🛠️ Suggested fix: only set provider/model when explicitly passed
-  private provider: string
-  private model: string
+  private provider?: string
+  private model?: string

-  constructor(provider?: string, model?: string) {
-    const defaultVisionModel = presenter.configPresenter.getDefaultVisionModel()
-    this.provider = provider || defaultVisionModel?.providerId || 'openai'
-    this.model = model || defaultVisionModel?.modelId || 'gpt-4o'
+  constructor(provider?: string, model?: string) {
+    this.provider = provider
+    this.model = model
     this.server = new Server(
🤖 Fix all issues with AI agents
In `@src/renderer/settings/components/common/DefaultModelSettingsSection.vue`:
- Around line 97-103: The Vision ModelSelect inside
DefaultModelSettingsSection.vue is missing the exclude-providers prop, causing
ACP providers to be shown inconsistently; update the <ModelSelect> instance (the
one with :type="[ModelType.Chat, ModelType.ImageGeneration]" and
`@update`:model="handleVisionModelSelect") to add :exclude-providers="['acp']" so
it matches the other model selects and the syncModelSelections ACP filtering
logic.
- Around line 223-273: syncModelSelections lacks error handling and can produce
unhandled promise rejections; wrap the try/finally in a try/catch/finally (or
add a catch) to log errors and prevent crashes when configPresenter.getSetting
or persistModelSetting fail. Specifically, in the syncModelSelections function
catch exceptions from await calls (getSetting and persistModelSetting), use the
existing logging mechanism (or console.error/processLogger) to record the error
along with context (e.g., which setting failed), and then continue to the
finally block that resets isSyncingModelDefaults; ensure
selectedChatModel/selectedAssistantModel/selectedVisionModel assignment remains
inside the try so partial state isn't left inconsistent on error.

In `@src/renderer/src/components/mcp-config/mcpServerForm.vue`:
- Around line 62-64: The comment above the image model refs ("// imageServer
展示用(只读,来源于 defaultVisionModel)") is not in English; update it to an English
comment describing the same intent (e.g., that these are read-only display
values sourced from defaultVisionModel) near the declarations of
selectedImageModelName and selectedImageModelProvider in mcpServerForm.vue so
the repository comment/linting policy is satisfied.
- Around line 624-631: Replace the Chinese comment above the watch block with an
English comment conveying the same meaning; specifically change "imageServer
仅展示默认视觉模型,不再通过 args 配置" to something like "imageServer only displays the default
vision model and is no longer configured via args" and ensure this English
comment sits immediately above the watch([() => name.value, () => type.value, ()
=> modelStore.enabledModels], ... ) that calls
refreshImageServerDefaultModelDisplay().
- Around line 91-115: The async call inside
refreshImageServerDefaultModelDisplay to configPresenter.getSetting can reject
and currently bubbles out of the watch; wrap the await in a try/catch around
configPresenter.getSetting (and the subsequent resolution logic) to catch
errors, set selectedImageModelName.value and selectedImageModelProvider.value to
'' on error, and optionally log the error; ensure the rest of the function still
returns early when isImageServer.value is false or the defaultVisionModel is
missing, and keep usage of modelStore.enabledModels / providerEntry /
resolvedModel unchanged.

In `@src/renderer/src/components/NewThread.vue`:
- Around line 320-321: Translate the non-English inline comment above the
currentMode check in NewThread.vue into English; replace the comment "// 0) 非
ACP 模式下,优先使用 defaultModel" with an English equivalent such as "// 0) When not in
ACP mode, prefer using defaultModel" so all comments comply with the
English-only guideline and refer to the currentMode !== 'acp agent' conditional.
- Around line 323-332: The code sets active model from stored defaultModel
without checking ACP mode; update the block around
defaultModel/findEnabledModel/setActiveFromEnabled to verify the provider's ACP
status matches the app's current ACP mode before applying it: after obtaining
match = findEnabledModel(...), check the provider/model ACP flag (e.g.,
match.provider.isAcp or match.model.isAcp) against the current ACP mode (use the
existing app/state helper like isAcpMode() or equivalent), and only call
setActiveFromEnabled(...) and mark initialized.value = true when they match; if
they don't match, skip applying the defaultModel so chat mode and model remain
in sync.
🧹 Nitpick comments (5)
src/main/presenter/agentPresenter/utility/utilityHandler.ts (1)

268-305: Well-structured fallback mechanism with clear logging.

The approach of preferring the assistantModel config, falling back to the conversation's model on failure, and short-circuiting when both are the same is clean and correct. The warning log captures all the relevant context for debugging.

One minor nit: messagesWithLength.map((item) => item.formattedMessage) is computed identically on both lines 280 and 301. Extracting it to a local variable avoids the duplication and makes the intent clearer.

♻️ Extract the mapped messages to a variable
     const preferredModelId = assistantModel?.modelId || fallbackModelId
 
+    const formattedMessages = messagesWithLength.map((item) => item.formattedMessage)
+
     let title: string
     try {
       title = await this.ctx.llmProviderPresenter.summaryTitles(
-        messagesWithLength.map((item) => item.formattedMessage),
+        formattedMessages,
         preferredProviderId,
         preferredModelId
       )
     } catch (error) {
       const shouldFallback =
         preferredProviderId !== fallbackProviderId || preferredModelId !== fallbackModelId
       if (!shouldFallback) {
         throw error
       }
       console.warn(
         '[UtilityHandler] Failed to generate title with assistant model, fallback to conversation model',
         {
           preferredProviderId,
           preferredModelId,
           fallbackProviderId,
           fallbackModelId,
           error
         }
       )
       title = await this.ctx.llmProviderPresenter.summaryTitles(
-        messagesWithLength.map((item) => item.formattedMessage),
+        formattedMessages,
         fallbackProviderId,
         fallbackModelId
       )
     }
docs/specs/default-model-settings/tasks.md (1)

9-57: Consider updating checklist status to match what’s already implemented.
If this PR completes items in T1–T6, marking them as done will keep the spec artifacts aligned with reality.

test/main/presenter/configPresenter/defaultModelSettings.test.ts (1)

21-69: These tests don’t cover the actual ConfigPresenter methods.
They currently assert the mock behavior, not the getDefaultModel/setDefaultModel wrappers. Consider instantiating the presenter (or importing the real functions) and asserting they delegate to getSetting/setSetting.

src/main/presenter/sessionPresenter/index.ts (1)

263-299: Well-structured fallback with a minor robustness concern.

The preferred-then-fallback pattern is clean. One subtle edge case: lines 268–269 resolve providerId and modelId independently via ||, so if assistantModel has one field set but the other empty/falsy, you'd get a cross-provider mismatch (e.g., provider from config + modelId from conversation). In practice this shouldn't happen since the settings UI always persists both fields atomically, but a defensive guard would be safer.

🛡️ Optional: validate assistantModel atomically
     const assistantModel = this.configPresenter.getSetting<{ providerId: string; modelId: string }>(
       'assistantModel'
     )
     const fallbackProviderId = conversation.settings.providerId
     const fallbackModelId = conversation.settings.modelId
-    const preferredProviderId = assistantModel?.providerId || fallbackProviderId
-    const preferredModelId = assistantModel?.modelId || fallbackModelId
+    const hasValidAssistantModel = Boolean(assistantModel?.providerId && assistantModel?.modelId)
+    const preferredProviderId = hasValidAssistantModel ? assistantModel!.providerId : fallbackProviderId
+    const preferredModelId = hasValidAssistantModel ? assistantModel!.modelId : fallbackModelId
src/renderer/settings/components/common/DefaultModelSettingsSection.vue (1)

196-221: Consider extracting the setting key constants.

The config keys 'assistantModel', 'defaultModel', and 'defaultVisionModel' are repeated across the handlers and persistModelSetting. Extracting them into constants would reduce the risk of typos and improve maintainability.

Comment on lines +97 to +103
<PopoverContent class="w-[320px] p-0" align="end">
<ModelSelect
:type="[ModelType.Chat, ModelType.ImageGeneration]"
:vision-only="true"
@update:model="handleVisionModelSelect"
/>
</PopoverContent>
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Vision model selector is missing :exclude-providers="['acp']".

The assistant and chat model selects both explicitly exclude 'acp', and syncModelSelections (line 252/258) also explicitly filters out 'acp' for vision. For consistency and to avoid showing ACP models in edge cases, add the same exclusion here.

Proposed fix
             <ModelSelect
               :type="[ModelType.Chat, ModelType.ImageGeneration]"
               :vision-only="true"
+              :exclude-providers="['acp']"
               `@update`:model="handleVisionModelSelect"
             />
📝 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
<PopoverContent class="w-[320px] p-0" align="end">
<ModelSelect
:type="[ModelType.Chat, ModelType.ImageGeneration]"
:vision-only="true"
@update:model="handleVisionModelSelect"
/>
</PopoverContent>
<PopoverContent class="w-[320px] p-0" align="end">
<ModelSelect
:type="[ModelType.Chat, ModelType.ImageGeneration]"
:vision-only="true"
:exclude-providers="['acp']"
`@update`:model="handleVisionModelSelect"
/>
</PopoverContent>
🤖 Prompt for AI Agents
In `@src/renderer/settings/components/common/DefaultModelSettingsSection.vue`
around lines 97 - 103, The Vision ModelSelect inside
DefaultModelSettingsSection.vue is missing the exclude-providers prop, causing
ACP providers to be shown inconsistently; update the <ModelSelect> instance (the
one with :type="[ModelType.Chat, ModelType.ImageGeneration]" and
`@update`:model="handleVisionModelSelect") to add :exclude-providers="['acp']" so
it matches the other model selects and the syncModelSelections ACP filtering
logic.

Comment on lines +62 to 64
// imageServer 展示用(只读,来源于 defaultVisionModel)
const selectedImageModelName = ref('')
const selectedImageModelProvider = ref('')
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Translate the new comment to English.
Line 62 introduces a non‑English comment, which violates the repository rule.

✅ Suggested fix
-// imageServer 展示用(只读,来源于 defaultVisionModel)
+// imageServer display (read-only, sourced from defaultVisionModel)

As per coding guidelines, "All logs and comments must be in English".

📝 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
// imageServer 展示用(只读,来源于 defaultVisionModel
const selectedImageModelName = ref('')
const selectedImageModelProvider = ref('')
// imageServer display (read-only, sourced from defaultVisionModel)
const selectedImageModelName = ref('')
const selectedImageModelProvider = ref('')
🤖 Prompt for AI Agents
In `@src/renderer/src/components/mcp-config/mcpServerForm.vue` around lines 62 -
64, The comment above the image model refs ("// imageServer 展示用(只读,来源于
defaultVisionModel)") is not in English; update it to an English comment
describing the same intent (e.g., that these are read-only display values
sourced from defaultVisionModel) near the declarations of selectedImageModelName
and selectedImageModelProvider in mcpServerForm.vue so the repository
comment/linting policy is satisfied.

Comment on lines +91 to +115
const refreshImageServerDefaultModelDisplay = async (): Promise<void> => {
if (!isImageServer.value) {
selectedImageModelName.value = ''
selectedImageModelProvider.value = ''
return
}

const defaultVisionModel = (await configPresenter.getSetting('defaultVisionModel')) as
| { providerId: string; modelId: string }
| undefined
if (!defaultVisionModel?.providerId || !defaultVisionModel?.modelId) {
selectedImageModelName.value = ''
selectedImageModelProvider.value = ''
return
}

selectedImageModelProvider.value = defaultVisionModel.providerId
const providerEntry = modelStore.enabledModels.find(
(entry) => entry.providerId === defaultVisionModel.providerId
)
const resolvedModel = providerEntry?.models.find(
(model) => model.id === defaultVisionModel.modelId
)
selectedImageModelName.value =
resolvedModel?.name || `${defaultVisionModel.providerId}/${defaultVisionModel.modelId}`
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Guard async presenter call to avoid unhandled rejections.
configPresenter.getSetting can fail; right now a rejection bubbles into a watch callback.

✅ Suggested fix
 const refreshImageServerDefaultModelDisplay = async (): Promise<void> => {
   if (!isImageServer.value) {
     selectedImageModelName.value = ''
     selectedImageModelProvider.value = ''
     return
   }
 
-  const defaultVisionModel = (await configPresenter.getSetting('defaultVisionModel')) as
-    | { providerId: string; modelId: string }
-    | undefined
-  if (!defaultVisionModel?.providerId || !defaultVisionModel?.modelId) {
-    selectedImageModelName.value = ''
-    selectedImageModelProvider.value = ''
-    return
-  }
+  try {
+    const defaultVisionModel = (await configPresenter.getSetting('defaultVisionModel')) as
+      | { providerId: string; modelId: string }
+      | undefined
+    if (!defaultVisionModel?.providerId || !defaultVisionModel?.modelId) {
+      selectedImageModelName.value = ''
+      selectedImageModelProvider.value = ''
+      return
+    }
 
-  selectedImageModelProvider.value = defaultVisionModel.providerId
-  const providerEntry = modelStore.enabledModels.find(
-    (entry) => entry.providerId === defaultVisionModel.providerId
-  )
-  const resolvedModel = providerEntry?.models.find(
-    (model) => model.id === defaultVisionModel.modelId
-  )
-  selectedImageModelName.value =
-    resolvedModel?.name || `${defaultVisionModel.providerId}/${defaultVisionModel.modelId}`
+    selectedImageModelProvider.value = defaultVisionModel.providerId
+    const providerEntry = modelStore.enabledModels.find(
+      (entry) => entry.providerId === defaultVisionModel.providerId
+    )
+    const resolvedModel = providerEntry?.models.find(
+      (model) => model.id === defaultVisionModel.modelId
+    )
+    selectedImageModelName.value =
+      resolvedModel?.name || `${defaultVisionModel.providerId}/${defaultVisionModel.modelId}`
+  } catch (error) {
+    console.warn('Failed to load default vision model:', error)
+    selectedImageModelName.value = ''
+    selectedImageModelProvider.value = ''
+  }
 }
🤖 Prompt for AI Agents
In `@src/renderer/src/components/mcp-config/mcpServerForm.vue` around lines 91 -
115, The async call inside refreshImageServerDefaultModelDisplay to
configPresenter.getSetting can reject and currently bubbles out of the watch;
wrap the await in a try/catch around configPresenter.getSetting (and the
subsequent resolution logic) to catch errors, set selectedImageModelName.value
and selectedImageModelProvider.value to '' on error, and optionally log the
error; ensure the rest of the function still returns early when
isImageServer.value is false or the defaultVisionModel is missing, and keep
usage of modelStore.enabledModels / providerEntry / resolvedModel unchanged.

Comment on lines +320 to +321
// 0) 非 ACP 模式下,优先使用 defaultModel
if (currentMode !== 'acp agent') {
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Translate the new comment to English.
Line 320 introduces a non‑English comment.

✅ Suggested fix
-  // 0) 非 ACP 模式下,优先使用 defaultModel
+  // 0) Prefer defaultModel when not in ACP mode

As per coding guidelines, "All logs and comments must be in English".

📝 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
// 0) 非 ACP 模式下,优先使用 defaultModel
if (currentMode !== 'acp agent') {
// 0) Prefer defaultModel when not in ACP mode
if (currentMode !== 'acp agent') {
🤖 Prompt for AI Agents
In `@src/renderer/src/components/NewThread.vue` around lines 320 - 321, Translate
the non-English inline comment above the currentMode check in NewThread.vue into
English; replace the comment "// 0) 非 ACP 模式下,优先使用 defaultModel" with an English
equivalent such as "// 0) When not in ACP mode, prefer using defaultModel" so
all comments comply with the English-only guideline and refer to the currentMode
!== 'acp agent' conditional.

…handling

- Add ACP mode check when applying default model in NewThread.vue
- Add error handling in DefaultModelSettingsSection.vue syncModelSelections
- Update imageModel i18n keys to remove 'select' verb for display-only fields
@zerob13 zerob13 merged commit 92ec33d into dev Feb 14, 2026
2 checks passed
zerob13 added a commit that referenced this pull request Feb 15, 2026
* docs: add spec for default model setting

* feat: #1174 support default models setting

* fix(settings): sync model selections with ACP mode and improve error handling

- Add ACP mode check when applying default model in NewThread.vue
- Add error handling in DefaultModelSettingsSection.vue syncModelSelections
- Update imageModel i18n keys to remove 'select' verb for display-only fields
zerob13 added a commit that referenced this pull request Feb 16, 2026
* docs: add spec for default model setting

* feat: #1174 support default models setting

* fix(settings): sync model selections with ACP mode and improve error handling

- Add ACP mode check when applying default model in NewThread.vue
- Add error handling in DefaultModelSettingsSection.vue syncModelSelections
- Update imageModel i18n keys to remove 'select' verb for display-only fields
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant