mirror of
https://github.com/microsoft/semantic-kernel.git
synced 2026-10-12 11:19:56 +00:00
## Summary Fixes #12708 `ChatHistoryTruncationReducer.reduce()` can orphan `TOOL` role messages by truncating the preceding `assistant` message that contains the `tool_calls`, causing OpenAI to reject the history with: ``` messages with role 'tool' must be a response to a preceding message with 'tool_calls' ``` ## Root Cause `locate_safe_reduction_index()` uses `contains_function_call_or_result()` to detect tool-related messages during its backward scan. This function only checks `msg.items` for `FunctionCallContent`/`FunctionResultContent` instances. However, `TOOL` role messages can contain only text content (no `FunctionResultContent` in `items`), which causes the backward scan to treat them as regular messages. The truncation point then lands between the `tool_calls` assistant message and its `TOOL` responses, orphaning the tool results. ## Fix Added `AuthorRole.TOOL` check to `contains_function_call_or_result()`: ```python if msg.role == AuthorRole.TOOL: return True ``` This ensures **any** `TOOL` role message is recognized as part of a tool call/result pair, regardless of whether it has `FunctionResultContent` in its `items`. ## Test Added `test_locate_safe_reduction_index_tool_role_without_function_result_content` that verifies TOOL role messages with only text content are not separated from their tool call. --------- Co-authored-by: giulio-leone <[email protected]> Co-authored-by: Evan Mattson <[email protected]> Co-authored-by: Copilot <[email protected]>