Routing coding tasks across Claude Code, Codex and Grok

25 October 2026

A run in CodeLynq can be executed by one of three coding agents: Claude Code, OpenAI's Codex CLI or a Grok CLI. They all receive the same approved spec and go through the same verification, review, security and architecture gates before the same pull request opens. The agent is a setting per organisation, not a different product.

Having three raises an obvious question: should a run pick between them? In September we wrote about routing across the Claude tiers and said, at the time correctly, that Grok and Codex were not part of it. That has changed for one narrow case, and the narrowness is the point of this post.

Two settings, not one

Automatic routing picks a Claude model per task. Cross-provider routing is a second switch, off by default, that lets the router consider another vendor's agent as well. We kept them separate on purpose. Which model does the work is a cost decision; which company sees your code is a contractual one. Plenty of teams want the first and are not allowed the second, and a single toggle would force them to give up both.

A model pinned in the organisation settings beats both. If someone has deliberately chosen a model, the router does not second-guess them.

Only where a mistake costs one retry

The router only considers leaving Claude when it has already landed on the cheapest Claude tier. In practice that is mechanical work: small chores such as a dependency bump or a rename, and small bugfixes that arrived with a stack trace, where finding the bug is already done. There, a cheaper agent getting it wrong costs one retry, and the retry is cheap.

Features, refactors and anything else the rules put on a stronger tier never switch provider. A bad refactor is expensive because of the review it takes to find out it is bad, not because of the tokens, so saving a few cents on the run is the wrong trade.

Measured failure beats price. The router already counts, per project and per kind of task, how often each model got the work right first time. Once the cheaper agent has ten runs in a bucket and gets fewer than half of them right first time, the project goes back to Claude for that kind of work, and the run's reason says so.

Today the cross-provider candidate is Grok's coding model. Codex runs when an organisation selects it as its agent; the router does not pick it on its own.

Comparing three vendors in one unit

You cannot route on cost without comparing costs, and the CLIs do not help. Claude Code reports what a run cost. Grok and Codex report neither a cost nor, reliably, token counts. So we keep a rate table per model, and the router compares a blended rate weighted to the shape of a coding run: a lot of repository read in, a small diff out.

The estimate made from that table is stored separately from the cost a CLI reports, so a guess is never read as a measurement, and each run keeps the estimate made at the time it ran. A model without a rate gets no estimate rather than zero, because a zero would make it look free and win every comparison. For the same reason the screen where we maintain the rates refuses zero and, before saving, shows which kinds of task would switch agent under the new numbers. A mistyped rate would otherwise reroute work without any error at all.

What went wrong on the way

The first version had a gap: the router could choose a Grok model while the run was still set to use Claude Code. Our own safety check drops a model that does not belong to the agent, so the run would have quietly gone ahead on the default Claude model, at the price the router was trying to avoid. The agent now follows the routed model, and the run log says when it switched.

The CLIs taught us a second lesson. Our first Grok command line copied Claude Code's flags, which Grok does not accept, and Codex starts in a read-only sandbox unless told otherwise, so it can edit nothing and still exit as if it had succeeded. The command lines are now checked against the real binaries, which are pinned to exact versions in our image, because these tools run next to your repository credentials.

A router has to explain itself

For a while we recorded, on every run, the model the router chose, the reason, the agent and whether the run was an escalation. None of it was shown to the customer. A routing decision you cannot see is one you cannot trust with a budget, and we had built exactly that.

Every routed run now shows its model, the agent that ran it and the reason in plain text on the run page: the task type and size, a second repository, a stack trace, or the measured success rate that moved it up or down. If it switched to a cheaper agent, the reason says how much cheaper it was on the rates in force.

Retries had the same problem. With routing on, a failed run that you retry is escalated, because repeating the same attempt on the same model usually repeats the same failure, but the button only appeared on queued runs, so the one case that carried escalation could not be reached from the run page. It now appears on failed runs too, as Retry run, and the run shows which model it was escalated from. A failed run on a cheaper agent is not handed back to it; the retry goes to Claude, on a stronger tier.

What this does not do

  • It does not route judgement work to a cheaper vendor, by design.
  • It does not choose Codex for you.
  • It does not know the vendors' prices; it knows our rate table. The router needs the order of those numbers to be right, which is a lower bar than exact, but a stale rate still biases it.
  • With cross-provider routing on, the code for those runs goes to that provider. Leave it off if your contracts say one vendor.

If you are comparing agents, the practical test is the same one we apply to the router: for any run, can you see which model wrote it and why? The agents themselves are described on coding agents, and the cost side on cost control.

Back to all articles

Test it on a task from your own backlog

Send us one real task. We run CodeLynq on your repository and you review the pull request. Free, within 5 working days.