mirror of
https://github.com/fawney19/Aether.git
synced 2026-10-06 01:17:46 +08:00
fix(codex): preserve explicit service tiers and adapt usage badges
This commit is contained in:
@@ -8,8 +8,8 @@
|
||||
: undefined"
|
||||
>
|
||||
<div
|
||||
class="flex min-w-0 max-w-full items-center gap-1"
|
||||
:class="[modelRowClass, actualModel ? 'flex-wrap' : '']"
|
||||
class="flex min-w-0 max-w-full flex-wrap items-center gap-1"
|
||||
:class="modelRowClass"
|
||||
>
|
||||
<span
|
||||
class="min-w-0 truncate"
|
||||
@@ -29,7 +29,7 @@
|
||||
:data-usage-model-badge="badge.key"
|
||||
:data-request-detail-model-badge="context === 'detail' ? badge.key : undefined"
|
||||
:variant="badge.variant"
|
||||
class="h-4 shrink-0 whitespace-nowrap rounded-full px-1.5 text-[10px] leading-4"
|
||||
class="h-4 max-w-full shrink-0 truncate rounded-full px-1.5 text-[10px] leading-4"
|
||||
:class="badge.className"
|
||||
:title="badge.title"
|
||||
:aria-label="badge.ariaLabel"
|
||||
@@ -51,7 +51,7 @@
|
||||
:data-usage-model-badge="badge.key"
|
||||
:data-request-detail-model-badge="context === 'detail' ? badge.key : undefined"
|
||||
:variant="badge.variant"
|
||||
class="h-4 shrink-0 whitespace-nowrap rounded-full px-1.5 text-[10px] leading-4"
|
||||
class="h-4 max-w-full shrink-0 truncate rounded-full px-1.5 text-[10px] leading-4"
|
||||
:class="badge.className"
|
||||
:title="badge.title"
|
||||
:aria-label="badge.ariaLabel"
|
||||
@@ -69,7 +69,7 @@ import { Badge } from '@/components/ui'
|
||||
import { isCyberPolicyError } from '../utils/cyberError'
|
||||
import { formatServiceTierFact } from '../utils/service-tier'
|
||||
|
||||
type ModelBadgeKey = 'compact' | 'reasoning' | 'fast' | 'cyber' | 'reasoning_tokens'
|
||||
type ModelBadgeKey = 'compact' | 'reasoning' | 'fast' | 'service-tier' | 'cyber' | 'reasoning_tokens'
|
||||
|
||||
interface ModelBadgePresentation {
|
||||
key: ModelBadgeKey
|
||||
@@ -154,14 +154,16 @@ const modelBadges = computed<ModelBadgePresentation[]>(() => {
|
||||
})
|
||||
}
|
||||
|
||||
if (props.showServiceTierBadge && formatServiceTierFact(props.record.service_tier) === 'Fast') {
|
||||
const serviceTier = formatServiceTierFact(props.record.service_tier)
|
||||
if (props.showServiceTierBadge && serviceTier
|
||||
&& !['auto', 'default', 'standard'].includes(serviceTier.toLowerCase())) {
|
||||
badges.push({
|
||||
key: 'fast',
|
||||
label: 'Fast',
|
||||
key: serviceTier === 'Fast' ? 'fast' : 'service-tier',
|
||||
label: serviceTier,
|
||||
variant: 'outline-transparent',
|
||||
className: 'text-blue-500 dark:text-blue-300',
|
||||
title: '上游请求档位:Fast\n计费档位:Fast',
|
||||
ariaLabel: '上游请求档位:Fast,计费档位:Fast',
|
||||
title: `上游请求档位:${serviceTier}\n计费档位:${serviceTier}`,
|
||||
ariaLabel: `上游请求档位:${serviceTier},计费档位:${serviceTier}`,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
+12
-10
@@ -309,7 +309,11 @@ describe('RequestDetailDrawer settlement pricing', () => {
|
||||
})
|
||||
})
|
||||
|
||||
it('shows mapping, reasoning, Fast, and Cyber together in the model header', async () => {
|
||||
it.each([
|
||||
{ tier: 'priority', label: 'Fast', badgeKey: 'fast' },
|
||||
{ tier: 'ultrafast', label: 'ultrafast', badgeKey: 'service-tier' },
|
||||
{ tier: 'future-tier', label: 'future-tier', badgeKey: 'service-tier' },
|
||||
])('shows mapping, reasoning, $tier, and Cyber together in the model header', async ({ tier, label, badgeKey }) => {
|
||||
apiMocks.getRequestDetail.mockResolvedValue({
|
||||
...buildEmbeddingDetail(),
|
||||
id: 'usage-cyber-risk-demo',
|
||||
@@ -322,13 +326,13 @@ describe('RequestDetailDrawer settlement pricing', () => {
|
||||
model: 'gpt-5',
|
||||
reasoning: { effort: 'xhigh' },
|
||||
},
|
||||
service_tier: 'priority',
|
||||
service_tier: tier,
|
||||
// A response-side tier must not be used for the Fast badge or billing.
|
||||
actual_service_tier: 'default',
|
||||
provider_request_body: {
|
||||
model: 'gpt-5.1',
|
||||
reasoning: { effort: 'max' },
|
||||
service_tier: 'priority',
|
||||
service_tier: tier,
|
||||
},
|
||||
status: 'failed',
|
||||
status_code: 400,
|
||||
@@ -369,10 +373,8 @@ describe('RequestDetailDrawer settlement pricing', () => {
|
||||
.toContain('gpt-5.1')
|
||||
expect(document.body.querySelector('[data-request-detail-model-badge="reasoning"]')?.textContent)
|
||||
.toContain('xhigh -> max')
|
||||
expect(document.body.querySelector('[data-request-detail-model-badge="fast"]')?.textContent)
|
||||
.toContain('Fast')
|
||||
expect(document.body.querySelector('[data-request-detail-model-badge="fast"]')?.textContent?.trim())
|
||||
.toBe('Fast')
|
||||
expect(document.body.querySelector(`[data-request-detail-model-badge="${badgeKey}"]`)?.textContent?.trim())
|
||||
.toBe(label)
|
||||
expect(document.body.querySelector('[data-request-detail-model-badge="cyber"]')?.textContent)
|
||||
.toContain('Cyber')
|
||||
const modelLayout = document.body.querySelector(
|
||||
@@ -386,8 +388,8 @@ describe('RequestDetailDrawer settlement pricing', () => {
|
||||
.toBe(true)
|
||||
expect(modelRow?.querySelector('[data-request-detail-model-badge="reasoning"]')?.textContent)
|
||||
.toContain('xhigh -> max')
|
||||
expect(modelRow?.querySelector('[data-request-detail-model-badge="fast"]')?.textContent)
|
||||
.toContain('Fast')
|
||||
expect(modelRow?.querySelector(`[data-request-detail-model-badge="${badgeKey}"]`)?.textContent)
|
||||
.toContain(label)
|
||||
expect(modelRow?.querySelector('[data-request-detail-model-badge="cyber"]')?.textContent)
|
||||
.toContain('Cyber')
|
||||
expect(modelLayout?.querySelector('[data-request-detail-model-badges-row]')).toBeNull()
|
||||
@@ -395,7 +397,7 @@ describe('RequestDetailDrawer settlement pricing', () => {
|
||||
expect([...serviceTierFacts?.querySelectorAll('dt') ?? []].map(node => node.textContent?.trim()))
|
||||
.toEqual(['上游请求层级', '计费层级'])
|
||||
expect([...serviceTierFacts?.querySelectorAll('dd') ?? []].map(node => node.textContent?.trim()))
|
||||
.toEqual(['Fast', 'Fast'])
|
||||
.toEqual([label, label])
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
@@ -560,6 +560,37 @@ describe('UsageRecordsTable', () => {
|
||||
},
|
||||
)
|
||||
|
||||
it.each(['ultrafast', 'flex', 'future-tier', ' UltraFast '])(
|
||||
'shows the final provider request tier %s without a fixed badge allowlist',
|
||||
(requested) => {
|
||||
const root = mountUsageRecordsTable([buildRecord({
|
||||
service_tier: requested,
|
||||
actual_service_tier: 'default',
|
||||
})])
|
||||
const badges = [...root.querySelectorAll<HTMLElement>('[data-usage-model-badge="service-tier"]')]
|
||||
expect(badges.length).toBeGreaterThan(0)
|
||||
for (const badge of badges) {
|
||||
expect(badge.textContent?.trim()).toBe(requested.trim())
|
||||
expect(badge.title).toBe(`上游请求档位:${requested.trim()}\n计费档位:${requested.trim()}`)
|
||||
expect(badge.getAttribute('aria-label')).toBe(
|
||||
`上游请求档位:${requested.trim()},计费档位:${requested.trim()}`,
|
||||
)
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
it.each(['auto', 'default', 'standard', ' DEFAULT ', '', ' ', null])(
|
||||
'does not show a badge for the default or absent request tier %s',
|
||||
(requested) => {
|
||||
const root = mountUsageRecordsTable([buildRecord({
|
||||
service_tier: requested,
|
||||
actual_service_tier: 'ultrafast',
|
||||
})])
|
||||
expect(root.querySelector('[data-usage-model-badge="service-tier"]')).toBeNull()
|
||||
expect(root.querySelector('[data-usage-model-badge="fast"]')).toBeNull()
|
||||
},
|
||||
)
|
||||
|
||||
it.each(['default', 'flex', null])(
|
||||
'ignores the response-side tier %s when the request tier is Fast',
|
||||
(actualServiceTier) => {
|
||||
|
||||
Reference in New Issue
Block a user