pai
    Preparing search index...

    Routing

    This guide covers model routing and the route policy that decides which model a request for model: "auto" runs.

    Phantom AI stores and enforces all of this on its side. pai sends the settings and prints what Phantom AI returns. Where this guide describes how Phantom AI applies a setting, it describes the server's code at the time of writing.

    A request for model: "auto" needs a route policy on the key. Without one, Phantom AI refuses it. A policy names the models auto may run and the rules that pick one ( RoutePolicy, RouteRule):

    Field Meaning Phantom AI's default
    models the models auto may run; the first is the default required
    applies_to auto routes only requests for auto; all routes named models too auto
    rules checked in order; the first one that matches picks the model none
    on_empty when credit is exhausted: stop refuses, cheapest runs the cheapest model in models stop
    fallback_on_error if the chosen model fails, try the other models false
    stick_minutes keep a conversation on its model this many minutes after its last request; 0 turns it off 5
    stick_by_prompt recognise a conversation by its opening when it sends no x-phantom-session header true

    Each rule has one condition in if and a model in use:

    Condition Matches when
    pace the plan's pace is on_pace or ahead
    budget_left_pct_below less than this percent of the cap is left
    days_left_below fewer than this many days are left in the period
    has_tools the request does (true) or doesn't (false) send tools
    input_tokens_over the prompt is estimated at more than this many tokens
    reasoning_requested the request does or doesn't ask for reasoning

    use names a model from models, or one of:

    • cheapest: the model in models with the lowest input plus output price,
    • first: the first model in models,
    • next: the model after the one requested in models, wrapping around; for auto, the second model.

    With no match, auto runs the first model, and a named model (under applies_to: "all") runs as asked.

    pai route                                          # show the policy
    pai route set --models <model-a>,<model-b> # the first is the default
    pai route set --on-empty cheapest --fallback # change two fields, keep the rest
    pai route set --file policy.json # replace the whole policy
    pai route rule add --if has_tools=true --use first --at 1 # add it first
    pai route rule rm 2 # remove rule 2
    pai route clear # remove the policy

    route set with flags reads the current policy first. When one exists, pai sends only the fields you gave, and Phantom AI keeps the rest ( patchRoute). When none exists, pai sends the fields as a new policy ( putRoute), so the first route set needs --models. --file always replaces the whole policy.

    --fallback and --stick-by-prompt turn a field on; follow them with false to turn it off.

    route rule add needs a policy already. pai reads --if name=value into one condition: true and false become true and false, a number becomes a number, and anything else stays text ( parseCondition). --at n puts the rule at position n, counting from 1. pai then sends the whole new list of rules.

    Phantom AI checks every policy before saving it: from one to ten models, up to 20 rules, one condition per rule, and a use that names one of models or cheapest, first or next.

    pai route test                # what "auto" would run now, and the rule that picked it
    pai route test --model <id> # the same for a named model

    route test runs Phantom AI's router against the key's current policy. Phantom AI calls no model and charges nothing ( testRoute). pai sends only the model name, so conditions about the request itself (has_tools, input_tokens_over, reasoning_requested) see an empty request. The MCP tool test_route does the same.

    Switching models mid-conversation throws away the prompt cache, the discount a provider gives for repeating the start of a prompt. With stick_minutes above 0, Phantom AI keeps a conversation on the model it last ran unless the rules' pick costs less even against the cached price.

    Phantom AI tells conversations apart by the x-phantom-session header your own inference requests send. Without the header, and with stick_by_prompt on, it uses a hash of the conversation's opening, held in memory. pai sends no x-phantom-session header: it makes no inference calls apart from verify. Add the header in the client your agent uses to call Phantom AI.

    A request with the header x-phantom-route: off skips routing; a request for auto with that header is refused.

    The MCP tools are get_route, set_route (pass policy: null to remove it, or merge: true to change some fields) and test_route.