Models & Providers
dseepseek-ha-API
438417623wq/dseepseek-ha-API · ★ 0
Expose every model the DeepSeek Harness can already call as a loopback OpenAI/Anthropic-compatible gateway, so other local dev tools can use them.
Manifest details
安装
dsh plugin --profile web add 'github:438417623wq/dseepseek-ha-API#4fa02069add32dad87a72a183b9a8d293aeaa6eb'GitHub 源码安装:首次需按提示配置 allowBuilds 构建授权后重试
For install and environment setup, plus plugin development tutorials, see DSH community docs ↗
README
Table of contents
- 1. The three things you fill in
- 2. Install
- 3. Toggle and pick models inside DSH
- 4. Configuring common tools
- Anthropic-native tools (Claude Code and clones)
- OpenAI-compatible clients (Cline, Roo Code, Continue, Cherry Studio, ChatBox, …)
- Python
- Node.js
- curl
- 5. Endpoints
- 6. Four things you must know
- 7. Design notes
- 8. Tests
- 9. Troubleshooting
- 10. License
中文: README.md
Expose every model your DeepSeek Harness (DSH) can already call through one loopback gateway, so any tool that speaks the OpenAI or Anthropic API can use them — Claude Code, Cline, Roo Code, Continue, Cherry Studio, ChatBox, ZCode, or your own scripts.
No second API key to fill in. The gateway calls ctx.llm.stream() inside the
DSH process, so credentials are resolved by whichever adapter already owns the
route. The plugin never reads and never stores an upstream credential.
┌──────────────┐ OpenAI / Anthropic ┌───────────────────┐ ctx.llm.stream() ┌─────────────┐
│ your dev tool│ ──────────────────────▶ │ dsh-model-bridge │ ─────────────────▶ │ DSH adapter │
│ (ZCode etc) │ ◀────────────────────── │ 127.0.0.1:8791 │ ◀───────────────── │ (credentials│
└──────────────┘ SSE └───────────────────┘ in-process call │ live here) │
└─────────────┘
1. The three things you fill in
| Setting | Value |
|---|---|
| OpenAI-compatible Base URL | http://127.0.0.1:8791/v1 |
| Anthropic Base URL | http://127.0.0.1:8791 |
| API Key | see ~/.dsh/model-bridge/key (copyable from the DSH settings page) |
Model names are qualified, e.g. workbuddy/deepseek-v4.1-flash.
The full list is at http://127.0.0.1:8791/v1/models, or in the DSH settings page.
2. Install
The plugin is a standard DSH bundle. Add it to your profile's dependencies and bundles list, then restart DSH:
// ~/.dsh/profiles/<profile>/package.json
{
"dependencies": {
"dsh-model-bridge": "file:F:/KF/dsh api/dsh-model-bridge"
},
"dsh": {
"profile": {
"bundles": [
"@deepseek-ai/dsh-base",
// …
"dsh-model-bridge"
]
}
}
}
The mount itself is done by the plugin's own cordis.patch.yml — one row, and
that row is the entire host-side wiring:
- insert:
- id: model-bridge
name: 'dsh-model-bridge'
Then run the pre-flight check to confirm the profile can compose this bundle:
node "F:\KF\dsh api\dsh-model-bridge\tools\verify-mount.mjs"
Installing a new bundle requires a DSH restart. Port 8791 starts listening only after that restart.
3. Toggle and pick models inside DSH
Settings → Plugins → Model Bridge:
- Enable local gateway — a switch. Turning it off stops 8791 immediately; the choice is remembered and honoured on the next start.
- Connection info — the three values above, each with a copy button. The key is masked by default; "Show" reveals it.
- Exposed models — grouped by provider, individually checkable, with a search
box. An unchecked model does not appear in
/v1/modelsand cannot be called — it is not merely hidden. "Select all / none" handles bulk changes. - Copying model names — a per-row copy button (on hover), and a toolbar "Copy all" that copies every checked model, one per line.
The gateway starts with DSH and stops with DSH. The settings switch is an additional runtime control that does not need a restart.
4. Configuring common tools
Anthropic-native tools (Claude Code and clones)
$env:ANTHROPIC_BASE_URL = "http://127.0.0.1:8791"
$env:ANTHROPIC_API_KEY = "<your key>"
Use workbuddy/deepseek-v4.1-flash as the model name.
OpenAI-compatible clients (Cline, Roo Code, Continue, Cherry Studio, ChatBox, …)
- Provider: OpenAI Compatible (or "Custom OpenAI")
- Base URL:
http://127.0.0.1:8791/v1 - API Key:
<your key> - Model:
workbuddy/deepseek-v4.1-flash
Python
from openai import OpenAI
client = OpenAI(
base_url="http://127.0.0.1:8791/v1",
api_key="<your key>",
)
reply = client.chat.completions.create(
model="workbuddy/deepseek-v4.1-flash",
messages=[
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Hello"},
],
)
print(reply.choices[0].message.content)
Node.js
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "http://127.0.0.1:8791/v1",
apiKey: "<your key>",
});
const reply = await client.chat.completions.create({
model: "workbuddy/deepseek-v4.1-flash",
messages: [
{ role: "system", content: "You are a helpful assistant." },
{ role: "user", content: "Hello" },
],
});
console.log(reply.choices[0].message.content);
curl
curl.exe -H "Authorization: Bearer <your key>" http://127.0.0.1:8791/v1/models
5. Endpoints
| Method | Path | Notes |
|---|---|---|
GET |
/healthz |
Liveness probe. The only unauthenticated route, because it only answers "is the process listening" |
GET |
/v1/models |
Model catalog (OpenAI shape). ?refresh=1 re-enumerates |
POST |
/v1/chat/completions |
OpenAI chat completions, with stream: true and tools |
POST |
/v1/messages |
Anthropic Messages, with stream: true and tools |
GET |
/v1/bridge/info |
Gateway info (both base URLs, provider list) |
Authenticate with Authorization: Bearer <key> or x-api-key: <key> (the
latter is what Anthropic-native clients send). Both are compared in constant time.
An ambiguous bare name is an explicit error, never a guess. deepseek-v4.1-flash,
for instance, is served by more than one provider, so it must be written
workbuddy/deepseek-v4.1-flash; the error lists every candidate.
6. Four things you must know
It only works while DSH is running. This is an in-process DSH plugin, not a standalone daemon — close DSH and 8791 is gone. A 24/7 service is a different design.
The key is a local file that any local program can read. That is deliberate: for an external tool to authenticate, the key must be readable by it. The gateway binds
127.0.0.1only and validatesHost/Originon every request to defeat DNS rebinding, so LAN and internet clients cannot reach it.The WorkBuddy pool requires the first message to be
system. That is an upstream policy the gateway simply forwards:// ❌ rejected upstream: 502 "first message is not system prompt" {"messages": [{"role": "user", "content": "Hello"}]} // ✅ correct {"messages": [ {"role": "system", "content": "You are a helpful assistant."}, {"role": "user", "content": "Hello"} ]}Most clients send a system prompt automatically, so this rarely needs action.
These models spend reasoning tokens — do not set
max_tokenstoo low (≥512 is advisable), or reasoning consumes the whole budget and the visible text comes back empty.
7. Design notes
- Zero credentials. The plugin registers no adapter and declares no
configurable provider, so it can never collide with an existing provider route.
It only consumes
ctx.llm. - In-process call. It goes through
ctx.llm.stream()rather than HTTP, which sidesteps credential transport entirely. - Two protocols, one core. The chunk walk, error handling and terminal handling exist once; each protocol supplies its own renderer.
- Tool calls are complete. A
tool-callopens with a bareblock-startthat carries no id or name (that is what the real adapter emits), socontent_block_startis deferred until id/name are known. A call that only ever reportsblock-endis materialized from there, so the client always receives a runnable call.
8. Tests
cd "F:\KF\dsh api\dsh-model-bridge"
node test\test.mjs # 35 checks: keys, auth, loopback policy, translation, routing, assembly
node test\test-toolcalls.mjs # 6 checks: the tool-call streaming contract (incl. zero-argument calls)
node test\test-settings.mjs # 41 checks: settings page and the on/off switch
node test\test-client.mjs # 61 checks: the client bundle
node tools\verify-mount.mjs # pre-flight: can the profile compose this bundle?
node tools\verify-fix-proves.mjs # control: proves the regression test catches the real bug
node tools\smoke-mount.mjs # end-to-end: a fake host on 8799, both protocols exercised
node tools\check-live.mjs # live check: is the gateway really up after a DSH restart?
verify-fix-proves.mjs is a deliberate control experiment: it reconstructs the
pre-fix output and asserts that the tests reject it. A test that passes both before
and after a fix proves nothing.
9. Troubleshooting
| Symptom | Cause and fix |
|---|---|
| Cannot reach 8791 | DSH is not running, the plugin is not mounted, or the settings switch is off |
| 401 | Wrong key. Read ~/.dsh/model-bridge/key and copy it again |
403 host_not_allowed |
You used an address other than 127.0.0.1, or went through a proxy |
| 400 saying the model is ambiguous | Write it as provider/model, as the error suggests |
503 no_adapter |
That provider has no active adapter in the current DSH |
| A model is missing from the list | It is unchecked in the settings page |
502 no API key for provider route |
That provider (e.g. deepseek-official) needs a sign-in on the DSH models page |
10. License
MIT — see LICENSE.