mirror of
https://github.com/microsoft/semantic-kernel.git
synced 2026-10-12 02:19:06 +00:00
## Summary `ChatHistoryTruncationReducer.reduce()` silently deletes system/developer messages when truncating chat history. This is because it calls `extract_range()`, which unconditionally filters out system/developer messages — a function designed for the summarization use case, not truncation. Fixes #12612. ## Approach Port the .NET SDK fix (PR #10344) to Python: 1. Detect the first system/developer message before truncation 2. Pass `has_system_message=True` to `locate_safe_reduction_index` so `target_count` accounts for the preserved message (matches .NET's `targetCount -= hasSystemMessage ? 1 : 0`) 3. Use a simple `history[truncation_index:]` slice instead of `extract_range` (which strips system messages) 4. Prepend the system message if it was truncated away Also adds a guard for `target_count <= 0` after the system message adjustment to prevent `IndexError` when `target_count=1`. ## Changes | File | Change | |------|--------| | `chat_history_reducer_utils.py` | Add `has_system_message` parameter, adjust `target_count`, guard against `<= 0` | | `chat_history_truncation_reducer.py` | Detect system message, bypass `extract_range`, prepend if truncated | | `test_chat_history_truncation_reducer.py` | Update 2 existing tests + 4 new tests (system, developer, no-system, target_count=1) | ## Note The summarization reducer (`ChatHistorySummarizationReducer`) has the same bug — it also uses `extract_range` and loses system messages during summarization. The .NET summarization reducer preserves system messages via `AssemblySummarizedHistory`. This should be addressed in a follow-up PR to keep this change focused. ## Test plan - [x] 11/11 truncation reducer tests pass (was 7, now 11) - [x] 9/9 utils tests pass (no regressions from new parameter) - [x] 11/11 summarization reducer tests pass (unaffected) - [x] Reproduces and fixes the exact scenario from #12612 - [x] Edge case: `target_count=1` with system message does not crash --------- Co-authored-by: Claude Opus 4.6 <[email protected]> Co-authored-by: Evan Mattson <[email protected]>