dsh-web
zhu1090093659/dsh-webDeepSeek Harness(DSH)Web 插件聚合生态包 · 一切皆插件,创意工坊分发(dsh-market.com)
Free OpenCode Zen models, natively inside DSH (DeepSeek Harness).
No API key. No registration. No extra process.
English | 简体中文
opencode2dsh registers a native DSH LlmAdapter that streams directly from
OpenCode Zen's anonymous free lane — the same
models OpenCode's own CLI uses without an account, served to your DSH model
picker as a regular provider called opencode2dsh.
Requests leave your machine looking exactly like traffic from the OpenCode CLI (same user agent, same correlation headers), and the model catalog stays fresh through a three-tier fallback chain. There is nothing to log into and nothing to host.
legacy/)muse-spark-* models expose only upstream-supported effort levels, and no selection keeps the provider defaultimage in modalities.input, and refused for the ones that declare text only; models.dev being silent falls back to the live-verified vision familyFrom the plugin market (recommended, once this repo is listed there):
in DSH open Settings → Plugin Market, search opencode2dsh, one-click
install.
From npm:
dsh plugin --profile web add @opencode2dsh/dsh-plugin
From source (build the tarball yourself):
git clone https://github.com/FishBottle7/opencode2dsh.git
cd opencode2dsh/packages/plugin
pnpm install && pnpm pack
dsh plugin --profile web add ./opencode2dsh-dsh-plugin-<version>.tgz
Verify: restart dsh web, open the model picker, and pick a model from
the opencode2dsh group.
Requires DSH (DeepSeek Harness) 0.1.7 or newer with a web profile (the IP 池
settings page rides the 0.1.7 Plugins page contract); Node.js ≥ 20 (already
present if DSH runs); outbound HTTPS to opencode.ai and models.dev.
Defaults work out of the box. Override via the profile's cordis.patch.yml:
- id: opencode2dsh
name: '@opencode2dsh/dsh-plugin'
config:
mode: adapter # adapter (default) | sidecar
providerId: opencode2dsh
refreshSeconds: 300 # catalog refresh cadence
| Option | Default | Description |
|---|---|---|
mode | adapter | adapter: native LlmAdapter streaming straight from Zen. sidecar: legacy local-agent mode, not bundled — build the agent from legacy/agent and pass agentPath. |
providerId | opencode2dsh | Provider name shown in DSH. |
refreshSeconds | 300 | Live catalog refresh interval. Pricing metadata refreshes every 24 h. |
allowedModels | [] | Model whitelist, adapter mode only — legacy sidecar ignores it (plugin 0.3.14+, issue #83): exact model ids DSH may show and call. Empty exposes every eligible free-lane model. Narrowing only — paid/deprecated/blocklist/probe rules still win, and a direct call to a non-whitelisted id fails fast with a tagged error before any network traffic. |
agentPath | auto-resolved | Sidecar only: path to the agent binary. |
agentArgs | — | Sidecar only: extra CLI args for the agent. |
restartDelayMs / restartMaxDelayMs / maxConsecutiveCrashes | 1000 / 60000 / 5 | Sidecar only: restart backoff and circuit breaker. |
firstEventMs / bodyIdleMs / responsesBodyIdleMs | 30000 / 120000 / 300000 | Adapter only, plugin 0.3.7+: stream-liveness watchdogs, in ms (integers from 1 to 600000). Time to the first stream event, mid-response body silence, and the body-idle floor for Responses models (muse-spark-*). Increase firstEventMs for slow cold starts. Unset keeps the defaults; restart DSH after editing. |
Local OpenCode delegation (plugin 0.3.x, docs/delegation.md, ref #76) — opt-in fallback for the persistent 403 FreeTierError credential gate. Disabled by default; the anonymous path is unchanged unless you enable it:
delegation:
enabled: true # arm the delegate (default false)
# opencodePath: '' # explicit binary; else managed -> global -> npm
# minVersion: '1.18.0' # candidates below this are skipped
# memLimit: '96MiB' # GOMEMLIMIT for the child
# gcPercent: 30 # GOGC for the child
# trimIntervalMs: 60000 # Windows EmptyWorkingSet tick; 0 disables
# startTimeoutMs: 60000 # health-wait budget
Enabling it makes the plugin custody your opencode credential (only the opencode entry, seeded 0600 into an isolated XDG root, never logged) and run a managed local opencode serve when — and only when — the anonymous lane and its sibling retry both refuse with the credential gate. Read docs/delegation.md §2 before enabling.
DSH session
│ harness chunks (block-start / text-delta / usage / finish …)
▼
ZenAdapter (registered LlmAdapter)
│ pi-ai openai-completions stream (chat models)
│ pi-ai openai-responses stream (`muse-spark-*`, Responses-only on Zen)
▼
https://opencode.ai/zen/v1 ← Authorization: Bearer public
with CLI-identical headers:
user-agent: opencode/…
x-opencode-client, x-opencode-session, x-session-affinity,
X-Session-Id, x-opencode-request, x-opencode-project
GET /v1/models; S2: models.dev
pricing metadata decides "free"; S3: a compile-time verified static list.
A disk cache (~7-day TTL) covers upstream outages.mode: sidecar, legacy) — spawns a local Go agent (a
single-tenant port of opencode2api)
on 127.0.0.1:<random>, token-authenticated, and registers a standard
llm-pi-ai route. Not part of the published package; build it from
legacy/agent (go build ./cmd/agent) and point agentPath at the binary.The plugin writes a health snapshot after every refresh round:
~/.opencode2dsh/adapter-status.json
{
"status": "ready",
"total": 64,
"exposed": 9,
"lastError": "",
"writtenAt": "2026-08-29T07:01:54.915Z"
}
| Symptom | Likely cause & fix |
|---|---|
403 FreeTierError / "OpenCode's free tier can only be used from within OpenCode" | The upstream restricts free-tier clients. The plugin preserves the explanation instead of reporting an invalid API key. Use the supported OpenCode client or an official API service. If the refusal is persistent (direct + sibling both 403 while your shape/IP are clean), issue #76's opt-in local delegation runs the turn through your own opencode login — enable delegation.enabled after reading its security notes. |
Boot screen shows Failed to load plugins … list slot "plugins.item" requires options.id, or the IP 池 entry has no configuration page | Your DSH predates the 0.1.7 Plugins page contract. Upgrade DSH to 0.1.7 (latest recommended). On 0.1.6 and older the page never mounts (it is gated on configForms.whileServed) — model routing is unaffected. |
DSH 0.1.7/0.2 cannot start after plugin installation (pending … settingsScope) | Upgrade the plugin to 0.3.5. On DSH 0.2, configure IP pooling through the installed opencode2dsh row on the Plugins page. |
| Only 3 models | Startup fetch raced your network; retries land within ~1 min. Check adapter-status.json for lastError. |
lastError: "fetch failed" persisting | Outbound HTTPS to opencode.ai blocked; check proxy/VPN rules. |
Rate-limit errors in chat (429 … Endpoint is unavailable) | The anonymous lane is quota-per-IP and free models are contended. Since the fix for #51 the plugin's provider retry policy rides out 429 bursts silently (8 retries, ~1s→20s backoff, ≈90s worst case per step) instead of surfacing them; when contention still wins, lower the reasoning effort, pick a less contended -free model, or enable IP pooling (multi-exit rotation) on the plugin settings page. |
| Output limit reached after reasoning with no answer | Plugin 0.3.6 retries once with thinking Off when the model supports it. Any answer text or tool-call event prevents replay. The retry preserves the original output cap and may still fail; both requests' usage is counted. Models without Off, including Muse, require a manual change of settings or model. |
Muse reports REGION_BLOCKED / "This model is not available in your country" | Zen has rejected the current network region for this model. Plugin 0.3.5 preserves that explanation; older versions mislabeled the same 403 as an invalid API key. The anonymous lane does not need a personal key. Use a model available in your region. |
Connection error to 127.0.0.1:* | A stale sidecar route shadows the adapter; plugin ≥ 0.2.1 removes it at startup. |
Install fails with ERR_PNPM_IGNORED_BUILDS | A transitive dependency of pi-ai (@google/genai, protobufjs) has build scripts that are not needed at runtime. Approve-or-decline them via the plugin market, or set both to false under allowBuilds: in the profile's pnpm-workspace.yaml. |
public; nothing is stored, nothing telemetry.lib/ only; no build scripts run from dependencies.opencode.ai / models.dev.opencode entry, seeded 0600 into an isolated XDG root, never logged, never sent anywhere but the local child — and proxy it through a managed local opencode serve. If upstream deems that abnormal use, your account bears the consequence. Tool execution on your machine is prevented in depth (ask-then-reject + response scan + isolated env); see the doc.git clone https://github.com/FishBottle7/opencode2dsh.git
cd opencode2dsh/packages/plugin
pnpm install
pnpm typecheck && pnpm test
pnpm build # bundle to lib/
The legacy Go sidecar lives in legacy/agent (go test ./...). Architecture
notes and the porting record live in docs/.
Releasing: pnpm pack in packages/plugin (prepack builds and syncs docs).
legacy/agent is a port of its anonymous-lane implementation, and the
catalog fallback chain and request-disguise details are derived from it.
This project stands on its shoulders.LinuxDo — 新的理想型社区 / a new ideal community
MIT © FishBottle7