# `MingaAgent.ModelResolver`
[🔗](https://github.com/jsmestad/minga/blob/main/lib/minga_agent/model_resolver.ex#L1)

Resolves boundary input into one exact executable `ModelSelection`.

Catalog lookup happens only at selection and restore boundaries.
Restore validates the persisted exact route against its current source-owned declaration and never substitutes another route.

# `context`

```elixir
@type context() :: %{
  spec: MingaAgent.Provider.Spec.t(),
  config: MingaAgent.Config.t(),
  snapshot: MingaAgent.Credentials.Snapshot.t(),
  opts: keyword()
}
```

# `intent`

```elixir
@type intent() ::
  String.t()
  | map()
  | MingaAgent.ModelSelection.t()
  | MingaAgent.ModelSelection.Stored.t()
  | nil
```

# `resolution_error`

```elixir
@type resolution_error() ::
  :no_available_model
  | {:invalid_model_selection, String.t()}
  | {:model_not_found, String.t()}
  | {:backend_unavailable, String.t()}
  | {:credential_unavailable, String.t()}
  | {:route_unavailable, String.t()}
  | {:incompatible_selection, String.t()}
  | {:selection_correction_required, String.t()}
```

# `source`

```elixir
@type source() :: {:catalog, map()}
```

# `candidates`

```elixir
@spec candidates(keyword()) :: [MingaAgent.ModelCandidate.t()]
```

Lists exact credential-backed executable routes suitable for the picker.

# `message`

```elixir
@spec message(resolution_error() | term()) :: String.t()
```

Formats an actionable, secret-free resolution error.

# `resolve`

```elixir
@spec resolve(intent(), keyword()) ::
  {:ok, MingaAgent.ModelSelection.t()} | {:error, resolution_error()}
```

Resolves raw config, picker, command, or migration input to one exact selection.

# `restore`

```elixir
@spec restore(
  map() | MingaAgent.ModelSelection.Stored.t() | MingaAgent.ModelSelection.t(),
  keyword()
) ::
  {:ok, MingaAgent.ModelSelection.t()} | {:error, resolution_error()}
```

Validates persisted exact route data against its source without route substitution.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
