# `LLMDB.Query`
[🔗](https://github.com/agentjido/llm_db/blob/main/lib/llm_db/query.ex#L1)

Query functions for selecting models based on capabilities and requirements.

Provides capability-based model selection with provider preferences.
All queries operate on the filtered catalog loaded into the Store.

# `model_id`

```elixir
@type model_id() :: String.t()
```

# `model_spec`

```elixir
@type model_spec() :: {provider(), model_id()} | String.t() | LLMDB.Model.t()
```

# `provider`

```elixir
@type provider() :: atom()
```

# `candidates`

```elixir
@spec candidates(keyword()) :: [{provider(), model_id()}]
```

Gets all allowed models matching capability requirements.

Returns all models that match the capability filters in preference order.
Similar to `select/1` but returns all matches instead of just the first.

## Options

- `:require` - Keyword list of required capabilities (e.g., `[tools: true, json_native: true]`)
- `:forbid` - Keyword list of forbidden capabilities
- `:prefer` - List of provider atoms in preference order (e.g., `[:openai, :anthropic]`)
- `:scope` - Either `:all` (default) or a specific provider atom

## Returns

List of `{provider, model_id}` tuples matching the criteria, in preference order.

## Examples

    candidates = Query.candidates(
      require: [chat: true, tools: true],
      prefer: [:openai, :anthropic]
    )
    #=> [{:openai, "gpt-4o"}, {:openai, "gpt-4o-mini"}, {:anthropic, "claude-3-5-sonnet-20241022"}, ...]

    candidates = Query.candidates(
      require: [json_native: true],
      scope: :openai
    )
    #=> [{:openai, "gpt-4o"}, {:openai, "gpt-4o-mini"}, ...]

# `capabilities`

```elixir
@spec capabilities(model_spec()) :: map() | nil
```

Gets capabilities for a model spec.

Returns capabilities map or nil if model not found.

## Parameters

- `spec` - Either `{provider, model_id}` tuple, `"provider:model"` string, or `%Model{}` struct

## Examples

    caps = Query.capabilities({:openai, "gpt-4o-mini"})
    #=> %{chat: true, tools: %{enabled: true, ...}, ...}

    caps = Query.capabilities("openai:gpt-4o-mini")
    #=> %{chat: true, tools: %{enabled: true, ...}, ...}

    {:ok, model} = LLMDB.model("openai:gpt-4o-mini")
    caps = Query.capabilities(model)
    #=> %{chat: true, tools: %{enabled: true, ...}, ...}

# `select`

```elixir
@spec select(keyword()) :: {:ok, {provider(), model_id()}} | {:error, :no_match}
```

Selects the first model matching capability requirements.

Returns the first allowed model that matches the required capabilities,
in provider preference order.

## Options

- `:require` - Keyword list of required capabilities (e.g., `[tools: true, json_native: true]`)
- `:forbid` - Keyword list of forbidden capabilities
- `:prefer` - List of provider atoms in preference order (e.g., `[:openai, :anthropic]`)
- `:scope` - Either `:all` (default) or a specific provider atom

## Returns

- `{:ok, {provider, model_id}}` - First matching model
- `{:error, :no_match}` - No models match the criteria

## Examples

    {:ok, {provider, model_id}} = Query.select(
      require: [chat: true, tools: true],
      prefer: [:openai, :anthropic]
    )

    {:ok, {:openai, model_id}} = Query.select(
      require: [json_native: true],
      scope: :openai
    )

---

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