@alexeiled/pi-model-router 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +16 -0
- package/LICENSE +21 -0
- package/README.md +141 -0
- package/extensions/commands.ts +677 -0
- package/extensions/config.ts +642 -0
- package/extensions/constants.ts +49 -0
- package/extensions/index.ts +573 -0
- package/extensions/provider.ts +650 -0
- package/extensions/routing.ts +483 -0
- package/extensions/state.ts +101 -0
- package/extensions/types.ts +109 -0
- package/extensions/ui.ts +131 -0
- package/model-router.example.json +72 -0
- package/package.json +77 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.5.0 (unreleased)
|
|
4
|
+
|
|
5
|
+
This is the first release of the independently maintained `@alexeiled/pi-model-router` fork.
|
|
6
|
+
|
|
7
|
+
- Require Pi `0.86.0` or newer and test against the synchronized Pi 0.86.0 packages.
|
|
8
|
+
- Upgrade development tooling to TypeScript 7 and Vitest 5.
|
|
9
|
+
- Replace Prettier with pinned Biome 2.5.14 for lint, formatting, and import-order checks. Enforce the same read-only checks in CI, releases, and before publishing.
|
|
10
|
+
- Preserve the last selected router profile across new Pi sessions.
|
|
11
|
+
- Dispatch registered custom-provider streams when Pi exposes a provider-specific stream.
|
|
12
|
+
- Accept headers-only authentication used by providers such as Kimi Code OAuth.
|
|
13
|
+
- Apply credential-specific provider base URLs when Pi exposes them.
|
|
14
|
+
- Keep classifier requests isolated from the main conversation system prompt and tools.
|
|
15
|
+
- Ignore the startup thinking-level event emitted by newer Pi versions instead of turning it into a router-wide override.
|
|
16
|
+
- Keep the original MIT license and upstream attribution.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Ye Liu
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
# pi-model-router
|
|
2
|
+
|
|
3
|
+
Smart per-turn model router extension for the [pi-coding-agent](https://github.com/earendil-works/pi/tree/main/packages/coding-agent) that optimizes your AI budget and usage limits without sacrificing quality by dynamically routing each turn to the optimal LLM tier. It automatically selects between high, medium, and low-tier models based on task intent, session budget, context size, and custom rules — complete with automatic fallbacks and phase awareness.
|
|
4
|
+
|
|
5
|
+
> **Independent fork:** This project is an independently maintained fork of [yeliu84/pi-model-router](https://github.com/yeliu84/pi-model-router), originally created by Ye Liu. It is not an official upstream release. The original MIT license and copyright notice are preserved.
|
|
6
|
+
|
|
7
|
+
## Fork status
|
|
8
|
+
|
|
9
|
+
This fork is maintained at [alexei-led/pi-model-router](https://github.com/alexei-led/pi-model-router). It publishes independent releases as `@alexeiled/pi-model-router` and accepts fixes for current Pi versions and provider integrations. See [CHANGELOG.md](CHANGELOG.md) for fork-specific changes.
|
|
10
|
+
|
|
11
|
+
## What it does
|
|
12
|
+
|
|
13
|
+
- **Logical Router Provider**: Registers a `router` provider that exposes stable profiles (e.g., `router/balanced`) as models.
|
|
14
|
+
- **Per-Turn Routing**: Intelligently chooses between `high`, `medium`, and `low` tiers for every turn based on task intent and complexity.
|
|
15
|
+
- **Task-Aware Heuristics**: Detects planning vs. implementation vs. lightweight tasks using keyword analysis, word count, and conversation history.
|
|
16
|
+
- **Advanced Controls**: Includes built-in support for:
|
|
17
|
+
- **LLM Intent Classifier**: Optionally use a fast model to categorize intent (overrides heuristics).
|
|
18
|
+
- **Custom Rules**: Define keyword-based tier overrides for specific patterns (e.g., `deploy` → `high`).
|
|
19
|
+
- **Cost Budgeting**: Set a session spend limit; high tier downgrades to medium once exceeded.
|
|
20
|
+
- **Fallback Chains**: Automatic retry with alternative models if the primary choice fails.
|
|
21
|
+
- **Phase Memory**: Biased stickiness to keep you in the same tier during multi-turn planning or implementation work.
|
|
22
|
+
- **Thinking Control**: Full control over reasoning/thinking levels per tier and profile. Changing pi's thinking level (e.g. via `shift+tab`) automatically applies as an all-tier override for the active router profile.
|
|
23
|
+
- **Persistent State**: Pins, costs, and debug history are remembered across agent restarts and conversation branches. When Pi starts on the router provider, new sessions use the last selected router profile if it is still configured. An explicit `--model` selection takes precedence.
|
|
24
|
+
|
|
25
|
+
## Installation
|
|
26
|
+
|
|
27
|
+
### Requirements
|
|
28
|
+
|
|
29
|
+
- Pi `0.86.0` or newer.
|
|
30
|
+
- Node.js `22.19.0` or newer.
|
|
31
|
+
|
|
32
|
+
Install from npm:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
pi install npm:@alexeiled/pi-model-router
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### Migrating from the upstream package
|
|
39
|
+
|
|
40
|
+
Do not load both packages at the same time: both register the `router` provider. Replace the upstream package with this package and keep your existing `model-router.json` configuration:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
pi remove npm:@yeliu84/pi-model-router
|
|
44
|
+
pi install npm:@alexeiled/pi-model-router
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
If the upstream package was installed through another manifest, remove that entry there instead. The configuration file and router commands remain compatible for this release.
|
|
48
|
+
|
|
49
|
+
### For development
|
|
50
|
+
|
|
51
|
+
Use Node.js 22.19+ and npm. Install and validate with:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
npm ci --ignore-scripts
|
|
55
|
+
npm run check
|
|
56
|
+
npm test
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
`npm run check` runs Biome lint, formatting and import-order checks, then the
|
|
60
|
+
TypeScript compiler. Warnings fail the check. CI and releases use the same gate.
|
|
61
|
+
|
|
62
|
+
- `npm run format` formats TypeScript and root JSON files.
|
|
63
|
+
- `npm run lint` checks lint rules; `npm run lint:fix` applies safe lint fixes.
|
|
64
|
+
- `npx biome check --write .` also fixes formatting and import order.
|
|
65
|
+
- `npm run tsc` runs only the type checker.
|
|
66
|
+
|
|
67
|
+
[Biome](https://biomejs.dev/) replaces Prettier and supplies linting in one pinned
|
|
68
|
+
direct tooling dependency, without ESLint or formatter plugins. Type checking stays with
|
|
69
|
+
TypeScript 7. Markdown and YAML are not formatted by this setup; validate
|
|
70
|
+
workflow YAML with `actionlint .github/workflows/*.yml`. The generated lockfile
|
|
71
|
+
is excluded from formatting.
|
|
72
|
+
|
|
73
|
+
Install from source:
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
pi install .
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Or load directly for one run:
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
pi -e ./extensions/index.ts
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Configuration
|
|
86
|
+
|
|
87
|
+
Copy the example config to one of:
|
|
88
|
+
|
|
89
|
+
- `~/.pi/agent/model-router.json` (Global)
|
|
90
|
+
- `.pi/model-router.json` (Project-specific)
|
|
91
|
+
|
|
92
|
+
The extension stores the last selected profile in `~/.pi/agent/model-router-state.json`. It restores this preference only when Pi starts on the router provider without an explicit `--model` selection. Branch-specific state remains in Pi session entries and takes precedence when a session is resumed.
|
|
93
|
+
|
|
94
|
+
### Basic Config Shape
|
|
95
|
+
|
|
96
|
+
```json
|
|
97
|
+
{
|
|
98
|
+
"classifierModel": "google/gemini-flash-latest",
|
|
99
|
+
"maxSessionBudget": 1.0,
|
|
100
|
+
"profiles": {
|
|
101
|
+
"auto": {
|
|
102
|
+
"high": { "model": "openai/gpt-5.4-pro", "thinking": "high" },
|
|
103
|
+
"medium": { "model": "google/gemini-flash-latest", "thinking": "medium" },
|
|
104
|
+
"low": { "model": "openai/gpt-5.4-nano", "thinking": "low" }
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Configuration Fields
|
|
111
|
+
|
|
112
|
+
| Field | Description |
|
|
113
|
+
| ----------------------- | --------------------------------------------------------------------------------- |
|
|
114
|
+
| `classifierModel` | (Optional) Model used to categorize intent. Supports model aliases. If omitted, fast heuristics are used. |
|
|
115
|
+
| `maxSessionBudget` | (Optional) USD budget for the session. Forces `medium` tier once exceeded. |
|
|
116
|
+
| `phaseBias` | (0.0 - 1.0) Stickiness of the current phase. Higher = more stable. Default `0.5`. |
|
|
117
|
+
| `rules` | List of custom keyword rules (e.g. `{ "matches": "deploy", "tier": "high" }`). |
|
|
118
|
+
| `models` | (Optional) Map of model aliases to definitions with `model`, `contextWindow`, `maxTokens`. |
|
|
119
|
+
| `profiles` | Map of profile definitions, each containing optional `high`, `medium`, and `low` tiers (at least one required). Tier models can reference aliases from `models`. |
|
|
120
|
+
|
|
121
|
+
## Commands
|
|
122
|
+
|
|
123
|
+
| Command | Description |
|
|
124
|
+
| --------------------------- | ------------------------------------------------------------------------------- |
|
|
125
|
+
| `/router` | Show detailed status, current profile, spend, and settings. |
|
|
126
|
+
| `/router status` | Alias for `/router` (show current status). |
|
|
127
|
+
| `/router profile [name]` | Switch to a profile or list available ones (enables router if off). |
|
|
128
|
+
| `/router pin <t\|a>` | Pin a tier (high/medium/low/auto) for the active profile. |
|
|
129
|
+
| `/router fix <tier>` | Correct the _last_ decision and pin that tier for the current profile. |
|
|
130
|
+
| `/router thinking <level>` | Override thinking level for all tiers (e.g. `/router thinking max`). Not all tier models may support every level. |
|
|
131
|
+
| `/router thinking <tier> <level>` | Override thinking level for a specific tier (e.g. `/router thinking low off`). |
|
|
132
|
+
| `/router disable` | Disable the router and switch back to the last non-router model. |
|
|
133
|
+
| `/router widget <on\|off>` | Toggle the persistent state widget (supports `toggle`). |
|
|
134
|
+
| `/router debug <on\|off>` | Toggle turn-by-turn routing notifications (supports `toggle`, `clear`, `show`). |
|
|
135
|
+
| `/router reload` | Hot-reload the configuration JSON. |
|
|
136
|
+
| `/router help` | Show usage help for all subcommands. |
|
|
137
|
+
|
|
138
|
+
## Documentation
|
|
139
|
+
|
|
140
|
+
- [Architecture Guide](docs/ARCHITECTURE.md): Deep dive into the routing logic and modular design.
|
|
141
|
+
- [Sample Configuration](model-router.example.json): Diverse profile examples (`cheap`, `deep`, `balanced`).
|