dsh-cpa-monitor
Verifieddsh-cpa-monitor · v0.2.1 · MIT · Web UI
DSH web plugin: a CLIProxyAPI (CPA) Codex account monitor — sidebar quota badge (5h/7d), account enable/disable and note/priority editing, failure diagnostics from CPA error logs, and a Settings card for the endpoint and proxies
Install
dsh plugin add dsh-cpa-monitor Confirm the layer applied with dsh --profile default --dump-config — see the install guide.
Source
Tags
Creators
Readme
dsh-cpa-monitor
一个 DSH Web profile 插件。它在左侧栏底部显示 CLIProxyAPI(以下简称 CPA)中各 Codex 账号的订阅额度状态,并提供地址与代理的可视化配置、账号写操作以及失败请求诊断。
同一份代码同时适配两代宿主与两代 CPA 管理接口:
| 维度 | 支持范围 |
|---|---|
| DSH 宿主 | ≥ 0.2(含桌面 App,配置入口在侧栏「插件」页)与 ≤ 0.1(配置入口在「设置 → 插件」) |
| CPA 管理 API | v8(优先)与 v0(回退),启动时自动探测 |
功能
| 能力 | 说明 |
|---|---|
| 侧栏额度徽标 | 显示 5h/7d(有 30 天窗口时补充 30d)剩余百分比,并给出可用账号数 |
| 详情面板 | 汇总条与逐账号卡片:状态、双窗口进度条与重置倒计时、成功/失败计数、近期请求分布 |
| 账号写操作 | 禁用/启用、修改备注与优先级,均在同一面板内完成 |
| 重置券 | 展示可用张数与到期时间,并可在二次确认后使用一张 |
| 本地冷却 | 展示 CPA 因上游 429 记录的本地冷却条目,并可将其清空 |
| OAuth 凭证刷新 | 让 CPA 立即用 refresh token 换取新的 access token(仅 CPA v8) |
| 失败诊断 | 列出最近的失败请求,就地展开解析后的摘要与逐跳归属账号 |
| 版本提示 | 显示当前 CPA 构建版本,并在有新版本时提示 |
适用范围:额度部分仅适配 Codex
额度采集依赖 Codex 的订阅用量接口,因此下表需要区分能力边界:
| 能力 | 是否与 provider 无关 |
|---|---|
| 配额/额度(徽标百分比、卡片进度条) | 否,仅 Codex |
| 账号启用/禁用、备注、优先级 | 是,任何 CPA 凭据 |
| 失败原因诊断 | 是,任何 provider 的请求 |
| CPA 版本与更新提示 | 是 |
额度数据取自 GET https://chatgpt.com/backend-api/wham/usage,鉴权使用 Chatgpt-Account-Id 请求头(取值来自凭据的 id_token.chatgpt_account_id),窗口语义同样来自 Codex 的 primary_window / secondary_window 与 limit_window_seconds(5 小时 / 7 天 / 30 天)。其它 provider 没有对应的用量接口,因此:
- 默认配置
providerFilter: "codex",仅列出 Codex 凭据; - 将该字段留空会列出其它 provider 的凭据,但其额度条不会出现,卡片会显示取数失败。该行为属于"不隐藏",不代表已支持。
账号开关、备注、优先级与失败诊断使用 CPA 的凭据管理与日志接口,与 provider 无关,对 Claude、Gemini 等凭据同样可用。
环境要求
- DSH 0.1 及以上版本(桌面 App 亦适用)。
- 一个可访问的 CPA 管理口,以及其管理密钥。
- Node.js 18 及以上(服务端半边仅使用
node:内置模块)。
安装
从 npm 安装:
dsh plugin --profile web add dsh-cpa-monitor
# 重启 dsh web;服务端半边在启动时挂载
从源码安装(修改代码即时生效,参见开发文档中的热更新说明):
cd /path/to/dsh-cpa-monitor && npm install
dsh plugin --profile web add /path/to/dsh-cpa-monitor
# 重启 dsh web
dsh plugin add 使用 pnpm 建立软链接(link:,不复制代码),并将 dsh-cpa-monitor 追加到 profile 的 dsh.profile.bundles。重启后刷新浏览器即可。
卸载:
dsh plugin --profile web remove dsh-cpa-monitor
安装完成后,需要填写 CPA 地址与密钥,方式见下一节。
配置
配置页
配置页入口跟随 DSH 版本变化,插件对两代均做了注册,只会命中其中一个:
| DSH | 入口 |
|---|---|
| ≥ 0.2(含桌面 App) | 左侧栏 插件 → 已安装 → dsh-cpa-monitor → 行 cpa-monitor 的 配置 |
| ≤ 0.1 | 设置 → 插件 → 「CPA 账号状态」 |
表单由宿主持有状态,保存后写入;离开页面会丢弃未保存的修改。两代宿主均为保存即生效,无需重启。
字段
| 字段 | 说明 |
|---|---|
| CPA 地址 | CLIProxyAPI 管理口,例如 https://cpa.example.com:8317 |
| 管理密钥 | Authorization: Bearer <密钥>;留空表示不修改(脱敏字段,界面不回显) |
| 代理地址 | 默认为空(直连)。需要时每行一个、按顺序尝试,支持 http://、https://、socks5://,也可直接填写 host:port(按 HTTP 代理处理) |
| 允许直连 | 所有代理均失败后再尝试直连;代理列表为空时自动直连 |
| 轮询周期(秒) | 后台拉取间隔,最小 5 秒 |
| 请求超时(秒) | 单个上游请求的端到端上限 |
| 连接超时(秒) | 单条代理握手/TLS 的上限,不得大于请求超时 |
| Provider 过滤 | 仅监控该 provider 的凭据,留空表示全部(额度部分仅适配 Codex,见上文) |
| 侧栏徽标口径 | lowest 显示额度最紧张的账号;total 按窗口累加各账号余量 |
| 包含已禁用账号 | 将 CPA 中已禁用的账号一并列出(置灰显示) |
| 时区 | 重置时间的显示时区,例如 Asia/Shanghai |
| 跳过证书校验 | 仅用于 CPA 使用自签名证书的场景 |
每个字段都会显示当前生效值与是否被覆盖,并提供"清除"以回到默认层。
YAML(部署级默认值)
配置按三层逐级覆盖:
schema 默认值 → 组合层(本包的 cordis.patch.yml) → 用户层
用户层的落点取决于宿主版本:
| DSH | 用户层位置 | 写入方 |
|---|---|---|
| ≤ 0.1 | ~/.dsh/settings.yaml 的 cpa-monitor: 段 |
本包注册的设置命名空间 |
| ≥ 0.2 | 当前 profile 自身的配置文档 | 宿主的配置编辑器 |
如需为整个部署准备默认值(例如为新 profile 预置一套),可按 id 定位补丁写入 ~/.dsh/profiles/<profile>/cordis.patch.yml:
- id: cpa-monitor
config:
baseURL: "https://cpa.example.com:8317"
proxies: ["http://127.0.0.1:1080"]
注意:按 id 定位的补丁会整体替换 config 对象,而非深合并。只修改单个字段时,需要将其余字段一并写出。dsh web --dump-config 可打印组合结果。在配置页中清除过的字段会回到该层取值。
仓库与发布包中不含任何真实地址与密钥:cordis.patch.yml 只包含占位地址且不含 managementKey,真实部署信息位于用户层,或通过环境变量 DSH_CPA_MANAGEMENT_KEY 提供。
使用
侧栏徽标
徽标形如 [图标] CPA 账号 133%/89% 2/3。数值为 5h余量/7d余量,存在 30 天窗口数据时补充为 5h/7d/30d;缺少 5h 或 7d 时显示 -,缺少 30 天窗口时该段整体不显示(因此仅有 7 天窗口的账号池显示为 94%/12%)。右侧的 2/3 为可用账号数与总数。侧栏折叠为 rail 时显示为 36px 圆形图标。点击徽标展开详情面板。
数值口径由配置项 「侧栏徽标口径」 决定:
| 口径 | 显示内容 | 示例 |
|---|---|---|
lowest(默认) |
额度最紧张的单个账号自身的 5h/7d/30d 余量 | 100%/0% |
total |
各账号按窗口累加的余量 | 133%/89%(两个账号 5h 分别为 100% 与 33%) |
lowest 的"最紧张"按以下顺序判定:
- 存在 5h 余量低于 20% 的账号时,取其中余量最低者。5h 是会话最先触达的限制;
- 所有账号的 5h 余量均不低于 20% 时,取长窗口(7d/30d)余量最低者。5h 宽裕不应掩盖长窗口即将耗尽。
total 的累加只统计未禁用账号。其语义是账号池的总余量而非百分比:三个账号各 100% 即为 300%(分母为账号数 × 100%)。
颜色跟随屏幕上显示的数值(不高于 10% 显示红色,不高于 30% 显示黄色,其余为绿色)。lowest 模式下显示的是最紧张的账号,该账号见底时徽标随之变红;total 模式下显示的是池子总量。不按"最差账号"上色的原因是:账号池由 CPA 做负载均衡,单个账号耗尽只会将流量切换到下一个,不影响整体可用性;而池子整体接近耗尽时,total 口径仍会给出警示。账号被禁用或取数失败由右侧的可用账号计数体现。悬停提示会说明当前是"用量最低的账号 + 邮箱"还是"各账号按窗口累加"。
详情面板
- 汇总条:最紧张窗口的百分比、可用/总数、待处理数、已禁用数与本次采集耗时。
- 账号卡片:邮箱、套餐、CPA 状态、
5h与7d/30d两条进度条(剩余百分比、重置时间与倒计时)、成功/失败计数,以及近 20 个 10 分钟区间的迷你柱状图。 - 单账号取数失败时,错误原文显示在该卡片内,不影响其它卡片;后端整体不可达时,顶部横幅显示传输层错误原文与重试入口。
- 副标题显示
更新于 HH:MM:SS · <CPA 地址>。 - 点击面板外部或按 Esc 均可关闭。
- 标题「CPA 账号状态」旁的
ⓘ悬停显示额度口径说明。
账号开关 / 备注 / 优先级
账号卡片提供以下操作,均直接作用于 CPA:
- 禁用 / 启用:调用 CPA 的凭据状态接口。账号被风控或返回 401 时,可直接在面板中停用。写入期间按钮显示"写入中…",服务端写入完成后会强制重读快照并将结果折回面板,状态与计数随之更新。
- 编辑:就地修改
note(备注)与priority(优先级)。备注显示在卡片上,优先级进入信息行。编辑器内的说明文案挂在字段旁的ⓘ上,悬停显示。 - 未提供
prefix字段:CPA 可以写入该字段,但不会在凭据接口中回读,做成只写字段会造成困惑。
写操作遵循三条约束:浏览器只提交 authIndex,由服务端从快照解析凭据文件名;disabled 必须为布尔值、priority 必须为数字;未通过校验的请求不会发送到 CPA。
刷新 OAuth 凭证(仅 CPA v8)
账号卡片的编辑器中提供 刷新 OAuth 凭证 按钮,用于让 CPA 立即使用 refresh token 换取新的 access token。该接口仅在 CPA v8 上存在,因此按钮只在检测到 v8 时显示,服务端在 v0 上也会直接拒绝该请求。
该操作仅作用于单个凭据,不会触发 CPA 的全量刷新。
重置券与本地冷却
账号卡片底部的 重置券 N 链接(无券但存在冷却时显示为「本地冷却」)会在卡片内就地展开,内容包括:可用重置券张数与每张的到期时间(只读),以及该账号当前的本地冷却条目——即 CPA 在收到上游 429 后自行记录的状态。
面板提供两个不同的动作,各自需要一次确认:
| 动作 | 作用 | 代价 |
|---|---|---|
| 清空本地冷却 | 清除 CPA 中该账号的本地冷却记录,使其可以立即重试 | 无 |
| 使用重置券 | 兑换一张重置券,重置该账号的 5h/7d 限额,并随后清除本地冷却 | 不可撤销地消耗 1 张重置券 |
需要同时清除本地冷却的原因是:兑换只解除上游侧的限额,CPA 自身的冷却记录仍然存在,账号不会立即恢复可用。该步骤免费且幂等,因此由同一次点击完成。执行顺序为先兑换、后清除;反向顺序会使 CPA 立即以一个仍在限流的上游进行重试。
若重置券已消耗而清除冷却失败(例如网络中断),接口会返回成功并附带一条警告,面板以黄色提示条显示「重置券已使用,但清空本地冷却失败」。此时不应重复兑换(重置券无法退回),点击「清空本地冷却」重试即可。
安全约束:
- 上述两个动作不会被任何自动流程调用:不在轮询、重试或刷新时隐式触发。
- 展开面板、点击"取消"均不会发送任何写请求。
- 动作完成后会立即重读用量与重置券:服务端先重新观测快照并失效该凭据的重置券缓存,客户端再读取一次明细。在数值更新完成之前,相关按钮保持禁用,避免依据过期数值做出第二次消费。
- 本地冷却的来源是 CPA 凭据列表中的
cooldowns与next_retry_after字段(含作用域、原因、模型、重试时刻、HTTP 状态),属于路由状态而非上游额度,因此仅在 CPA v8 上提供。 - 重置券的到期时间来自上游一个独立的只读接口,面板仅在展开时按需读取(服务端缓存 60 秒)。该接口可能限流;读取失败时显示"到期时间未提供",不会推断数值。
失败原因
面板底部提供「最近失败请求」区块。点击"查看"列出 CPA 的失败请求日志,点击"详情"在该行正下方就地展开,按钮随之变为"收起"。展开内容为解析后的摘要,而非请求正文:
- 上游状态码与错误标识(如
service_unavailable_error/server_is_overloaded)及可读文案; - 逐跳归属账号:CPA 为每次上游尝试记录了凭据文件名与邮箱,因此可显示「第 1 跳 alpha → 第 2 跳 bravo」,与上方账号卡片对应;
- 模型、端点、重试次数与发生时刻。
请求正文(主要是提示词负载)默认不显示;仅当摘要无法解析(日志格式未被识别)时才回退显示正文。正文读取上限为 24KB,超出部分会标注为已截断。
列表与详情中的时刻均以绝对时刻取值,再按浏览器本地时区渲染。若 CPA 开启了 request-log,失败记录会并入请求日志目录,此时失败日志为空,插件会明确提示该状态,而不是表现为"没有失败"。
常见问题
| 现象 | 原因与处理 |
|---|---|
| 配置按钮点开为空白 | 宿主版本与服务端半边不匹配,或配置契约未满足。升级到最新版本并重启宿主。 |
| 面板提示"服务端半边是旧版" | lib/index.js 等文件只在进程启动时加载,需重启 dsh web(或桌面 App)。 |
| 账号卡片缺少开关/编辑/诊断 | 同上:客户端已更新而服务端仍是旧版。 |
| 徽标只有图标没有数值 | 尚未取得任何账号数据,或全部账号取数失败;展开面板查看错误原文。 |
| 额度条显示取数失败 | 该凭据不是 Codex,或凭据的 access token 已失效。 |
| 看不到任何重置券 | 上游未发放重置券,或该接口读取失败;展开面板查看提示。 |
| 缺少 OAuth 刷新按钮 | 当前 CPA 为 v0,该路由仅在 v8 上存在。 |
| 所有请求都提示无法连接 | 检查 CPA 地址、网络与代理配置;代理地址留空表示直连。 |
安全说明
- 插件注册的所有 HTTP 路由仅接受 loopback 对端;强制刷新与全部写操作还必须携带自定义请求头(跨站页面可以访问 localhost,但无法携带自定义头,预检会失败)。写操作仅接受
POST。 - 管理密钥仅保存在宿主配置中,界面不回显;快照接口只以
managementKeyConfigured: true/false表示其是否已配置。 - 仓库与发布包中不含任何真实地址或密钥;提交前由仓库内的检查脚本扫描密钥形状的字面量。
- 会消耗重置券的操作需要二次确认,且不会被任何自动流程触发。
开发文档
架构说明、接口契约、测试与发布流程见 DEVELOPMENT.md。
许可
MIT © 2026 intx96