mirror of
https://github.com/agentscope-ai/ReMe.git
synced 2026-08-28 05:25:04 +00:00
* feat(compactor): add extra instruction support and improve error handling - Add extra_instruction parameter to compactor for custom guidance during message compaction - Implement try-catch blocks around AS LLM initialization with detailed error logging - Add extra_instruction parameter to ReMe.compact method with comprehensive documentation - Update agentscope dependency from 1.0.17 to 1.0.18 in light installation - Bump version number from 0.3.1.6 to 0.3.1.7 - Pass extra_instruction parameter through compactor instantiation and execution flow * fix(core): add error handling for AS LLM formatters and token counters initialization - Wrapped AS LLM formatters initialization in try-except blocks - Added specific error logging for failed AS LLM formatter initialization - Wrapped AS token counters initialization in try-except blocks - Added specific error logging for failed AS token counter initialization - Applied same error handling pattern to both initial setup and restart operations - Maintained existing warning logs for unsupported backends
115 lines
4 KiB
Python
115 lines
4 KiB
Python
"""Compactor module for memory compaction operations."""
|
|
|
|
from agentscope.agent import ReActAgent
|
|
from agentscope.message import Msg
|
|
|
|
from ..utils import AsMsgHandler
|
|
from ....core.op import BaseOp
|
|
from ....core.utils import get_logger
|
|
|
|
logger = get_logger()
|
|
|
|
|
|
def _is_valid_summary(content: str) -> bool:
|
|
"""Check if the summary content is valid.
|
|
|
|
Args:
|
|
content: The summary content to validate.
|
|
|
|
Returns:
|
|
True if valid, False otherwise.
|
|
"""
|
|
if not content or not content.strip():
|
|
return False
|
|
if "##" not in content:
|
|
return False
|
|
return True
|
|
|
|
|
|
class Compactor(BaseOp):
|
|
"""Compactor class for compacting memory messages."""
|
|
|
|
def __init__(
|
|
self,
|
|
memory_compact_threshold: int,
|
|
console_enabled: bool = False,
|
|
return_dict: bool = False,
|
|
add_thinking_block: bool = True,
|
|
extra_instruction: str = "",
|
|
**kwargs,
|
|
):
|
|
super().__init__(**kwargs)
|
|
self.memory_compact_threshold: int = memory_compact_threshold
|
|
self.console_enabled: bool = console_enabled
|
|
self.return_dict: bool = return_dict
|
|
self.add_thinking_block: bool = add_thinking_block
|
|
self.extra_instruction: str = extra_instruction
|
|
|
|
# pylint: disable=too-many-return-statements
|
|
async def execute(self):
|
|
messages: list[Msg] = self.context.get("messages", [])
|
|
previous_summary: str = self.context.get("previous_summary", "")
|
|
|
|
if not messages:
|
|
if self.return_dict:
|
|
return {"user_message": "", "history_compact": "", "is_valid": False}
|
|
return ""
|
|
|
|
msg_handler = AsMsgHandler(self.as_token_counter)
|
|
before_token_count = await msg_handler.count_msgs_token(messages)
|
|
history_formatted_str: str = await msg_handler.format_msgs_to_str(
|
|
messages=messages,
|
|
memory_compact_threshold=self.memory_compact_threshold,
|
|
include_thinking=self.add_thinking_block,
|
|
)
|
|
after_token_count = await msg_handler.count_str_token(history_formatted_str)
|
|
logger.info(f"Compactor before_token_count={before_token_count} after_token_count={after_token_count}")
|
|
|
|
if not history_formatted_str:
|
|
logger.warning(f"No history to compact. messages={messages}")
|
|
if self.return_dict:
|
|
return {"user_message": "", "history_compact": "", "is_valid": False}
|
|
return ""
|
|
|
|
agent = ReActAgent(
|
|
name="reme_compactor",
|
|
model=self.as_llm,
|
|
sys_prompt=self.get_prompt("system_prompt"),
|
|
formatter=self.as_llm_formatter,
|
|
)
|
|
agent.set_console_output_enabled(self.console_enabled)
|
|
|
|
if previous_summary:
|
|
user_message: str = (
|
|
f"# conversation\n{history_formatted_str}\n\n"
|
|
f"# previous-summary\n{previous_summary}\n\n" + self.get_prompt("update_user_message")
|
|
)
|
|
else:
|
|
user_message: str = f"# conversation\n{history_formatted_str}\n\n" + self.get_prompt("initial_user_message")
|
|
|
|
if self.extra_instruction:
|
|
user_message += f"\n\n# extra-instruction\n{self.extra_instruction}"
|
|
logger.info(f"Compactor sys_prompt={agent.sys_prompt} user_message={user_message}")
|
|
|
|
compact_msg: Msg = await agent.reply(
|
|
Msg(
|
|
name="reme",
|
|
role="user",
|
|
content=user_message,
|
|
),
|
|
)
|
|
|
|
history_compact: str = compact_msg.get_text_content()
|
|
is_valid: bool = _is_valid_summary(history_compact)
|
|
|
|
if not is_valid:
|
|
logger.warning(f"Invalid summary result: {history_compact[:200]}...")
|
|
if self.return_dict:
|
|
return {"user_message": user_message, "history_compact": history_compact, "is_valid": False}
|
|
return ""
|
|
|
|
logger.info(f"Compactor Result:\n{history_compact}")
|
|
|
|
if self.return_dict:
|
|
return {"user_message": user_message, "history_compact": history_compact, "is_valid": True}
|
|
return history_compact
|