mirror of
https://github.com/Wei-Shaw/sub2api.git
synced 2026-10-29 16:20:27 +00:00
fix(grok): gateway media/voice routing, models, and status UI polish
Align gateway Grok media/voice paths and model lists, harden upstream failure and quota handling, clear non-Grok video generation config migration, and polish temp-unsched/status indicators with model whitelist updates.
This commit is contained in:
@@ -14,15 +14,19 @@
|
||||
|
||||
<!-- Main Status Badge (shown when not rate limited/overloaded) -->
|
||||
<template v-else>
|
||||
<button
|
||||
v-if="isTempUnschedulable"
|
||||
type="button"
|
||||
:class="['badge text-xs', statusClass, 'cursor-pointer']"
|
||||
:title="t('admin.accounts.status.viewTempUnschedDetails')"
|
||||
@click="handleTempUnschedClick"
|
||||
>
|
||||
{{ statusText }}
|
||||
</button>
|
||||
<div v-if="isTempUnschedulable" class="flex flex-col items-center gap-1">
|
||||
<button
|
||||
type="button"
|
||||
:class="['badge text-xs', statusClass, 'cursor-pointer']"
|
||||
:title="t('admin.accounts.status.viewTempUnschedDetails')"
|
||||
@click="handleTempUnschedClick"
|
||||
>
|
||||
{{ statusText }}
|
||||
</button>
|
||||
<span class="max-w-[180px] text-center text-[11px] leading-4 text-gray-500 dark:text-gray-400">
|
||||
{{ tempUnschedRecoveryText }}
|
||||
</span>
|
||||
</div>
|
||||
<span v-else :class="['badge text-xs', statusClass]">
|
||||
{{ statusText }}
|
||||
</span>
|
||||
@@ -302,6 +306,13 @@ const overloadCountdown = computed(() => {
|
||||
return formatCountdownWithSuffix(props.account.overload_until)
|
||||
})
|
||||
|
||||
const tempUnschedRecoveryText = computed(() => {
|
||||
if (!isTempUnschedulable.value || !props.account.temp_unschedulable_until) return ''
|
||||
return t('admin.accounts.status.tempUnschedulableUntil', {
|
||||
time: formatDateTime(props.account.temp_unschedulable_until)
|
||||
})
|
||||
})
|
||||
|
||||
// Computed: status badge class
|
||||
const statusClass = computed(() => {
|
||||
if (hasError.value) {
|
||||
|
||||
@@ -101,6 +101,14 @@
|
||||
{{ state?.error_message || '-' }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="hasThresholdEvidence"
|
||||
class="rounded-lg border border-blue-200 bg-blue-50 p-3 text-sm text-blue-800 dark:border-blue-500/30 dark:bg-blue-500/10 dark:text-blue-300"
|
||||
data-testid="temp-unsched-trigger-evidence"
|
||||
>
|
||||
{{ triggerEvidenceText }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -176,10 +184,28 @@ const isActive = computed(() => {
|
||||
})
|
||||
|
||||
const ruleIndexDisplay = computed(() => {
|
||||
if (!state.value) return '-'
|
||||
if (!state.value || !state.value.matched_keyword || state.value.rule_index < 0) return '-'
|
||||
return state.value.rule_index + 1
|
||||
})
|
||||
|
||||
const hasThresholdEvidence = computed(() => (state.value?.trigger_count || 0) > 1)
|
||||
|
||||
const triggerEvidenceText = computed(() => {
|
||||
const count = state.value?.trigger_count || 0
|
||||
const threshold = state.value?.trigger_threshold || 0
|
||||
const minutes = state.value?.trigger_window_minutes || 0
|
||||
if (threshold > 0 && minutes > 0) {
|
||||
return t('admin.accounts.tempUnschedulable.multipleErrorTrigger', { count, threshold, minutes })
|
||||
}
|
||||
if (threshold > 0) {
|
||||
return t('admin.accounts.tempUnschedulable.multipleErrorTriggerNoWindow', { count, threshold })
|
||||
}
|
||||
if (minutes > 0) {
|
||||
return t('admin.accounts.tempUnschedulable.multipleErrorCountInWindow', { count, minutes })
|
||||
}
|
||||
return t('admin.accounts.tempUnschedulable.multipleErrorCount', { count })
|
||||
})
|
||||
|
||||
const triggeredAtText = computed(() => {
|
||||
if (!state.value?.triggered_at_unix) return '-'
|
||||
return formatDateTime(new Date(state.value.triggered_at_unix * 1000))
|
||||
|
||||
@@ -49,6 +49,7 @@ describe('useModelWhitelist', () => {
|
||||
expect(models).toContain('grok-4.5')
|
||||
expect(models).toContain('grok-4.5-latest')
|
||||
expect(models).toContain('grok-build-latest')
|
||||
expect(models).toContain('grok-imagine-video-1.5-preview')
|
||||
})
|
||||
|
||||
it('combined 模式支持 Grok 4.5 官方别名映射', () => {
|
||||
@@ -74,7 +75,7 @@ describe('useModelWhitelist', () => {
|
||||
const models = getModelsByPlatform('grok')
|
||||
|
||||
expect(models).toContain('grok-composer-2.5-fast')
|
||||
expect(models).toContain('grok-composer')
|
||||
expect(models).not.toContain('grok-composer')
|
||||
expect(models).toContain('composer-2.5')
|
||||
})
|
||||
|
||||
|
||||
@@ -143,20 +143,20 @@ const xaiModels = [
|
||||
'grok-4.20-0309-reasoning',
|
||||
'grok-4.20-0309-non-reasoning',
|
||||
'grok-4.20-multi-agent-0309',
|
||||
'grok',
|
||||
'grok-4.20-multi-agent',
|
||||
'grok-4.20-multi-agent-latest',
|
||||
'grok-4.3-latest',
|
||||
'grok-latest',
|
||||
'grok-4.5-latest',
|
||||
'grok-build',
|
||||
'grok-build-latest',
|
||||
'grok-composer',
|
||||
'composer-2.5',
|
||||
'grok-4.20-reasoning',
|
||||
'grok-4.20-non-reasoning',
|
||||
'grok-imagine',
|
||||
'grok-imagine-image-quality',
|
||||
'grok-imagine-image',
|
||||
'grok-imagine-edit',
|
||||
'grok-imagine-video',
|
||||
'grok-imagine-video-1.5-preview',
|
||||
'grok-imagine-video-1.5'
|
||||
]
|
||||
|
||||
@@ -314,7 +314,7 @@ const grokPresetMappings = [
|
||||
{ label: '4.20 Reasoning', from: 'grok-4.20-reasoning', to: 'grok-4.20-0309-reasoning', color: 'bg-indigo-100 text-indigo-700 hover:bg-indigo-200 dark:bg-indigo-900/30 dark:text-indigo-400' },
|
||||
{ label: '4.20 Non Reasoning', from: 'grok-4.20-non-reasoning', to: 'grok-4.20-0309-non-reasoning', color: 'bg-violet-100 text-violet-700 hover:bg-violet-200 dark:bg-violet-900/30 dark:text-violet-400' },
|
||||
{ label: 'Imagine Image', from: 'grok-imagine', to: 'grok-imagine-image-quality', color: 'bg-sky-100 text-sky-700 hover:bg-sky-200 dark:bg-sky-900/30 dark:text-sky-400' },
|
||||
{ label: 'Imagine Edit', from: 'grok-imagine-edit', to: 'grok-imagine-edit', color: 'bg-rose-100 text-rose-700 hover:bg-rose-200 dark:bg-rose-900/30 dark:text-rose-400' },
|
||||
{ label: 'Imagine Edit', from: 'grok-imagine-edit', to: 'grok-imagine-image-quality', color: 'bg-rose-100 text-rose-700 hover:bg-rose-200 dark:bg-rose-900/30 dark:text-rose-400' },
|
||||
{ label: 'Imagine Video', from: 'grok-imagine-video-1.5', to: 'grok-imagine-video-1.5', color: 'bg-amber-100 text-amber-700 hover:bg-amber-200 dark:bg-amber-900/30 dark:text-amber-400' }
|
||||
]
|
||||
|
||||
|
||||
Reference in New Issue
Block a user