dsh-plugin-image-gen
Generate images from inside DeepSeek Harness (DSH) through any OpenAI-compatible image endpoint you configure. The package ships no endpoint, no model list tied to a vendor, and no credentials - you bring all three.
It registers two agent tools:
| Tool | Purpose |
|---|
generate_image | Generate image(s) from a prompt and save them to disk; returns absolute path(s). |
get_image_gen_config | Show the effective configuration and setup diagnostics (never secret values). |
What you need
- DSH (Desktop or CLI) with the tools service. Tested against DSH Desktop 0.2.0-rc.2.
- An image endpoint that speaks the OpenAI images API:
POST {baseURL}/images/generations, returning data[].b64_json or data[].url. This covers OpenAI itself and most relays/gateways.
- An API key for that endpoint.
Nothing else: no system Node install, no dependencies, no build step.
Install
In DSH's Plugins page:
- Latest:
github:HaoyanZhang123/dsh-plugin-image-gen
- Pinned:
github:HaoyanZhang123/dsh-plugin-image-gen#v0.1.2
- Offline: download the
.tgz from Releases and paste its absolute path
- npm (if you prefer registry installs):
dsh-plugin-image-gen
A fresh install takes effect immediately - the next turn already has both tools. Upgrading an already-installed version is the one case DSH reports as restart-required: quit and reopen DSH afterwards (closing the window is not quitting; use the tray icon).
Set up
1. Find your DSH home
Everything lives there. Ask your agent to run get_image_gen_config - it prints the exact path in the "Config file" line. Or work it out:
| Platform | Default DSH home |
|---|
| Windows | %USERPROFILE%.dsh (for example C:\Users\you.dsh) |
| macOS / Linux | ~/.dsh |
| Any, if set | whatever DSH_HOME points to |
2. Add your API key
Pick whichever suits you:
Resolution mirrors the official DSH layering: process environment > .credentials.yaml refs > /.env > /.env.
Keys are never read from conversation, shown in tool output, or stored by this plugin. Do not paste your key into a chat message - put it in one of the three places above.
3. Point it at your endpoint
Create /image-gen.config.json:
{
"baseURL": "https://your-relay.example.com/v1",
"apiKeyEnv": "IMAGE_GEN_API_KEY",
"models": ["gpt-image-1", "another-model"],
"defaultModel": "gpt-image-1"
}
That is the whole setup for most people. Skip this step entirely if you are using OpenAI itself with the default values - just add the key in step 2.
Two practical notes:
Edits take effect on the next tool call - no restart.
4. Verify
Ask your agent to run get_image_gen_config. You want to see your endpoint, your models, and Resolved keys: 1 (or more). Then say "generate an image of a red apple on a white table" and check the returned path on disk.
Using it
Just describe the image. Overrides are per call and phrased naturally:
- "画一只在代码里游泳的猫" / "draw a cat swimming in code"
- "a 16:9 banner for a launch post" - the agent passes a matching
size
- "four versions of the logo" -
n=4
- "use another-model for this one" - a per-call model override
Images are saved as PNG files and reported by absolute path, so they survive independently of the conversation. To view one in chat, the active model must accept image input - otherwise open the file.
Configuration reference
| Field | Default | Meaning |
|---|
baseURL | https://api.openai.com/v1 | Any OpenAI-compatible base URL; POST /images/generations is called. |
apiKeyEnv | IMAGE_GEN_API_KEY | Credential name(s), comma-separated for rotation (for example KEY_A,KEY_B). Stores names, never keys. |
models | ["gpt-image-1"] | Model ids shown to the agent; it may pass any id. |
defaultModel | first of models | Used when a call does not specify model. |
defaultParams | {} | Extra request fields merged into every call - the escape hatch for provider-specific parameters such as aspect_ratio or style. |
timeoutMs | 240000 | Per-request timeout. |
outputDir | /image-gen/output | Where images are saved; per-call output_dir overrides. |
proxy | auto | auto (keep an environment proxy, else detect the OS system proxy: Windows registry / macOS scutil), off, or an explicit http://host:port. |
Layering: package defaults < the entry's optional config: block in the profile patch < image-gen.config.json.
size and quality are pass-through strings: they are sent only when you set them (per call or via defaultParams); otherwise the endpoint applies its own defaults. Vocabulary differs per provider - the plugin never validates them, and endpoint errors are returned verbatim so the agent can retry.
Troubleshooting
| Symptom | Cause and fix |
|---|
No API key found for "IMAGE_GEN_API_KEY" | Step 2 was skipped, or the key sits under a name that differs from apiKeyEnv. Run get_image_gen_config to see which names are consulted. |
Configuration warnings: ... invalid JSON | The config file failed to parse and was ignored; defaults apply. Validate the JSON and check for Windows backslashes. |
upstream HTTP 401 | The endpoint rejected the key (wrong key, wrong account, or a key for a different gateway). |
upstream HTTP 404 | baseURL is wrong - usually it already includes or omits /v1. The called URL is {baseURL}/images/generations. |
upstream HTTP 429 | Rate limited. Add a second key to apiKeyEnv (KEY_A,KEY_B); the plugin rotates on 401/429. |
upstream returned no image data | The endpoint answered, but not in OpenAI image shape (data[].b64_json / data[].url). It is not compatible. |
| Request timed out | Raise timeoutMs. Large sizes and high quality can take minutes. |
| Connection errors behind a proxy | Leave proxy: "auto", or set an explicit URL (including credentials if the proxy needs them). OS proxies requiring authentication are not picked up automatically. |
Anything else: the error text is returned verbatim from the endpoint, and get_image_gen_config reports the effective settings and config-file path.
Security
- The published package contains no endpoint beyond the neutral OpenAI default and no credentials; the
files whitelist in package.json defines exactly what ships.
npm run pack:check packs the tarball and scans every shipped file for key-shaped strings before a release.
- API keys resolve only from your own credential stores and never appear in logs, tool output, or errors.
Compatibility and failure behavior
See COMPATIBILITY.md. In short: the plugin imports only Node builtins and the documented tool-registration contract, declares no DSH version gate at all, and fails loudly and locally if that contract ever changes. It is tested against DSH Desktop 0.2.0-rc.2 on Windows; macOS uses the same contracts (system-proxy detection covered by unit tests).
Uninstall
Remove the bundle in the Plugins page. Your image-gen.config.json, saved images, and credentials are left untouched.
For maintainers
node --test # 37 tests
node tools/check-package.mjs # file whitelist + credential-leak scan, then packs the tarball
Release flow: bump version in package.json, add a CHANGELOG entry, run both commands, commit, then gh release create vX.Y.Z dsh-plugin-image-gen-X.Y.Z.tgz.