feat(usage): 使用记录展示映射前的推理强度

用量行新增 requested_reasoning_effort,记录分组策略与模型族改写前的客户端请求值;推理强度列与模型列一致,主行显示请求值,有映射时用 ↳ 展示实际转发值。
This commit is contained in:
刘佳林
2026-08-25 15:10:52 +08:00
parent aa2c4e8d13
commit 11ada80d58
40 changed files with 595 additions and 97 deletions
@@ -0,0 +1,33 @@
import { describe, expect, it } from 'vitest'
import {
formatReasoningEffort,
formatReasoningEffortMapping,
reasoningEffortValuesEqual,
} from '@/utils/format'
describe('formatReasoningEffort', () => {
it('title-cases known effort values', () => {
expect(formatReasoningEffort('max')).toBe('Max')
expect(formatReasoningEffort('x-high')).toBe('XHigh')
expect(formatReasoningEffort(null)).toBe('-')
})
})
describe('formatReasoningEffortMapping', () => {
it('shows a single value when requested and forwarded match', () => {
expect(formatReasoningEffortMapping('max', 'max')).toBe('Max')
expect(formatReasoningEffortMapping(null, 'high')).toBe('High')
})
it('shows requested then forwarded when mapping changed the value', () => {
expect(formatReasoningEffortMapping('max', 'xhigh')).toBe('Max → XHigh')
expect(formatReasoningEffortMapping('high', 'medium')).toBe('High → Medium')
})
})
describe('reasoningEffortValuesEqual', () => {
it('treats x-high aliases as equal', () => {
expect(reasoningEffortValuesEqual('x-high', 'xhigh')).toBe(true)
expect(reasoningEffortValuesEqual('max', 'xhigh')).toBe(false)
})
})
+30 -1
View File
@@ -211,11 +211,15 @@ export function parseDateTimeLocalInput(value: string): number | null {
* @param effort 原始 effort(如 "low" / "medium" / "high" / "xhigh")
* @returns 格式化后的字符串(Low / Medium / High / Xhigh),无值返回 "-"
*/
function normalizeReasoningEffortKey(effort: string | null | undefined): string {
return (effort ?? '').toString().trim().toLowerCase().replace(/[-_\s]/g, '')
}
export function formatReasoningEffort(effort: string | null | undefined): string {
const raw = (effort ?? '').toString().trim()
if (!raw) return '-'
const normalized = raw.toLowerCase().replace(/[-_\s]/g, '')
const normalized = normalizeReasoningEffortKey(raw)
switch (normalized) {
case 'low':
return 'Low'
@@ -237,6 +241,31 @@ export function formatReasoningEffort(effort: string | null | undefined): string
}
}
export function reasoningEffortValuesEqual(
left: string | null | undefined,
right: string | null | undefined,
): boolean {
const a = normalizeReasoningEffortKey(left)
const b = normalizeReasoningEffortKey(right)
if (!a && !b) return true
return a !== '' && a === b
}
/** Requested vs forwarded effort for usage export; one value when they match. */
export function formatReasoningEffortMapping(
requested: string | null | undefined,
forwarded: string | null | undefined,
): string {
const requestedLabel = formatReasoningEffort(requested)
const forwardedLabel = formatReasoningEffort(forwarded)
if (requestedLabel === '-' && forwardedLabel === '-') return '-'
if (requestedLabel === '-' || reasoningEffortValuesEqual(requested, forwarded)) {
return forwardedLabel === '-' ? requestedLabel : forwardedLabel
}
if (forwardedLabel === '-') return requestedLabel
return `${requestedLabel} → ${forwardedLabel}`
}
/**
* 格式化时间(显示时分秒)
* @param date 日期字符串或 Date 对象