edynasty/dsh-opencode-go-provider ↗★ 1
dsh-opencode-go-provider
OpenCode Go LLM provider bundle for DeepSeek Harness (DSH rc.6).
AI Analysis
核心用途是为 DSH 提供 OpenCode Go 网关的 LLM 模型路由。适合需要接入 OpenCode Go 模型的用户。必要条件是需使用 DSH rc.6 版本,且需作为 Git 依赖安装。
Install
npx -p @deepseek-ai/dsh dsh plugin --profile web add github:edynasty/dsh-opencode-go-providerREADME
Read the full README ↗dsh-opencode-go-provider
OpenCode Go LLM provider bundle for DeepSeek Harness (DSH rc.6): a single
opencode-go model route over the OpenCode Go gateway, with a Web Connect
settings card, a stale-while-revalidate model catalog and safe diagnostic
commands.
Status: community software, not published to npm. This package is installed as a commit-pinned Git dependency into a DSH profile; the npm registry is not an installation path. It is not affiliated with, endorsed by, or sponsored by DeepSeek, OpenCode, or any model provider vendor. See LICENSE and THIRD_PARTY_NOTICES.md.
Requirements
- DeepSeek Harness DSH rc.6 (the bundle targets the
0.1.0-rc.6peer graph). - Node.js
^22.19.0 || >=24.0.0. - corepack-managed pnpm 11.7.0 (
corepack enablefirst ifpnpm --versiondoes not resolve through Corepack). - An OpenCode Go API key. The key is stored and resolved only through the
DSH credentials service at operation time under the ref
OPENCODE_GO_API_KEY; it is never written into settings, the catalog, logs, errors or the package.
Installation (Git, commit-pinned)
The package is not published to npm; the supported installation is a commit-pinned Git dependency for the DSH web profile:
dsh plugin --profile web add github:edynasty/dsh-opencode-go-provider#d2a447610a5dff4006ac966525effd9669342a78
lib/ is committed to the repository, so the Git install loads the bundle
without a build step. Uninstall removes the package and its bundle row:
dsh plugin --profile web remove dsh-opencode-go-provider
Coexistence with the web base bundle
The web profile's base bundle (@deepseek-ai/dsh-llm-pi-ai) already declares
opencode-go in the provider directory (its catalog ships the route). This
bundle adopts that entry instead of re-registering it, and takes over the
route with its own adapter (richer SWR catalog), Connect card and doctor
routes. No profile changes — and in particular no need to disable
llm-pi-ai — are required to install alongside the base bundle.
What the bundle registers
- One provider route:
opencode-go, mounted by thellm-opencode-gobundle row (cordis.patch.yml). - One settings namespace:
llm-opencode-go(refresh interval, freshness window, network timeout, deprecated grace, credential ref). - A Web Connect settings card (injected through
dsh.client.inject) that can connect, test the connection, run diagnostics and disconnect. - A standalone
bin(dsh plugin --profile web exec dsh-opencode-go-provider) forstatus,doctor,migration-dry-runandmigration-apply.
Model catalog and protocols
The embedded catalog (catalog/models.json) is derived from OpenCode's
models.dev metadata (https://models.opencode.ai/api.json); only the
opencode-go provider record is retained. Each model carries its own protocol
from that metadata, and the adapter dispatches per model with no
model-name-prefix guessing:
| Protocol | Selection |
|---|---|
openai-responses | models whose models.dev SDK metadata maps to @ai-sdk/openai |
openai-completions | models mapped to @ai-sdk/openai-compatible (the default class) |
anthropic-messages | models mapped to @ai-sdk/anthropic (base URL https://opencode.ai/zen/go) |
Model availability is checked against the live endpoint
https://opencode.ai/zen/go/v1/models, which contributes only available
ids; models.dev remains the sole authority for protocol, context, modalities,
cost and reasoning metadata.
Catalog lifecycle (stale-while-revalidate)
- Embedded catalog is available immediately at boot — offline and without a credential.
- Background refresh keeps a 5-minute freshness window; within it reads never touch the network.
- A 60-minute periodic refresh revalidates; a stale read schedules one single-flight background refresh.
- Every network attempt is bounded by a 10-second timeout.
- Successful refresh writes the cache atomically (same-directory temp,
0600, fsync, rename) at$DSH_HOME/cache/dsh-opencode-go-provider/catalog.jsonand only then swaps the in-memory snapshot; in-flight requests keep the snapshot they started with. - Offline fallback: a missing or corrupt cache serves the embedded catalog
(
origin: embedded/corrupt); the corrupt file is never deleted, and failures never overwrite the last good state. - Quarantine: a live id with no models.dev metadata is recorded with a sanitized machine-readable reason and is never exposed as a callable model.
- 14-day deprecated grace: a models.dev-known model missing from live
availability stays selectable with a
deprecatedAttimestamp; after 14 days it is evicted (and resurrects if it returns to live).
Connect / status / doctor / disconnect
- Connect (Web card or Host route) stores the key only in the DSH
credentials service under
OPENCODE_GO_API_KEY; keys are never rendered back, echoed or written anywhere else. - Status reports sanitized facts only: configured yes/no, source (embedded/cache/refreshed), model count, last refresh, last attempt, refresh ok/failed counts.
- Test connection / doctor performs exactly one authenticated
GET https://opencode.ai/zen/go/v1/modelsand reports sanitized counts and fixed error codes; it never calls generation endpoints. - Disconnect removes only the
OPENCODE_GO_API_KEYcredential. Theopencode-goroute and Connect card remain registered and selectable — disconnect never removes the provider, writes it to a disabled list, or touches other providers.
connect/disconnect are Host-only: the standalone bin refuses them with a
fixed message because the DSH credential store is owned by the running Host.
Migrating the manual route
If an older setup configured llm-pi-ai.providers.opencode-go by hand, the
bundle can migrate it away:
dsh plugin --profile web exec dsh-opencode-go-provider migration-dry-run
dsh plugin --profile web exec dsh-opencode-go-provider migration-apply --revision
migration-dry-runis read-only and prints the target, the SHA-256 revision and removed key/line counts (never the key names or values).migration-applyverifies the expected revision, acquires a same-directory lock, re-reads and re-hashes immediately before writing, creates a timestamped recoverable backup (never touching credentials files), and publishes atomically. A concurrent edit yieldsconflictwith zero residue; a second apply is an idempotentno-change.- Only conservative YAML shapes are supported: block mappings without flow
maps, anchors or aliases are migrated; unsupported shapes abort
(
unsupported-shape) before any lock, backup or write. - The migration preserves the default model, all other providers, comments,
quoting and key order — only the
llm-pi-ai.providers.opencode-goblock is removed, and the credential ref is left untouched.
Security
See SECURITY.md for the supported scope, the private reporting route, credential handling and the safe-diagnostics contract.
Development
See CONTRIBUTING.md for setup, the TDD workflow, the strict-type/no-private-import rules, the 250-LOC production ceiling and the full local gate:
corepack enable
pnpm install --frozen-lockfile
pnpm run check
CI (.github/workflows/ci.yml) runs the same gates on Node 22.19.0, 24 and 26
with pnpm 11.7.0 and a frozen lockfile. Live smoke requires both a local
RUN_OPENCODE_GO_LIVE=1 opt-in and a local OPENCODE_GO_API_KEY; CI
injects neither, so the step always skips.
License
MIT — see LICENSE. Upstream notices and attribution are retained in THIRD_PARTY_NOTICES.md.