dsh-qoder-connect
把 Qoder CN(阿里 Qoder 国内版桌面 App)订阅里的模型接入 DeepSeek Harness。
⚠️ 只对我自己的账号有效。 本插件读取的是我自己生成的 PAT。 PAT 绑定账号,别人拿到也无从使用(且不该外传)。要在自己环境跑, 需要自己生成 PAT 并按自己的环境改常量。改法见下方自用改法。
它做什么
在 DSH 里以 OpenAI 兼容端点暴露 Qoder CN 的模型,让模型选择器里出现对应分组
(渠道名 qoder1),可直接对话。
DSH ──OpenAI──▶ 本插件的回环 shim ──Qoder 双层 SSE──▶ gateway.qoder.com.cn
shim 只绑 127.0.0.1 随机端口 + 32 字节随机 bearer(timingSafeEqual 比对),
只服务 /healthz、/v1/models、/v1/chat/completions,无写接口。
为什么走 PAT,而不是啃加密凭据
Qoder CN 的桌面 App 自己不实现 agent 循环——它 spawn 一个内嵌的 Claude Code 式 worker
(@qoder-ai/qoder-cn-agent-sdk 的 qoder-worker-runtime.obf.mjs)。App 只负责登录,
并把短期 jobToken 交给它。
所以「接模型」的正路不是去啃 App 的加密凭据(auth.v1.dat 是 Electron safeStorage
密文,要弹钥匙串授权),而是走官方自建的 PAT:
PAT(pt-…) ──exchange──▶ jobToken(jt-…, 短期) ──COSY 签名──▶ gateway.qoder.com.cn
PAT 在 https://qoder.com.cn/account/integrations 自建,是官方支持的通道。
⚠️ PAT 过期不会自动续。 Qoder 官方明确「The SDK does not refresh PATs」, 过期后重新生成一个即可(
jobToken那一层插件自己刷)。
协议的三层坑(都已在官方 SDK 里核对过)
1. 鉴权不是 Bearer <token>,是 Qoder 自研的 COSY 签名:
aesKey = 随机 16 字符
info = AES-128-CBC(JSON({uid,security_oauth_token,name,aid,email}), key=iv=aesKey) → base64
cosyKey = RSA_PKCS1(aesKey, 内置公钥) → base64
payloadB64 = base64(JSON({version:"v1", requestId, info, cosyVersion, ideVersion:""}))
sig = md5(payloadB64 \n cosyKey \n 秒级时间戳 \n bodyBytes \n sigPath)
Authorization: Bearer COSY.<payloadB64>.<sig>
外加一整组 Cosy-* 头。
sigPath 是 pathname 去掉前导 /algo,且不含 query。
2. 请求体多一层自定义编码(URL 上的 Encode=1):先标准 base64,再按 Qoder 自定义
字母表重映射(= → $),最后做三段块旋转 [n-a,n) [a,n-a) [0,a),其中
a = floor(n/3)。见 qoderEncodeBody。
3. 响应是双层 SSE:外层 data: {"statusCodeValue":200,"body":"<JSON 字符串>"},
内层才是 OpenAI 形状的 choices[0].delta。控制哨兵还有 [DONE]、
[NOT_EXCEED_QUOTA]、[EXCEED_QUOTA]…、[NOTIFICATIONS]…。
两个平面(别混)
| 平面 | 端点 | 鉴权 |
|---|---|---|
| 推理平面 | gateway.qoder.com.cn/algo/** |
COSY 签名 + Encode=1 请求体 |
| OpenAPI 平面 | openapi.qoder.com.cn/** |
普通 Bearer <jobToken> + Cosy-ClientType |
额度与「签到活动」走的都是 OpenAPI 平面(App 自己就是这么打的),所以那边不需要签名,
只需要一个有效 jobToken。
凭据
读宿主侧 $DSH_HOME/qoder/pat(权限 0600;~/.dsh 已 bind mount 成容器里的
/root/.dsh),或环境变量(按优先级):
QODERCN_PAT
QODERCN_PERSONAL_ACCESS_TOKEN
QODERCN_API_KEY
内容就是那串 pt- 开头的 PAT 明文。插件只读明文 PAT,绝不碰 App 的目录。
安装
前置:已在 https://qoder.com.cn/account/integrations 生成 PAT,并写入上述路径或环境变量。
dsh plugin --profile web add github:yembors64632/dsh-qoder-connect
Desktop / TUI 把 --profile 换成 desktop / tui。
cordis.patch.yml 会注册 llm-qoder 这个 provider id(渠道名 qoder1),
不改动 profile 当前的默认模型。
自用改法:把这段提示词丢给你的 AI
插件是照着我自己的账号和环境写死的。你在自己环境改的时候,把下面这段连同插件目录交给 AI:
我在用 DeepSeek Harness(DSH),装了你写的 dsh-qoder-connect 插件。
这个插件是照着原作者的环境硬编码的,我要改成适配我自己的环境。
请你:
1. 先通读插件目录下的 lib/index.js,找出所有硬编码的路径、端点、常量,
特别是 COSY 签名里用到的身份字段;
2. 对照我下面的实际环境,逐项告诉我每一处需要改成什么,并给出修改后的完整代码;
3. 改完给我一条自检命令,用来验证 PAT 能读到、jobToken 能换到、上游能连通。
我的实际环境:
- 我用的是(Linux / macOS / Windows WSL),DSH 数据目录 $DSH_HOME 是:<填你的路径>
- 我的 PAT 我打算放在:<填路径,或说明用环境变量>
- 我的 Qoder 账号情况:<个人号 / 企业号>
- 插件报的错是:<贴报错>
注意:只改凭据读取路径、身份字段和上游端点,不要动 COSY 签名算法、
body 编码、双层 SSE 解析这些协议实现——那部分已在官方 SDK 里核对过。
你大概率要改什么
| 差异点 | 位置 |
|---|---|
| PAT 路径 / 环境变量名 | 凭据解析段 |
签名里的身份字段(uid / name / aid / email) |
#region COSY 客户端身份常量 |
| 网关域名 | DEFAULT_GATEWAY / DEFAULT_OPENAPI |
渠道名 qoder1 |
QODER_PROVIDER |
不要动 COSY 签名算法、body 编码、双层 SSE 解析——那部分已在官方 SDK 里核对过。
适配版本
| 项 | 版本 |
|---|---|
| 插件 | 0.1.0 |
| DSH 核心 | 0.1.5 / 0.1.6 / 0.1.7 alpha 线 |
| 上游 | Qoder CN(阿里 Qoder 国内版) |
| Node.js | ^22.19.0 || >=24.0.0 |
| 界面 | Web / Desktop / TUI |
DSH 核心版本不匹配会导致 DSH 启动失败,不是静默降级。装之前先对表。
依赖 @deepseek-ai/* 系列包(cordis、dsh-llm、dsh-llm-pi-ai、dsh-home-paths、
dsh-host-webserver、schemastery)与 @earendil-works/pi-ai。
如果 star 多了:作者会考虑做全版本适配
现在是单点适配——我验证通过的那一套环境能跑,换个版本就可能挂。这是有意的取舍: 在没确认有多少人用之前,为每个 DSH 版本做兼容矩阵的性价比不高。
如果这个仓库 star 多了(说明确实有人在用),作者会考虑做以下工作:
- 跨版本适配矩阵:把
0.1.5-rc.x/0.1.6-alpha.x/0.1.6/0.1.7各代的 peer range 与配置入口差异整理成表,插件加载时按宿主实际能力自适应。 - PAT 轮换与失效提示:PAT 官方不自动续期,计划在设置卡片上显示 PAT 剩余有效期, 失效时给出明确提示而不是静默报错。
- 上游变更的降级策略:推理平面与 OpenAPI 平面都是私有实现,随时可能变。 计划做「实时 → 上次成功 → 内置兜底」三级降级,并显示当前来源与失败原因。
- 安装体验:一条命令探测环境 + 拉取对应版本,替代现在的手工对照。
想要哪个,开 issue 说一声——用的人多就先做哪个。
风险
上游是私有实现,没有稳定契约。Qoder 服务端一改,插件就可能失效。 PAT 需要手工轮换(官方不自动续期)。这不是 bug,是这类方案的固有风险。
免责声明
本项目仅供个人学习与研究,驱动你自己账号在你自己的机器上使用。 使用者需自行遵守 Qoder 的服务条款。因使用本项目产生的任何后果 (包括但不限于账号受限、积分消耗、服务中断),由使用者自行承担。 仓库不含任何真实账号、凭据或密钥。
许可
MIT
No comments yet. Be the first to write one.