From ca381913cb426d04e82f49dfd50e9c03a0cb32c9 Mon Sep 17 00:00:00 2001 From: Mery-Sanz Date: Tue, 6 May 2025 10:57:47 +0200 Subject: [PATCH] solve /flush command --- src/cai/repl/commands/__init__.py | 3 +- src/cai/repl/commands/flush.py | 120 ++++++++++++++++++++++++++++++ 2 files changed, 122 insertions(+), 1 deletion(-) create mode 100644 src/cai/repl/commands/flush.py diff --git a/src/cai/repl/commands/__init__.py b/src/cai/repl/commands/__init__.py index 95bb4a27..cfb0a13a 100644 --- a/src/cai/repl/commands/__init__.py +++ b/src/cai/repl/commands/__init__.py @@ -37,7 +37,8 @@ from cai.repl.commands import ( # pylint: disable=import-error,unused-import,li turns, agent, history, - config + config, + flush ) # Define helper functions diff --git a/src/cai/repl/commands/flush.py b/src/cai/repl/commands/flush.py new file mode 100644 index 00000000..9cee48df --- /dev/null +++ b/src/cai/repl/commands/flush.py @@ -0,0 +1,120 @@ +""" +Flush command for CAI REPL. +This module provides commands for clear the context. +""" +import os +from typing import ( + Dict, + List, + Optional +) +from rich.console import Console # pylint: disable=import-error +from rich.panel import Panel # pylint: disable=import-error +from cai.util import get_model_input_tokens +from cai.repl.commands.base import Command, register_command +from cai.sdk.agents.models.openai_chatcompletions import message_history + +console = Console() + + +class FlushCommand(Command): + """Command to flush the conversation history.""" + + def __init__(self): + """Initialize the flush command.""" + super().__init__( + name="/flush", + description="Clear the current conversation history.", + aliases=["/clear"] + ) + + def handle_no_args(self, messages: Optional[List[Dict]] = None) -> bool: + """Handle the flush command when no args are provided. + + Args: + messages: The conversation history messages + + Returns: + True if the command was handled successfully + """ + # Use both the local messages parameter and the global message_history + local_messages = messages or [] + global_history_length = len(message_history) + + # Get token usage information before clearing + token_info = "" + context_usage = "" + + # Access client through a function to avoid circular imports + # We can use globals() to get the client at runtime + client = self._get_client() + + if client and hasattr(client, 'interaction_input_tokens') and hasattr( + client, 'total_input_tokens'): + model = os.getenv('CAI_MODEL', "qwen2.5:14b") + input_tokens = client.interaction_input_tokens if hasattr( + client, 'interaction_input_tokens') else 0 + total_tokens = client.total_input_tokens if hasattr( + client, 'total_input_tokens') else 0 + max_tokens = get_model_input_tokens(model) + context_pct = (input_tokens / max_tokens) * \ + 100 if max_tokens > 0 else 0 + + token_info = f"Current tokens: {input_tokens}, Total tokens: {total_tokens}" + context_usage = f"Context usage: {context_pct:.1f}% of {max_tokens} tokens" + + # Clear both the local messages list and the global message_history + if local_messages: + local_messages.clear() + + # Always clear the global message history + message_history.clear() + + # Determine which length to report (use the greater of the two) + initial_length = max(len(local_messages) if messages else 0, global_history_length) + + # Display information about the cleared messages + if initial_length > 0: + content = [ + f"Conversation history cleared. Removed {initial_length} messages." + ] + + if token_info: + content.append(token_info) + if context_usage: + content.append(context_usage) + + console.print(Panel( + "\n".join(content), + title="[bold cyan]Context Flushed[/bold cyan]", + border_style="blue", + padding=(1, 2) + )) + else: + console.print(Panel( + "No conversation history to clear.", + title="[bold cyan]Context Flushed[/bold cyan]", + border_style="blue", + padding=(1, 2) + )) + return True + + def _get_client(self): + """Get the CAI client from the global namespace. + + This function avoids circular imports by accessing the client + at runtime instead of import time. + + Returns: + The global CAI client instance or None if not available + """ + try: + # Import here to avoid circular import + from cai.repl.repl import client as global_client # pylint: disable=import-outside-toplevel # noqa: E501 + return global_client + except (ImportError, AttributeError): + return None + + +# Register the /flush command +register_command(FlushCommand()) \ No newline at end of file