dsh-web
zhu1090093659/dsh-webDeepSeek Harness(DSH)Web 插件聚合生态包 · 一切皆插件,创意工坊分发(dsh-market.com)
TrustedRouter privacy and routing settings per model for DeepSeek Harness (dsh)
Per-model TrustedRouter privacy and routing settings for DeepSeek Harness (dsh).
For each model, choose a privacy floor, which providers may serve it, what to optimize for, how it's billed and whether providers must be US-based. You do this from Settings → Models in the dsh web UI. The plugin adds your choices to every request as TrustedRouter's provider object.

TrustedRouter reads routing and privacy policy only from the request body, for example {"provider": {"min_privacy": "confidential"}}. No header or API-key setting does the same job. dsh's model providers can add headers but not body fields, so without this plugin there's no way to ask for a privacy floor.
corepack enable pnpm or npm install -g pnpm.https://api.trustedrouter.com/v1;z-ai/glm-5.3.From the dsh web UI:
https://github.com/AmmarByFar/dsh-trustedrouter#v0.1.0 and choose Install.From the command line, for the web profile that dsh web uses:
dsh plugin --profile web add github:AmmarByFar/dsh-trustedrouter#v0.1.0
Then restart dsh web if it was running.
The plugin has no build step, so pnpm doesn't ask you to allow one. Its only peer dependency, @deepseek-ai/schemastery, comes from dsh itself, so the peer warning pnpm prints is expected.
Installing changes nothing yet. Requests go out unchanged until you set a policy.
Upgrading. dsh doesn't update installed plugins yet. Uninstall the plugin (Plugins → TrustedRouter privacy → Uninstall), then install the new tag. Your settings live in your profile, not in the plugin, so they're kept.
Open Settings → Models, find your TrustedRouter card and open Privacy & routing.
Each of the provider's models is listed with the policy it gets. Its tag says where that policy comes from:
z-ai/glm-5.3:nitro, which follows its base model unless you give it settings of its own.Edit opens a model's settings:

| Setting | Sends | Notes |
|---|---|---|
| Privacy floor | min_privacy: no_store, zdr or confidential | Each level lists the providers that meet it for this model. TrustedRouter refuses the request rather than use a provider below the floor. |
| Prefer | sort: price, latency or throughput | |
| Only these providers | only | Empty allows every provider. |
| Never these providers | ignore | |
| Billing | usage: credits or byok | TrustedRouter credits, or your own provider key (BYOK). |
| US-headquartered providers only | jurisdiction: "us" |
As you change settings, the editor counts the providers that still qualify. It warns you if none do, because TrustedRouter would then refuse every request for that model.
Apply saves to your profile, and the next request uses it. No restart is needed.
A few things to know:
https://api.trustedrouter.com/v1.<base URL>/models, no API key sent) the first time you open the section. If that fails, every privacy level is offered.Sidebar → Plugins → TrustedRouter privacy (under Installed), then the TrustedRouter privacy row under Components.

https://api-europe-west4.quillrouter.com/v1, if you use it.order);allow_fallbacks);max_price).provider field the Models page doesn't show.provider.Both pages write the trustedrouter row in your profile's cordis.patch.yml. For dsh web that's ~/.dsh/profiles/web/cordis.patch.yml, or under $DSH_HOME if you set it. You can also edit it by hand:
- id: trustedrouter
config:
gateways: [https://api.trustedrouter.com/v1] # the default
defaults: { min_privacy: zdr } # for every model on those gateways
models: # keyed by model id
z-ai/glm-5.3: { min_privacy: confidential, only: [tinfoil, privatemode] }
rules: [] # optional [{ baseURL, body }], deep-merged after the policy
log: false
How a request's provider is built:
models, merged over defaults. A :suffix id such as z-ai/glm-5.3:nitro uses its base model's entry unless it has its own.provider the request already has, so your policy wins. Lists replace rather than combine.log: true).dsh web prints a line like this:
[trustedrouter] added provider to POST https://api.trustedrouter.com/v1/chat/completions for z-ai/glm-5.3: {"min_privacy":"confidential"}
anthropic/claude-haiku-4.5. The chat should fail with TrustedRouter's 400: No route candidates match the requested provider filters.Repeat step 2 after every dsh upgrade (see Limitations). The log never includes request bodies, only the URL, the model id and the fields added.
fetch. POSTs under a gateway get provider merged into their JSON body. GETs, such as model discovery, and requests to other URLs pass through untouched. A request whose model has no policy is sent byte for byte.fetch. If a dsh release changes that, requests would go out without your policy, and nothing would error. Check the log line after upgrading dsh. This repo's CI also runs weekly against dsh's latest and alpha releases to catch it.dsh web in a browser, not the desktop app.| dsh | Node |
|---|---|
0.2.0-rc.2 (npm latest) | 22 |
0.2.1-alpha.1 (npm alpha) | 22 |
dsh is pre-release, so newer versions may move the settings pages this plugin hooks into.
npm install # the schemastery devDependency, for tests
npm test # unit tests, host and client
test/e2e/run-all.sh # headless dsh against a mock gateway; DSH_VERSION=0.2.0-rc.2|alpha|latest
test/e2e/clean-install.sh # install the packed plugin into a fresh dsh home and check both halves
test/ui/scratch-web.sh start <dir> # a scratch dsh web with this checkout linked in, for the browser
There's no build step: index.js (the server half) and client.js (the browser half) are what ships. PLAN.md has the design notes and the dsh internals they depend on.