hotfix(models): add MiMo V2.5 model support (#14557)

### What this PR does

Before this PR:

- Cherry Studio did not recognize the new MiMo V2.5 chat models as
expected across model capability checks.
- MiMo V2.5 models were missing or incomplete in the built-in model
list.
- Function calling, reasoning option detection, and vision capability
detection were not aligned for the new MiMo V2.5 models.

After this PR:

- Adds MiMo V2.5 and MiMo V2.5 Pro to the built-in MiMo model list.
- Enables reasoning/thinking support detection for MiMo V2.5 chat
models.
- Enables function-calling detection for MiMo V2.5 chat models.
- Enables vision detection for MiMo V2.5 while keeping unsupported MiMo
V2.5 speech models excluded.
- Adds regression tests covering reasoning, tool calling, and vision
behavior for the MiMo V2.5 family.

<!-- (optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)`
format, will close the issue(s) when PR gets merged)*: -->

Fixes # N/A

### Why we need it and why it was done in this way

The following tradeoffs were made:

- This hotfix keeps the change set minimal and scoped to model
capability configuration and tests only.
- The implementation updates existing model detection logic instead of
introducing new abstractions, which reduces risk for a `main` branch
hotfix.

The following alternatives were considered:

- Deferring support until a larger model capability refactor on the `v2`
branch.
- Adding broader refactoring around MiMo model matching and capability
normalization.

Links to places where the discussion took place: N/A <!-- optional:
slack, other GH issue, mailinglist, ... -->

### Breaking changes

<!-- optional -->

If this PR introduces breaking changes, please describe the changes and
the impact on users.

- None.

### Special notes for your reviewer

<!-- optional -->

- This PR is intentionally minimal because it targets `main` from a
`hotfix/*` branch under code freeze.
- Validation performed:
- `pnpm test:renderer --
src/renderer/src/config/models/__tests__/vision.test.ts
src/renderer/src/config/models/__tests__/tooluse.test.ts
src/renderer/src/config/models/__tests__/reasoning.test.ts`

### Checklist

This checklist is not enforcing, but it's a reminder of items that could
be relevant to every PR.
Approvers are expected to review this list.

- [x] PR: The PR description is expressive enough and will help future
contributors
- [x] Code: [Write code that humans can
understand](https://en.wikiquote.org/wiki/Martin_Fowler#code-for-humans)
and [Keep it simple](https://en.wikipedia.org/wiki/KISS_principle)
- [x] Refactor: You have [left the code cleaner than you found it (Boy
Scout
Rule)](https://learning.oreilly.com/library/view/97-things-every/9780596809515/ch08.html)
- [x] Upgrade: Impact of this change on upgrade flows was considered and
addressed if required
- [] Documentation: A [user-guide update](https://docs.cherry-ai.com)
was considered and is present (link) or not required. Check this only
when the PR introduces or changes a user-facing feature or behavior.
- [x] Self-review: I have reviewed my own code (e.g., via
[`/gh-pr-review`](/.claude/skills/gh-pr-review/SKILL.md), `gh pr diff`,
or GitHub UI) before requesting review from others

### Release note

<!--  Write your release note:
1. Enter your extended release note in the below block. If the PR
requires additional action from users switching to the new release,
include the string "action required".
2. If no release note is required, just write "NONE".
3. Only include user-facing changes (new features, bug fixes visible to
users, UI changes, behavior changes). For CI, maintenance, internal
refactoring, build tooling, or other non-user-facing work, write "NONE".
-->

```release-note
Fixed MiMo V2.5 model capability detection so MiMo V2.5 chat models are recognized correctly for reasoning controls, function calling, and vision support.

Signed-off-by: ousugo <dkzyxh@gmail.com>
Co-authored-by: SuYao <sy20010504@gmail.com>
This commit is contained in:
Asurada
2026-04-25 00:28:33 +08:00
committed by GitHub
parent 774aa674d2
commit 5a1b20fe08
7 changed files with 66 additions and 9 deletions

View File

@@ -31,6 +31,7 @@ import {
isSupportedThinkingTokenDoubaoModel,
isSupportedThinkingTokenGeminiModel,
isSupportedThinkingTokenKimiModel,
isSupportedThinkingTokenMiMoModel,
isSupportedThinkingTokenModel,
isSupportedThinkingTokenQwenModel,
isSupportedThinkingTokenZhipuModel,
@@ -831,6 +832,13 @@ describe('getThinkModelType - Comprehensive Coverage', () => {
})
})
describe('MiMo models', () => {
it('should return mimo for V2.5 thinking models', () => {
expect(getThinkModelType(createModel({ id: 'mimo-v2.5' }))).toBe('mimo')
expect(getThinkModelType(createModel({ id: 'mimo-v2.5-pro' }))).toBe('mimo')
})
})
describe('Perplexity models', () => {
it('should return perplexity for supported Perplexity models', () => {
expect(getThinkModelType(createModel({ id: 'sonar-pro', provider: 'perplexity' }))).toBe('default')
@@ -2168,6 +2176,19 @@ describe('getModelSupportedReasoningEffortOptions', () => {
])
})
it('should return correct options for MiMo V2.5 models', () => {
expect(getModelSupportedReasoningEffortOptions(createModel({ id: 'mimo-v2.5' }))).toEqual([
'default',
'none',
'auto'
])
expect(getModelSupportedReasoningEffortOptions(createModel({ id: 'mimo-v2.5-pro' }))).toEqual([
'default',
'none',
'auto'
])
})
it('should return correct options for Zhipu models', () => {
expect(getModelSupportedReasoningEffortOptions(createModel({ id: 'glm-4.5' }))).toEqual([
'default',
@@ -2335,6 +2356,13 @@ describe('isInterleavedThinkingModel', () => {
})
describe('MiMo models', () => {
it('should support thinking control for V2.5 models only on chat models', () => {
expect(isSupportedThinkingTokenMiMoModel(createModel({ id: 'mimo-v2.5' }))).toBe(true)
expect(isSupportedThinkingTokenMiMoModel(createModel({ id: 'mimo-v2.5-pro' }))).toBe(true)
expect(isSupportedThinkingTokenMiMoModel(createModel({ id: 'mimo-v2.5-tts' }))).toBe(false)
expect(isSupportedThinkingTokenMiMoModel(createModel({ id: 'mimo-v2.5-tts-voiceclone' }))).toBe(false)
})
it('should return true for mimo-v2-flash', () => {
expect(isInterleavedThinkingModel(createModel({ id: 'mimo-v2-flash' }))).toBe(true)
})

View File

@@ -177,6 +177,18 @@ describe('isFunctionCallingModel', () => {
})
})
describe('MiMo V2.5 Models', () => {
it('supports function calling for V2.5 chat models', () => {
expect(isFunctionCallingModel(createModel({ id: 'mimo-v2.5', provider: 'mimo' }))).toBe(true)
expect(isFunctionCallingModel(createModel({ id: 'mimo-v2.5-pro', provider: 'mimo' }))).toBe(true)
})
it('does not treat V2.5 speech models as function calling chat models', () => {
expect(isFunctionCallingModel(createModel({ id: 'mimo-v2.5-tts', provider: 'mimo' }))).toBe(false)
expect(isFunctionCallingModel(createModel({ id: 'mimo-v2.5-tts-voiceclone', provider: 'mimo' }))).toBe(false)
})
})
describe('Doubao Seed 2.0 Models', () => {
it('should identify doubao-seed-2-0-pro-260215 as function calling model', () => {
const model: Model = {

View File

@@ -349,6 +349,15 @@ describe('isVisionModel', () => {
})
})
describe('MiMo Models', () => {
it('should identify only the full-modal V2.5 chat model as vision-capable', () => {
expect(isVisionModel(createModel({ id: 'mimo-v2.5' }))).toBe(true)
expect(isVisionModel(createModel({ id: 'xiaomi/mimo-v2.5' }))).toBe(true)
expect(isVisionModel(createModel({ id: 'mimo-v2.5-pro' }))).toBe(false)
expect(isVisionModel(createModel({ id: 'mimo-v2.5-tts' }))).toBe(false)
})
})
describe('Qwen Models', () => {
it('should return true for Qwen vision models', () => {
expect(isVisionModel(createModel({ id: 'qwen-vl-max' }))).toBe(true)

View File

@@ -2029,23 +2029,29 @@ export const SYSTEM_MODELS: Record<SystemProviderId | 'defaultModel', Model[]> =
}
],
mimo: [
{
id: 'mimo-v2.5',
name: 'Mimo V2.5',
provider: 'mimo',
group: 'mimo'
},
{
id: 'mimo-v2.5-pro',
name: 'Mimo V2.5 Pro',
provider: 'mimo',
group: 'mimo'
},
{
id: 'mimo-v2-flash',
name: 'Mimo V2 Flash',
provider: 'mimo',
group: 'Mimo'
},
{
id: 'mimo-v2-pro',
name: 'Mimo V2 Pro',
provider: 'mimo',
group: 'Mimo'
group: 'mimo'
},
{
id: 'mimo-v2-omni',
name: 'Mimo V2 Omni',
provider: 'mimo',
group: 'Mimo'
group: 'mimo'
}
],
zai: [

View File

@@ -613,7 +613,7 @@ export const isSupportedThinkingTokenZhipuModel = (model: Model): boolean => {
export const isSupportedThinkingTokenMiMoModel = (model: Model): boolean => {
const modelId = getLowerBaseModelName(model.id, '/')
return ['mimo-v2-flash', 'mimo-v2-pro', 'mimo-v2-omni'].some((id) => modelId.includes(id))
return ['mimo-v2-flash', 'mimo-v2-pro', 'mimo-v2-omni', 'mimo-v2.5', 'mimo-v2.5-pro'].includes(modelId)
}
/**

View File

@@ -36,6 +36,7 @@ export const FUNCTION_CALLING_MODELS = [
'ling-\\w+(?:-[\\w-]+)?',
'ring-\\w+(?:-[\\w-]+)?',
'minimax-m2(?:\\.\\d+)?(?:-[\\w-]+)?',
'mimo-v2\\.5(?:-pro)?(?!-)',
'mimo-v2-flash',
'mimo-v2-pro',
'mimo-v2-omni',

View File

@@ -61,6 +61,7 @@ const visionAllowedModels = [
'mistral-large-(2512|latest)',
'mistral-medium-(2508|latest)',
'mistral-small-(2506|latest)',
'mimo-v2\\.5$',
'mimo-v2-omni(?:-[\\w-]+)?',
'glm-5v-turbo'
]