@s-berdia/opencode-router 0.0.0-stage → 1.0.1
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/LICENSE +21 -0
- package/README.md +202 -2
- package/USAGE.md +513 -0
- package/dist/bin.js +2951 -0
- package/dist/bin.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +2010 -0
- package/dist/index.js.map +1 -0
- package/model-scores.json +181 -0
- package/package.json +71 -4
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 s-berdia
|
|
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
CHANGED
|
@@ -1,3 +1,203 @@
|
|
|
1
|
-
#
|
|
1
|
+
# opencode-router
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Automatic model routing for [OpenCode](https://opencode.ai) on the **Go**, **Go Plus**, and **Free** plans.
|
|
4
|
+
|
|
5
|
+

|
|
6
|
+
|
|
7
|
+
[Watch the demo in full quality (MP4, 25 seconds)](docs/router-demo.mp4?raw=true)
|
|
8
|
+
|
|
9
|
+
opencode-router gives each OpenCode agent the best model for its job and for your plan.
|
|
10
|
+
It records how much of your quota each model uses. When a model is near its limit, the
|
|
11
|
+
router moves the agent to the next model in its list. When the limit resets, the router
|
|
12
|
+
moves the agent back.
|
|
13
|
+
|
|
14
|
+
For full step-by-step instructions, read the [usage guide](./USAGE.md). Before you use
|
|
15
|
+
the router, read its [known limits](./USAGE.md#11-known-limits).
|
|
16
|
+
|
|
17
|
+
## Features
|
|
18
|
+
|
|
19
|
+
- **One model per job.** The `plan` agent gets the most intelligent model that your plan
|
|
20
|
+
can supply. The `build` agent gets a fast model with a high limit. The `explore` agent and
|
|
21
|
+
the internal helpers (titles, summaries, compaction) get fast, low-cost models.
|
|
22
|
+
- **Plan-aware.** Three plan profiles: `go`, `go-plus`, and `free`. Each profile uses the
|
|
23
|
+
monthly allowance of each model to calculate how many tokens the model can supply in
|
|
24
|
+
5 hours.
|
|
25
|
+
- **Automatic failover.** The `plan`, `build`, `general`, and `explore` agents each have a
|
|
26
|
+
ranked list of up to 4 models. The router changes to the next model before a limit is
|
|
27
|
+
reached, and after a rate-limit error.
|
|
28
|
+
- **Live apply.** The router changes the models in the running OpenCode session. You do
|
|
29
|
+
not have to restart OpenCode after a refresh.
|
|
30
|
+
- **Clear results.** A scorecard shows each model and its scores. With `--verbose`, it
|
|
31
|
+
also shows the source of each score.
|
|
32
|
+
|
|
33
|
+
## Requirements
|
|
34
|
+
|
|
35
|
+
| Item | Version or condition |
|
|
36
|
+
| :-- | :-- |
|
|
37
|
+
| OpenCode | A version that supports plugins (tested with plugin API 1.19) |
|
|
38
|
+
| Node.js | 20 or later, on your `PATH` (the slash commands run `node`) |
|
|
39
|
+
| OpenCode plan | Go, Go Plus, or no subscription (free models only) |
|
|
40
|
+
| Model catalog | Start OpenCode one time before you install. OpenCode then writes `~/.cache/opencode/models.json`. |
|
|
41
|
+
|
|
42
|
+
## Quick start
|
|
43
|
+
|
|
44
|
+
1. Open your global OpenCode config file in a text editor:
|
|
45
|
+
- Windows: `C:\Users\<your-user-name>\.config\opencode\opencode.json`
|
|
46
|
+
- macOS and Linux: `~/.config/opencode/opencode.json`
|
|
47
|
+
|
|
48
|
+
If the file does not exist, make it. If you have `opencode.jsonc`, use that file.
|
|
49
|
+
2. Add the plugin to the `plugin` list:
|
|
50
|
+
|
|
51
|
+
```json
|
|
52
|
+
{
|
|
53
|
+
"$schema": "https://opencode.ai/config.json",
|
|
54
|
+
"plugin": ["@s-berdia/opencode-router"]
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
3. Save the file. Close OpenCode and start it again.
|
|
59
|
+
4. In the OpenCode prompt, type this command and push Enter:
|
|
60
|
+
|
|
61
|
+
```text
|
|
62
|
+
/refresh-routing
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
5. Read the scorecard. It shows the model for each agent.
|
|
66
|
+
|
|
67
|
+
The router now selects models automatically. You do not have to do more.
|
|
68
|
+
|
|
69
|
+
## Commands
|
|
70
|
+
|
|
71
|
+
### In OpenCode
|
|
72
|
+
|
|
73
|
+
| Command | What it does |
|
|
74
|
+
| :-- | :-- |
|
|
75
|
+
| `/refresh-routing` | Calculate the routing table again, apply it, and show the scorecard |
|
|
76
|
+
| `/routing-status` | Show the model in use for each agent (after failover) and its 5-hour quota use |
|
|
77
|
+
| `/routing-plan go-plus` | Save a plan profile (`go`, `go-plus`, or `free`) and apply it immediately |
|
|
78
|
+
| `/routing-eval` | Send one test prompt to the `build` models and write a report |
|
|
79
|
+
|
|
80
|
+
### In a terminal
|
|
81
|
+
|
|
82
|
+
The package also has a command-line tool. Use it for scripts, CI, or scheduled jobs.
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
npx @s-berdia/opencode-router refresh --dry-run # show the scorecard, write nothing
|
|
86
|
+
npx @s-berdia/opencode-router refresh --plan go # calculate and write opencode.json
|
|
87
|
+
npx @s-berdia/opencode-router status # models in use and quota use
|
|
88
|
+
npx @s-berdia/opencode-router plan go-plus # save the plan profile and rebuild
|
|
89
|
+
npx @s-berdia/opencode-router cat # catalog file, date, model count
|
|
90
|
+
npx @s-berdia/opencode-router install --scope global # write slash-command files
|
|
91
|
+
npx @s-berdia/opencode-router --help # all commands and options
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
These commands work in PowerShell, CMD, Git Bash, and macOS or Linux shells.
|
|
95
|
+
|
|
96
|
+
| Option | Meaning |
|
|
97
|
+
| :-- | :-- |
|
|
98
|
+
| `--plan <go\|go-plus\|free>` | Plan profile for this run |
|
|
99
|
+
| `--scope <project\|global>` | Which `opencode.json` to write. Default: `project` in a project folder, else `global` |
|
|
100
|
+
| `--catalog <file>` | Use a different `models.json` catalog file |
|
|
101
|
+
| `--dry-run` | Do not write `opencode.json` |
|
|
102
|
+
| `--no-apply` | Write `opencode.json`, but do not send the change to a running server |
|
|
103
|
+
| `--json` | Print JSON, not a table |
|
|
104
|
+
| `--verbose` | Show the source of each score in the scorecard |
|
|
105
|
+
|
|
106
|
+
## Configuration
|
|
107
|
+
|
|
108
|
+
The router works with no configuration. To change its behavior, make a file named
|
|
109
|
+
`router.config.json`:
|
|
110
|
+
|
|
111
|
+
- Global (all projects): `~/.config/opencode/router.config.json`
|
|
112
|
+
- One project: `<project>/.opencode/router.config.json`
|
|
113
|
+
|
|
114
|
+
Values in the project file replace values in the global file. If a file has a JSON error
|
|
115
|
+
or a value that is not valid, the router ignores it and shows a note in the scorecard.
|
|
116
|
+
|
|
117
|
+
```json
|
|
118
|
+
{
|
|
119
|
+
"plan": "go",
|
|
120
|
+
"softThreshold": 0.85,
|
|
121
|
+
"privacy": { "freeModelsOk": true },
|
|
122
|
+
"denyModels": ["*-preview"],
|
|
123
|
+
"allowModels": [],
|
|
124
|
+
"weights": { "build": { "intelligence": 0.4, "speed": 0.25, "endurance": 0.35 } },
|
|
125
|
+
"scores": { "opencode-go/deepseek-v4.1-flash": { "intelligence": 82 } }
|
|
126
|
+
}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
| Key | Default | Meaning |
|
|
130
|
+
| :-- | :-- | :-- |
|
|
131
|
+
| `plan` | detected from your catalog | `go`, `go-plus`, or `free` |
|
|
132
|
+
| `chainDepth` | 4 for agents, 3 for helpers | Number of models in each failover list. `roles.<role>.chainDepth` wins over it |
|
|
133
|
+
| `softThreshold` | `0.85` | Change to the next model when 5-hour use reaches this part of the 5-hour limit (0.85 = 85%) |
|
|
134
|
+
| `privacy.freeModelsOk` | `true` | `false` keeps `plan`, `build`, and `general` off free models |
|
|
135
|
+
| `denyModels` | `[]` | Model IDs to never use. `*` and `?` wildcards are permitted |
|
|
136
|
+
| `allowModels` | `[]` | If not empty, use only these model IDs |
|
|
137
|
+
| `weights.<role>` | see `model-scores.json` | Weights for `intelligence`, `speed`, and `endurance`. Use values that add up to 1 |
|
|
138
|
+
| `scores.<model-id>` | see `model-scores.json` | Your own `intelligence` and `speed` values (0 to 100) |
|
|
139
|
+
| `roles.<role>` | see `model-scores.json` | Change `variant`, `chainDepth`, `requires`, `preferFree`, or `diversifyFamily` for one role |
|
|
140
|
+
| `blend` | `{ "input": 0.75, "output": 0.25, "cacheRead": 0.1 }` | Token mix used to calculate the cost of one million tokens |
|
|
141
|
+
| `enduranceScale` | `{ "minTokensPer5h": 0.25, "maxTokensPer5h": 40 }` | Millions of tokens per 5 hours that give an endurance score of 0 and 100 |
|
|
142
|
+
| `feeds` | `{ "enabled": false }` | Optional benchmark feed: `{ "enabled": true, "url": "https://...", "timeoutMs": 5000 }` |
|
|
143
|
+
|
|
144
|
+
The [usage guide](./USAGE.md#6-change-the-router-settings) has examples for each key.
|
|
145
|
+
|
|
146
|
+
## How scoring works
|
|
147
|
+
|
|
148
|
+
```text
|
|
149
|
+
score = w_intelligence * intelligence
|
|
150
|
+
+ w_speed * speed
|
|
151
|
+
+ w_endurance * endurance
|
|
152
|
+
+ plan preference
|
|
153
|
+
- penalty for a model that has no entry in model-scores.json
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
- **Intelligence and speed** (0 to 100) come from, in this order: your `scores`, the
|
|
157
|
+
benchmark feed (if enabled), and then name patterns in `model-scores.json`.
|
|
158
|
+
- **Endurance** (0 to 100) comes from your quota. The router divides the 5-hour allowance
|
|
159
|
+
(20% of the monthly allowance) by the cost of one million tokens. A free model, or a
|
|
160
|
+
model with no limit, gets 100.
|
|
161
|
+
- **Plan preference** puts the subscription models that you pay for before free models.
|
|
162
|
+
The `explore` agent and the internal helpers prefer free models.
|
|
163
|
+
- With `--verbose`, the scorecard shows the source of each score: `override` (your
|
|
164
|
+
`scores` or `model-scores.json`), `feed`, `cap` (from quota), `heuristic` (name pattern),
|
|
165
|
+
or `default` (no match).
|
|
166
|
+
|
|
167
|
+
## Files that the router writes
|
|
168
|
+
|
|
169
|
+
| File | Contents |
|
|
170
|
+
| :-- | :-- |
|
|
171
|
+
| `~/.config/opencode/router/ledger.json` | Spend and tokens per model for 5 hours, 7 days, and 30 days |
|
|
172
|
+
| `~/.config/opencode/router/routing-table.json` | The last routing table |
|
|
173
|
+
| `~/.config/opencode/router/last-apply.json` | The result of the last live apply |
|
|
174
|
+
| `~/.config/opencode/router/eval-report.md` | The report of the last `/routing-eval` |
|
|
175
|
+
| `opencode.json` or `opencode.jsonc` (global, or the project file with `--scope project`) | `model`, `small_model`, and `agent.<role>.model` and `variant`. Comments and all other keys stay. A file with a JSON error is not changed |
|
|
176
|
+
|
|
177
|
+
If `XDG_CONFIG_HOME` is set, the router uses `$XDG_CONFIG_HOME/opencode` in place of
|
|
178
|
+
`~/.config/opencode`. Do not commit the `router/` folder. It contains your usage data.
|
|
179
|
+
|
|
180
|
+
## Privacy
|
|
181
|
+
|
|
182
|
+
Models with `-free` in their name can collect your prompts for training. The scorecard
|
|
183
|
+
marks them `free*`. To keep your main work off these models, set
|
|
184
|
+
`"privacy": { "freeModelsOk": false }`. To never use them, set `"denyModels": ["*-free"]`.
|
|
185
|
+
|
|
186
|
+
## Development
|
|
187
|
+
|
|
188
|
+
```bash
|
|
189
|
+
git clone https://github.com/s-berdia/Opencode_router.git
|
|
190
|
+
cd Opencode_router
|
|
191
|
+
npm install
|
|
192
|
+
npm run build # compile to dist/
|
|
193
|
+
npm test # run the tests
|
|
194
|
+
npm run typecheck # check the types
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
To use your local build in OpenCode, put the absolute path of the folder in the `plugin`
|
|
198
|
+
list. Example for Windows: `"plugin": ["file:///C:/code/Opencode_router"]`. Run
|
|
199
|
+
`npm run build` after each change, then restart OpenCode.
|
|
200
|
+
|
|
201
|
+
## License
|
|
202
|
+
|
|
203
|
+
[MIT](./LICENSE)
|