Skip to content

feat: implement summarizing conversation manager #112

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

stefanoamorelli
Copy link

@stefanoamorelli stefanoamorelli commented May 25, 2025

Description

Tip

Follows conventional commits. Better reviewed commit-by-commit.

Introducing a new SummarizingConversationManager as an alternative to the existing sliding window approach. It optionally uses AI-powered summarization to retain the semantic context of older messages, rather than discarding them, while staying within model context limits.

Related Issues

Closes #90

Documentation PR

strands-agents/docs#63

Type of Change

  • New feature

Testing

  • hatch fmt --linter
  • hatch fmt --formatter
  • hatch test --all
  • Verify that the changes do not break functionality or introduce warnings in consuming repositories: agents-docs, agents-tools, agents-cli

Checklist

  • I have read the CONTRIBUTING document
  • I have added tests that prove my fix is effective or my feature works
  • I have updated the documentation accordingly
  • I have added an appropriate example to the documentation to outline the feature
  • My changes generate no new warnings
  • Any dependent changes have been merged and published

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

@stefanoamorelli stefanoamorelli force-pushed the feat/summarizing-conversation-manager branch 2 times, most recently from 02bb209 to f90af97 Compare May 27, 2025 18:33
@stefanoamorelli
Copy link
Author

@Unshure:

  • Using Agent (fallback to parent Agent if not provided) instead of Model;
  • Added ability to use a custom system prompt for the summarizer;
  • Removed the fallback to SlidingWindowConversationManager;
  • Improved the system prompt of the summarizer;
  • Kept multi-modal in the history;
  • Adjusted tests based on impl. and increased coverage; interactive-rebased to keep git history clean (not sure if you prefer to squash).

Let me know your feedback, I'll hold on the documentation updates until we have a final version (and before merging).

@stefanoamorelli stefanoamorelli requested a review from Unshure May 27, 2025 19:06
@Unshure Unshure self-assigned this May 29, 2025
@Unshure
Copy link
Member

Unshure commented May 29, 2025

Can you add an integration test for this implementation as well? We wand to make sure it passes end to end.

@stefanoamorelli stefanoamorelli force-pushed the feat/summarizing-conversation-manager branch from f90af97 to 9431bf7 Compare June 1, 2025 16:11
@stefanoamorelli stefanoamorelli requested a review from Unshure June 1, 2025 16:13
@stefanoamorelli stefanoamorelli force-pushed the feat/summarizing-conversation-manager branch 13 times, most recently from c0b84b2 to f1525c2 Compare June 3, 2025 21:46
Copy link
Member

@Unshure Unshure left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is looking really good, thank you for all the work here!

@stefanoamorelli stefanoamorelli force-pushed the feat/summarizing-conversation-manager branch 11 times, most recently from c2ea68d to 565f7ef Compare June 5, 2025 21:06
@stefanoamorelli stefanoamorelli force-pushed the feat/summarizing-conversation-manager branch from 565f7ef to ddb29f0 Compare June 5, 2025 21:06
@stefanoamorelli stefanoamorelli requested a review from Unshure June 5, 2025 21:12
@stefanoamorelli
Copy link
Author

stefanoamorelli commented Jun 5, 2025

@Unshure thanks for all the feedback and really appreciate your thorough review 🙏 I've pushed the changes following your comments, let me know if I addressed everything.
(I let you resolve the pending threads)

Happy to contribute and help!

Copy link
Member

@Unshure Unshure left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code looks great! I was able to pull it locally and the integ tests ran much faster as well 🪄.

Few small things to clean up, and then this is good to merge!

Comment on lines +224 to +230
def _message_contains_tool_use(self, message: Message) -> bool:
"""Check if a message contains a ToolUse."""
return any("toolUse" in content for content in message.get("content", []))

def _message_contains_tool_result(self, message: Message) -> bool:
"""Check if a message contains a ToolResult."""
return any("toolResult" in content for content in message.get("content", []))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These aren't used anymore

Comment on lines +200 to +201
if split_point >= len(messages):
return split_point
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Duplicate logic

Comment on lines +265 to +276
# Verify we have tool usage in the conversation
has_tool_use = False
has_tool_result = False
for message in agent.messages:
for content in message.get("content", []):
if "toolUse" in content:
has_tool_use = True
if "toolResult" in content:
has_tool_result = True

assert has_tool_use, "Conversation should contain tool usage"
assert has_tool_result, "Conversation should contain tool results"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We dont need this check anymore since we manually set up the conversation

Comment on lines +388 to +392
assert len(summary_text) > 30 # Should be a substantial summary

# The dedicated agent should create a structured summary
# (We can't assert exact content since AI responses vary, but we can check it's substantive)
assert any(keyword in summary_text.lower() for keyword in ["space", "exploration", "apollo", "mission"])
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would just remove this check for now. These have led to transient failures in tests which are really annoying to deal with. Im fine with just checking that the summary_text is not empty.

Comment on lines +10 to +11
if TYPE_CHECKING:
from ..agent import Agent

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm curious what this is about?



class SummarizingConversationManager(ConversationManager):
"""Extends sliding window manager with optional summarization of older messages.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This no longer extends sliding window manager

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[FEATURE] Compaction Conversation Manager
3 participants