- Accueil
- Plugins
- Compétences
- dsh-skill-router
dsh-skill-router
lau4tin1/dsh-skill-router
Routeur de skills pour DeepSeek Harness : un modèle local crée les embeddings des skills et de chaque tâche utilisateur, conserve celles qui sont clairement pertinentes selon une règle d’écart et insère automatiquement leur contenu intégral dans le prompt.
Installer
dsh plugin --profile web add github:lau4tin1/dsh-skill-routerREADME
Welcome to DSH-SKILL-ROUTER!

A Skill Router for DeepSeek Harness
RAG-style skill routing plugin for DeepSeek Harness: embeds skills (their
name + description + whenToUse routing surface), embeds each user task, keeps
only the clearly-relevant skills with a gap-based selection rule, and
auto-injects their full bodies into the prompt — no model round-trip to load a
skill.
- Design: see DESIGN.md.
- Status: V1 complete and running — type-checks against the real DSH
0.1.5-rc.2types, builds, mounts in a live DSH profile (verified in the web and headless profiles), and passes 20/24 bilingual routing prompts on real skills (node demo/e2e.ts). Compatible with DSH0.1.5-rc.2through0.2.0-rc.2(peer range>=0.1.5-rc.2 <0.3.0-0); all routing APIs it uses —ctx.skills.snapshot/get,skills/change,renderSkillContent,createUserMessage, and theagent/pre-stepmiddleware — are unchanged in0.2.0-rc.2.
Install
dsh plugin --profile web add dsh-skill-router
Installs into the web profile; swap web for another profile name to target
it. Requires dsh and pnpm on
PATH.
pnpm 12 build approval — the first install pulls native dependencies (
onnxruntime-node,sharp,protobufjs) whose build scripts pnpm blocks by default. Ifdsh pluginstops withERR_PNPM_IGNORED_BUILDS, open$DSH_HOME/profiles/<name>/pnpm-workspace.yaml, set theallowBuildsentries pnpm wrote there totrue, then re-run the samedsh plugin ... addcommand.The first real task downloads the embedding model once (~543MB, q8) into
$DSH_HOME/skill-router/models, then runs fully offline.
Layout
src/index.ts— the Cordis plugin entry (name/inject/Config/apply).src/selection.ts— the selection rule (largest-gap / ratio-to-max, weak floor).src/similarity.ts— cosine similarity + vector helpers (pure).src/embedding.ts— one real embedding model via transformers.js (ONNX).src/skillIndex.ts— the index: build, embed, digest-diff sync on change.src/config.ts— schemastery config schema + mappers.src/render.ts— renders the injected<system-reminder>block (reuses DSH'srenderSkillContent).demo/e2e.ts— end-to-end routing test over downloaded skills.
Build
npm install # toolchain (typescript, esbuild); DSH types come from a local checkout symlink
npm run typecheck # tsc --noEmit against the real DSH types
npm run build # esbuild -> lib/index.js (@deepseek-ai/* kept external)
Demo
Skills live in .agents/skills/ — a real DSH scanned root (rank 200, see
DESIGN.md §14). The demo parses them the same way the registry would surface
them:
node demo/e2e.ts # plugin defaults
node demo/e2e.ts 0.2 # experiment with the minScore floor
Config (defaults)
enabled: true
embedding:
model: Xenova/bge-m3 # optional; any HF ONNX embedding model
dtype: q8 # or fp32
cacheDir: ~/.dsh/skill-router # optional; models + index live here
rule: largest-gap # or ratio-to-max
minScore: 0.2 # confidence floor (precision > recall)
ratioThreshold: 0.75
maxSkills: 4
The plugin default above is classic gap/ratio mode. The bundled
cordis.patch.yml ships with the scale-invariant override instead:
minScore: 0.05 and zThreshold: 2.5.
Languages
Chinese and English both work out of the box — the default model is
multilingual, and a Chinese prompt matches an English skill description (and
vice versa) by meaning, cross-lingual. One DSH registry rule to respect:
skill names must stay kebab-case ASCII (pdf-tools), but description,
whenToUse, and the body can be Chinese. The injected instruction block is
bilingual (中文/English).
Embedding model
One engine: a real local model via transformers.js (ONNX) — dense semantic
vectors; synonyms and paraphrases match, word sharing is not required.
Default Xenova/bge-m3 (q8, ~543MB download, 1024-dim, [CLS] pooling) —
flagship multilingual quality for Chinese + English. Alternatives via
embedding.model: multilingual-e5-small (fast, needs query/passage
prefixes — handled automatically), bge-large-en-v1.5, bge-large-zh-v1.5.
Scoring de-biases the vectors by subtracting the corpus mean ("centering"), which removes the shared direction that would otherwise make unrelated texts score ~0.8. Inference is pinned to a single thread so results are deterministic.
All heavy data lives OUTSIDE the working directory: the model downloads once
from huggingface.co into <cacheDir>/models, and the skill-embedding index
persists at <cacheDir>/skill-index.json (atomic writes, tagged with the
model id), so unchanged skills are never re-embedded after a restart.
Dev note
node_modules/@deepseek-ai and node_modules/js-yaml are local symlinks into
a DSH checkout for type-checking and demos; recreate them after a fresh
install. At runtime a real DSH profile provides the @deepseek-ai/* packages
(they are declared as peerDependencies and kept external by the build).