dsh-llm-cc-switch
Manifest validExposes the accounts in a local CC Switch database to DeepSeek Harness: every account (Claude Code, Codex, OpenCode, Grok Build) becomes a model category in the picker, and the SQLite database is re-r
dsh-llm-cc-switch
DSH (DeepSeek Harness) 的 CC Switch 桥接插件:把 farion1231/cc-switch 里管理的账号直接变成 DSH 的模型,每次操作都重新读取 ~/.cc-switch/cc-switch.db,与 CC Switch 保持同步,无需重启 DSH。
映射方式
| CC Switch | DSH |
|---|---|
| harness(claude / claude-desktop / codex / opencode / grokbuild …) | provider 路由(如 cc-switch/claude → 选择器里显示 "Claude Code") |
| 账号(MiniMax、DeepSeek、Xiaomi MiMo …) | 该类别下的模型(显示为 MiniMax · claude-opus-4 [200k] · anthropic) |
- 端点 / 协议 / 密钥:在每次请求时按账号动态解析,不会在 DSH 端持久化。
- 协议支持:
anthropic-messages/openai-completions/openai-responses,对应claude*/openai类路由。内部复用 DSH 自带的@deepseek-ai/dsh-llm-pi-ai,流式、工具调用、重试语义与官方适配器一致。 - bearer-auth 密钥:以
tp-开头的 token-plan 密钥自动改用Authorization: Bearer发送(默认前缀可配置)。 - baseURL 护栏:每个账号的
baseURL在缓存时通过 scheme + host allowlist 校验,不在白名单的行直接跳过——这是对 cc-switch.db 内一行恶意 env 的最后一道护盾。
支持的 harness
CC Switch app_type | 支持情况 | 备注 |
|---|---|---|
claude | ✅ | 通过 ANTHROPIC_AUTH_TOKEN / ANTHROPIC_BASE_URL 解析,模型来自 ANTHROPIC_DEFAULT_*_MODEL / ANTHROPIC_MODEL / CLAUDE_CODE_SUBAGENT_MODEL |
claude-desktop | ✅ | 同上 |
codex | ✅ | 通过 auth.json + model_providers TOML + modelCatalog,支持 wire_api = chat | responses |
opencode | ✅ | 根据 npm 自动选 anthropic-messages 还是 openai-completions;AI-SDK 风格 options.baseURL |
grokbuild | ✅ | TOML [model.<profile>] + models.default;api_backend = chat | responses |
gemini · openclaw · hermes · pi | ⏸ | 是 CC Switch 的合法 app_type,但 settings_config JSON shape 在上游 farion1231/cc-switch 尚未稳定到可直接写一个准确 parser 的程度;列在源码注释里,等上游 schema 锁定再加 parser |
前提
- CC Switch 桌面端(SQLite 版本,数据目录
~/.cc-switch/,即cc-switch.db+settings.json) - DSH Desktop(内置
@deepseek-ai/dsh-llm-pi-ai与@earendil-works/pi-ai) - Node ≥ 22.19(与 DSH 自身一致)
兼容性
| 本插件 | 已验证的 DSH | 已验证的 @earendil-works/pi-ai |
|---|---|---|
| 0.3.1 | @deepseek-ai/dsh-llm / dsh-llm-pi-ai 0.2.0-rc.2(DSH Desktop 0.2.0-rc.2,Node 24.18.1 / Electron 44) | 0.87.1 |
| 0.3.0 | 0.1.5-rc.3 | 0.85.1 |
@deepseek-ai/dsh-llm / dsh-llm-pi-ai 的 peer range 是 >=0.1.5-rc.3 <0.3.0-0,@earendil-works/pi-ai 是 >=0.85.1 <0.88.0-0。适配器直接依赖 PiAiAdapter 合成的 profile 形状,所以 peer range 只覆盖实际验证过的版本线;DSH 升级后如果 profile 形状再变,test/adapter/profile-shape.vitest.test.js 会先失败而不是在选择器里失败。
安装
在目标 profile 的 package.json 中加入本地依赖并把它追加到 dsh.profile.bundles,然后:
dsh plugin --profile <name> install
启动 DSH 后在选择器里可以看到新类别;CC Switch 里增删改账号无需重启即可在下次选择/请求时生效。
配置(cordis.patch.yml 中该插件的 config)
- insert:
- id: cc-switch
name: 'dsh-llm-cc-switch'
config:
# source: cc-switch # 改写时使用的账号源,详见 lib/source/index.js
# dbPath: 'C:/.../cc-switch.db' # 默认 ~/.cc-switch/cc-switch.db
appTypes: [claude, claude-desktop, codex, opencode, grokbuild]
contextWindow: 200000 # 未声明上下文的模型的兜底窗口
maxTokens: 64000 # 请求输出上限
streamIdleTimeoutMs: 300000
bearerAuthPrefixes: [tp-] # 这些前缀开头的密钥走 Authorization: Bearer
urlAllowlist: # baseURL 护栏——下面的任一项都可在 config 里覆盖
schemes: ["http:", "https:", "ws:", "wss:"] # Scheme allowlist(注意结尾冒号,与 URL.protocol 一致);其他 scheme 全部拒绝
# hosts: [api.openai.com, anthropic.com] # 仅允许这些 host 后缀(可选)
opencodeSession: # OpenCode Go / Zen 的按会话 session 头
enabled: true # false = 完全不发(退回旧行为)
header: x-opencode-session # OpenCode 也认 session_id / x-session-id
# hosts: [opencode.ai] # 默认 opencode.ai 及其子域
urlAllowlist.schemes/hosts 是闭集 allowlist,不是配置 = 拒绝。这给了"你从 CC Switch 数据库加载,但实际不允许模型路由到某 host"的能力。
OpenCode Go / Zen 的 session 头
自 2026-09-06 起 opencode.ai 会拒绝没有稳定会话 id 的请求(400 MissingSessionID),且只认 x-opencode-session / session_id / x-session-id 这三个名字——pi-ai 自带的 session-affinity 在 Anthropic 协议上发的是 x-session-affinity,OpenCode 不认;DSH 目前在 pi-ai 适配器路径上也不发任何会话头(上游见 discussion #5495)。所以凡 baseURL host 命中 opencodeSession.hosts 的账号,本插件都会补上这个头:值取 DSH 的会话 id(每个会话稳定,OpenCode 才能据此做路由与提示词缓存),调用方没带会话 id 时(模型探测、手工单次调用)用本进程内稳定的兜底值——同样不会再 400。enabled: false 可以整体关掉。
API
import { CcSwitchStore } from "dsh-llm-cc-switch/source/internal";
const store = new CcSwitchStore({ dbPath: "/custom/cc-switch.db" });
await store.accounts(); // 解析后的账号列表,按 (appType, current, name) 排序
store.stamp; // mtime:size;为空表示还没读过
store.lastError; // 最近一次读库的 error
await store.routes(); // 当前能挂的 harness 路由
await store.account("<uuid>"); // 按 id 取一个(同一 id 可能出现在多个 app_type,取排序后的第一个)
await store.accountOf("claude-desktop", "<uuid>"); // 按 (app_type, id) 取,唯一
账号身份是 (appType, accountId) 这一对,而不是裸 id:CC Switch 会把同一个
provider 行同时镜像到 claude 和 claude-desktop 两个 app_type(UUID
完全相同,providers 表主键是 (id, app_type))。所以内部路由是
cc-switch-account/<appType>:<accountId>,Account 上也带 accountKey;选择器里
展示的 model id 仍是 <account-uuid>::<wire model id>,老会话/默认模型配置照常
解析。
新增一种账号源只要写一个 AccountStore 子类,然后调用:
import { registerAccountSource } from "dsh-llm-cc-switch/source/internal";
registerAccountSource("my-source", (config) => new MyStore(config));
并在 cordis.patch.yml 的 config.source 里写 "my-source" 即可,不改这个插件的代码。
安全性
- 不存储密钥:账号密钥从 CC Switch
settings_config直读到请求,无中间缓存层。 - 不写入数据库:以
readOnly: true打开cc-switch.db——这个插件从不修改 CC Switch 的状态。 - 日志脱敏:
logger.warn打印的 row info 走redactAccountShape+redactUrl,只出现sk-t…abcd这种前缀/后缀保留形式;Authorization/x-api-key/Bearer …在日志头里一律替换为***redacted***。 - baseURL 护栏:见
urlAllowlist,每行数据从 store 加载前就被过滤,不在白名单直接跳过。 - 披露:
weichen.work@qq.com(见SECURITY.md)。
开发
npm install # 会装上 devDependencies 里的 harness 包,adapter 测试才能跑
npm test # vitest run:parser / allowlist / redact / 注册表 / adapter seam
npm run test:integration # node --experimental-sqlite,跑真实 SQLite fixture
npm run test:all # 两套都跑
npm run test:watch # vitest --watch
devDependencies 固定了本插件验证过的 @deepseek-ai/dsh-llm / dsh-llm-pi-ai / @earendil-works/pi-ai 版本,test/adapter/ 下的两个 seam 测试直接 import 它们;只装 vitest 的话这两个文件会因为解析不到 peer 而整文件失败(其余 8 个文件仍然通过)。
test:integration 走的是 node --test 而不是 vitest——vite-node 的 pre-bundle 在 Windows 上不能解析 node:sqlite 内建,所以单独拆开;两套测试都通过才算过 CI。
已知限制
- 只支持 API Key 类账号;Codex 的官方 OAuth(ChatGPT 登录)、claude 官方登录账号会被跳过。
- 类别(harness 路由)在 DSH 启动时注册;CC Switch 新增一种全新 harness 需要重启 DSH 才出现(账号/模型的增删改无需重启)。
- 模型为纯文本模态;图片输入暂未声明。
- grokbuild 解析器只接受
api_key直接出现;env_key(环境变量名)等价形式需要等 CC Switch 上游grokBuildConfig.ts提供解析后产物。 gemini/openclaw/hermes/pi这四种 cc-switch 已经识别的 app_type,暂不在默认appTypes里——它们的 settings_config JSON 形态未稳定到能负责任地写 parser。
Comments
Loading…
Similar plugins
by a981008
CC Switch bridge for DeepSeek Harness: mirrors cc-switch providers and models into DSH, and shows each provider quota or balance.
★ 0
MIT
TypeScript
Sep 18, 2026
dsh plugin --profile web add dsh-switchAdds CC Switch providers and models to DeepSeek Harness, with provider filtering and model-name search.
★ 0
dsh plugin --profile web add dsh-ccswitchby kam74515-boop
Import local Codex, Grok, Claude, OpenCode, and CC Switch logins into DSH; pick sources and enable models in Settings.
★ 3
JavaScript
Aug 14, 2026
dsh plugin --profile web add dsh-everything-oauthby fu827707013
Reuses the CodeBuddy CLI sign-in to bring its models into DeepSeek Harness, with a settings card showing account, token expiry, and remaining credit.
★ 7
↓ 455/wk
MIT
TypeScript
Oct 17, 2026
dsh plugin --profile web add dsh-codebuddy-cliby chenbin-dev
导入本地 Claude、Codex、Grok、Gemini、Copilot、OpenCode 与 CC Switch 配置。 为支持的官方供应商提供 OAuth 登录。 从 OpenAI 兼容网关的 /v1/models 与 /models 发现 CC Switch 模型。
★ 4
↓ 295/wk
NOASSERTION
JavaScript
Aug 21, 2026
dsh plugin --profile web add dsh-auth-everyingby katsos
LLM provider that runs the locally installed Claude Code CLI as the model backend, so requests go through an existing Claude subscription instead of a metered API key; native tool calls are bridged ov
★ 6
MIT
TypeScript
Aug 15, 2026
dsh plugin --profile web add dsh-claude-cli