mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-10 21:20:20 +08:00
fix(usage): expose pending reasoning and exact reset expiry
This commit is contained in:
@@ -2029,6 +2029,22 @@ fn build_runtime_request_metadata_seed(
|
||||
provider_request_body_ref.as_deref(),
|
||||
plan.body.body_bytes_b64.as_deref(),
|
||||
);
|
||||
let provider_request_body = plan.body.json_body.as_ref().or_else(|| {
|
||||
context_value_ref(context, "provider_request_body").filter(|value| !value.is_null())
|
||||
});
|
||||
let provider_api_format = context_string(context, "provider_api_format")
|
||||
.or_else(|| non_empty_str(Some(plan.provider_api_format.as_str())));
|
||||
let provider_model = context_string(context, "mapped_model")
|
||||
.or_else(|| non_empty_str(plan.model_name.as_deref()));
|
||||
let source_model =
|
||||
context_string(context, "model").or_else(|| non_empty_str(plan.model_name.as_deref()));
|
||||
metadata = attach_provider_request_body_metadata(
|
||||
metadata,
|
||||
provider_api_format.as_deref(),
|
||||
provider_model.as_deref(),
|
||||
source_model.as_deref(),
|
||||
provider_request_body,
|
||||
);
|
||||
if let Some(proxy) = plan.proxy.as_ref() {
|
||||
if let Some(node_id) = proxy
|
||||
.node_id
|
||||
@@ -3625,7 +3641,8 @@ mod tests {
|
||||
content_encoding: None,
|
||||
body: RequestBody::from_json(json!({
|
||||
"model": "gpt-5.4",
|
||||
"messages": [{"role": "user", "content": "hello"}]
|
||||
"messages": [{"role": "user", "content": "hello"}],
|
||||
"reasoning": {"effort": "max"}
|
||||
})),
|
||||
stream: false,
|
||||
client_api_format: "claude:messages".to_string(),
|
||||
@@ -3684,7 +3701,10 @@ mod tests {
|
||||
.as_ref()
|
||||
.and_then(Value::as_object)
|
||||
.expect("pending usage should only keep lightweight request metadata");
|
||||
assert_eq!(metadata.len(), 1);
|
||||
assert_eq!(
|
||||
metadata.get("provider_reasoning_effort"),
|
||||
Some(&json!("max"))
|
||||
);
|
||||
let body_size = metadata
|
||||
.get("body_size")
|
||||
.and_then(Value::as_object)
|
||||
|
||||
@@ -310,7 +310,7 @@
|
||||
:title="item.title"
|
||||
class="tabular-nums"
|
||||
>
|
||||
{{ item.displayKey }} {{ formatCodexResetCreditDays(item.remainingSeconds) }}
|
||||
{{ item.displayKey }} {{ formatCodexResetCreditExpiresAt(item.expiresAt) }}
|
||||
</span>
|
||||
<span
|
||||
v-if="itemIndex < getVisibleCodexResetCreditItems(key).length - 1"
|
||||
@@ -1019,7 +1019,7 @@ import {
|
||||
import { getGeminiCliAccountCreditsText } from '@/utils/providerKeyQuota'
|
||||
import {
|
||||
formatCodexResetCreditCount as formatCodexResetCreditCountLabel,
|
||||
formatCodexResetCreditDays,
|
||||
formatCodexResetCreditExpiresAt,
|
||||
getCodexResetCreditAvailableCount as getCodexResetCreditAvailableCountFromSnapshot,
|
||||
getVisibleCodexResetCreditItems as getVisibleCodexResetCreditItemsFromSnapshot,
|
||||
} from './codex-reset-credit-display'
|
||||
@@ -1702,7 +1702,7 @@ async function handleConsumeCodexResetCredit(key: EndpointAPIKey) {
|
||||
|
||||
const earliest = getVisibleCodexResetCreditItems(key)[0]
|
||||
const detailMessage = earliest
|
||||
? `\n当前最早过期项:${earliest.displayKey},约 ${formatCodexResetCreditDays(earliest.remainingSeconds)} 后过期。`
|
||||
? `\n当前最早过期项:${earliest.displayKey},${formatCodexResetCreditExpiresAt(earliest.expiresAt)} 过期。`
|
||||
: ''
|
||||
const confirmed = await confirm({
|
||||
title: legacyT('确认使用 Codex 重置机会'),
|
||||
|
||||
+16
-4
@@ -2,7 +2,7 @@ import { describe, expect, it } from 'vitest'
|
||||
|
||||
import {
|
||||
formatCodexResetCreditCount,
|
||||
formatCodexResetCreditDays,
|
||||
formatCodexResetCreditExpiresAt,
|
||||
getCodexResetCreditAvailableCount,
|
||||
getVisibleCodexResetCreditItems,
|
||||
} from '@/features/providers/components/codex-reset-credit-display'
|
||||
@@ -74,8 +74,20 @@ describe('codex reset credit display helpers', () => {
|
||||
])
|
||||
})
|
||||
|
||||
it('formats reset credit remaining days with a one-day minimum', () => {
|
||||
expect(formatCodexResetCreditDays(1)).toBe('1天')
|
||||
expect(formatCodexResetCreditDays(86_401)).toBe('2天')
|
||||
it('formats reset credit expiry as a precise local timestamp', () => {
|
||||
const expiresAt = new Date(2026, 6, 12, 22, 4, 41).getTime() / 1000
|
||||
expect(formatCodexResetCreditExpiresAt(expiresAt)).toBe('07-12 22:04:41')
|
||||
expect(formatCodexResetCreditExpiresAt(null)).toBe('-')
|
||||
})
|
||||
|
||||
it('derives a stable expiry timestamp from remaining seconds', () => {
|
||||
const snapshot: QuotaResetCreditsSnapshot = {
|
||||
available_count: 1,
|
||||
updated_at: 1_700_000_000,
|
||||
credits: [{ status: 'available', remaining_seconds: 600 }],
|
||||
}
|
||||
|
||||
expect(getVisibleCodexResetCreditItems(snapshot, 1_700_000_300)[0]?.expiresAt)
|
||||
.toBe(1_700_000_600)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -66,7 +66,7 @@ export function getVisibleCodexResetCreditItems(
|
||||
if (remainingSeconds === null || remainingSeconds <= 0) return null
|
||||
return {
|
||||
id: item.id,
|
||||
expiresAt: item.expires_at,
|
||||
expiresAt: nowUnixSecs + remainingSeconds,
|
||||
remainingSeconds,
|
||||
} satisfies CodexResetCreditDisplayCandidate
|
||||
})
|
||||
@@ -83,7 +83,11 @@ export function getVisibleCodexResetCreditItems(
|
||||
})
|
||||
}
|
||||
|
||||
export function formatCodexResetCreditDays(remainingSeconds: number): string {
|
||||
const days = Math.max(1, Math.ceil(remainingSeconds / 86_400))
|
||||
return `${days}天`
|
||||
export function formatCodexResetCreditExpiresAt(expiresAt: number | null | undefined): string {
|
||||
if (typeof expiresAt !== 'number' || !Number.isFinite(expiresAt)) return '-'
|
||||
const date = new Date(expiresAt * 1000)
|
||||
if (Number.isNaN(date.getTime())) return '-'
|
||||
|
||||
const pad = (value: number) => String(value).padStart(2, '0')
|
||||
return `${pad(date.getMonth() + 1)}-${pad(date.getDate())} ${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}`
|
||||
}
|
||||
|
||||
@@ -288,6 +288,15 @@ describe('UsageRecordsTable', () => {
|
||||
expect(root.textContent).toContain('xhigh')
|
||||
})
|
||||
|
||||
it('shows request reasoning effort while the record is pending', () => {
|
||||
const root = mountUsageRecordsTable([buildRecord({
|
||||
status: 'pending',
|
||||
reasoning_effort: 'max',
|
||||
})])
|
||||
|
||||
expect(root.textContent).toContain('max')
|
||||
})
|
||||
|
||||
it('shows fast badge for priority service tier', () => {
|
||||
const root = mountUsageRecordsTable([buildRecord({ service_tier: 'priority' })])
|
||||
|
||||
|
||||
Reference in New Issue
Block a user