Skip to content

bug(agent-context): inject_semantic_recall inserts Role::User recall but remove_recall_messages only removes Role::System — recall messages accumulate on repeated calls #4019

@bug-ops

Description

@bug-ops

Description

ContextService::inject_semantic_recall (service.rs:257) creates a recall message with Role::User when the tiered-retrieval path is active:

Some(Message::from_legacy(
    Role::User,
    format!("{RECALL_PREFIX}{recalled_text}"),
))

However remove_recall_messages delegates to remove_by_part_or_prefix (service.rs:1360–1368), which only removes messages where m.role == Role::System:

messages.retain(|m| {
    if m.role != Role::System {
        return true; // User-role recall is never removed
    }
    ...
});

This means every call to inject_semantic_recall with tiered retrieval enabled inserts a new Role::User recall message that is never cleaned up by remove_recall_messages, causing recall messages to accumulate turn over turn.

Reproduction Steps

  1. Enable tiered_retrieval_config.enabled = true in config.
  2. Call ContextService::inject_semantic_recall multiple times on successive turns.
  3. Inspect window.messages: observe multiple Role::User messages starting with RECALL_PREFIX accumulating.

Expected Behavior

Each call to inject_semantic_recall should first remove any existing recall message (regardless of role) and then insert at most one.

Actual Behavior

Role::User recall messages from the tiered-retrieval path are never removed; they accumulate across turns.

Fix Candidate

remove_by_part_or_prefix should also remove Role::User messages whose content starts with RECALL_PREFIX, or inject_semantic_recall should use Role::System consistently with the ContextAssembler::gather path.

Environment

  • Commit: c9ff16a
  • Crate: zeph-agent-context, service.rs:203, service.rs:1355
  • Feature: tiered_retrieval

Metadata

Metadata

Assignees

Labels

P2High value, medium complexitybugSomething isn't working

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions