feat(ai): add Xiaomi MiMo provider, ZAI as last-resort fallback
All checks were successful
Beta Release / beta (push) Successful in 57s
All checks were successful
Beta Release / beta (push) Successful in 57s
Add MiMo-V2.5-Pro from Xiaomi Token Plan as a new AI provider with base URL https://token-plan-ams.xiaomimimo.com/v1. The /model change command now switches between MiniMax and MiMo only. ZAI is always placed last in the fallback chain as the provider of ultimate resort. Config panel shows MiniMax and MiMo cards. 💘 Generated with Crush Assisted-by: GLM-5.1 via Crush <crush@charm.land>
This commit is contained in:
@@ -530,6 +530,11 @@ func (s *Server) handleProvidersQuota(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
case "mimo":
|
||||||
|
q.Healthy = p.APIKey != ""
|
||||||
|
if p.APIKey == "" {
|
||||||
|
q.Error = "no API key"
|
||||||
|
}
|
||||||
case "claude", "anthropic":
|
case "claude", "anthropic":
|
||||||
// Claude Code n'a pas d'API externe, vérifier l'installation
|
// Claude Code n'a pas d'API externe, vérifier l'installation
|
||||||
claudePath := "/usr/bin/claude"
|
claudePath := "/usr/bin/claude"
|
||||||
|
|||||||
@@ -269,6 +269,12 @@ func Default() *MuyueConfig {
|
|||||||
BaseURL: "https://api.minimax.io/v1",
|
BaseURL: "https://api.minimax.io/v1",
|
||||||
Active: true,
|
Active: true,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Name: "mimo",
|
||||||
|
Model: "MiMo-V2.5-Pro",
|
||||||
|
BaseURL: "https://token-plan-ams.xiaomimimo.com/v1",
|
||||||
|
Active: false,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
Name: "zai",
|
Name: "zai",
|
||||||
Model: "glm",
|
Model: "glm",
|
||||||
|
|||||||
@@ -476,6 +476,8 @@ func getProviderBaseURL(name string) string {
|
|||||||
return "https://api.openai.com/v1"
|
return "https://api.openai.com/v1"
|
||||||
case "zai":
|
case "zai":
|
||||||
return "https://api.z.ai/v1"
|
return "https://api.z.ai/v1"
|
||||||
|
case "mimo":
|
||||||
|
return "https://token-plan-ams.xiaomimimo.com/v1"
|
||||||
default:
|
default:
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
@@ -503,11 +505,19 @@ func (o *Orchestrator) sendWithFallback(reqBody ChatRequest, baseURLOverride str
|
|||||||
if o.provider != nil {
|
if o.provider != nil {
|
||||||
providerOrder = append(providerOrder, o.provider)
|
providerOrder = append(providerOrder, o.provider)
|
||||||
}
|
}
|
||||||
|
var zaiProvider *config.AIProvider
|
||||||
for _, p := range providers {
|
for _, p := range providers {
|
||||||
if o.provider == nil || p.Name != o.provider.Name {
|
if o.provider == nil || p.Name != o.provider.Name {
|
||||||
providerOrder = append(providerOrder, p)
|
if p.Name == "zai" {
|
||||||
|
zaiProvider = p
|
||||||
|
} else {
|
||||||
|
providerOrder = append(providerOrder, p)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if zaiProvider != nil {
|
||||||
|
providerOrder = append(providerOrder, zaiProvider)
|
||||||
|
}
|
||||||
|
|
||||||
var lastErr error
|
var lastErr error
|
||||||
var triedProviders []string
|
var triedProviders []string
|
||||||
|
|||||||
@@ -343,7 +343,7 @@ function PanelProviders({ providers, editProvider, providerForm, setProviderForm
|
|||||||
setValidating(null)
|
setValidating(null)
|
||||||
}
|
}
|
||||||
|
|
||||||
const displayed = providers.filter(p => p.name === 'minimax' || p.name === 'zai')
|
const displayed = providers.filter(p => p.name === 'minimax' || p.name === 'mimo')
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="config-providers-list">
|
<div className="config-providers-list">
|
||||||
|
|||||||
@@ -452,15 +452,15 @@ export default function Studio({ api }) {
|
|||||||
api.getProviders().then(data => {
|
api.getProviders().then(data => {
|
||||||
const providers = data.providers || []
|
const providers = data.providers || []
|
||||||
const minimax = providers.find(p => p.name.toUpperCase() === 'MINIMAX')
|
const minimax = providers.find(p => p.name.toUpperCase() === 'MINIMAX')
|
||||||
const zai = providers.find(p => p.name.toUpperCase() === 'ZAI')
|
const mimo = providers.find(p => p.name.toUpperCase() === 'MIMO')
|
||||||
if (!minimax || !zai) {
|
if (!minimax || !mimo) {
|
||||||
setMessages(prev => [...prev, { id: Date.now().toString(), role: 'assistant', content: 'MiniMax et ZAI doivent être configurés pour utiliser `/model change`.', time: new Date().toISOString() }])
|
setMessages(prev => [...prev, { id: Date.now().toString(), role: 'assistant', content: 'MiniMax et MiMo doivent être configurés pour utiliser `/model change`.', time: new Date().toISOString() }])
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const active = providers.find(p => p.active)
|
const active = providers.find(p => p.active)
|
||||||
const activeName = active ? active.name.toUpperCase() : ''
|
const activeName = active ? active.name.toUpperCase() : ''
|
||||||
const switchTo = activeName === 'MINIMAX' ? 'ZAI' : 'MINIMAX'
|
const switchTo = activeName === 'MINIMAX' ? 'MIMO' : 'MINIMAX'
|
||||||
const target = switchTo === 'MINIMAX' ? minimax : zai
|
const target = switchTo === 'MINIMAX' ? minimax : mimo
|
||||||
api.saveProvider({ name: target.name, active: true }).then(() => {
|
api.saveProvider({ name: target.name, active: true }).then(() => {
|
||||||
setMessages(prev => [...prev, { id: Date.now().toString(), role: 'assistant', content: `✓ Provider changé: **${target.name}** (${target.model})`, time: new Date().toISOString() }])
|
setMessages(prev => [...prev, { id: Date.now().toString(), role: 'assistant', content: `✓ Provider changé: **${target.name}** (${target.model})`, time: new Date().toISOString() }])
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
|
|||||||
Reference in New Issue
Block a user