Skip to content

mtplx start dsh: DSH quickstart integration - #412

Open
Deesha08 wants to merge 1 commit into
youssofal:mainfrom
Deesha08:start-dsh
Open

mtplx start dsh: DSH quickstart integration#412
Deesha08 wants to merge 1 commit into
youssofal:mainfrom
Deesha08:start-dsh

Conversation

@Deesha08

@Deesha08 Deesha08 commented Aug 31, 2026

Copy link
Copy Markdown

What this is

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:

  1. Install check — detects dsh on PATH; offers npm install -g @deepseek-ai/dsh if missing.
  2. Connect — writes/updates the mtplx provider profile in DSH's settings and the MTPLX_API_KEY credential, backing up any existing files first.
  3. 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 precedence MTPLX_DSH_HOME > DSH_HOME > ~/.dsh (matching DSH's own; the MTPLX override exists for tests and power users).
  • Credentials mode 0600, apiKeyEnv: MTPLX_API_KEY (local default key mtplx-local).
  • 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.

Files

  • mtplx/dsh.py (new, 506) — home/settings/credentials resolution, provider profile + write logic (merge, backup, 0600, invalid-file handling), dsh web launch.
  • 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-dsh flag, 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?

  • 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.

Built with MTPLX with DeepSeek Harness :D

@Deesha08
Deesha08 requested a review from youssofal as a code owner August 31, 2026 00:13
@youssofal
youssofal force-pushed the main branch 2 times, most recently from 2382dfd to 8bc4d88 Compare September 1, 2026 08:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant