opencode-model-router 1.0.2 → 1.0.4
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/README.md +11 -1
- package/package.json +1 -1
- package/src/index.ts +16 -48
package/README.md
CHANGED
|
@@ -16,6 +16,16 @@ The agent automatically delegates via the Task tool when it recognizes the task
|
|
|
16
16
|
|
|
17
17
|
This applies both to plan-driven execution and direct ad-hoc requests. For every new user message, the orchestrator performs an intent gate, splits multi-task requests into atomic units, and routes each unit to `@fast`, `@medium`, or `@heavy`.
|
|
18
18
|
|
|
19
|
+
### Token overhead disclaimer
|
|
20
|
+
|
|
21
|
+
The injected protocol is compact, but it still adds tokens on every iteration.
|
|
22
|
+
|
|
23
|
+
- Estimated average injection: ~208 tokens per iteration
|
|
24
|
+
- Preset breakdown (default `tiers.json`): `anthropic` ~209, `openai` ~206
|
|
25
|
+
- Estimation method: `prompt_characters / 4` (rough heuristic)
|
|
26
|
+
|
|
27
|
+
Real token usage varies by tokenizer/model and any custom changes you make to `tiers.json`.
|
|
28
|
+
|
|
19
29
|
## Installation
|
|
20
30
|
|
|
21
31
|
### Option A: npm package (recommended)
|
|
@@ -25,7 +35,7 @@ Add the plugin package in your `opencode.json`:
|
|
|
25
35
|
```json
|
|
26
36
|
{
|
|
27
37
|
"plugin": [
|
|
28
|
-
"opencode-model-router@
|
|
38
|
+
"opencode-model-router@latest"
|
|
29
39
|
]
|
|
30
40
|
}
|
|
31
41
|
```
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -98,62 +98,30 @@ function buildAgentOptions(tier: TierConfig): Record<string, unknown> {
|
|
|
98
98
|
function buildDelegationProtocol(cfg: RouterConfig): string {
|
|
99
99
|
const tiers = getActiveTiers(cfg);
|
|
100
100
|
|
|
101
|
-
const
|
|
101
|
+
const tierSummary = Object.entries(tiers)
|
|
102
102
|
.map(([name, t]) => {
|
|
103
103
|
const shortModel = t.model.split("/").pop() ?? t.model;
|
|
104
|
-
const
|
|
105
|
-
return
|
|
104
|
+
const variant = t.variant ? ` (${t.variant})` : "";
|
|
105
|
+
return `@${name}=${shortModel}${variant}`;
|
|
106
106
|
})
|
|
107
|
-
.join("
|
|
108
|
-
|
|
109
|
-
const whenToUse = Object.entries(tiers)
|
|
110
|
-
.map(([name, t]) => `- **@${name}**: ${t.whenToUse.join(", ")}`)
|
|
111
|
-
.join("\n");
|
|
112
|
-
|
|
113
|
-
const rules = cfg.rules.map((r, i) => `${i + 1}. ${r}`).join("\n");
|
|
114
|
-
|
|
115
|
-
const directRoutingRules = [
|
|
116
|
-
"Run an Intent Gate for every new user message, even without a plan file.",
|
|
117
|
-
"If the message contains multiple asks, split it into atomic tasks before routing.",
|
|
118
|
-
"Route read-only exploration/search tasks to @fast.",
|
|
119
|
-
"Route implementation/edit/test/refactor tasks to @medium.",
|
|
120
|
-
"Route architecture/security/performance/complex debugging tasks to @heavy.",
|
|
121
|
-
"If a request mixes tiers, delegate each subtask to the right tier and then synthesize one final response.",
|
|
122
|
-
"If a task is trivial (single grep/read), execute directly instead of delegating.",
|
|
123
|
-
"When uncertain, default to the configured default tier unless user constraints clearly require another tier.",
|
|
124
|
-
];
|
|
125
|
-
|
|
126
|
-
const directRoutingList = directRoutingRules
|
|
127
|
-
.map((rule, index) => `${index + 1}. ${rule}`)
|
|
128
|
-
.join("\n");
|
|
107
|
+
.join(" | ");
|
|
129
108
|
|
|
130
109
|
return [
|
|
131
110
|
"## Model Delegation Protocol",
|
|
111
|
+
`Preset: ${cfg.activePreset}. Tiers: ${tierSummary}.`,
|
|
132
112
|
"",
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
"",
|
|
136
|
-
"
|
|
137
|
-
"
|
|
138
|
-
|
|
139
|
-
"",
|
|
140
|
-
"
|
|
141
|
-
|
|
142
|
-
"",
|
|
143
|
-
"### Rules:",
|
|
144
|
-
rules,
|
|
145
|
-
"",
|
|
146
|
-
"### Direct Request Routing (No Plan Required):",
|
|
147
|
-
"These rules also apply to ad-hoc user requests, not only PLAN.md execution.",
|
|
148
|
-
directRoutingList,
|
|
149
|
-
"",
|
|
150
|
-
"### How to delegate:",
|
|
151
|
-
"Use the Task tool with the tier name as `subagent_type`:",
|
|
152
|
-
'- `Task(subagent_type="fast", prompt="Find all files importing AuthContext")`',
|
|
153
|
-
'- `Task(subagent_type="medium", prompt="Implement the UserService class per the spec")`',
|
|
154
|
-
'- `Task(subagent_type="heavy", prompt="Review this auth flow for security vulnerabilities")`',
|
|
113
|
+
"Apply to every user message (plan and ad-hoc):",
|
|
114
|
+
"1. Split multi-part requests into atomic tasks.",
|
|
115
|
+
"2. Respect explicit tier instructions and [tier:fast|medium|heavy] tags.",
|
|
116
|
+
"3. Route read-only search/exploration tasks to @fast.",
|
|
117
|
+
"4. Route implementation/edit/refactor/test/bugfix tasks to @medium.",
|
|
118
|
+
"5. Route architecture/security/performance/complex debugging to @heavy.",
|
|
119
|
+
"6. For mixed requests, delegate each subtask to the matching tier, then synthesize one final response.",
|
|
120
|
+
"7. For trivial single read/grep tasks, execute directly.",
|
|
121
|
+
`8. If uncertain, default to @${cfg.defaultTier}.`,
|
|
155
122
|
"",
|
|
156
|
-
|
|
123
|
+
"Delegate with Task(subagent_type=\"fast|medium|heavy\", prompt=\"...\").",
|
|
124
|
+
"Keep orchestration and final synthesis in the primary agent.",
|
|
157
125
|
].join("\n");
|
|
158
126
|
}
|
|
159
127
|
|