
# AI Eco Routing

Sovrium treats environmental footprint as a first-class platform property. AI inference is one of the most resource-intensive operations a platform can perform, so Sovrium routes AI calls **local-first by default**: when a local model (Ollama) is reachable, it answers; only when it is not does the call fall back to a configured cloud provider.

This is controlled by a single operator env var — `ECO_AI_PROVIDER_PRECEDENCE` — never by the app schema. Like every `ECO_*` variable, its default is the eco-aligned setting; operators opt _out_, never in.

```bash
ECO_AI_PROVIDER_PRECEDENCE=local-first   # the default — usually omit it entirely
AI_PROVIDER=anthropic                    # cloud fallback target
ANTHROPIC_API_KEY=sk-ant-...
OLLAMA_BASE_URL=http://localhost:11434   # local provider endpoint
```

## Precedence Modes

| Value         | Behavior                                                                                                                       |
| ------------- | ------------------------------------------------------------------------------------------------------------------------------ |
| `local-first` | **(default)** Prefer a reachable local Ollama; fall back to the configured cloud `AI_PROVIDER` when Ollama is unreachable.     |
| `cloud-first` | Use the configured cloud provider; use a reachable Ollama only when no cloud provider is configured.                           |
| `local-only`  | Use a local provider exclusively. AI calls have no cloud fallback — when no reachable Ollama is configured, AI is unavailable. |

An unset, empty, or unrecognized value resolves to the eco-aligned default, `local-first`.

## How Routing Resolves

The resolver combines three inputs: the active precedence, whether an Ollama endpoint is **configured** (via `OLLAMA_BASE_URL`, or `AI_BASE_URL` when `AI_PROVIDER=ollama`), and whether the runtime's reachability probe found Ollama **usable** (configured _and_ responding).

| Precedence    | Ollama usable | Cloud configured | Routes to     | Notes                                                                       |
| ------------- | ------------- | ---------------- | ------------- | --------------------------------------------------------------------------- |
| `local-first` | yes           | —                | Ollama        | Preferred local path.                                                       |
| `local-first` | no            | yes              | cloud         | Fallback. Flagged with a reason when Ollama was configured but unreachable. |
| `local-first` | no            | no               | Ollama / none | Disabled when no provider is configured at all.                             |
| `cloud-first` | —             | yes              | cloud         | Cloud always wins when configured.                                          |
| `cloud-first` | yes           | no               | Ollama        | Local used only because no cloud is configured.                             |
| `local-only`  | yes           | —                | Ollama        | Local exclusively.                                                          |
| `local-only`  | no            | —                | none          | No fallback — AI unavailable until a reachable Ollama exists.               |

:::callout
**Reachability is probed, not assumed.** The runtime checks whether the configured Ollama endpoint actually responds before routing to it. Under `local-first`, when Ollama is _configured but unreachable_, the fallback to cloud is recorded with an operator-facing reason; when Ollama was never configured, the fallback happens silently.
:::

## Observability

The active eco-routing decision is surfaced on the health endpoint (`GET /api/health`, under `body.ai`):

| Field              | Meaning                                                                            |
| ------------------ | ---------------------------------------------------------------------------------- |
| `precedence`       | The active `ECO_AI_PROVIDER_PRECEDENCE` value.                                     |
| `resolvedProvider` | The canonical provider AI calls are routed to (or absent when AI is disabled).     |
| `ollamaReachable`  | Whether the local Ollama probe succeeded.                                          |
| `configured`       | The raw `AI_PROVIDER` value.                                                       |
| `fallbackReason`   | Why the resolver fell back to a non-preferred provider (present only on fallback). |

This makes routing auditable: operators can confirm whether a deployment is actually running on its local model or quietly burning cloud tokens.

## Configuration Examples

```bash
# Frugal default: local Ollama with an Anthropic safety net.
# (ECO_AI_PROVIDER_PRECEDENCE=local-first is the default — shown for clarity.)
ECO_AI_PROVIDER_PRECEDENCE=local-first
AI_PROVIDER=anthropic
ANTHROPIC_API_KEY=sk-ant-...
OLLAMA_BASE_URL=http://localhost:11434
AI_MODEL=claude-sonnet-4-5
```

```bash
# Strict local-only deployment — no data ever leaves the host.
ECO_AI_PROVIDER_PRECEDENCE=local-only
AI_PROVIDER=ollama
AI_BASE_URL=http://localhost:11434
AI_MODEL=llama3.1
```

```bash
# Quality-first: always use the cloud provider.
ECO_AI_PROVIDER_PRECEDENCE=cloud-first
AI_PROVIDER=openai
OPENAI_API_KEY=...
AI_MODEL=gpt-4o
```

## Related Pages

- [AI Providers](/en/docs/ai-providers) — provider, key, and base-URL configuration.
- [AI Overview](/en/docs/ai-overview) — the AI ecosystem and configuration philosophy.
- [Environment Variables](/en/docs/env-vars) — complete `ECO_*` and `AI_*` reference.
