DeepSeek Harness plugin

dsh-agentic-router

DeepSeek Harness plugin: learning agentic router — rule + UCB + LinUCB + k-NN experts under an EXP3 meta-selector, with a durable quality-reward flywheel

Jump to install

Source facts

Repository
lhwwxy/dsh-agentic-router
Latest update
Aug 19, 2026
Category
Models & Providers
GitHub stars
0
Format
plugin
Catalog evidence
Upstream dsh.bundle evidence
Evidence path
package.json#dsh.bundle
Checked against
0.1.0-rc.8
Upstream check date
2026-08-20

This evidence comes from the upstream catalog. This site has not installed, run, or security-reviewed the plugin.

Install

Start with a prompt that asks an agent to review the GitHub repository and source. Switch to the command if you want to install it yourself.

Copy this prompt into DSH, Codex, or another agent and ask it to review the GitHub repository and source first.

Do not install or run any commands yet. Read this plugin's GitHub repository, README, and relevant source code. Then answer the questions below clearly and directly so I can decide whether it fits my needs:

1. What is this plugin, and what problem does it solve?
2. Who is it for, and what are its typical use cases?
3. How is it used after installation? Include one minimal example.
4. What known limitations or privacy, security, compatibility, or maintenance risks does it have?
5. Give a clear recommendation: recommend, conditionally recommend, or do not recommend, with reasons.

Distinguish statements documented by the repository, inferences from source code, and unknowns. If evidence is insufficient, say so explicitly. Do not guess or simply repeat the README.

GitHub: https://github.com/lhwwxy/dsh-agentic-router
Plugin: dsh-agentic-router
Author: lhwwxy

Check the source files

Read the README and other files from this plugin directory before installing.

File explorer4 files
README.en.mdSource · read only
README language

dsh-agentic-router

> 🌐 Language / 语言切换: English · 简体中文

DeepSeek Harness (DSH) plugin: a learning agentic router with a data flywheel.

At the start of every turn (agent/inbox/claimed) it routes the request to the most appropriate model tier by task type and complexity, asks four experts in parallel and lets an EXP3 meta-selector decide who to trust. Every turn is scored with quality-proxy signals (tool failures, model retries, cost, latency) and the reward feeds back into the strategies — the router gets better as it runs. Every decision and reward is persisted locally: auditable and replayable.

Real switching since v1.4.0: v1.3.0 and earlier swapped models by returning a replaced config from the agent/request waterfall, but DSH's built-in model-selection listener overrides that value, so the swap never took effect. v1.4.0 instead appends a request/header event (reason: router) to the session log at turn start, going through DSH's official model-selection precedence chain (in-process selection → latest logged session request/header → default model).

Architecture

user input → classify (rules, <1ms) → 4 expert recommendations → EXP3 meta-pick → request/header append (real switch)
                                            ↑                              │
              UCB/LinUCB/k-NN/EXP3 updates ← quality-proxy reward ← turn end (tool errors/retries/cost/latency)
ExpertAlgorithmStatus
ruledeterministic thresholds (complexity ≤0.3→fast, ≥0.7→strong, else mid)cold-start prior, always in pool
UCBcluster×tier multi-armed bandit; unexplored arms get ∞, ties rotateactive from day zero
LinUCBlinear feature scoring + exploration bonus, gradient updatesshadow; graduates at 50 samples
k-NNk=5 nearest-neighbor aggregation over the experience poolshadow; graduates at 30 experiences
EXP3meta-selector, importance-weighted updatesalways on; cold-start biased to rule (weight 2.5)

Design rationale and roadmap: [docs/DESIGN.md](./docs/DESIGN.md). The implementation was validated against a live runtime prototype first; eight defects found there are fixed and pinned as regression tests.

Install

dsh plugin --profile web add dsh-agentic-router

> --profile is mandatory. Restart the web profile after installing so the tool schemas join prompt assembly.

Switch to real routing (active)

Default mode is shadow (records and learns, never swaps). To enable real switching, the easiest way is: after restarting, tell the agent in any DSH session:

> Switch the agentic router to active mode

The agent calls agentic_router_set_mode (mode=active) and persists it to ~/.dsh/storages/dsh-agentic-router/policy.json — it stays active across restarts.

Alternatively, start active on first load by adding config in the profile's cordis.patch.yml:

- id: agentic-router
  config:
    mode: active

(Pick one; once a mode has been saved via the tool, policy.json takes precedence over config.mode.)

Tools

ToolPurpose
agentic_router_statsdecision log, four-expert recommendations, EXP3 weights, flywheel state
agentic_router_set_modeshadow (default) / active (real swaps) / off (bypass)
agentic_router_forceforce a model id (active mode only); clear=true to release
agentic_router_resetwipe flywheel learning state, keep mode
agentic_router_set_pricesset/query per-provider per-model (or per-tier) prices

Data flywheel (persistence)

Directory: ${DSH_HOME:-~/.dsh}/storages/dsh-agentic-router/ (override with AGENTIC_ROUTER_HOME)

  • decisions.jsonl — one line per decision: task type/complexity, all four recommendations, meta pick, actual route, swapped?
  • rewards.jsonl — one line per reward with breakdown (tool errors/retries/latency) + feature vector; replayed on startup to restore learning state; human-feedback settlements (feedback-settle lines) correct the replayed rewards exactly
  • Human feedback: 45s after a turn closes, the plugin polls messageFeedback (the Web UI 👍/👎); a thumbs-down costs −0.5, a thumbs-up adds +0.1, applied as an exact correction to the already-applied reward
  • policy.json — mode and forced model (atomic write)

Reward: clean close starts at 1; tool failures −0.2 each (cap 0.6), model retries −0.2 each (cap 0.4), cost min(0.5, 20 × turn cost in CNY), latency >30s −0.1 / >90s −0.3; errored turns score 0.

Cost signal (token billing): the plugin wraps llm/stream and accumulates each model call's usage chunk (input/output/cache-read/reasoning tokens); providers without usage fall back to length-based estimates (flagged estimated).

Three-level price resolution (CNY per million tokens): provider→model exact price > provider→tier price > * generic tier > conservative fallback. Unknown providers never inherit DeepSeek pricing — they use the generic tier and carry a pricingSource audit field. DeepSeek's official pricing ships as default; add other models at runtime via the agentic_router_set_prices tool (persisted to policy.json) or at install via config.prices:

{ 'deepseek-official': { 'deepseek-v4-pro': { in: 1, out: 12 } },
  openai: { 'gpt-x-pro': { in: 15, out: 60 } },
  '*': { fast: { in: 1, out: 4 }, mid: { in: 2, out: 8 }, strong: { in: 3, out: 16 } } }

Known limits

  • Model tiers are recognized by id keywords (flash→fast, pro→strong); real swaps happen only when more than one tier exists
  • Feedback settles after a 45s window (configurable via settleDelayMs); unsettled pending entries are lost on restart; late feedback may be attributed to a later turn
  • Feedback only works where the deployment's Web UI actually writes it (this plugin only reads)
  • LinUCB / k-NN need dozens of turns before they graduate into the meta pool

Development, testing and release flow (maintainers): see [docs/MAINTAINING.md](./docs/MAINTAINING.md).

License

MIT