Today the core SDK exposes the protocol and loss-guard contract only — the
MemoryConsolidationProtocol interface plus the ConsolidationResult math. The heavy LLM consolidation pass and its scheduling ship in praisonai-plugins. Until that plugin lands, you implement the protocol yourself and run it behind your own scheduler.Quick Start
1
Check a result under the loss guard
Construct a
ConsolidationResult, read loss_fraction, and ask the guard whether a pass drops too much.2
Wire a consolidator to an Agent
Implement
MemoryConsolidationProtocol and hand it your agent’s memory on a schedule — the agent keeps chatting while consolidation runs in the background.How It Works
Consolidation is background maintenance: the user never invokes it mid-conversation — a scheduler runs it off-turn, and the loss guard decides whether the rewrite is applied. The protocols are@runtime_checkable, so isinstance works at runtime, and both consolidate and aconsolidate carry a resolvable ConsolidationResult return annotation for introspection.
Configuration Options
ConsolidationResult reports what a pass did and carries the loss-guard math. No feature_configs.py entry exists — this is a protocol, not a config class — so these are the fields the dataclass exposes.
Methods:
Loss-Guard Semantics
The loss guard is the invariant that keeps a bad rewrite from wiping your memory. Originals-based vs net-count loss.loss_fraction normally divides the drop in entries by entries_before. When you set retained_originals, it instead measures how many original entries survived — which catches destructive rewrites that keep the count the same.
0.0, never a divide-by-zero, and growth never reports negative loss.
exceeds_loss raises ValueError on NaN, inf, out-of-range, or non-numeric input.
Common Patterns
Implement the sync protocol and reject rewrites that trip the guard:praisonai-plugins:
@runtime_checkable:
Sync vs Async
Pick the protocol that matches how your memory store and consolidation logic run.Layering
Consolidation is built in three layers so the core stays dependency-free.Best Practices
Start with a conservative max_loss_fraction
Start with a conservative max_loss_fraction
The
0.25 default is a sane starting point — it lets a pass merge and prune meaningfully while blocking anything that would gut a quarter of your store. Lower it if your memories are high-value and irreplaceable.Always set retained_originals when you can compute it
Always set retained_originals when you can compute it
Net entry-count loss misses destructive equal-size rewrites. If your implementation knows how many original entries survived, set
retained_originals so the guard measures real loss, not just the change in count.Never run consolidation on the reply path
Never run consolidation on the reply path
Consolidation is a heavy background pass — schedule it (nightly cron, idle window) so it never adds latency to a user turn. The plugin layer wires this for you.
Emit telemetry via context
Emit telemetry via context
Populate
context with counts and timings so you can observe merge/prune/reject rates over time and tune max_loss_fraction.Related
Memory Lifecycle Hooks
React to compression, session switches, writes, and delegation from inside your memory backend.
Pre-Compaction Memory Flush
Save durable facts to long-term memory before compaction discards them.

