dsh-factory-provider
把 Factory(Droid)的订阅额度接入 DeepSeek Harness(DSH),让你在 DSH 里直接选用 Factory 的模型——GLM、Claude、GPT、Kimi、Qwen、Nemotron 等,走你自己的订阅额度。
零构建:装完即用,不需要编译。
免责声明:本项目是非官方的第三方插件,与 Factory 无隶属关系。它用你自己的 Factory API key 访问 Factory 服务,属于个人使用场景。请遵守 Factory 服务条款,多账号轮换等用法风险自负。
目录
它做什么
DSH 本身不认 Factory。这个插件在中间架了一座只监听本机的桥:
DSH(模型选择器)
↓
llm-pi-ai provider 条目(factory-g / factory-a / factory-o)
↓
本插件在本机开的回环网关(127.0.0.1)
↓ 自动附加你选的 Factory API key + 官方 CLI 头集合
Factory 推理服务(prem.factory.ai)
于是 Factory 的模型会直接出现在 DSH 的模型选择器里,和内置模型一样选用。你只需要一个 Factory API key(第 1 步),用掉的是你的 Factory 订阅额度。
三条路由分别对接不同的上游协议:
| 路由 | 覆盖模型 | 额度池 |
|---|---|---|
factory-g |
GLM / Kimi / MiniMax / DeepSeek 等 | Core 池模型(倍率低,但同样先扣标准额度) |
factory-a |
Claude 全系(Opus / Sonnet / Fable) | 标准订阅额度 |
factory-o |
GPT / Codex 系 | 标准订阅额度 |
支持的 DSH 版本
| 已验证 | DeepSeek Harness 0.2.0-rc.2(macOS 桌面版,实测通过) |
| 更早版本 | 未测试 —— 接口可能不存在,见下表 |
| 更新版本 | 未测试 —— 若接口有变动,插件会记日志而不是静默失败 |
查自己的版本:
dsh --version
插件依赖的 DSH 接口
这些是插件与 DSH 的接触面。缺哪个,对应功能就失效 —— 插件会在日志里写明原因,不会静默出错。
| 接口 | 用途 | 缺失时的表现 |
|---|---|---|
ctx.inject(["webServer", "settings"]) |
取得 web 端口与设置服务 | 插件不注册任何路由,日志:webServer/port unavailable |
webServer.register(route) |
注册回环网关与设置页接口 | 同上 |
settings.installSection(ctx, ns, schema, entry, hooks) |
注册设置页 | 自动降级到 settings.register |
settings.describe() / settings.mutate(ns, ops, revision) |
写入 provider 配置 | provider 写不进去 → 模型列表为空,日志:provider reconcile failed |
schemastery 的 .volatile() |
让设置项可写 | 保存设置报 has no volatile fields |
ctx.emit("loader/volatile-update") |
通知 DSH 重建模型目录 | 模型能用,但选择器可能要重启才刷新 |
怎么确认在你的版本上正常
- 装好并重启 DSH
- 打开 设置 → Factory (Droid),看「连接状态」徽标是不是 API key
- 点 测试连接 —— 返回 200 就说明从 DSH 到 Factory 整条链路通了
任何一步不对,先看插件目录下的 journal.jsonl(最后几行会写明是哪一步失败)。
使用流程
第 1 步:拿一个 Factory API key
这个插件只用 API key,不需要安装 droid CLI。
- 打开 https://app.factory.ai/settings/api-keys
- 点 Create Key,起个名字(比如
dsh) - 复制那串
fk-...——它只显示一次
key 是长期有效的(不过期),可以直接当推理凭据用,扣的是你的订阅额度,不是另一套计费。
还需要 DSH 本身,并确认 dsh 命令可用。
第 2 步:安装插件
把仓库 clone 到本地任意目录,然后:
dsh plugin --profile desktop add link:<你 clone 的目录>
desktop是 DSH 桌面版 GUI 使用的 profile 名;如果你是别的 profile,换成对应的名字- 用
link:安装表示直接引用本地目录——你改了源码,插件就跑新代码(改完需重启 DSH 生效)
安装完成后,重启一次 DeepSeek Harness,让插件完整加载。
卸载:
dsh plugin --profile desktop remove dsh-factory-provider
卸载时插件会自动清理它写进 DSH 的 provider 配置(按 baseURL 识别,不会碰你自己的其他 provider)。
第 3 步:把 key 粘进插件
打开 设置 → Factory (Droid) → 账号与 API key:
- 在「粘贴 Factory API key(fk-…)」输入框里粘上那串 key(可选填备注名)
- 点 保存并使用
保存后插件立刻切到这个 key,不需要重启。key 只存在本机(~/.dsh-factory-provider/accounts/<id>/api-key,权限 0600),不写进设置文件,也不进日志。
第 4 步:确认接入成功
打开 设置 → Factory (Droid)(在左栏「内置插件」下方),看「连接状态」面板:
- 徽标显示 API key(表示已配置)
- 能看到 token 有效期和组织 ID
- Provider 写入显示
clean或applied
如果徽标显示未配置 API key,去「账号与 API key」面板粘贴一个(见第 5 步之前的说明)。
最直接的验证:点 测试连接 按钮。它会真实发一条 16-token 的请求走完整链路:
- 成功 → 说明从 DSH 到 Factory 全线打通 ✅
- 失败 → 面板会给出上游返回的状态码和消息
同一个面板还能看「订阅额度」:标准池与 Core 池各自的 5 小时 / 周 / 月 用量进度条、重置倒计时、超额策略。
第 5 步:在 DSH 里选模型
接入成功后,Factory 的模型会出现在 DSH 的模型选择器里,按 provider 分组(Factory (Droid) — …)。直接选就行。
每个模型的可选思考强度(low / medium / high / xhigh / max 等)按 Factory 官方模型表的实际取值写入,在 DSH 的模型选项旁直接选。Claude 系走自适应 thinking(Factory 的 bedrock_anthropic 路由只接受这种),旧式 budget 参数会被上游拒绝。
遇到模型不可用? 部分模型有地区门禁(上游返回 Provider not available in this region),插件已把确认受限的几个从列表里剔除。
第 6 步:按需精简模型列表
DSH 的模型列表太长会很碍事。在设置页「路由与模型」面板里:
- 每个模型左侧有勾选框,逐条挑选;卡片右上角有全选 / 清空
- 勾完点保存
- DSH 的模型列表之后只保留你勾选的模型
语义:
- 一个都不勾 = 显示全部(默认行为,不会把列表清空)
- 某条路由的模型被全部取消勾选 → 该 provider 整条从列表消失
- 想恢复全部,点「全选」再保存
⚠️ 已知问题:保存后模型列表可能需要重启 DSH 才会刷新(配置已正确写入并持久化,但运行中的模型目录不会立刻重建)。设置页的模型勾选本身立即生效、不会丢失。
设置页说明
装好后在 设置 → Factory (Droid) 下是这样一个面板:
| 区块 | 内容 |
|---|---|
| 连接状态 | 一行事实:凭据徽标 · 推理主机 · provider 写入状态;右侧是测试连接 |
| API key | 每个 key 一张卡片,按钮按状态显示「选择 / 已选择」;另有查额度、删除,以及全局的「停用 / 启用」 |
| 订阅额度 | 标准池与 Core 池的 5h / 周 / 月 进度条、重置时间、超额策略 |
| 模型(折叠) | 三条路由的开关与模型勾选表;保存按钮就在折叠标题右侧,不用展开也能点 |
| 高级(折叠) | 配置项编辑 + 诊断日志 |
页面每 60 秒自动刷新状态与额度(编辑中的配置不会被轮询覆盖)。
--- | --- | | 连接状态 | 凭据徽标(API key / 未配置 / 已停用)、推理主机、provider 写入状态、测试连接按钮 | | 账号与 API key | 粘贴并保存 API key、多个 key 一键切换、按 key 查额度、删除 / 停用 | | 订阅额度 | 标准池与 Core 池的 5h/周/月 进度条、重置时间、超额策略、Extra Usage 余额 | | 路由与模型 | 三条路由的开关 + 每路由模型表(勾选 / ID / 名称 / 倍率 / 思考档位) | | 配置 | 各项配置可视化编辑 + 模型显示范围 | | 诊断日志 | 最近 10 条转发记录(时间 / 路由 / 模型 / 事件 / 上游状态 / 耗时) |
页面每 60 秒自动刷新状态与额度(编辑中的配置不会被轮询覆盖)。
多账号切换
一个 API key 属于一个 Factory 账号。如果你有多个账号,就为每个账号各建一个 key,都存进插件,然后一键切换:
| 操作 | 说明 |
|---|---|
| 保存并使用 | 粘贴一个 key(可填备注名),保存后立即切换过去 |
| 使用 | 切换到列表里已有的某个 key |
| 额度 | 单独查这个 key 对应账号的 5h / 周 / 月 用量 |
| 删除 | 移除这个 key。⚠️ 删除正在使用的那个会停用凭据——额度查询与模型调用随即失败,直到你选择其它 key |
| 停用 / 取消选择 | 「停用」= 不使用任何凭据;「取消选择」= 回到未选择状态(此时环境变量 FACTORY_API_KEY 若存在则生效) |
优先级:选中的 key > 环境变量 FACTORY_API_KEY(也读 DSH 凭据存储)。选中一个 key 就压过环境变量——否则一个残留的环境变量会静默钉死账号,让列表看起来失灵。
旧版快照:如果你用过早期版本(用 droid CLI 登录态做快照),那些目录会显示为「旧版快照」并且不再被读取,可以直接删除。
跨平台
macOS / Windows / Linux 完全一致,不需要任何系统组件。 这是用 API key 而不是 droid 登录态的直接好处:
| API key | |
|---|---|
| 有效期 | 不过期,无需续期 |
| 读取方式 | 直接读本机存下的字符串 |
| 系统依赖 | 无(不需要钥匙串 / 凭据管理器 / Secret Service) |
| 需要装什么 | 不需要 droid CLI,不需要任何其它东西 |
key 存在 ~/.dsh-factory-provider/accounts/<id>/api-key(Windows 是 %USERPROFILE%\.dsh-factory-provider\accounts\<id>\api-key),权限 0600,目录 0700。
如果你确实想改用 droid CLI 登录态(例如不想建 key),那属于 0.6.x 的能力,已在本版本移除;用
git log可以找回那部分代码。
配置项
cordis.patch.yml 里是出厂默认值;设置页的修改优先且写入插件自己的 settings 命名空间。两边字段一致:
| 字段 | 默认 | 说明 |
|---|---|---|
enabled |
true |
关闭后只保留诊断路由,并清理已写入的 provider |
routes |
["generic","anthropic","openai"] |
启用哪几条路由 |
cliVersion |
"0.231.0" |
网关呈现给 Factory 的 CLI 版本(UA)。保持默认即可,它是边缘校验的一部分 |
apiBaseURL |
"https://prem.factory.ai" |
推理主机。EU 等区域账号若不同,在这里改 |
quotaHost |
"https://api.factory.ai" |
额度端点主机 |
keyEnv |
"FACTORY_API_KEY" |
未选择任何 key 时,从这个环境变量(以及 DSH 凭据存储)取 key |
proactiveRefreshMinutes |
5 |
provider 写入未落地时的重试周期;0 关闭定时器(API key 不过期,无需刷新凭据) |
modelAllowlist |
[] |
模型显示范围:[] = 全部;非空则只显示列出的模型(建议在设置页勾选,不要手填) |
常见问题
Q:会消耗我的 Factory 额度吗?
三条路由都先扣标准额度,区别只在倍率(烧得快慢)和耗尽后的去向:
| 阶段 | 谁在用 |
|---|---|
| ① 标准池 | 所有模型,包括 GLM 这类 Core 模型 —— 倍率低所以扣得慢(GLM-5.3-Flash 0.06x vs Opus 5.5 1.6x) |
| ② Core 池 | 标准池耗尽后,Core 模型免费溢出到这里 |
| ③ Extra Usage | 再往后走预付余额 |
所以"Core 池模型"不等于"不占标准额度"—— 它们只是烧得慢。设置页「订阅额度」两个池子的进度条可以实时对照。
Q:插件会读走或上传我的凭据吗?
不会上传到任何第三方。凭据只在本机用于向 Factory 发起你主动触发的请求,网关只接受本机回环调用(即使 DSH 绑了 0.0.0.0 供局域网访问,外部调用也会被拒绝)。诊断日志 journal.jsonl 记录请求形态、上游状态码,以及便于排障的片段:system 开头 300 字、首条用户消息开头 200 字、上游错误响应体。不含 token,也不含完整请求体——但请知道它确实包含你提示词的开头部分,介意的话可以删掉该文件(插件会重建)。
Q:key 会存在哪里?安全吗?
存在本机 ~/.dsh-factory-provider/accounts/<id>/api-key,权限 0600(目录 0700)。它不写进 DSH 的设置文件、不进日志、不上传任何第三方。注意 key 是长期有效凭证——泄露等于账号被别人用,所以别提交进 git、别在截图里露出来。
Q:模型列表怎么这么长 / 有些模型用不了?
用设置页「路由与模型」勾选精简(见第 6 步)。部分模型有地区门禁,已被剔除。模型清单是对着账号实弹探测整理的——只有真实返回 200 的才收录。
Q:保存勾选后 DSH 模型列表没更新?
这是已知问题:配置已正确写入,但运行中的模型目录不会立刻重建。重启 DSH 后即可看到新列表。
Q:DSH 提示「API 密钥无效」怎么办?
先看「连接状态」的徽标,再点「测试连接」看真实上游响应。徽标显示未配置 API key 就说明还没粘 key(见第 3 步);显示已停用则是被手动关掉了,点「启用」即可。
Q:改了插件源码,为什么没生效?
插件用 link: 安装,但 DSH 只在启动时加载模块。改完代码需要重启 DSH。
工作原理
给想深入了解的读者:
- 凭据 — 你粘贴的 API key 存在本机(0600),网关每次转发时作为
Authorization: Bearer附加;key 不过期,所以没有刷新与回写。实测同一个 key 也能查额度(与订阅额度是同一份) - 请求重写 — 注入完整的
factory-cli头集合(UA /X-Factory-Client/x-stainless-*/traceparent/x-api-provider)、补齐 droid 身份 system 行(边缘硬门槛)、剥离未知字段;客户端 attribution 头一律不透传 - 会话亲和 —
x-session-id按(模型 × system 提示 × 首条用户消息)哈希派生,同一会话每轮相同,对齐官方 CLI 的会话级 id,避免打散 Factory 侧的前缀缓存(实测 20K+ token 会话命中率约 85%) - 协议适配 — 三条路由分别处理 Anthropic Messages、OpenAI chat/completions、OpenAI responses 三种协议,SSE 流式原样透传;上游 401 会重新解析凭据并重试一次
- 诊断 —
journal.jsonl记录每次转发的请求形态与上游状态;handler-error记录转发前就抛出的失败、apply-error记录插件加载崩溃(这两类失败原本会被宿主静默吞掉)
开发
node test/run.mjs # 65 项离线测试,不需要网络、不需要 API key
测试覆盖:API key 账号库与权限、凭据解析与切换竞态、请求净化规则、模型目录、桥接路由的回环守卫、设置生命周期与卸载回滚、网关端到端(本地 mock 上游,含 SSE 流式、断连取消与 401 重试)。全部离线,不需要网络、API key 或 droid CLI。
macOS 上如果系统 git/python3 因 Xcode 许可不可用,可用:
/Library/Developer/CommandLineTools/usr/bin/git --version
许可
MIT,见 LICENSE。
No comments yet. Be the first to write one.