Introduction¶
DSH’s plugin ecosystem breaks down different capabilities into installable components. dsh-openai-gateway solves a specific problem: OpenAI clients typically only call standard endpoints like /v1/chat/completions and /v1/models, whereas DSH Agent sessions are also backed by tools and workspaces.
This plugin exposes DeepSeek Harness (DSH) as an OpenAI-compatible API server: after configuring base_url and the API key, clients can invoke DSH’s real Agent sessions. Below is an introduction to its features, installation methods, typical usage, and precautions.
What is this¶
dsh-openai-gateway is a DSH plugin maintained by backrooms-yrc. The version introduced here is v0.1.1 with an MIT license.
It provides the following core endpoints:
POST /v1/chat/completions, supporting streaming and non-streamingGET /v1/modelsGET /v1/models/:idGET /healthz, an unauthenticated health check
Every API call is backed by a real DSH Agent session equipped with tools and a workspace. The plugin includes an independent HTTP listener and Bearer authentication. If the API key is not configured, a key is generated upon the first start and written to disk with 0600 permissions.
Installation and Enabling¶
First, install the plugin:
dsh plugin --profile web add github:backrooms-yrc/dsh-openai-gateway#v0.1.1
Restarting dsh web is required for a new package. After restarting, check the actual listening status:
cat $DSH_HOME/openai-gateway/state.json
Then check the API key:
cat $DSH_HOME/openai-gateway/api-keys.json
DSH_HOME defaults to ~/.dsh; if DSH_HOME is customized via an environment variable, the actual directory takes precedence.
If the API key is not configured, the plugin will automatically generate one on first start and write it to:
$DSH_HOME/openai-gateway/api-keys.json
The file permissions are 0600.
The health check endpoint does not require authentication:
curl http://127.0.0.1:41540/healthz
Ports and Listening¶
The default listening address is:
127.0.0.1:41540
The 41540 here is the default port of dsh-openai-gateway, not an official DSH convention.
If the port is occupied, the plugin logs FATAL, state.json does not update, and /healthz becomes unavailable. Simply change the port in this case.
You can also set port to 0 to let the operating system allocate a random port. After random allocation, the actual port is written to:
$DSH_HOME/openai-gateway/state.json
Configuration Reference¶
The configuration items listed below use the plugin’s default values as a reference:
| Key | Default Value | Description |
|---|---|---|
host |
127.0.0.1 |
Binds only to the loopback address by default |
port |
41540 |
Listening port; set to 0 for random allocation, actual value in state.json |
sessionMode |
both |
Supports both stateless and sticky sessions; when set to stateless, sticky session requests are rejected |
maxSessions |
16 |
Limit for sticky session bookkeeping, using the LRU strategy |
timeoutSeconds |
300 |
Timeout per round; after timeout, the Agent is cancelled and 504 is returned |
workspace.cwd |
Empty string | Agent working directory; if empty, $DSH_HOME/openai-gateway/workspace is used |
Making the First Call¶
Replace $KEY with the key from api-keys.json, and replace $PORT with the port from state.json:
curl http://127.0.0.1:$PORT/v1/chat/completions \
-H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
-d '{"model":"default","messages":[{"role":"user","content":"你好"}]}'
The model parameter supports three formats:
default: Follows DSH’s current default modelprovider/model: Precisely routes to a specific provider and model- Bare model name: Automatically matches the provider via the DSH directory
The complete list of models can be queried via GET /v1/models.
Session Modes¶
By default, the plugin supports stateless sessions as well as sticky sessions.
The characteristic of stateless sessions is that the messages in the request are concatenated into a single prompt, and the session is destroyed after the round ends. It is suitable for direct integration of standard OpenAI clients.
Sticky sessions are suitable for continuous multi-round tasks. The first request should carry:
X-DSH-Session: new
Or in the extension field of the request body:
"dsh_session": "new"
The response will return a dsh_session_id. Subsequent requests carry this ID to reuse the same Agent session.
Example:
curl -X POST http://127.0.0.1:$PORT/v1/chat/completions \
-H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
-H "X-DSH-Session: new" \
-d '{"model":"default","messages":[{"role":"user","content":"记住一个词:蓝鲸"}]}'
Record the dsh_session_id in the response. In the second round, only send the new user message:
curl -X POST http://127.0.0.1:$PORT/v1/chat/completions \
-H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
-H "X-DSH-Session: openai-..." \
-d '{"model":"default","messages":[{"role":"user","content":"刚才让你记住的词是什么?"}]}'
If sessionMode is set to stateless, sticky session requests will be rejected.
Integration with OpenAI Clients¶
Any OpenAI client only needs to configure base_url and the API key.
Python example:
from openai import OpenAI
client = OpenAI(
base_url="http://127.0.0.1:41540/v1",
api_key="sk-dsh-...",
)
resp = client.chat.completions.create(
model="default",
messages=[{"role": "user", "content": "你好"}],
)
print(resp.choices[0].message.content)
Streaming responses also support the reasoning increment for reasoning models, with the field being delta.reasoning_content, in a style similar to DeepSeek.
stream = client.chat.completions.create(
model="default",
stream=True,
messages=[{"role": "user", "content": "解释一下 SSE"}],
)
for chunk in stream:
delta = chunk.choices[0].delta
reasoning = getattr(delta, "reasoning_content", None)
if reasoning:
print("[思考]", reasoning, end="", flush=True)
if delta.content:
print(delta.content, end="", flush=True)
Extension Fields and Tool Calls¶
The plugin provides extension fields in the response:
dsh_session_iddsh_tool_calls
Tool calls are presented as comment frames in the SSE stream:
: dsh tool-call <name>
These extension fields do not break the parsing of standard OpenAI clients.
Reverse Proxy¶
The default host is 127.0.0.1, binding only to the loopback address. If you need to provide services externally, it is recommended to expose them through a reverse proxy, with the reverse proxy handling TLS.
Using nginx as an example, at least /v1/ needs to be proxied, and SSE buffering needs to be disabled:
location ^~ /v1/ {
proxy_pass http://127.0.0.1:41540;
proxy_buffering off;
}
The 41540 should be replaced with the actual port from state.json.
Afterward, clients can configure the base URL as:
https://your-domain/v1
Applicable Scenarios and Notes¶
This plugin is suitable for scenarios where users are already using DSH and want to integrate DSH Agent with OpenAI SDK, scripts, or other OpenAI-compatible clients.
Pre-use precautions:
- The plugin joins the runtime environment of
dsh weband runs with the permissions of the current DSH process; it is recommended to check the source code and MIT license before installing. - By default, it only listens on the loopback address; external deployment is suggested via a reverse proxy.
- The default port
41540is the default for this plugin, not an official DSH convention. - When
portis0, a random port is allocated; the actual value is determined bystate.json. - Sticky sessions have a limit on bookkeeping, with the default
maxSessionsbeing16. - The single-round timeout defaults to
300seconds; after timeout, the Agent is cancelled and504is returned. workspace.cwddefaults to empty; in this case,$DSH_HOME/openai-gateway/workspaceis used.
The current version is v0.1.1, implemented and tested for DSH 0.1.1-rc.2. It is a developer preview with no compatibility guarantees at this time.
Known limitations include:
tool_callsare not projected into OpenAI tool call framestoolsandtool_choicein the request body are ignored- No quota or rate limiting per key
maxSessionsis the limit for sticky session bookkeeping; old Agents evicted by the DSH registry are reclaimed based on its own strategy
If installed via a local path or link, the plugin does not automatically install peer dependencies. You need to ensure the following packages are resolvable:
@deepseek-ai/dsh-agent
@deepseek-ai/dsh-llm
@deepseek-ai/dsh-session
@deepseek-ai/dsh-home-paths
@deepseek-ai/schemastery
Conclusion¶
The value of dsh-openai-gateway lies in its ability to wrap the session, tool, and workspace capabilities of DSH Agent into standard OpenAI endpoints. As long as you configure base_url and the API key, OpenAI clients can initiate calls, and behind every call is a real DSH Agent session.
Code repository:
https://github.com/backrooms-yrc/dsh-openai-gateway
Plugin entry page provided by the plugin clue:
https://www.skillhub.cn/plugins/backrooms-yrc/dsh-openai-gateway
The entry page is subject to the actual accessible address.