deepseek-harness
deepseek-ai
DeepSeek Harness: Everything is a Plugin.
PROJECT TOPICS
INSTALL REFERENCE
dsh plugin --profile web add github:whitelonng/dsh-opencode-go-pool
该命令指向仓库当前默认分支;尚无绑定当前 commit 的完整验证结果。
PROJECT README
DeepSeek Harness(DSH)插件:OpenCode Go 套餐的多 Key 池 —— 当前 Key 额度耗尽时自动、无感地切换到下一个 Key,并在设置页提供与官网一致的套餐余额管理卡片(5 小时滚动 / 每周 / 每月 已用·剩余·重置时间)。
dsh-llm-pi-ai 的 opencode-go 路由)每个供应商只能填一个 Key,额度耗尽后必须手动更换——本插件接管该路由,用 Key 池 + 自动故障切换解决。| 功能 | 说明 |
|---|---|
| 🔄 自动切换 Key | 请求因额度耗尽(QUOTA)失败时,在同一次流式调用内静默换下一个 Key 重发,对话零感知;凭据失效(401/INVALID_CREDENTIAL)同样自动跳过 |
| 📊 套餐管理卡片 | 设置侧边栏「OpenCode Go 套餐池」页:每个 Key 的 5h 滚动 / 每周 / 每月 已用%·剩余%·重置倒计时,与官网一致 |
| 🎛 运行态管理 | 卡片内:立即切换、停用/启用、清除失效、新增/删除 Key(写入插件命名空间,带版本栅栏,无需改 yml) |
| ♻️ 自动复活 | 额度耗尽的 Key 在其 5h 窗口重置后(用量接口报告恢复)自动回到池中 |
| 🧭 无缝接管 | 接管 opencode-go 路由:删除「设置 → 模型」中的 opencode-go 行后自动完成,历史会话与模型选择器完全不变 |
dsh plugin --profile web add github:whitelonng/dsh-opencode-go-pool
重启 DSH(插件变更需重启生效)。随后:
opencode-go 供应商行(本插件会自动接管该路由;未删除时插件保持休眠并在卡片中显示引导)。OPENCODE_GO_KEY_A)。~/.dsh/.credentials.yaml / 环境变量。明文 Key 永不进入插件配置、日志或任何 RPC 响应。$DSH_HOME/profiles/web/cordis.patch.yml 加入插件行:
- id: opencode-go-pool
name: 'dsh-opencode-go-pool'
config:
route: opencode-go # 接管官方路由;冲突时休眠等待接管
keys: [] # 初始为空,由卡片管理(也可在此预置)
preemptAtPercent: 100 # <100 时,5h 用量达到即主动避让(默认 100:失败才切)
usageBaseUrl: https://opencode.ai/zen/go/v1/usage
usageRefreshMs: 30000
timeoutMs: 15000
并在 profile 的 package.json 中声明依赖后重新安装依赖。
flowchart TD
A[Agent 请求 opencode-go 模型] --> B[OpenCodeGoPoolAdapter.stream]
B --> C[KeyPool 选择当前活动 Key<br/>跳过 exhausted/disabled/invalid/近耗尽]
C --> D[PiAiAdapter 发起请求<br/>凭据按引用经 credentials seam 解析]
D --> E{结果}
E -->|成功| F[正常流式返回]
E -->|额度耗尽 QUOTA| G{是否已输出内容?}
G -->|否| H[标记该 Key 耗尽<br/>轮换下一 Key]
H --> C
G -->|是(流中途)| I[轮换 Key 后上抛错误]
I --> J[llm-retry 按扩展策略开新一轮<br/>命中新 Key]
E -->|401 / 凭据失效| K[标记 invalid → 轮换]
K --> C
E -->|全部 Key 耗尽| L[向对话呈现明确额度错误]
M[用量网关 30s 轮询官方 /v1/usage] -.按用量避让与复活.-> C
N[设置页套餐池卡片] -.停用/立即切换/增删 Key.-> C
stream() 内:额度错误在产出任何 token 前到达时,直接换 Key 重发,上层(agent loop)看到的是一次成功的流式回复。QUOTA 加入该路由的可重试码(预算 = Key 数),dsh-llm-retry 会自动开新一轮命中新 Key。opencode-go 路由被 dsh-llm-pi-ai 持有时,插件休眠并监听 llm/adapters-updated,路由一释放即原子接管;老会话记录的路由 id 不变,历史对话无缝继续。apiKeyEnv),明文走 DSH 凭据 seam,每次请求按引用解析;解析失败大声报 MISSING_CREDENTIAL,绝不回落到无关的环境变量 Key。$DSH_HOME/opencode-go-pool.state.json,重启恢复。GET https://opencode.ai/zen/go/v1/usage
Authorization: Bearer <OpenCode Go API Key>
返回三个窗口的 percent(0–100)与 resetsAt(ISO-8601):
{ "usage": { "rolling": {"status":"ok","percent":9, "resetsAt":"…"},
"weekly": {"status":"ok","percent":12,"resetsAt":"…"},
"monthly": {"status":"ok","percent":6, "resetsAt":"…"} } }
该接口未写入 OpenCode 公开文档,解析做了防御式处理:形状变动只影响卡片显示(降级为错误提示),不影响自动切换功能;usageBaseUrl 可配置。
| 键 | 默认 | 含义 |
|---|---|---|
route |
opencode-go |
接管官方路由;改为 opencode-go-pool 时注册自有路由(与官方并存,模型选择器需手动切换一次) |
keys |
[] |
Key 列表:{id, label, apiKeyEnv};通常留空由卡片管理 |
preemptAtPercent |
100 |
5h 滚动用量达到该百分比即主动避让;100 = 仅在失败时切换 |
usageBaseUrl |
https://opencode.ai/zen/go/v1/usage |
用量接口地址 |
usageRefreshMs |
30000 |
卡片轮询间隔(host 侧另有 15s TTL 缓存) |
timeoutMs |
15000 |
用量请求超时 |
dsh-llm-pi-ai 共存:接管模式下请删除其 opencode-go 行;pi-ai 的其他供应商不受影响。纯 ESM,零构建步骤:
index.js(插件 + 池适配器 + 接管)、pool.js(状态机)、usage.js(用量网关)、typert.host.js(RPC 清单)client.js(lazy-CJS bundle,window.__ModuleLoader__.load 格式)node --test test/*.test.mjs(38 项:状态机 13、用量网关 7、cordis 烟测 8(接管协议与静默切换端到端)、真实服务集成 5(LlmRuntime 注册表/llm.stream 全链路/settings 写入/接管握手)、客户端 bundle 执行与渲染 5;缺少 harness 依赖时相关测试优雅跳过)node --test test/*.test.mjs
MIT
除 38 项测试外,插件已在真实 DSH host 中完成无 GUI 启动验证(dsh CLI + 一次性测试 profile):
DSH_HOME=/tmp/dsh-boot-test/home \
OPENCODE_GO_KEY_A=sk-test-placeholder-aaaa OPENCODE_GO_KEY_B=sk-test-placeholder-bbbb \
node $DSH_APP/node_modules/@deepseek-ai/dsh/lib/bin.js --profile test "ping"
预期输出(证明 agent 请求真实派发进池适配器并完成轮换):
dsh: QUOTA: opencode-go-pool: every key is exhausted, disabled, or invalid …
状态文件同时记录:两个 Key 因真实 401(AuthError: Invalid API key.)被标记 invalid、依次轮换、lastSwitch.reason: invalid。真实凭据下额度耗尽(QUOTA)走完全相同的轮换机器。
CLASSIFICATION EVIDENCE
系统优先读取 GitHub Topics,再与站内分类词典和词根规则比对。当前命中: 无有效分类标签。