mirror of
https://github.com/headroomlabs-ai/headroom.git
synced 2026-08-27 14:17:10 -04:00
perf: add compress_system_messages and min_tokens_to_compress config
- compress_system_messages (default True): set False to skip system prompt compression entirely - min_tokens_to_compress (default 250): minimum word count for a message to be eligible for compression (was hardcoded at 50) Both flow through CompressConfig to ContentRouter. Default behavior unchanged.
This commit is contained in:
parent
1039f66f67
commit
3242efe3a5
2 changed files with 23 additions and 1 deletions
|
|
@ -101,6 +101,11 @@ class CompressConfig:
|
|||
Set True for document compression, RAG pipelines, or when user messages
|
||||
contain large tool outputs."""
|
||||
|
||||
compress_system_messages: bool = True
|
||||
"""Compress system messages (default: True).
|
||||
Set False to preserve system prompts exactly as-is. Useful for voice
|
||||
agents where tool definitions and instructions must not be altered."""
|
||||
|
||||
protect_recent: int = 4
|
||||
"""Don't compress the last N messages (they're the active conversation).
|
||||
Set 0 to compress everything."""
|
||||
|
|
@ -115,6 +120,11 @@ class CompressConfig:
|
|||
Only affects Kompress (text compression). SmartCrusher (JSON) has its
|
||||
own logic based on array dedup."""
|
||||
|
||||
min_tokens_to_compress: int = 250
|
||||
"""Minimum token count (word count) for a message to be compressed.
|
||||
Messages shorter than this are left unchanged. Default 250.
|
||||
Set lower for voice agents where turns are short."""
|
||||
|
||||
# Model variant
|
||||
kompress_model: str | None = None
|
||||
"""Kompress model ID. None = default (chopratejas/kompress-base).
|
||||
|
|
@ -219,9 +229,11 @@ def compress(
|
|||
biases=biases,
|
||||
# Pass CompressConfig options through to transforms
|
||||
compress_user_messages=cfg.compress_user_messages,
|
||||
compress_system_messages=cfg.compress_system_messages,
|
||||
target_ratio=cfg.target_ratio,
|
||||
protect_recent=cfg.protect_recent,
|
||||
protect_analysis_context=cfg.protect_analysis_context,
|
||||
min_tokens_to_compress=cfg.min_tokens_to_compress,
|
||||
kompress_model=cfg.kompress_model,
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -1484,10 +1484,12 @@ class ContentRouter(Transform):
|
|||
skip_user = (
|
||||
kwargs.get("compress_user_messages") is not True and self.config.skip_user_messages
|
||||
)
|
||||
skip_system = kwargs.get("compress_system_messages") is False
|
||||
protect_recent = kwargs.get("protect_recent", self.config.protect_recent_code)
|
||||
protect_analysis = kwargs.get(
|
||||
"protect_analysis_context", self.config.protect_analysis_context
|
||||
)
|
||||
min_tokens = kwargs.get("min_tokens_to_compress", 50)
|
||||
# Store runtime options on self for access by _route_and_compress_block
|
||||
self._runtime_target_ratio: float | None = kwargs.get("target_ratio")
|
||||
self._runtime_kompress_model: str | None = kwargs.get("kompress_model")
|
||||
|
|
@ -1664,7 +1666,15 @@ class ContentRouter(Transform):
|
|||
route_counts["user_msg"] += 1
|
||||
continue
|
||||
|
||||
if not content or len(content.split()) < 50:
|
||||
# Protection 1b: Never compress system messages (when disabled)
|
||||
if skip_system and role == "system":
|
||||
result_slots[i] = message
|
||||
transforms_applied.append("router:protected:system_message")
|
||||
route_counts.setdefault("system_msg", 0)
|
||||
route_counts["system_msg"] += 1
|
||||
continue
|
||||
|
||||
if not content or len(content.split()) < min_tokens:
|
||||
# Skip small content
|
||||
result_slots[i] = message
|
||||
route_counts["small"] += 1
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue