feat: 国产供应商一等支持(Kimi/Zhipu/DeepSeek 多协议 + 配额/余额监控)

后端:
- 协议凭证维度 credentials[api_protocol] ∈ chat_completions(默认)/anthropic/responses(deepseek)
- /v1/messages 零转换直通原生 Anthropic 端点(kimi/zhipu/deepseek),CC/Responses
  入站交叉组合走 apicompat 双向转换链(responses/chat_completions anthropic-native 转发器)
- count_tokens:anthropic 协议透传原生端点;其余 CN 协议本地 tiktoken 估算
- Coding Plan 额度探测(5h/weekly 滚动窗口)+ payg 余额探测(kimi/deepseek),
  deepseek 双币种 CNY+USD 明细,任一币种达标不停调
- 周期任务 [CNBalance] 并发探测 + 预算随工作量放大;响应式 429 冷却到最早窗口
  重置点;余额不足可恢复临时停调;智谱 CREDIT_LIMIT 不污染窗口解析
- CC→anthropic 流式客户端断开后继续排水上游保住 usage 计量

前端:
- 创建/编辑弹窗 account_mode + api_protocol + base_url 联动预设(含 watcher 竞态防护)
- 用量单元格:kimi/zhipu coding 显示 5h/weekly 窗口,kimi/deepseek payg 显示余额,
  多币种并列展示;探测失败保留快照;挂载自动探测 5min 去抖
- 调度阈值设置面板补 kimi/zhipu 平台(对齐后端 AllowedSchedulingThresholdPlatforms)
This commit is contained in:
Randark
2026-08-15 10:37:51 +00:00
parent 073e92d171
commit 901a0439f1
72 changed files with 5754 additions and 125 deletions
+63 -2
View File
@@ -5,7 +5,16 @@
* instead of defining their own color mappings.
*/
export type Platform = 'anthropic' | 'openai' | 'antigravity' | 'gemini' | 'grok' | 'composite'
export type Platform =
| 'anthropic'
| 'openai'
| 'antigravity'
| 'gemini'
| 'grok'
| 'kimi'
| 'zhipu'
| 'deepseek'
| 'composite'
// ── Badge (bg + text + border, for inline badges with border) ───────
const BADGE: Record<Platform, string> = {
@@ -14,6 +23,9 @@ const BADGE: Record<Platform, string> = {
antigravity: 'bg-purple-500/10 text-purple-600 border-purple-500/30 dark:text-purple-400',
gemini: 'bg-blue-500/10 text-blue-600 border-blue-500/30 dark:text-blue-400',
grok: 'bg-zinc-800/10 text-zinc-800 border-zinc-800/30 dark:bg-zinc-500/10 dark:text-zinc-200 dark:border-zinc-500/30',
kimi: 'bg-pink-500/10 text-pink-600 border-pink-500/30 dark:text-pink-400',
zhipu: 'bg-indigo-500/10 text-indigo-600 border-indigo-500/30 dark:text-indigo-400',
deepseek: 'bg-teal-500/10 text-teal-600 border-teal-500/30 dark:text-teal-400',
composite: 'bg-cyan-500/10 text-cyan-700 border-cyan-500/30 dark:text-cyan-300',
}
const BADGE_DEFAULT = 'bg-slate-500/10 text-slate-600 border-slate-500/30 dark:text-slate-400'
@@ -25,6 +37,9 @@ const BADGE_LIGHT: Record<Platform, string> = {
antigravity: 'bg-purple-500/10 text-purple-600 dark:bg-purple-500/10 dark:text-purple-300',
gemini: 'bg-blue-500/10 text-blue-600 dark:bg-blue-500/10 dark:text-blue-300',
grok: 'bg-zinc-800/10 text-zinc-800 dark:bg-zinc-500/10 dark:text-zinc-200',
kimi: 'bg-pink-500/10 text-pink-600 dark:bg-pink-500/10 dark:text-pink-300',
zhipu: 'bg-indigo-500/10 text-indigo-600 dark:bg-indigo-500/10 dark:text-indigo-300',
deepseek: 'bg-teal-500/10 text-teal-600 dark:bg-teal-500/10 dark:text-teal-300',
composite: 'bg-cyan-500/10 text-cyan-700 dark:bg-cyan-500/10 dark:text-cyan-300',
}
@@ -35,6 +50,9 @@ const BORDER: Record<Platform, string> = {
antigravity: 'border-purple-500/20 dark:border-purple-500/20',
gemini: 'border-blue-500/20 dark:border-blue-500/20',
grok: 'border-zinc-800/20 dark:border-zinc-500/20',
kimi: 'border-pink-500/20 dark:border-pink-500/20',
zhipu: 'border-indigo-500/20 dark:border-indigo-500/20',
deepseek: 'border-teal-500/20 dark:border-teal-500/20',
composite: 'border-cyan-500/20 dark:border-cyan-500/20',
}
const BORDER_DEFAULT = 'border-gray-200 dark:border-dark-700'
@@ -46,6 +64,9 @@ const BORDER_STRONG: Record<Platform, string> = {
antigravity: 'border-purple-500/35 dark:border-purple-500/30',
gemini: 'border-blue-500/35 dark:border-blue-500/30',
grok: 'border-zinc-800/35 dark:border-zinc-500/35',
kimi: 'border-pink-500/35 dark:border-pink-500/30',
zhipu: 'border-indigo-500/35 dark:border-indigo-500/30',
deepseek: 'border-teal-500/35 dark:border-teal-500/30',
composite: 'border-cyan-500/35 dark:border-cyan-500/30',
}
const BORDER_STRONG_DEFAULT = 'border-gray-300 dark:border-dark-600'
@@ -58,6 +79,9 @@ const ACCENT: Record<Platform, string> = {
antigravity: '#a855f7', // purple-500
gemini: '#3b82f6', // blue-500
grok: '#71717a', // zinc-500
kimi: '#ec4899', // pink-500
zhipu: '#6366f1', // indigo-500
deepseek: '#14b8a6', // teal-500
composite: '#06b6d4', // cyan-500
}
const ACCENT_DEFAULT = '#14b8a6' // primary-500 (teal)
@@ -69,6 +93,9 @@ const ACCENT_BAR: Record<Platform, string> = {
antigravity: 'bg-gradient-to-r from-purple-400 to-purple-500',
gemini: 'bg-gradient-to-r from-blue-400 to-blue-500',
grok: 'bg-gradient-to-r from-zinc-700 to-zinc-900',
kimi: 'bg-gradient-to-r from-pink-400 to-pink-500',
zhipu: 'bg-gradient-to-r from-indigo-400 to-indigo-500',
deepseek: 'bg-gradient-to-r from-teal-400 to-teal-500',
composite: 'bg-gradient-to-r from-slate-500 to-cyan-500',
}
const ACCENT_BAR_DEFAULT = 'bg-gradient-to-r from-primary-400 to-primary-500'
@@ -80,6 +107,9 @@ const TEXT: Record<Platform, string> = {
antigravity: 'text-purple-600 dark:text-purple-400',
gemini: 'text-blue-600 dark:text-blue-400',
grok: 'text-zinc-800 dark:text-zinc-200',
kimi: 'text-pink-600 dark:text-pink-400',
zhipu: 'text-indigo-600 dark:text-indigo-400',
deepseek: 'text-teal-600 dark:text-teal-400',
composite: 'text-cyan-700 dark:text-cyan-300',
}
const TEXT_DEFAULT = 'text-primary-600 dark:text-primary-400'
@@ -91,6 +121,9 @@ const ICON: Record<Platform, string> = {
antigravity: 'text-purple-500 dark:text-purple-400',
gemini: 'text-blue-500 dark:text-blue-400',
grok: 'text-zinc-800 dark:text-zinc-200',
kimi: 'text-pink-500 dark:text-pink-400',
zhipu: 'text-indigo-500 dark:text-indigo-400',
deepseek: 'text-teal-500 dark:text-teal-400',
composite: 'text-cyan-600 dark:text-cyan-300',
}
const ICON_DEFAULT = 'text-primary-500 dark:text-primary-400'
@@ -102,6 +135,9 @@ const BUTTON: Record<Platform, string> = {
antigravity: 'bg-purple-500 text-white hover:bg-purple-600 active:bg-purple-700 dark:bg-purple-500/80 dark:hover:bg-purple-500',
gemini: 'bg-blue-500 text-white hover:bg-blue-600 active:bg-blue-700 dark:bg-blue-500/80 dark:hover:bg-blue-500',
grok: 'bg-zinc-800 text-white hover:bg-zinc-900 active:bg-black dark:bg-zinc-700 dark:hover:bg-zinc-600',
kimi: 'bg-pink-500 text-white hover:bg-pink-600 active:bg-pink-700 dark:bg-pink-500/80 dark:hover:bg-pink-500',
zhipu: 'bg-indigo-500 text-white hover:bg-indigo-600 active:bg-indigo-700 dark:bg-indigo-500/80 dark:hover:bg-indigo-500',
deepseek: 'bg-teal-500 text-white hover:bg-teal-600 active:bg-teal-700 dark:bg-teal-500/80 dark:hover:bg-teal-500',
composite: 'bg-cyan-700 text-white hover:bg-cyan-800 active:bg-cyan-900 dark:bg-cyan-600 dark:hover:bg-cyan-500',
}
const BUTTON_DEFAULT = 'bg-primary-500 text-white hover:bg-primary-600 dark:bg-primary-600 dark:hover:bg-primary-500'
@@ -113,6 +149,9 @@ const DISCOUNT: Record<Platform, string> = {
antigravity: 'bg-purple-100 text-purple-700 dark:bg-purple-900/40 dark:text-purple-300',
gemini: 'bg-blue-100 text-blue-700 dark:bg-blue-900/40 dark:text-blue-300',
grok: 'bg-zinc-100 text-zinc-800 dark:bg-zinc-800 dark:text-zinc-200',
kimi: 'bg-pink-100 text-pink-700 dark:bg-pink-900/40 dark:text-pink-300',
zhipu: 'bg-indigo-100 text-indigo-700 dark:bg-indigo-900/40 dark:text-indigo-300',
deepseek: 'bg-teal-100 text-teal-700 dark:bg-teal-900/40 dark:text-teal-300',
composite: 'bg-cyan-100 text-cyan-800 dark:bg-cyan-900/40 dark:text-cyan-300',
}
const DISCOUNT_DEFAULT = 'bg-red-100 text-red-700 dark:bg-red-900/40 dark:text-red-300'
@@ -124,6 +163,9 @@ const GRADIENT: Record<Platform, string> = {
antigravity: 'from-purple-500 to-purple-600',
gemini: 'from-blue-500 to-blue-600',
grok: 'from-zinc-700 to-zinc-900',
kimi: 'from-pink-500 to-pink-600',
zhipu: 'from-indigo-500 to-indigo-600',
deepseek: 'from-teal-500 to-teal-600',
composite: 'from-slate-600 to-cyan-600',
}
const GRADIENT_DEFAULT = 'from-primary-500 to-primary-600'
@@ -135,6 +177,9 @@ const GRADIENT_TEXT: Record<Platform, string> = {
antigravity: 'text-purple-100',
gemini: 'text-blue-100',
grok: 'text-zinc-100',
kimi: 'text-pink-100',
zhipu: 'text-indigo-100',
deepseek: 'text-teal-100',
composite: 'text-cyan-100',
}
const GRADIENT_TEXT_DEFAULT = 'text-primary-100'
@@ -145,6 +190,9 @@ const GRADIENT_SUBTEXT: Record<Platform, string> = {
antigravity: 'text-purple-200',
gemini: 'text-blue-200',
grok: 'text-zinc-300',
kimi: 'text-pink-200',
zhipu: 'text-indigo-200',
deepseek: 'text-teal-200',
composite: 'text-cyan-200',
}
const GRADIENT_SUBTEXT_DEFAULT = 'text-primary-200'
@@ -152,7 +200,17 @@ const GRADIENT_SUBTEXT_DEFAULT = 'text-primary-200'
// ── Public API ──────────────────────────────────────────────────────
function isPlatform(p: string): p is Platform {
return p === 'anthropic' || p === 'openai' || p === 'antigravity' || p === 'gemini' || p === 'grok' || p === 'composite'
return (
p === 'anthropic' ||
p === 'openai' ||
p === 'antigravity' ||
p === 'gemini' ||
p === 'grok' ||
p === 'kimi' ||
p === 'zhipu' ||
p === 'deepseek' ||
p === 'composite'
)
}
export function platformBadgeClass(p: string): string {
@@ -214,6 +272,9 @@ export function platformLabel(p: string): string {
case 'antigravity': return 'Antigravity'
case 'gemini': return 'Gemini'
case 'grok': return 'Grok'
case 'kimi': return 'Kimi'
case 'zhipu': return 'Zhipu GLM'
case 'deepseek': return 'DeepSeek'
case 'composite': return 'Composite'
default: return p || 'API'
}