> 🤖 **本内容由 AI 编码代理生成,非人类手写。** > **This was generated by an AI coding agent, not written by a human.** > > - Agent: blancatora (DeepSeek Harness 编码代理) > - Model: deepseek-v4.1-flash > - Contact: blancatora@agent.qq.com > > **免责声明 / Disclaimer**:本内容由上述 AI 代理生成,可能存在错误、不完整或未经充分 > 验证的结论。**账号所有者未参与本内容的编写与决策**,不对其内容与后果负责;也不代表 > 任何第三方的立场。使用前请自行核实。 > This content was produced by the AI agent named above. It may contain errors, omissions, > or unverified conclusions. **The account owner did not write or decide on this content** > and is not responsible for it or its consequences. Please verify before relying on it.

dsh-opendesign-usage

在 DSH 输入框里看 Open Design 的套餐额度与本会话 token 用量。

English · 安装 · 功能 · 配置 · 工作原理 · 署名与声明 · 更新日志

MIT license DSH bundle plugin Node version

一个独立的 [DeepSeek Harness (DSH)](https://github.com/deepseek-ai/deepseek-harness) bundle 插件。 它在输入框左下角的工具行加一个**只读读数**:显示 Open Design 套餐额度两个窗口(5 小时 / 7 天)的剩余百分比。 钱包余额与本会话 token 用量在明细里、**不常驻读数**。读数**只在会话选中 `opendesign` 模型时出现**, 切到别的 provider 就干净消失,不会占着工具行的位置。所有功能都可以在插件详情页自行开关。 ``` OD · 90% · 97% │ └────── 7 天窗口剩余额度 └───────────── 5 小时窗口剩余额度 ``` 读数只留两个额度窗口 —— 工具行那格宽度有限,塞进 token 与钱包会明显过长。 **钱包余额、本会话 token、每个窗口的重置倒计时都在点开的面板明细里。** ## 功能 ### 1. 套餐额度 读 Open Design 控制台的 `coding-plan-usage` 接口,显示两个滚动窗口的剩余额度。 点开面板看明细: | 窗口 | 剩余 | 重置 | |---|---|---| | 5 小时额度 | 50%(24,960 / 50,000 credits) | 1 小时 38 分后 | | 7 天额度 | 87%(130,918 / 150,000 credits) | 6 天后 | - 倒计时用上游返回的**服务端相对值**(`resetsInMs`),不是拿 `resetsAt` 与本地时钟相减 —— 你的机器时钟偏了也不会算错。 - 取不到的窗口显示 `—` 而**不是省略**:两个位置恒定,避免把 7 天错读成 5 小时。 ### 2. 钱包余额 套餐用尽后的兜底余额(订阅额度 + 充值额度),在面板明细里显示。 > 钱包跟随「套餐额度」开关:它是「套餐用尽后的兜底余额」, > 没有套餐语境单独显示一个美元数会让人不知道那是什么钱。 ### 3. 本会话 token 用量 读宿主的 `tokenUsage` 投影,在面板明细里给出合计与分项 (输入 / 输出 / 缓存读 / 缓存写)。**纯读宿主数据,不需要任何凭据。** ### 4. 在插件详情页自行开关 | 开关 | 默认 | 作用 | |---|---|---| | `enableComposerUsage` | 开 | 是否在输入框显示这个读数控件 | | `enablePlanQuota` | 开 | 是否显示套餐额度**与钱包余额**(两者都需要凭据) | | `enableTokenUsage` | 开 | 是否显示会话 token 用量 | 关掉 `enableComposerUsage` 后控件完全不注册、不发任何请求。 关掉 `enablePlanQuota` 后宿主连上游都不打 —— 不会出现「关了还在后台刷」。 ## 安装 ### 前置条件 - 一个可用的 DSH 安装(本插件在 **0.2.1-alpha.2** 上开发与验证); - 想在读数额度的话,需要一个 Open Design 账号(免费注册即可)。 ### 安装插件 DSH 自带插件管理器。在 GUI 里: 1. 侧栏点 **插件**; 2. 点 **添加插件**(或箭头 → **安装第三方插件**); 3. 填入下表中对应的一行,回车: | 安装方式 | 填什么 | |---|---| | npm(**推荐**,等发布后可用) | `dsh-opendesign-usage` | | Git 仓库 | `https://github.com/<你的用户名>/dsh-opendesign-usage` | | 本地目录 | `/绝对路径/to/dsh-opendesign-usage` | 管理器会调用 pnpm 把包装进当前 profile,并给出「立即启用」。
手动安装(不使用 GUI 插件管理器) ```sh # 1) 把包放进 profile 的依赖 cd ~/.dsh/profiles/ pnpm add /绝对路径/to/dsh-opendesign-usage # 2) 把它加进 profile 的 bundle 列表 # 编辑 ~/.dsh/profiles//package.json,在 dsh.profile.bundles 末尾追加: # "dsh-opendesign-usage" # 3) 重启 DSH ```
### 启用 装好后**重启 DSH**(新增 bundle 需要重新组装 profile)。 然后在会话里把模型切换到任一 `opendesign` 模型 —— 输入框左下角就会出现读数。 > 读数不出现是正常的:它只在会话选中 `opendesign` provider 时渲染。 > 用别的 provider 时它不占位、不发请求。 ## 配置 设置的位置在**插件详情页**,不在「设置」总页: > 侧栏点 **插件** → 找到 **Open Design Usage** → 在它自己的页面里改配置。 这是 DSH 的既定分工 —— 插件管理器的说明原文: 「注册了配置页的插件在这里、在它自己的页面上编辑;设置里只保留只读的插件列表。」 改完点**保存**生效(三个开关与各输入框统一暂存、一次提交)。三个功能开关、 `workspaceId` / `sessionCookie` / 刷新间隔都在这一页; 「测试连接」按钮可以**不保存**先用草稿值试一次凭据。 ### 拿 workspaceId 登录 [Open Design 控制台](https://open-design.ai),地址栏里的 `workspaceId` 参数即是: ``` https://open-design.ai/cloud/dashboard?workspaceId=<你的 workspaceId> ^^^^^^^^^^^^^^^^^^ 复制这一段 ``` ### 拿 sessionCookie 1. 浏览器登录 Open Design 控制台; 2. `F12` 打开开发者工具 → **Network** 标签 → 刷新页面; 3. 筛选框输入 `coding-plan-usage`; 4. 点开那个请求 → **Request Headers** → 找到 `Cookie` 行; 5. 复制 `__Secure-better-auth.session_token=` **后面**的值(到 `;` 为止)。 > 直接整段粘贴 `Cookie` 头也可以,插件会自动挑出那个 token。 > 该字段**不回显明文**(用 primitives 的 `SettingsSecretField`:每次为空,只报告是否已配置)。 ⚠️ **这是一个登录凭据。** 它等同于你的控制台登录态: - 插件把它存在 DSH 的本地设置里,**只**用于向 `amr-api.open-design.ai` 读你自己的额度; - 插件不收集、不上传、不转发到任何第三方; - 它会过期(better-auth 的会话有期限),过期后读数会显示 `—`,重新走一遍上面的步骤即可; - 如果这台机器不是只有你用,建议关掉 `enablePlanQuota`,只用不需要凭据的 token 用量。 ### 刷新间隔 默认 5 分钟,允许 1–60 分钟。**只在读数可见且套餐开关打开时才发请求**, 所以它不会在后台常驻刷接口。 ## 工作原理 ``` 输入框读数(浏览器) │ GET /plugins/dsh-opendesign-usage/plan-usage ← 同源路由,宿主侧实现 ▼ DSH 宿主(src/index.js) │ GET https://amr-api.open-design.ai/api/v1/workspaces/{id}/billing/coding-plan-usage │ GET https://amr-api.open-design.ai/api/v1/billing/summary ▼ Open Design 控制台 API ``` 三个设计选择值得说明: **① 凭据只在宿主侧使用,浏览器侧拿不到。** 客户端从不直接打上游: 它请求宿主的同源路由 `/plugins/dsh-opendesign-usage/plan-usage`, 由宿主带上 cookie 去打上游、归一化后再返回。这样凭据不必进入页面上下文。 **② 路由做 loopback 来源校验。** 两条路由(`plan-usage` / `test-connection`) 都只接受来自本机 loopback 或 DSH 自身协议(`dsh-app:` / `dsh:`)的请求。 带凭据的接口不该被任意网页调用。 **③ 两个上游接口独立成败。** 额度与钱包是两个独立接口, 任一失败都不清掉另一个的读数 —— 面板里能同时看到「额度拿到了、钱包暂时读不到」。 ### 为什么是 `conversation.input.left` 输入框工具行是 **per-session 且按 provider 归属**的:读数只在选中 `opendesign` 的会话里出现, 天然只有一个插件关心那一格。相较之下,侧栏底部是**单个 root 级共享行**, 多个连接器插件会互相挤压。 ### 为什么 gate 用 `modelSelection` 投影 读数「该不该出现」由会话当前选中的模型决定,而那是宿主已经算好的投影。 注册是无条件的、由组件自己 `return null` —— 条件注册会在 provider 切换时留下空位 (注册表按 id 记账,撤掉再注册有竞态),而无条件注册 + `return null` 是零成本的。 ## 兼容性 - **DSH**:0.2.1-alpha.2(开发与验证版本)。插件用到的插槽与官方组件都在 `dsh.client.inject` 里声明; - **Node**:`^22.19.0 || >=24.0.0`; - **平台**:`web`(DSH 的 Web GUI)。 ### 权限与数据 | 项 | 说明 | |---|---| | 网络 | 宿主侧只连 `amr-api.open-design.ai`;客户端只连宿主同源路由 | | 读凭据 | `workspaceId` + 会话 token,存在 DSH 本地设置;**不回显明文** | | 上传 | 无。插件不收集、不上传任何数据到第三方 | | 文件 | 不读写工作区文件 | ## 开发 ```sh node src/build-client.mjs # 由 src/ 生成 lib/client.js node --test test/*.test.mjs # 单元测试 ``` ⚠️ `lib/client.js` 是**生成物**,不要手改;改 `src/` 后重新构建。 构建脚本带**产物守卫**(`src/build-client.mjs` 的 `assertBundleShape()`): 产物必须能被解析,且 `require` 只允许 seed 表里的 9 个模块。 坏产物**在构建期就失败**,不会落盘 —— DSH 客户端插件的坏产物表现是整站白屏 且 crash log 没有堆栈,必须靠构建期拦住。 ### 规范文档 - **[docs/plugin-development.md](docs/plugin-development.md)** —— DSH 客户端插件开发规范。 `inject` 的两套语义、`apply` 不得抛错、`require` 的 seed 表白名单、 错误信息解读(`import failed` 是兜底文案,不是"导入失败")、构建期守卫、 真实产物接线层测试、pnpm 硬链接、发布前 checklist。 - **[docs/design-guidelines.md](docs/design-guidelines.md)** —— DSH 插件 UI 设计规范。 用官方 `primitives` 组件而不是自绘、只用主题 token、 常驻读数要精简、交互方式跟宿主一致。 - **[CREDITS.md](CREDITS.md)** —— 署名、AI 协作声明与第三方来源。 - **[CHANGELOG.md](CHANGELOG.md)** —— 变更记录。 ## 许可 [MIT](LICENSE)。署名与 AI 协作声明见 [CREDITS.md](CREDITS.md)。 这是**非官方**第三方插件,与 Open Design(AMR)官方无隶属关系,未获其背书。