Skip to main content
Auto is an entry in the model picker. Selecting it hands per-call model choice to a router instead of pinning one provider. The router costs no inference: it never asks an LLM which model to use, because doing so would make Auto slower and more expensive than just picking one yourself.

What it actually optimises

The obvious framing is “use a smarter model for harder prompts”. That is not the main problem Auto solves. In practice the models available to you at any moment are usually cloud frontier near-peers with no quality spread worth arbitraging. What actually costs you turns is a provider being rate-limited or returning errors. So Auto treats availability and health as hard filters, and treats quality as a preference on top. Three things follow from that, and they are worth knowing before you turn it on:
  • Routing is structural, not semantic. It reads the shape of the turn, never the meaning of your prompt.
  • On a pool of near-peers the router often reports low confidence, and that is correct — it means the models really are interchangeable for that turn.
  • If you ask for a local-only route and no local model is available, Auto refuses rather than quietly sending your prompt to the cloud.

Turning it on

From the CLI:
Or in ~/.xynthis/config.toml:
From the app, pick Smart Auto at the top of the model picker. It appears whenever at least one provider is available. Anything that doesn’t parse as auto[:policy] is a manual target and bypasses the router completely, so existing configs are unaffected. Picking a specific model in the picker is a hard override — Auto is off until you select it again.

The four policies

A policy changes exactly two weights: how much the router values speed, and how much it values raw model strength. Nothing else.
auto:private is a hard constraint, not a preference. If no local model is available and healthy, the router returns no feasible model and the turn fails rather than falling back to a cloud provider. That is deliberate. Set up a local model before relying on it.

How a decision is made

Three stages, in order. Stage 1 — feasibility. A hard filter that produces the set of models allowed to run this turn. A model must be available, healthy, reachable with usable credentials, have enough context capacity for the transcript, support the tool mode the turn needs, and satisfy the privacy requirement. Feasibility is computed before scoring, and no score can re-admit a model the filter excluded. That is the safety property — it is what makes auto:private trustworthy. Stage 2 — scoring. Every surviving candidate gets a utility score (below). Stage 3 — selection. Highest score wins. Ties break on stable input order, so the same inputs always produce the same route.

The arithmetic

The score for a model mm on a turn zz: S(m,z)  =  Φ(d,q)  +  wsσ(m)  +  wqκ(m)  +  R    C    XS(m,z) \;=\; \Phi(d,q) \;+\; w_s\,\sigma(m) \;+\; w_q\,\kappa(m) \;+\; R \;-\; C \;-\; X Each term, concretely. Depth fit Φ(d,q)\Phi(d,q) — how well the model’s strength class matches the reasoning depth the turn needs: The Trivial row inverts on purpose. A one-line summary after a tool call gains nothing from a deliberate model, and paying its latency is a real cost. Speed σ\sigma and strength κ\kappa: Policy weights (ws,wq)(w_s, w_q) — the only thing a policy changes: Risk escalation R=0.5R = 0.5, applied when the turn is high-risk and the candidate is a Frontier model. High-risk work escalates regardless of policy, including under auto:fast — a wrong destructive edit costs far more than the latency saved. Access cost C=0.6C = 0.6, applied when the route is not prepaid. This is not spend-optimisation. It exists so that if you already hold a Claude or ChatGPT subscription, you aren’t silently routed through purchased Xynthis credits and charged twice for the same capability. Your own API key counts as prepaid. Switch cost X=0.25X = 0.25, applied to any candidate that isn’t the model that handled the previous turn. This matters because the models are near-peers: without it, scoring noise alone would flip the model every turn.

Confidence is a margin, not a probability

c  =  clamp ⁣(S(m)S(mrunner-up)2,  0,  1)c \;=\; \operatorname{clamp}\!\left(\frac{S(m^*) - S(m_{\text{runner-up}})}{2},\; 0,\; 1\right) with c=1c = 1 when only one candidate is feasible. Near-peers routinely tie, and a low number there is the honest answer: it means the choice genuinely didn’t matter. Reporting high confidence for a 0.01 margin would be fabricated.

Worked example

Pool: one Frontier/Deliberate model and one Mid/Fast model. Policy balanced, no incumbent, both prepaid, low risk. Trivial turn (a summary after tool results):
Deep turn, same pool:

How the turn is classified

Structural signals only — no inference, and your prompt text is never inspected to infer intent:

Health tracking

The router learns provider health from real failures during the session:
  • A 429 or quota error marks the provider rate-limited and evicts it immediately.
  • Other failures are counted; a provider is evicted on the second one. A single 5xx is routinely transient, and evicting on it would make routing flap.
  • Any success clears the record, so one bad minute can’t bench a provider for the rest of the session.
Failures are only recorded after the normal retry path has already given up, so an eviction means genuinely unusable, not transient.
Health is only learned from providers actually called. A provider that is rate-limited but untouched this session still looks healthy until the first call fails. Discovering it costs one failed call.

When it falls back

The router never returns a model that failed the feasibility filter.

What Auto deliberately does not do

Three signals are absent from the score, and the omission is a design decision rather than unfinished work — each needs observed success statistics that don’t exist yet, and inventing them would produce confident-looking numbers with nothing behind them:
  • Uncertainty. Penalising models the router has merely seen too little of, rather than models it has seen fail.
  • Domain specialty. Knowing that one model is genuinely better at, say, Rust than another.
  • Routing entropy. Detecting that the router can’t separate the candidates at all, and responding by adding verification or asking you, instead of picking arbitrarily.
Until those are measured, Auto optimises for what it can actually observe: availability, health, depth fit, latency, and not charging you twice.