Manages context window size by compacting older tool-call rounds.
When the message history exceeds a byte budget, the oldest rounds (AI tool-call + tool results) are dropped and replaced with a brief summary of what tools were called and their outcomes. This preserves the investigation narrative while staying within the LLM's effective context window.
Usage
messages = LangEx.ContextCompaction.compact_if_needed(messages)
# With custom budget:
messages = LangEx.ContextCompaction.compact_if_needed(messages, max_bytes: 100_000)Options
:max_bytes— byte budget for the message list (default200_000):min_rounds_to_keep— never drop below this many rounds (default2):error_detector—fn(content :: String.t()) -> boolean()to detect error payloads in tool results (default: JSON"error"/"errors"key detection):summarizer—fn(dropped_messages :: [Message.t()]) -> String.t()to produce a real summary of the dropped rounds' content (e.g. an LLM call). When absent, a mechanical notice listing tool names and outcomes is used.:compaction_notice—fn(summary_text, dropped_count) -> Message.t()to customize the compaction notice message
Summary
Functions
Compact messages if total size exceeds the context budget.
Default error detector for tool results.
Calculate total byte size of a message list.
Functions
@spec compact_if_needed( [LangEx.Message.t()], keyword() ) :: [LangEx.Message.t()]
Compact messages if total size exceeds the context budget.
Returns messages unchanged if under budget, or with oldest rounds replaced by a summary notice if over budget.
Default error detector for tool results.
Returns true if the content parses as JSON with an "error" or
"errors" top-level key.
@spec messages_byte_size([LangEx.Message.t()]) :: non_neg_integer()
Calculate total byte size of a message list.