Elyra 0.9.20: The Agent That Checks Its Own Work — and Remembers Which Models Let It Down
Auto-diagnostics and blast radius on every edit, swarm pipelines isolated in git worktrees, and failover that learns which models actually work on your machine. Three instincts, one idea: the agent should check its own work, and the system should learn from the outcome.
Some releases add features. This one adds instincts. Three of them: noticing your own mistakes, not making a mess of someone else's desk, and remembering who's reliable. Suspiciously human traits for a coding agent — and all three came out of one question we kept asking ourselves: where does a developer lose time when pairing with an agent?
Why this release
Watch a session closely and you'll see the same three time sinks over and over:
The agent edits a file, declares victory, and the type error it just introduced surfaces two turns later — usually because you ran the check.
You want the agent to do a bigger piece of work autonomously, but you don't quite dare — it works directly in your working tree, and you've got uncommitted changes sitting there.
A provider has a bad day, failover kicks in... and picks a fallback model that has also been having a bad day all week. The static ranking had no way of knowing.
0.9.20 attacks all three. Here's the why and the how.
1. Auto-diagnostics + blast radius on every edit
In 0.9.18 we taught the LSP extensions to resolve referenced types after an edit. That was step one. This release completes the loop — after every successful edit in a TypeScript, PHP, or Rust project, the agent now sees three things in the edit's own tool result, with zero extra tool calls:
Successfully replaced 1 block(s) in src/services/export.ts.
[Diagnostics — auto-checked via LSP]
2 errors in this file after the edit:
- src/services/export.ts:48:11 [2345]: Argument of type 'string' is not
assignable to parameter of type 'ExportFormat'.
- src/services/export.ts:52:3 [2741]: Property 'compress' is missing...
[Blast radius — auto-resolved via LSP]
scheduleExport is referenced in 4 places outside this file:
- src/routes/api.ts:112
- src/jobs/nightly-export.ts:31
- src/controllers/ReportController.ts:88
- test/export.test.ts:19
[Related symbols — auto-resolved via LSP, no extra tool call needed]
- ExportFormat: type ExportFormat = "csv" | "json"
Why this matters: the agent used to discover that first error when you did. Now it sees it before writing its next sentence — and it knows there are four call sites to update before it congratulates itself on changing a signature. Each of these used to be a full round trip: a wasted turn, a grep, a follow-up prompt. Now it's free context, delivered in-band.
It's built on the language servers you already have (tsserver, Intelephense, rust-analyzer), waits briefly for fresh diagnostics after syncing the file, and is entirely best-effort — if anything fails, the edit result is untouched. Rust gets a slightly longer diagnostics window because rust-analyzer likes to think things over.
2. Swarm worktree mode: multi-agent work without the mess
Our /swarm pipelines (build, review, refactor) have always run their stages in your session. Effective — but every write stage worked directly in your working tree. Autonomy with your uncommitted changes as collateral.
Now:
/swarm --worktrees build add rate limiting to the API
Here's what happens differently:
Every stage — planner, coder, tester, reviewer, fixer — runs as its own isolated
elyra -psub-agent inside a detached git worktree based on HEAD. Your working tree is never touched while the swarm runs. Go on editing; the swarm can't step on you.Read-only stages aren't just told not to edit files anymore — they're mechanically restricted to
read,grep,find, andls. A planner literally cannot write.When all stages finish, Elyra collects the combined changes as a single patch and checks it against every file that changed in your tree during the run. Clean? The patch is applied uncommitted, ready for your review — Elyra never commits without being asked. Conflict? Nothing is applied, the conflicting paths are listed, and the worktree is kept so no work is lost.
Not in a git repo? It degrades gracefully to the classic inline mode.
Why this matters: this is the difference between "I'll run a swarm when the tree is clean and I'm watching" and "run the swarm, I'll review the diff when it's done." Isolation is what turns multi-agent pipelines from a demo into a tool.
3. Measured routing: failover that learns from your machine
Elyra's cross-provider failover has always been a favorite: provider melts down mid-turn, Elyra reroutes to an equivalent model from another vendor you hold keys for. But the fallback ranking was purely static — cost band, reasoning capability, context window. Sensible on paper. Blind in practice.
Now Elyra keeps a small local ledger (~/.elyra/agent/routing-ledger.jsonl) of how models actually perform for you: turn success rate, edit failures, retries, failovers away, latency, cost. When failover fires, models the ledger shows to be demonstrably unreliable get demoted in the ranking.
Check what it knows anytime:
/routing-stats
Model outcome measurements (last 30 days, local only):
- anthropic/claude-sonnet-5: 212 turns, 98% success, 3/94 edit failures,
2 retries, 0 failovers away, $4.1120 total, 9.3s avg
- openai/gpt-5.6: 41 turns, 95% success, 1/18 edit failures, 1 retry,
1 failover away, $1.0330 total, 7.8s avg
- somevendor/flaky-model: 12 turns, 58% success, 4/9 edit failures,
7 retries, 5 failovers away, $0.4410 total, 21.6s avg [demoted in failover ranking]
Also available outside a session as elyra doctor routing.
Three design choices worth spelling out:
A sample-size floor. Below five measured turns, a model ranks exactly as before. Thin data never changes anything; measurements only ever demote demonstrated problems.
Demotion, not promotion. This isn't a bandit algorithm chasing scores. Static heuristics still decide; the ledger just keeps the ranking from walking into a known wall.
Local, and only numbers. Model ids, counters, timings, cost. Never prompts, never file paths, never code. Nothing leaves your disk. Opt out entirely with the
routingLedgersetting.
Why this matters: every vendor-locked agent has exactly one answer when its provider stumbles: an error message. Elyra's answer is "route around it" — and as of today, "route around it toward the model that's actually been working for you." That's only possible because Elyra is provider-agnostic and your usage history lives on your machine.
The thread connecting all three
Auto-diagnostics closes the loop on a single edit. Worktree mode closes the loop on a whole pipeline. Measured routing closes the loop on model choice itself. Same idea at three scales: the agent should check its own work, and the system should learn from the outcome.
Get it
npm install -g @elyracode/coding-agent@latest
Then /reload old sessions, point a swarm at something with --worktrees, and take a look at /routing-stats in a week — it reads like a performance review your models didn't know they were getting.