Skip to content

Continuous compaction with contextual hand summaries #896

@pbranchu

Description

@pbranchu

Problem

Conversation history accumulates without structure. Long sessions hit token limits, old topics get conflated with current ones, and the agent has no situational awareness of what happened between exchanges (calendar events, emails received, etc.).

Proposed Design: Continuous Compaction with Context Sources

Core idea

Instead of compacting only when message count exceeds a threshold, compact continuously every N exchanges. Each compaction cycle doesn't just summarize old turns — it also queries configured hands for contextual summaries scoped to the compacted time window.

Compaction cycle

Every N exchanges (configurable, default 5), when the turn count exceeds keep_recent:

  1. Identify the compaction window: timestamps of the first and last turns being compacted.

  2. Summarize old turns: existing compactor behavior — summarize all turns except the most recent keep_recent into a paragraph.

  3. Query context sources: for each configured hand, send a request with the time window:

    "Provide a contextual summary for the period from {first_turn_ts} to {last_turn_ts}. {user_prompt}"

    Examples:

    • Calendar hand: "Edgewood Park hike 9am-12pm completed. Dentist at 2pm in 45 minutes."
    • Mail hand: "5 new emails since 9am. One from school principal marked urgent."
  4. Merge into context block: combine turn summary + hand summaries into a single compact context that replaces the old history:

    [Session summary — 9:15 AM to 2:30 PM]
    Conversation: discussed enzymatic cleaners for cat-urine shoes, decided to 
    order from Amazon. Planned Edgewood Park hike.
    
    Calendar: Edgewood Park hike 9am-12pm completed. Dentist at 2pm in 45 min.
    Mail: 5 new emails. Urgent: school principal re: Matteo incident.
    
  5. Keep recent turns verbatim: the last keep_recent turns stay as raw messages for full context.

Time window handling

  • The hand receives from_timestamp and to_timestamp (ISO 8601)
  • The hand queries its data source for that window (e.g., calendar events, emails received)
  • If the gap between to_timestamp and now is large (user was away), the hand naturally fills in what happened during the gap
  • No special "session boundary" logic needed — the time window handles it

Configuration

[compaction]
# Compact every N exchanges (0 = disabled, use threshold-based)
interval = 5
# Number of recent turns to keep verbatim
keep_recent = 6
# Model to use for summarization (cheap/fast)
model = "gemini-2.5-flash"

# Context sources queried during compaction
[[compaction.context_sources]]
hand = "calendar-hand"
prompt = "Summarize events that occurred and upcoming events in the next 4 hours. One paragraph, concise."

[[compaction.context_sources]]
hand = "mail-hand"
prompt = "Summarize unread or notable emails. Flag anything urgent. One paragraph."

Why this works

  • No session boundary detection needed: the time window naturally handles gaps. A 5-hour gap means the hands report 5 hours of context.
  • Graceful context aging: old topics fade into summaries while recent exchanges have full detail.
  • Situational awareness: the agent always knows what's happening in calendar/email/etc., refreshed every few exchanges.
  • Stable token count: context size stays bounded regardless of conversation length.
  • Channel-agnostic: works the same on voice, chat, email — compaction happens in the bridge/kernel, not adapters.
  • User-configurable: users decide what context sources to include and what to ask for.

Implementation

Component Change
config.rs Add CompactionConfig with interval, keep_recent, context_sources
compactor.rs Add continuous compaction mode (interval-based trigger)
compactor.rs Add query_context_sources() — sends time-windowed requests to configured hands
kernel.rs Wire continuous compaction into the agent loop (check after each exchange)
bridge.rs Pass timestamps through to compaction context

Test Plan

  • Compaction triggers every N exchanges, not just at threshold
  • Context sources queried with correct time window
  • Hand summaries merged into compacted context
  • Recent turns preserved verbatim
  • Large time gaps produce rich context summaries
  • Token count stays stable over long conversations
  • Calendar/mail context appears in agent's session context
  • Agent uses contextual awareness in responses
  • Configuration: custom prompts, custom hands, interval tuning

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions