An Opus-run dev got no verification and no message, so silence meant both "still verifying" and "will never verify" (SAFETY-135 waited overnight, SAFETY-126 8 h). Verdicts were also labelled with the routing choice, not the model the run used. - Every dev hand-back posts one line at once: "[model-router] Tn verifying on Opus..." (a verdict follows), or "[model-router] Tn no verification: dev ran on Opus. Go straight to review." A run that ends with an error or names no clone says so. - Each round is decided and labelled by the model the run reported (its end usage), the routing choice only as fallback. A difference is shown as "(routed to X, ran on Y)", also on later rounds. - 8 new tests; each new rule was also broken on purpose and caught, apart from one equivalent change. Version 0.4.6. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MdqPWvuDpbpRvDEdURoAwo
64 lines
2.8 KiB
JSON
64 lines
2.8 KiB
JSON
{
|
|
"name": "model-router",
|
|
"version": "0.4.6",
|
|
"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": ""
|
|
}
|
|
}
|
|
} |