news 2026/9/13 18:29:54

CodexBar Neuralwatt Provider 接入指南:基于 API Key 的订阅 kWh 与预付费余额配额解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
CodexBar Neuralwatt Provider 接入指南:基于 API Key 的订阅 kWh 与预付费余额配额解析

CodexBar Neuralwatt Provider 接入指南:基于 API Key 的订阅 kWh 与预付费余额配额解析

【免费下载链接】CodexBarShow usage stats for OpenAI Codex and Claude Code, without having to login.项目地址: https://gitcode.com/GitHub_Trending/co/CodexBar

Neuralwatt 是 CodexBar 中一个通过 API Key 读取账户配额的使用量数据源。Neuralwatt Cloud 采用基于能耗(energy-based)的定价模型,配额接口同时暴露"订阅 kWh 用量"与"预付费 USD 余额"两套计费表面。本文基于仓库中的 docs/neuralwatt.md 及对应源码实现,完整说明该 Provider 的接入方式、配额 API 协议、字段解析逻辑、重试机制与故障排查方法,帮助你理解并复用这套配额读取方案。

Neuralwatt 的计费模型与三类配额表面

Neuralwatt Cloud 是一个 OpenAI 兼容的推理 API,但其定价按能耗(kWh)计费,与常见的按 token 计费模型不同。从文档与源码看,一个账户下存在三个相互独立的配额表面:

配额表面关键字段计费行为在 CodexBar 中的呈现
订阅 kWh 用量kwh_used/kwh_included按计费周期结算,周期结束时重置主配额窗口(primary),重置日期为订阅周期结束日
预付费 USD 余额credits_remaining_usd/total_credits_usd随用随扣,不随计费周期重置,通过充值补充独立的 pay-as-you-go 余额展示
按密钥消费限额spent_usd/limit_usd可选配置,按key.allowance.period(如 monthly)统计额外的配额窗口(extraRateWindow)

这种"订阅额度 + 预付费余额"的双轨结构在实现中体现得尤为明确:当订阅 kWh 仍可用而预付费余额为 0 时,CodexBar 不会把余额归零误判为配额耗尽(见下文源码分析)。

此外,配额接口还会返回当前自然月消费(usage.current_month.cost_usd),CodexBar 会解析它供后续/报表使用,但不作为可重置的配额窗口展示

快速接入:三种 API Key 配置方式

方式一:CLI(无需打开设置界面)

文档推荐直接通过codexbar命令写入密钥,适合脚本化部署:

printf '%s' "$NEURALWATT_API_KEY" | codexbar config set-api-key --provider neuralwatt --stdin

该命令的行为包括:

  • 修剪输入:管道传入的密钥首尾空白会被剔除(对应 NeuralWattSettingsReader.swift 中的cleaned(_:)实现,同时支持去除单双引号包裹);
  • 写入配置文件:默认写入~/.config/codexbar/config.json;若已存在旧版~/.codexbar/config.json则写入该旧路径;
  • 默认启用 Provider:如需只保存密钥而不启用,追加--no-enable参数。

方式二:设置界面

  1. 打开Settings → Providers
  2. 启用Neuralwatt
  3. 打开https://portal.neuralwatt.com/dashboard创建或复制 API Key
  4. 将密钥粘贴到 CodexBar 的 Neuralwatt Provider 设置中

设置界面中的密钥字段在 NeuralWattProviderImplementation.swift 中定义为 secure 类型(占位符sk-...),密钥存储在 CodexBar 配置文件中,同时支持在 CodexBar 中配置多个 Neuralwatt token 账户(见 NeuralWattProviderDescriptor.swift 中的TokenAccountSupport,其占位符同样为sk-...,最小刷新间隔为 1 秒,与配额接口限流对齐)。

方式三:环境变量

CodexBar 还支持通过环境变量注入:

  • NEURALWATT_API_KEY:API Key
  • NEURALWATT_API_URL:API 基础地址覆盖,用于测试或自建代理场景

值得注意的细节:NEURALWATT_API_URL并非无条件生效。从 NeuralWattSettingsReader.swift 源码可见,该覆盖值必须通过ProviderEndpointOverrideValidator.normalizedHTTPSURL校验,即只允许 HTTPS URL 或裸主机名;非法覆盖会抛出NeuralWattSettingsError.invalidEndpointOverride,且该校验发生在发起任何请求之前(对应测试fetch rejects endpoint override before sending API key,见 NeuralWattUsageFetcherTests.swift)。

配额 API 协议与响应字段详解

请求协议

  • 端点GET https://api.neuralwatt.com/v1/quota
  • 认证头Authorization: Bearer sk-...
  • 请求头Accept: application/json
  • 超时:15 秒(见 NeuralWattUsageFetcher.swift 中timeoutSeconds

从 NeuralWattUsageFetcher.swift 的quotaURL(baseURL:)逻辑看,若基础地址已以v1结尾则直接拼接quota,否则拼接v1/quota,这保证了NEURALWATT_API_URL指向任意层级地址时都能得到正确的配额路径。

响应字段与用途

文档明确列出 CodexBar 实际使用的字段,结合源码模型(NeuralWattQuotaResponse及其子结构)可整理如下:

字段路径类型用途
balance.credits_remaining_usdDouble?预付费余额剩余
balance.total_credits_usdDouble?预付费余额总额
balance.credits_used_usdDouble?预付费已用;API 缺省时由 total − remaining 推导
balance.accounting_methodString?计费方式(Token/Energy),用于身份标签兜底
usage.current_month.cost_usdDouble?当前自然月消费(仅解析,不展示为重置窗口)
usage.current_month.energy_kwhDouble?当前自然月能耗
subscription.planString?订阅计划名,作为身份标签主来源
subscription.current_period_endDate?订阅周期结束,即配额重置时间
subscription.kwh_includedDouble?周期内含 kWh 额度
subscription.kwh_usedDouble?周期内已用 kWh
subscription.kwh_remainingDouble?周期内剩余 kWh
key.allowance.limit_usdDouble?按密钥限额上限
key.allowance.spent_usdDouble?按密钥已消费
key.allowance.periodString?限额周期(如monthly),用于窗口标题

测试夹具 NeuralWattUsageFetcherTests.swift 给出了一个完整的响应示例,可直接用于对照验证:

{ "snapshot_at": "2026-04-16T18:30:00Z", "balance": { "credits_remaining_usd": 32.6774, "total_credits_usd": 52.34, "credits_used_usd": 19.6626, "accounting_method": "energy" }, "usage": { "lifetime": { "cost_usd": 243.9145, "requests": 37801, "tokens": 1235477176, "energy_kwh": 15.6009 }, "current_month": { "cost_usd": 160.1463, "requests": 23902, "tokens": 1116658995, "energy_kwh": 9.7278 } }, "limits": { "overage_limit_usd": null, "rate_limit_tier": "standard" }, "subscription": { "plan": "standard", "status": "active", "billing_interval": "month", "current_period_start": "2026-04-11T05:05:25Z", "current_period_end": "2026-05-11T05:05:25Z", "auto_renew": true, "kwh_included": 20.0, "kwh_used": 13.9023, "kwh_remaining": 6.0977, "in_overage": false }, "key": { "name": "my-production-key", "allowance": { "limit_usd": 50.0, "period": "monthly", "spent_usd": 12.5, "remaining_usd": 37.5, "blocked": false } } }

对应测试断言:主配额窗口百分比为13.9023 / 20 × 100,重置描述为"13.90 / 20 kWh",预付费余额作为providerCost展示,密钥限额窗口标题为"Key Monthly",且不会出现"current-month-spend"窗口——印证了"当月消费仅解析不展示"的设计。

源码级解析:快照计算与边界处理

缺失字段的推导

credits_used_usd可能被 API 省略,此时 CodexBar 按total − remaining推导。更细致的是NeuralWattUsageSnapshot中的effectiveUsedCredits/effectiveTotalCredits/effectiveRemainingCredits三套有效值逻辑(见 NeuralWattUsageFetcher.swift):

  • 直接字段有效时优先使用;
  • 否则由其余两个字段互相推导;
  • 所有数值必须通过validNonNegative(有限且 ≥ 0)或validPositive(有限且 > 0)校验,非法值(NaN、无穷、负数)一律视为缺失,避免污染计算。

对应测试parses response with missing credits used derived from remaining验证了remaining=30, total=100时推导出used=70、百分比 70%。

预付费余额归零 ≠ 订阅耗尽

代码中有一个值得注意的防御:hasKnownZeroRemainingBalance在"余额明确为 0 且总额未知"时将creditUsedPercent置为 100%,但同时余额与订阅是两个独立对象。测试zero prepaid balance does not exhaust active subscription证明:余额为 0 时,订阅窗口照常按2.50 / 10 kWh(25%)展示,预付费余额单独显示$0.00,二者互不干扰。

订阅窗口与身份标签

订阅窗口(subscriptionRateWindow)由kwh_used / kwh_included计算百分比,current_period_end作为resetsAt,重置描述格式化为"已用 / 总量 kWh"(kWh 数值按整数舍入规则最多保留两位小数)。窗口时长(windowMinutes)由current_period_startcurrent_period_end差值计算。

身份标签(displayLoginMethod)的优先级为:

  1. subscription.plan非空时使用,如pro_energy显示为"Pro Energy plan"(下划线转空格并首字母大写);
  2. 否则回退到accounting_method,如energy显示为"Energy"
  3. 两者皆缺则无标签。

测试parses response with null subscription using accounting method验证了订阅为null时的回退行为:此时主窗口为nil、无续订日期,仅剩预付费余额与身份标签。

按密钥限额窗口

key.allowance存在且limit_usd > 0时生成一个extraRateWindow,标题按period生成(如monthly"Key Monthly")。特殊场景:当密钥被标记blocked: true且没有数值限额时,窗口百分比直接取 100%(测试blocked key allowance is exhausted without numeric limit验证),提示用户该密钥已不可用。

日期解析

订阅周期时间戳使用自定义 ISO8601 解码(decodeISO8601Date),同时兼容带与不带小数秒两种格式(测试parses fractional subscription dates覆盖了2026-04-11T05:05:25.123Z这类带毫秒的时间戳)。

重试、限流与"为何用原生 fetcher"

瞬态失败重试一次

配额接口可能出现 503 等瞬态错误。CodexBar 对 Neuralwatt 使用ProviderHTTPRetryPolicy.transientIdempotent(即maxRetries: 1),可重试状态码集合为{408, 429, 500, 502, 503, 504},URL 层错误(超时、连接丢失、无法连接主机、DNS 失败等)同样可重试(见 ProviderHTTPClient.swift)。

测试fetch retries transient quota failure[503, 200]状态序列验证:最终成功取数且请求总数为 2,证明重试确实发生。

Retry-After 处理

重试延迟计算(delaySeconds(attempt:response:))会优先读取响应头的Retry-After秒数,并封顶在maxDelaySeconds(默认 10 秒);无该头时按指数退避(baseDelaySeconds × 2^attempt,默认基数为 1 秒)。这一点正是文档强调"原生 fetcher 保持权威地位"的原因:当前插件 HTTP API 没有重试策略或 sleep 能力,无法表达这种带延迟的重试行为,因此 Neuralwatt 用量读取只能走原生实现(NeuralWattUsageFetcher.swift)。

每秒 1 次限流

配额端点的限流为每个客户每秒 1 次请求。CodexBar 按正常刷新周期拉取,实际不会触及该限制;多账户场景下,TokenAccountSupport将账户刷新最小间隔设为 1 秒,测试 UsageStoreNeuralWattAccountRefreshTests.swift 专门验证了多账户刷新遵守这一限流节奏。

HTTP 错误映射

  • 200:解析成功;
  • 401 / 403:映射为missingCredentials("Missing Neuralwatt API key"),测试unauthorized fetch throws missing credentials以 401 响应验证;
  • 其他状态码:映射为apiError("HTTP xxx")
  • 取消(CancellationError/URLError.cancelled):原样透传,转化为 Provider 错误,避免刷新取消被误报(测试fetch preserves transport cancellation验证)。

菜单卡片中的最终呈现

从 MenuCardNeuralWattTests.swift 可看到用户实际看到的形态:

  • 订阅窗口以标题"Subscription"展示,百分比 25%,详情"2.50 / 10 kWh",重置文案"Resets in 20d"
  • 预付费余额以独立的"Pay-as-you-go"卡片展示,文案为"Balance: $51.00"(标题与payAsYouGoBalance风格对应,见 NeuralWattProviderDescriptor.swift 的costPresenter);
  • 无订阅窗口时metrics为空,仅显示余额。

此外,Neuralwatt 的 Provider 元数据还定义了品牌色(绿色系#38D98C)、CLI 名称neuralwatt(别名nwneural)、仪表盘地址https://portal.neuralwatt.com/dashboard,以及"不支持 token 成本历史"(配额 API 不提供该数据)的说明。

故障排查

"Missing Neuralwatt API key"

按以下任一方式提供密钥即可:

  1. codexbar config set-api-key --provider neuralwatt --stdin
  2. Settings → Providers → Neuralwatt中粘贴
  3. 设置环境变量NEURALWATT_API_KEY
  4. 在 CodexBar 中配置 Neuralwatt token 账户

"Neuralwatt API error"

  • 确认 API Key 有效(401/403会先被映射为 missingCredentials,因此该错误通常意味着其他 HTTP 状态码,如 5xx);
  • 确认当前网络可访问api.neuralwatt.com
  • 注意配额端点限流为每客户每秒 1 次,CodexBar 正常刷新周期下不应触发,若自建脚本高频调用需自行限速;
  • 若使用NEURALWATT_API_URL覆盖地址,请确保其是 HTTPS URL 或裸主机名,否则会在发请求前被拒绝。

相关实现文件速览

  • 文档:docs/neuralwatt.md
  • 取数与快照计算:NeuralWattUsageFetcher.swift
  • 配置读取与环境变量:NeuralWattSettingsReader.swift
  • Provider 描述与元数据:NeuralWattProviderDescriptor.swift
  • 应用层实现(可用性判断、设置字段):NeuralWattProviderImplementation.swift
  • 重试策略与 Retry-After 处理:ProviderHTTPClient.swift
  • 解析与边界测试:NeuralWattUsageFetcherTests.swift
  • 菜单卡片呈现测试:MenuCardNeuralWattTests.swift
  • 多账户限流测试:UsageStoreNeuralWattAccountRefreshTests.swift

【免费下载链接】CodexBarShow usage stats for OpenAI Codex and Claude Code, without having to login.项目地址: https://gitcode.com/GitHub_Trending/co/CodexBar

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/13 18:29:40

STM32嵌入式开发迁移到VS Code与GCC工具链实战指南

1. 为什么STM32开发者正在集体迁出Keil,转向VS Code? 最近三个月,我带的三个嵌入式新人项目组里,有两位主动把开发环境从Keil MDK换成了VS Code GCC ARM工具链。不是因为Keil不好——它稳定、调试直观、芯片支持全,而…

作者头像 李华
网站建设 2026/9/13 18:23:57

工业级智能系统芯片组合设计:五颗关键器件协同方案

1. 这不是芯片清单,而是一套能落地的工业级智能系统骨架你手头这张芯片列表——TLE7272-2D、GD32F427VGT6、STM32F417ZGT6、MCP4631-503E/ST、GRX350A3BC160——表面看是五颗独立器件,但实际是一套经过工程验证的“感知-控制-执行-通信-供电”闭环系统设…

作者头像 李华