# Where Is the AI Provider Model Routing Table in career-ops?

> Find the AI provider model routing table in santifer/career-ops within opencode.json. Discover default model, provider priority, and fallback policies for runtime.

- Repository: [Santiago Fernández de Valderrama/career-ops](https://github.com/santifer/career-ops)
- Tags: internals
- Published: 2026-08-28

---

**The AI provider model routing table in career-ops is located in the [[`opencode.json`](https://github.com/santifer/career-ops/blob/main/opencode.json)](https://github.com/santifer/career-ops/blob/main/opencode.json) configuration file, which defines the default model, provider priority order, and fallback policies consumed by the runtime.**

The **career-ops** repository manages AI provider interactions through a declarative configuration system. Understanding the location and structure of the **AI provider model routing table** is essential for customizing model selection, provider priority, and fallback behavior without modifying core source code. This routing configuration resides in a static JSON asset that the pipeline runner evaluates during command execution.

## The Routing Table Configuration File

The primary source of truth for model routing is [[`opencode.json`](https://github.com/santifer/career-ops/blob/main/opencode.json)](https://github.com/santifer/career-ops/blob/main/opencode.json). This file declares the default model and maps individual models to ordered provider lists with fallback permissions.

### Default Model and Provider Order

The configuration structure separates concerns between the global default and provider-specific routing:

```json
{
  "model": "openrouter/openai/gpt-oss-120b",
  "provider": {
    "openrouter": {
      "models": {
        "openai/gpt-oss-120b": {
          "options": {
            "provider": {
              "order": ["fireworks", "cerebras"],
              "allow_fallbacks": true
            }
          }
        },
        "qwen/qwen3-32b": {
          "options": {
            "provider": {
              "order": ["sambanova", "groq"],
              "allow_fallbacks": true
            }
          }
        }
      }
    }
  }
}

```

In this structure, the `provider.openrouter.models` object contains the **routing table keys**. Each model identifier maps to an `options.provider` object specifying the `order` array and the `allow_fallbacks` boolean.

## Runtime Implementation in the Runner

While [[`opencode.json`](https://github.com/santifer/career-ops/blob/main/opencode.json)](https://github.com/santifer/career-ops/blob/main/opencode.json) stores the static routing rules, the execution logic resides in [`openrouter-runner.mjs`](https://github.com/santifer/career-ops/blob/main/openrouter-runner.mjs). This module parses the JSON configuration at runtime to construct the request pipeline.

When the CLI initializes, the runner performs the following resolution steps:

1. Loads the routing table from [[`opencode.json`](https://github.com/santifer/career-ops/blob/main/opencode.json)](https://github.com/santifer/career-ops/blob/main/opencode.json).
2. Resolves the target model from the `--model` flag or falls back to the default specified in the `model` property.
3. Retrieves the provider `order` array for the resolved model.
4. Iterates through the ordered providers, attempting the request with each until one succeeds or `allow_fallbacks` is exhausted.

The separation of concerns allows the routing logic to remain generic while the JSON file controls policy.

## CLI Integration and Usage Examples

Command-line tools like [`rank-pipeline.mjs`](https://github.com/santifer/career-ops/blob/main/rank-pipeline.mjs) consume the routing table when executing AI-driven tasks. The CLI forwards model selections to the runner, which applies the provider ordering defined in the configuration.

### Executing with Default Routing

```bash
node rank-pipeline.mjs --cli codex

```

This invocation loads the default model `openrouter/openai/gpt-oss-120b` and attempts providers in the sequence `fireworks` → `cerebras` as specified in the routing table.

### Overriding Models via Command Line

```bash
node rank-pipeline.mjs --cli codex --model qwen/qwen3-32b

```

Although this bypasses the default model setting, the runner still consults the routing table to apply the provider order `sambanova` → `groq` defined for `qwen/qwen3-32b`.

### Extending the Routing Table

To modify routing behavior, edit the `models` object in [[`opencode.json`](https://github.com/santifer/career-ops/blob/main/opencode.json)](https://github.com/santifer/career-ops/blob/main/opencode.json):

```json
{
  "provider": {
    "openrouter": {
      "models": {
        "anthropic/claude-3.5-sonnet": {
          "options": {
            "provider": {
              "order": ["anthropic", "openai"],
              "allow_fallbacks": true
            }
          }
        }
      }
    }
  }
}

```

After saving, any request targeting `anthropic/claude-3.5-sonnet` will prioritize the `anthropic` provider before falling back to `openai`.

## Supporting Type Definitions

The provider contract utilized by the runner is defined in [[`providers/_types.js`](https://github.com/santifer/career-ops/blob/main/providers/_types.js)](https://github.com/santifer/career-ops/blob/main/providers/_types.js). While this file establishes the interface for provider implementations, it does not contain the routing table itself. The routing configuration in [[`opencode.json`](https://github.com/santifer/career-ops/blob/main/opencode.json)](https://github.com/santifer/career-ops/blob/main/opencode.json) drives the runtime selection logic, while [`_types.js`](https://github.com/santifer/career-ops/blob/main/_types.js) ensures type safety for the underlying provider modules.

## Summary

- The **AI provider model routing table** is stored in [[`opencode.json`](https://github.com/santifer/career-ops/blob/main/opencode.json)](https://github.com/santifer/career-ops/blob/main/opencode.json), which defines default models and provider priority orders.
- The [`openrouter-runner.mjs`](https://github.com/santifer/career-ops/blob/main/openrouter-runner.mjs) module reads this configuration at runtime to determine provider selection and fallback sequences.
- Command-line interfaces like [`rank-pipeline.mjs`](https://github.com/santifer/career-ops/blob/main/rank-pipeline.mjs) pass model selections to the runner, which applies the routing rules without requiring code changes.
- Routing behavior is customizable by editing the JSON structure, allowing dynamic reconfiguration of provider priorities and fallback policies.

## Frequently Asked Questions

### Where exactly is the AI provider model routing table stored in the career-ops repository?

The routing table is stored in the repository root as [[`opencode.json`](https://github.com/santifer/career-ops/blob/main/opencode.json)](https://github.com/santifer/career-ops/blob/main/opencode.json). This JSON file contains the complete mapping of AI models to their ordered provider lists and fallback settings, serving as the single source of truth for model routing decisions.

### How does career-ops determine which provider to use when multiple options exist?

The system consults the `order` array within the specific model's configuration in [[`opencode.json`](https://github.com/santifer/career-ops/blob/main/opencode.json)](https://github.com/santifer/career-ops/blob/main/opencode.json). The [`openrouter-runner.mjs`](https://github.com/santifer/career-ops/blob/main/openrouter-runner.mjs) iterates through this array sequentially, attempting the request with each provider until successful, provided `allow_fallbacks` remains enabled.

### Can I override the routing table defaults without modifying the opencode.json file?

Yes. You can bypass the default model specified in [[`opencode.json`](https://github.com/santifer/career-ops/blob/main/opencode.json)](https://github.com/santifer/career-ops/blob/main/opencode.json) by passing the `--model` flag to CLI commands like [`rank-pipeline.mjs`](https://github.com/santifer/career-ops/blob/main/rank-pipeline.mjs). However, the provider ordering for the specified model will still be resolved from the routing table unless the runner implementation is modified.

### What happens if the primary provider in the routing table is unavailable?

If the `allow_fallbacks` property is set to `true` for the model configuration in [[`opencode.json`](https://github.com/santifer/career-ops/blob/main/opencode.json)](https://github.com/santifer/career-ops/blob/main/opencode.json), the [`openrouter-runner.mjs`](https://github.com/santifer/career-ops/blob/main/openrouter-runner.mjs) will automatically proceed to the next provider in the `order` array. If fallbacks are disabled or all providers fail, the request will error out.