pub trait BlockCompactionStrategy: Send + Sync {
// Required methods
fn keep_first<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
record: &'life1 LoopRecord,
turn_map: &'life2 TurnMap,
config: &'life3 CompactionConfig,
) -> Pin<Box<dyn Future<Output = Option<TurnRange>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait;
fn keep_recent<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
record: &'life1 LoopRecord,
turn_map: &'life2 TurnMap,
config: &'life3 CompactionConfig,
) -> Pin<Box<dyn Future<Output = Option<CompactedSection>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait;
fn keep_compacted<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
record: &'life1 LoopRecord,
turn_map: &'life2 TurnMap,
config: &'life3 CompactionConfig,
is_most_recent: bool,
) -> Pin<Box<dyn Future<Output = Option<CompactedSection>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait;
// Provided method
fn compact<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
record: &'life1 LoopRecord,
config: &'life2 CompactionConfig,
is_most_recent: bool,
) -> Pin<Box<dyn Future<Output = CompactionBlock> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait { ... }
}Expand description
Strategy for creating non-destructive CompactionBlock overlays.
Three methods produce the three sections of a CompactionBlock:
keep_first: turns kept verbatim from the startkeep_recent: recent turns with truncated tool outputskeep_compacted: fully summarised section
The default compact() method assembles them. Override individual methods
to customise specific sections (e.g. LLM-based summarisation for keep_compacted).
As of phi-core 0.9.0, all four methods are async fn (via #[async_trait])
so implementations can issue LLM calls inside keep_compacted/keep_recent
without block_in_place workarounds. Sync implementations migrate by
prepending #[async_trait] to the impl + async to each method —
existing bodies need no changes if they don’t .await anything.
Required Methods§
Sourcefn keep_first<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
record: &'life1 LoopRecord,
turn_map: &'life2 TurnMap,
config: &'life3 CompactionConfig,
) -> Pin<Box<dyn Future<Output = Option<TurnRange>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
fn keep_first<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
record: &'life1 LoopRecord,
turn_map: &'life2 TurnMap,
config: &'life3 CompactionConfig,
) -> Pin<Box<dyn Future<Output = Option<TurnRange>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
Determine the keep_first section: turns kept verbatim from the start. Only called for the most recent loop.
Sourcefn keep_recent<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
record: &'life1 LoopRecord,
turn_map: &'life2 TurnMap,
config: &'life3 CompactionConfig,
) -> Pin<Box<dyn Future<Output = Option<CompactedSection>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
fn keep_recent<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
record: &'life1 LoopRecord,
turn_map: &'life2 TurnMap,
config: &'life3 CompactionConfig,
) -> Pin<Box<dyn Future<Output = Option<CompactedSection>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
Create the keep_recent section: recent turns with truncated tool outputs. Only called for the most recent loop.
Sourcefn keep_compacted<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
record: &'life1 LoopRecord,
turn_map: &'life2 TurnMap,
config: &'life3 CompactionConfig,
is_most_recent: bool,
) -> Pin<Box<dyn Future<Output = Option<CompactedSection>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
fn keep_compacted<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
record: &'life1 LoopRecord,
turn_map: &'life2 TurnMap,
config: &'life3 CompactionConfig,
is_most_recent: bool,
) -> Pin<Box<dyn Future<Output = Option<CompactedSection>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
Create the keep_compacted section: fully summarised turns. For most recent loop: summarises the middle (between keep_first and keep_recent). For older loops: summarises the entire loop.
Implementations should aim to summarise ALL turns in the range within
config.max_summary_tokens — e.g. shorter per-turn summaries or an
LLM-generated holistic digest. The token budget is for the total output,
not a per-turn limit.
Provided Methods§
Sourcefn compact<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
record: &'life1 LoopRecord,
config: &'life2 CompactionConfig,
is_most_recent: bool,
) -> Pin<Box<dyn Future<Output = CompactionBlock> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn compact<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
record: &'life1 LoopRecord,
config: &'life2 CompactionConfig,
is_most_recent: bool,
) -> Pin<Box<dyn Future<Output = CompactionBlock> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Assemble a CompactionBlock from the three sections.
Default implementation calls the three methods above.
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".