search_memory and store_memory before compaction, so stable user-provided facts in the older slice are saved to long-term memory first. It never blocks compaction: if the child times out or fails, compaction still runs.
Quick Start
1
Enable with True
One bool on
ExecutionConfig turns the flush on. It stays off by default with zero overhead — the child agent is never constructed.2
Tune with the config class
Swap the bool for
PreCompactionMemoryFlushConfig to set the deadline, token cap, minimum turns, or a cheaper model for the child.How It Works
The flush fires at the older-slice boundary — exactly the messages that are about to disappear — searches memory to avoid duplicates, stages writes, and commits them only if the child finishes in time. The child agent has zero autonomy budget (max_steps=3, no streaming, no verbose) and cannot recurse into another compaction. Only user and assistant text is serialised — tool messages and non-text parts are dropped.
MemoryFlushResult
The flush returns a frozenMemoryFlushResult (importable from praisonaiagents.compaction) describing what happened.
Configuration Options
PreCompactionMemoryFlushConfig controls the child agent’s budget.
The nested config defaults to
enabled=True so PreCompactionMemoryFlushConfig(...) is ergonomic. The containing ExecutionConfig.pre_compaction_memory_flush slot stays default-off.Environment Overrides
Two environment variables override the code-level config at runtime.
Invalid values are ignored with a logged warning — the code-level config stands.
Behaviour Guarantees
- Never blocks compaction. Every failure path returns a
MemoryFlushResult(attempted=True, completed=False, ...)and logs a warning; compaction proceeds unchanged. - Atomic commit-or-nothing. Child writes are staged and committed only after successful, in-time completion. A timed-out worker cannot mutate the parent memory store.
- Sync path in a daemon thread. A stuck provider cannot delay process shutdown.
- Tool payloads excluded. Only
userandassistanttext is serialised. - Prompt-injection posture. The child treats the transcript as data, not instructions, refuses to store credentials or secrets, and uses only the two provided memory tools.
Common Patterns
Save user preferences before a chat session’s context rotates by enabling the flush alongside compaction:MemoryFlushResult.reason (count timeout vs completed) to tune timeout_seconds over time.
Best Practices
Leave the default timeout unless the flush times out
Leave the default timeout unless the flush times out
The child is capped at
max_steps=3 and rarely needs more than the default timeout_seconds=20.0. Raise it only if you observe reason == "timeout" dominating.Set a cheap dedicated model for the flush
Set a cheap dedicated model for the flush
When the parent uses an expensive model, pass
llm="gpt-4o-mini" (or similar). The flush job is short and doesn’t need the top-tier model.Tune min_turns_to_flush to skip tiny compactions
Tune min_turns_to_flush to skip tiny compactions
The default
min_turns_to_flush=2 avoids firing on trivial compactions. Raise it if reason == "below_minimum" dominates your metrics.Respect the child's security boundary
Respect the child's security boundary
The child agent shares the parent’s memory backend but cannot access its tools — that’s a deliberate boundary. Don’t try to bypass it by mutating the child.
Advanced
Framework authors wiring the flush into a custom compactor path can callrun_pre_compaction_flush (async) or run_pre_compaction_flush_sync directly. Both need a parent_agent shaped like Agent — it must expose _memory_instance and .llm.
Related
Context Compaction
Automatically compact chat history near the token limit.
Memory
Long-term memory storage and retrieval.
Context Compaction Policy
Choose the strategy that runs after the older-slice boundary.
Session Compaction Checkpoint
Persist compaction state across sessions.

