Current section

Files

Jump to
condukt lib condukt compactor.ex
Raw

lib/condukt/compactor.ex

defmodule Condukt.Compactor do
@moduledoc """
Behaviour for compacting a session's conversation history.
Long-running agents accumulate messages that grow past the model's context
window. A compactor receives the current message list and returns a shorter
one — by dropping old turns, eliding large tool results, or replacing a
prefix with a summary.
Compactors are pluggable just like `Condukt.SessionStore`. Pass one to
`start_link/1` and Condukt will apply it after each completed turn.
MyApp.Agent.start_link(
compactor: Condukt.Compactor.Sliding
)
MyApp.Agent.start_link(
compactor: {Condukt.Compactor.Sliding, keep: 30}
)
Compaction can also be triggered manually with `Condukt.compact/1`.
## Built-in compactors
- `Condukt.Compactor.Sliding` — keeps the most recent N messages.
- `Condukt.Compactor.ToolResultPrune` — replaces old tool result payloads
with a placeholder, preserving the surrounding reasoning structure.
## Implementing a compactor
defmodule MyApp.MyCompactor do
@behaviour Condukt.Compactor
@impl true
def compact(messages, _opts) do
{:ok, Enum.take(messages, -10)}
end
end
## Telemetry
Each compaction emits a `[:condukt, :compact, :stop]` event with
measurements `%{duration, before, after}` and metadata `%{agent}`.
"""
alias Condukt.Message
@callback compact([Message.t()], keyword()) :: {:ok, [Message.t()]} | {:error, term()}
@doc """
Dispatches `compact/2` to the configured compactor module or `{module, opts}`
tuple. Default options are merged underneath the tuple's options.
"""
def compact(compactor, messages, default_opts \\ [])
def compact({module, opts}, messages, default_opts) do
module.compact(messages, Keyword.merge(default_opts, opts))
end
def compact(module, messages, default_opts) when is_atom(module) do
module.compact(messages, default_opts)
end
end