print tool calls in /history

This commit is contained in:
Mery-Sanz 2025-05-06 08:58:22 +02:00
parent b5fd3427b0
commit 3568519538
1 changed files with 74 additions and 7 deletions

View File

@ -2,8 +2,12 @@
History command for CAI REPL.
This module provides commands for displaying conversation history.
"""
import json
from typing import Any, Dict, List, Optional
from rich.console import Console # pylint: disable=import-error
from rich.table import Table # pylint: disable=import-error
from rich.text import Text # pylint: disable=import-error
from cai.repl.commands.base import Command, register_command
@ -20,6 +24,20 @@ class HistoryCommand(Command):
description="Display the conversation history",
aliases=["/h"]
)
def handle(self, args: Optional[List[str]] = None,
messages: Optional[List[Dict]] = None) -> bool:
"""Handle the history command.
Args:
args: Optional list of command arguments
messages: Optional list of conversation messages
Returns:
True if the command was handled successfully, False otherwise
"""
# Currently, the history command doesn't take any arguments
return self.handle_no_args()
def handle_no_args(self) -> bool:
"""Handle the command when no arguments are provided.
@ -27,7 +45,7 @@ class HistoryCommand(Command):
Returns:
True if the command was handled successfully, False otherwise
"""
# Access messages directly from repl.py's global scope
# Access messages directly from openai_chatcompletions.py
try:
from cai.sdk.agents.models.openai_chatcompletions import message_history # pylint: disable=import-outside-toplevel # noqa: E501
except ImportError:
@ -54,10 +72,11 @@ class HistoryCommand(Command):
try:
role = msg.get("role", "unknown")
content = msg.get("content", "")
tool_calls = msg.get("tool_calls", None)
# Truncate long content for better display
if len(content) > 100:
content = content[:97] + "..."
# Create formatted content based on message type
formatted_content = self._format_message_content(
content, tool_calls)
# Color the role based on type
if role == "user":
@ -74,14 +93,62 @@ class HistoryCommand(Command):
table.add_row(
str(idx),
f"[{role_style}]{role}[/{role_style}]",
content
formatted_content
)
except Exception:
# Si hay un error, evita esto (no agregues la fila)
except Exception as e:
# Log error but continue with next message
console.print(f"[red]Error displaying message {idx}: {e}[/red]")
continue
console.print(table)
return True
def _format_message_content(
self, content: Any, tool_calls: List[Dict[str, Any]]
) -> str:
"""Format message content for display, handling both text and tool calls.
Args:
content: Text content of the message
tool_calls: List of tool calls if present
Returns:
Formatted string representation of the message content
"""
if tool_calls:
# Format tool calls into a readable string
result = []
for tc in tool_calls:
func_details = tc.get("function", {})
func_name = func_details.get("name", "unknown_function")
# Format arguments (pretty-print JSON if possible)
args_str = func_details.get("arguments", "{}")
try:
# Parse and re-format JSON for better readability
args_dict = json.loads(args_str)
args_formatted = json.dumps(args_dict, indent=2)
# Limit to first 100 chars for display
if len(args_formatted) > 100:
args_formatted = args_formatted[:97] + "..."
except (json.JSONDecodeError, TypeError):
# If not valid JSON, use as is
args_formatted = args_str
if len(args_formatted) > 100:
args_formatted = args_formatted[:97] + "..."
result.append(f"Function: [bold blue]{func_name}[/bold blue]")
result.append(f"Args: {args_formatted}")
return "\n".join(result)
elif content:
# Regular text content (truncate if too long)
if len(content) > 100:
return content[:97] + "..."
return content
else:
# No content or tool calls (empty message)
return "[dim italic]Empty message[/dim italic]"
# Register the command