DSH Plugins Marketplace

DSH Plugins

Plugins

/

dsh-opencode-model-sync

V

dsh-opencode-model-sync

Discovered

Keep the DSH model picker in sync with the live OpenCode Go model catalog - new models appear without a DSH release.

DSH OpenCode Model Sync

Keep the DSH model picker in sync with the live OpenCode Go model catalog.

DSH ships its provider catalog as a build-time snapshot. When OpenCode publishes a new model — say kimi-k3.1-pro — the model exists on the endpoint but the picker does not list it until a new DSH build ships. This plugin closes that gap: it fetches the catalog from opencode.ai and writes the result into the llm-pi-ai settings section, so new models appear after a sync instead of after a release.

  • No DSH rebuild, no app.asar patching, no custom protocol code.
  • Startup sync, periodic refresh, and a manual agent tool.
  • Writes only the three provider routes it owns; every other provider and credential is left untouched.
  • Idempotent: an unchanged catalog produces no settings write.

中文说明

Requirements

RequirementNotes
DSH Desktop / runtime with llm-pi-aiBuilt and tested against DSH Desktop 44.7.0 (@deepseek-ai/dsh-desktop@0.2.1-rc.5).
An OpenCode API keyDefaults to the OPENCODE_API_KEY environment variable or the DSH credentials entry of the same name.
The llm-pi-ai provider rowPresent in the default profile as the opencode-go route.

The plugin never reads the key value into logs, tool output, or settings.

Install

Release archives are produced by npm pack and attached to GitHub Releases as dsh-opencode-model-sync-<version>.tgz. See the latest release.

From Plugin Manager

  1. Download the .tgz from the latest release.
  2. Install it as a bundle. With an agent that has Plugin Manager, use install_bundle with the downloaded file's absolute path (or with the unpacked directory). The same action works from DSH's plugin UI where a local package path is accepted.
  3. Enable the bundle when asked. DSH applies it immediately when HMR is available; otherwise restart DSH.

From a checkout

install_bundle target: /absolute/path/to/dsh-opencode-model-sync

A linked checkout is used in place, so edits to the plugin are picked up by the next recomposition/restart.

What it creates

The plugin groups the live catalog by wire protocol and maintains three provider routes under the llm-pi-ai settings section:

RouteDSH protocolEndpoint from the catalog
opencode-go-chatopenai-completionshttps://opencode.ai/inference/go/openai/v1
opencode-go-anthropicanthropic-messageshttps://opencode.ai/inference/go/anthropic/v1
opencode-go-responsesopenai-responseshttps://opencode.ai/inference/go/openai/v1

Each route carries its models, context/output limits, image support, and reasoning levels translated from the catalog. Models served over protocols DSH cannot speak (currently generate-content for Gemini models) are skipped.

The bundled opencode-go route is not modified by default. DSH's adapter takes the wire protocol at the route level, so a live catalog that spans three protocols cannot be represented by one provider route without dropping its session header and compatibility quirks. Leaving the bundled route intact means an existing default model selection keeps working while the synced routes take over discovery of new models. Set retireBundledRoute when you want the duplicate gone.

Usage

Select any model from OpenCode Go · Chat Completions, OpenCode Go · Messages, or OpenCode Go · Responses in the model picker. New catalog entries show up after the next sync.

Manual sync with the agent tool

The plugin registers one tool:

opencode_model_sync action=status
opencode_model_sync action=sync
opencode_model_sync action=sync dryRun=true
opencode_model_sync action=remove
  • status — last attempt/success, last error, the live model count of each generated route, and how the live catalog compares with DSH's bundled one.
  • sync — fetch the catalog now. Only changed routes are written.
  • remove — delete the three generated routes from settings.

Retiring the bundled route

By default the bundled opencode-go provider stays registered, so a model that is already in DSH's snapshot appears twice. Set retireBundledRoute: true to let the plugin remove that route on the next sync:

  1. It only removes the provider when its profile is the untouched default (opencode-go: {}). A customized profile is left alone with a warning.
  2. It first moves agent-default-model to the generated route that serves the same model. If the default model is not in the live catalog, retirement is aborted so DSH never points at a missing route.
  3. It unsets providers.opencode-go from the llm-pi-ai settings section.

This is one-way: turning the option off later does not restore the route. To restore it manually, add opencode-go: {} back to the providers dict; the bundled catalog and ambient credentials are then used again.

Session-level model selections are not migrated: a conversation that pinned a model under the old provider will report UNKNOWN_MODEL after retirement.

Configuration

Configuration is the bundle row's config in the Cordis patch. Defaults are shown below; every field is optional.

- id: opencode-model-sync
  name: dsh-opencode-model-sync
  config:
    enabled: true
    syncOnStart: true
    intervalMinutes: 360
    modelsUrl: https://opencode.ai/zen/go/v1/models
    apiKeyEnv: OPENCODE_API_KEY
    routePrefix: opencode-go
    displayNamePrefix: OpenCode Go
    sessionId: 00000000-0000-7000-8000-000000000000
    retiredModels: drop
    retireBundledRoute: false
    excludeModels: []
    timeoutMs: 20000
FieldDefaultMeaning
enabledtrueMaster switch. Off registers no tool and performs no sync.
syncOnStarttrueRun a sync a few seconds after DSH starts.
intervalMinutes360Automatic refresh period. 0 disables the periodic refresh.
modelsUrlhttps://opencode.ai/zen/go/v1/modelsCatalog endpoint. The chat base URLs come from each model record, not from this URL.
apiKeyEnvOPENCODE_API_KEYCredential reference / environment variable name.
routePrefixopencode-goPrefix of the three managed routes (<prefix>-chat, <prefix>-anthropic, <prefix>-responses).
displayNamePrefixOpenCode GoDisplay prefix shown in the model picker.
sessionId00000000-0000-7000-8000-000000000000Value of the required x-opencode-session header. All conversations on the generated routes share it.
retiredModelsdropdrop follows the live catalog; keep keeps models that disappeared from the catalog on the same route.
retireBundledRoutefalseRemove the bundled opencode-go provider after a sync and move the default model to the matching generated route. One-way; see below.
excludeModels[]Model ids that must never be synced.
timeoutMs20000Catalog fetch timeout.

Keep the routePrefix stable: changing it creates a new set of routes and leaves the old ones behind (action=remove cleans up the current prefix).

How it works

  1. Resolve the API key through ctx.credentials (falling back to the Host process environment).
  2. GET <modelsUrl> with a bearer token.
  3. Translate every type: chat record by its protocol: limits → contextWindow/maxTokens, image modalities → input: [text, image], reasoning levels → reasoningEfforts (none becomes off).
  4. Group records into one route per supported protocol and add the x-opencode-session header plus DSH's thinkingFormat: deepseek compatibility switch on Chat Completions.
  5. Compare with the current llm-pi-ai provider values and call ctx.settings.update('llm-pi-ai', …) only when something changed.
  6. Retry once on network errors, HTTP 429, and HTTP 5xx; a managed route whose protocol disappears from the catalog is unset in retiredModels: drop mode.

Two safety rules keep the write narrow: the plugin refuses to overwrite a same-named provider whose wire protocol differs, and it only removes routes it can identify as its own.

The write goes through DSH's settings service, so the profile patch stays human-readable and the pi-ai adapter rebuilds on the next request.

Known limitations

  • Cost is not synced. DSH's provider configuration has no cost field; synced models report zero cost in the usage panel.
  • The bundled opencode-go route remains by default. While DSH ships an older snapshot, the same model can appear under both the bundled route and a synced route. Enable retireBundledRoute to remove it.
  • One session id for every conversation. Generated routes are hand-declared providers, and only the bundled catalog provider receives DSH's per-session x-opencode-session header. A fixed value satisfies the gateway but may reduce upstream cache affinity across conversations.
  • Gemini generate-content models are skipped because DSH implements only openai-completions, anthropic-messages, and openai-responses.
  • Catalog metadata is the only source. If OpenCode advertises a wrong limit or modality, the synced route inherits that error.

Troubleshooting

SymptomCheck
no API key in status/errorExport OPENCODE_API_KEY, or store it in DSH credentials under that name.
HTTP 401/403The key is present but not accepted by the catalog endpoint. A 403 unsupported_country_region_territory means that model is unavailable in your region — not a plugin failure.
HTTP 404modelsUrl was changed away from https://opencode.ai/zen/go/v1/models.
Tool says llm-pi-ai settings entry is not availableThe llm-pi-ai plugin row is disabled or missing in this profile.
New models absent after syncRun action=status; the model count per route shows whether the write reached the adapter. Some pickers cache until the next session.
Settings conflictThe plugin retries once; if it persists, another settings writer is editing the same entry concurrently.

Uninstall

plugin_manager action=remove_bundle target=dsh-opencode-model-sync, then run opencode_model_sync action=remove beforehand if you also want the generated providers deleted from the profile patch.

Development

npm test          # pure catalog translation tests (node:test, no dependencies)
npm run check     # parse every module
npm pack          # release tarball

The package has no build step: index.js and lib/*.js are the shipped modules. Peer dependencies (@deepseek-ai/dsh-tools, @deepseek-ai/dsh-credentials, @deepseek-ai/schemastery) are resolved by the DSH runtime, not installed from npm.

License

MIT. See LICENSE.

Comments

Loading…

Similar plugins

dsh-opencode-go-plus

by deepseek-harness-plugins-1121

OpenCode Go model provider for DeepSeek Harness - a maintained fork that keeps the model catalog reachable and configures itself from Settings > Models

Manifest valid

★ 4

↓ 356/wk

MIT

JavaScript

Sep 28, 2026

dsh plugin --profile web add dsh-opencode-go-plus

by DPH-1121

OpenCode Go model provider for DeepSeek Harness - a maintained fork that keeps the model catalog reachable and configures itself from Settings > Models

Manifest valid

★ 4

MIT

JavaScript

Oct 19, 2026

dsh plugin --profile web add dsh-opencode-go-plus

by CJYLZS

auto sync opencode-go models in dsh

Development & InfrastructureManifest valid

★ 3

JavaScript

Sep 4, 2026

dsh plugin --profile web add dsh-opencode-go-autosync

by scavanger2221

OpenCode Go models as a DeepSeek Harness provider, with session-affinity headers, a live model catalog, and a Web settings card

Manifest valid

★ 0

MIT

JavaScript

Sep 29, 2026

dsh plugin --profile web add dsh-llm-opencode-go

by Retr67

DeepSeek Harness (DSH) plugin: one-click OpenCode Go model sync in the settings panel - fetch all server models, probe availability & vision, write back to llm-pi-ai config

Manifest valid

★ 4

MIT

JavaScript

Oct 27, 2026

dsh plugin --profile web add dsh-opencode-models

by serra006

Expose every free model from a local opencode serve catalog — all providers, including your own custom ones — to DeepSeek Harness's model picker, with OpenCode's native tools denied so execution stays

Development & InfrastructureModels & ProvidersManifest valid

★ 3

MIT

JavaScript

Oct 17, 2026

dsh plugin --profile web add dsh-connect-opencode