You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
mtplx start dsh (alias deepseek-harness) — one command that wires the DeepSeek Harness to a locally served MTPLX model, starts the server, and opens the DSH web app.
Background: what DSH is
DSH (@deepseek-ai/dsh, npm) is a coding-agent / web-harness built around a plugin bundle. Its LLM layer is pi-ai based: a provider profile speaks the same Chat-Completions wire contract as Pi — api: openai-completions plus a compat block — which is exactly what MTPLX's OpenAI-compatible server speaks. DSH keeps provider config in <dshHome>/settings.yaml under the llm-pi-ai namespace (a providers map), and secrets in a versioned <dshHome>/.credentials.yaml store where the profile names an environment variable (apiKeyEnv) whose value lives in the file, mode 0600. dsh web boots its web profile (auto-initializing on first run) and opens the dashboard.
Why this is useful
MTPLX serves local MLX models (MTP-accelerated) over an OpenAI-compatible endpoint. Until now, pointing DSH at one meant hand-editing YAML: guessing the port, the compat flags, the credential plumbing, and praying you didn't clobber settings you'd tuned. Now the whole connection is one idempotent command:
Install check — detects dsh on PATH; offers npm install -g @deepseek-ai/dsh if missing.
Connect — writes/updates the mtplx provider profile in DSH's settings and the MTPLX_API_KEY credential, backing up any existing files first.
Serve + launch — starts the MTPLX server on the fixed integration port and launches dsh web in a new terminal.
--dry-run prints the full plan (base URL, model ref, context window, target file paths) and writes nothing — it's safe to run anywhere, including CI, and needs no dsh binary.
Design decisions (and why)
Fixed port 18086 for the dsh surface, so the connection identity stays stable across launches and doesn't collide with other local dev services.
DSH-owned keys only. On re-runs MTPLX rewrites only ("baseURL", "api", "apiKeyEnv", "headers", "compat") — the keys that must stay correct for the connection — and leaves everything else the user edited untouched (see Don't mess with tools and system prompt by default #282, silent clobber of user edits). Existing settings are backed up before any write.
No hidden max_tokens. The profile advertises the detected model context window (262 144 fallback) and no cap, so DSH sees the model's real headroom instead of a smuggled default.
mtplx/<public_id> model ref + x-mtplx-client: dsh header — the header lets the server attribute and log traffic from the harness.
thinkingFormat: qwen + api: openai-completions + compat — MTPLX's Qwen thinking vocabulary and reasoning streaming pass through the pi-ai wire contract unchanged.
Home precedenceMTPLX_DSH_HOME > DSH_HOME > ~/.dsh (matching DSH's own; the MTPLX override exists for tests and power users).
Server handoff: the serve step re-execs with --launch-dsh --server-console; the DSH launch is a delayed, non-blocking post-startup open (argless dsh web) that drops AIME workers, so an interactive server console stays usable.
Wizard: dsh is option 6 in the interactive mtplx start wizard (dashboard → 7); the deepseek-harness alias routes identically.
tests/test_public_cli.py(+203) — alias routing, dry-run JSON (provider registration, zero writes), live-path write + handoff flag, parser target list, fan mode.
How do I know it's right?
Unit/CLI suite: 38 new tests across test_public_cli.py + test_onboarding.py, all passing.
Real dry-run on real hardware: MTPLX_DSH_HOME=$(mktemp -d) mtplx start dsh --dry-run → exit 0, plan printed, and a control run confirmed zero filesystem writes (no files created in the fresh home).
Rebased onto latest main (557e637, v2.10.1) — clean rebase, no conflicts — and the suite re-run green on the new base. Full tests/ shows one failure, test_laguna_model.py::test_laguna_s_2_1_ar_route_skips_qwen_performance_hooks, which fails identically on the base commit (its preflight requires 85.3 GiB; this dev box has 48 GiB). It is pre-existing and machine-dependent, not caused by this change.
I read the branch. The shape is right: a launch target that writes DSH's provider profile the way the Pi target writes Pi's, keeps the token in .credentials.yaml, and tags requests with x-mtplx-client=dsh. It is queued for review after the correctness items of the next release.
One question decides how the review goes: which server profile does x-mtplx-client=dsh land on? Pi's profile pins the local_qwen36 chat template and the hybrid tool prompt mode, and it took a measured tool loop (a real multi-turn task with tool calls, checked against the request log's cached_tokens and the tool-call parse counts) before it shipped. If DSH reuses Pi's block one-to-one, say so, and add one such loop from your machine (model, turns, any parse failures). Then the review can be about the code only.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this is
mtplx start dsh(aliasdeepseek-harness) — one command that wires the DeepSeek Harness to a locally served MTPLX model, starts the server, and opens the DSH web app.Background: what DSH is
DSH (
@deepseek-ai/dsh, npm) is a coding-agent / web-harness built around a plugin bundle. Its LLM layer is pi-ai based: a provider profile speaks the same Chat-Completions wire contract as Pi —api: openai-completionsplus acompatblock — which is exactly what MTPLX's OpenAI-compatible server speaks. DSH keeps provider config in<dshHome>/settings.yamlunder thellm-pi-ainamespace (aprovidersmap), and secrets in a versioned<dshHome>/.credentials.yamlstore where the profile names an environment variable (apiKeyEnv) whose value lives in the file, mode 0600.dsh webboots its web profile (auto-initializing on first run) and opens the dashboard.Why this is useful
MTPLX serves local MLX models (MTP-accelerated) over an OpenAI-compatible endpoint. Until now, pointing DSH at one meant hand-editing YAML: guessing the port, the compat flags, the credential plumbing, and praying you didn't clobber settings you'd tuned. Now the whole connection is one idempotent command:
dshon PATH; offersnpm install -g @deepseek-ai/dshif missing.mtplxprovider profile in DSH's settings and theMTPLX_API_KEYcredential, backing up any existing files first.dsh webin a new terminal.--dry-runprints the full plan (base URL, model ref, context window, target file paths) and writes nothing — it's safe to run anywhere, including CI, and needs nodshbinary.Design decisions (and why)
("baseURL", "api", "apiKeyEnv", "headers", "compat")— the keys that must stay correct for the connection — and leaves everything else the user edited untouched (see Don't mess with tools and system prompt by default #282, silent clobber of user edits). Existing settings are backed up before any write.max_tokens. The profile advertises the detected model context window (262 144 fallback) and no cap, so DSH sees the model's real headroom instead of a smuggled default.mtplx/<public_id>model ref +x-mtplx-client: dshheader — the header lets the server attribute and log traffic from the harness.thinkingFormat: qwen+api: openai-completions+compat— MTPLX's Qwen thinking vocabulary and reasoning streaming pass through the pi-ai wire contract unchanged.MTPLX_DSH_HOME>DSH_HOME>~/.dsh(matching DSH's own; the MTPLX override exists for tests and power users).apiKeyEnv: MTPLX_API_KEY(local default keymtplx-local).--launch-dsh --server-console; the DSH launch is a delayed, non-blocking post-startup open (arglessdsh web) that drops AIME workers, so an interactive server console stays usable.mtplx startwizard (dashboard → 7); thedeepseek-harnessalias routes identically.Files
mtplx/dsh.py(new, 506) — home/settings/credentials resolution, provider profile + write logic (merge, backup, 0600, invalid-file handling),dsh weblaunch.mtplx/commands/public.py(+318) — dsh quickstart target: install check, dry-run/live payload, 3-step handoff, port/alias wiring.mtplx/server/openai.py(+31) —--launch-dshflag, delayed web launch, worker drop-flags.mtplx/cli.py(+21) — help surfaces + alias (4 surfaces).mtplx/ui/onboarding.py(+21) +tests/test_onboarding.py(+15) — wizard option numbering.tests/test_public_cli.py(+203) — alias routing, dry-run JSON (provider registration, zero writes), live-path write + handoff flag, parser target list, fan mode.How do I know it's right?
test_public_cli.py+test_onboarding.py, all passing.MTPLX_DSH_HOME=$(mktemp -d) mtplx start dsh --dry-run→ exit 0, plan printed, and a control run confirmed zero filesystem writes (no files created in the fresh home).main(557e637, v2.10.1) — clean rebase, no conflicts — and the suite re-run green on the new base. Fulltests/shows one failure,test_laguna_model.py::test_laguna_s_2_1_ar_route_skips_qwen_performance_hooks, which fails identically on the base commit (its preflight requires 85.3 GiB; this dev box has 48 GiB). It is pre-existing and machine-dependent, not caused by this change.Built with MTPLX with DeepSeek Harness :D