From 7d03a9d512ca2e51b892d501b6dac333178e8111 Mon Sep 17 00:00:00 2001 From: Jonathan Boisson Date: Thu, 11 Jun 2026 12:13:48 +0200 Subject: [PATCH] feat: protect skills mentioned in user messages from pre-pass pruning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Even if a skill is loaded only once (count==1), if the user mentions its name in recent messages, we keep it protected instead of pruning. This prevents false positives where a single-use skill is actually the focus of the current task (e.g. user says 'use the doc-builder skill'). Cost: zero — simple string matching on recent user messages. Fixes #32106. --- agent/context_compressor.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/agent/context_compressor.py b/agent/context_compressor.py index 0fa9107003e5..efbf9a95ab40 100644 --- a/agent/context_compressor.py +++ b/agent/context_compressor.py @@ -900,8 +900,19 @@ class ContextCompressor(ContextEngine): # Count skill_view calls across entire history + identify recent skill_call_count: Dict[str, int] = {} skill_recent_calls: set = set() + skill_mentioned_in_user_messages: set = set() total = len(messages) tail_start = max(0, total - prepass_tail) + # Gather user message texts from recent context for mention checking + recent_user_texts: list[str] = [] + for i, msg in enumerate(messages): + if msg.get("role") != "user": + continue + if i < tail_start: + continue + cont = msg.get("content", "") + if isinstance(cont, str): + recent_user_texts.append(cont.lower()) for i, msg in enumerate(messages): if msg.get("role") != "assistant": @@ -921,6 +932,11 @@ class ContextCompressor(ContextEngine): skill_call_count[name.lower()] = skill_call_count.get(name.lower(), 0) + 1 if i >= tail_start: skill_recent_calls.add(name.lower()) + # Check if skill name is mentioned in recent user messages + for user_text in recent_user_texts: + if name.lower() in user_text: + skill_mentioned_in_user_messages.add(name.lower()) + break # Collect skill_view results >10000 chars (not already pruned) skill_results: Dict[str, list] = {} @@ -957,6 +973,8 @@ class ContextCompressor(ContextEngine): continue # Actively used in recent context if skill_call_count.get(name_lower, 0) >= 2: continue # Reused skill, likely still relevant + if name_lower in skill_mentioned_in_user_messages: + continue # Skill name mentioned in recent user messages stale_skills.append((skill_name, results)) if not stale_skills: