Smart Routing

Smart routing lets the server pick the best harness and model for a session automatically, based on the first message. Instead of committing to one model up front, the server asks a router, "given this task, which harness and model fit?", and applies the answer for the rest of the session.

Two routers are available:

Enable smart routing

Smart routing is enabled by configuration alone:

Start the server with your config file:

omni server -c path/to/config.yaml

With a router configured, users see an Auto option in the harness picker; picking it defers harness + model selection to the router on the first message. With neither an llm: block nor an external routing: block, routing stays off and the Auto option is hidden.

Configure the external routing API

To delegate routing to an external service, add a top-level routing: block to the server config with provider: external:

routing:
  provider: external
  base_url: https://gateway.example.com/ai-gateway/routing/v1
  router_name: task_v0
  # Optional: strip a prefix from catalog model ids before sending them to
  # the router (and restore it on the answer). Accepts a string or a list.
  model_prefix: databricks-
  # Optional auth, see "Authentication" below.
  api_key: ${ROUTING_API_KEY}
FieldRequiredDescription
provideryesMust be external to select the external routing API. Any other value (or omitting the block) falls back to the built-in judge.
base_urlyesBase URL of the routing service. The server appends /routes:select to it.
router_nameyesThe routing strategy the gateway should apply, e.g. task_v0. Sent as route_selector.router_name.
model_prefixnoA prefix (or list of prefixes) stripped from catalog model ids before they are sent to the router, and restored on its answer. Example: databricks-.
api_keynoStatic bearer token. ${ENV} references are expanded. Takes precedence over profile.
profilenoDatabricks CLI profile. The server mints a fresh bearer per call (OAuth refresh), so a long-lived server never sends an expired token.

If base_url or router_name is missing, the external provider is skipped and a warning is logged: routing stays off rather than failing the server.

Authentication

Auth mirrors the llm: block, in precedence order:

  1. api_key: an explicit, provider-agnostic bearer token (${ENV} expanded). Sent as Authorization: Bearer <token>.
  2. profile: a Databricks CLI profile. The server resolves a fresh token per request via the Databricks SDK, so tokens that expire (~1h) are refreshed automatically.
  3. Neither: requests are sent unauthenticated.

External routing API spec

The server calls a single endpoint:

POST <base_url>/routes:select
Content-Type: application/json

The request and response bodies follow the omnigent.api.routing.v1 schema (proto3, serialized as JSON with snake_case field names). This schema is versioned independently of any gateway so the contract can evolve without coupling to a gateway's release cycle.

Request: SelectRouteRequest

FieldTypeDescription
route_optionsRouteOption[]Candidate destinations the router may choose from. One entry per (model, harness) pair.
taskTaskThe unit of work to route. Carries the user's prompt (truncated to 4000 chars).
route_selectorRouteSelectorThe routing strategy to apply. Required in practice; a gateway rejects a request that omits it.
session_historySessionHistoryPrior turns in the session, when available. Routers may use it to keep turns consistent.

RouteOption

FieldTypeDescription
modelstringModel id to serve the request, e.g. gpt-5-5.
harnessstringHarness that drives the model. May be omitted for a native harness; required for a meta-harness.

RouteSelector

FieldTypeDescription
router_namestringName of the routing strategy to invoke (from the router_name config field).
configStructOptional router-specific configuration, interpreted by the selected router (gateway-defined).

Example request body:

{
  "route_options": [
    { "model": "claude-opus-4-8", "harness": "claude-sdk" },
    { "model": "gpt-5-5", "harness": "codex" },
    { "model": "gpt-5-4-mini", "harness": "pi" }
  ],
  "task": { "prompt": "Refactor the auth module and add tests" },
  "route_selector": { "router_name": "task_v0" }
}

Response: SelectRouteResponse

FieldTypeDescription
route_selectionRouteSelection[]The routing decision(s). The server uses the first entry.
rationalestringHuman-readable explanation of why this route was selected.

RouteSelection

FieldTypeDescription
route_optionRouteOptionThe chosen destination (model + harness).
paramsStructOptional router-specific parameters emitted alongside the decision.

Example response body:

{
  "route_selection": [
    {
      "route_option": { "model": "claude-opus-4-8", "harness": "claude-sdk" }
    }
  ],
  "rationale": "Multi-file refactor with tests: favor the most capable model."
}

The server maps the chosen model (and harness, when present) back to the matching catalog entry, restoring any stripped model_prefix. A model the server did not offer in route_options is rejected, and the session falls back to its default harness. On any error (HTTP 4xx/5xx, unparseable body, empty selection) the server surfaces the reason and degrades gracefully rather than blocking the session.