# `Puck.Client`
[🔗](https://github.com/bradleygolden/puck/blob/v0.2.25/lib/puck/client.ex#L1)

Configuration struct for an LLM client.

## Creating Clients

    # Basic
    Puck.Client.new({Puck.Backends.ReqLLM, "anthropic:claude-sonnet-4-5"})

    # With options
    Puck.Client.new({Puck.Backends.ReqLLM, "anthropic:claude-sonnet-4-5"},
      system_prompt: "You are helpful."
    )

    # With backend options
    Puck.Client.new({Puck.Backends.ReqLLM, model: "anthropic:claude-sonnet-4-5", temperature: 0.7})

    # Mock backend for testing
    Puck.Client.new({Puck.Backends.Mock, response: "Hello!"})

## Options

- `:system_prompt` - System prompt for conversations
- `:hooks` - Hook module(s) for lifecycle events (see `Puck.Hooks`)
- `:auto_compaction` - Auto-compaction configuration (see below)

## Auto-Compaction

Enables automatic context compaction when thresholds are exceeded.

    # Summarize when context exceeds token threshold
    Puck.Client.new(backend, auto_compaction: {:summarize, max_tokens: 100_000})
    Puck.Client.new(backend, auto_compaction: {:summarize, max_tokens: 100_000, keep_last: 5})

    # SlidingWindow strategy (keeps last N messages)
    Puck.Client.new(backend, auto_compaction: {:sliding_window, window_size: 30})

    # Full custom config with different summarization model
    compaction_client = Puck.Client.new({Puck.Backends.ReqLLM, "anthropic:claude-haiku"})
    Puck.Client.new(backend, auto_compaction: {Puck.Compaction.Summarize, %{
      client: compaction_client,
      max_tokens: 100_000,
      keep_last: 3
    }})

    # BAML users: must provide explicit :client (BAML functions are compile-time specific)
    summarize_client = Puck.Client.new({Puck.Backends.Baml, function: "SummarizeConversation"})
    # Or use ReqLLM for summarization:
    summarize_client = Puck.Client.new({Puck.Backends.ReqLLM, "anthropic:claude-haiku"})

    Puck.Client.new({Puck.Backends.Baml, function: "MyFunction"},
      auto_compaction: {:summarize, max_tokens: 100_000, client: summarize_client}
    )

# `auto_compaction`

```elixir
@type auto_compaction() ::
  {:summarize, keyword()}
  | {:sliding_window, keyword()}
  | {module(), keyword() | map()}
  | nil
```

# `backend`

```elixir
@type backend() :: {backend_module(), backend_config()}
```

# `backend_config`

```elixir
@type backend_config() :: map()
```

# `backend_module`

```elixir
@type backend_module() :: module()
```

# `hooks`

```elixir
@type hooks() :: module() | [module()] | nil
```

# `t`

```elixir
@type t() :: %Puck.Client{
  auto_compaction: auto_compaction(),
  backend: backend(),
  hooks: hooks(),
  system_prompt: String.t() | nil
}
```

# `backend_config`

Returns the backend config for this client.

## Examples

    iex> client = Puck.Client.new({Puck.Backends.Mock, response: "Hello"})
    iex> Puck.Client.backend_config(client)
    %{response: "Hello"}

# `backend_module`

Returns the backend module for this client.

## Examples

    iex> client = Puck.Client.new({Puck.Backends.Mock, response: "Hello"})
    iex> Puck.Client.backend_module(client)
    Puck.Backends.Mock

# `new`

Creates a new client.

Accepts either a backend tuple as the first argument with optional keyword options,
or a pure keyword list with a `:backend` key.

## Examples

    # Mock backend (built-in)
    iex> Puck.Client.new({Puck.Backends.Mock, response: "Hello!"})
    %Puck.Client{backend: {Puck.Backends.Mock, %{response: "Hello!"}}, system_prompt: nil, hooks: nil, auto_compaction: nil}

    # With options
    iex> Puck.Client.new({Puck.Backends.Mock, response: "Hi"}, system_prompt: "You are helpful.")
    %Puck.Client{backend: {Puck.Backends.Mock, %{response: "Hi"}}, system_prompt: "You are helpful.", hooks: nil, auto_compaction: nil}

    # Pure keyword style
    iex> Puck.Client.new(backend: {Puck.Backends.Mock, response: "Test"}, system_prompt: "You are helpful.")
    %Puck.Client{backend: {Puck.Backends.Mock, %{response: "Test"}}, system_prompt: "You are helpful.", hooks: nil, auto_compaction: nil}

---

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