Documentation

Search documentation

Choose and route models

Select a model, prefer models for particular tasks, and inspect the decision Orek made.

Orek can choose a model for each turn from your configured providers. A route describes a kind of task, such as simple/lookup or planning/general, and can express model preferences for that task.

Pin a model when you want to choose it yourself. Add route files when you want automatic selection with preferences for different kinds of work.

Need to connect a service first? Start with Providers to choose from the built-in catalog, then follow Quickstart.

Pinning

Start in an open Orek session with a configured provider. Open the model picker:

In Orek · command

/model

Choose a model and press Enter. Ask a project question, then inspect the applied selection:

In Orek · command

/routing

/model sets the model for the current session (/model auto returns to automatic routing). To save a default across sessions, run /config set routing.pinned_model <id> or /config set routing.pinned_provider <provider>.

Use Left/Right in /model to adjust reasoning effort. /routing show and /routing status are aliases for /routing.

Pins do not block network access or disable provider fallback. See Local models — disconnected setup.

The rest of this page covers route files, which are advanced configuration. Route tests run in your shell; /routes is not a TUI command.

Add a route preference

Create a TOML file in your project’s .orek/routes/ directory. For example, .orek/routes/review.toml:

Configuration

[[routes]]
name = "review/audit"
description = "Code review, security auditing, and performance analysis"
sample_queries = [
    "Review this implementation for race conditions",
    "Audit this controller for security flaws",
    "Check the connection pool for performance bottlenecks"
]
tags = ["review", "audit", "security", "performance"]
provider_preference = ["google", "mistral"]
preferred_models = ["mistral/mistral-medium-3-5"]
complexity_bias = "high"
enabled = true

Replace the provider and model preferences with ones you have configured. sample_queries helps Orek match prompts by meaning; tags gives exact words to match.

preferred_models and provider_preference raise a model’s score; they do not exclude other models. To restrict routing to one provider, set routing.pinned_provider.

Check that your route loaded:

In your shell

orek routes list
orek routes test "audit this controller"

The list should include review/audit. The test should match its audit tag and show the route’s fields. This tests keyword matching only, not the model Orek would select for a real turn.

Check the actual decision

After a turn, open /routing to see the latest routing decision. Compare the selected model with your intended preference and confirm that its provider is configured.

orek routes test "<your query>" does not match by meaning, estimate complexity, or score models. The preferred_models it prints come from the matching route; they are not a predicted winner. A real turn can match a different route, because matching by meaning runs first when it is available.

For a detailed trace, set up OpenTelemetry export. When you set observe.otlp_endpoint, Orek exports these events with each turn:

Event What to inspect
model_pinned / pin_lookup_failed Whether the requested model pin resolved
route_classified Route name, confidence, and matching method
complexity_assessed Estimated task tier and score
candidates_scored Candidate quality, cost, latency, capability, and total scores
model_selected The model and provider Orek applied, and whether they changed
route_not_matched Why a routing decision could not be applied
model_segment_started A model taking over the conversation, at its first request: why (session_start, user, router, fallback or resume), the reasoning method in effect, the provider and model before and after, and why Claude’s earlier thinking stopped being sent, if it did
provider_request_recorded Each request a turn sent: its purpose (always main_turn), the reasoning method, how it ended, the earlier reasoning it resent, passed on from another model, filled with an empty value, or dropped (items and estimated tokens), its latency, and how many resent thinking blocks Anthropic left out, if any

Pin behavior

If Orek cannot resolve a pinned model or provider for the first turn, it does not start. During a running session, a routing failure keeps the current model and emits route_not_matched. The TUI shows a warning when you can fix the cause.

If a pin stops applying after a provider or catalog change, check the warning, /model list, and your provider configuration. A failed routing decision does not stop the turn.

Where routes come from

Orek loads routes from three layers. Later layers take precedence:

Layer Path
Built-in Routes bundled with Orek
User Linux: ~/.config/orek-ai/routes/*.toml; macOS: ~/Library/Application Support/orek-ai/routes/*.toml; Windows: %APPDATA%\orek-ai\config\routes\*.toml
Project <project>/.orek/routes/*.toml

A route with an existing name replaces that route in full. Omitted fields take their defaults; they do not inherit the earlier route’s values. For example, replacing simple/lookup without a complexity_bias removes the built-in bias.

Within a directory, .toml files load in sorted path order; other files are ignored. With OREK_HOME set, user route files go in <OREK_HOME>/config/routes/.

The [[routes]] schema

Each file contains one or more [[routes]] tables:

Field Type Default Purpose
name String Required Identifies the route for replacement, keyword matching, and diagnostics
description String Required Describes the task; used when matching by meaning
sample_queries Array of strings [] Example prompts added to the description when matching by meaning
preferred_models Array of selectors [] Ordered scoring preference for models
provider_preference String or array of strings [] Ordered scoring preference for providers
complexity_bias simple or low, medium, complex or high, reasoning Unset Adjusts estimated task complexity
quality_floor low, medium, high, frontier Unset Penalizes models below this quality tier
tags Array of strings [] Whole-word terms for keyword matching
enabled Boolean true Excludes the route when false

Unknown fields are ignored. Tier names are case-insensitive. An unknown complexity_bias or quality_floor value on an enabled route invalidates the file; on a disabled route, these values are not checked.

When a route file is malformed

A TOML syntax error, missing required field, or invalid tier value skips the entire file and logs a warning. Other valid route files still load.

After editing a file, confirm the expected route names and fields in orek routes list. The route count alone cannot show a failed override, because the route it meant to replace is still present.

If a route is missing, check its name, description, enabled value, and TOML syntax. Then look for the file’s parse error in the application log; see local diagnostics for log locations.

The decision pipeline

Without a model pin, routing follows these steps:

  1. Match the prompt to a route.
  2. Estimate the task’s complexity.
  3. Filter and score models from configured providers.
  4. Select the highest-scoring eligible model.

Steps 2 to 4 run however the route was matched. Routing selects a model; it does not change Plan mode, tool permissions, or approval requirements.

Route classification

Orek tries these methods in order:

  1. Matching by meaning: compare the prompt with each route’s description and sample queries, using a similarity threshold of 0.5.
  2. Keyword matching: use the first route whose name or tags match the prompt.
  3. Default route: use the built-in default route when neither method matches.

Matching by meaning uses the project index’s embeddings and runs only when Orek searches the index before the turn. It is skipped when there is no index, automatic retrieval is off, the prompt uses @!retrieve, or Orek treats the prompt as a short follow-up.

Keyword matching is case-insensitive and checks whole words, in route load order. test matches “write a test,” but not “latest.” A tag such as refactor does not match refactoring; include both when you want both forms:

Configuration

tags = ["refactor", "refactoring"]

Multi-word tags match as a whole phrase. Punctuation at a tag’s edge counts: /diff matches “run /diff” but not “/diffing.” Built-in routes have no tags, so keyword matching uses only their names.

The default route uses routing.default_preferred_models when set. Otherwise it combines the preferred_models of routes whose complexity_bias is not simple or low (or of all routes, if that gives none).

What the scorer does with those fields

The scorer considers each model’s quality, price, latency, and capabilities from the catalog. Models from unconfigured providers are never candidates.

A model is excluded when it is hidden in the catalog, is not meant for agent chat, cannot fit the estimated context, or lacks a capability the turn needs. Tools need supports_tools; images need supports_vision. Routes with a tag containing tools or code also need tool support.

Custom [[models]] entries default to supports_tools = false and are skipped on turns with tools unless you set supports_tools = true. If you pick a model without tool support yourself, it runs without tools, and Orek says so once per session.

Eligible models are ranked by combining their quality, cost, latency, and capability scores. The cost estimate uses the price tier for the estimated prompt length; recorded costs use the model that actually served the request and the tokens it reported (see Prompt-length pricing).

Preference Scoring effect
preferred_models Boosts models in the order you list them (earlier entries receive a larger boost)
provider_preference Boosts models from your preferred providers in listed order
quality_floor Penalizes models below the specified quality tier (low, medium, high, or frontier)

Use valid selectors and order your preferred models deliberately. Quality floors and preferences change rankings; they do not exclude models.

Complexity scoring

Orek estimates task complexity (Simple, Medium, Complex, or Reasoning) from your prompt, explicit references, conversation history, and gathered code context. Longer multi-step prompts, planning or refactoring requests, and larger context shift selection toward more capable models.

complexity_bias nudges that estimate down (simple/low) or up (complex/high or reasoning) for a route. It affects which model is selected, not how hard the model thinks; set routing.thinking_effort (or use /effort) for that.

[routing] keys

Key Default Effect
pinned_model Unset Selects a model without route scoring
pinned_provider Unset Limits automatic routing to one provider’s models
default_preferred_models Unset Supplies the default route’s model preferences
thinking_effort Unset auto, none, minimal, low, medium, high, xhigh, or max
temperature Unset Sent only when set; never sent to Anthropic or to a model that rejects it, and Orek reports this once per model
cascade_enabled false Lets the main conversation fall back to another provider after a temporary failure; subagents can fall back independently

Set routing.pinned_model, routing.pinned_provider, and routing.temperature with orek config set <key> <value> (or /config set in the TUI). Set default_preferred_models, thinking_effort, and cascade_enabled in config.toml, or use /effort for the session’s thinking effort. See Local models before enabling cascade_enabled with local providers.

Orek has no per-request cost cap. Older configurations that still contain budget_per_request or preferred_complexity load normally; those keys are ignored.