Bosphorus

← Knowledge base

Choosing Jev Router in aimo: which model answers

See which model answers when you choose OpenRouter's Jev Router in aimo: the calls that list it, send to it and show the model that replied.

ModelsOpenRouterAPIaimoChecked against the product on

Some models in the picker are not one model. Jev Router, typesafe/jev-router on OpenRouter, looks at each request and chooses another model to answer it. When you pick it in aimo, the model that replies can change from one message to the next, and the platform shows you which one it was.

This article follows the API calls behind that: how the router gets into the list, what the gateway sends, where the choice is made and what you can read back. Every command below was run against a live installation on 5 October 2026, and the answers quoted are the ones it gave.

The short answer

aimo never switches models. It sends one model id, OR/typesafe/jev-router, and the gateway passes that id on to OpenRouter. The choice happens inside OpenRouter. Jev, the decision model behind the router, reads the conversation, judges the task and how hard it is, and picks the cheapest model in its pool that meets the bar. The model it chose is reported in the model field of the answer, and the provider that ran it in provider.

The gateway’s part is smaller. It lists the router like any other OpenRouter model, applies the models your account may use, sends the request and records the provider and the cost OpenRouter reports.

Who does what

Step Who Where
Register the router Administrator Console, /providers → OpenRouter
Allow it for a team or person Administrator Console, /keys → model profiles
Pick it in a chat Each person aimo, the model picker
Call it from a script Each person Any HTTP client, with a platform key

Step 1: the router is in the list

An administrator registers typesafe/jev-router on the OpenRouter tab of /providers. Add & check asks OpenRouter two things that cost no tokens: whether the key is valid and whether the id exists. A router has no fixed endpoint, so an empty endpoint list is normal and does not count as an error. The check saves the model’s modality, and the platform turns that into the capabilities it shows.

aimo fills its picker from the list the gateway gives it. Look at the same list yourself:

GW=https://ai.corp.example
curl -s $GW/v1/models -H "Authorization: Bearer $BOSPHORUS_KEY" \
  | jq -c '.data[] | select(.id=="OR/typesafe/jev-router")'

The entry the live gateway returned:

{"capabilities":["vision","audio"],"id":"OR/typesafe/jev-router","nodes":["openrouter"],"object":"model","owned_by":"openrouter","type":"llm"}

OpenRouter models are listed under the prefix OR/. The entry appears only if the models your account may use include it. A capability that is missing from an entry means the platform could not confirm it, not that the model lacks it.

Step 2: what one message does

When you send a message, aimo posts to /v1/chat/completions with the model OR/typesafe/jev-router. The gateway then:

  1. Removes the OR/ prefix and works with the id typesafe/jev-router from here on.
  2. Serves the request from the OpenRouter models only. It never falls through to another provider that happens to have a model of the same name.
  3. Checks that the model is enabled, that a key exists for it and that your account may use it. Then your policy checks and rate limits run, as for any model.
  4. Sends the request to OpenRouter with one field added, so that OpenRouter reports the cost.

OpenRouter hands the request to Jev, which chooses the model. The answer comes back with the model that ran and the provider that served it, and the gateway streams it to you unchanged.

Step 3: see the switch yourself

Send two very different prompts and compare the model field of each answer. The first command defines a small helper so the two calls stay short.

ask() {
  curl -s $GW/v1/chat/completions \
    -H "Authorization: Bearer $BOSPHORUS_KEY" -H 'Content-Type: application/json' \
    -d "$1" \
    | jq -c '{model, provider, cost: .usage.cost, tokens: .usage.completion_tokens}'
}

An easy prompt:

ask '{"model":"OR/typesafe/jev-router","max_tokens":200,"messages":[{"role":"user","content":"Say hello in one word."}]}'
{"model":"openai/gpt-6-luna","provider":"Azure","cost":0.0000037,"tokens":5}

A hard one:

ask '{"model":"OR/typesafe/jev-router","max_tokens":3000,"messages":[{"role":"user","content":"Prove that the square root of 2 is irrational, then find the smallest solution of x^2 - 2y^2 = 1 with y>0."}]}'
{"model":"anthropic/claude-sonnet-5.5","provider":"Claude Platform on AWS","cost":0.005046,"tokens":494}

Same model id in the request, two different models in the answers, and a cost for each that is the figure OpenRouter reported for that one request. These two are samples of what Jev chose on that day. What it picks is up to OpenRouter and TypeSafe, and it can change.

With "stream": true the first frame already carries the same two fields, so a client can show which model is answering before the text arrives:

{"model":"openai/gpt-6-luna","provider":"Azure"}

Narrowing the pool

By default Jev chooses from its whole pool. A script can narrow it by sending a jev-router plugin with the request. Each entry is an exact model id or a pattern such as openai/*. The gateway passes the field through. aimo’s picker does not send one.

ask '{"model":"OR/typesafe/jev-router","max_tokens":300,"plugins":[{"id":"jev-router","models":["openai/*"]}],"messages":[{"role":"user","content":"Prove that the square root of 2 is irrational, in three sentences."}]}'
{"model":"openai/gpt-6.1-sol","provider":"OpenAI","cost":0.001734,"tokens":169}

A hard prompt that went to Anthropic’s model above stayed with OpenAI’s here. Entries in models that match nothing are ignored. Entries in excluded_models are never ignored: if they remove every candidate, the request fails with a 404.

A policy note. Allowing OR/typesafe/jev-router for a team allows whatever Jev routes to, because the platform only learns the chosen model when the answer arrives. If that matters, narrow the pool with the plugin or choose a specific model. The article on calling the API with your own keys explains which credential a script sends.

What the platform records

Each request leaves one usage record. It holds the model you asked for, typesafe/jev-router, the provider that actually served it and the cost OpenRouter reported. The name of the model that answered is in the response body that you receive, not in that record. In the console the same requests appear on /activity, and the cost on /usage.

When something is not right

What you see Likely cause
The router is missing from the list It is not registered, it is disabled, or the models your account may use leave it out. Ask an administrator.
A 503 that names /providers The id is not registered, or no key is set for it.
A 403 model_not_allowed The models your account may use do not include it. In aimo this appears as a message in the chat.
A 404 after you sent a plugin Your excluded_models removed every candidate.
Costs look like they change between turns Jev chose a different model. Compare the model field of each answer.