Configuration

Choosing a model

How OpenRouter routing works, when to split indexing and review models, and which models Mira recognizes.

Mira can reach an LLM four ways:

  • OpenRouter (default) — one OPENROUTER_API_KEY covers Anthropic, OpenAI, Google, DeepSeek, and others. You pay your provider directly with no Mira markup.
  • Any OpenAI-compatible endpoint — point llm.base_url at a self-hosted or alternative server: Ollama, vLLM, LiteLLM proxy, LocalAI, llama.cpp, Together, Fireworks, Groq, Cerebras, etc. See Custom endpoints.
  • AWS Bedrock — llm.provider: "bedrock" talks to Bedrock's Converse API directly, using the standard AWS credential chain. Good for teams with data-residency rules or existing AWS billing.
  • Codex CLI — llm.provider: "codex-cli" uses an existing OpenAI Codex login instead of an HTTP API key. Mira isolates every invocation in a temporary home and read-only sandbox.

The rest of this page uses OpenRouter-style provider/model strings, but the indexing/review split and fallback chain work the same whichever backend you pick.

How MIRA_MODEL resolves

.mira.yaml llm.model        ← per-repo override (highest priority)
   └── env MIRA_MODEL      ← deployment-wide default
       └── built-in        ← anthropic/claude-sonnet-4-6

The string is whatever the OpenRouter Models page lists in the format provider/model-id.

Use caseMIRA_MODELNotes
Default (balanced)anthropic/claude-sonnet-4-6What Mira ships with.
Fastest reviewsanthropic/claude-haiku-4-5Cheaper and faster. Good for low-stakes repos.
Highest qualityanthropic/claude-opus-4-8Strongest review, most expensive.
OpenAI shopopenai/gpt-5.1-codexCode-tuned. Or openai/gpt-5.1-codex-mini for cheap.
Google shopgoogle/gemini-3.1-pro-previewOr google/gemini-3-flash-preview for cheap.

Set it once via env var:

export MIRA_MODEL=anthropic/claude-sonnet-4-6

…or per repo in .mira.yaml:

llm:
  model: "openai/gpt-5.2"

Splitting indexing and review

Indexing reads every file in your repo to build summaries, so it benefits from a cheap, fast model. Review reasons over diffs and project context, so it benefits from a stronger model. The focused security pass can use its own high-trust model. You can split all three tiers:

llm:
  indexing_model: "anthropic/claude-haiku-4-5"
  review_model: "anthropic/claude-sonnet-4-6"
  security_model: "anthropic/claude-sonnet-4-6"

If security_model is unset it falls back to review_model, then model. It never silently falls back to the cheaper indexing_model.

The dashboard's Settings page exposes the same split via searchable model pickers. They list your backend's live catalog (OpenRouter, Bedrock, or any OpenAI-compatible endpoint), accept any free-form model id, and offer an Inherit from deployment config choice that defers to mira.yaml. Mira logs the effective model and where it came from (dashboard setting vs mira.yaml) on every review, so an override is never silent.

Review thinking mode

Reviews can run with an extended-reasoning budget so a model spends more effort before commenting — useful for pairing a cheaper model with deeper analysis. Set it in mira.yaml or via the Review Thinking Mode dropdown on the Settings page:

llm:
  review_reasoning_effort: "high"   # off | low | medium | high | xhigh | max

It applies to reviews only (never indexing) and defaults to off.

Provider support. Thinking mode is sent as OpenRouter's unified reasoning.effort, so it works out of the box on OpenRouter (DeepSeek, Claude, and OpenAI reasoning models) and on Bedrock for Claude (mapped to a thinking-token budget). xhigh can be selected directly; provider profiles may also remap levels where an API uses different names (for example, mapping max to xhigh). On models or endpoints that don't support a reasoning effort, Mira drops it and reviews normally rather than failing, so turning it on is safe.

Fallback chain

If the primary model errors (rate limit, transient outage), Mira retries with fallback_model:

llm:
  model: "anthropic/claude-sonnet-4-6"
  fallback_model: "anthropic/claude-haiku-4-5"

The fallback applies to both indexing and review.

AWS Bedrock

To run reviews against models on Amazon Bedrock instead of an OpenAI-compatible endpoint, set llm.provider: "bedrock". Mira talks to Bedrock through the Converse API; model and fallback_model are Bedrock model IDs rather than OpenRouter provider/model strings.

llm:
  provider: "bedrock"
  model: "us.anthropic.claude-sonnet-4-6-v1:0"
  fallback_model: "us.anthropic.claude-haiku-4-5-v1:0"
  region: "us-east-1"
  # aws_profile: "my-profile"   # optional — see auth below

Authentication uses the standard AWS credential chain — no Mira-specific keys. Mira picks up whatever boto3 finds: environment variables (AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY / AWS_SESSION_TOKEN), an EC2 instance profile, an ECS task role, or SSO. Set aws_profile to pin a named profile from ~/.aws/credentials; omit it to use the default chain.

indexing_model / review_model splitting and the fallback_model chain work the same as with OpenRouter. The model must be enabled in your account for the configured region, and you'll need the boto3 dependency available in the runtime.

On Bedrock, the dashboard's model pickers list your account's inference profiles and on-demand foundation models for the configured region — only ids your deployment can actually serve.

Codex CLI

If the deployment already has an OpenAI Codex login, Mira can run its model calls through the Codex CLI instead of an HTTP API key. Authenticate once with codex login, then use an operator-owned deployment config:

# mira.yaml
llm:
  provider: "codex-cli"
  model: "codex-default"      # keep the Codex CLI default model
  codex_home: "/run/codex"    # optional; defaults to CODEX_HOME
  codex_sandbox: "read-only"   # the only accepted sandbox policy
  codex_timeout_seconds: 900

The official Mira image includes a pinned Codex CLI. Mount the login read-only:

docker run -p 8000:8000 --env-file .env \
  -e CODEX_HOME=/run/codex \
  -v "$HOME/.codex:/run/codex:ro" \
  -v "$(pwd)/mira.yaml:/app/mira.yaml:ro" \
  ghcr.io/miracodeai/mira:latest --config /app/mira.yaml

Mira copies only auth.json into a private, writable temporary Codex home for each invocation. Codex runs in an empty temporary workspace with a minimal environment, inherited shell variables and user/project rules disabled, and a read-only sandbox. No OPENROUTER_API_KEY is required.

provider, the Codex executable and auth paths, sandbox policy, and timeout are deployment-only settings. Repository .mira.yaml files cannot override them. For one-shot mira review runs, only use --trust-execution-settings with an operator-owned config, never a repository-controlled file. Treat the mounted OAuth session as a sensitive deployment credential and prefer a dedicated Codex account/session.

Codex CLI does not expose Mira's temperature or hard output-token controls, so Mira disables ensemble sampling for this provider. It also does not expose Mira's interactive tool-calling loop; cross-file context still comes from the normal index and JIT context collection.

Model catalog

The dashboard's model pickers list your backend's live catalog: OpenRouter's tool-capable models, your Bedrock account's inference profiles, or a generic endpoint's /models listing (refreshed hourly; if the fetch fails, Mira falls back to its bundled registry). Any free-form id can also be typed directly — the same flexibility as .mira.yaml.

The bundled registry at src/mira/llm/models.json supplies labels, per-purpose recommendations, and the pricing used in cost estimates. Models outside it work normally but show default pricing in estimates and no "Recommended" badge. Highlights:

ModelProviderInput ctxOutputIndexingReview
anthropic/claude-haiku-4-5Anthropic200k64k✅ recommended✅
anthropic/claude-sonnet-4-6Anthropic200k64k—✅ recommended
anthropic/claude-sonnet-5Anthropic1M128k—✅
anthropic/claude-opus-4-8Anthropic1M128k—✅
anthropic/claude-fable-5Anthropic1M128k—✅
openai/gpt-5-nanoOpenAI400k128k✅—
openai/gpt-5-miniOpenAI400k128k✅✅
openai/gpt-5.1-codex-miniOpenAI400k100k✅✅
openai/gpt-5.1-codexOpenAI400k128k—✅
openai/gpt-5.2OpenAI400k128k—✅
google/gemini-3-flash-previewGoogle1M65k✅✅
google/gemini-3.1-flash-liteGoogle1M65k✅—
google/gemini-3.1-pro-previewGoogle1M65k—✅
deepseek/deepseek-v4-flashDeepSeek1M16k✅—
deepseek/deepseek-v4-proDeepSeek1M384k—✅
minimax/minimax-m3MiniMax1M512k✅✅

Custom pricing and recommendations

To give a custom model accurate cost estimates, a label, or a Recommended badge — e.g. DeepSeek or a local endpoint — point MIRA_MODELS_JSON_PATH at your own models.json (a volume mount works well). Its entries are merged over the bundled ones by model id, so you only list what you want to add or override:

MIRA_MODELS_JSON_PATH=/config/models.json
// /config/models.json — copy an entry from the bundled file as a template
{
  "deepseek/deepseek-chat": {
    "label": "DeepSeek Chat",
    "provider": "openai",
    "max_input_tokens": 64000,
    "max_output_tokens": 8000,
    "input_cost_per_1m": 0.27,
    "output_cost_per_1m": 1.10,
    "supports_json_mode": true,
    "purposes": ["indexing", "review"]
  }
}

The file is read at startup; a missing or invalid file falls back to the bundled registry with a warning.

Cost expectations

Order-of-magnitude figures for a medium-sized repo (~50k LOC, ~50 PRs/month):

  • Indexing (one-time per repo, plus incremental on push): a few cents to a few dollars depending on repo size and model.
  • Review (per PR): typically $0.05–$0.50 per PR with a Sonnet/GPT-4o-class model on a small-to-medium diff. Big diffs scale roughly linearly.

The dashboard's Stats page tracks token usage and estimated spend per repo once you've run a few reviews.

On this page