Model Switch implementation plan
September 5, 2026 · View on GitHub
Milestone 1 — package and pure routing core
- Establish the publishable package, strict TypeScript declaration build, ESM bundle, and fail-closed Cordis entry.
- Preserve the released Main/Subagent deep modules. Add two confirmed v0.2 seams: a
ModelSwitchSearchProviderimplementing the officialWebSearchProviderinterface over a provider adapter registry, and a stablegenerate_imagetool over an Image adapter registry. Keep Vision outside runtime delivery. - Gate an actual tarball: load every export target from extraction; reject source, tests, scripts, source maps, patch/diff payloads, Core paths/fork contracts, and local dependency protocols.
- Prove emitted artifacts reproduce from different checkout paths.
Completion: pnpm run check and git diff --check pass. No DSH runtime, UI, preset, or lab changes occur.
Milestone 2 — released runtime seams
Register each feasible Settings/runtime capability only through released public Cordis/DSH interfaces, and expose every unavailable route as explicit capability data rather than simulated behavior. Contract-test against clean alpha.1 infrastructure rather than a hand-built context alone.
Implemented foundation on alpha.1: Model Switch owns its Settings namespace; Main reads/saves through the official Agent Default Model service; registration, committed updates, Main delegation, and disposal are covered by a real Cordis + Settings composition test.
Implemented coordinated replacement: the package bundle patch disables the released Loader row with id subagent and inserts the uniquely identified plugin-owned dsh-model-switch/subagent-runtime; removing the bundle restores the official profile composition. The replacement selects provider/model/effort before delegating to the official alpha.1 one-shot and continuable descriptor creation, and fails closed for partial routes, ambiguous or unexpected rows, and unsupported effort transport. Do not replace the launcher-pinned AgentPresets row: a nested AgentPresets instance loads a second dsh-scope identity and breaks session.create. Official presets consume the replacement subagents service after the Subagent Loader row is replaced. Search must use the released Web provider seam rather than registering a duplicate tool; Image may register only the unique generate_image name.
Known seam constraints from alpha.1 inspection:
- Web session creation has no atomic create-time model override; use the existing public Main Settings namespace rather than post-create selection. The Host couples
session.selectModelto a deployment-default write, so the owned composer/Plan picker restores the captured Main default throughsettings.mutateat the immediately following revision; conflicts are left untouched so concurrent Settings edits win. - Tool registration has disposal but no atomic replacement; stage complete generations and roll back on registration failure.
- A later child model switch cannot rewrite its durable continuable descriptor; creation snapshots remain authoritative.
- Search routing owns only provider id
model-switch; the deployment profile pinsweb.searchProvider: model-switchwhile preserving its existingfetchProvider. The officialweb_searchandweb_fetchtools are untouched. generate_imageis unique, so existing provider-specific image tools remain enabled and require no owner suppression.- Codex and Grok register Search and Image adapters. The DeepSeek bridge reuses the official public search implementation and existing settings/credential service. Optional Cordis injection preserves standalone provider behavior and disposal; only Host-projected search metadata reaches the UI.
- Vision remains outside runtime delivery and must not register or shadow
read_image.
Milestone 3 — settings surface
Contribute the Model Switch settings section through declared client slots (alpha.1 has no generic standalone page registry). Use one lifecycle controller/store, three derived prop shares, plain presentation data/callbacks, optimistic revisions, independent row saves, capability filtering, and zh/en dictionaries.
Milestone 4 — provider adapters and composition
Keep the launcher-pinned agent-presets row and official web tools. Add clean optional adapter releases to Codex and Grok without Vision or hard runtime dependency cycles. Explicitly configure Lab web.searchProvider to model-switch while preserving the complete existing Web config, including fetchProvider. The bundle does not modify the Web row; restore the prior deployment search pin before removing Model Switch. Model Switch ships no preset copies.
Milestone 5 — pack/profile/lab acceptance
Run the full composition matrix from packed artifacts under DSH_HOME=~/.dsh-lab on port 3082. Validate boot, HTTP, profile composition, and artifact hashes; leave browser-only visual checks to the human because the managed browser must not open DSH itself.