# `Sycophant.Credentials`

Three-layer credential resolution for LLM providers.

Credentials are resolved in order of specificity:

1. **Per-request** -- credentials passed directly in options
2. **Application config** -- from `config :sycophant, :providers`
3. **Environment variables** -- discovered via LLMDB provider metadata

The first non-empty layer wins. If all layers are empty, providers with
`extra: %{auth: :none}` or `extra: %{auth: :optional}` in their LLMDB
metadata receive an empty credential map, while all other providers raise
a `MissingCredentials` error.

## Examples

    # Per-request credentials take priority
    Sycophant.generate_text("openai:gpt-4o-mini", messages,
      credentials: %{api_key: "sk-override"}
    )

    # Falls back to app config, then env vars
    Sycophant.generate_text("openai:gpt-4o-mini", messages)

    # Local providers with auth: :none skip credentials entirely
    Sycophant.generate_text("ollama:llama3", messages)

# `resolve`

```elixir
@spec resolve(atom(), map() | nil) :: {:ok, map()} | {:error, Splode.Error.t()}
```

Resolves credentials for the given provider using a three-layer strategy.

Checks in order: (1) per-request credentials passed as `per_request_creds`,
(2) application config under `:sycophant, :providers`, (3) environment
variables discovered via LLMDB provider metadata. Returns the first non-empty
result. When all layers come up empty, returns an empty map for providers
with `auth: :none` or `auth: :optional` in LLMDB, or a `MissingCredentials`
error otherwise.

---

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