PtcRunner.SubAgent.Compression behaviour (PtcRunner v0.5.1)

View Source

Behaviour for message history compression strategies.

Compression strategies transform turn history into LLM messages at render time. This enables various prompt optimization techniques like coalescing multiple turns into a single USER message.

Strategy Pattern

Strategies implement to_messages/3 which receives:

  • turns - List of completed turns to compress
  • memory - Accumulated definitions from all turns
  • opts - Rendering options (mission, tools, data, limits, etc.)

Configuration

Use normalize/1 to handle the various compression option formats:

# Disabled (default)
normalize(nil)   # => {nil, []}
normalize(false) # => {nil, []}

# Enabled with defaults
normalize(true)  # => {SingleUserCoalesced, [println_limit: 15, tool_call_limit: 20]}

# Custom strategy or options
normalize(MyStrategy)               # => {MyStrategy, [println_limit: 15, ...]}
normalize({MyStrategy, opts})       # => {MyStrategy, merged_opts}

Summary

Types

An LLM message with role and content.

Options passed to compression strategies.

Statistics about what compression did.

Callbacks

Human-readable name for this compression strategy.

Render turns into LLM messages with compression statistics.

Functions

Returns the default compression options.

Normalize compression configuration into {strategy, opts} tuple.

Types

message()

@type message() :: %{role: :system | :user | :assistant, content: String.t()}

An LLM message with role and content.

opts()

@type opts() :: [
  prompt: String.t(),
  system_prompt: String.t(),
  tools: map(),
  data: map(),
  println_limit: non_neg_integer(),
  tool_call_limit: non_neg_integer(),
  turns_left: non_neg_integer()
]

Options passed to compression strategies.

  • mission - The agent's mission/prompt text
  • system_prompt - Static system prompt content
  • tools - Map of available tools
  • data - Input data provided to the agent
  • println_limit - Max println calls to include (default: 15)
  • tool_call_limit - Max tool calls to include (default: 20)
  • turns_left - Remaining turns for the agent

stats()

@type stats() :: %{
  enabled: boolean(),
  strategy: String.t(),
  turns_compressed: non_neg_integer(),
  tool_calls_total: non_neg_integer(),
  tool_calls_shown: non_neg_integer(),
  tool_calls_dropped: non_neg_integer(),
  printlns_total: non_neg_integer(),
  printlns_shown: non_neg_integer(),
  printlns_dropped: non_neg_integer(),
  error_turns_collapsed: non_neg_integer()
}

Statistics about what compression did.

Returned alongside messages to report exactly what was dropped or collapsed.

Callbacks

name()

@callback name() :: String.t()

Human-readable name for this compression strategy.

to_messages(turns, memory, opts)

@callback to_messages(
  turns :: [PtcRunner.Turn.t()],
  memory :: map(),
  opts :: opts()
) :: {[message()], stats()}

Render turns into LLM messages with compression statistics.

Returns a tuple of {messages, stats} where stats reports exactly what the compression did (items dropped, errors collapsed, etc.).

Compression is a pure function - same inputs always produce the same output. Turn count is derived from length(turns), not message count.

Functions

default_opts()

@spec default_opts() :: keyword()

Returns the default compression options.

Examples

iex> PtcRunner.SubAgent.Compression.default_opts()
[println_limit: 15, tool_call_limit: 20]

normalize(module)

@spec normalize(boolean() | module() | {module(), keyword()} | nil) ::
  {module() | nil, keyword()}

Normalize compression configuration into {strategy, opts} tuple.

Handles various configuration formats:

  • nil or false - Compression disabled, returns {nil, []}
  • true - Use default strategy with default options
  • Module - Use custom strategy with default options
  • {Module, opts} - Use custom strategy with merged options

Examples

iex> PtcRunner.SubAgent.Compression.normalize(nil)
{nil, []}

iex> PtcRunner.SubAgent.Compression.normalize(false)
{nil, []}

iex> {strategy, opts} = PtcRunner.SubAgent.Compression.normalize(true)
iex> strategy
PtcRunner.SubAgent.Compression.SingleUserCoalesced
iex> opts[:println_limit]
15
iex> opts[:tool_call_limit]
20

iex> {strategy, _opts} = PtcRunner.SubAgent.Compression.normalize(SomeStrategy)
iex> strategy
SomeStrategy

iex> {strategy, opts} = PtcRunner.SubAgent.Compression.normalize({SomeStrategy, println_limit: 5})
iex> strategy
SomeStrategy
iex> opts[:println_limit]
5
iex> opts[:tool_call_limit]
20