# How the OmniRoute 12-Factor Auto-Combo System Selects Targets with Task-Aware Routing

> Discover how OmniRoute's 12-factor auto-combo system selects targets using task-aware routing. Learn about mapping, scoring, and optimal routing for model providers.

- Repository: [Diego Rodrigues de Sa e Souza/OmniRoute](https://github.com/diegosouzapw/OmniRoute)
- Tags: architecture
- Published: 2026-07-30

---

**The OmniRoute 12-factor auto-combo system routes requests to optimal model providers by detecting the task type from message content, mapping it to a capability placeholder via `DEFAULT_TASK_MODEL_MAP`, and scoring available candidates based on quota, latency, cost, and health metrics.**

OmniRoute’s intelligent routing engine—internally codenamed **I²-Factor**—automates model selection through a **task-aware routing** layer that intercepts incoming chat requests. According to the diegosouzapw/OmniRoute source code, this system eliminates manual model selection by analyzing semantic intent and matching it against real-time provider performance data to select the best backend target.

## The Three-Stage Selection Pipeline

The 12-factor auto-combo engine chains three distinct phases to resolve every request. The implementation spans [`open-sse/services/taskAwareRouter.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/services/taskAwareRouter.ts) for detection logic and [`src/sse/handlers/chat.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/sse/handlers/chat.ts) for pipeline integration.

### Stage 1: Task Detection

The `detectTaskType` function in [`open-sse/services/taskAwareRouter.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/services/taskAwareRouter.ts) infers semantic intent by scanning the request body for specific patterns:

- **Vision cues** – Any message containing `image_url` or `image` parts triggers immediate classification as `"vision"`.
- **System-prompt patterns** – Predefined strings in system messages (e.g., “write code”, “summarize”) map to `coding` or `summarization`.
- **User-message patterns** – Code fences, SQL keywords, or analytical phrasing detected in user content.

The detection follows a hardcoded precedence order—**background → coding → vision → summarization → analysis → creative**—ensuring the most specific intent wins. If no patterns match, the function returns `"chat"` and routing is bypassed.

### Stage 2: Task-to-Model Mapping

Once detected, the task maps to a placeholder string via `DEFAULT_TASK_MODEL_MAP`:

```typescript
const DEFAULT_TASK_MODEL_MAP: Record<TaskType, string> = {
  coding: "auto/coding",
  creative: "",
  analysis: "auto/reasoning",
  vision: "auto/vision",
  summarization: "auto/chat:fast",
  background: "auto/chat:cheap",
  chat: "",
};

```

An empty string disables routing for that task, preserving the user-specified model. Operators can override this map at runtime via the **Task-Routing Settings API** (`PUT /api/settings/task-routing`), which persists configuration to the global object `__omniroute_taskRouting_config__` and is accessed through `getTaskRoutingConfig()`.

When enabled (`config.enabled === true`), the chat handler calls `applyTaskAwareRouting(modelStr, body)`, which returns `{ model: placeholder, taskType, wasRouted: true }` if a placeholder exists.

### Stage 3: Auto-Combo Scoring

The placeholder (e.g., `"auto/coding"`) feeds into the auto-combo resolver in [`src/sse/handlers/chat.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/sse/handlers/chat.ts):

```typescript
const combo = await getComboForModel(resolvedModelStr);

```

The scoring logic, implemented in [`open-sse/services/combo/autoStrategy.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/services/combo/autoStrategy.ts), evaluates **all** connected providers capable of fulfilling the placeholder’s requirements. The scorer weights candidates using:

- **Quota soft-penalty** – Deprioritizes providers with exhausted rate limits.
- **Latency/cost blending** – Honors suffixes like `:fast` (latency-optimized) or `:cheap` (cost-optimized).
- **Health and circuit-breaker status** – Filters out unhealthy connections before scoring.

The highest-scoring candidate becomes the concrete target for the request.

## Configuring Task-Aware Routing

Enable and customize routing by posting to the settings endpoint:

```json
// PUT /api/settings/task-routing
{
  "enabled": true,
  "taskModelMap": {
    "coding": "auto/coding",
    "analysis": "auto/reasoning",
    "vision": "auto/vision",
    "summarization": "auto/chat:fast",
    "background": "auto/chat:cheap"
  },
  "detectionEnabled": true
}

```

To disable routing for specific tasks—forcing the system to respect the user’s original model selection—set the task value to an empty string in the map.

## Monitoring Routing Decisions

Each detection and routing action increments counters on the global configuration object:

- `config.stats.detected` – Tracks how often task patterns are identified.
- `config.stats.routed` – Tracks successful overrides to auto-combo placeholders.

These metrics provide observability into how frequently the 12-factor system intervenes in request routing.

## Example: Routing a Coding Request

Consider a request sent to `/api/v1/chat/completions`:

```json
{
  "model": "openai/gpt-4o",
  "messages": [
    { "role": "user", "content": "Write a function that sorts an array in JavaScript." }
  ]
}

```

1. `detectTaskType` matches the JavaScript reference and code intent, returning `"coding"`.
2. `applyTaskAwareRouting` replaces `"openai/gpt-4o"` with `"auto/coding"`.
3. The auto-combo scorer evaluates available coding-capable models (e.g., `openai/gpt-4o-mini`, `anthropic/claude-3.5-sonnet`) and selects the optimal candidate based on current quota and latency data.

## Summary

- The **12-factor auto-combo system** automates target selection through detection, mapping, and scoring phases implemented in [`taskAwareRouter.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/taskAwareRouter.ts) and [`chat.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/chat.ts).
- **Task detection** prioritizes vision content, then coding patterns, then analytical language, defaulting to `"chat"` if ambiguous.
- **Model mapping** uses `DEFAULT_TASK_MODEL_MAP` to translate tasks into capability placeholders like `auto/coding` or `auto/chat:fast`.
- **Runtime configuration** allows operators to override mappings via `PUT /api/settings/task-routing` and inspect routing frequency through `config.stats`.
- **Scoring logic** balances quota availability, latency preferences, cost constraints, and health checks to pick the best provider.

## Frequently Asked Questions

### How does OmniRoute detect the task type for routing?

OmniRoute scans request messages for vision content (images), system-prompt keywords, and user-message patterns like code fences or SQL syntax. The `detectTaskType` function in [`open-sse/services/taskAwareRouter.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/services/taskAwareRouter.ts) evaluates these cues in a fixed order—background, coding, vision, summarization, analysis, creative—to determine the most specific intent.

### Can I disable task-aware routing for specific workloads?

Yes. Set the task’s value to an empty string in `DEFAULT_TASK_MODEL_MAP` or via the `PUT /api/settings/task-routing` API. For example, setting `"creative": ""` forces creative requests to use the user-specified model rather than auto-routing.

### What happens if no task patterns match the request?

If `detectTaskType` finds no matching cues, it returns `"chat"` and the system bypasses task-aware routing. The original model specified in the request is preserved and sent directly to the auto-combo scorer without task-specific overrides.

### Where is the routing statistics data stored?

Statistics are stored on the global configuration object `__omniroute_taskRouting_config__`, specifically under `config.stats.detected` and `config.stats.routed`. These counters increment each time a task is identified and each time a routing override is applied, respectively.