opencode-model-router 1.1.0 → 1.1.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.
Files changed (4) hide show
  1. package/README.md +139 -28
  2. package/package.json +1 -1
  3. package/src/index.ts +29 -66
  4. package/tiers.json +21 -55
package/README.md CHANGED
@@ -6,11 +6,11 @@ An [OpenCode](https://opencode.ai) plugin that automatically routes tasks to tie
6
6
 
7
7
  The plugin injects a **delegation protocol** into the system prompt that teaches the primary agent to route work:
8
8
 
9
- | Tier | Default (Anthropic) | Purpose |
10
- |------|---------------------|---------|
11
- | `@fast` | Claude Haiku 4.5 | Exploration, search, file reads, grep |
12
- | `@medium` | Claude Sonnet 4.5 | Implementation, refactoring, tests, bug fixes |
13
- | `@heavy` | Claude Opus 4.6 | Architecture, complex debugging, security review |
9
+ | Tier | Default (Anthropic) | Cost | Purpose |
10
+ |------|---------------------|------|---------|
11
+ | `@fast` | Claude Haiku 4.5 | 1x | Exploration, search, file reads, grep |
12
+ | `@medium` | Claude Sonnet 4.5 | 5x | Implementation, refactoring, tests, bug fixes |
13
+ | `@heavy` | Claude Opus 4.6 | 20x | Architecture, complex debugging, security review |
14
14
 
15
15
  The agent automatically delegates via the Task tool when it recognizes the task complexity, or when plan steps are annotated with `[tier:fast]`, `[tier:medium]`, or `[tier:heavy]` tags.
16
16
 
@@ -98,32 +98,32 @@ All configuration lives in `tiers.json` at the plugin root. Edit it to match you
98
98
  The plugin ships with four presets:
99
99
 
100
100
  **anthropic** (default):
101
- | Tier | Model | Notes |
102
- |------|-------|-------|
103
- | fast | `anthropic/claude-haiku-4-5` | Cheapest, fastest |
104
- | medium | `anthropic/claude-sonnet-4-5` | Extended thinking (variant: max) |
105
- | heavy | `anthropic/claude-opus-4-6` | Extended thinking (variant: max) |
101
+ | Tier | Model | Cost | Notes |
102
+ |------|-------|------|-------|
103
+ | fast | `anthropic/claude-haiku-4-5` | 1x | Cheapest, fastest |
104
+ | medium | `anthropic/claude-sonnet-4-5` | 5x | Extended thinking (variant: max) |
105
+ | heavy | `anthropic/claude-opus-4-6` | 20x | Extended thinking (variant: max) |
106
106
 
107
107
  **openai**:
108
- | Tier | Model | Notes |
109
- |------|-------|-------|
110
- | fast | `openai/gpt-5.3-codex-spark` | Cheapest, fastest |
111
- | medium | `openai/gpt-5.3-codex` | Default settings (no variant/reasoning override) |
112
- | heavy | `openai/gpt-5.3-codex` | Variant: `xhigh` |
108
+ | Tier | Model | Cost | Notes |
109
+ |------|-------|------|-------|
110
+ | fast | `openai/gpt-5.3-codex-spark` | 1x | Cheapest, fastest |
111
+ | medium | `openai/gpt-5.3-codex` | 5x | Default settings (no variant/reasoning override) |
112
+ | heavy | `openai/gpt-5.3-codex` | 20x | Variant: `xhigh` |
113
113
 
114
114
  **github-copilot**:
115
- | Tier | Model | Notes |
116
- |------|-------|-------|
117
- | fast | `github-copilot/claude-haiku-4-5` | Cheapest, fastest |
118
- | medium | `github-copilot/claude-sonnet-4-5` | Balanced coding model |
119
- | heavy | `github-copilot/claude-opus-4-6` | Variant: `thinking` |
115
+ | Tier | Model | Cost | Notes |
116
+ |------|-------|------|-------|
117
+ | fast | `github-copilot/claude-haiku-4-5` | 1x | Cheapest, fastest |
118
+ | medium | `github-copilot/claude-sonnet-4-5` | 5x | Balanced coding model |
119
+ | heavy | `github-copilot/claude-opus-4-6` | 20x | Variant: `thinking` |
120
120
 
121
121
  **google**:
122
- | Tier | Model | Notes |
123
- |------|-------|-------|
124
- | fast | `google/gemini-2.5-flash` | Cheapest, fastest |
125
- | medium | `google/gemini-2.5-pro` | Balanced coding model |
126
- | heavy | `google/gemini-3-pro-preview` | Strongest reasoning in default set |
122
+ | Tier | Model | Cost | Notes |
123
+ |------|-------|------|-------|
124
+ | fast | `google/gemini-2.5-flash` | 1x | Cheapest, fastest |
125
+ | medium | `google/gemini-2.5-pro` | 5x | Balanced coding model |
126
+ | heavy | `google/gemini-3-pro-preview` | 20x | Strongest reasoning in default set |
127
127
 
128
128
  Switch presets with the `/preset` command:
129
129
 
@@ -141,13 +141,14 @@ Add a new preset to the `presets` object in `tiers.json`:
141
141
  "my-preset": {
142
142
  "fast": {
143
143
  "model": "provider/model-name",
144
+ "costRatio": 1,
144
145
  "description": "What this tier does",
145
146
  "steps": 30,
146
147
  "prompt": "System prompt for the subagent",
147
148
  "whenToUse": ["Use case 1", "Use case 2"]
148
149
  },
149
- "medium": { ... },
150
- "heavy": { ... }
150
+ "medium": { "costRatio": 5, "..." : "..." },
151
+ "heavy": { "costRatio": 20, "..." : "..." }
151
152
  }
152
153
  }
153
154
  }
@@ -159,6 +160,7 @@ Each tier supports these fields:
159
160
  |-------|------|-------------|
160
161
  | `model` | string | Full model ID (`provider/model-name`) |
161
162
  | `variant` | string | Optional variant (e.g., `"max"` for extended thinking) |
163
+ | `costRatio` | number | Relative cost multiplier (e.g., 1 for cheapest, 20 for most expensive). Injected into the system prompt so the agent considers cost when delegating. |
162
164
  | `thinking` | object | Anthropic thinking config: `{ "budgetTokens": 10000 }` |
163
165
  | `reasoning` | object | OpenAI reasoning config: `{ "effort": "high", "summary": "detailed" }` |
164
166
  | `description` | string | Human-readable description shown in `/tiers` |
@@ -167,6 +169,91 @@ Each tier supports these fields:
167
169
  | `color` | string | Optional display color |
168
170
  | `whenToUse` | string[] | List of use cases (shown in delegation protocol) |
169
171
 
172
+ ### Routing modes
173
+
174
+ The plugin supports three routing modes that control how aggressively the agent delegates to cheaper tiers. Switch modes with the `/budget` command:
175
+
176
+ | Mode | Default Tier | Behavior |
177
+ |------|-------------|----------|
178
+ | `normal` | `@medium` | Balanced quality and cost — delegates based on task complexity |
179
+ | `budget` | `@fast` | Aggressive cost savings — defaults to cheapest tier, escalates only when needed |
180
+ | `quality` | `@medium` | Quality-first — uses stronger models more liberally for better results |
181
+
182
+ When a mode has `overrideRules`, those replace the global `rules` array in the system prompt. This lets each mode have fundamentally different delegation behavior.
183
+
184
+ Configure modes in `tiers.json`:
185
+
186
+ ```json
187
+ {
188
+ "modes": {
189
+ "normal": {
190
+ "defaultTier": "medium",
191
+ "description": "Balanced quality and cost"
192
+ },
193
+ "budget": {
194
+ "defaultTier": "fast",
195
+ "description": "Aggressive cost savings",
196
+ "overrideRules": [
197
+ "Default ALL tasks to @fast unless they clearly require code edits",
198
+ "Use @medium ONLY for: multi-file edits, complex refactors, test suites",
199
+ "Use @heavy ONLY when explicitly requested or after 2+ failed @medium attempts"
200
+ ]
201
+ },
202
+ "quality": {
203
+ "defaultTier": "medium",
204
+ "description": "Quality-first",
205
+ "overrideRules": [
206
+ "Default to @medium for all tasks including exploration",
207
+ "Use @heavy for architecture, debugging, security, or multi-file coordination",
208
+ "Use @fast only for trivial single-tool operations"
209
+ ]
210
+ }
211
+ }
212
+ }
213
+ ```
214
+
215
+ The active mode is persisted in `~/.config/opencode/opencode-model-router.state.json` and survives restarts.
216
+
217
+ ### Task taxonomy
218
+
219
+ The `taskPatterns` object maps common coding task descriptions to tiers. This is injected into the system prompt as a routing guide so the agent can quickly look up which tier to use:
220
+
221
+ ```json
222
+ {
223
+ "taskPatterns": {
224
+ "fast": [
225
+ "Find, search, locate, or grep files and code patterns",
226
+ "Read or display specific files or sections",
227
+ "Check git status, log, diff, or blame"
228
+ ],
229
+ "medium": [
230
+ "Implement a new feature, function, or component",
231
+ "Refactor or restructure existing code",
232
+ "Write or update tests",
233
+ "Fix a bug (first or second attempt)"
234
+ ],
235
+ "heavy": [
236
+ "Design system or module architecture from scratch",
237
+ "Debug a problem after 2+ failed attempts",
238
+ "Security audit or vulnerability review"
239
+ ]
240
+ }
241
+ }
242
+ ```
243
+
244
+ Customize these patterns to match your workflow. The agent uses them as heuristics, not hard rules.
245
+
246
+ ### Cost ratios
247
+
248
+ Each tier's `costRatio` is injected into the system prompt so the agent is aware of relative costs:
249
+
250
+ ```
251
+ Cost ratios: @fast=1x, @medium=5x, @heavy=20x.
252
+ Always use the cheapest tier that can reliably handle the task.
253
+ ```
254
+
255
+ Adjust `costRatio` values in each tier to reflect your actual provider pricing. The ratios don't need to be exact — they're directional signals for the agent.
256
+
170
257
  ### Rules
171
258
 
172
259
  The `rules` array in `tiers.json` controls when delegation happens. These are injected into the system prompt verbatim:
@@ -179,11 +266,33 @@ The `rules` array in `tiers.json` controls when delegation happens. These are in
179
266
  "Use @fast for any read-only exploration or research task",
180
267
  "Keep orchestration (planning, decisions, verification) for yourself -- delegate execution",
181
268
  "For trivial tasks (single grep, single file read), execute directly without delegation",
182
- "Never delegate to @heavy if you are already running on an opus-class model -- do it yourself"
269
+ "Never delegate to @heavy if you are already running on an opus-class model -- do it yourself",
270
+ "If a task takes 1-2 tool calls, execute directly -- delegation overhead is not worth the cost",
271
+ "Consult the task routing guide below to match task type to the correct tier",
272
+ "Consider cost ratios when choosing tiers -- always use the cheapest tier that can reliably handle the task"
183
273
  ]
184
274
  }
185
275
  ```
186
276
 
277
+ When a routing mode has `overrideRules`, those replace this array entirely for that mode.
278
+
279
+ ### Fallback
280
+
281
+ The `fallback` section defines which presets to try when a provider fails:
282
+
283
+ ```json
284
+ {
285
+ "fallback": {
286
+ "global": {
287
+ "anthropic": ["openai", "google", "github-copilot"],
288
+ "openai": ["anthropic", "google", "github-copilot"]
289
+ }
290
+ }
291
+ }
292
+ ```
293
+
294
+ When a delegated task fails with a provider/model/rate-limit error, the agent is instructed to retry with the next preset in the fallback chain.
295
+
187
296
  ## Commands
188
297
 
189
298
  | Command | Description |
@@ -191,6 +300,8 @@ The `rules` array in `tiers.json` controls when delegation happens. These are in
191
300
  | `/tiers` | Show active tier configuration and delegation rules |
192
301
  | `/preset` | List available presets |
193
302
  | `/preset <name>` | Switch to a different preset |
303
+ | `/budget` | Show available routing modes and which is active |
304
+ | `/budget <mode>` | Switch routing mode (`normal`, `budget`, or `quality`) |
194
305
  | `/annotate-plan [path]` | Annotate a plan file with `[tier:X]` tags for each step |
195
306
 
196
307
  ## Plan annotation
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-model-router",
3
- "version": "1.1.0",
3
+ "version": "1.1.1",
4
4
  "description": "OpenCode plugin that routes tasks to tiered subagents (fast/medium/heavy) based on complexity",
5
5
  "type": "module",
6
6
  "main": "./src/index.ts",
package/src/index.ts CHANGED
@@ -310,23 +310,16 @@ function buildFallbackInstructions(cfg: RouterConfig): string {
310
310
  const map = presetMap && Object.keys(presetMap).length > 0 ? presetMap : fb.global;
311
311
  if (!map) return "";
312
312
 
313
- const providerLines = Object.entries(map).flatMap(([provider, presetOrder]) => {
313
+ const chains = Object.entries(map).flatMap(([provider, presetOrder]) => {
314
314
  if (!Array.isArray(presetOrder)) return [];
315
- const validOrder = presetOrder.filter(
316
- (preset) => preset !== cfg.activePreset && Boolean(cfg.presets[preset]),
315
+ const valid = presetOrder.filter(
316
+ (p) => p !== cfg.activePreset && Boolean(cfg.presets[p]),
317
317
  );
318
- return validOrder.length > 0 ? [`- ${provider}: ${validOrder.join(" -> ")}`] : [];
318
+ return valid.length > 0 ? [`${provider}→${valid.join("")}`] : [];
319
319
  });
320
320
 
321
- if (providerLines.length === 0) return "";
322
-
323
- return [
324
- "Fallback on delegated task errors:",
325
- "1. If Task(...) returns provider/model/rate-limit/timeout/auth errors, retry once with a different tier suited to the same task.",
326
- "2. If retry also fails, stop delegating that task and complete it directly in the primary agent.",
327
- "3. Use the failing model prefix and this preset fallback order for next-run recovery (`/preset <name>` + restart):",
328
- ...providerLines,
329
- ].join("\n");
321
+ if (chains.length === 0) return "";
322
+ return `Err→retry-alt-tier→fail→direct. Chain: ${chains.join(" | ")}`;
330
323
  }
331
324
 
332
325
  // ---------------------------------------------------------------------------
@@ -336,24 +329,10 @@ function buildFallbackInstructions(cfg: RouterConfig): string {
336
329
  function buildTaskTaxonomy(cfg: RouterConfig): string {
337
330
  if (!cfg.taskPatterns || Object.keys(cfg.taskPatterns).length === 0) return "";
338
331
 
339
- const lines = ["Coding task routing guide:"];
340
- for (const [tier, patterns] of Object.entries(cfg.taskPatterns)) {
341
- if (Array.isArray(patterns) && patterns.length > 0) {
342
- lines.push(`- @${tier}: ${patterns.join(", ")}`);
343
- }
344
- }
345
- return lines.join("\n");
346
- }
347
-
348
- function buildCostAwareness(cfg: RouterConfig): string {
349
- const tiers = getActiveTiers(cfg);
350
- const costs = Object.entries(tiers)
351
- .filter(([_, t]) => t.costRatio != null)
352
- .map(([name, t]) => `@${name}=${t.costRatio}x`)
353
- .join(", ");
354
-
355
- if (!costs) return "";
356
- return `Cost ratios: ${costs}. Always use the cheapest tier that can reliably handle the task.`;
332
+ return Object.entries(cfg.taskPatterns)
333
+ .filter(([_, p]) => Array.isArray(p) && p.length > 0)
334
+ .map(([tier, patterns]) => `@${tier}→${(patterns as string[]).join("/")}`)
335
+ .join("\n");
357
336
  }
358
337
 
359
338
  // ---------------------------------------------------------------------------
@@ -363,51 +342,35 @@ function buildCostAwareness(cfg: RouterConfig): string {
363
342
  function buildDelegationProtocol(cfg: RouterConfig): string {
364
343
  const tiers = getActiveTiers(cfg);
365
344
 
366
- const tierSummary = Object.entries(tiers)
345
+ // Compact tier summary: @name=model/variant(costRatio)
346
+ const tierLine = Object.entries(tiers)
367
347
  .map(([name, t]) => {
368
- const shortModel = t.model.split("/").pop() ?? t.model;
369
- const variant = t.variant ? ` (${t.variant})` : "";
370
- return `@${name}=${shortModel}${variant}`;
348
+ const short = t.model.split("/").pop() ?? t.model;
349
+ const v = t.variant ? `/${t.variant}` : "";
350
+ const c = t.costRatio != null ? `(${t.costRatio}x)` : "";
351
+ return `@${name}=${short}${v}${c}`;
371
352
  })
372
- .join(" | ");
353
+ .join(" ");
373
354
 
374
- // Build per-tier whenToUse descriptions so the agent knows when to pick each tier
375
- const tierDescriptions = Object.entries(tiers)
376
- .map(([name, t]) => {
377
- const uses = t.whenToUse.length > 0 ? t.whenToUse.join(", ") : t.description;
378
- return `- @${name}: ${uses}`;
379
- })
380
- .join("\n");
355
+ // Compact mode
356
+ const mode = getActiveMode(cfg);
357
+ const modeSuffix = cfg.activeMode ? ` mode:${cfg.activeMode}` : "";
381
358
 
382
- // Task taxonomy from config
359
+ // Compact task routing guide
383
360
  const taxonomy = buildTaskTaxonomy(cfg);
384
361
 
385
- // Cost awareness
386
- const costLine = buildCostAwareness(cfg);
387
-
388
- // Mode-aware rules: if active mode has overrideRules, use those; otherwise use global rules
389
- const mode = getActiveMode(cfg);
362
+ // Compact rules
390
363
  const effectiveRules = mode?.overrideRules?.length ? mode.overrideRules : cfg.rules;
391
- const numberedRules = effectiveRules
392
- .map((rule, i) => `${i + 1}. ${rule}`)
393
- .join("\n");
364
+ const rulesLine = effectiveRules.map((r, i) => `${i + 1}.${r}`).join(" ");
394
365
 
395
- const fallbackInstructions = buildFallbackInstructions(cfg);
366
+ const fallback = buildFallbackInstructions(cfg);
396
367
 
397
368
  return [
398
- "## Model Delegation Protocol",
399
- `Preset: ${cfg.activePreset}. Tiers: ${tierSummary}.`,
400
- "",
401
- "Tier capabilities:",
402
- tierDescriptions,
403
- ...(taxonomy ? ["", taxonomy] : []),
404
- ...(costLine ? ["", costLine] : []),
405
- ...(mode ? [`\nActive mode: ${cfg.activeMode} (${mode.description})`] : []),
406
- "",
407
- "Apply to every user message (plan and ad-hoc):",
408
- numberedRules,
409
- ...(fallbackInstructions ? ["", fallbackInstructions] : []),
410
- "",
369
+ `## Model Delegation Protocol`,
370
+ `Preset: ${cfg.activePreset}. Tiers: ${tierLine}.${modeSuffix}`,
371
+ ...(taxonomy ? [taxonomy] : []),
372
+ rulesLine,
373
+ ...(fallback ? [fallback] : []),
411
374
  `Delegate with Task(subagent_type="fast|medium|heavy", prompt="...").`,
412
375
  "Keep orchestration and final synthesis in the primary agent.",
413
376
  ].join("\n");
package/tiers.json CHANGED
@@ -174,39 +174,9 @@
174
174
  }
175
175
  },
176
176
  "taskPatterns": {
177
- "fast": [
178
- "Find, search, locate, or grep files and code patterns",
179
- "List or show directory structure and file contents",
180
- "Read or display specific files or sections",
181
- "Check git status, log, diff, or blame",
182
- "Lookup documentation, API signatures, or type definitions",
183
- "Count occurrences, lines, or matches",
184
- "Check if a file, function, or class exists",
185
- "Simple rename or string replacement across files"
186
- ],
187
- "medium": [
188
- "Implement a new feature, function, or component",
189
- "Refactor or restructure existing code",
190
- "Write or update tests",
191
- "Fix a bug (first or second attempt)",
192
- "Modify or update existing code logic",
193
- "Code review with suggested changes",
194
- "Run build/lint/test and fix resulting errors",
195
- "Create a new file from a template or pattern",
196
- "Database migration or schema changes",
197
- "API endpoint implementation",
198
- "Configuration or dependency updates"
199
- ],
200
- "heavy": [
201
- "Design system or module architecture from scratch",
202
- "Debug a problem after 2+ failed attempts",
203
- "Security audit or vulnerability review",
204
- "Performance profiling and optimization",
205
- "Migration strategy (framework, language, infrastructure)",
206
- "Complex multi-system integration design",
207
- "Evaluate tradeoffs between competing approaches",
208
- "Root cause analysis of complex or elusive failures"
209
- ]
177
+ "fast": ["search", "grep", "read", "git-info", "ls", "lookup-docs/types", "count", "exists-check", "rename"],
178
+ "medium": ["impl-feature", "refactor", "write-tests", "bugfix(≤2)", "edit-logic", "code-review", "build-fix", "create-file", "db-migrate", "api-endpoint", "config-update"],
179
+ "heavy": ["arch-design", "debug(≥3fail)", "sec-audit", "perf-opt", "migrate-strategy", "multi-system-integration", "tradeoff-analysis", "rca"]
210
180
  },
211
181
  "modes": {
212
182
  "normal": {
@@ -217,22 +187,22 @@
217
187
  "defaultTier": "fast",
218
188
  "description": "Aggressive cost savings — defaults to cheapest tier, escalates only when needed",
219
189
  "overrideRules": [
220
- "Default ALL tasks to @fast unless they clearly require code edits or complex reasoning",
221
- "Use @medium ONLY for: multi-file edits, complex refactors, test suites, or build-fix cycles",
222
- "Use @heavy ONLY when explicitly requested by user or after 2+ failed @medium attempts",
223
- "Prefer executing simple tasks directly (grep, read, glob) over delegating — zero delegation overhead",
224
- "Batch multiple related searches into a single @fast delegation instead of multiple calls",
225
- "When uncertain between @fast and @medium, choose @fast — escalate only on failure"
190
+ "default→@fast unless edits/complex-reasoning needed",
191
+ "@medium ONLY: multi-file-edit/refactor/test-suite/build-fix",
192
+ "@heavy ONLY: user-requested OR 2 @medium failures",
193
+ "trivial(grep/read/glob)→direct,no-delegate",
194
+ "batch related searchessingle @fast",
195
+ "uncertain @fast vs @medium→@fast,escalate on fail"
226
196
  ]
227
197
  },
228
198
  "quality": {
229
199
  "defaultTier": "medium",
230
200
  "description": "Quality-first — uses stronger models more liberally for better results",
231
201
  "overrideRules": [
232
- "Default to @medium for all tasks including exploration when deep context understanding matters",
233
- "Use @heavy for any task involving architecture, debugging, security, or multi-file coordination",
234
- "Use @fast only for trivial single-tool operations (one grep, one file read)",
235
- "Prefer thoroughness over speed — better to over-qualify a task than under-qualify it"
202
+ "default→@medium incl exploration when deep-context matters",
203
+ "@heavy: arch/debug/security/multi-file-coord",
204
+ "@fast ONLY: trivial single-tool ops (1 grep/1 read)",
205
+ "prefer thoroughness over speed"
236
206
  ]
237
207
  }
238
208
  },
@@ -245,18 +215,14 @@
245
215
  }
246
216
  },
247
217
  "rules": [
248
- "When a plan step contains [tier:fast], [tier:medium], or [tier:heavy], delegate to that agent",
249
- "When a plan says 'use a fast/cheap model' -> delegate to @fast",
250
- "When a plan says 'use a medium/balanced model' -> delegate to @medium",
251
- "When a plan says 'use a heavy/powerful model' -> delegate to @heavy",
252
- "Default to @medium for implementation tasks you could delegate",
253
- "Use @fast for any read-only exploration or research task",
254
- "Keep orchestration (planning, decisions, verification) for yourself - delegate execution",
255
- "For trivial tasks (single grep, single file read), execute directly without delegation",
256
- "Never delegate to @heavy if you are already running on an opus-class model - do it yourself",
257
- "If a task takes 1-2 tool calls, execute directly — delegation overhead is not worth the cost",
258
- "Consult the task routing guide below to match task type to the correct tier",
259
- "Consider cost ratios when choosing tiers — always use the cheapest tier that can reliably handle the task"
218
+ "[tier:X]delegate X",
219
+ "plan:fast/cheap→@fast | plan:medium→@medium | plan:heavy→@heavy",
220
+ "default:impl→@medium | readonly→@fast",
221
+ "orchestrate=self,delegate=exec",
222
+ "trivial(≤2tools)→direct,skip-delegate",
223
+ "self∈opus→never→@heavy,do-it-yourself",
224
+ "consult route-guide↑",
225
+ "min(cost,adequate-tier)"
260
226
  ],
261
227
  "defaultTier": "medium"
262
228
  }