diff --git a/src/i18n/ja.ts b/src/i18n/ja.ts index 4ad1aa8..90f2d1e 100644 --- a/src/i18n/ja.ts +++ b/src/i18n/ja.ts @@ -140,17 +140,23 @@ export const jaOverrides = { 'usage.loading': 'ローカル SQLite の使用履歴を読み込んでいます', 'usage.stat.requests': '総リクエスト数', 'usage.stat.requestMeta': '成功 {success} · 失敗 {failed} · キャンセル {canceled}', + 'usage.stat.requestMetaTitle': '合計 {total} 件:成功 {success}、失敗 {failed}、キャンセル {canceled}', 'usage.stat.tokens': '合計 Token', - 'usage.stat.tokenMeta': '入 {input} · 出 {output}', + 'usage.stat.tokenMeta': '入力 {input} · 出力 {output}', + 'usage.stat.tokenMetaTitle': '入力 {input}、出力 {output}、推論 {reasoning}、キャッシュ読取 {cache}', 'usage.stat.successRate': '成功率', - 'usage.stat.reasoningMeta': '推論 {tokens}', + 'usage.stat.successMeta': '成功 {success} · 失敗 {failed}', + 'usage.stat.successMetaTitle': '成功 {success} 件、失敗 {failed} 件、キャンセル {canceled} 件', 'usage.stat.averageLatency': '平均レイテンシ', 'usage.stat.tps': 'TPS', - 'usage.stat.performanceMeta': 'RPM {rpm} · {latency} ms', + 'usage.stat.performanceMeta': 'RPM {rpm} · 平均レイテンシ {latency} ms', + 'usage.stat.performanceMetaTitle': 'TPS {tps}、RPM {rpm}、平均レイテンシ {latency} ms', 'usage.stat.cacheHitRate': 'キャッシュヒット率', - 'usage.stat.cacheHitMeta': 'キャッシュ {hit}/{input}', + 'usage.stat.cacheHitMeta': 'キャッシュ読取 {hit} · 入力 {input}', + 'usage.stat.cacheHitMetaTitle': 'キャッシュヒット率 {rate}%、読取 {hit} Token、入力 {input} Token', 'usage.stat.estimatedCost': '推定コスト', - 'usage.stat.costMeta': '計算 {priced}/{total} · 推定', + 'usage.stat.costMeta': '料金カバー率 {priced} / {total} 件', + 'usage.stat.costMetaTitle': 'モデル料金で {priced} / {total} 件を推定、未計算 {unpriced} 件', 'usage.pricing.coverage': '{priced} / {total} 件を計算済み · 利用可能なモデル料金 {saved} 件', 'usage.pricing.search': 'モデルを検索', 'usage.pricing.add': '手動で追加', diff --git a/src/i18n/locales/en.ts b/src/i18n/locales/en.ts index cff3412..1c0365b 100644 --- a/src/i18n/locales/en.ts +++ b/src/i18n/locales/en.ts @@ -140,17 +140,23 @@ export const en: Record = { 'usage.loading': 'Loading local SQLite usage history', 'usage.stat.requests': 'Total Requests', 'usage.stat.requestMeta': 'OK {success} · Fail {failed} · Canceled {canceled}', + 'usage.stat.requestMetaTitle': '{total} requests: {success} succeeded, {failed} failed, {canceled} canceled', 'usage.stat.tokens': 'Total Tokens', - 'usage.stat.tokenMeta': 'In {input} · Out {output}', + 'usage.stat.tokenMeta': 'Input {input} · Output {output}', + 'usage.stat.tokenMetaTitle': 'Input {input}, output {output}, reasoning {reasoning}, cache read {cache}', 'usage.stat.successRate': 'Success Rate', - 'usage.stat.reasoningMeta': 'Reasoning {tokens}', + 'usage.stat.successMeta': 'Success {success} · Failed {failed}', + 'usage.stat.successMetaTitle': '{success} succeeded, {failed} failed, {canceled} canceled', 'usage.stat.averageLatency': 'Average Latency', 'usage.stat.tps': 'TPS', - 'usage.stat.performanceMeta': 'RPM {rpm} · {latency} ms', + 'usage.stat.performanceMeta': 'RPM {rpm} · Avg. latency {latency} ms', + 'usage.stat.performanceMetaTitle': 'TPS {tps}, RPM {rpm}, average latency {latency} ms', 'usage.stat.cacheHitRate': 'Cache Hit Rate', - 'usage.stat.cacheHitMeta': 'Cache {hit}/{input}', + 'usage.stat.cacheHitMeta': 'Cache read {hit} · Input {input}', + 'usage.stat.cacheHitMetaTitle': 'Cache hit rate {rate}%, cache read {hit} tokens, input {input} tokens', 'usage.stat.estimatedCost': 'Estimated Cost', - 'usage.stat.costMeta': 'Priced {priced}/{total} · Est.', + 'usage.stat.costMeta': 'Price coverage: {priced} / {total} requests', + 'usage.stat.costMetaTitle': '{priced} of {total} requests estimated from model prices; {unpriced} unpriced', 'usage.pricing.coverage': '{priced} / {total} requests priced · {saved} model prices available', 'usage.pricing.search': 'Search model', 'usage.pricing.add': 'Add Manually', diff --git a/src/i18n/locales/zh-CN.ts b/src/i18n/locales/zh-CN.ts index ae0b02e..07f751f 100644 --- a/src/i18n/locales/zh-CN.ts +++ b/src/i18n/locales/zh-CN.ts @@ -138,17 +138,23 @@ export const zhCN = { 'usage.loading': '正在读取本地 SQLite 使用记录', 'usage.stat.requests': '请求总数', 'usage.stat.requestMeta': '成功 {success} · 失败 {failed} · 取消 {canceled}', + 'usage.stat.requestMetaTitle': '共 {total} 次请求:成功 {success},失败 {failed},取消 {canceled}', 'usage.stat.tokens': 'Token 总量', - 'usage.stat.tokenMeta': '入 {input} · 出 {output}', + 'usage.stat.tokenMeta': '输入 {input} · 输出 {output}', + 'usage.stat.tokenMetaTitle': '输入 {input},输出 {output},思考 {reasoning},缓存读取 {cache}', 'usage.stat.successRate': '成功率', - 'usage.stat.reasoningMeta': '思考 {tokens}', + 'usage.stat.successMeta': '成功 {success} · 失败 {failed}', + 'usage.stat.successMetaTitle': '成功 {success} 次,失败 {failed} 次,取消 {canceled} 次', 'usage.stat.averageLatency': '平均延迟', 'usage.stat.tps': 'TPS', - 'usage.stat.performanceMeta': 'RPM {rpm} · {latency} ms', + 'usage.stat.performanceMeta': 'RPM {rpm} · 平均延迟 {latency} ms', + 'usage.stat.performanceMetaTitle': 'TPS {tps},RPM {rpm},平均延迟 {latency} ms', 'usage.stat.cacheHitRate': '缓存命中率', - 'usage.stat.cacheHitMeta': '缓存 {hit}/{input}', + 'usage.stat.cacheHitMeta': '缓存读取 {hit} · 输入 {input}', + 'usage.stat.cacheHitMetaTitle': '缓存命中率 {rate}%,缓存读取 {hit} Token,输入 {input} Token', 'usage.stat.estimatedCost': '预估成本', - 'usage.stat.costMeta': '计价 {priced}/{total} · 估算', + 'usage.stat.costMeta': '价格覆盖 {priced} / {total} 次请求', + 'usage.stat.costMetaTitle': '已按模型价格估算 {priced} / {total} 次请求,未计价 {unpriced} 次', 'usage.pricing.coverage': '已计价 {priced} / {total} 次请求 · 可用 {saved} 个模型价格', 'usage.pricing.search': '搜索模型', 'usage.pricing.add': '手动添加', diff --git a/src/pages/UsageRecordsPage.tsx b/src/pages/UsageRecordsPage.tsx index df6969d..1122340 100644 --- a/src/pages/UsageRecordsPage.tsx +++ b/src/pages/UsageRecordsPage.tsx @@ -692,6 +692,12 @@ function OverviewView({ overview }: { overview: UsageOverview }) { failed: compactNumber(overview.failureCount), canceled: compactNumber(overview.canceledCount), }), + metaTitle: t('usage.stat.requestMetaTitle', { + total: compactNumber(overview.totalRequests), + success: compactNumber(overview.successCount), + failed: compactNumber(overview.failureCount), + canceled: compactNumber(overview.canceledCount), + }), }, { label: t('usage.stat.tokens'), @@ -700,11 +706,25 @@ function OverviewView({ overview }: { overview: UsageOverview }) { input: compactNumber(overview.inputTokens), output: compactNumber(overview.outputTokens), }), + metaTitle: t('usage.stat.tokenMetaTitle', { + input: compactNumber(overview.inputTokens), + output: compactNumber(overview.outputTokens), + reasoning: compactNumber(overview.reasoningTokens), + cache: compactNumber(overview.cacheReadTokens), + }), }, { label: t('usage.stat.successRate'), value: `${overview.successRate.toFixed(1)}%`, - meta: t('usage.stat.reasoningMeta', { tokens: compactNumber(overview.reasoningTokens) }), + meta: t('usage.stat.successMeta', { + success: compactNumber(overview.successCount), + failed: compactNumber(overview.failureCount), + }), + metaTitle: t('usage.stat.successMetaTitle', { + success: compactNumber(overview.successCount), + failed: compactNumber(overview.failureCount), + canceled: compactNumber(overview.canceledCount), + }), }, { label: t('usage.stat.tps'), @@ -713,6 +733,11 @@ function OverviewView({ overview }: { overview: UsageOverview }) { rpm: overview.rpm.toFixed(2), latency: Math.round(overview.averageLatencyMs), }), + metaTitle: t('usage.stat.performanceMetaTitle', { + tps: overview.tps.toFixed(1), + rpm: overview.rpm.toFixed(2), + latency: Math.round(overview.averageLatencyMs), + }), }, { label: t('usage.stat.cacheHitRate'), @@ -721,6 +746,11 @@ function OverviewView({ overview }: { overview: UsageOverview }) { hit: compactNumber(overview.cacheReadTokens), input: compactNumber(overview.inputTokens), }), + metaTitle: t('usage.stat.cacheHitMetaTitle', { + rate: (overview.cacheHitRate * 100).toFixed(1), + hit: compactNumber(overview.cacheReadTokens), + input: compactNumber(overview.inputTokens), + }), }, { label: t('usage.stat.estimatedCost'), @@ -729,17 +759,22 @@ function OverviewView({ overview }: { overview: UsageOverview }) { priced: compactNumber(overview.pricedRequests), total: compactNumber(overview.totalRequests), }), + metaTitle: t('usage.stat.costMetaTitle', { + priced: compactNumber(overview.pricedRequests), + total: compactNumber(overview.totalRequests), + unpriced: compactNumber(Math.max(overview.totalRequests - overview.pricedRequests, 0)), + }), }, ]; return (
- {cards.map(({ label, value, meta }) => ( + {cards.map(({ label, value, meta, metaTitle }) => (
{label} {value} - + {meta}