@gehennawu/dsh-service 1.6.3 → 1.7.0
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.en.md +14 -5
- package/README.md +14 -5
- package/backup-integrity.js +1 -1
- package/client.js +1 -1
- package/index.js +182 -16
- package/package.json +1 -1
- package/quota-adapters.js +214 -2
package/README.en.md
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
<em>DeepSeek Harness (DSH) Web 服务控制与运维插件。</em>
|
|
10
10
|
</p>
|
|
11
11
|
|
|
12
|
-
[](package.json)
|
|
13
13
|
[](LICENSE)
|
|
14
14
|
[](https://github.com/deepseek-ai/deepseek-harness)
|
|
15
15
|
[](https://cordis.moe/)
|
|
@@ -49,7 +49,7 @@ A service-control and operations plugin for DSH Web: safe restart, version manag
|
|
|
49
49
|
|
|
50
50
|
## 🚀 Features
|
|
51
51
|
|
|
52
|
-
The Settings "Service Control" panel has a six-page navigation: **Overview · Model stats · Quota lookup · Health · Maintenance · Configuration**; "Maintenance" aggregates five subpages — Sessions · Skills · Subagents · Backups · Restart — and "Configuration" aggregates Features · Task notifications. Restart, Quota lookup, and Sessions can each enable a **quick entry in the settings left navigation** (off by default; the Skills and Subagents sidebar entries were removed).
|
|
52
|
+
The Settings "Service Control" panel has a six-page navigation: **Overview · Model stats · Quota lookup · Health · Maintenance · Configuration**; "Maintenance" aggregates five subpages — Sessions · Skills · Subagents · Backups · Restart — and "Configuration" aggregates Features · Task notifications · Settings Nav. Restart, Quota lookup, and Sessions can each enable a **quick entry in the settings left navigation** (off by default; the Skills and Subagents sidebar entries were removed).
|
|
53
53
|
|
|
54
54
|
Under **Plugins → Plugin configuration**, eleven host-level switches: **Health diagnostics, Model statistics, Quota lookup, Backup maintenance, Task notifications, Skill manager, Subagent model, Session manager, Mobile adaptation, Right-Sidebar file editing, `/healthz` liveness endpoint** (all on by default except Mobile adaptation). All are live settings: disabling hides the UI, stops polling/subscriptions, and makes the host reject that capability; Overview and Restart stay available.
|
|
55
55
|
|
|
@@ -67,7 +67,8 @@ Under **Plugins → Plugin configuration**, eleven host-level switches: **Health
|
|
|
67
67
|

|
|
68
68
|
|
|
69
69
|
- Maintenance groups Sessions, Skills, Subagents, Backups, and Restart; it remembers the most recent subpage and falls back to an available item when a feature is disabled
|
|
70
|
-
- Configuration groups feature switches and
|
|
70
|
+
- Configuration groups feature switches, task notifications, and settings nav tabs; switches are grouped and apply live, Notifications stays visible but disabled when that feature is off, and Settings Nav supports manual reordering (drag / arrows) and visibility management of all tabs in the settings dialog sidebar, with every label shown in the active interface language only (a third-party plugin registering a static `中文 / English` string contributes just its current-language half, so narrow mobile viewports no longer truncate it), persisted to the server-side unified config file `$DSH_HOME/dsh-service-config.json` (cross-device sync, auto-fetched on startup with a local-cache fallback), applying live (the Service Control tab is permanently locked visible to prevent lockout)
|
|
71
|
+
- Unified plugin config file: lightweight per-feature preferences converge into a single `$DSH_HOME/dsh-service-config.json` (atomic write, `0600`), partitioned by feature section — updating or clearing one section never touches others; large caches (usage index etc.) and encrypted credentials stay out of this file
|
|
71
72
|
|
|
72
73
|
### Version and updates
|
|
73
74
|
|
|
@@ -124,12 +125,13 @@ Under **Plugins → Plugin configuration**, eleven host-level switches: **Health
|
|
|
124
125
|
| StepFun Balance | Official `GET /v1/accounts` (API key, com/ai dual domains) |
|
|
125
126
|
| StepFun Step Plan | Console BFF subscription quota (Oasis-Token console session; 5-hour/weekly windows vs Credit pool auto-detected) |
|
|
126
127
|
| Xiaomi MiMo Token Plan | Console-origin plan quota (web session cookie) |
|
|
128
|
+
| Command Code (command-goat) | Official account quota plane `api.commandcode.ai/alpha/*` (same key reused: balance + period spend + plan + 5-hour/weekly windows) |
|
|
127
129
|
| CLIProxyAPI deployment | Official remaining quota of each OAuth upstream account |
|
|
128
130
|
|
|
129
|
-
- Credentials go into the DSH credential store (`$DSH_HOME/.credentials.yaml`, hot-effective): an API key, the CPA management key, the Xiaomi console cookie, or the StepFun Step Plan console token (Oasis-Token; the `Oasis-Webid` is derived from the token automatically — no manual entry)
|
|
131
|
+
- Credentials go into the DSH credential store (`$DSH_HOME/.credentials.yaml`, hot-effective): an API key, the CPA management key, the Xiaomi console cookie, or the StepFun Step Plan console token (Oasis-Token; the `Oasis-Webid` is derived from the token automatically — no manual entry); the Command Code quota plane reuses the inference key, so no extra credential is needed
|
|
130
132
|
- Anti-rate-limit pacing: 60 s result cache, exponential backoff (30 s doubling, capped at 15 min); auto-query can be set to manual-only / 1 / 2 / 5 / 10 minutes
|
|
131
133
|
- CLIProxyAPI: when an account's live query fails, its last cached snapshot windows are shown with a "cached" badge; snapshot windows whose reset time has already passed (the window they described has ended) are dropped, avoiding the illusion of quota stuck on yesterday
|
|
132
|
-
- Failures state their real reason: cards and the ring show "error copy (HTTP status · failing endpoint · failing account · upstream message) · next automatic retry" — a wrong key, an unpaid balance, rate limiting, and a moved endpoint each read differently instead of one generic notice; an upstream 401/403 is classified as "credential rejected by upstream" and the card keeps its credential form available
|
|
134
|
+
- Failures state their real reason: cards and the ring show "error copy (HTTP status · failing endpoint · failing account · upstream message) · next automatic retry" — a wrong key, an unpaid balance, rate limiting, and a moved endpoint each read differently instead of one generic notice; an upstream 401/403 is classified as "credential rejected by upstream" and the card keeps its credential form available, and business error codes inside an HTTP 200 envelope are classified the same way (auth failure → credential rejected, expired plan → no active subscription, vendor-side failure → upstream service error) instead of being reported as "unexpected response format"
|
|
133
135
|
- API keys are resolved only inside the host process; the browser receives normalized window data only; unadapted providers are never requested
|
|
134
136
|
|
|
135
137
|
### Backup management
|
|
@@ -149,6 +151,7 @@ Under **Plugins → Plugin configuration**, eleven host-level switches: **Health
|
|
|
149
151
|

|
|
150
152
|
|
|
151
153
|
- Lists local skills in three sections — **auto-loaded / manual-only / fully disabled**; same-name shadowing marks both copies, bundled directories are read-only
|
|
154
|
+
- Entries start collapsed into one row (name plus source / read-only / annotated badges); the top button expands or collapses every visible entry at once, and clicking an entry's name row toggles that entry alone; an invalid entry keeps its ⚠ and one-click fix visible while collapsed
|
|
152
155
|
- Two switches edit the SKILL.md frontmatter directly (`disable-model-invocation` / `user-invocable`); changes go live within ~200 ms
|
|
153
156
|
- Entries with legacy camelCase keys are dropped by the official parser: ⚠ warning + one-click canonical fix
|
|
154
157
|
- ✨ Fill with AI: pick a model to draft a description (follows the UI language), saved to a plugin sidecar index — **SKILL.md is never modified**; one-click batch fill runs in the host background and can be cancelled. Already-annotated skills are listed separately in the plan and are only overwritten after a "Confirm forced refill" second confirmation (annotating no longer blocks future batch fills forever); completion-log timestamps use your local timezone
|
|
@@ -354,6 +357,12 @@ It is the "likely manual terminal launch" detection — no process manager found
|
|
|
354
357
|
Use the inline form on the card: an API key for regular adaptations, the management key for CLIProxyAPI (not the proxy key), and the console cookie for Xiaomi Token Plan. The value goes into the DSH credential store and the provider refreshes automatically; if a process environment variable shadows the name, the host refuses the write — change the variable itself.
|
|
355
358
|
</details>
|
|
356
359
|
|
|
360
|
+
<details>
|
|
361
|
+
<summary><strong>Command Code shows "credential rejected by upstream"?</strong></summary>
|
|
362
|
+
|
|
363
|
+
The inference and quota planes share one key (`user_*` prefix, created in Studio's API keys page). This error means the upstream rejected the key: regenerate or copy it in Studio at commandcode.ai, then paste it via "Set API credential". If the channel's baseURL points at a self-hosted relay rather than `api.commandcode.ai`, note the quota plane always queries the official account plane — a relay key cannot read official quota.
|
|
364
|
+
</details>
|
|
365
|
+
|
|
357
366
|
<details>
|
|
358
367
|
<summary><strong>Xiaomi shows "credential rejected by upstream"?</strong></summary>
|
|
359
368
|
|
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
<em>A service-control & operations plugin for DeepSeek Harness (DSH) Web.</em>
|
|
10
10
|
</p>
|
|
11
11
|
|
|
12
|
-
[](package.json)
|
|
13
13
|
[](LICENSE)
|
|
14
14
|
[](https://github.com/deepseek-ai/deepseek-harness)
|
|
15
15
|
[](https://cordis.moe/)
|
|
@@ -49,7 +49,7 @@ DSH Web 服务控制与运维插件:安全重启、版本管理与一键升级
|
|
|
49
49
|
|
|
50
50
|
## 🚀 功能
|
|
51
51
|
|
|
52
|
-
设置页「服务控制」面板六页导航:**概览 · 模型统计 · 额度查询 · 健康诊断 · 维护 · 配置**;其中「维护」聚合 会话管理 · 技能 · 子代理 · 备份维护 · 重启 五个子页,「配置」聚合 功能开关 · 任务通知
|
|
52
|
+
设置页「服务控制」面板六页导航:**概览 · 模型统计 · 额度查询 · 健康诊断 · 维护 · 配置**;其中「维护」聚合 会话管理 · 技能 · 子代理 · 备份维护 · 重启 五个子页,「配置」聚合 功能开关 · 任务通知 · 设置栏标签 三个子页。重启、额度查询、会话管理可另行开启**设置页左列快捷入口**(默认关闭;技能与子代理的左列入口已撤销)。
|
|
53
53
|
|
|
54
54
|
「插件 → 插件配置」提供十一个宿主级开关:**健康诊断、模型统计、额度查询、备份维护、任务通知、技能管理、子代理模型、会话管理、移动端适配、右栏文件编辑、`/healthz` 探活**(除移动端适配外默认开启)。全部热生效:关闭即隐藏界面、停止轮询并让宿主拒绝对应能力;概览与重启固定保留。
|
|
55
55
|
|
|
@@ -67,7 +67,8 @@ DSH Web 服务控制与运维插件:安全重启、版本管理与一键升级
|
|
|
67
67
|

|
|
68
68
|
|
|
69
69
|
- 「维护」集中会话管理、技能、子代理、备份维护与重启;记住最近使用的子页,关闭对应功能后自动回退到仍可用的项目
|
|
70
|
-
-
|
|
70
|
+
- 「配置」集中功能开关、任务通知与设置栏标签;开关按功能组展示并热生效,任务通知关闭时保留入口但显示置灰状态,设置栏标签支持对设置弹窗左侧全部导航标签进行手动排序(拖拽/上下箭头换位)与显隐管理,标签按当前界面语言单语显示(外部插件注册成 `中文 / English` 静态双语串时只取当前语言一侧,移动端窄屏不再被截断),配置持久化到服务端统一配置文件 `$DSH_HOME/dsh-service-config.json`(多设备同步、启动自动拉取,本地缓存兜底),即时生效(服务控制面板永久锁定显示防锁死)
|
|
71
|
+
- 插件统一配置文件:各功能的轻量偏好收敛在 `$DSH_HOME/dsh-service-config.json` 单一文件(原子写入、`0600`),按功能分区块隔离——修改或清除某一区块绝不影响其他区块;大缓存(使用统计索引等)与加密凭据不在此文件内
|
|
71
72
|
|
|
72
73
|
### 版本与更新
|
|
73
74
|
|
|
@@ -126,12 +127,13 @@ DSH Web 服务控制与运维插件:安全重启、版本管理与一键升级
|
|
|
126
127
|
| StepFun 余额 | 官方 `GET /v1/accounts`(API key,com/ai 双域) |
|
|
127
128
|
| StepFun Step Plan | 控制台 BFF 订阅额度(Oasis-Token 登录令牌;5 小时/周窗口与 Credit 月池自动识别) |
|
|
128
129
|
| 小米 MiMo Token Plan | 控制台同源套餐额度(网页登录态 Cookie) |
|
|
130
|
+
| Command Code(command-goat) | 官方账号额度面 `api.commandcode.ai/alpha/*`(同 key 复用:余额 + 本周期花费 + 套餐 + 5 小时/周窗口) |
|
|
129
131
|
| CLIProxyAPI 部署 | 各 OAuth 上游账号官方剩余额度 |
|
|
130
132
|
|
|
131
|
-
- 凭据写入 DSH 凭据库(`$DSH_HOME/.credentials.yaml`,热生效):普通适配填 API key,CLIProxyAPI 填管理密钥,小米填控制台 Cookie,StepFun Step Plan 填控制台令牌(Oasis-Token,`Oasis-Webid`
|
|
133
|
+
- 凭据写入 DSH 凭据库(`$DSH_HOME/.credentials.yaml`,热生效):普通适配填 API key,CLIProxyAPI 填管理密钥,小米填控制台 Cookie,StepFun Step Plan 填控制台令牌(Oasis-Token,`Oasis-Webid` 由令牌自动派生无需手填);Command Code 额度面与推理面同一把 key,无需另配
|
|
132
134
|
- 防风控:结果缓存 60 秒、失败指数退避(30 秒 ×2、封顶 15 分钟);自动查询可调为仅手动 / 1 / 2 / 5 / 10 分钟
|
|
133
135
|
- CLIProxyAPI 某账号实时查询失败时,回退显示其上次缓存的快照窗口并标注「缓存」徽标;重置时间已过的快照窗口(快照描述的窗口已结束)直接丢弃,避免「额度停在昨天」的错觉
|
|
134
|
-
- 失败原因如实呈现:卡片与圆环显示「错误文案(HTTP 状态 · 失败端点 · 失败账号 · 上游原话)· 下次自动重试时刻」——错 key、欠费、限流、路径变更各有各的上游原话与状态码,不再只有一个笼统提示;上游 401/403
|
|
136
|
+
- 失败原因如实呈现:卡片与圆环显示「错误文案(HTTP 状态 · 失败端点 · 失败账号 · 上游原话)· 下次自动重试时刻」——错 key、欠费、限流、路径变更各有各的上游原话与状态码,不再只有一个笼统提示;上游 401/403 判为「凭据被上游拒绝」,卡片同时保留凭据填写入口;HTTP 200 业务信封里的错误码同样定族——鉴权失败判凭据被拒(保留填写入口)、套餐到期判无生效订阅、上游自身故障判「上游服务故障」,不再一律报「响应格式异常」
|
|
135
137
|
- API key 只在宿主进程内解析,浏览器仅收到归一化窗口数据;未适配的供应商绝不发起请求
|
|
136
138
|
|
|
137
139
|
### 备份管理
|
|
@@ -151,6 +153,7 @@ DSH Web 服务控制与运维插件:安全重启、版本管理与一键升级
|
|
|
151
153
|

|
|
152
154
|
|
|
153
155
|
- 按 **自动加载 / 仅手动调用 / 完全停用** 三区展示本地技能;同名遮蔽与被遮蔽副本均有标注,内置目录只读
|
|
156
|
+
- 条目默认全部折叠成一行(名称 + 来源/只读/已注释徽标);顶部按钮对当前可见条目一键「全部展开 / 全部折叠」,点单条名称行可独立开合;无效条目的 ⚠ 与一键修复折叠态也保留
|
|
154
157
|
- 双开关直接改写 SKILL.md frontmatter(`disable-model-invocation` / `user-invocable`),约 200ms 热生效
|
|
155
158
|
- 带 camelCase 旧版键的条目会被官方解析器剔除:⚠ 提示 + 一键修复
|
|
156
159
|
- ✨ AI 补全说明:选模型生成描述草稿(跟随界面语言),确认后存入插件侧车索引——**绝不改写 SKILL.md**;支持一键批量补全(宿主后台运行、可取消)。已注释技能会在计划中单列,经「确认强制补全」二次确认后才会被覆盖(不再是一旦注释就永远无法再次补全);补全日志时间按本机时区显示
|
|
@@ -356,6 +359,12 @@ pm2 start "dsh web --host 127.0.0.1" --name dsh-web
|
|
|
356
359
|
点击卡片上的内联表单写入凭据:普通适配填 API key,CLIProxyAPI 填管理密钥(不是代理 key),小米 Token Plan 填控制台 Cookie。写入 DSH 凭据库后自动强制刷新;被进程环境变量遮蔽时宿主会拒绝写入,需改环境变量本身。
|
|
357
360
|
</details>
|
|
358
361
|
|
|
362
|
+
<details>
|
|
363
|
+
<summary><strong>Command Code 卡片显示「凭据被上游拒绝」?</strong></summary>
|
|
364
|
+
|
|
365
|
+
推理面和额度面共用同一把 key(`user_*` 前缀,Studio 的 API keys 页生成)。卡片显示该错误说明 key 被上游判为无效:到 commandcode.ai 的 Studio 重新生成或复制 key,点卡片「填写 API 密钥」粘贴即可。若渠道 baseURL 指向的是自建中转而非 `api.commandcode.ai`,额度面仍固定查官方账号面——中转 key 查不到官方额度。
|
|
366
|
+
</details>
|
|
367
|
+
|
|
359
368
|
<details>
|
|
360
369
|
<summary><strong>小米卡片显示「凭据被上游拒绝」?</strong></summary>
|
|
361
370
|
|
package/backup-integrity.js
CHANGED
|
@@ -5,7 +5,7 @@ import { dirname, join, resolve, sep } from 'node:path'
|
|
|
5
5
|
import { promisify } from 'node:util'
|
|
6
6
|
import { gunzip } from 'node:zlib'
|
|
7
7
|
|
|
8
|
-
const CONFIG_FILES = Object.freeze(['settings.yaml', 'cordis.patch.yml', 'AGENTS.md'])
|
|
8
|
+
const CONFIG_FILES = Object.freeze(['settings.yaml', 'cordis.patch.yml', 'AGENTS.md', 'dsh-service-config.json'])
|
|
9
9
|
const PLAN_TTL_MS = 5 * 60 * 1000
|
|
10
10
|
const MAX_COMPRESSED_BYTES = 512 * 1024 * 1024
|
|
11
11
|
const MAX_EXPANDED_BYTES = 1024 * 1024 * 1024
|