# pi-deepseek-route — Reasoning-Mode Routing for DeepSeek V4 Flash (pi)

[中文](README.md) | [English](README.en.md)

A **task-aware reasoning-mode router** extension for the pi coding agent,
built specifically for **DeepSeek V4 Flash**. It switches thinking modes
based on task type; **non-Flash models are completely untouched**.

Ported from [dsh-routing-suite](https://github.com/yjh051108/dsh-routing-suite)'s
mode-boost v0.1.0 — every behavior text and threshold comes from official-API
probes measured on 2026-08-15 (`deepseek-v4-flash, reasoning_effort=max, n=2`,
same-battery A/B comparison).

## Features

| Mechanism | Description | Measured effect |
|---|---|---|
| **Flash-only gate** | Non-Flash models see nothing: no persona injection, no tool narrowing, no guidance; `pi_router_*` tools are hidden from the tool surface | — |
| **Task classification** | Session's first message picks one of three bands: fix/maintain → spec (plan-first, read-first tools); build/develop → react (doer, write-first); ambiguous → weak (model self-classifies) | weak-band discrimination +5.67 |
| **First-turn anchoring** | Flash sessions expose only the core tools matching the band on the first request; the full surface is restored after the first tool call | capability preserved, trajectory stable |
| **Near-field guidance** | In weak sessions, one fixed guidance message follows every real user message: rounds 1-2 classify, rounds 3+ reclassify (anti-dilution); simple tasks converge fast, complex tasks get directed depth | multi-turn routing 63% → **94%** |
| **Chat stand-down** | Greetings / task-less messages are never touched | avoids 338-chunk reasoning spirals |
| **deep-persona** | Weak persona embeds "Think deeply first, then produce." | convergence 88% → **100%** |
| **Self-optimization tools** | `pi_router_status` / `pi_router_mode` / `pi_router_subagent` | the model tunes its own routing |

More measurements: simple tasks 3.5 steps / 6.5k chars → **1.0 step / 1.2k** (zero
waste), complex tasks 8.5 steps / 9.9k → **7.5 steps / 10.8k** (deeper without
rumination), rumination rate 0.0–0.4%.

## Install

```bash
# Recommended: npm package (versioned; pi update upgrades it)
pi install npm:pi-deepseek-route

# Or git package (tracks the latest commit directly)
pi install git:github.com/hisence999/pi-deepseek-route

# Try without installing (current run only)
pi -e npm:pi-deepseek-route

# Project-level sharing (writes .pi/settings.json; teammates get it after trust)
pi install -l npm:pi-deepseek-route
```

> User installs: `pi list` to show; `pi update npm:pi-deepseek-route` upgrades just
> this package, `pi update --all` updates everything. npm package requires Node ≥18.

**Manual fallback**:

```powershell
# Copy to the global extensions directory
$target = Join-Path $env:USERPROFILE '.pi\agent\extensions\pi-router'
New-Item -ItemType Directory -Force -Path $target
Copy-Item .\index.ts, .\core.ts $target
```

(`install.ps1` in the repo is a scripted version of the manual fallback, for
environments where `pi install` is not available.)

Restart pi or run `/reload`. Flash sessions pick it up automatically — zero
configuration.

## Usage

Three self-optimization tools (visible only in Flash sessions):

| Tool | Description |
|---|---|
| `pi_router_status` | Show routing state: model gate, mode/band, persona, first-turn core tools, override |
| `pi_router_mode` | Manually override the mode: `spec` / `weak` / `mixed` (trap, avoid) / `react`, 0-100 or 0.0-1.0 numbers, `auto` returns to task classification; persisted across resumes |
| `pi_router_subagent` | Run a task in a DIFFERENT reasoning mode, isolated system prompt, current session trajectory untouched |

## How It Works

```
user message (Flash model)
  ├─ chat / no task → zero intervention
  ├─ spec (fix/maintain) → plan-first persona + read-first first-turn tools
  ├─ react (build/develop) → doer persona + write-first first-turn tools
  └─ weak (ambiguous) → self-classify persona + bash+edit first-turn surface
       └─ one guidance after each message: rounds 1-2 classify / rounds 3+ reclassify
          simple task → fast convergence / complex task → directed depth
first tool call (or agent_settled) → full surface restored, tools untouched afterwards
```

- **Cache principle**: persona is static per session (unless overridden); guidance
  is injected at the message layer — the system-prompt prefix changes only once
- **State persistence**: `pi.appendEntry` + rebuild from the current branch
  (`/tree`-safe), survives resumes
- **Safe restoration**: compare-and-set — the full surface is written back only
  when the current surface is still exactly our narrowed `core`, so other
  extensions' changes are never overwritten

### Known limitations & design trade-offs

1. **agent_settled releases the first-turn narrowing early**: the DSH original
   restores the full surface only after the first tool/call; this version adds
   an `agent_settled` fallback (restore even without a tool call, to avoid
   getting stuck). Side effect: in spec mode, if the model plans in pure text
   on the first turn, the surface is already full on turn two. Minor for react
   (usually acts immediately), slightly looser for spec (plan-first).
2. **Global tool surface across sessions**: `setActiveTools` is a pi global API.
   No effect in single-session use (the coding-agent norm). With a custom host
   running several sessions at once, one session's narrowing/restore can
   briefly affect another's tool surface (compare-and-set mitigates: it won't
   overwrite a surface another extension changed).

## Verification

```bash
node verify.mjs     # 44 logic tests (load/gate/routing/guidance/persistence/branches)
```

Type checking: `tsconfig.json` uses `types/pi-coding-agent.d.ts`, a minimal type
stub (pi's full type graph explodes under tsc, so local checks use the stub; at
runtime the pi extension loader provides the real modules — the extension itself
has zero npm dependencies).

## Differences from the DSH version (mode-boost)

| Dimension | DSH mode-boost | pi-deepseek-route |
|---|---|---|
| Form | cordis host-plane bundle plugin | pi extension (auto-discovered + `/reload` hot reload) |
| Gate | all models (Pro/Flash branches) | **Flash only** (non-Flash zero intervention + tools hidden) |
| First-turn surface | shell + str_replace_editor (RL shape) | shell + edit (pi has no str_replace_editor; approximate) |
| Tool names | dev_mode_status / dev_mode_set | pi_router_status / pi_router_mode |
| State persistence | derived from session.events | `pi.appendEntry` + branch rebuild (tree-safe) |
| Tool restore | after first tool/call | first tool/call **or agent_settled** ends the lease (compare-and-set) |

## License

MIT. Credits: yjh051108/dsh-routing-suite (measured data & texts),
xiaobright/modeltest (V4.1b evaluation),
xiaobright/dsh-anchored-standard (anchoring mechanism),
[Linux.do community](https://linux.do) (developer exchange & inspiration).
