cainiao1992
dsh-codebuddy-auth
CodeBuddy (Tencent IOA) provider plugin for DeepSeek Harness: OAuth login, token refresh, and model sync via native dsh seams
- Stars
- 0
- Language
- JavaScript
- Created
- Aug 16, 2026
- Updated
- Aug 16, 2026
Introduction
dsh-codebuddy-auth
English | 简体中文
A DeepSeek Harness (DSH) port of kuops/opencode-codebuddy-auth — use Tencent CodeBuddy (IOA) chat models directly in DSH: browser OAuth login, automatic token renewal, and automatic model-list sync. Log in once, and craft-agent models such as deepseek-v4-pro, glm-5.2, kimi-k3-1, and minimax-m3 appear in the model picker.
How it works
The original OpenCode plugin works through three hooks; this package maps each one onto a native DSH seam, with zero interception on the request path (DSH's pi-ai adapter natively speaks the OpenAI-completions protocol, the credential is sent automatically as Authorization: Bearer, and route headers pass through verbatim):
| OpenCode plugin | DSH equivalent |
|---|---|
config hook: register provider + discover models from /v3/config | the llm-pi-ai.providers.codebuddy route, which the plugin creates on first boot and syncs your account's real model list into after login |
auth hook: IOA browser OAuth + polling + refresh | the codebuddy model tool (login / status / refresh / logout / sync-models) + automatic renewal at startup |
token stored in auth.json | the ctx.credentials service (~/.dsh/.credentials.yaml, resolved per request, hot-swapped) |
Installation
DSH installs profile plugins through its official dsh plugin CLI (a thin pnpm forwarder that installs the dependency, appends the package to the profile's dsh.profile.bundles layer stack, and mounts the plugin via the bundle's in-package patch — no manual file editing).
Prerequisite: make sure pnpm is on your PATH, e.g. via Homebrew:
brew install pnpm
Install the plugin
dsh plugin --profile web add github:cainiao1992/dsh-codebuddy-auth
This single command resolves the dependency from GitHub, installs it, and activates the plugin as a profile layer.
Restart DSH
Restart DSH. On first boot the plugin creates the llm-pi-ai.providers.codebuddy route itself (with a placeholder model list), so CodeBuddy already appears in the Models page — unauthenticated — before you log in.
Log in
You can log in either through the agent, or from the command line. Pick one.
Option A — through the agent
Tell the agent "log in with codebuddy". The agent calls the codebuddy tool, which opens the IOA login page in your browser, polls in the background, and once the token arrives automatically writes credentials, writes JWT-derived identity headers (X-User-Id etc.) into the route, and replaces the placeholder models with your account's real /v3/config list.
Option B — from the command line (headless / bootstrapping)
# Directly, no npm deps, Node >= 18 only:
node ~/.dsh/profiles/web/node_modules/dsh-codebuddy-auth/bin/login-flow.mjs
# Or via the package bin from the install directory:
cd ~/.dsh/profiles/web && pnpm exec codebuddy-login
# Add --no-browser on a remote server / headless box
The CLI writes the credentials and ensures the llm-pi-ai.providers.codebuddy route exists in settings.yaml (China edition by default; --international pre-creates an international route). The plugin fills in identity headers and the model list at its next startup (or when the codebuddy tool is invoked).
Uninstall
dsh plugin --profile web remove dsh-codebuddy-auth
This removes the dependency and takes the plugin back out of the profile layer stack. Restart DSH to unload it.
International edition
The plugin targets the China edition by default (copilot.tencent.com / www.codebuddy.cn). To use the international edition (www.codebuddy.ai), log in with the CLI's --international flag — it not only logs you into codebuddy.ai, but also points the llm-pi-ai.providers.codebuddy route at the international API for you, so a fresh install (no route yet) goes straight to the international edition:
codebuddy-login --international # or node bin/login-flow.mjs --international
Everything else follows automatically:
- Chat requests hit
https://www.codebuddy.ai/v2(the route'sbaseURL). X-Domainfollows the baseURL — the plugin rewrites it towww.codebuddy.aiwhenever the route points atcodebuddy.ai.- Login / refresh / model discovery (
/v3/config) use the international endpoints, because the plugin derives itsserverUrl/domainfrom the samebaseURL.
Omit --international to log into the China edition (the default).
Usage
- Switch models: pick any model under CodeBuddy in the model picker (e.g.
deepseek-v4-pro) - Status: "check codebuddy status" → the
codebuddytool'sstatusaction - Renewal (automatic, three layers): ① at every startup, the token is renewed when less than 5 minutes of validity remains (or it has already expired); ② while running, a check every 30 minutes renews whenever less than 1 hour remains — covering a long-lived dsh that never restarts; ③ if the refresh token itself is invalidated (password change / revocation), the first two layers fail and log it — then say "refresh codebuddy" to confirm, or log in again
- Model updates: after Tencent ships new models, say "sync codebuddy models" →
sync-models - Logout: "log out of codebuddy" → clears stored credentials
Files
lib/index.js— the Cordis host plugin (host composition row). Registers thecodebuddytool; refreshes/syncs at startup.lib/codebuddy-core.mjs— core OAuth, JWT decoding, and/v3/configdiscovery logic; dependency-free.bin/login-flow.mjs— standalone login CLI; no npm dependencies.cordis.patch.yml— in-package patch (self-mount row for bundle consumers).
Known limitations (all verified empirically)
POST /v2/chat/completionsdoes not check User-Agent — any UA works; but the request must bestream: true(non-streaming returnscode 11101). DSH's pi-ai adapter is streaming by default, so nothing to handle.GET /v3/config(model discovery) does check User-Agent — any non-VSCode-shaped UA gets a 400. The plugin'sfetchRemoteModelssends its own direct request (bypassing DSH's user-agent attribution override) and explicitly carries a VSCode UA.- Models are declared as non-reasoning (no reasoning parameters sent), matching the original OpenCode plugin's behavior; the API reports supportsReasoning for every model, so add
compaton the route if you want it.
License
MIT