Skip to content

Python: feat: Support custom ChatHistory in GroupChatOrchestration#12912

Closed
angangwa wants to merge 3 commits into
microsoft:mainfrom
angangwa:feature/custom-chat-history-group-chat
Closed

Python: feat: Support custom ChatHistory in GroupChatOrchestration#12912
angangwa wants to merge 3 commits into
microsoft:mainfrom
angangwa:feature/custom-chat-history-group-chat

Conversation

@angangwa

@angangwa angangwa commented Aug 11, 2025

Copy link
Copy Markdown

Motivation and Context

This change addresses Issue #12911 - "Group Chat Orchestration Does Not Expose Chat History for Custom Reducer Integration".

Why is this change required?

Currently, GroupChatOrchestration creates its own internal ChatHistory instance that cannot be customized or accessed externally. This prevents users from leveraging ChatHistoryReducer implementations (like ChatHistoryTruncationReducer and ChatHistorySummarizationReducer) for automatic memory management in group chat scenarios.

What problem does it solve?

  • Enables automatic conversation memory management in group chats
  • Prevents memory issues in long-running group chat conversations
  • Supports custom ChatHistory implementations for specific use cases

What scenario does it contribute to?

  • Long-running group chat conversations that need automatic truncation
  • Custom memory management strategies through ChatHistoryReducer subclasses

Fixes: #12911

Description

This PR adds support for custom ChatHistory instances in GroupChatOrchestration while maintaining backward compatibility.

Welcome any feedback and happy to change approach. First-time contribution!

Example Usage:

# Automatic truncation in group chat
truncation_reducer = ChatHistoryTruncationReducer(
    target_count=10,
    threshold_count=2,
    auto_reduce=True
)

orchestration = GroupChatOrchestration(
    members=[agent1, agent2],
    manager=RoundRobinGroupChatManager(),
    chat_history=truncation_reducer  # Custom ChatHistory with auto-reduction
)

Current Understanding of GroupChat Architecture

GroupChatOrchestration works with multiple components:

  • GroupChatManagerActor: Manages the conversation flow and maintains the canonical chat history
  • GroupChatAgentActor: Individual agent actors that process messages and maintain their own message caches
  • InProcess Runtime: Handles message passing between actors using publish/subscribe pattern

Currently, the manager creates its own internal ChatHistory that agents can't access directly.

Implementation Approach

High-Level Flow:

  1. Allow users to pass a ChatHistoryReducer (or regular ChatHistory) to GroupChatOrchestration constructor
  2. Manager uses this custom history instance instead of creating its own
  3. When the manager adds messages to its history, it broadcasts the updated history to all agents via a new GroupChatHistorySyncMessage
  4. Agents receive this sync message and update their local message caches to match the manager's history
  5. This ensures all agents see the same reduced context, especially important for LLM-based summarization

Why This Approach:

  • Alternative 1: Give each agent its own reducer instance → Problem: LLM-based summarizers might produce different summaries, causing inconsistent context
  • Alternative 2: Only reduce at the manager level without syncing → Problem: Agents would see full history while manager sees reduced, causing inconsistent behavior
  • Current Choice: Manager maintains canonical reduced history and syncs to agents → Ensures consistent context across all participants

Issues discovered while trying to build this

  • Async Method Handling: Reducers use add_message_async() to trigger auto_reduce, but regular ChatHistory only has add_message(). Added dynamic method detection to handle both cases.
  • Race Condition: InProcess Runtime uses asyncio.gather() for concurrent message handling, causing agents to sometimes read empty caches before history sync completes. Had to add a small delay after sync messages to ensure proper ordering.

Testing

  • Did a validation with a counter agent
  • Added AI generated unit tests as of now

Note on future improvements

  • Ideally, this needs to be extended to all orchestration patterns including hand-off etc.
  • Expose the chat history object cleanly after .invoke() for further analysis
  • We should also allow the orchestration to start with previous history intact. E.g. Orchestration -> Termination -> Custom action -> Resume. This is possible with autogen.

Contribution Checklist

@angangwa angangwa requested a review from a team as a code owner August 11, 2025 18:03
@moonbox3 moonbox3 added the python Pull requests for the Python Semantic Kernel label Aug 11, 2025
@github-actions github-actions Bot changed the title feat: Support custom ChatHistory in GroupChatOrchestration Python: feat: Support custom ChatHistory in GroupChatOrchestration Aug 11, 2025
@angangwa

Copy link
Copy Markdown
Author

@microsoft-github-policy-service agree company="Microsoft"

@angangwa angangwa marked this pull request as draft August 11, 2025 19:38
Enable GroupChatOrchestration to accept ChatHistoryReducer instances for
context management in multi-agent conversations.

- Add GroupChatHistorySyncMessage for history synchronization
- Support chat_history parameter in GroupChatManagerActor and GroupChatOrchestration
- Implement async/sync handling for reducers with add_message_async
- Add 10ms delay to resolve race condition in concurrent message handlers
- Maintain backward compatibility with existing ChatHistory usage
@angangwa angangwa force-pushed the feature/custom-chat-history-group-chat branch from 4a82a8f to e562bc1 Compare August 12, 2025 00:04
@moonbox3

moonbox3 commented Aug 12, 2025

Copy link
Copy Markdown
Collaborator

Python Test Coverage

Python Test Coverage Report •
FileStmtsMissCoverMissing
agents/orchestration
   group_chat.py2071294%118–120, 122, 322–325, 327, 329, 369, 412
TOTAL26863461582% 

Python Unit Test Overview

Tests Skipped Failures Errors Time
3686 22 💤 0 ❌ 0 🔥 1m 56s ⏱️

@angangwa angangwa marked this pull request as ready for review August 12, 2025 10:37
@angangwa

Copy link
Copy Markdown
Author

Hi @moonbox3 , imagine this will take time to triage, but when there:

  • This might not be the right approach, if its close, great if you can guide me to get it to an acceptable position
  • If not, would be great if you can review and comment if this will work as a workaround in the short term to unblock a use-case

For context, we have a use-case where the Group Chat makes sequential progress and saves progress in memory for a large task that easily uses up a million token within a few minutes. We are looking for a way to progress - any workarounds appreciated.

@angangwa

angangwa commented Sep 3, 2025

Copy link
Copy Markdown
Author

Closing as this likely needs a well thought out approach that works for all orchestration patterns.

@angangwa angangwa closed this Sep 3, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

python Pull requests for the Python Semantic Kernel

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants