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

Behaviour for context compaction strategies.

Context compaction reduces conversation history size while preserving essential
information. This helps manage LLM context windows and avoid "context rot" -
degraded performance as context length increases.

## Callbacks

- `compact/2` - Compacts the context using the strategy's approach
- `should_compact?/2` - (optional) Returns whether compaction should occur
- `introspect/1` - (optional) Returns strategy metadata for observability

## Example

    defmodule MyApp.Compaction.Custom do
      @behaviour Puck.Compaction

      @impl true
      def compact(context, config) do
        # Custom compaction logic
        {:ok, compacted_context}
      end
    end

## Built-in Strategies

- `Puck.Compaction.Summarize` - LLM-based summarization (preserves semantic meaning)

## Usage

    # Manual compaction
    {:ok, compacted} = Puck.Compaction.compact(context, {Puck.Compaction.Summarize, %{
      client: client,
      keep_last: 3
    }})

# `config`

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

# `introspection`

```elixir
@type introspection() :: %{:strategy =&gt; String.t(), optional(atom()) =&gt; term()}
```

Metadata returned by introspect/1 for observability.

# `result`

```elixir
@type result() :: {:ok, Puck.Context.t()} | {:error, term()}
```

# `compact`

```elixir
@callback compact(Puck.Context.t(), config()) :: result()
```

Compacts the context to reduce its size.

## Parameters

- `context` - The context to compact
- `config` - Strategy-specific configuration

## Returns

- `{:ok, compacted_context}` on success
- `{:error, reason}` on failure

# `introspect`
*optional* 

```elixir
@callback introspect(config()) :: introspection()
```

Returns metadata about the compaction strategy.

Used by telemetry/tracing to identify the strategy being used.

## Parameters

- `config` - Strategy configuration

## Expected Keys

- `:strategy` - Strategy name (e.g., "summarize", "sliding_window")

# `should_compact?`
*optional* 

```elixir
@callback should_compact?(Puck.Context.t(), config()) :: boolean()
```

Returns whether the context should be compacted.

Implementations can check token counts, message counts, or other criteria.

## Parameters

- `context` - The context to check
- `config` - Strategy-specific configuration (may include thresholds)

## Returns

- `true` if compaction should occur
- `false` otherwise

# `compact`

Compacts a context using the specified strategy.

This is a convenience function that delegates to the strategy module.

## Parameters

- `context` - The context to compact
- `strategy_tuple` - A tuple of `{strategy_module, config}`

## Examples

    {:ok, compacted} = Puck.Compaction.compact(context, {Puck.Compaction.Summarize, %{
      client: client,
      keep_last: 3
    }})

# `should_compact?`

Checks if context should be compacted using the specified strategy.

Falls back to `true` if the strategy doesn't implement `should_compact?/2`.

## Parameters

- `context` - The context to check
- `strategy_tuple` - A tuple of `{strategy_module, config}`

## Examples

    if Puck.Compaction.should_compact?(context, {Puck.Compaction.Summarize, config}) do
      {:ok, compacted} = Puck.Compaction.compact(context, {Puck.Compaction.Summarize, config})
    end

---

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