diff --git a/reme_ai/context/offload/context_compact_op.py b/reme_ai/context/offload/context_compact_op.py index 3f9a0dcb..9f5a81ef 100644 --- a/reme_ai/context/offload/context_compact_op.py +++ b/reme_ai/context/offload/context_compact_op.py @@ -141,5 +141,5 @@ class ContextCompactOp(BaseAsyncOp): tool_message.content = compact_result # Return the compacted messages as JSON - self.context.response.answer = json.dumps([x.model_dump() for x in messages], ensure_ascii=False, indent=2) + self.context.response.answer = json.dumps([x.simple_dump() for x in messages], ensure_ascii=False, indent=2) logger.info(f"Context compaction completed: {len(write_file_dict)} tool messages were compacted") diff --git a/test_op/test_context_compact_op.py b/test_op/test_context_compact_op.py new file mode 100644 index 00000000..5cdf8b96 --- /dev/null +++ b/test_op/test_context_compact_op.py @@ -0,0 +1,79 @@ +"""Test script for ContextCompactOp. + +This script provides test cases for ContextCompactOp class. +It can be run directly with: python test_context_compact_op.py +""" + +import asyncio + +from flowllm.core.enumeration import Role +from flowllm.core.schema import Message + +from reme_ai.context.offload.context_compact_op import ContextCompactOp +from reme_ai.main import ReMeApp + + +async def async_main(): + """Test function for ContextCompactOp.""" + async with ReMeApp(): + # Create test messages with system, user, assistant, tool sequence + messages = [ + Message(role=Role.SYSTEM, content="You are a helpful assistant."), + Message(role=Role.USER, content="What is the weather today?"), + Message( + role=Role.ASSISTANT, + content="I'll check the weather for you.", + ), + Message( + role=Role.TOOL, + content="A" * 5000, # Large tool message that should be compacted + tool_call_id="call_001", + ), + Message( + role=Role.ASSISTANT, + content="Let me also check the forecast.", + ), + Message( + role=Role.TOOL, + content="B" * 5000, # Another large tool message + tool_call_id="call_002", + ), + Message( + role=Role.USER, + content="What about tomorrow?", + ), + Message( + role=Role.ASSISTANT, + content="I'll check tomorrow's weather.", + ), + Message( + role=Role.TOOL, + content="C" * 5000, # Third large tool message + tool_call_id="call_003", + ), + Message( + role=Role.TOOL, + content="Recent result", # Recent tool message (should be kept) + tool_call_id="call_004", + ), + ] + + # Create op with lower thresholds for testing + op = ContextCompactOp( + all_token_threshold=1000, # Low threshold to trigger compaction + tool_token_threshold=100, # Low threshold to compact tool messages + tool_left_char_len=50, # Keep 50 chars in preview + keep_recent=1, # Keep 1 recent tool message + storage_path="./test_compact_storage", + ) + + # Execute the compaction + await op.async_call(messages=[m.model_dump() for m in messages]) + + # Print results + result = op.context.response.answer + print(f"Context compaction result: {result}") + + +if __name__ == "__main__": + asyncio.run(async_main())