feat(context): implement context compaction with simple dump

This commit is contained in:
jinli.yl 2025-11-18 18:30:06 +08:00
parent 722a80ac4b
commit 079afae9e8
2 changed files with 80 additions and 1 deletions

View file

@ -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")

View file

@ -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())