← 返回列表
未验证
将 GitHub Copilot 订阅 桥接为 DeepSeek Harness dsh 中的普通 LLM 提供商。
尚未跑自动兼容性验证,可查看页面内的依赖与入口分析。 · 最近上游提交 2026/9/3 · 已提供中文文档
将 GitHub Copilot 订阅用作 DSH LLM 提供商
综合分
29.8
GitHub 分
29.8
用户评分
—
★ Stars
2
周下载量
—
安装插件(需先安装 dsh CLI 引擎:npm install -g @deepseek-ai/dsh)
dsh plugin --profile web add youngrock-labs/dsh-provider-copilot该插件未发布到 npm,走 GitHub 源安装(pnpm 若拦截 prepare 脚本,按其提示在 pnpm-workspace.yaml 的 allowBuilds 中放行后重跑)
数据截至 2026/9/19(元数据每日更新 · 实装验证按队列轮转,单条结论的验证时间见上方)
用户评分
还没有人投票,来当第一个
订阅周报,不错过优质插件更新
每周一封 · 高评分插件 + 新用户活动
README
dsh-provider-copilot
将 GitHub Copilot 订阅 桥接为 DeepSeek Harness (dsh) 中的普通 LLM 提供商。
范围
- ✅ 聊天补全(流式)
- ✅ 模型列表(白名单 ∩ 远程)
- ✅ 推理流透传(delta.reasoning_content → reasoning 块)
- ✅ /copilot login | logout | status 命令
- ✅ 带严格字段允许列表的 JSONL 可观测性
- ❌ 工具 / 函数调用(明确不在范围内)
- ❌ Copilot CLI 运行时 / FFI(未使用)
架构
该包是一个 dsh 插件包:一个 cordis 对象插件
(name/inject/apply),其 apply(ctx) 在
harness LLM 服务上注册一个提供商路由。dsh 完全通过该注册来发现模型组 —— 无需修改 dsh 源码。
┌────────────────────────────────────────────────────────────────────┐
│ dsh (host, any profile) │
│ cordis loader ── apply(ctx, config) │
│ └─ ctx.llm.registerAdapter(["copilot"], CopilotAdapter) │
└────────────────┬───────────────────────────────────────────────────┘
│
▼
┌────────────────────────────┐ ┌────────────────────────────────┐
│ CopilotAdapter │──▶│ CopilotClient (HTTP) │
│ • dsh StreamChunk emit │ │ • layered timeouts │
│ • no tools ever │ │ • SSE parser │
│ • whitelist (+ ∩/models) │ │ • 429 retry once │
│ • alias collapse │ │ • never hardcodes base URL │
└────────────┬───────────────┘ └────────────────┬───────────────┘
│ │
▼ ▼
┌────────────────────────────┐ ┌────────────────────────────────┐
│ JsonlLogger + Metrics │ │ AuthManager │
│ • ring buffer for status │ │ • Device Flow state machine │
│ • JSONL 0600/0700 daily │ │ • token exchange + cache │
│ • strict field allowlist │ │ • blocking + bg refresh, dedup│
└────────────────────────────┘ └────────────────────────────────┘
在 dsh 内部,流式响应使用 harness 块协议
(block-start / text-delta / reasoning-delta / block-end / usage /
finish);reasoning 增量会渲染在 dsh 可折叠的“thinking”行中。
该适配器是纯聊天:它从不转发 tools,而 dsh 能很好地处理这一点 —— 不带工具调用的助手回复会正常结束该轮次。
时序:登录后的首次调用
user dsh CopilotAdapter CopilotClient AuthManager github
│ /copilot login │ │ │ │
│────────────────────▶│ │ │ │
│ (returns code+URL; device flow continues in the background) │
│◀── code: ABCD-1234 ─│ │ │ │
│ authorize in browser │◀── ghu_* ─│
│ │ │ │──── exchange│
│ │ │ │◀ Copilot bearer + endpoints
│ first prompt │ │ │ │
│──────────────────▶│ stream(req) │ │ │
│ │───────────────▶│ getBearer() │ │
│ │ │─────────────▶│ cached │
│ │ │◀── bearer ───│ │
│ │ │──── POST /chat/completions (SSE) ─▶
│ │◀── StreamChunks│◀── parsed chunks ────────────────
│◀── rendered ───────│ │ │ │
非公开 API 注意事项
本项目使用 api.github.com/copilot_internal/v2/token 将 GitHub OAuth
令牌兑换为 Copilot bearer 令牌。该端点是一个
非公开、不稳定的接口;GitHub 可能随时更改或撤销它。
在生产环境中使用需自行承担风险。
其他合规注意事项:
- User-Agent 必须以 GitHubCopilot 开头;否则反爬机制会返回
一个看起来像认证错误的 403。
- 该插件附带官方 VSCode Copilot Chat OAuth 的 client_id
(Iv1.b507a08c87ecfe98)。令牌在你的 GitHub 账户下生成,
仅用于你所拥有的 Copilot 订阅。
- Device Flow 的 scope 仅为 read:user。不会请求任何
repository / gist / issue scope。
- dsh 要求每个 provider HTTP 请求都带有应用归属信息;Copilot
端点还额外要求 GitHubCopilot User-Agent。发布前请针对
实际请求验证你所使用的请求头组合。
安装
该包是一个 dsh bundle:其 manifest 声明了 dsh.bundle,并且
附带一个 cordis.patch.yml,用于插入插件行。因此使用
dsh plugin 安装它时,会将其添加到 profile 的 bundle 层中:
bash
install from GitHub:
dsh plugin --profile add github:youngrock-labs/dsh-provider-copilot
install from a local checkout:
dsh plugin --profile add /absolute/path/to/dsh-provider-copilot
重启 dsh(或重新加载 profile)以激活该插件。它以休眠状态挂载:
copilot provider 组会立即被公布——无需任何登录即可出现在
模型选择器中——而第一个不带凭据的请求会报告 MISSING_CREDENTIAL,
并附带指向 /copilot login 以及下方环境变量的提示。
安装插件后模型选择器中立即显示 Copilot (GitHub) 组
不打包的开发方式:手动将以下行添加到 profile patch 中
yaml
- id: llm-copilot
name: './path/to/dsh-provider-copilot/src/plugin/plugin.ts'
用法 — 在 dsh 内部
/copilot login | logout | status 命令是真正的 dsh 命令,
在宿主命令服务存在时注册(dsh Web 会针对它们解析 /
开头的行):
/copilot login # 设备流程:打印验证 URL + 代码,并在
后台完成授权
/copilot status # 来源、过期时间、模型数量、p50/p95 延迟
/copilot logout # 清除缓存 + 内存 + 指标
/copilot login 返回 GitHub 验证 URL 以及需要在该处输入的一次性代码;
在浏览器中批准后,授权将在后台继续进行:
Copilot 登录提示输入 GitHub 设备代码
在 dsh 的模型选择器中(安装后即可看到该分组,见上文),
选择 Copilot (GitHub) 分组内的模型。选择某个模型会将其设为
新会话的默认模型;每个会话保留各自记录的选择。随时可再次选择以切换模型。
发送请求需要凭据:设置 COPILOT_TOKEN / COPILOT_GITHUB_TOKEN,或运行
上文的 /copilot login。登录后,所公布的列表将与上游 /models 目录取交集。
用法 — 编程方式(BYOK)
ts
import { AuthManager, CopilotClient, CopilotProvider } from "dsh-provider-copilot";
const auth = new AuthManager({
byok: { kind: "github", token: process.env.MY_GITHUB_TOKEN! },
});
const client = new CopilotClient({
getBearer: async () => {
const s = await auth.getSession();
return { token: s.token, endpoints: { api: s.endpoints.api } };
},
});
const provider = new CopilotProvider({ client });
for await (const chunk of provider.stream({
model: "gpt-4o-mini",
messages: [{ role: "user", content: "hi" }],
})) {
if (chunk.type === "text") process.stdout.write(chunk.text);
}
令牌来源优先级
AuthManager 按以下顺序解析凭据:
1. byok 构造函数选项 — 一个 { kind: "bearer" | "github", token }。
2. env COPILOT_TOKEN — 原始 Copilot bearer;跳过交换。
3. env COPILOT_GITHUB_TOKEN — 一个 GitHub 令牌;驱动交换。
4. 来自先前 /copilot login 的磁盘 OAuth 缓存。
5. ~/.config/gh/hosts.yml(需选择启用:DSH_COPILOT_ALLOW_GH_HOSTS=1)。
6. GH_TOKEN / GITHUB_TOKEN(需选择启用:DSH_COPILOT_ALLOW_ENV_GH=1)。
来源 5–6 需选择启用,因为“任意 GitHub 令牌”意外泄漏到
Copilot 专用凭据面中很容易发生。
配置
| 环境变量 | 作用 |
| ----------------------------- | ---------------------------------------------------------- |
| COPILOT_TOKEN | 跳过交换;直接用作 Copilot bearer。 |
| COPILOT_GITHUB_TOKEN | 用于交换 Copilot bearer 的 GitHub 令牌。 |
| DSH_COPILOT_ALLOW_GH_HOSTS | 1 启用读取 gh hosts.yml 作为回退。 |
| DSH_COPILOT_ALLOW_ENV_GH | 1 启用读取 GH_TOKEN / GITHUB_TOKEN 回退。 |
| DSH_COPILOT_NO_LOG | 1 禁用 JSONL 日志写入(不创建目录 / 文件)。 |
| XDG_CONFIG_HOME | 用于缓存和日志位置的标准 XDG 覆盖项。 |
可观测性
- 内存环形缓冲区: 最近 10 次成功调用,用于
/copilot status 的 p50/p95。
- JSONL 日志: ~/.config/dsh/copilot/log/copilot-YYYY-MM-DD.jsonl。
字段是硬编码的允许列表:
ts, requestId, event, model, latencyMs, promptTokens, completionTokens,
totalTokens, errorCode, source, sku。
任何尝试记录该集合之外内容的操作都会在运行时被拒绝。
- 保留期: 默认 7 天;清理在新 UTC 日期的首次写入时惰性执行;失败时静默处理。
- 权限: 目录 0700,文件 0600,与认证缓存一致。
故障排除
| 症状 | 可能原因 / 修复 |
| ---------------------------------------------- | ----------------------------------------------------------------------------------------------------- |
| 来自 api.github.com 的 403 scraping | 非 Copilot UA。不要覆盖内置请求头。 |
| token_exchange_forbidden (403) | 账户没有 Copilot 权益(个人未订阅,组织/企业席位未分配)。 |
| token_exchange_unauthorized (401) | GitHub token 过期。/copilot logout 然后 /copilot login。 |
| no_token_source | 没有可用于认证的凭据。设置 COPILOT_TOKEN / COPILOT_GITHUB_TOKEN 或运行 /copilot login。 |
| http_connect_timeout | 网络 / DNS。检查企业代理;如有需要,调整 timeouts.connectMs。 |
| http_first_byte_timeout | 上游响应缓慢。调整 timeouts.firstByteMs。 |
| http_idle_timeout | 流在传输中途停滞。调整 timeouts.idleMs。 |
| /copilot status 计数中缺少模型 | 不在白名单 ∩ 上游中。如果你知道该 id,请向 CopilotProvider 传入自定义 whitelist。 |
| unknown subcommand: X | 仅支持 login、logout、status。 |
开发
bash
npm install
npm test # 160+ tests across auth / client / provider / plugin / commands / observability / e2e
npm run typecheck
npm run lint
面向 dsh 的新代码位于 src/plugin/ 下(适配器、分块转换、
错误分类、插件入口、dsh 命令处理器);旧版 BYOK
CopilotProvider API 保持不变。
可行性 PoC(设备流程 → 模型 → 流):
bash
npm run poc -- device
export GH_OAUTH_TOKEN=ghu_xxx
npm run poc
覆盖率是可选的:
bash
npm i -D @vitest/coverage-v8@2.1.8 # match your vitest version
npx vitest run --coverage
许可证
MIT — 见 LICENSE。扫码进群