dsh-bottom-info-bar 1.20.13 → 1.20.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/README.zh-CN.md +1 -1
- package/lib/client.js +53 -10
- package/lib/index.js +47 -13
- package/lib/locales.js +10 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -11,7 +11,7 @@ A DeepSeek Harness plugin that replaces the stats row under the composer with on
|
|
|
11
11
|
|
|
12
12
|
## What it shows
|
|
13
13
|
|
|
14
|
-
The bar follows the active session and picks one of three readings per provider (mutually exclusive, nothing to switch by hand): **balance** shows the real balance from the provider's own API, **subscription quota** shows each quota window's remaining allowance with its reset countdown, and **cloud billing** shows this month's real spend from the official billing API. On top of that come four spend tallies — this session, today, last 30 days, all time — plus extras such as time and custom text.
|
|
14
|
+
The bar follows the active session and picks one of three readings per provider (mutually exclusive, nothing to switch by hand): **balance** shows the real balance from the provider's own API, **subscription quota** shows each quota window's remaining allowance with its reset countdown, and **cloud billing** shows this month's real spend from the official billing API. On top of that come four spend tallies — this session, today, last 30 days, all time — plus extras such as time and custom text. In balance mode, hovering the balance expands it into topped-up and granted balances, so gifted credit is never conflated with the money you paid in.
|
|
15
15
|
|
|
16
16
|
Click the bar to switch between **Full** and **Compact**. They differ in exactly one way: Full keeps DSH's native stats row, Compact collapses it. Whether a field appears is decided by that field's own switch alone, so the main row reads identically in both.
|
|
17
17
|
|
package/README.zh-CN.md
CHANGED
|
@@ -11,7 +11,7 @@ DeepSeek Harness 插件:把输入框下方那行统计栏换成一行信息栏
|
|
|
11
11
|
|
|
12
12
|
## 它显示什么
|
|
13
13
|
|
|
14
|
-
信息栏跟随当前会话,按服务商自动选择三种口径之一(互斥,不用手动切):**余额制**显示官方接口的真实余额,**订阅制**显示各额度窗口剩余额度与重置倒计时,**云账单制**显示官方账单接口的本月真实花费。之外还有本会话/今天/近 30
|
|
14
|
+
信息栏跟随当前会话,按服务商自动选择三种口径之一(互斥,不用手动切):**余额制**显示官方接口的真实余额,**订阅制**显示各额度窗口剩余额度与重置倒计时,**云账单制**显示官方账单接口的本月真实花费。之外还有本会话/今天/近 30 天/累计四档花费,以及时间、自定义文字等通用项。余额制下把鼠标停在余额上,会展开「充值余额 / 赠金余额」两行明细,赠送的那部分不再是糊涂账。
|
|
15
15
|
|
|
16
16
|
点一下信息栏可以在**完整**与**简洁**之间切换,区别只有一处:完整保留 DSH 原生统计行,简洁把它收起。看哪个字段,只由该字段自己的开关决定,两种模式显示的主行逐字相同。
|
|
17
17
|
|
package/lib/client.js
CHANGED
|
@@ -104,7 +104,7 @@ const BIB_SET_NATIVE_MENU = bibSetNative('Menu');
|
|
|
104
104
|
// 与上面同一条铁律:取不到时退回插件内等价实现,绝不把 undefined 交给 React.createElement。
|
|
105
105
|
const BIB_SET_NATIVE_RISK_CONFIRM = bibSetNative('RiskConfirmation');
|
|
106
106
|
const LOCALE_NAMESPACE = 'dsh-bottom-info-bar';
|
|
107
|
-
const LOCALES = {"zh":{"meta.title":"底部信息栏","meta.description":"在输入框下方显示当前模型、余额和花费。","ui.requestTimedOut":"请求超时","ui.requestCanceled":"请求已取消","ui.couldNotParseResponse":"响应解析失败","ui.rpcFailed":"RPC 失败","ui.refreshFailed":"刷新失败","color.red":"红","color.green":"绿","color.blue":"蓝","color.purple":"紫","color.orange":"橙","color.neutral":"中性","ui.pleaseTryAgainLater":"请稍后再试","ui.restoreDefaultColor":"恢复默认颜色","ui.infoBarSettings":"信息栏","ui.settingsAreTemporarilyUnavailable":"暂时无法读取设置","ui.loadingInfoBarSettings":"正在加载设置…","ui.couldNotLoadInfoBar":"无法读取信息栏设置:","ui.changesAppliedButCouldNot":"已应用,但无法保存到本地:","ui.unknownReason":"未知原因","ui.couldNotSave":"{errorPrefix}保存失败:{value}","ui.color":"“{value}”颜色:","ui.hasAnInvalidColorEnter":"“{value}”的颜色格式不正确,请输入 #RRGGBB(例如 #0044CC)。","ui.defaultColorsRestored":"已恢复默认颜色","ui.defaultLabelsRestored":"已恢复默认显示设置","ui.couldNotReset":"重置失败:{value}","ui.show":"显示{label}","ui.clickToHide":"点击隐藏","ui.clickToShow":"点击显示","ui.presetColor":"{label}的预设颜色","ui.customColor":"{label}的自定义颜色","ui.customColorOpenColorPicker":"自定义颜色(打开系统取色器)","ui.customColorItem":"自定义…","ui.colorSwatchLabel":"{label}的颜色","ui.hexColor":"{label}的十六进制颜色","ui.expand":"展开","ui.collapse":"收起","ui.saving":"正在保存…","ui.processing":"正在处理…","ui.visibleFields":"要显示的信息","ui.timeDateTitle":"时间与日期","ui.timeDateDesc":"主时间和世界时间的时区。","ui.customTextSectionDesc":"在信息栏中显示一行自定义文字。","ui.resetConfirmTitle":"重置信息栏设置","ui.resetConfirmDescFields":"将所有显示项恢复为默认;自定义颜色不受影响,改动会直接生效。","ui.resetConfirmDescColors":"将清除全部自定义颜色并恢复默认配色,字段显示开关不受影响。该操作会直接应用到信息栏。","ui.resetConfirmAcknowledge":"我了解这次重置不可撤销","ui.resetConfirmCancel":"取消","ui.resetConfirmConfirm":"确认重置","ui.resetLabels":"恢复显示","ui.resetColors":"恢复颜色","ui.resetRowTitle":"恢复默认","ui.resetRowDesc":"将显示项或颜色恢复为默认。","ui.customTextCount":"已输入 {value}/64 个字符","ui.couldNotDisplayInfoBar":"无法显示信息栏设置:{value}","ui.dataAndBilling":"账单数据","ui.dataAndBillingDesc":"导出或清除本插件保存的用量与花费记录。","ui.exportBillingRecords":"导出账单","ui.exportBillingRecordsDesc":"将记录导出为 CSV 或 JSON 文件。","ui.exportBillingCsv":"导出 CSV","ui.exportBillingJson":"导出 JSON","ui.clearBillingRecords":"清除账单","ui.clearBillingRecordsDesc":"清除后无法恢复。","ui.clearBillingRecordsConfirm":"确定清除本插件保存的全部账单记录吗?建议先导出。清除后无法恢复,但不会影响设置或登录信息。","ui.exportedBillingRecords":"已导出 {count} 条账单记录({format})","ui.noBillingRecordsToExport":"目前没有可导出的账单记录。","ui.exportFailed":"导出失败:{value}","ui.exportIncomplete":"历史账单读取不完整:{value}。本次未导出,请稍后再试。","ui.clearFailed":"清除失败:{value}","ui.clearFailedWithoutDetails":"账单记录未能全部清除","ui.clearedBillingRecords":"已清除 {count} 条账单记录","ui.clearCanceled":"已取消","ui.exportNotSupported":"当前环境不支持下载文件。","ui.weekly":"周","ui.monthly":"月","ui.window":"窗口","ui.quotaDisplayUsed":"已用","ui.quotaDisplayRemaining":"剩余","ui.quotaDisplayModeTitle":"订阅窗口百分比方向","ui.quotaDisplayModeDesc":"订阅额度窗口按「剩余」或「已用」显示;低额度告警始终按剩余不足 20% 判定。","ui.windowUsedRemaining":"{label}窗口:已用 {usedPercent}%(剩余 {value}%)","ui.windowUsedRemainingResets":"{label}窗口 已用 {usedPercent}%(剩余 {value}%) · 重置 {value4}","ui.minimax":"MiniMax","ui.supportsImageInput":"支持图像输入。","ui.vision":"视觉","ui.unknown":"未知","ui.unknownModel":"未知模型","ui.modelSelectionPending":"正在读取当前模型","ui.modelCapabilityPending":"正在确认是否支持图像输入","ui.pluginVersion":"\n插件版本:{current}","ui.provider":"服务商:{provLabel} {modelLabel}\n","ui.pricingPeakOffPeakBeijing":"定价:峰谷价(北京时间周一至周五高峰 9-12、14-18 点;周末及中国节假日全天空闲)","ui.pricingFixed":"定价:固定价","ui.pricingNotListedUsingDefaults":"定价:暂未收录,不计算花费","ui.zhipu":"智谱","ui.xiaomiMiMo":"小米 MiMo","ui.commandCode":"Command Code","ui.subscription":"订阅","ui.cloudBilling":"云账单","ui.plan":"\n套餐:{plan}","ui.expiresLocalTime":"\n到期:{value}(本地时区)","ui.subscriptionServiceModel":"订阅服务:{serviceName}\n模型:{rawModelLabel}{planLine}{expiryLine}{versionLine}","ui.balanceLookupIsNotYet":"暂时无法读取该服务商的余额。","ui.notSupported":"未适配","ui.accountDataUnavailable":"无公开账户数据","ui.accountDataUnavailableDetail":"该服务商已支持模型识别与本地用量记账,但没有可由插件安全读取的公开余额或配额接口。","ui.notConfigured":"未配置 ","ui.notConfiguredConfigureItIn":"未配置 {credName}。请在\"设置 → 模型\"中填写。","ui.notConfiguredSettingsModels":"未配置 {credName}。请在设置 → 模型中填写。","ui.accountSignedOut":"账号未登录","ui.accountSignedOutHow":"在 DSH 的「设置 → 账户」里登录 DeepSeek 账号,这里就会显示余额。","ui.estimatedBalance":"估算余额:{symbol}{value}","ui.balance":"余额:{symbol}{value}","ui.balance.pushBalanceGroups":"余额","ui.low":"低","ui.estimated":"(估算)","ui.balanceIsTemporarilyUnavailableShowing":"余额暂不可用;正在显示上次数据并自动重试。","ui.couldNotLoadBalanceCheck":"余额获取失败。请检查网络和 API Key。","ui.balanceUnavailable":"余额获取失败","ui.beijingTime":"北京时间 ","ui.peakPrice":"高峰价","ui.offPeakPrice":"空闲价","ui.input":":输入 ¥","ui.mCachedInput":"/M · 缓存 ¥","ui.mOutput":"/M · 输出 ¥","ui.beijingTimeSwitchesTo":"北京时间 {atLabel} 切换为","ui.until":"距","ui.offPeak":"空闲","ui.peak":"高峰","ui.today":"今天 {symbol}{value}","ui.lastDays":"近一月 {symbol}{value}","ui.allTime":"全部 {symbol}{value}","ui.sessionIncludingSubagents":"本会话 {costTxt}(含子代理){value}","ui.session":"本会话","ui.spendIsTemporarilyUnavailableChat":"花费暂不可用;不会影响对话。","ui.spendUnavailable":"花费获取失败","ui.noSignInCredentialsFound":"未找到 {serviceName} 登录凭证。请重新授权。","ui.credentialsHaveExpiredPleaseReauthorize":"{serviceName} 登录凭证已失效。请重新授权。","ui.deniedAccessReauthorizeOrTry":"{serviceName} 拒绝访问。请重新授权或稍后再试。","ui.rateLimitReachedPleaseTry":"{serviceName} 请求过于频繁。请稍后再试。","ui.timedOutCheckYourConnection":"{serviceName} 响应超时。请检查网络后再试。","ui.returnedAnUnrecognizedResponsePlease":"{serviceName} 返回的数据暂时无法识别。请稍后再试。","ui.isTemporarilyUnavailableCheckYour":"{serviceName} 暂不可用。请检查网络后再试。","ui.subscriptionExpiresLocalTime":"订阅到期:{value}(本地时区)","ui.expires":"到期","ui.subscriptionSource":"订阅源:{value}(","ui.prepaidBalance":"可用余额","ui.availableBalanceLabel":"可用余额","ui.remainingCredits":"剩余额度","ui.availableBalance":"可用余额:{balTxt}","ui.availableCredits":"剩余 credits:{value}","ui.subscriptionSource.titleLines":"订阅源:{value}","ui.windowRemainingUsed":"{label}窗口:剩余 {value}%(已用 {usedPercent}%)","ui.resetsResetsIn":" · 重置 {value} · 距重置 {value2}","ui.windowRemainingUsedResets":"{label}窗口 剩余 {value}%(已用 {usedPercent}%) · 重置 {value4}","ui.resetsIn":"距重置","ui.configureItInSettingsModels":"。请在\"设置 → 模型\"中填写。","ui.deniedAccessTheTokenMay":"{serviceName} 拒绝访问:Token 可能缺少账单读取权限。","ui.billingIsTemporarilyUnavailableCheck":"{serviceName} 账单暂不可用。请检查网络与权限后再试。","ui.billingSource":"账单源:{value}","ui.thisMonthSSpend":"本月花费:{symbol}{value}","ui.budgetUsed":"预算使用:{value}%","ui.dailyFreeQuotaRemaining":"每日免费额度剩余:{value}","ui.thisMonth":"本月","ui.thisMonthSUsage":"本月用量","ui.budget":"预算","ui.free":"免费","ui.resetsIn.pushBillingGroups":"{value} · 距重置 {value2}","ui.billingServiceModel":"账单服务:{serviceName}\n模型:{modelLabel}{versionLine}","ui.pricing":"定价","ui.spend":"花费","ui.mode":"模式","ui.subscriptionQuota":"订阅额度","ui.billing":"账单","ui.temporarilyUnavailableKeepingTheLast":"暂不可用;正在保留上次数据并自动重试。","ui.spendJournalSavedButThe":"账单流水已保存,但可直接查看的账单文件暂未更新:","ui.thisSpendRecordWasNot":"本次账单未保存,不会计入金额:","ui.ledgerUpdatePending":"账单待整理","ui.spendNotSaved":"账单未保存","ui.versionAndUpdateTitle":"版本与更新","ui.versionAndUpdateDesc":"更新只替换插件自己的程序文件,账单记录和设置不受影响。","ui.versionUnavailable":"当前运行的 DSH 还没载入这一版插件的更新功能,所以这里暂时只显示这一行。重启 DSH 后,下面就会出现当前版本、更新方式与「检查更新」。","ui.versionRunning":"运行中版本 {version}","ui.versionLatest":"最新版本 {version}","ui.versionLastCheck":"上次检查:{time}","ui.versionUnknown":"未知","ui.timeJustNow":"刚刚","ui.timeMinutesAgo":"{n} 分钟前","ui.timeHoursAgo":"{n} 小时前","ui.timeDaysAgo":"{n} 天前","ui.autoUpdateTitle":"更新方式","ui.updateModeAutoDesc":"启动 DSH 时自动检查并安装。使用中手动检查到新版后,确认才会更新。","ui.updateModeManualDesc":"启动时不自动安装。使用中手动检查到新版后,确认才会更新。","ui.updateModeAuto":"自动更新","ui.updateModeManual":"手动更新","ui.updateConfirm":"发现新版本 {version}。现在更新插件吗?更新后需重启 DSH 才会生效。","ui.updateCheckNow":"检查更新","ui.updateChecking":"检查中…","ui.updateInstallNow":"更新到 {version}","ui.updateInstalling":"正在更新到 {version}…","ui.updateAvailableNow":"发现新版本 {version},现在可以更新。","ui.updateRollbackFailed":"回滚没成功,本机没有可用的备份。你可以到插件页卸载后重装。","ui.updateHostOutdated":"这次动作没有执行:当前运行的 DSH 还带着旧版本的更新逻辑,重启 DSH 之后按钮就好用了。","ui.updateUpToDate":"已是最新版本。","ui.updateDisabled":"当前环境不支持自动更新","ui.updateDisabledWhy":"自动更新只在插件装进 DSH 插件目录后可用。这一份是从源码或链接装进来的,升级请用原来的命令。","ui.updatePendingRestart":"已更新到 {version},重启 DSH 后生效。","ui.updateFailed":"上次更新没成功","ui.updateFallbackWhy":"万一新版有问题,可以退回上一版。","ui.updateHoldWhy":"这个版本被你暂缓过,不会自己装回来。","ui.updateErrorIncompleteDownload":"更新包没下完整(网络中途断了),这次已放弃,你现在用的版本没受影响。","ui.updateErrorIntegrityMismatch":"更新包没通过安全校验,这次已放弃,你现在用的版本没受影响。","ui.updateErrorDownloadFailed":"连不上更新服务器,稍后再试。","ui.updateErrorTooLarge":"更新包大得反常,出于安全已放弃。","ui.updateErrorPayloadMismatch":"更新包的内容和版本号对不上,已放弃。","ui.updateErrorPayloadUnsafe":"更新包里出现了不该有的文件路径,已放弃。","ui.updateErrorCheckFailed":"检查更新没成功,可能是网络问题。","ui.updateErrorUnknown":"更新没成功,详细原因记在更新日志里。","ui.updateRollback":"回滚到上一版","ui.updateRolledBack":"已回滚到上一版 {version}。","ui.updateHeld":"新版 {version} 已被你暂缓,不会自动装回来。","ui.updateAllowHeld":"允许更新到 {version}","ui.updateRestartBadge":"重启生效","ui.updateFailedBadge":"更新失败","ui.tools":"工具调用","ui.avgTTFT":"首 token 平均","ui.cacheHit":"缓存命中","ui.input.BottomInfoBar":"输入","ui.output":"输出","ui.savingView":"正在保存切换…","ui.clickToSwitchFullCompact":"单击切换 完整/简洁","ui.pressEnterOrSpaceFor":"按 Enter 或空格切换为简洁模式。","ui.pressEnterOrSpaceFor.BottomInfoBar":"按 Enter 或空格切换为完整模式。","host.hour":"5 小时","host.unknownProvider":"未知服务商","error.subscription.request-failed":"订阅额度请求未知异常","host.settingsFileCouldNotBe":"设置文件写入未完成","error.settings.save-failed":"settings.json 落盘失败:{value}","error.balance.credentials":"凭据读取失败","error.balance.not-configured":"未配置 {credential}","error.balance.account-signed-out":"内置账号未登录","error.balance.account-unavailable":"当前宿主没有内置账号服务","error.balance.account-request-failed":"内置账号余额获取失败","error.request.http":"请求失败(HTTP {status})","error.request.parse":"响应格式异常","error.subscription.not-connected":"未找到 ChatGPT 订阅登录凭证(~/.codex/auth.json),请安装 dsh-chatgpt-sub 插件绑定","error.subscription.credentials-missing":"ChatGPT 订阅登录凭证缺少 id_token,请安装 dsh-chatgpt-sub 插件重新绑定","error.subscription.opencode-not-configured":"未配置 OpenCode Go(OPENCODE_GO_API_KEY 或 opencode auth.json)","error.subscription.commandcode-not-configured":"未配置 Command Code(COMMAND_CODE_API_KEY、CMD_API_KEY 或 ~/.commandcode/auth.json)","error.subscription.commandcode-auth-failed":"Command Code 登录凭证已失效。请重新登录或更新 API Key","error.subscription.commandcode-unrecognized":"Command Code 返回了无法识别的额度格式(接口可能已变更),已保留上次数据","host.zhipu":"智谱 {mapped}","host.zhipu.parseZaiQuota":"智谱 {value}{value2}","error.subscription.zhipu-not-configured":"未配置智谱 API Key(ZAI_API_KEY 或 ZAI_CODING_CN_API_KEY)","error.subscription.zhipu-auth-failed":"智谱 API 认证失败(密钥过期或不正确)","error.subscription.zhipu-unrecognized":"智谱返回了无法识别的额度格式(接口可能已变更),已保留上次数据","error.request.failed":"请求失败({value} {msg})","error.subscription.xiaomi-not-configured":"未配置小米 MiMo Token Plan 凭据({credName} 或 XIAOMI_API_KEY)","error.subscription.xiaomi-http":"请求失败(HTTP {value})","error.subscription.minimax-not-configured":"未配置 MiniMax 凭据(MINIMAX_API_KEY 或 MINIMAX_CN_API_KEY)。查询 Token Plan 必须使用 Subscription Key,按量 API Key 会被服务端拒绝","error.subscription.minimax-auth-failed":"MiniMax 拒绝了当前 API Key:查询 Token Plan 必须使用 Subscription Key(在 Token Plan 订阅页生成),按量 API Key 会被服务端拒绝(status_code=1004 / HTTP 401)","error.subscription.minimax-unrecognized":"MiniMax 返回了无法识别的额度格式(接口可能已变更),已保留上次数据","error.billing.together-not-configured":"未配置 TOGETHER_API_KEY","host.actualMonthlyBillFromThe":"本月真实账单(Together 官方 Usage API)","error.billing.fireworks-not-configured":"未配置 FIREWORKS_API_KEY","error.billing.fireworks-account":"账户解析失败(未取得 account_id)","host.actualBillForThisPeriod":"本周期真实账单(Fireworks Billing Summary)","host.actualUsageForThisPeriod":"本周期真实用量(billingUsage 回退端点,无金额)","error.billing.aws-not-configured":"未配置 AWS 凭据(AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY)","error.billing.aws-http":"请求失败(HTTP {status}),可能缺少 ce:GetCostAndUsage 权限","host.actualMonthlyBillFromAWS":"AWS Cost Explorer 本月真实账单(账单延迟约 24 小时)","error.billing.cloudflare-not-configured":"未配置 CLOUDFLARE_API_KEY(需账号级 Token 并授予 Billing 读权限)","error.billing.cloudflare-account":"未配置 CLOUDFLARE_ACCOUNT_ID","error.billing.cloudflare-http":"请求失败(HTTP {status}),Token 需 Billing 读权限","host.actualMonthlyUsageFromThe":"Cloudflare Billable Usage API(Alpha),本月真实用量","error.billing.huggingface-not-configured":"未配置 HF_TOKEN(细粒度 token 需授予 Billing 读权限)","host.actualMonthlyBillFromHF":"本月真实账单(Hugging Face Billing API)","error.billing.request-failed":"账单请求未知异常","host.spendSummaryFileMissingArchived":"账单汇总文件缺失:折叠期间的历史金额暂未计入显示(明细仍在冷归档 usage-archive/,可人工恢复)","host.spendLedgerCouldNotBe":"账单文件写入未完成","host.usageLedgerBusy":"当前仍有回答正在进行,完成后再清除账单记录","error.ledger.clear-failed":"账单记录清理未完成:{value}","error.ledger.snapshot-stale":"折叠汇总落盘失败:{value}","host.basedOnYourLastSessions":"基于你最近 {count} 次会话","host.estimatedFromSpendingOverThe":"基于过去 {SPEND_DAYS} 天消耗速度的估算","host.patchMustIncludeFieldsOr":"patch 需包含 fields、colors、timeZones 或 customText 之一","host.timeZonesMustBeAnObject":"timeZones 必须是对象","host.timeZoneMustBeAValid":"时区必须是有效的 IANA 时区:{key}","host.customTextMustBeAString":"自定义文本必须是字符串","host.customTextTooLong":"自定义文本不能超过 64 个字符","host.quotaDisplayModeInvalid":"订阅窗口百分比方向必须是 used 或 remaining","host.infoDensityMustBeFullOrCompact":"信息显示方式必须是完整或简洁","host.fieldsMustBeAnObject":"fields 必须是对象","host.unknownFieldId":"未知字段 id: {key}","host.fieldVisibilityMustBeA":"字段开关必须是布尔值: {key}","host.colorsMustBeAnObject":"colors 必须是对象","host.colorMustBeAPreset":"颜色只接受预设色名或 #RRGGBB: {key}","field.anchorGroup.label":"服务商与模型","field.anchorGroup.note":"显示当前会话使用的服务商和模型。","field.subServiceGroup.label":"订阅服务与模型","field.subServiceGroup.note":"显示订阅服务和当前模型或套餐。","field.billingServiceGroup.label":"账单服务与模型","field.billingServiceGroup.note":"显示账单服务和当前模型。","field.customText.label":"自定义文字","field.customText.note":"显示一段自定义文字,可用作备注或签名。","field.mainTime.label":"主时间","field.mainTime.note":"显示主时区的时间;时区在「时间与日期」中调整。","field.worldTime.label":"世界时间","field.worldTime.note":"显示另一时区的时间。","field.sessionCost.label":"本次会话花费","field.sessionCost.note":"显示本次会话的实际花费,包含子代理。","field.balance.note":"显示账户余额;余额过低时标红提醒。","field.period.label":"当前时段","field.period.note":"峰谷定价的服务商显示当前是高峰还是空闲时段。","field.countdown.label":"下次价格切换","field.countdown.note":"显示距离下次高峰 / 空闲价格切换的时间。","field.expiry.label":"订阅到期日","field.expiry.note":"服务商返回到期时间时显示。","field.subWindow5h.label":"5 小时额度","field.subWindow5h.note":"显示滚动 5 小时额度的剩余比例。","field.subWindowWeek.label":"每周额度","field.subWindowWeek.note":"显示每周额度的剩余比例。","field.subWindowMonth.label":"每月额度","field.subWindowMonth.note":"显示每月额度的剩余比例。","field.resetCountdown.label":"距额度重置","field.resetCountdown.note":"显示当前额度重置的剩余时间。","field.subBalance.label":"可用余额或剩余额度","field.subBalance.note":"按量账户显示可用余额;没有额度窗口的 credits 订阅显示剩余额度。","field.billingSpend.label":"本月用量","field.billingSpend.note":"显示本计费周期的实际用量或花费。","field.budget.label":"预算使用情况","field.budget.note":"服务商支持时显示已使用的预算比例。","field.freeQuota.label":"免费额度","field.freeQuota.note":"服务商提供免费额度时显示剩余额度和重置时间。","field.turnsSteps.label":"轮次与步数","field.turnsSteps.note":"显示本会话对话的轮次和步数。","field.llmTime.label":"模型耗时","field.llmTime.note":"显示模型推理累计耗时。","field.toolTime.label":"工具耗时","field.toolTime.note":"显示工具调用累计耗时。","field.avgTTFT.label":"首 Token 平均耗时","field.avgTTFT.note":"显示本会话模型步骤的平均首 Token 时间。","field.outputSpeed.label":"输出速率","field.outputSpeed.note":"显示本会话已上报用量的模型步骤的平均输出速率(tok/s)。","field.cacheHit.note":"显示提示词缓存命中率。","field.tokensIO.label":"输入/输出 Token","field.tokensIO.note":"显示本会话累计的输入 / 输出 Token 量。","field.contextUsage.label":"上下文用量","field.contextUsage.note":"显示上下文占用比例;圆环越满表示剩余可写空间越少。","ui.contextAria":"上下文已用 {percent}","ui.contextUsed":"上下文已用","ui.contextSystem":"系统提示词","ui.contextTools":"工具定义","ui.contextMessages":"对话消息","ui.contextFigures":"~{used} / {window}","number.thousand":"{value}K","number.million":"{value}M","field.unmapped.label":"账户数据状态提示","field.unmapped.note":"服务商未知或未公开账户余额/配额接口时显示;本地用量记账仍正常工作。","field.noKeyHint.label":"缺少密钥提示","field.noKeyHint.note":"缺少 API Key 时显示去填写的提示。","field.balanceError.label":"余额更新失败提示","field.balanceError.note":"余额更新失败时显示。","field.usageError.label":"用量更新失败提示","field.usageError.note":"花费暂时不可用时显示。","field.refreshFailure.label":"更新失败提示","field.refreshFailure.note":"任一数据刷新失败时显示提醒。","field.persistWarning.label":"记录未保存提醒","field.persistWarning.note":"账单保存失败时显示提醒,建议保留。","field.updateNotice.label":"更新提醒","field.updateNotice.note":"有新版本可更新、或新版已就绪待重启时显示短标记。","field.updateFailure.label":"更新失败提醒","field.updateFailure.note":"自动更新失败时显示短标记。","group.native":"原生信息","group.plugin":"插件信息","group.notice":"提醒信息","group.native.desc":"DSH 原生底栏自带的字段,列在原生统计行;这一行只在完整模式显示。","group.plugin.desc":"本插件新增的字段(含接管过来的上下文圆环),归在主行里;简洁与完整都显示。","group.notice.desc":"更新、失败等一次性提醒。当下真有事要提醒就出现,与模式无关。","section.identity.label":"服务商与模型","section.identity.desc":"任何计费方式都显示的一行:当前用的是哪家的服务、哪个模型。","section.balance.label":"余额制:充值后按用量扣钱","section.balance.desc":"这类服务商只有下面几项有数据:余额、本次会话花费、当前时段与下次价格切换。","section.subscription.label":"订阅制:按月付费,额度内不限量","section.subscription.desc":"ChatGPT 这类订阅只有下面几项有数据:额度窗口、额度重置、到期日与可用余额。","section.billing.label":"账单制:先用后付,按月出账","section.billing.desc":"这类服务商只有下面几项有数据:本月用量、预算使用情况、免费额度。","section.common.label":"通用显示项","section.common.desc":"和计费方式无关,用什么服务商都能开:自定义文字、时间、上下文用量。","ui.listSeparator":"、","ui.sentenceEnd":"。","ui.fieldErrorPrefix":"「{label}」:","ui.turnCount":"{count} 轮","ui.turnCountPlural":"{count} 轮","ui.stepCount":"{count} 步","ui.stepCountPlural":"{count} 步","ui.mainTimeZone":"主时间时区","ui.worldTimeZone":"世界时间时区","ui.customTextTitle":"自定义文本","ui.customTextPlaceholder":"输入文字(最多 64 个字符)","ui.searchPlaceholder":"按名称或说明搜索…","ui.searchFieldsLabel":"搜索显示内容","ui.searchResultCount":"找到 {count} 项","ui.enabledFieldsCount":"已启用 {count} 项","ui.noSearchResults":"没有找到匹配的设置项","ui.mainTime":"主时间","ui.worldTime":"世界时间","ui.customText":"自定义文本"},"en":{"meta.title":"Bottom Info Bar","meta.description":"Shows the current model, balance and spend under the composer.","ui.requestTimedOut":"Request timed out","ui.requestCanceled":"Request canceled","ui.couldNotParseResponse":"Could not parse response","ui.rpcFailed":"RPC failed","ui.refreshFailed":"Refresh failed","color.red":"Red","color.green":"Green","color.blue":"Blue","color.purple":"Purple","color.orange":"Orange","color.neutral":"Neutral","ui.pleaseTryAgainLater":"Please try again later","ui.restoreDefaultColor":"Restore default color","ui.infoBarSettings":"Info Bar","ui.settingsAreTemporarilyUnavailable":"Settings are temporarily unavailable","ui.loadingInfoBarSettings":"Loading settings…","ui.couldNotLoadInfoBar":"Could not load Info Bar settings: ","ui.changesAppliedButCouldNot":"Applied, but could not save locally: ","ui.unknownReason":"Unknown reason","ui.couldNotSave":"{errorPrefix}Could not save: {value}","ui.color":"\"{value}\" color: ","ui.hasAnInvalidColorEnter":"\"{value}\" has an invalid color. Enter #RRGGBB (for example, #0044CC).","ui.defaultColorsRestored":"Default colors restored","ui.defaultLabelsRestored":"Default display restored","ui.couldNotReset":"Could not reset: {value}","ui.show":"Show {label}","ui.clickToHide":"Click to hide","ui.clickToShow":"Click to show","ui.presetColor":"{label} preset color","ui.customColor":"{label} custom color","ui.customColorOpenColorPicker":"Custom color (open color picker)","ui.customColorItem":"Custom…","ui.colorSwatchLabel":"{label} color","ui.hexColor":"{label} hex color","ui.expand":"Expand","ui.collapse":"Collapse","ui.saving":"Saving…","ui.processing":"Working…","ui.visibleFields":"Information to show","ui.timeDateTitle":"Time and date","ui.timeDateDesc":"Time zones for main and world time.","ui.customTextSectionDesc":"Shows one line of custom text in the info bar.","ui.resetConfirmTitle":"Reset Info Bar settings","ui.resetConfirmDescFields":"Restore all display choices to their defaults. Custom colors are not affected and the change applies right away.","ui.resetConfirmDescColors":"All custom colors will be cleared and defaults restored. Field switches are not affected. This applies to the Info Bar right away.","ui.resetConfirmAcknowledge":"I understand this reset cannot be undone","ui.resetConfirmCancel":"Cancel","ui.resetConfirmConfirm":"Reset","ui.resetLabels":"Restore display","ui.resetColors":"Restore colors","ui.resetRowTitle":"Reset to defaults","ui.resetRowDesc":"Restore displayed items or colors to their defaults.","ui.customTextCount":"{value}/64 characters","ui.couldNotDisplayInfoBar":"Could not display Info Bar settings: {value}","ui.dataAndBilling":"Billing data","ui.dataAndBillingDesc":"Export or clear the usage and spend records saved by this plugin.","ui.exportBillingRecords":"Export billing","ui.exportBillingRecordsDesc":"Export the records as a CSV or JSON file.","ui.exportBillingCsv":"Export CSV","ui.exportBillingJson":"Export JSON","ui.clearBillingRecords":"Clear billing","ui.clearBillingRecordsDesc":"This cannot be undone.","ui.clearBillingRecordsConfirm":"Clear all billing records saved by this plugin? Export first. This cannot be undone, but settings and sign-in information will stay unchanged.","ui.exportedBillingRecords":"Exported {count} billing records ({format})","ui.noBillingRecordsToExport":"There are no billing records to export.","ui.exportFailed":"Export failed: {value}","ui.exportIncomplete":"Some historical billing records could not be read: {value}. Nothing was exported; try again later.","ui.clearFailed":"Could not clear billing records: {value}","ui.clearFailedWithoutDetails":"Billing records could not be fully cleared","ui.clearedBillingRecords":"Cleared {count} billing records","ui.clearCanceled":"Canceled","ui.exportNotSupported":"File downloads are not supported in this environment.","ui.weekly":"Weekly","ui.monthly":"Monthly","ui.window":"Window","ui.quotaDisplayUsed":"Used","ui.quotaDisplayRemaining":"Remaining","ui.quotaDisplayModeTitle":"Subscription window percentage","ui.quotaDisplayModeDesc":"Show subscription quota windows as remaining or used. The low-quota warning always triggers when less than 20% remains.","ui.windowUsedRemaining":"{label} window: used {usedPercent}% (remaining {value}%)","ui.windowUsedRemainingResets":"{label} window: used {usedPercent}% (remaining {value}%) · Resets {value4}","ui.minimax":"MiniMax","ui.supportsImageInput":"Supports image input.","ui.vision":"Vision","ui.unknown":"Unknown","ui.unknownModel":"Unknown model","ui.modelSelectionPending":"Reading current model","ui.modelCapabilityPending":"Checking image-input support","ui.pluginVersion":"\nPlugin version: {current}","ui.provider":"Provider: {provLabel} {modelLabel}\n","ui.pricingPeakOffPeakBeijing":"Pricing: peak/off-peak (Beijing time; weekday peaks 09:00-12:00 and 14:00-18:00; weekends and Chinese public holidays off-peak)","ui.pricingFixed":"Pricing: fixed","ui.pricingNotListedUsingDefaults":"Pricing: not listed; spend is not calculated","ui.zhipu":"Zhipu","ui.xiaomiMiMo":"Xiaomi MiMo","ui.commandCode":"Command Code","ui.subscription":"Subscription","ui.cloudBilling":"Cloud billing","ui.plan":"\nPlan: {plan}","ui.expiresLocalTime":"\nExpires: {value} (local time)","ui.subscriptionServiceModel":"Subscription service: {serviceName}\nModel: {rawModelLabel}{planLine}{expiryLine}{versionLine}","ui.balanceLookupIsNotYet":"This provider's balance is not available yet.","ui.notSupported":"Not supported","ui.accountDataUnavailable":"No public account data","ui.accountDataUnavailableDetail":"This provider is supported for model recognition and local usage accounting, but has no public balance or quota endpoint that the plugin can safely read.","ui.notConfigured":"Not configured: ","ui.notConfiguredConfigureItIn":"Not configured: {credName}. Configure it in Settings → Models.","ui.notConfiguredSettingsModels":"{credName} is not configured. Add it in Settings → Models.","ui.accountSignedOut":"Account signed out","ui.accountSignedOutHow":"Sign in to your DeepSeek account in DSH settings, Account, and the balance will appear here.","ui.estimatedBalance":"Estimated balance: {symbol}{value}","ui.balance":"Balance: {symbol}{value}","ui.balance.pushBalanceGroups":"Balance","ui.low":"Low","ui.estimated":"(estimated)","ui.balanceIsTemporarilyUnavailableShowing":"Balance is temporarily unavailable. Showing the last data and retrying automatically.","ui.couldNotLoadBalanceCheck":"Could not load balance. Check your connection and API key.","ui.balanceUnavailable":"Balance unavailable","ui.beijingTime":"Beijing time: ","ui.peakPrice":"Peak price","ui.offPeakPrice":"Off-peak price","ui.input":": input ¥","ui.mCachedInput":"/M · cached input ¥","ui.mOutput":"/M · output ¥","ui.beijingTimeSwitchesTo":"Beijing time: {atLabel} switches to ","ui.until":"Until ","ui.offPeak":"off-peak","ui.peak":"peak","ui.today":"Today {symbol}{value}","ui.lastDays":"Last 30 days {symbol}{value}","ui.allTime":"All time {symbol}{value}","ui.sessionIncludingSubagents":"Session {costTxt} (including subagents){value}","ui.session":"Session","ui.spendIsTemporarilyUnavailableChat":"Spend is temporarily unavailable. Chat is unaffected.","ui.spendUnavailable":"Spend unavailable","ui.noSignInCredentialsFound":"No sign-in credentials found for {serviceName}. Please reauthorize.","ui.credentialsHaveExpiredPleaseReauthorize":"{serviceName} credentials have expired. Please reauthorize.","ui.deniedAccessReauthorizeOrTry":"{serviceName} denied access. Reauthorize or try again later.","ui.rateLimitReachedPleaseTry":"{serviceName} rate limit reached. Please try again later.","ui.timedOutCheckYourConnection":"{serviceName} timed out. Check your connection and try again.","ui.returnedAnUnrecognizedResponsePlease":"{serviceName} returned an unrecognized response. Please try again later.","ui.isTemporarilyUnavailableCheckYour":"{serviceName} is temporarily unavailable. Check your connection and try again.","ui.subscriptionExpiresLocalTime":"Subscription expires: {value} (local time)","ui.expires":"Expires","ui.subscriptionSource":"Subscription source: {value} (","ui.prepaidBalance":"Available balance","ui.availableBalanceLabel":"Available balance","ui.remainingCredits":"Credits remaining","ui.availableBalance":"Available balance: {balTxt}","ui.availableCredits":"Credits remaining: {value}","ui.subscriptionSource.titleLines":"Subscription source: {value}","ui.windowRemainingUsed":"{label} window: remaining {value}% (used {usedPercent}%)","ui.resetsResetsIn":" · Resets {value} · Resets in {value2}","ui.windowRemainingUsedResets":"{label} window: remaining {value}% (used {usedPercent}%) · Resets {value4}","ui.resetsIn":"Resets in","ui.configureItInSettingsModels":". Configure it in Settings → Models.","ui.deniedAccessTheTokenMay":"{serviceName} denied access: the token may lack billing read permissions.","ui.billingIsTemporarilyUnavailableCheck":"{serviceName} billing is temporarily unavailable. Check your connection and permissions, then try again.","ui.billingSource":"Billing source: {value}","ui.thisMonthSSpend":"This month’s spend: {symbol}{value}","ui.budgetUsed":"Budget used: {value}%","ui.dailyFreeQuotaRemaining":"Daily free quota remaining: {value}","ui.thisMonth":"This month","ui.thisMonthSUsage":"This month’s usage","ui.budget":"Budget","ui.free":"Free","ui.resetsIn.pushBillingGroups":"{value} · Resets in {value2}","ui.billingServiceModel":"Billing service: {serviceName}\nModel: {modelLabel}{versionLine}","ui.pricing":"Pricing","ui.spend":"Spend","ui.mode":"Mode","ui.subscriptionQuota":"Subscription quota","ui.billing":"Billing","ui.temporarilyUnavailableKeepingTheLast":": temporarily unavailable. Keeping the last data and retrying automatically.","ui.spendJournalSavedButThe":"Spend journal saved, but the readable ledger has not been updated: ","ui.thisSpendRecordWasNot":"This spend record was not saved and will not be added to totals: ","ui.ledgerUpdatePending":"Ledger update pending","ui.spendNotSaved":"Spend not saved","ui.versionAndUpdateTitle":"Version and updates","ui.versionAndUpdateDesc":"Updates replace only the plugin's own files; billing records and settings are untouched.","ui.versionUnavailable":"The DSH currently running has not loaded this version of the plugin yet, so only this line can be shown here. Restart DSH and the running version, the update mode and the check button will appear.","ui.versionRunning":"Running version {version}","ui.versionLatest":"Latest version {version}","ui.versionLastCheck":"Last checked {time}","ui.versionUnknown":"Unknown","ui.timeJustNow":"just now","ui.timeMinutesAgo":"{n} min ago","ui.timeHoursAgo":"{n} h ago","ui.timeDaysAgo":"{n} d ago","ui.autoUpdateTitle":"Update method","ui.updateModeAutoDesc":"Checks and installs when DSH starts. During use, a manual check asks before installing.","ui.updateModeManualDesc":"Does not install at startup. During use, a manual check asks before installing.","ui.updateModeAuto":"Automatic updates","ui.updateModeManual":"Manual updates","ui.updateConfirm":"Version {version} is available. Update the plugin now? Restart DSH to apply it.","ui.updateCheckNow":"Check now","ui.updateChecking":"Checking…","ui.updateInstallNow":"Update to {version}","ui.updateInstalling":"Updating to {version}…","ui.updateAvailableNow":"Version {version} is ready; you can update now.","ui.updateRollbackFailed":"The rollback did not succeed because no usable backup exists. Uninstall and reinstall from the plugins page instead.","ui.updateHostOutdated":"This action did not run: the DSH now running still carries the old update logic. Restart DSH and the button will work.","ui.updateUpToDate":"Up to date.","ui.updateDisabled":"Automatic updates are unavailable here","ui.updateDisabledWhy":"Automatic updates need the plugin installed into the DSH plugin directory. This copy came from a source checkout or a link, so use the original update command.","ui.updatePendingRestart":"Updated to {version}. Restart DSH to activate.","ui.updateFailed":"The last update did not succeed","ui.updateFallbackWhy":"If the new version misbehaves, you can go back to the previous one.","ui.updateHoldWhy":"You held this version back, so it will not be installed automatically.","ui.updateErrorIncompleteDownload":"The download was incomplete (the connection dropped). This update was abandoned and the version you have is untouched.","ui.updateErrorIntegrityMismatch":"The update package failed its safety check, so it was abandoned. The version you have is untouched.","ui.updateErrorDownloadFailed":"Could not reach the update server. Try again later.","ui.updateErrorTooLarge":"The update package was unusually large, so it was abandoned.","ui.updateErrorPayloadMismatch":"The update package did not match its version number, so it was abandoned.","ui.updateErrorPayloadUnsafe":"The update package contained an unexpected file path, so it was abandoned.","ui.updateErrorCheckFailed":"The version check did not succeed, possibly a network problem.","ui.updateErrorUnknown":"The update did not succeed. Details are in the update log.","ui.updateRollback":"Roll back to previous version","ui.updateRolledBack":"Rolled back to the previous version {version}.","ui.updateHeld":"Version {version} is held back and will not be installed automatically.","ui.updateAllowHeld":"Allow updating to {version}","ui.updateRestartBadge":"Restart to apply","ui.updateFailedBadge":"Update failed","ui.tools":"Tools","ui.avgTTFT":"Avg. TTFT","ui.cacheHit":"Cache hit","ui.input.BottomInfoBar":"Input","ui.output":"Output","ui.savingView":"Saving view…","ui.clickToSwitchFullCompact":"Click to switch full/compact view","ui.pressEnterOrSpaceFor":"Press Enter or Space for compact view.","ui.pressEnterOrSpaceFor.BottomInfoBar":"Press Enter or Space for full view.","host.hour":"5-hour","host.unknownProvider":"Unknown provider","error.subscription.request-failed":"Unexpected subscription quota request failure","host.settingsFileCouldNotBe":"Settings file could not be saved","error.settings.save-failed":"Could not save settings.json: {value}","error.balance.credentials":"Could not read credentials","error.balance.not-configured":"Not configured: {credential}","error.balance.account-signed-out":"The built-in account is signed out","error.balance.account-unavailable":"This host has no built-in account service","error.balance.account-request-failed":"Could not fetch the built-in account balance","error.request.http":"Request failed: HTTP {status}.","error.request.parse":"Unexpected response format","error.subscription.not-connected":"ChatGPT subscription is not connected: credentials not found in ~/.codex/auth.json. Install dsh-chatgpt-sub and sign in.","error.subscription.credentials-missing":"ChatGPT subscription credentials are missing id_token. Install dsh-chatgpt-sub and reauthorize.","error.subscription.opencode-not-configured":"OpenCode Go is not configured. Set OPENCODE_GO_API_KEY or use opencode auth.json.","error.subscription.commandcode-not-configured":"Command Code is not configured. Set COMMAND_CODE_API_KEY, CMD_API_KEY, or sign in with the Command Code CLI.","error.subscription.commandcode-auth-failed":"Command Code credentials were rejected. Sign in again or update the API key.","error.subscription.commandcode-unrecognized":"Command Code returned an unrecognized quota format; the previous snapshot was kept.","host.zhipu":"Zhipu {mapped}","host.zhipu.parseZaiQuota":"Zhipu {value}{value2}","error.subscription.zhipu-not-configured":"Zhipu API key is not configured. Set ZAI_API_KEY or ZAI_CODING_CN_API_KEY.","error.subscription.zhipu-auth-failed":"Zhipu API authentication failed: the key is expired or invalid.","error.subscription.zhipu-unrecognized":"Zhipu returned an unrecognized quota format (the API may have changed); the last known data is kept.","error.request.failed":"Request failed: {value} {msg}.","error.subscription.xiaomi-not-configured":"Xiaomi MiMo Token Plan credentials are not configured: {credName} or XIAOMI_API_KEY.","error.subscription.xiaomi-http":"Request failed: HTTP {value}.","error.subscription.minimax-not-configured":"MiniMax is not configured. Set MINIMAX_API_KEY or MINIMAX_CN_API_KEY. Token Plan queries require a Subscription Key; pay-as-you-go API keys are rejected by the server.","error.subscription.minimax-auth-failed":"MiniMax rejected the API key: Token Plan queries require a Subscription Key (generated on the Token Plan subscription page). Pay-as-you-go keys are rejected (status_code=1004 / HTTP 401).","error.subscription.minimax-unrecognized":"MiniMax returned an unrecognized quota format (the API may have changed); the last known data is kept.","error.billing.together-not-configured":"Not configured: TOGETHER_API_KEY","host.actualMonthlyBillFromThe":"Actual monthly bill from the Together Usage API","error.billing.fireworks-not-configured":"Not configured: FIREWORKS_API_KEY","error.billing.fireworks-account":"Could not read account (account_id missing)","host.actualBillForThisPeriod":"Actual bill for this period (Fireworks Billing Summary)","host.actualUsageForThisPeriod":"Actual usage for this period (billingUsage fallback; no spend amount)","error.billing.aws-not-configured":"Not configured: AWS credentials (AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY)","error.billing.aws-http":"Request failed: HTTP {status}. The token may lack ce:GetCostAndUsage permission","host.actualMonthlyBillFromAWS":"Actual monthly bill from AWS Cost Explorer (about 24 hours behind)","error.billing.cloudflare-not-configured":"Not configured: CLOUDFLARE_API_KEY (requires an account-level token with Billing read permission)","error.billing.cloudflare-account":"Not configured: CLOUDFLARE_ACCOUNT_ID","error.billing.cloudflare-http":"Request failed: HTTP {status}. The token requires Billing read permission","host.actualMonthlyUsageFromThe":"Actual monthly usage from the Cloudflare Billable Usage API (Alpha)","error.billing.huggingface-not-configured":"Not configured: HF_TOKEN (fine-grained tokens require Billing read permission)","host.actualMonthlyBillFromHF":"Actual monthly bill from the Hugging Face Billing API","error.billing.request-failed":"Unexpected billing request failure","host.spendSummaryFileMissingArchived":"Spend summary file missing: archived amounts are not included in displayed totals. Details remain in usage-archive/ for manual recovery.","host.spendLedgerCouldNotBe":"Spend ledger could not be saved","host.usageLedgerBusy":"A response is still in progress. Clear billing records after it finishes.","error.ledger.clear-failed":"Billing records could not be fully cleared: {value}","error.ledger.snapshot-stale":"Could not save archived spend summaries: {value}","host.basedOnYourLastSessions":"Based on your last {count} sessions","host.estimatedFromSpendingOverThe":"Estimated from spending over the last {SPEND_DAYS} days","host.patchMustIncludeFieldsOr":"patch must include fields, colors, timeZones or customText","host.timeZonesMustBeAnObject":"timeZones must be an object","host.timeZoneMustBeAValid":"Time zone must be a valid IANA zone: {key}","host.customTextMustBeAString":"Custom text must be a string","host.customTextTooLong":"Custom text must not exceed 64 characters","host.quotaDisplayModeInvalid":"Subscription window percentage mode must be \"used\" or \"remaining\"","host.infoDensityMustBeFullOrCompact":"Information display must be full or compact","host.fieldsMustBeAnObject":"fields must be an object","host.unknownFieldId":"Unknown field id: {key}","host.fieldVisibilityMustBeA":"Field visibility must be a boolean: {key}","host.colorsMustBeAnObject":"colors must be an object","host.colorMustBeAPreset":"Color must be a preset name or #RRGGBB: {key}","field.anchorGroup.label":"Provider and model","field.anchorGroup.note":"Shows the provider and model used in this conversation.","field.subServiceGroup.label":"Subscription service and model","field.subServiceGroup.note":"Shows the subscription service and current model or plan.","field.billingServiceGroup.label":"Billing service and model","field.billingServiceGroup.note":"Shows the billing service and current model.","field.customText.label":"Custom text","field.customText.note":"Shows custom text for a note or signature.","field.mainTime.label":"Main time","field.mainTime.note":"Shows the main time zone; adjust zone in Time and date.","field.worldTime.label":"World time","field.worldTime.note":"Shows another time zone.","field.sessionCost.label":"Session spend","field.sessionCost.note":"Shows actual spend for this session, including subagents.","field.balance.note":"Shows the account balance; a low balance is highlighted in red.","field.period.label":"Current period","field.period.note":"For peak-valley pricing providers, shows whether the current period is peak or off-peak.","field.countdown.label":"Next price change","field.countdown.note":"Shows the time until the next peak / off-peak price change.","field.expiry.label":"Subscription expiry","field.expiry.note":"Shown when the provider returns an expiry date.","field.subWindow5h.label":"5-hour quota","field.subWindow5h.note":"Shows the remaining rolling 5-hour quota.","field.subWindowWeek.label":"Weekly quota","field.subWindowWeek.note":"Shows the remaining weekly quota.","field.subWindowMonth.label":"Monthly quota","field.subWindowMonth.note":"Shows the remaining monthly quota.","field.resetCountdown.label":"Quota reset","field.resetCountdown.note":"Shows the time remaining until the current quota resets.","field.subBalance.label":"Available balance or credits","field.subBalance.note":"Shows available balance for pay-as-you-go accounts, or remaining credits when a subscription has no visible quota window.","field.billingSpend.label":"Monthly usage","field.billingSpend.note":"Shows actual usage or spend for the current billing period.","field.budget.label":"Budget status","field.budget.note":"Shown when the provider reports a budget percentage.","field.freeQuota.label":"Free quota","field.freeQuota.note":"Shown when the provider offers a free allowance, with the remaining amount and reset time.","field.turnsSteps.label":"Turns and steps","field.turnsSteps.note":"Shows turns and steps in this session.","field.llmTime.label":"Model time","field.llmTime.note":"Shows total model inference time.","field.toolTime.label":"Tool time","field.toolTime.note":"Shows total tool execution time.","field.avgTTFT.label":"Average time to first token","field.avgTTFT.note":"Shows the average time to first token across model steps in this session.","field.outputSpeed.label":"Output speed","field.outputSpeed.note":"Shows average output speed for usage-reporting model steps in this session (tok/s).","field.cacheHit.note":"Shows the prompt cache hit rate.","field.tokensIO.label":"Input / output tokens","field.tokensIO.note":"Shows this session’s total input / output tokens.","field.contextUsage.label":"Context usage","field.contextUsage.note":"Shows context usage; a fuller ring means less writable space remains.","ui.contextAria":"{percent} of context used","ui.contextUsed":"Context used","ui.contextSystem":"System prompt","ui.contextTools":"Tool definitions","ui.contextMessages":"Conversation messages","ui.contextFigures":"~{used} / {window}","number.thousand":"{value}K","number.million":"{value}M","field.unmapped.label":"Account data status","field.unmapped.note":"Shown when a provider is unknown or has no public balance/quota endpoint; local usage accounting still works.","field.noKeyHint.label":"Missing key hint","field.noKeyHint.note":"Shown when an API key is missing, pointing to where it goes.","field.balanceError.label":"Balance update error","field.balanceError.note":"Shown when balance update fails.","field.usageError.label":"Usage update error","field.usageError.note":"Shown when spend data is temporarily unavailable.","field.refreshFailure.label":"Update error","field.refreshFailure.note":"Shown when any data refresh fails.","field.persistWarning.label":"Unsaved record alert","field.persistWarning.note":"Shown when billing records cannot be saved; recommended.","field.updateNotice.label":"Update notice","field.updateNotice.note":"Shows a short marker when a new version is ready, or a downloaded version is waiting for a restart.","field.updateFailure.label":"Update failure notice","field.updateFailure.note":"Shows a short marker when the automatic update failed.","group.native":"Native information","group.plugin":"Plugin information","group.notice":"Notices","group.native.desc":"Fields the DSH bar already had. They live in the native stats row, which only Full mode shows.","group.plugin.desc":"Fields this plugin adds, the adopted context ring included. They live in the main row, shown in both modes.","group.notice.desc":"One-off notices such as updates and failures. They appear whenever there is really something to say, whatever the mode.","section.identity.label":"Provider and model","section.identity.desc":"Shown whatever you pay with: which service and model this conversation runs on.","section.subscription.label":"Subscription: monthly plan, quota included","section.subscription.desc":"A plan like ChatGPT only fills the items below: quota windows, quota reset, expiry date and available balance.","section.balance.label":"Prepaid balance: top up, then usage is deducted","section.balance.desc":"These providers only fill the items below: balance, session spend, current period and next price change.","section.billing.label":"Billed usage: use first, invoiced monthly","section.billing.desc":"These providers only fill the items below: this month's usage, budget and free allowance.","section.common.label":"General items","section.common.desc":"Nothing to do with billing, useful on any provider: custom text, clocks, context usage.","ui.listSeparator":", ","ui.sentenceEnd":".","ui.fieldErrorPrefix":"\"{label}\": ","ui.turnCount":"{count} turn","ui.turnCountPlural":"{count} turns","ui.stepCount":"{count} step","ui.stepCountPlural":"{count} steps","ui.mainTimeZone":"Main time zone","ui.worldTimeZone":"World time zone","ui.customTextTitle":"Custom text","ui.customTextPlaceholder":"Enter text (up to 64 characters)","ui.searchPlaceholder":"Search by name or description…","ui.searchFieldsLabel":"Search visible content","ui.searchResultCount":"{count} found","ui.enabledFieldsCount":"{count} enabled","ui.noSearchResults":"No matching settings found","ui.mainTime":"Main time","ui.worldTime":"World time","ui.customText":"Custom text"}};
|
|
107
|
+
const LOCALES = {"zh":{"meta.title":"底部信息栏","meta.description":"在输入框下方显示当前模型、余额和花费。","ui.requestTimedOut":"请求超时","ui.requestCanceled":"请求已取消","ui.couldNotParseResponse":"响应解析失败","ui.rpcFailed":"RPC 失败","ui.refreshFailed":"刷新失败","color.red":"红","color.green":"绿","color.blue":"蓝","color.purple":"紫","color.orange":"橙","color.neutral":"中性","ui.pleaseTryAgainLater":"请稍后再试","ui.restoreDefaultColor":"恢复默认颜色","ui.infoBarSettings":"信息栏","ui.settingsAreTemporarilyUnavailable":"暂时无法读取设置","ui.loadingInfoBarSettings":"正在加载设置…","ui.couldNotLoadInfoBar":"无法读取信息栏设置:","ui.changesAppliedButCouldNot":"已应用,但无法保存到本地:","ui.unknownReason":"未知原因","ui.couldNotSave":"{errorPrefix}保存失败:{value}","ui.color":"“{value}”颜色:","ui.hasAnInvalidColorEnter":"“{value}”的颜色格式不正确,请输入 #RRGGBB(例如 #0044CC)。","ui.defaultColorsRestored":"已恢复默认颜色","ui.defaultLabelsRestored":"已恢复默认显示设置","ui.couldNotReset":"重置失败:{value}","ui.show":"显示{label}","ui.clickToHide":"点击隐藏","ui.clickToShow":"点击显示","ui.presetColor":"{label}的预设颜色","ui.customColor":"{label}的自定义颜色","ui.customColorOpenColorPicker":"自定义颜色(打开系统取色器)","ui.customColorItem":"自定义…","ui.colorSwatchLabel":"{label}的颜色","ui.hexColor":"{label}的十六进制颜色","ui.expand":"展开","ui.collapse":"收起","ui.saving":"正在保存…","ui.processing":"正在处理…","ui.visibleFields":"要显示的信息","ui.timeDateTitle":"时间与日期","ui.timeDateDesc":"主时间和世界时间的时区。","ui.customTextSectionDesc":"在信息栏中显示一行自定义文字。","ui.resetConfirmTitle":"重置信息栏设置","ui.resetConfirmDescFields":"将所有显示项恢复为默认;自定义颜色不受影响,改动会直接生效。","ui.resetConfirmDescColors":"将清除全部自定义颜色并恢复默认配色,字段显示开关不受影响。该操作会直接应用到信息栏。","ui.resetConfirmAcknowledge":"我了解这次重置不可撤销","ui.resetConfirmCancel":"取消","ui.resetConfirmConfirm":"确认重置","ui.resetLabels":"恢复显示","ui.resetColors":"恢复颜色","ui.resetRowTitle":"恢复默认","ui.resetRowDesc":"将显示项或颜色恢复为默认。","ui.customTextCount":"已输入 {value}/64 个字符","ui.couldNotDisplayInfoBar":"无法显示信息栏设置:{value}","ui.dataAndBilling":"账单数据","ui.dataAndBillingDesc":"导出或清除本插件保存的用量与花费记录。","ui.exportBillingRecords":"导出账单","ui.exportBillingRecordsDesc":"将记录导出为 CSV 或 JSON 文件。","ui.exportBillingCsv":"导出 CSV","ui.exportBillingJson":"导出 JSON","ui.clearBillingRecords":"清除账单","ui.clearBillingRecordsDesc":"清除后无法恢复。","ui.clearBillingRecordsConfirm":"确定清除本插件保存的全部账单记录吗?建议先导出。清除后无法恢复,但不会影响设置或登录信息。","ui.exportedBillingRecords":"已导出 {count} 条账单记录({format})","ui.noBillingRecordsToExport":"目前没有可导出的账单记录。","ui.exportFailed":"导出失败:{value}","ui.exportIncomplete":"历史账单读取不完整:{value}。本次未导出,请稍后再试。","ui.clearFailed":"清除失败:{value}","ui.clearFailedWithoutDetails":"账单记录未能全部清除","ui.clearedBillingRecords":"已清除 {count} 条账单记录","ui.clearCanceled":"已取消","ui.exportNotSupported":"当前环境不支持下载文件。","ui.weekly":"周","ui.monthly":"月","ui.window":"窗口","ui.quotaDisplayUsed":"已用","ui.quotaDisplayRemaining":"剩余","ui.quotaDisplayModeTitle":"订阅窗口百分比方向","ui.quotaDisplayModeDesc":"订阅额度窗口按「剩余」或「已用」显示;低额度告警始终按剩余不足 20% 判定。","ui.windowUsedRemaining":"{label}窗口:已用 {usedPercent}%(剩余 {value}%)","ui.windowUsedRemainingResets":"{label}窗口 已用 {usedPercent}%(剩余 {value}%) · 重置 {value4}","ui.minimax":"MiniMax","ui.supportsImageInput":"支持图像输入。","ui.vision":"视觉","ui.unknown":"未知","ui.unknownModel":"未知模型","ui.modelSelectionPending":"正在读取当前模型","ui.modelCapabilityPending":"正在确认是否支持图像输入","ui.pluginVersion":"\n插件版本:{current}","ui.provider":"服务商:{provLabel} {modelLabel}\n","ui.pricingPeakOffPeakBeijing":"定价:峰谷价(北京时间周一至周五高峰 9-12、14-18 点;周末及中国节假日全天空闲)","ui.pricingFixed":"定价:固定价","ui.pricingNotListedUsingDefaults":"定价:暂未收录,不计算花费","ui.zhipu":"智谱","ui.xiaomiMiMo":"小米 MiMo","ui.commandCode":"Command Code","ui.subscription":"订阅","ui.cloudBilling":"云账单","ui.plan":"\n套餐:{plan}","ui.expiresLocalTime":"\n到期:{value}(本地时区)","ui.subscriptionServiceModel":"订阅服务:{serviceName}\n模型:{rawModelLabel}{planLine}{expiryLine}{versionLine}","ui.balanceLookupIsNotYet":"暂时无法读取该服务商的余额。","ui.notSupported":"未适配","ui.accountDataUnavailable":"无公开账户数据","ui.accountDataUnavailableDetail":"该服务商已支持模型识别与本地用量记账,但没有可由插件安全读取的公开余额或配额接口。","ui.notConfigured":"未配置 ","ui.notConfiguredConfigureItIn":"未配置 {credName}。请在\"设置 → 模型\"中填写。","ui.notConfiguredSettingsModels":"未配置 {credName}。请在设置 → 模型中填写。","ui.accountSignedOut":"账号未登录","ui.accountSignedOutHow":"在 DSH 的「设置 → 账户」里登录 DeepSeek 账号,这里就会显示余额。","ui.estimatedBalance":"估算余额:{symbol}{value}","ui.balance":"余额:{symbol}{value}","ui.balanceDetailToppedUp":"充值余额:{symbol}{value}","ui.balanceDetailGranted":"赠金余额:{symbol}{value}","ui.balance.pushBalanceGroups":"余额","ui.low":"低","ui.estimated":"(估算)","ui.balanceIsTemporarilyUnavailableShowing":"余额暂不可用;正在显示上次数据并自动重试。","ui.couldNotLoadBalanceCheck":"余额获取失败。请检查网络和 API Key。","ui.balanceUnavailable":"余额获取失败","ui.beijingTime":"北京时间 ","ui.peakPrice":"高峰价","ui.offPeakPrice":"空闲价","ui.input":":输入 ¥","ui.mCachedInput":"/M · 缓存 ¥","ui.mOutput":"/M · 输出 ¥","ui.beijingTimeSwitchesTo":"北京时间 {atLabel} 切换为","ui.until":"距","ui.offPeak":"空闲","ui.peak":"高峰","ui.today":"今天 {symbol}{value}","ui.lastDays":"近一月 {symbol}{value}","ui.allTime":"全部 {symbol}{value}","ui.sessionIncludingSubagents":"本会话 {costTxt}(含子代理){value}","ui.session":"本会话","ui.spendIsTemporarilyUnavailableChat":"花费暂不可用;不会影响对话。","ui.spendUnavailable":"花费获取失败","ui.noSignInCredentialsFound":"未找到 {serviceName} 登录凭证。请重新授权。","ui.credentialsHaveExpiredPleaseReauthorize":"{serviceName} 登录凭证已失效。请重新授权。","ui.deniedAccessReauthorizeOrTry":"{serviceName} 拒绝访问。请重新授权或稍后再试。","ui.rateLimitReachedPleaseTry":"{serviceName} 请求过于频繁。请稍后再试。","ui.timedOutCheckYourConnection":"{serviceName} 响应超时。请检查网络后再试。","ui.returnedAnUnrecognizedResponsePlease":"{serviceName} 返回的数据暂时无法识别。请稍后再试。","ui.isTemporarilyUnavailableCheckYour":"{serviceName} 暂不可用。请检查网络后再试。","ui.subscriptionExpiresLocalTime":"订阅到期:{value}(本地时区)","ui.expires":"到期","ui.subscriptionSource":"订阅源:{value}(","ui.prepaidBalance":"可用余额","ui.availableBalanceLabel":"可用余额","ui.remainingCredits":"剩余额度","ui.availableBalance":"可用余额:{balTxt}","ui.availableCredits":"剩余 credits:{value}","ui.subscriptionSource.titleLines":"订阅源:{value}","ui.windowRemainingUsed":"{label}窗口:剩余 {value}%(已用 {usedPercent}%)","ui.resetsResetsIn":" · 重置 {value} · 距重置 {value2}","ui.windowRemainingUsedResets":"{label}窗口 剩余 {value}%(已用 {usedPercent}%) · 重置 {value4}","ui.resetsIn":"距重置","ui.configureItInSettingsModels":"。请在\"设置 → 模型\"中填写。","ui.deniedAccessTheTokenMay":"{serviceName} 拒绝访问:Token 可能缺少账单读取权限。","ui.billingIsTemporarilyUnavailableCheck":"{serviceName} 账单暂不可用。请检查网络与权限后再试。","ui.billingSource":"账单源:{value}","ui.thisMonthSSpend":"本月花费:{symbol}{value}","ui.budgetUsed":"预算使用:{value}%","ui.dailyFreeQuotaRemaining":"每日免费额度剩余:{value}","ui.thisMonth":"本月","ui.thisMonthSUsage":"本月用量","ui.budget":"预算","ui.free":"免费","ui.resetsIn.pushBillingGroups":"{value} · 距重置 {value2}","ui.billingServiceModel":"账单服务:{serviceName}\n模型:{modelLabel}{versionLine}","ui.pricing":"定价","ui.spend":"花费","ui.mode":"模式","ui.subscriptionQuota":"订阅额度","ui.billing":"账单","ui.temporarilyUnavailableKeepingTheLast":"暂不可用;正在保留上次数据并自动重试。","ui.spendJournalSavedButThe":"账单流水已保存,但可直接查看的账单文件暂未更新:","ui.thisSpendRecordWasNot":"本次账单未保存,不会计入金额:","ui.ledgerUpdatePending":"账单待整理","ui.spendNotSaved":"账单未保存","ui.versionAndUpdateTitle":"版本与更新","ui.versionAndUpdateDesc":"更新只替换插件自己的程序文件,账单记录和设置不受影响。","ui.versionUnavailable":"当前运行的 DSH 还没载入这一版插件的更新功能,所以这里暂时只显示这一行。重启 DSH 后,下面就会出现当前版本、更新方式与「检查更新」。","ui.versionRunning":"运行中版本 {version}","ui.versionLatest":"最新版本 {version}","ui.versionLastCheck":"上次检查:{time}","ui.versionUnknown":"未知","ui.timeJustNow":"刚刚","ui.timeMinutesAgo":"{n} 分钟前","ui.timeHoursAgo":"{n} 小时前","ui.timeDaysAgo":"{n} 天前","ui.autoUpdateTitle":"更新方式","ui.updateModeAutoDesc":"启动 DSH 时自动检查并安装。使用中手动检查到新版后,确认才会更新。","ui.updateModeManualDesc":"启动时不自动安装。使用中手动检查到新版后,确认才会更新。","ui.updateModeAuto":"自动更新","ui.updateModeManual":"手动更新","ui.updateConfirm":"发现新版本 {version}。现在更新插件吗?更新后需重启 DSH 才会生效。","ui.updateCheckNow":"检查更新","ui.updateChecking":"检查中…","ui.updateInstallNow":"更新到 {version}","ui.updateInstalling":"正在更新到 {version}…","ui.updateAvailableNow":"发现新版本 {version},现在可以更新。","ui.updateRollbackFailed":"回滚没成功,本机没有可用的备份。你可以到插件页卸载后重装。","ui.updateHostOutdated":"这次动作没有执行:当前运行的 DSH 还带着旧版本的更新逻辑,重启 DSH 之后按钮就好用了。","ui.updateUpToDate":"已是最新版本。","ui.updateDisabled":"当前环境不支持自动更新","ui.updateDisabledWhy":"自动更新只在插件装进 DSH 插件目录后可用。这一份是从源码或链接装进来的,升级请用原来的命令。","ui.updatePendingRestart":"已更新到 {version},重启 DSH 后生效。","ui.updateFailed":"上次更新没成功","ui.updateFallbackWhy":"万一新版有问题,可以退回上一版。","ui.updateHoldWhy":"这个版本被你暂缓过,不会自己装回来。","ui.updateErrorIncompleteDownload":"更新包没下完整(网络中途断了),这次已放弃,你现在用的版本没受影响。","ui.updateErrorIntegrityMismatch":"更新包没通过安全校验,这次已放弃,你现在用的版本没受影响。","ui.updateErrorDownloadFailed":"连不上更新服务器,稍后再试。","ui.updateErrorTooLarge":"更新包大得反常,出于安全已放弃。","ui.updateErrorPayloadMismatch":"更新包的内容和版本号对不上,已放弃。","ui.updateErrorPayloadUnsafe":"更新包里出现了不该有的文件路径,已放弃。","ui.updateErrorCheckFailed":"检查更新没成功,可能是网络问题。","ui.updateErrorUnknown":"更新没成功,详细原因记在更新日志里。","ui.updateRollback":"回滚到上一版","ui.updateRolledBack":"已回滚到上一版 {version}。","ui.updateHeld":"新版 {version} 已被你暂缓,不会自动装回来。","ui.updateAllowHeld":"允许更新到 {version}","ui.updateRestartBadge":"重启生效","ui.updateFailedBadge":"更新失败","ui.tools":"工具调用","ui.avgTTFT":"首 token 平均","ui.cacheHit":"缓存命中","ui.cacheHitScope":"按 token 计:命中 {hit} / 未命中 {miss}({percent}% 命中)。\n口径:当前会话主 Agent 的模型调用,不含子代理。","ui.tokenScope":"输入 / 输出是本会话主 Agent 的模型调用累计,不含子代理;右侧『本会话』花费含子代理。","ui.spendPartlyUnpriced":"其中部分调用尚未收录价格(绝不套用其他模型价格估算),实际花费高于此处显示值。","ui.input.BottomInfoBar":"输入","ui.output":"输出","ui.savingView":"正在保存切换…","ui.clickToSwitchFullCompact":"单击切换 完整/简洁","ui.pressEnterOrSpaceFor":"按 Enter 或空格切换为简洁模式。","ui.pressEnterOrSpaceFor.BottomInfoBar":"按 Enter 或空格切换为完整模式。","host.hour":"5 小时","host.unknownProvider":"未知服务商","error.subscription.request-failed":"订阅额度请求未知异常","host.settingsFileCouldNotBe":"设置文件写入未完成","error.settings.save-failed":"settings.json 落盘失败:{value}","error.balance.credentials":"凭据读取失败","error.balance.not-configured":"未配置 {credential}","error.balance.account-signed-out":"内置账号未登录","error.balance.account-unavailable":"当前宿主没有内置账号服务","error.balance.account-request-failed":"内置账号余额获取失败","error.request.http":"请求失败(HTTP {status})","error.request.parse":"响应格式异常","error.subscription.not-connected":"未找到 ChatGPT 订阅登录凭证(~/.codex/auth.json),请安装 dsh-chatgpt-sub 插件绑定","error.subscription.credentials-missing":"ChatGPT 订阅登录凭证缺少 id_token,请安装 dsh-chatgpt-sub 插件重新绑定","error.subscription.opencode-not-configured":"未配置 OpenCode Go(OPENCODE_GO_API_KEY 或 opencode auth.json)","error.subscription.commandcode-not-configured":"未配置 Command Code(COMMAND_CODE_API_KEY、CMD_API_KEY 或 ~/.commandcode/auth.json)","error.subscription.commandcode-auth-failed":"Command Code 登录凭证已失效。请重新登录或更新 API Key","error.subscription.commandcode-unrecognized":"Command Code 返回了无法识别的额度格式(接口可能已变更),已保留上次数据","host.zhipu":"智谱 {mapped}","host.zhipu.parseZaiQuota":"智谱 {value}{value2}","error.subscription.zhipu-not-configured":"未配置智谱 API Key(ZAI_API_KEY 或 ZAI_CODING_CN_API_KEY)","error.subscription.zhipu-auth-failed":"智谱 API 认证失败(密钥过期或不正确)","error.subscription.zhipu-unrecognized":"智谱返回了无法识别的额度格式(接口可能已变更),已保留上次数据","error.request.failed":"请求失败({value} {msg})","error.subscription.xiaomi-not-configured":"未配置小米 MiMo Token Plan 凭据({credName} 或 XIAOMI_API_KEY)","error.subscription.xiaomi-http":"请求失败(HTTP {value})","error.subscription.minimax-not-configured":"未配置 MiniMax 凭据(MINIMAX_API_KEY 或 MINIMAX_CN_API_KEY)。查询 Token Plan 必须使用 Subscription Key,按量 API Key 会被服务端拒绝","error.subscription.minimax-auth-failed":"MiniMax 拒绝了当前 API Key:查询 Token Plan 必须使用 Subscription Key(在 Token Plan 订阅页生成),按量 API Key 会被服务端拒绝(status_code=1004 / HTTP 401)","error.subscription.minimax-unrecognized":"MiniMax 返回了无法识别的额度格式(接口可能已变更),已保留上次数据","error.billing.together-not-configured":"未配置 TOGETHER_API_KEY","host.actualMonthlyBillFromThe":"本月真实账单(Together 官方 Usage API)","error.billing.fireworks-not-configured":"未配置 FIREWORKS_API_KEY","error.billing.fireworks-account":"账户解析失败(未取得 account_id)","host.actualBillForThisPeriod":"本周期真实账单(Fireworks Billing Summary)","host.actualUsageForThisPeriod":"本周期真实用量(billingUsage 回退端点,无金额)","error.billing.aws-not-configured":"未配置 AWS 凭据(AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY)","error.billing.aws-http":"请求失败(HTTP {status}),可能缺少 ce:GetCostAndUsage 权限","host.actualMonthlyBillFromAWS":"AWS Cost Explorer 本月真实账单(账单延迟约 24 小时)","error.billing.cloudflare-not-configured":"未配置 CLOUDFLARE_API_KEY(需账号级 Token 并授予 Billing 读权限)","error.billing.cloudflare-account":"未配置 CLOUDFLARE_ACCOUNT_ID","error.billing.cloudflare-http":"请求失败(HTTP {status}),Token 需 Billing 读权限","host.actualMonthlyUsageFromThe":"Cloudflare Billable Usage API(Alpha),本月真实用量","error.billing.huggingface-not-configured":"未配置 HF_TOKEN(细粒度 token 需授予 Billing 读权限)","host.actualMonthlyBillFromHF":"本月真实账单(Hugging Face Billing API)","error.billing.request-failed":"账单请求未知异常","host.spendSummaryFileMissingArchived":"账单汇总文件缺失:折叠期间的历史金额暂未计入显示(明细仍在冷归档 usage-archive/,可人工恢复)","host.spendLedgerCouldNotBe":"账单文件写入未完成","host.usageLedgerBusy":"当前仍有回答正在进行,完成后再清除账单记录","error.ledger.clear-failed":"账单记录清理未完成:{value}","error.ledger.snapshot-stale":"折叠汇总落盘失败:{value}","host.basedOnYourLastSessions":"基于你最近 {count} 次会话","host.estimatedFromSpendingOverThe":"基于过去 {SPEND_DAYS} 天消耗速度的估算","host.patchMustIncludeFieldsOr":"patch 需包含 fields、colors、timeZones 或 customText 之一","host.timeZonesMustBeAnObject":"timeZones 必须是对象","host.timeZoneMustBeAValid":"时区必须是有效的 IANA 时区:{key}","host.customTextMustBeAString":"自定义文本必须是字符串","host.customTextTooLong":"自定义文本不能超过 64 个字符","host.quotaDisplayModeInvalid":"订阅窗口百分比方向必须是 used 或 remaining","host.infoDensityMustBeFullOrCompact":"信息显示方式必须是完整或简洁","host.fieldsMustBeAnObject":"fields 必须是对象","host.unknownFieldId":"未知字段 id: {key}","host.fieldVisibilityMustBeA":"字段开关必须是布尔值: {key}","host.colorsMustBeAnObject":"colors 必须是对象","host.colorMustBeAPreset":"颜色只接受预设色名或 #RRGGBB: {key}","field.anchorGroup.label":"服务商与模型","field.anchorGroup.note":"显示当前会话使用的服务商和模型。","field.subServiceGroup.label":"订阅服务与模型","field.subServiceGroup.note":"显示订阅服务和当前模型或套餐。","field.billingServiceGroup.label":"账单服务与模型","field.billingServiceGroup.note":"显示账单服务和当前模型。","field.customText.label":"自定义文字","field.customText.note":"显示一段自定义文字,可用作备注或签名。","field.mainTime.label":"主时间","field.mainTime.note":"显示主时区的时间;时区在「时间与日期」中调整。","field.worldTime.label":"世界时间","field.worldTime.note":"显示另一时区的时间。","field.sessionCost.label":"本次会话花费","field.sessionCost.note":"显示本次会话的实际花费,包含子代理。","field.balance.note":"显示账户余额;余额过低时标红提醒。","field.period.label":"当前时段","field.period.note":"峰谷定价的服务商显示当前是高峰还是空闲时段。","field.countdown.label":"下次价格切换","field.countdown.note":"显示距离下次高峰 / 空闲价格切换的时间。","field.expiry.label":"订阅到期日","field.expiry.note":"服务商返回到期时间时显示。","field.subWindow5h.label":"5 小时额度","field.subWindow5h.note":"显示滚动 5 小时额度的剩余比例。","field.subWindowWeek.label":"每周额度","field.subWindowWeek.note":"显示每周额度的剩余比例。","field.subWindowMonth.label":"每月额度","field.subWindowMonth.note":"显示每月额度的剩余比例。","field.resetCountdown.label":"距额度重置","field.resetCountdown.note":"显示当前额度重置的剩余时间。","field.subBalance.label":"可用余额或剩余额度","field.subBalance.note":"按量账户显示可用余额;没有额度窗口的 credits 订阅显示剩余额度。","field.billingSpend.label":"本月用量","field.billingSpend.note":"显示本计费周期的实际用量或花费。","field.budget.label":"预算使用情况","field.budget.note":"服务商支持时显示已使用的预算比例。","field.freeQuota.label":"免费额度","field.freeQuota.note":"服务商提供免费额度时显示剩余额度和重置时间。","field.turnsSteps.label":"轮次与步数","field.turnsSteps.note":"显示本会话对话的轮次和步数。","field.llmTime.label":"模型耗时","field.llmTime.note":"显示模型推理累计耗时。","field.toolTime.label":"工具耗时","field.toolTime.note":"显示工具调用累计耗时。","field.avgTTFT.label":"首 Token 平均耗时","field.avgTTFT.note":"显示本会话模型步骤的平均首 Token 时间。","field.outputSpeed.label":"输出速率","field.outputSpeed.note":"显示本会话已上报用量的模型步骤的平均输出速率(tok/s)。","field.cacheHit.note":"显示提示词缓存命中率。","field.tokensIO.label":"输入/输出 Token","field.tokensIO.note":"显示本会话累计的输入 / 输出 Token 量。","field.contextUsage.label":"上下文用量","field.contextUsage.note":"显示上下文占用比例;圆环越满表示剩余可写空间越少。","ui.contextAria":"上下文已用 {percent}","ui.contextUsed":"上下文已用","ui.contextSystem":"系统提示词","ui.contextTools":"工具定义","ui.contextMessages":"对话消息","ui.contextFigures":"~{used} / {window}","number.thousand":"{value}K","number.million":"{value}M","field.unmapped.label":"账户数据状态提示","field.unmapped.note":"服务商未知或未公开账户余额/配额接口时显示;本地用量记账仍正常工作。","field.noKeyHint.label":"缺少密钥提示","field.noKeyHint.note":"缺少 API Key 时显示去填写的提示。","field.balanceError.label":"余额更新失败提示","field.balanceError.note":"余额更新失败时显示。","field.usageError.label":"用量更新失败提示","field.usageError.note":"花费暂时不可用时显示。","field.refreshFailure.label":"更新失败提示","field.refreshFailure.note":"任一数据刷新失败时显示提醒。","field.persistWarning.label":"记录未保存提醒","field.persistWarning.note":"账单保存失败时显示提醒,建议保留。","field.updateNotice.label":"更新提醒","field.updateNotice.note":"有新版本可更新、或新版已就绪待重启时显示短标记。","field.updateFailure.label":"更新失败提醒","field.updateFailure.note":"自动更新失败时显示短标记。","group.native":"原生信息","group.plugin":"插件信息","group.notice":"提醒信息","group.native.desc":"DSH 原生底栏自带的字段,列在原生统计行;这一行只在完整模式显示。","group.plugin.desc":"本插件新增的字段(含接管过来的上下文圆环),归在主行里;简洁与完整都显示。","group.notice.desc":"更新、失败等一次性提醒。当下真有事要提醒就出现,与模式无关。","section.identity.label":"服务商与模型","section.identity.desc":"任何计费方式都显示的一行:当前用的是哪家的服务、哪个模型。","section.balance.label":"余额制:充值后按用量扣钱","section.balance.desc":"这类服务商只有下面几项有数据:余额、本次会话花费、当前时段与下次价格切换。","section.subscription.label":"订阅制:按月付费,额度内不限量","section.subscription.desc":"ChatGPT 这类订阅只有下面几项有数据:额度窗口、额度重置、到期日与可用余额。","section.billing.label":"账单制:先用后付,按月出账","section.billing.desc":"这类服务商只有下面几项有数据:本月用量、预算使用情况、免费额度。","section.common.label":"通用显示项","section.common.desc":"和计费方式无关,用什么服务商都能开:自定义文字、时间、上下文用量。","ui.listSeparator":"、","ui.sentenceEnd":"。","ui.fieldErrorPrefix":"「{label}」:","ui.turnCount":"{count} 轮","ui.turnCountPlural":"{count} 轮","ui.stepCount":"{count} 步","ui.stepCountPlural":"{count} 步","ui.mainTimeZone":"主时间时区","ui.worldTimeZone":"世界时间时区","ui.customTextTitle":"自定义文本","ui.customTextPlaceholder":"输入文字(最多 64 个字符)","ui.searchPlaceholder":"按名称或说明搜索…","ui.searchFieldsLabel":"搜索显示内容","ui.searchResultCount":"找到 {count} 项","ui.enabledFieldsCount":"已启用 {count} 项","ui.noSearchResults":"没有找到匹配的设置项","ui.mainTime":"主时间","ui.worldTime":"世界时间","ui.customText":"自定义文本"},"en":{"meta.title":"Bottom Info Bar","meta.description":"Shows the current model, balance and spend under the composer.","ui.requestTimedOut":"Request timed out","ui.requestCanceled":"Request canceled","ui.couldNotParseResponse":"Could not parse response","ui.rpcFailed":"RPC failed","ui.refreshFailed":"Refresh failed","color.red":"Red","color.green":"Green","color.blue":"Blue","color.purple":"Purple","color.orange":"Orange","color.neutral":"Neutral","ui.pleaseTryAgainLater":"Please try again later","ui.restoreDefaultColor":"Restore default color","ui.infoBarSettings":"Info Bar","ui.settingsAreTemporarilyUnavailable":"Settings are temporarily unavailable","ui.loadingInfoBarSettings":"Loading settings…","ui.couldNotLoadInfoBar":"Could not load Info Bar settings: ","ui.changesAppliedButCouldNot":"Applied, but could not save locally: ","ui.unknownReason":"Unknown reason","ui.couldNotSave":"{errorPrefix}Could not save: {value}","ui.color":"\"{value}\" color: ","ui.hasAnInvalidColorEnter":"\"{value}\" has an invalid color. Enter #RRGGBB (for example, #0044CC).","ui.defaultColorsRestored":"Default colors restored","ui.defaultLabelsRestored":"Default display restored","ui.couldNotReset":"Could not reset: {value}","ui.show":"Show {label}","ui.clickToHide":"Click to hide","ui.clickToShow":"Click to show","ui.presetColor":"{label} preset color","ui.customColor":"{label} custom color","ui.customColorOpenColorPicker":"Custom color (open color picker)","ui.customColorItem":"Custom…","ui.colorSwatchLabel":"{label} color","ui.hexColor":"{label} hex color","ui.expand":"Expand","ui.collapse":"Collapse","ui.saving":"Saving…","ui.processing":"Working…","ui.visibleFields":"Information to show","ui.timeDateTitle":"Time and date","ui.timeDateDesc":"Time zones for main and world time.","ui.customTextSectionDesc":"Shows one line of custom text in the info bar.","ui.resetConfirmTitle":"Reset Info Bar settings","ui.resetConfirmDescFields":"Restore all display choices to their defaults. Custom colors are not affected and the change applies right away.","ui.resetConfirmDescColors":"All custom colors will be cleared and defaults restored. Field switches are not affected. This applies to the Info Bar right away.","ui.resetConfirmAcknowledge":"I understand this reset cannot be undone","ui.resetConfirmCancel":"Cancel","ui.resetConfirmConfirm":"Reset","ui.resetLabels":"Restore display","ui.resetColors":"Restore colors","ui.resetRowTitle":"Reset to defaults","ui.resetRowDesc":"Restore displayed items or colors to their defaults.","ui.customTextCount":"{value}/64 characters","ui.couldNotDisplayInfoBar":"Could not display Info Bar settings: {value}","ui.dataAndBilling":"Billing data","ui.dataAndBillingDesc":"Export or clear the usage and spend records saved by this plugin.","ui.exportBillingRecords":"Export billing","ui.exportBillingRecordsDesc":"Export the records as a CSV or JSON file.","ui.exportBillingCsv":"Export CSV","ui.exportBillingJson":"Export JSON","ui.clearBillingRecords":"Clear billing","ui.clearBillingRecordsDesc":"This cannot be undone.","ui.clearBillingRecordsConfirm":"Clear all billing records saved by this plugin? Export first. This cannot be undone, but settings and sign-in information will stay unchanged.","ui.exportedBillingRecords":"Exported {count} billing records ({format})","ui.noBillingRecordsToExport":"There are no billing records to export.","ui.exportFailed":"Export failed: {value}","ui.exportIncomplete":"Some historical billing records could not be read: {value}. Nothing was exported; try again later.","ui.clearFailed":"Could not clear billing records: {value}","ui.clearFailedWithoutDetails":"Billing records could not be fully cleared","ui.clearedBillingRecords":"Cleared {count} billing records","ui.clearCanceled":"Canceled","ui.exportNotSupported":"File downloads are not supported in this environment.","ui.weekly":"Weekly","ui.monthly":"Monthly","ui.window":"Window","ui.quotaDisplayUsed":"Used","ui.quotaDisplayRemaining":"Remaining","ui.quotaDisplayModeTitle":"Subscription window percentage","ui.quotaDisplayModeDesc":"Show subscription quota windows as remaining or used. The low-quota warning always triggers when less than 20% remains.","ui.windowUsedRemaining":"{label} window: used {usedPercent}% (remaining {value}%)","ui.windowUsedRemainingResets":"{label} window: used {usedPercent}% (remaining {value}%) · Resets {value4}","ui.minimax":"MiniMax","ui.supportsImageInput":"Supports image input.","ui.vision":"Vision","ui.unknown":"Unknown","ui.unknownModel":"Unknown model","ui.modelSelectionPending":"Reading current model","ui.modelCapabilityPending":"Checking image-input support","ui.pluginVersion":"\nPlugin version: {current}","ui.provider":"Provider: {provLabel} {modelLabel}\n","ui.pricingPeakOffPeakBeijing":"Pricing: peak/off-peak (Beijing time; weekday peaks 09:00-12:00 and 14:00-18:00; weekends and Chinese public holidays off-peak)","ui.pricingFixed":"Pricing: fixed","ui.pricingNotListedUsingDefaults":"Pricing: not listed; spend is not calculated","ui.zhipu":"Zhipu","ui.xiaomiMiMo":"Xiaomi MiMo","ui.commandCode":"Command Code","ui.subscription":"Subscription","ui.cloudBilling":"Cloud billing","ui.plan":"\nPlan: {plan}","ui.expiresLocalTime":"\nExpires: {value} (local time)","ui.subscriptionServiceModel":"Subscription service: {serviceName}\nModel: {rawModelLabel}{planLine}{expiryLine}{versionLine}","ui.balanceLookupIsNotYet":"This provider's balance is not available yet.","ui.notSupported":"Not supported","ui.accountDataUnavailable":"No public account data","ui.accountDataUnavailableDetail":"This provider is supported for model recognition and local usage accounting, but has no public balance or quota endpoint that the plugin can safely read.","ui.notConfigured":"Not configured: ","ui.notConfiguredConfigureItIn":"Not configured: {credName}. Configure it in Settings → Models.","ui.notConfiguredSettingsModels":"{credName} is not configured. Add it in Settings → Models.","ui.accountSignedOut":"Account signed out","ui.accountSignedOutHow":"Sign in to your DeepSeek account in DSH settings, Account, and the balance will appear here.","ui.estimatedBalance":"Estimated balance: {symbol}{value}","ui.balance":"Balance: {symbol}{value}","ui.balanceDetailToppedUp":"Topped-up balance: {symbol}{value}","ui.balanceDetailGranted":"Granted balance: {symbol}{value}","ui.balance.pushBalanceGroups":"Balance","ui.low":"Low","ui.estimated":"(estimated)","ui.balanceIsTemporarilyUnavailableShowing":"Balance is temporarily unavailable. Showing the last data and retrying automatically.","ui.couldNotLoadBalanceCheck":"Could not load balance. Check your connection and API key.","ui.balanceUnavailable":"Balance unavailable","ui.beijingTime":"Beijing time: ","ui.peakPrice":"Peak price","ui.offPeakPrice":"Off-peak price","ui.input":": input ¥","ui.mCachedInput":"/M · cached input ¥","ui.mOutput":"/M · output ¥","ui.beijingTimeSwitchesTo":"Beijing time: {atLabel} switches to ","ui.until":"Until ","ui.offPeak":"off-peak","ui.peak":"peak","ui.today":"Today {symbol}{value}","ui.lastDays":"Last 30 days {symbol}{value}","ui.allTime":"All time {symbol}{value}","ui.sessionIncludingSubagents":"Session {costTxt} (including subagents){value}","ui.session":"Session","ui.spendIsTemporarilyUnavailableChat":"Spend is temporarily unavailable. Chat is unaffected.","ui.spendUnavailable":"Spend unavailable","ui.noSignInCredentialsFound":"No sign-in credentials found for {serviceName}. Please reauthorize.","ui.credentialsHaveExpiredPleaseReauthorize":"{serviceName} credentials have expired. Please reauthorize.","ui.deniedAccessReauthorizeOrTry":"{serviceName} denied access. Reauthorize or try again later.","ui.rateLimitReachedPleaseTry":"{serviceName} rate limit reached. Please try again later.","ui.timedOutCheckYourConnection":"{serviceName} timed out. Check your connection and try again.","ui.returnedAnUnrecognizedResponsePlease":"{serviceName} returned an unrecognized response. Please try again later.","ui.isTemporarilyUnavailableCheckYour":"{serviceName} is temporarily unavailable. Check your connection and try again.","ui.subscriptionExpiresLocalTime":"Subscription expires: {value} (local time)","ui.expires":"Expires","ui.subscriptionSource":"Subscription source: {value} (","ui.prepaidBalance":"Available balance","ui.availableBalanceLabel":"Available balance","ui.remainingCredits":"Credits remaining","ui.availableBalance":"Available balance: {balTxt}","ui.availableCredits":"Credits remaining: {value}","ui.subscriptionSource.titleLines":"Subscription source: {value}","ui.windowRemainingUsed":"{label} window: remaining {value}% (used {usedPercent}%)","ui.resetsResetsIn":" · Resets {value} · Resets in {value2}","ui.windowRemainingUsedResets":"{label} window: remaining {value}% (used {usedPercent}%) · Resets {value4}","ui.resetsIn":"Resets in","ui.configureItInSettingsModels":". Configure it in Settings → Models.","ui.deniedAccessTheTokenMay":"{serviceName} denied access: the token may lack billing read permissions.","ui.billingIsTemporarilyUnavailableCheck":"{serviceName} billing is temporarily unavailable. Check your connection and permissions, then try again.","ui.billingSource":"Billing source: {value}","ui.thisMonthSSpend":"This month’s spend: {symbol}{value}","ui.budgetUsed":"Budget used: {value}%","ui.dailyFreeQuotaRemaining":"Daily free quota remaining: {value}","ui.thisMonth":"This month","ui.thisMonthSUsage":"This month’s usage","ui.budget":"Budget","ui.free":"Free","ui.resetsIn.pushBillingGroups":"{value} · Resets in {value2}","ui.billingServiceModel":"Billing service: {serviceName}\nModel: {modelLabel}{versionLine}","ui.pricing":"Pricing","ui.spend":"Spend","ui.mode":"Mode","ui.subscriptionQuota":"Subscription quota","ui.billing":"Billing","ui.temporarilyUnavailableKeepingTheLast":": temporarily unavailable. Keeping the last data and retrying automatically.","ui.spendJournalSavedButThe":"Spend journal saved, but the readable ledger has not been updated: ","ui.thisSpendRecordWasNot":"This spend record was not saved and will not be added to totals: ","ui.ledgerUpdatePending":"Ledger update pending","ui.spendNotSaved":"Spend not saved","ui.versionAndUpdateTitle":"Version and updates","ui.versionAndUpdateDesc":"Updates replace only the plugin's own files; billing records and settings are untouched.","ui.versionUnavailable":"The DSH currently running has not loaded this version of the plugin yet, so only this line can be shown here. Restart DSH and the running version, the update mode and the check button will appear.","ui.versionRunning":"Running version {version}","ui.versionLatest":"Latest version {version}","ui.versionLastCheck":"Last checked {time}","ui.versionUnknown":"Unknown","ui.timeJustNow":"just now","ui.timeMinutesAgo":"{n} min ago","ui.timeHoursAgo":"{n} h ago","ui.timeDaysAgo":"{n} d ago","ui.autoUpdateTitle":"Update method","ui.updateModeAutoDesc":"Checks and installs when DSH starts. During use, a manual check asks before installing.","ui.updateModeManualDesc":"Does not install at startup. During use, a manual check asks before installing.","ui.updateModeAuto":"Automatic updates","ui.updateModeManual":"Manual updates","ui.updateConfirm":"Version {version} is available. Update the plugin now? Restart DSH to apply it.","ui.updateCheckNow":"Check now","ui.updateChecking":"Checking…","ui.updateInstallNow":"Update to {version}","ui.updateInstalling":"Updating to {version}…","ui.updateAvailableNow":"Version {version} is ready; you can update now.","ui.updateRollbackFailed":"The rollback did not succeed because no usable backup exists. Uninstall and reinstall from the plugins page instead.","ui.updateHostOutdated":"This action did not run: the DSH now running still carries the old update logic. Restart DSH and the button will work.","ui.updateUpToDate":"Up to date.","ui.updateDisabled":"Automatic updates are unavailable here","ui.updateDisabledWhy":"Automatic updates need the plugin installed into the DSH plugin directory. This copy came from a source checkout or a link, so use the original update command.","ui.updatePendingRestart":"Updated to {version}. Restart DSH to activate.","ui.updateFailed":"The last update did not succeed","ui.updateFallbackWhy":"If the new version misbehaves, you can go back to the previous one.","ui.updateHoldWhy":"You held this version back, so it will not be installed automatically.","ui.updateErrorIncompleteDownload":"The download was incomplete (the connection dropped). This update was abandoned and the version you have is untouched.","ui.updateErrorIntegrityMismatch":"The update package failed its safety check, so it was abandoned. The version you have is untouched.","ui.updateErrorDownloadFailed":"Could not reach the update server. Try again later.","ui.updateErrorTooLarge":"The update package was unusually large, so it was abandoned.","ui.updateErrorPayloadMismatch":"The update package did not match its version number, so it was abandoned.","ui.updateErrorPayloadUnsafe":"The update package contained an unexpected file path, so it was abandoned.","ui.updateErrorCheckFailed":"The version check did not succeed, possibly a network problem.","ui.updateErrorUnknown":"The update did not succeed. Details are in the update log.","ui.updateRollback":"Roll back to previous version","ui.updateRolledBack":"Rolled back to the previous version {version}.","ui.updateHeld":"Version {version} is held back and will not be installed automatically.","ui.updateAllowHeld":"Allow updating to {version}","ui.updateRestartBadge":"Restart to apply","ui.updateFailedBadge":"Update failed","ui.tools":"Tools","ui.avgTTFT":"Avg. TTFT","ui.cacheHit":"Cache hit","ui.cacheHitScope":"By token: {hit} hit / {miss} miss ({percent}% hit).\nScope: this session's main Agent only, subagents excluded.","ui.tokenScope":"Input/output accumulate this session's main Agent only (subagents excluded); Session cost includes subagents.","ui.spendPartlyUnpriced":"Some calls have no listed price (no other model's price is substituted); the real cost is higher than shown.","ui.input.BottomInfoBar":"Input","ui.output":"Output","ui.savingView":"Saving view…","ui.clickToSwitchFullCompact":"Click to switch full/compact view","ui.pressEnterOrSpaceFor":"Press Enter or Space for compact view.","ui.pressEnterOrSpaceFor.BottomInfoBar":"Press Enter or Space for full view.","host.hour":"5-hour","host.unknownProvider":"Unknown provider","error.subscription.request-failed":"Unexpected subscription quota request failure","host.settingsFileCouldNotBe":"Settings file could not be saved","error.settings.save-failed":"Could not save settings.json: {value}","error.balance.credentials":"Could not read credentials","error.balance.not-configured":"Not configured: {credential}","error.balance.account-signed-out":"The built-in account is signed out","error.balance.account-unavailable":"This host has no built-in account service","error.balance.account-request-failed":"Could not fetch the built-in account balance","error.request.http":"Request failed: HTTP {status}.","error.request.parse":"Unexpected response format","error.subscription.not-connected":"ChatGPT subscription is not connected: credentials not found in ~/.codex/auth.json. Install dsh-chatgpt-sub and sign in.","error.subscription.credentials-missing":"ChatGPT subscription credentials are missing id_token. Install dsh-chatgpt-sub and reauthorize.","error.subscription.opencode-not-configured":"OpenCode Go is not configured. Set OPENCODE_GO_API_KEY or use opencode auth.json.","error.subscription.commandcode-not-configured":"Command Code is not configured. Set COMMAND_CODE_API_KEY, CMD_API_KEY, or sign in with the Command Code CLI.","error.subscription.commandcode-auth-failed":"Command Code credentials were rejected. Sign in again or update the API key.","error.subscription.commandcode-unrecognized":"Command Code returned an unrecognized quota format; the previous snapshot was kept.","host.zhipu":"Zhipu {mapped}","host.zhipu.parseZaiQuota":"Zhipu {value}{value2}","error.subscription.zhipu-not-configured":"Zhipu API key is not configured. Set ZAI_API_KEY or ZAI_CODING_CN_API_KEY.","error.subscription.zhipu-auth-failed":"Zhipu API authentication failed: the key is expired or invalid.","error.subscription.zhipu-unrecognized":"Zhipu returned an unrecognized quota format (the API may have changed); the last known data is kept.","error.request.failed":"Request failed: {value} {msg}.","error.subscription.xiaomi-not-configured":"Xiaomi MiMo Token Plan credentials are not configured: {credName} or XIAOMI_API_KEY.","error.subscription.xiaomi-http":"Request failed: HTTP {value}.","error.subscription.minimax-not-configured":"MiniMax is not configured. Set MINIMAX_API_KEY or MINIMAX_CN_API_KEY. Token Plan queries require a Subscription Key; pay-as-you-go API keys are rejected by the server.","error.subscription.minimax-auth-failed":"MiniMax rejected the API key: Token Plan queries require a Subscription Key (generated on the Token Plan subscription page). Pay-as-you-go keys are rejected (status_code=1004 / HTTP 401).","error.subscription.minimax-unrecognized":"MiniMax returned an unrecognized quota format (the API may have changed); the last known data is kept.","error.billing.together-not-configured":"Not configured: TOGETHER_API_KEY","host.actualMonthlyBillFromThe":"Actual monthly bill from the Together Usage API","error.billing.fireworks-not-configured":"Not configured: FIREWORKS_API_KEY","error.billing.fireworks-account":"Could not read account (account_id missing)","host.actualBillForThisPeriod":"Actual bill for this period (Fireworks Billing Summary)","host.actualUsageForThisPeriod":"Actual usage for this period (billingUsage fallback; no spend amount)","error.billing.aws-not-configured":"Not configured: AWS credentials (AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY)","error.billing.aws-http":"Request failed: HTTP {status}. The token may lack ce:GetCostAndUsage permission","host.actualMonthlyBillFromAWS":"Actual monthly bill from AWS Cost Explorer (about 24 hours behind)","error.billing.cloudflare-not-configured":"Not configured: CLOUDFLARE_API_KEY (requires an account-level token with Billing read permission)","error.billing.cloudflare-account":"Not configured: CLOUDFLARE_ACCOUNT_ID","error.billing.cloudflare-http":"Request failed: HTTP {status}. The token requires Billing read permission","host.actualMonthlyUsageFromThe":"Actual monthly usage from the Cloudflare Billable Usage API (Alpha)","error.billing.huggingface-not-configured":"Not configured: HF_TOKEN (fine-grained tokens require Billing read permission)","host.actualMonthlyBillFromHF":"Actual monthly bill from the Hugging Face Billing API","error.billing.request-failed":"Unexpected billing request failure","host.spendSummaryFileMissingArchived":"Spend summary file missing: archived amounts are not included in displayed totals. Details remain in usage-archive/ for manual recovery.","host.spendLedgerCouldNotBe":"Spend ledger could not be saved","host.usageLedgerBusy":"A response is still in progress. Clear billing records after it finishes.","error.ledger.clear-failed":"Billing records could not be fully cleared: {value}","error.ledger.snapshot-stale":"Could not save archived spend summaries: {value}","host.basedOnYourLastSessions":"Based on your last {count} sessions","host.estimatedFromSpendingOverThe":"Estimated from spending over the last {SPEND_DAYS} days","host.patchMustIncludeFieldsOr":"patch must include fields, colors, timeZones or customText","host.timeZonesMustBeAnObject":"timeZones must be an object","host.timeZoneMustBeAValid":"Time zone must be a valid IANA zone: {key}","host.customTextMustBeAString":"Custom text must be a string","host.customTextTooLong":"Custom text must not exceed 64 characters","host.quotaDisplayModeInvalid":"Subscription window percentage mode must be \"used\" or \"remaining\"","host.infoDensityMustBeFullOrCompact":"Information display must be full or compact","host.fieldsMustBeAnObject":"fields must be an object","host.unknownFieldId":"Unknown field id: {key}","host.fieldVisibilityMustBeA":"Field visibility must be a boolean: {key}","host.colorsMustBeAnObject":"colors must be an object","host.colorMustBeAPreset":"Color must be a preset name or #RRGGBB: {key}","field.anchorGroup.label":"Provider and model","field.anchorGroup.note":"Shows the provider and model used in this conversation.","field.subServiceGroup.label":"Subscription service and model","field.subServiceGroup.note":"Shows the subscription service and current model or plan.","field.billingServiceGroup.label":"Billing service and model","field.billingServiceGroup.note":"Shows the billing service and current model.","field.customText.label":"Custom text","field.customText.note":"Shows custom text for a note or signature.","field.mainTime.label":"Main time","field.mainTime.note":"Shows the main time zone; adjust zone in Time and date.","field.worldTime.label":"World time","field.worldTime.note":"Shows another time zone.","field.sessionCost.label":"Session spend","field.sessionCost.note":"Shows actual spend for this session, including subagents.","field.balance.note":"Shows the account balance; a low balance is highlighted in red.","field.period.label":"Current period","field.period.note":"For peak-valley pricing providers, shows whether the current period is peak or off-peak.","field.countdown.label":"Next price change","field.countdown.note":"Shows the time until the next peak / off-peak price change.","field.expiry.label":"Subscription expiry","field.expiry.note":"Shown when the provider returns an expiry date.","field.subWindow5h.label":"5-hour quota","field.subWindow5h.note":"Shows the remaining rolling 5-hour quota.","field.subWindowWeek.label":"Weekly quota","field.subWindowWeek.note":"Shows the remaining weekly quota.","field.subWindowMonth.label":"Monthly quota","field.subWindowMonth.note":"Shows the remaining monthly quota.","field.resetCountdown.label":"Quota reset","field.resetCountdown.note":"Shows the time remaining until the current quota resets.","field.subBalance.label":"Available balance or credits","field.subBalance.note":"Shows available balance for pay-as-you-go accounts, or remaining credits when a subscription has no visible quota window.","field.billingSpend.label":"Monthly usage","field.billingSpend.note":"Shows actual usage or spend for the current billing period.","field.budget.label":"Budget status","field.budget.note":"Shown when the provider reports a budget percentage.","field.freeQuota.label":"Free quota","field.freeQuota.note":"Shown when the provider offers a free allowance, with the remaining amount and reset time.","field.turnsSteps.label":"Turns and steps","field.turnsSteps.note":"Shows turns and steps in this session.","field.llmTime.label":"Model time","field.llmTime.note":"Shows total model inference time.","field.toolTime.label":"Tool time","field.toolTime.note":"Shows total tool execution time.","field.avgTTFT.label":"Average time to first token","field.avgTTFT.note":"Shows the average time to first token across model steps in this session.","field.outputSpeed.label":"Output speed","field.outputSpeed.note":"Shows average output speed for usage-reporting model steps in this session (tok/s).","field.cacheHit.note":"Shows the prompt cache hit rate.","field.tokensIO.label":"Input / output tokens","field.tokensIO.note":"Shows this session’s total input / output tokens.","field.contextUsage.label":"Context usage","field.contextUsage.note":"Shows context usage; a fuller ring means less writable space remains.","ui.contextAria":"{percent} of context used","ui.contextUsed":"Context used","ui.contextSystem":"System prompt","ui.contextTools":"Tool definitions","ui.contextMessages":"Conversation messages","ui.contextFigures":"~{used} / {window}","number.thousand":"{value}K","number.million":"{value}M","field.unmapped.label":"Account data status","field.unmapped.note":"Shown when a provider is unknown or has no public balance/quota endpoint; local usage accounting still works.","field.noKeyHint.label":"Missing key hint","field.noKeyHint.note":"Shown when an API key is missing, pointing to where it goes.","field.balanceError.label":"Balance update error","field.balanceError.note":"Shown when balance update fails.","field.usageError.label":"Usage update error","field.usageError.note":"Shown when spend data is temporarily unavailable.","field.refreshFailure.label":"Update error","field.refreshFailure.note":"Shown when any data refresh fails.","field.persistWarning.label":"Unsaved record alert","field.persistWarning.note":"Shown when billing records cannot be saved; recommended.","field.updateNotice.label":"Update notice","field.updateNotice.note":"Shows a short marker when a new version is ready, or a downloaded version is waiting for a restart.","field.updateFailure.label":"Update failure notice","field.updateFailure.note":"Shows a short marker when the automatic update failed.","group.native":"Native information","group.plugin":"Plugin information","group.notice":"Notices","group.native.desc":"Fields the DSH bar already had. They live in the native stats row, which only Full mode shows.","group.plugin.desc":"Fields this plugin adds, the adopted context ring included. They live in the main row, shown in both modes.","group.notice.desc":"One-off notices such as updates and failures. They appear whenever there is really something to say, whatever the mode.","section.identity.label":"Provider and model","section.identity.desc":"Shown whatever you pay with: which service and model this conversation runs on.","section.subscription.label":"Subscription: monthly plan, quota included","section.subscription.desc":"A plan like ChatGPT only fills the items below: quota windows, quota reset, expiry date and available balance.","section.balance.label":"Prepaid balance: top up, then usage is deducted","section.balance.desc":"These providers only fill the items below: balance, session spend, current period and next price change.","section.billing.label":"Billed usage: use first, invoiced monthly","section.billing.desc":"These providers only fill the items below: this month's usage, budget and free allowance.","section.common.label":"General items","section.common.desc":"Nothing to do with billing, useful on any provider: custom text, clocks, context usage.","ui.listSeparator":", ","ui.sentenceEnd":".","ui.fieldErrorPrefix":"\"{label}\": ","ui.turnCount":"{count} turn","ui.turnCountPlural":"{count} turns","ui.stepCount":"{count} step","ui.stepCountPlural":"{count} steps","ui.mainTimeZone":"Main time zone","ui.worldTimeZone":"World time zone","ui.customTextTitle":"Custom text","ui.customTextPlaceholder":"Enter text (up to 64 characters)","ui.searchPlaceholder":"Search by name or description…","ui.searchFieldsLabel":"Search visible content","ui.searchResultCount":"{count} found","ui.enabledFieldsCount":"{count} enabled","ui.noSearchResults":"No matching settings found","ui.mainTime":"Main time","ui.worldTime":"World time","ui.customText":"Custom text"}};
|
|
108
108
|
let t;
|
|
109
109
|
let localeService;
|
|
110
110
|
// 文案取值(跟随宿主界面语言):优先 DSH 的 locale 服务;服务缺席、未授权或 bind 失效时
|
|
@@ -632,6 +632,25 @@ function infoBarShouldRemoveAll(registry, isVisible) {
|
|
|
632
632
|
return registry.length > 0;
|
|
633
633
|
}
|
|
634
634
|
|
|
635
|
+
// 余额悬停明细(2026-10-07 用户拍板):底栏只放得下一个总数,但用户想知道其中「充的钱」与
|
|
636
|
+
// 「送的钱」各是多少 —— 两者的来源与规则不同,并成一个数就分不清了。
|
|
637
|
+
// 文案与 DSH 设置页逐字对齐(充值余额 / 赠金余额,见 src/locales.js):宿主已经这么叫,
|
|
638
|
+
// 插件换一套说法只会让同一个数在同一个界面上有两个名字。
|
|
639
|
+
// 展开条件只有一条「赠金为正」:
|
|
640
|
+
// · 赠金为 0 时(大多数服务商没有赠金概念)多出来的两行只是把同一个数字说三遍;
|
|
641
|
+
// · 首行直接沿用调用方给的既有文案,不展开时与老版本逐字一致 —— 零回归。
|
|
642
|
+
// 金额取不到(老快照 / 非数字形态)按 0 处理:宁可少显示一行明细,也不猜一个数。
|
|
643
|
+
function balanceHoverLines(baseTitle, data, symbol, translate, format) {
|
|
644
|
+
const lines = [baseTitle];
|
|
645
|
+
if (!data || typeof data !== 'object') return lines;
|
|
646
|
+
const granted = typeof data.granted === 'number' && isFinite(data.granted) ? data.granted : 0;
|
|
647
|
+
if (!(granted > 0)) return lines;
|
|
648
|
+
const toppedUp = typeof data.toppedUp === 'number' && isFinite(data.toppedUp) ? data.toppedUp : 0;
|
|
649
|
+
lines.push(translate('ui.balanceDetailToppedUp', { symbol: symbol, value: format(toppedUp) }));
|
|
650
|
+
lines.push(translate('ui.balanceDetailGranted', { symbol: symbol, value: format(granted) }));
|
|
651
|
+
return lines;
|
|
652
|
+
}
|
|
653
|
+
|
|
635
654
|
// 两处样式安装函数各自先探 DOM(无 DOM 的宿主启动路径上直接返回空 disposer,绝不抛):
|
|
636
655
|
// 有意各写一遍而不抽 helper——两个函数都会被测试单独抽出求值(installStyles 走切片、
|
|
637
656
|
// bibSetInstallStyles 走单函数抽取),helper 在抽离求值时不可见(localizeHostText 自包含原则);
|
|
@@ -3603,8 +3622,11 @@ module.exports = {
|
|
|
3603
3622
|
const balTitle = bal.estimate
|
|
3604
3623
|
? t('ui.estimatedBalance', { symbol: symbol, value: fmt(bal.data.total) })
|
|
3605
3624
|
: t('ui.balance', { symbol: symbol, value: fmt(bal.data.total) });
|
|
3625
|
+
// 悬停明细:赠金为正时在总计下面补「充值余额 / 赠金余额」两行(2026-10-07 拍板)。
|
|
3626
|
+
// 原生 title 里的换行符由浏览器渲染成多行;不展开时与老版本逐字一致。
|
|
3627
|
+
const balHoverTitle = balanceHoverLines(balTitle, bal.data, symbol, t, fmt).join('\n');
|
|
3606
3628
|
if (fieldVisible('balance')) {
|
|
3607
|
-
groups.push(fieldSpan('balance', 'bal', React.createElement('span', { title:
|
|
3629
|
+
groups.push(fieldSpan('balance', 'bal', React.createElement('span', { title: balHoverTitle },
|
|
3608
3630
|
metric(t('ui.balance.pushBalanceGroups'), symbol + fmt(bal.data.total), alertActive ? 'bi-alert-num' : ''),
|
|
3609
3631
|
alertActive ? React.createElement('span', { className: 'bi-low-status' }, t('ui.low')) : null,
|
|
3610
3632
|
bal.estimate ? React.createElement('span', { className: 'bi-muted' }, t('ui.estimated')) : null,
|
|
@@ -3666,14 +3688,23 @@ module.exports = {
|
|
|
3666
3688
|
const costCNY = cs && cs.costs && cs.costs.CNY != null ? cs.costs.CNY : null;
|
|
3667
3689
|
const costUSD = cs && cs.costs && cs.costs.USD != null ? cs.costs.USD : null;
|
|
3668
3690
|
const symbol = usdSymbol ? '$' : '¥';
|
|
3669
|
-
const
|
|
3670
|
-
|
|
3691
|
+
const priced = costCNY != null || costUSD != null;
|
|
3692
|
+
const unpricedRecords = cs && cs.unpricedRecords ? cs.unpricedRecords : 0;
|
|
3693
|
+
// 有 token 但一条都没定价 → 绝不用 ¥0.000 冒充“没有花费”(审计 2026-10-05):
|
|
3694
|
+
// 未收录模型只记账、不猜价,界面必须直说“暂不可计算”;部分未计价则前缀 ≈。
|
|
3695
|
+
const hasTokens = !!(cs && cs.tokens > 0);
|
|
3696
|
+
const costTxt = priced
|
|
3697
|
+
? (unpricedRecords > 0 ? '≈' : '') + (costCNY != null ? '¥' + costCNY.toFixed(3) : '$' + costUSD.toFixed(3))
|
|
3698
|
+
: (hasTokens ? symbol + '—' : symbol + (0).toFixed(3));
|
|
3671
3699
|
const today = usg.todaySpend != null ? t('ui.today', { symbol: symbol, value: fmt(usg.todaySpend, 3) }) : '';
|
|
3672
3700
|
const month = usg.monthSpend != null ? t('ui.lastDays', { symbol: symbol, value: fmt(usg.monthSpend, 3) }) : '';
|
|
3673
3701
|
const total = usg.totalSpend != null ? t('ui.allTime', { symbol: symbol, value: fmt(usg.totalSpend, 3) }) : '';
|
|
3674
3702
|
const detail = [today, month, total].filter(function (s) { return s.length > 0; }).join(' · ');
|
|
3703
|
+
const costTitle = [t('ui.sessionIncludingSubagents', { costTxt: costTxt, value: detail ? '\n' + detail : '' })];
|
|
3704
|
+
if (!priced && hasTokens) costTitle.push(t('ui.pricingNotListedUsingDefaults'));
|
|
3705
|
+
else if (priced && unpricedRecords > 0) costTitle.push(t('ui.spendPartlyUnpriced'));
|
|
3675
3706
|
groups.push(fieldSpan('sessionCost', 'convo', React.createElement('span', {
|
|
3676
|
-
title:
|
|
3707
|
+
title: costTitle.join('\n') },
|
|
3677
3708
|
metric(t('ui.session'), costTxt))));
|
|
3678
3709
|
}
|
|
3679
3710
|
} else if (errs.usage && fieldVisible('usageError')) {
|
|
@@ -3996,7 +4027,9 @@ module.exports = {
|
|
|
3996
4027
|
if (statsProj) {
|
|
3997
4028
|
// 每组:{ nodes: React 节点数组(数字用 num 加粗), text: 纯文本(title 用), fieldId: 字段 id(着色用) }
|
|
3998
4029
|
const ng = [];
|
|
3999
|
-
|
|
4030
|
+
// title:可选的原生悬浮说明。整行已有 title(nativeLine),组级 title 让每个指标
|
|
4031
|
+
// 能自带口径说明(例如“缓存命中”按 token 计、只含主 Agent),浏览器悬停取最内层。
|
|
4032
|
+
function group(parts, hidden, fieldId, title) {
|
|
4000
4033
|
const nodesArr = [];
|
|
4001
4034
|
const texts = [];
|
|
4002
4035
|
function textOf(part) {
|
|
@@ -4012,7 +4045,7 @@ module.exports = {
|
|
|
4012
4045
|
else if (Array.isArray(p)) { for (let j = 0; j < p.length; j++) nodesArr.push(p[j]); texts.push(textOf(p)); }
|
|
4013
4046
|
else { nodesArr.push(p); texts.push(textOf(p)); }
|
|
4014
4047
|
}
|
|
4015
|
-
ng.push({ nodes: nodesArr, text: texts.join(''), hidden: !!hidden, fieldId: fieldId || null });
|
|
4048
|
+
ng.push({ nodes: nodesArr, text: texts.join(''), hidden: !!hidden, fieldId: fieldId || null, title: title || null });
|
|
4016
4049
|
}
|
|
4017
4050
|
|
|
4018
4051
|
// v1.9.0 PR2:原生统计行字段按设置过滤(隐藏组完全不进 ng,不占版式也不进 title)
|
|
@@ -4038,10 +4071,19 @@ module.exports = {
|
|
|
4038
4071
|
|
|
4039
4072
|
if (usageProj && (billedInput(usageProj) > 0 || (usageProj.outputTokens || 0) > 0)) {
|
|
4040
4073
|
const denom = billedInput(usageProj);
|
|
4041
|
-
const
|
|
4042
|
-
|
|
4074
|
+
const cacheReadTokens = usageProj.cacheReadTokens || 0;
|
|
4075
|
+
// 一位小数(审计 2026-10-05):99.6% 过去被四舍五入成“100%”,用户会误以为缓存全命中、
|
|
4076
|
+
// 输入几乎免费。100% 只能意味着未命中为 0,否则必须把小数露出来。
|
|
4077
|
+
const hit = denom > 0 ? Math.round((cacheReadTokens / denom) * 1000) / 10 : null;
|
|
4078
|
+
if (hit != null && fieldVisible('cacheHit')) {
|
|
4079
|
+
group([metric(t('ui.cacheHit'), hit + '%')], false, 'cacheHit', t('ui.cacheHitScope', {
|
|
4080
|
+
hit: formatTokens(cacheReadTokens),
|
|
4081
|
+
miss: formatTokens(Math.max(0, denom - cacheReadTokens)),
|
|
4082
|
+
percent: hit,
|
|
4083
|
+
}));
|
|
4084
|
+
}
|
|
4043
4085
|
if (fieldVisible('tokensIO')) {
|
|
4044
|
-
group([metric(t('ui.input.BottomInfoBar'), formatTokens(billedInput(usageProj)) + ' tok'), ' · ', metric(t('ui.output'), formatTokens(usageProj.outputTokens || 0) + ' tok')], false, 'tokensIO');
|
|
4086
|
+
group([metric(t('ui.input.BottomInfoBar'), formatTokens(billedInput(usageProj)) + ' tok'), ' · ', metric(t('ui.output'), formatTokens(usageProj.outputTokens || 0) + ' tok')], false, 'tokensIO', t('ui.tokenScope'));
|
|
4045
4087
|
}
|
|
4046
4088
|
}
|
|
4047
4089
|
|
|
@@ -4056,6 +4098,7 @@ module.exports = {
|
|
|
4056
4098
|
key: 'ng' + i,
|
|
4057
4099
|
'data-field': ng[i].fieldId || undefined,
|
|
4058
4100
|
style: ng[i].fieldId ? fieldStyle(ng[i].fieldId) : undefined,
|
|
4101
|
+
title: ng[i].title || undefined,
|
|
4059
4102
|
}, ng[i].nodes));
|
|
4060
4103
|
}
|
|
4061
4104
|
// D6:原生组全部被隐藏(或全空)→ 原生行不渲染(不留空行/占位;hover 浮窗随之消失)
|
package/lib/index.js
CHANGED
|
@@ -1947,7 +1947,16 @@ export default {
|
|
|
1947
1947
|
return sessionLineageCache.pending
|
|
1948
1948
|
}
|
|
1949
1949
|
|
|
1950
|
-
// ---------- 定价表(元/美元 · 百万 tokens
|
|
1950
|
+
// ---------- 定价表(元/美元 · 百万 tokens) ----------
|
|
1951
|
+
// 维护铁律(2026-10-05 计费审计):
|
|
1952
|
+
// ① 只有官方**已生效**的价目才能进表;预告、传闻、"计划中的迁移"一律不得改变计费;
|
|
1953
|
+
// ② 表里没有的模型一律记为 unpriced(cost=null),UI 显示"费用暂不可计算",
|
|
1954
|
+
// **绝不套用别的模型价格**;新增模型请附官方来源与获取日期;
|
|
1955
|
+
// ③ 改价必须同时更新 tests/test-billing-audit.mjs 里钉死的价目断言(改了会红)。
|
|
1956
|
+
// 来源(2026-10-05 复核):官方价格页 https://api-docs.deepseek.com/quick_start/pricing;
|
|
1957
|
+
// 峰谷公告:空闲价 = 高峰价一半,高峰为北京时间周一至周五 09:00–12:00 / 14:00–18:00,
|
|
1958
|
+
// 2026-08-17 00:00 生效(https://www.cnfin.com/kx/detail/20260813/4454952_1.html);
|
|
1959
|
+
// 周末全天空闲 2026-08-23 起;Flash 降价(命中 0.02 / 输出 4)2026-09-10 12:00 起。
|
|
1951
1960
|
const PRICING = {
|
|
1952
1961
|
// DeepSeek 官方模型 & 价格页:deepseek-flash = DeepSeek-V4.1-Flash。
|
|
1953
1962
|
// CNY/百万 tokens;工作日北京时间 09:00–12:00、14:00–18:00 为高峰,其余为空闲。
|
|
@@ -3425,24 +3434,22 @@ export default {
|
|
|
3425
3434
|
// 价目键解析:优先"服务商:模型"作用域键(解决同名模型跨计费域价格/币种不同的问题,
|
|
3426
3435
|
// 如 Kimi 同一型号在 api.moonshot.cn=¥ 与 api.moonshot.ai=$ 两套价);
|
|
3427
3436
|
// 无作用域键时回退裸模型键。远程目录可下发任意一种形态。
|
|
3428
|
-
//
|
|
3429
|
-
//
|
|
3430
|
-
|
|
3431
|
-
|
|
3437
|
+
// 审计修正(2026-10-05):本函数曾按官方**预告**把 deepseek-v4-pro 在
|
|
3438
|
+
// 北京时间 2026-09-14 12:00 之后重定向到 deepseek-flash 价目。DeepSeek 随后(2026-09-13/14)
|
|
3439
|
+
// 改口:V4 Pro 继续提供、计费方式不变。留着这条重定向会让 Pro 用量按 Flash 价少算
|
|
3440
|
+
// (空闲价 miss 4.5×、cacheHit 7.5×、output 3.375×),故删除。
|
|
3441
|
+
// 铁律:只有官方**已生效**的价目才进 PRICING;预测性路由不得改变计费。
|
|
3442
|
+
function pricingEntryFor(provider, model) {
|
|
3432
3443
|
const scopedKey = provider + ':' + model;
|
|
3433
3444
|
const scoped = Object.hasOwn(PRICING, scopedKey) ? PRICING[scopedKey] : null;
|
|
3434
|
-
|
|
3445
|
+
return scoped && typeof scoped === 'object'
|
|
3435
3446
|
? scoped
|
|
3436
3447
|
: (Object.hasOwn(PRICING, model) ? PRICING[model] : null);
|
|
3437
|
-
if (model === 'deepseek-v4-pro' && Number.isFinite(atMs) && atMs >= DEEPSEEK_V4_PRO_FLASH_EFFECTIVE_AT) {
|
|
3438
|
-
return Object.hasOwn(PRICING, 'deepseek-flash') ? PRICING['deepseek-flash'] : null;
|
|
3439
|
-
}
|
|
3440
|
-
return entry;
|
|
3441
3448
|
}
|
|
3442
3449
|
|
|
3443
3450
|
function computePricing(nowMs, selection) {
|
|
3444
3451
|
const sel = selection || modelSelection();
|
|
3445
|
-
const entry = pricingEntryFor(sel.provider, sel.model
|
|
3452
|
+
const entry = pricingEntryFor(sel.provider, sel.model);
|
|
3446
3453
|
const period = entry && entry.mode === 'peak-valley' ? currentPeriod(nowMs) : 'flat';
|
|
3447
3454
|
let prices = null;
|
|
3448
3455
|
if (entry) {
|
|
@@ -3619,6 +3626,12 @@ export default {
|
|
|
3619
3626
|
return Number.isFinite(record.cost) && record.cost >= 0;
|
|
3620
3627
|
}
|
|
3621
3628
|
|
|
3629
|
+
// 一条记录的全部 token(未命中输入 + 缓存读写 + 输出)。只用于"未计价用量"归因展示,
|
|
3630
|
+
// 绝不参与计费,也不写回任何金额。
|
|
3631
|
+
function recordTokens(record) {
|
|
3632
|
+
return record.input + record.cacheRead + record.cacheWrite + record.output;
|
|
3633
|
+
}
|
|
3634
|
+
|
|
3622
3635
|
// 无 sessionId 的记录沿用 provider/model#ts 兜底键(与旧 sessionTotals 的 Map 键一致)
|
|
3623
3636
|
function sessionIndexKey(record) {
|
|
3624
3637
|
const account = accountBucketKey(recordAccount(record));
|
|
@@ -3655,6 +3668,9 @@ export default {
|
|
|
3655
3668
|
account: recordAccount(record),
|
|
3656
3669
|
input: 0, cacheRead: 0, cacheWrite: 0, output: 0,
|
|
3657
3670
|
costs: {},
|
|
3671
|
+
// 未计价记录(价目表没有该模型)单独计数:本会话花费必须能说清
|
|
3672
|
+
// 「这些 token 为什么没算钱」,而不是显示成 ¥0.000(审计 2026-10-05)。
|
|
3673
|
+
unpricedRecords: 0, unpricedTokens: 0,
|
|
3658
3674
|
minTs: record.ts,
|
|
3659
3675
|
maxTs: record.ts,
|
|
3660
3676
|
};
|
|
@@ -3668,6 +3684,9 @@ export default {
|
|
|
3668
3684
|
if (cost != null) {
|
|
3669
3685
|
const cur = recordCurrency(record);
|
|
3670
3686
|
entry.costs[cur] = (entry.costs[cur] || 0) + cost;
|
|
3687
|
+
} else {
|
|
3688
|
+
entry.unpricedRecords = (entry.unpricedRecords || 0) + 1;
|
|
3689
|
+
entry.unpricedTokens = (entry.unpricedTokens || 0) + recordTokens(record);
|
|
3671
3690
|
}
|
|
3672
3691
|
if (record.ts < entry.minTs) entry.minTs = record.ts;
|
|
3673
3692
|
if (record.ts > entry.maxTs) entry.maxTs = record.ts;
|
|
@@ -3708,6 +3727,11 @@ export default {
|
|
|
3708
3727
|
if (entry) {
|
|
3709
3728
|
const cur = recordCurrency(record);
|
|
3710
3729
|
entry.costs[cur] = (entry.costs[cur] || 0) + cost;
|
|
3730
|
+
// 补算成功:这条记录从"未计价"移到"已计价",否则 UI 会一直显示"部分未计价"
|
|
3731
|
+
if (entry.unpricedRecords > 0) {
|
|
3732
|
+
entry.unpricedRecords -= 1;
|
|
3733
|
+
entry.unpricedTokens = Math.max(0, (entry.unpricedTokens || 0) - recordTokens(record));
|
|
3734
|
+
}
|
|
3711
3735
|
}
|
|
3712
3736
|
const key = accountBucketKey(recordAccount(record));
|
|
3713
3737
|
summariesState.accountTotals[key] = (summariesState.accountTotals[key] || 0) + cost;
|
|
@@ -3760,6 +3784,9 @@ export default {
|
|
|
3760
3784
|
cacheWrite: Number(entry.cacheWrite) || 0,
|
|
3761
3785
|
output: Number(entry.output) || 0,
|
|
3762
3786
|
costs: Object.assign({}, entry.costs && typeof entry.costs === 'object' ? entry.costs : {}),
|
|
3787
|
+
// 旧版汇总文件没有这两个字段 → 0;unpriced 明细永不折叠,重启后由明细侧重建
|
|
3788
|
+
unpricedRecords: Number(entry.unpricedRecords) || 0,
|
|
3789
|
+
unpricedTokens: Number(entry.unpricedTokens) || 0,
|
|
3763
3790
|
minTs: Number(entry.minTs) || 0,
|
|
3764
3791
|
maxTs: Number(entry.maxTs) || 0,
|
|
3765
3792
|
};
|
|
@@ -4301,7 +4328,7 @@ export default {
|
|
|
4301
4328
|
// v2 ledger records carry the charge as observed. Use it for normal
|
|
4302
4329
|
// reporting; only the "all-offpeak" forecast intentionally recalculates.
|
|
4303
4330
|
if (!forceOffpeak && Number.isFinite(record.cost) && record.cost >= 0) return record.cost;
|
|
4304
|
-
const entry = pricingEntryFor(record.provider, record.model
|
|
4331
|
+
const entry = pricingEntryFor(record.provider, record.model);
|
|
4305
4332
|
if (!entry) return null;
|
|
4306
4333
|
let p;
|
|
4307
4334
|
if (entry.mode === 'peak-valley') {
|
|
@@ -4374,7 +4401,7 @@ export default {
|
|
|
4374
4401
|
warnSessionLineageUnavailable(err);
|
|
4375
4402
|
}
|
|
4376
4403
|
const ownedSessionIds = lineageItems ? sessionLineageIds(lineageItems, norm) : new Set([norm]);
|
|
4377
|
-
const acc = { input: 0, cacheRead: 0, cacheWrite: 0, output: 0, costs: {} };
|
|
4404
|
+
const acc = { input: 0, cacheRead: 0, cacheWrite: 0, output: 0, costs: {}, unpricedRecords: 0, unpricedTokens: 0 };
|
|
4378
4405
|
let matched = false;
|
|
4379
4406
|
for (const key of Object.keys(summariesState.sessions)) {
|
|
4380
4407
|
const entry = summariesState.sessions[key];
|
|
@@ -4385,6 +4412,8 @@ export default {
|
|
|
4385
4412
|
acc.cacheRead += entry.cacheRead;
|
|
4386
4413
|
acc.cacheWrite += entry.cacheWrite;
|
|
4387
4414
|
acc.output += entry.output;
|
|
4415
|
+
acc.unpricedRecords += entry.unpricedRecords || 0;
|
|
4416
|
+
acc.unpricedTokens += entry.unpricedTokens || 0;
|
|
4388
4417
|
for (const currency of Object.keys(entry.costs || {})) {
|
|
4389
4418
|
acc.costs[currency] = (acc.costs[currency] || 0) + (Number(entry.costs[currency]) || 0);
|
|
4390
4419
|
}
|
|
@@ -4398,6 +4427,11 @@ export default {
|
|
|
4398
4427
|
output: acc.output,
|
|
4399
4428
|
tokens: acc.input + acc.cacheRead + acc.cacheWrite + acc.output,
|
|
4400
4429
|
costs: acc.costs || {},
|
|
4430
|
+
// 未计价记录数与 token 数:客户端据此显示"费用暂不可计算",绝不把 0 当成真实花费
|
|
4431
|
+
unpricedRecords: acc.unpricedRecords,
|
|
4432
|
+
unpricedTokens: acc.unpricedTokens,
|
|
4433
|
+
// 按 token 计的缓存读取占比(一位小数)。注意口径:本字段覆盖当前会话**及其子代理**
|
|
4434
|
+
// (谱系合计),而底栏顶部那行"缓存命中"来自 DSH 原生 tokenUsage 投影(仅主 Agent)。
|
|
4401
4435
|
hitRate: denom > 0 ? Math.round((acc.cacheRead / denom) * 1000) / 10 : null,
|
|
4402
4436
|
};
|
|
4403
4437
|
}
|
package/lib/locales.js
CHANGED
|
@@ -118,6 +118,8 @@ export const LOCALES = {
|
|
|
118
118
|
"ui.accountSignedOutHow": "在 DSH 的「设置 → 账户」里登录 DeepSeek 账号,这里就会显示余额。",
|
|
119
119
|
"ui.estimatedBalance": "估算余额:{symbol}{value}",
|
|
120
120
|
"ui.balance": "余额:{symbol}{value}",
|
|
121
|
+
"ui.balanceDetailToppedUp": "充值余额:{symbol}{value}",
|
|
122
|
+
"ui.balanceDetailGranted": "赠金余额:{symbol}{value}",
|
|
121
123
|
"ui.balance.pushBalanceGroups": "余额",
|
|
122
124
|
"ui.low": "低",
|
|
123
125
|
"ui.estimated": "(估算)",
|
|
@@ -232,6 +234,9 @@ export const LOCALES = {
|
|
|
232
234
|
"ui.tools": "工具调用",
|
|
233
235
|
"ui.avgTTFT": "首 token 平均",
|
|
234
236
|
"ui.cacheHit": "缓存命中",
|
|
237
|
+
"ui.cacheHitScope": "按 token 计:命中 {hit} / 未命中 {miss}({percent}% 命中)。\n口径:当前会话主 Agent 的模型调用,不含子代理。",
|
|
238
|
+
"ui.tokenScope": "输入 / 输出是本会话主 Agent 的模型调用累计,不含子代理;右侧『本会话』花费含子代理。",
|
|
239
|
+
"ui.spendPartlyUnpriced": "其中部分调用尚未收录价格(绝不套用其他模型价格估算),实际花费高于此处显示值。",
|
|
235
240
|
"ui.input.BottomInfoBar": "输入",
|
|
236
241
|
"ui.output": "输出",
|
|
237
242
|
"ui.savingView": "正在保存切换…",
|
|
@@ -529,6 +534,8 @@ export const LOCALES = {
|
|
|
529
534
|
"ui.accountSignedOutHow": "Sign in to your DeepSeek account in DSH settings, Account, and the balance will appear here.",
|
|
530
535
|
"ui.estimatedBalance": "Estimated balance: {symbol}{value}",
|
|
531
536
|
"ui.balance": "Balance: {symbol}{value}",
|
|
537
|
+
"ui.balanceDetailToppedUp": "Topped-up balance: {symbol}{value}",
|
|
538
|
+
"ui.balanceDetailGranted": "Granted balance: {symbol}{value}",
|
|
532
539
|
"ui.balance.pushBalanceGroups": "Balance",
|
|
533
540
|
"ui.low": "Low",
|
|
534
541
|
"ui.estimated": "(estimated)",
|
|
@@ -643,6 +650,9 @@ export const LOCALES = {
|
|
|
643
650
|
"ui.tools": "Tools",
|
|
644
651
|
"ui.avgTTFT": "Avg. TTFT",
|
|
645
652
|
"ui.cacheHit": "Cache hit",
|
|
653
|
+
"ui.cacheHitScope": "By token: {hit} hit / {miss} miss ({percent}% hit).\nScope: this session's main Agent only, subagents excluded.",
|
|
654
|
+
"ui.tokenScope": "Input/output accumulate this session's main Agent only (subagents excluded); Session cost includes subagents.",
|
|
655
|
+
"ui.spendPartlyUnpriced": "Some calls have no listed price (no other model's price is substituted); the real cost is higher than shown.",
|
|
646
656
|
"ui.input.BottomInfoBar": "Input",
|
|
647
657
|
"ui.output": "Output",
|
|
648
658
|
"ui.savingView": "Saving view…",
|