{ "name": "model-router", "version": "0.4.4", "description": "Routes each subagent to Haiku, Sonnet or Opus by how well-defined its brief is, verifies dev work below Opus in its own clone on a different model, sends failures back to the same agent then a stronger one, and estimates the savings against Opus.", "author": { "name": "Glenn Schrooyen" }, "userConfig": { "testCommand": { "type": "string", "title": "Test command (run in the agent's clone)", "description": "The unit-suite command CI runs, from .gitea/workflows/checks.yml. Its output goes to the verifier. Empty: no tests.", "default": "" }, "testTimeoutSec": { "type": "number", "title": "Test time limit (seconds)", "description": "How long the test command may run in the clone. A run that times out is reported as NOT VERIFIED, never as a FAIL.", "default": 1800 }, "defaultBaseBranch": { "type": "string", "title": "Base branch when the brief names none", "description": "Used after the PR lookup and the brief's own base branch.", "default": "release/1.0" }, "prBaseCommand": { "type": "string", "title": "Command that prints the PR's base branch", "description": "Run in the clone; its first output line is the branch. Empty or failing: the brief's base branch, then the default.", "default": "" }, "maxRewrites": { "type": "number", "title": "Failed verdicts before handing back", "description": "1st fail: resume the same agent. 2nd: new agent one model up in the same clone. Past this number: handed back to the manager.", "default": 2 }, "safetyPatterns": { "type": "string", "title": "Safety-critical patterns (logged only)", "description": "Comma-separated. Marks a task as critical in the log. Dev work below Opus is always verified by Opus.", "default": "control loop,integrator,safety,staleness,watchdog,failsafe,fail-safe,deadlock,rs485,modbus,meter emulat,asyncio,setpoint" }, "respectExplicitModel": { "type": "boolean", "title": "Keep a named model on agents without a role", "description": "Review and test agents always keep a named model; dev agents never do. This covers everything else.", "default": false }, "allowFable": { "type": "boolean", "title": "Allow Fable for rewrites", "description": "A rewrite after Opus fails runs on Fable instead of handing back.", "default": false }, "prices": { "type": "string", "title": "Price overrides (JSON, USD per MTok)", "description": "Empty: list prices of 2026-10-08. Else a JSON list of rows, checked before the defaults: [{\"match\":\"sonnet-5-5\",\"price\":{\"in\":2,\"out\":10,\"write\":2.5,\"read\":0.1}}]", "default": "" } } }