mirror of
https://github.com/farion1231/cc-switch.git
synced 2026-07-29 09:37:37 +08:00
i18n: complete usage panel and settings internationalization
- Add missing i18n keys for usage statistics panel (trends, cost, perMillion, etc.) - Add i18n keys for settings advanced section (configDir, proxy, modelTest, etc.) - Add streamCheck i18n keys for health check configuration - Remove hardcoded Chinese fallback values from t() calls - Add common keys (all, search, reset, actions, deleting)
This commit is contained in:
@@ -47,12 +47,12 @@ export function ModelTestConfigPanel() {
|
||||
try {
|
||||
setIsSaving(true);
|
||||
await saveStreamCheckConfig(config);
|
||||
toast.success(t("streamCheck.configSaved", "健康检查配置已保存"), {
|
||||
toast.success(t("streamCheck.configSaved"), {
|
||||
closeButton: true,
|
||||
});
|
||||
} catch (e) {
|
||||
toast.error(
|
||||
t("streamCheck.configSaveFailed", "保存失败") + ": " + String(e),
|
||||
t("streamCheck.configSaveFailed") + ": " + String(e),
|
||||
);
|
||||
} finally {
|
||||
setIsSaving(false);
|
||||
@@ -78,12 +78,12 @@ export function ModelTestConfigPanel() {
|
||||
{/* 测试模型配置 */}
|
||||
<div className="space-y-4">
|
||||
<h4 className="text-sm font-medium text-muted-foreground">
|
||||
{t("streamCheck.testModels", "测试模型")}
|
||||
{t("streamCheck.testModels")}
|
||||
</h4>
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="claudeModel">
|
||||
{t("streamCheck.claudeModel", "Claude 模型")}
|
||||
{t("streamCheck.claudeModel")}
|
||||
</Label>
|
||||
<Input
|
||||
id="claudeModel"
|
||||
@@ -97,7 +97,7 @@ export function ModelTestConfigPanel() {
|
||||
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="codexModel">
|
||||
{t("streamCheck.codexModel", "Codex 模型")}
|
||||
{t("streamCheck.codexModel")}
|
||||
</Label>
|
||||
<Input
|
||||
id="codexModel"
|
||||
@@ -111,7 +111,7 @@ export function ModelTestConfigPanel() {
|
||||
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="geminiModel">
|
||||
{t("streamCheck.geminiModel", "Gemini 模型")}
|
||||
{t("streamCheck.geminiModel")}
|
||||
</Label>
|
||||
<Input
|
||||
id="geminiModel"
|
||||
@@ -128,12 +128,12 @@ export function ModelTestConfigPanel() {
|
||||
{/* 检查参数配置 */}
|
||||
<div className="space-y-4">
|
||||
<h4 className="text-sm font-medium text-muted-foreground">
|
||||
{t("streamCheck.checkParams", "检查参数")}
|
||||
{t("streamCheck.checkParams")}
|
||||
</h4>
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="timeoutSecs">
|
||||
{t("streamCheck.timeout", "超时时间(秒)")}
|
||||
{t("streamCheck.timeout")}
|
||||
</Label>
|
||||
<Input
|
||||
id="timeoutSecs"
|
||||
@@ -152,7 +152,7 @@ export function ModelTestConfigPanel() {
|
||||
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="maxRetries">
|
||||
{t("streamCheck.maxRetries", "最大重试次数")}
|
||||
{t("streamCheck.maxRetries")}
|
||||
</Label>
|
||||
<Input
|
||||
id="maxRetries"
|
||||
@@ -171,7 +171,7 @@ export function ModelTestConfigPanel() {
|
||||
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="degradedThresholdMs">
|
||||
{t("streamCheck.degradedThreshold", "降级阈值(毫秒)")}
|
||||
{t("streamCheck.degradedThreshold")}
|
||||
</Label>
|
||||
<Input
|
||||
id="degradedThresholdMs"
|
||||
@@ -196,12 +196,12 @@ export function ModelTestConfigPanel() {
|
||||
{isSaving ? (
|
||||
<>
|
||||
<Loader2 className="mr-2 h-4 w-4 animate-spin" />
|
||||
{t("common.saving", "保存中...")}
|
||||
{t("common.saving")}
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<Save className="mr-2 h-4 w-4" />
|
||||
{t("common.save", "保存")}
|
||||
{t("common.save")}
|
||||
</>
|
||||
)}
|
||||
</Button>
|
||||
|
||||
@@ -63,7 +63,7 @@ export function PricingConfigPanel() {
|
||||
<div className="flex items-center gap-2">
|
||||
<ChevronRight className="h-4 w-4" />
|
||||
<CardTitle className="text-base">
|
||||
{t("usage.modelPricing", "模型定价")}
|
||||
{t("usage.modelPricing")}
|
||||
</CardTitle>
|
||||
</div>
|
||||
</CardHeader>
|
||||
@@ -85,7 +85,7 @@ export function PricingConfigPanel() {
|
||||
<ChevronRight className="h-4 w-4" />
|
||||
)}
|
||||
<CardTitle className="text-base">
|
||||
{t("usage.modelPricing", "模型定价")}
|
||||
{t("usage.modelPricing")}
|
||||
</CardTitle>
|
||||
</div>
|
||||
</CardHeader>
|
||||
@@ -93,7 +93,7 @@ export function PricingConfigPanel() {
|
||||
<CardContent>
|
||||
<Alert variant="destructive">
|
||||
<AlertDescription>
|
||||
{t("usage.loadPricingError", "加载定价数据失败")}:{" "}
|
||||
{t("usage.loadPricingError")}:{" "}
|
||||
{String(error)}
|
||||
</AlertDescription>
|
||||
</Alert>
|
||||
@@ -107,7 +107,7 @@ export function PricingConfigPanel() {
|
||||
<div className="space-y-4">
|
||||
<div className="flex items-center justify-between mb-4">
|
||||
<h4 className="text-sm font-medium text-muted-foreground">
|
||||
{t("usage.modelPricingDesc", "配置各模型的 Token 成本")} (每百万)
|
||||
{t("usage.modelPricingDesc")} {t("usage.perMillion")}
|
||||
</h4>
|
||||
<Button
|
||||
onClick={(e) => {
|
||||
@@ -117,7 +117,7 @@ export function PricingConfigPanel() {
|
||||
size="sm"
|
||||
>
|
||||
<Plus className="mr-1 h-4 w-4" />
|
||||
{t("common.add", "新增")}
|
||||
{t("common.add")}
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
@@ -125,10 +125,7 @@ export function PricingConfigPanel() {
|
||||
{!pricing || pricing.length === 0 ? (
|
||||
<Alert>
|
||||
<AlertDescription>
|
||||
{t(
|
||||
"usage.noPricingData",
|
||||
'暂无定价数据。点击"新增"添加模型定价配置。',
|
||||
)}
|
||||
{t("usage.noPricingData")}
|
||||
</AlertDescription>
|
||||
</Alert>
|
||||
) : (
|
||||
@@ -136,22 +133,22 @@ export function PricingConfigPanel() {
|
||||
<Table>
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
<TableHead>{t("usage.model", "模型")}</TableHead>
|
||||
<TableHead>{t("usage.displayName", "显示名称")}</TableHead>
|
||||
<TableHead>{t("usage.model")}</TableHead>
|
||||
<TableHead>{t("usage.displayName")}</TableHead>
|
||||
<TableHead className="text-right">
|
||||
{t("usage.inputCost", "输入成本")}
|
||||
{t("usage.inputCost")}
|
||||
</TableHead>
|
||||
<TableHead className="text-right">
|
||||
{t("usage.outputCost", "输出成本")}
|
||||
{t("usage.outputCost")}
|
||||
</TableHead>
|
||||
<TableHead className="text-right">
|
||||
{t("usage.cacheReadCost", "缓存读取")}
|
||||
{t("usage.cacheReadCost")}
|
||||
</TableHead>
|
||||
<TableHead className="text-right">
|
||||
{t("usage.cacheWriteCost", "缓存写入")}
|
||||
{t("usage.cacheWriteCost")}
|
||||
</TableHead>
|
||||
<TableHead className="text-right">
|
||||
{t("common.actions", "操作")}
|
||||
{t("common.actions")}
|
||||
</TableHead>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
@@ -183,7 +180,7 @@ export function PricingConfigPanel() {
|
||||
setIsAddingNew(false);
|
||||
setEditingModel(model);
|
||||
}}
|
||||
title={t("common.edit", "编辑")}
|
||||
title={t("common.edit")}
|
||||
>
|
||||
<Pencil className="h-4 w-4" />
|
||||
</Button>
|
||||
@@ -191,7 +188,7 @@ export function PricingConfigPanel() {
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
onClick={() => setDeleteConfirm(model.modelId)}
|
||||
title={t("common.delete", "删除")}
|
||||
title={t("common.delete")}
|
||||
className="text-destructive hover:text-destructive"
|
||||
>
|
||||
<Trash2 className="h-4 w-4" />
|
||||
@@ -224,18 +221,15 @@ export function PricingConfigPanel() {
|
||||
<DialogContent>
|
||||
<DialogHeader>
|
||||
<DialogTitle>
|
||||
{t("usage.deleteConfirmTitle", "确认删除")}
|
||||
{t("usage.deleteConfirmTitle")}
|
||||
</DialogTitle>
|
||||
<DialogDescription>
|
||||
{t(
|
||||
"usage.deleteConfirmDesc",
|
||||
"确定要删除此模型定价配置吗?此操作无法撤销。",
|
||||
)}
|
||||
{t("usage.deleteConfirmDesc")}
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
<DialogFooter>
|
||||
<Button variant="outline" onClick={() => setDeleteConfirm(null)}>
|
||||
{t("common.cancel", "取消")}
|
||||
{t("common.cancel")}
|
||||
</Button>
|
||||
<Button
|
||||
variant="destructive"
|
||||
@@ -243,8 +237,8 @@ export function PricingConfigPanel() {
|
||||
disabled={deleteMutation.isPending}
|
||||
>
|
||||
{deleteMutation.isPending
|
||||
? t("common.deleting", "删除中...")
|
||||
: t("common.delete", "删除")}
|
||||
? t("common.deleting")
|
||||
: t("common.delete")}
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
|
||||
@@ -84,11 +84,11 @@ export function RequestLogTable() {
|
||||
}
|
||||
>
|
||||
<SelectTrigger className="w-[130px] bg-background">
|
||||
<SelectValue placeholder={t("usage.appType", "应用类型")} />
|
||||
<SelectValue placeholder={t("usage.appType")} />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="all">
|
||||
{t("usage.allApps", { defaultValue: "全部应用" })}
|
||||
{t("usage.allApps")}
|
||||
</SelectItem>
|
||||
<SelectItem value="claude">Claude</SelectItem>
|
||||
<SelectItem value="codex">Codex</SelectItem>
|
||||
@@ -106,10 +106,10 @@ export function RequestLogTable() {
|
||||
}
|
||||
>
|
||||
<SelectTrigger className="w-[130px] bg-background">
|
||||
<SelectValue placeholder={t("usage.statusCode", "状态码")} />
|
||||
<SelectValue placeholder={t("usage.statusCode")} />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="all">{t("common.all", "全部状态")}</SelectItem>
|
||||
<SelectItem value="all">{t("common.all")}</SelectItem>
|
||||
<SelectItem value="200">200 OK</SelectItem>
|
||||
<SelectItem value="400">400 Bad Request</SelectItem>
|
||||
<SelectItem value="401">401 Unauthorized</SelectItem>
|
||||
@@ -122,10 +122,7 @@ export function RequestLogTable() {
|
||||
<div className="relative flex-1">
|
||||
<Search className="absolute left-2.5 top-2.5 h-4 w-4 text-muted-foreground" />
|
||||
<Input
|
||||
placeholder={t(
|
||||
"usage.searchProviderPlaceholder",
|
||||
"搜索供应商...",
|
||||
)}
|
||||
placeholder={t("usage.searchProviderPlaceholder")}
|
||||
className="pl-9 bg-background"
|
||||
value={tempFilters.providerName || ""}
|
||||
onChange={(e) =>
|
||||
@@ -137,7 +134,7 @@ export function RequestLogTable() {
|
||||
/>
|
||||
</div>
|
||||
<Input
|
||||
placeholder={t("usage.searchModelPlaceholder", "搜索模型...")}
|
||||
placeholder={t("usage.searchModelPlaceholder")}
|
||||
className="w-[180px] bg-background"
|
||||
value={tempFilters.model || ""}
|
||||
onChange={(e) =>
|
||||
@@ -153,7 +150,7 @@ export function RequestLogTable() {
|
||||
<div className="flex flex-wrap items-center justify-between gap-3">
|
||||
<div className="flex items-center gap-2 text-sm text-muted-foreground">
|
||||
<span className="whitespace-nowrap">
|
||||
{t("usage.timeRange", { defaultValue: "时间范围" })}:
|
||||
{t("usage.timeRange")}:
|
||||
</span>
|
||||
<Input
|
||||
type="datetime-local"
|
||||
@@ -204,7 +201,7 @@ export function RequestLogTable() {
|
||||
className="h-8"
|
||||
>
|
||||
<Search className="mr-2 h-3.5 w-3.5" />
|
||||
{t("common.search", "查询")}
|
||||
{t("common.search")}
|
||||
</Button>
|
||||
<Button
|
||||
size="sm"
|
||||
@@ -213,7 +210,7 @@ export function RequestLogTable() {
|
||||
className="h-8"
|
||||
>
|
||||
<X className="mr-2 h-3.5 w-3.5" />
|
||||
{t("common.reset", "重置")}
|
||||
{t("common.reset")}
|
||||
</Button>
|
||||
<Button
|
||||
size="sm"
|
||||
@@ -236,34 +233,34 @@ export function RequestLogTable() {
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
<TableHead className="whitespace-nowrap">
|
||||
{t("usage.time", "时间")}
|
||||
{t("usage.time")}
|
||||
</TableHead>
|
||||
<TableHead className="whitespace-nowrap">
|
||||
{t("usage.provider", "供应商")}
|
||||
{t("usage.provider")}
|
||||
</TableHead>
|
||||
<TableHead className="min-w-[280px] whitespace-nowrap">
|
||||
{t("usage.billingModel", "计费模型")}
|
||||
{t("usage.billingModel")}
|
||||
</TableHead>
|
||||
<TableHead className="text-right whitespace-nowrap">
|
||||
{t("usage.inputTokens", "输入")}
|
||||
{t("usage.inputTokens")}
|
||||
</TableHead>
|
||||
<TableHead className="text-right whitespace-nowrap">
|
||||
{t("usage.outputTokens", "输出")}
|
||||
{t("usage.outputTokens")}
|
||||
</TableHead>
|
||||
<TableHead className="text-right min-w-[90px] whitespace-nowrap">
|
||||
{t("usage.cacheReadTokens", "缓存读取")}
|
||||
{t("usage.cacheReadTokens")}
|
||||
</TableHead>
|
||||
<TableHead className="text-right min-w-[90px] whitespace-nowrap">
|
||||
{t("usage.cacheCreationTokens", "缓存写入")}
|
||||
{t("usage.cacheCreationTokens")}
|
||||
</TableHead>
|
||||
<TableHead className="text-right whitespace-nowrap">
|
||||
{t("usage.totalCost", "成本")}
|
||||
{t("usage.totalCost")}
|
||||
</TableHead>
|
||||
<TableHead className="text-center min-w-[140px] whitespace-nowrap">
|
||||
{t("usage.timingInfo", "用时/首字")}
|
||||
{t("usage.timingInfo")}
|
||||
</TableHead>
|
||||
<TableHead className="whitespace-nowrap">
|
||||
{t("usage.status", "状态")}
|
||||
{t("usage.status")}
|
||||
</TableHead>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
@@ -274,7 +271,7 @@ export function RequestLogTable() {
|
||||
colSpan={10}
|
||||
className="text-center text-muted-foreground"
|
||||
>
|
||||
{t("usage.noData", "暂无数据")}
|
||||
{t("usage.noData")}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
) : (
|
||||
@@ -287,7 +284,7 @@ export function RequestLogTable() {
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
{log.providerName ||
|
||||
t("usage.unknownProvider", "未知供应商")}
|
||||
t("usage.unknownProvider")}
|
||||
</TableCell>
|
||||
<TableCell
|
||||
className="font-mono text-sm max-w-[280px] truncate"
|
||||
@@ -355,8 +352,8 @@ export function RequestLogTable() {
|
||||
}`}
|
||||
>
|
||||
{log.isStreaming
|
||||
? t("usage.stream", "流")
|
||||
: t("usage.nonStream", "非流")}
|
||||
? t("usage.stream")
|
||||
: t("usage.nonStream")}
|
||||
</span>
|
||||
</div>
|
||||
</TableCell>
|
||||
@@ -382,7 +379,7 @@ export function RequestLogTable() {
|
||||
{total > 0 && (
|
||||
<div className="flex items-center justify-between px-2">
|
||||
<span className="text-sm text-muted-foreground">
|
||||
{t("usage.totalRecords", "共 {{total}} 条记录", { total })}
|
||||
{t("usage.totalRecords", { total })}
|
||||
</span>
|
||||
<div className="flex items-center gap-1">
|
||||
<Button
|
||||
|
||||
@@ -25,9 +25,9 @@ export function UsageDashboard() {
|
||||
>
|
||||
<div className="flex flex-col sm:flex-row sm:items-center justify-between gap-4">
|
||||
<div className="flex flex-col gap-1">
|
||||
<h2 className="text-2xl font-bold">{t("usage.title", "使用统计")}</h2>
|
||||
<h2 className="text-2xl font-bold">{t("usage.title")}</h2>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
{t("usage.subtitle", "查看 AI 模型的使用情况和成本统计")}
|
||||
{t("usage.subtitle")}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -41,19 +41,19 @@ export function UsageDashboard() {
|
||||
value="1d"
|
||||
className="flex-1 sm:flex-none sm:px-6 data-[state=active]:bg-primary/10 data-[state=active]:text-primary hover:text-primary transition-colors"
|
||||
>
|
||||
{t("usage.today", "24小时")}
|
||||
{t("usage.today")}
|
||||
</TabsTrigger>
|
||||
<TabsTrigger
|
||||
value="7d"
|
||||
className="flex-1 sm:flex-none sm:px-6 data-[state=active]:bg-primary/10 data-[state=active]:text-primary hover:text-primary transition-colors"
|
||||
>
|
||||
{t("usage.last7days", "7天")}
|
||||
{t("usage.last7days")}
|
||||
</TabsTrigger>
|
||||
<TabsTrigger
|
||||
value="30d"
|
||||
className="flex-1 sm:flex-none sm:px-6 data-[state=active]:bg-primary/10 data-[state=active]:text-primary hover:text-primary transition-colors"
|
||||
>
|
||||
{t("usage.last30days", "30天")}
|
||||
{t("usage.last30days")}
|
||||
</TabsTrigger>
|
||||
</TabsList>
|
||||
</Tabs>
|
||||
@@ -69,15 +69,15 @@ export function UsageDashboard() {
|
||||
<TabsList className="bg-muted/50">
|
||||
<TabsTrigger value="logs" className="gap-2">
|
||||
<ListFilter className="h-4 w-4" />
|
||||
{t("usage.requestLogs", "请求日志")}
|
||||
{t("usage.requestLogs")}
|
||||
</TabsTrigger>
|
||||
<TabsTrigger value="providers" className="gap-2">
|
||||
<Activity className="h-4 w-4" />
|
||||
{t("usage.providerStats", "Provider 统计")}
|
||||
{t("usage.providerStats")}
|
||||
</TabsTrigger>
|
||||
<TabsTrigger value="models" className="gap-2">
|
||||
<BarChart3 className="h-4 w-4" />
|
||||
{t("usage.modelStats", "模型统计")}
|
||||
{t("usage.modelStats")}
|
||||
</TabsTrigger>
|
||||
</TabsList>
|
||||
</div>
|
||||
|
||||
@@ -34,7 +34,7 @@ export function UsageSummaryCards({ days }: UsageSummaryCardsProps) {
|
||||
|
||||
return [
|
||||
{
|
||||
title: t("usage.totalRequests", "总请求数"),
|
||||
title: t("usage.totalRequests"),
|
||||
value: totalRequests.toLocaleString(),
|
||||
icon: Activity,
|
||||
color: "text-blue-500",
|
||||
@@ -42,7 +42,7 @@ export function UsageSummaryCards({ days }: UsageSummaryCardsProps) {
|
||||
subValue: null,
|
||||
},
|
||||
{
|
||||
title: t("usage.totalCost", "总成本"),
|
||||
title: t("usage.totalCost"),
|
||||
value: `$${totalCost.toFixed(4)}`,
|
||||
icon: DollarSign,
|
||||
color: "text-green-500",
|
||||
@@ -50,7 +50,7 @@ export function UsageSummaryCards({ days }: UsageSummaryCardsProps) {
|
||||
subValue: null,
|
||||
},
|
||||
{
|
||||
title: t("usage.totalTokens", "总 Token 数"),
|
||||
title: t("usage.totalTokens"),
|
||||
value: totalTokens.toLocaleString(),
|
||||
icon: Layers,
|
||||
color: "text-purple-500",
|
||||
@@ -58,13 +58,13 @@ export function UsageSummaryCards({ days }: UsageSummaryCardsProps) {
|
||||
subValue: (
|
||||
<div className="flex flex-col gap-1 text-xs text-muted-foreground mt-3 pt-3 border-t border-border/50">
|
||||
<div className="flex justify-between items-center">
|
||||
<span>{t("usage.input", { defaultValue: "Input" })}</span>
|
||||
<span>{t("usage.input")}</span>
|
||||
<span className="text-foreground/80">
|
||||
{(inputTokens / 1000).toFixed(1)}k
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex justify-between items-center">
|
||||
<span>{t("usage.output", { defaultValue: "Output" })}</span>
|
||||
<span>{t("usage.output")}</span>
|
||||
<span className="text-foreground/80">
|
||||
{(outputTokens / 1000).toFixed(1)}k
|
||||
</span>
|
||||
@@ -73,7 +73,7 @@ export function UsageSummaryCards({ days }: UsageSummaryCardsProps) {
|
||||
),
|
||||
},
|
||||
{
|
||||
title: t("usage.cacheTokens", "缓存 Token"),
|
||||
title: t("usage.cacheTokens"),
|
||||
value: totalCacheTokens.toLocaleString(),
|
||||
icon: Database,
|
||||
color: "text-orange-500",
|
||||
@@ -81,13 +81,13 @@ export function UsageSummaryCards({ days }: UsageSummaryCardsProps) {
|
||||
subValue: (
|
||||
<div className="flex flex-col gap-1 text-xs text-muted-foreground mt-3 pt-3 border-t border-border/50">
|
||||
<div className="flex justify-between items-center">
|
||||
<span>{t("usage.cacheWrite", { defaultValue: "Write" })}</span>
|
||||
<span>{t("usage.cacheWrite")}</span>
|
||||
<span className="text-foreground/80">
|
||||
{(cacheWriteTokens / 1000).toFixed(1)}k
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex justify-between items-center">
|
||||
<span>{t("usage.cacheRead", { defaultValue: "Read" })}</span>
|
||||
<span>{t("usage.cacheRead")}</span>
|
||||
<span className="text-foreground/80">
|
||||
{(cacheReadTokens / 1000).toFixed(1)}k
|
||||
</span>
|
||||
|
||||
Reference in New Issue
Block a user