chore: remove verbose prints and add agent/memory tool registration in assistant core
This commit is contained in:
@@ -164,7 +164,7 @@ Break down the task and delegate subtasks to appropriate agents. Coordinate thei
|
||||
|
||||
return results
|
||||
|
||||
def get_session_summary(self) -> Dict[str, Any]:
|
||||
def get_session_summary(self) -> str:
|
||||
summary = {
|
||||
'session_id': self.session_id,
|
||||
'active_agents': len(self.active_agents),
|
||||
@@ -178,7 +178,7 @@ Break down the task and delegate subtasks to appropriate agents. Coordinate thei
|
||||
for agent_id, agent in self.active_agents.items()
|
||||
]
|
||||
}
|
||||
return summary
|
||||
return json.dumps(summary)
|
||||
|
||||
def clear_session(self):
|
||||
self.active_agents.clear()
|
||||
|
||||
+1
-19
@@ -14,12 +14,9 @@ def run_autonomous_mode(assistant, task):
|
||||
logger.debug(f"=== AUTONOMOUS MODE START ===")
|
||||
logger.debug(f"Task: {task}")
|
||||
|
||||
if assistant.verbose:
|
||||
print_autonomous_header(task)
|
||||
|
||||
assistant.messages.append({
|
||||
"role": "user",
|
||||
"content": f"AUTONOMOUS TASK: {task}\n\nPlease work on this task step by step. Use tools as needed. When the task is fully complete, clearly state 'Task complete'."
|
||||
"content": f"{task}"
|
||||
})
|
||||
|
||||
try:
|
||||
@@ -29,17 +26,11 @@ def run_autonomous_mode(assistant, task):
|
||||
logger.debug(f"--- Autonomous iteration {assistant.autonomous_iterations} ---")
|
||||
logger.debug(f"Messages before context management: {len(assistant.messages)}")
|
||||
|
||||
if assistant.verbose:
|
||||
print(f"\n{Colors.BOLD}{Colors.MAGENTA}{'▶' * 3} Iteration {assistant.autonomous_iterations} {'◀' * 3}{Colors.RESET}\n")
|
||||
|
||||
from pr.core.context import manage_context_window
|
||||
assistant.messages = manage_context_window(assistant.messages, assistant.verbose)
|
||||
|
||||
logger.debug(f"Messages after context management: {len(assistant.messages)}")
|
||||
|
||||
if assistant.verbose:
|
||||
print(f"{Colors.GRAY}Calling API...{Colors.RESET}")
|
||||
|
||||
from pr.core.api import call_api
|
||||
from pr.tools.base import get_tools_definition
|
||||
response = call_api(
|
||||
@@ -67,9 +58,6 @@ def run_autonomous_mode(assistant, task):
|
||||
logger.debug(f"=== AUTONOMOUS MODE COMPLETE ===")
|
||||
logger.debug(f"Total iterations: {assistant.autonomous_iterations}")
|
||||
logger.debug(f"Final message count: {len(assistant.messages)}")
|
||||
|
||||
print(f"{Colors.BOLD}Total Iterations:{Colors.RESET} {assistant.autonomous_iterations}")
|
||||
print(f"{Colors.BOLD}Messages in Context:{Colors.RESET} {len(assistant.messages)}\n")
|
||||
break
|
||||
|
||||
result = process_response_autonomous(assistant, response)
|
||||
@@ -97,16 +85,12 @@ def process_response_autonomous(assistant, response):
|
||||
assistant.messages.append(message)
|
||||
|
||||
if 'tool_calls' in message and message['tool_calls']:
|
||||
print(f"{Colors.BOLD}{Colors.CYAN}🔧 Executing {len(message['tool_calls'])} tool(s)...{Colors.RESET}\n")
|
||||
|
||||
tool_results = []
|
||||
|
||||
for tool_call in message['tool_calls']:
|
||||
func_name = tool_call['function']['name']
|
||||
arguments = json.loads(tool_call['function']['arguments'])
|
||||
|
||||
display_tool_call(func_name, arguments, "running")
|
||||
|
||||
result = execute_single_tool(assistant, func_name, arguments)
|
||||
result = truncate_tool_result(result)
|
||||
|
||||
@@ -121,8 +105,6 @@ def process_response_autonomous(assistant, response):
|
||||
|
||||
for result in tool_results:
|
||||
assistant.messages.append(result)
|
||||
|
||||
print(f"{Colors.GRAY}Processing tool results...{Colors.RESET}\n")
|
||||
from pr.core.api import call_api
|
||||
from pr.tools.base import get_tools_definition
|
||||
follow_up = call_api(
|
||||
|
||||
@@ -47,6 +47,8 @@ class AdvancedContextManager:
|
||||
return complexity
|
||||
|
||||
def extract_key_sentences(self, text: str, top_k: int = 5) -> List[str]:
|
||||
if not text.strip():
|
||||
return []
|
||||
sentences = re.split(r'(?<=[.!?])\s+', text)
|
||||
if not sentences:
|
||||
return []
|
||||
|
||||
+18
-1
@@ -133,6 +133,18 @@ class Assistant:
|
||||
'display_edit_summary': lambda **kw: display_edit_summary(),
|
||||
'display_edit_timeline': lambda **kw: display_edit_timeline(**kw),
|
||||
'clear_edit_tracker': lambda **kw: clear_edit_tracker(),
|
||||
'create_agent': lambda **kw: create_agent(**kw),
|
||||
'list_agents': lambda **kw: list_agents(**kw),
|
||||
'execute_agent_task': lambda **kw: execute_agent_task(**kw),
|
||||
'remove_agent': lambda **kw: remove_agent(**kw),
|
||||
'collaborate_agents': lambda **kw: collaborate_agents(**kw),
|
||||
'add_knowledge_entry': lambda **kw: add_knowledge_entry(**kw),
|
||||
'get_knowledge_entry': lambda **kw: get_knowledge_entry(**kw),
|
||||
'search_knowledge': lambda **kw: search_knowledge(**kw),
|
||||
'get_knowledge_by_category': lambda **kw: get_knowledge_by_category(**kw),
|
||||
'update_knowledge_importance': lambda **kw: update_knowledge_importance(**kw),
|
||||
'delete_knowledge_entry': lambda **kw: delete_knowledge_entry(**kw),
|
||||
'get_knowledge_statistics': lambda **kw: get_knowledge_statistics(**kw),
|
||||
}
|
||||
|
||||
if func_name in func_map:
|
||||
@@ -230,6 +242,7 @@ class Assistant:
|
||||
path_options = [p + os.sep if os.path.isdir(p) else p for p in path_options]
|
||||
|
||||
combined_options = sorted(list(set(options + path_options)))
|
||||
#combined_options.extend(self.commands)
|
||||
|
||||
if state < len(combined_options):
|
||||
return combined_options[state]
|
||||
@@ -279,7 +292,8 @@ class Assistant:
|
||||
else:
|
||||
message = sys.stdin.read()
|
||||
|
||||
process_message(self, message)
|
||||
from pr.autonomous.mode import run_autonomous_mode
|
||||
run_autonomous_mode(self, message)
|
||||
|
||||
def cleanup(self):
|
||||
if hasattr(self, 'enhanced') and self.enhanced:
|
||||
@@ -299,9 +313,12 @@ class Assistant:
|
||||
|
||||
def run(self):
|
||||
try:
|
||||
print(f"DEBUG: interactive={self.args.interactive}, message={self.args.message}, isatty={sys.stdin.isatty()}")
|
||||
if self.args.interactive or (not self.args.message and sys.stdin.isatty()):
|
||||
print("DEBUG: calling run_repl")
|
||||
self.run_repl()
|
||||
else:
|
||||
print("DEBUG: calling run_single")
|
||||
self.run_single()
|
||||
finally:
|
||||
self.cleanup()
|
||||
|
||||
@@ -166,6 +166,8 @@ class RPEditor:
|
||||
|
||||
def save_file(self):
|
||||
"""Thread-safe save file command."""
|
||||
if not self.running:
|
||||
return self._save_file()
|
||||
try:
|
||||
self.client_sock.send(pickle.dumps({'command': 'save_file'}))
|
||||
except:
|
||||
@@ -630,6 +632,10 @@ class RPEditor:
|
||||
|
||||
def set_text(self, text):
|
||||
"""Thread-safe text setting."""
|
||||
if not self.running:
|
||||
with self.lock:
|
||||
self._set_text(text)
|
||||
return
|
||||
try:
|
||||
self.client_sock.send(pickle.dumps({'command': 'set_text', 'text': text}))
|
||||
except:
|
||||
|
||||
@@ -0,0 +1,168 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Advanced input handler for PR Assistant with editor mode, file inclusion, and image support.
|
||||
"""
|
||||
|
||||
import os
|
||||
import re
|
||||
import base64
|
||||
import mimetypes
|
||||
import readline
|
||||
import glob
|
||||
from pathlib import Path
|
||||
from typing import Optional
|
||||
# from pr.ui.colors import Colors # Avoid import issues
|
||||
|
||||
|
||||
class AdvancedInputHandler:
|
||||
"""Handles advanced input with editor mode, file inclusion, and image support."""
|
||||
|
||||
def __init__(self):
|
||||
self.editor_mode = False
|
||||
self.setup_readline()
|
||||
|
||||
def setup_readline(self):
|
||||
"""Setup readline with basic completer."""
|
||||
try:
|
||||
# Simple completer that doesn't interfere
|
||||
def completer(text, state):
|
||||
return None
|
||||
|
||||
readline.set_completer(completer)
|
||||
readline.parse_and_bind('tab: complete')
|
||||
except:
|
||||
pass # Readline not available
|
||||
|
||||
def toggle_editor_mode(self):
|
||||
"""Toggle between simple and editor input modes."""
|
||||
self.editor_mode = not self.editor_mode
|
||||
mode = "Editor" if self.editor_mode else "Simple"
|
||||
print(f"\nSwitched to {mode.lower()} input mode.")
|
||||
|
||||
def get_input(self, prompt: str = "You> ") -> Optional[str]:
|
||||
"""Get input from user, handling different modes."""
|
||||
try:
|
||||
if self.editor_mode:
|
||||
return self._get_editor_input(prompt)
|
||||
else:
|
||||
return self._get_simple_input(prompt)
|
||||
except KeyboardInterrupt:
|
||||
return None
|
||||
except EOFError:
|
||||
return None
|
||||
|
||||
def _get_simple_input(self, prompt: str) -> Optional[str]:
|
||||
"""Get simple input with file completion."""
|
||||
try:
|
||||
user_input = input(prompt).strip()
|
||||
|
||||
if not user_input:
|
||||
return ""
|
||||
|
||||
# Check for special commands
|
||||
if user_input.lower() == '/editor':
|
||||
self.toggle_editor_mode()
|
||||
return self.get_input(prompt) # Recurse to get new input
|
||||
|
||||
# Process file inclusions and images
|
||||
processed_input = self._process_input(user_input)
|
||||
return processed_input
|
||||
|
||||
except KeyboardInterrupt:
|
||||
return None
|
||||
|
||||
def _get_editor_input(self, prompt: str) -> Optional[str]:
|
||||
"""Get multi-line input for editor mode."""
|
||||
try:
|
||||
print("Editor mode: Enter your message. Type 'END' on a new line to finish.")
|
||||
print("Type '/simple' to switch back to simple mode.")
|
||||
|
||||
lines = []
|
||||
while True:
|
||||
try:
|
||||
line = input()
|
||||
if line.strip().lower() == 'end':
|
||||
break
|
||||
elif line.strip().lower() == '/simple':
|
||||
self.toggle_editor_mode()
|
||||
return self.get_input(prompt) # Switch back and get input
|
||||
lines.append(line)
|
||||
except EOFError:
|
||||
break
|
||||
|
||||
content = '\n'.join(lines).strip()
|
||||
|
||||
if not content:
|
||||
return ""
|
||||
|
||||
# Process file inclusions and images
|
||||
processed_content = self._process_input(content)
|
||||
return processed_content
|
||||
|
||||
except KeyboardInterrupt:
|
||||
return None
|
||||
|
||||
def _process_input(self, text: str) -> str:
|
||||
"""Process input text for file inclusions and images."""
|
||||
# Process @[filename] inclusions
|
||||
text = self._process_file_inclusions(text)
|
||||
|
||||
# Process image inclusions (look for image file paths)
|
||||
text = self._process_image_inclusions(text)
|
||||
|
||||
return text
|
||||
|
||||
def _process_file_inclusions(self, text: str) -> str:
|
||||
"""Replace @[filename] with file contents."""
|
||||
def replace_file(match):
|
||||
filename = match.group(1).strip()
|
||||
try:
|
||||
path = Path(filename).expanduser().resolve()
|
||||
if path.exists() and path.is_file():
|
||||
with open(path, 'r', encoding='utf-8', errors='replace') as f:
|
||||
content = f.read()
|
||||
return f"\n--- File: {filename} ---\n{content}\n--- End of {filename} ---\n"
|
||||
else:
|
||||
return f"[File not found: {filename}]"
|
||||
except Exception as e:
|
||||
return f"[Error reading file {filename}: {e}]"
|
||||
|
||||
# Replace @[filename] patterns
|
||||
pattern = r'@\[([^\]]+)\]'
|
||||
return re.sub(pattern, replace_file, text)
|
||||
|
||||
def _process_image_inclusions(self, text: str) -> str:
|
||||
"""Process image file references and encode them."""
|
||||
# Find potential image file paths
|
||||
words = text.split()
|
||||
processed_parts = []
|
||||
|
||||
for word in words:
|
||||
# Check if it's a file path that exists and is an image
|
||||
try:
|
||||
path = Path(word.strip()).expanduser().resolve()
|
||||
if path.exists() and path.is_file():
|
||||
mime_type, _ = mimetypes.guess_type(str(path))
|
||||
if mime_type and mime_type.startswith('image/'):
|
||||
# Encode image
|
||||
with open(path, 'rb') as f:
|
||||
image_data = base64.b64encode(f.read()).decode('utf-8')
|
||||
|
||||
# Replace with data URL
|
||||
processed_parts.append(f"[Image: {path.name}]\ndata:{mime_type};base64,{image_data}\n")
|
||||
continue
|
||||
except:
|
||||
pass
|
||||
|
||||
processed_parts.append(word)
|
||||
|
||||
return ' '.join(processed_parts)
|
||||
|
||||
|
||||
# Global instance
|
||||
input_handler = AdvancedInputHandler()
|
||||
|
||||
|
||||
def get_advanced_input(prompt: str = "You> ") -> Optional[str]:
|
||||
"""Get advanced input from user."""
|
||||
return input_handler.get_input(prompt)
|
||||
@@ -8,6 +8,8 @@ from pr.tools.database import db_set, db_get, db_query
|
||||
from pr.tools.web import http_fetch, web_search, web_search_news
|
||||
from pr.tools.python_exec import python_exec
|
||||
from pr.tools.patch import apply_patch, create_diff
|
||||
from pr.tools.agents import create_agent, list_agents, execute_agent_task, remove_agent, collaborate_agents
|
||||
from pr.tools.memory import add_knowledge_entry, get_knowledge_entry, search_knowledge, get_knowledge_by_category, update_knowledge_importance, delete_knowledge_entry, get_knowledge_statistics
|
||||
|
||||
__all__ = [
|
||||
'get_tools_definition',
|
||||
@@ -17,5 +19,7 @@ __all__ = [
|
||||
'db_set', 'db_get', 'db_query',
|
||||
'http_fetch', 'web_search', 'web_search_news',
|
||||
'python_exec','tail_process', 'kill_process',
|
||||
'apply_patch', 'create_diff'
|
||||
'apply_patch', 'create_diff',
|
||||
'create_agent', 'list_agents', 'execute_agent_task', 'remove_agent', 'collaborate_agents',
|
||||
'add_knowledge_entry', 'get_knowledge_entry', 'search_knowledge', 'get_knowledge_by_category', 'update_knowledge_importance', 'delete_knowledge_entry', 'get_knowledge_statistics'
|
||||
]
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
import os
|
||||
from typing import Dict, Any, List
|
||||
from pr.agents.agent_manager import AgentManager
|
||||
from pr.core.api import call_api
|
||||
|
||||
def create_agent(role_name: str, agent_id: str = None) -> Dict[str, Any]:
|
||||
"""Create a new agent with the specified role."""
|
||||
try:
|
||||
# Get db_path from environment or default
|
||||
db_path = os.environ.get('ASSISTANT_DB_PATH', '~/.assistant_db.sqlite')
|
||||
db_path = os.path.expanduser(db_path)
|
||||
|
||||
manager = AgentManager(db_path, call_api)
|
||||
agent_id = manager.create_agent(role_name, agent_id)
|
||||
return {"status": "success", "agent_id": agent_id, "role": role_name}
|
||||
except Exception as e:
|
||||
return {"status": "error", "error": str(e)}
|
||||
|
||||
def list_agents() -> Dict[str, Any]:
|
||||
"""List all active agents."""
|
||||
try:
|
||||
db_path = os.path.expanduser('~/.assistant_db.sqlite')
|
||||
manager = AgentManager(db_path, call_api)
|
||||
agents = []
|
||||
for agent_id, agent in manager.active_agents.items():
|
||||
agents.append({
|
||||
"agent_id": agent_id,
|
||||
"role": agent.role.name,
|
||||
"task_count": agent.task_count,
|
||||
"message_count": len(agent.message_history)
|
||||
})
|
||||
return {"status": "success", "agents": agents}
|
||||
except Exception as e:
|
||||
return {"status": "error", "error": str(e)}
|
||||
|
||||
def execute_agent_task(agent_id: str, task: str, context: Dict[str, Any] = None) -> Dict[str, Any]:
|
||||
"""Execute a task with the specified agent."""
|
||||
try:
|
||||
db_path = os.path.expanduser('~/.assistant_db.sqlite')
|
||||
manager = AgentManager(db_path, call_api)
|
||||
result = manager.execute_agent_task(agent_id, task, context)
|
||||
return result
|
||||
except Exception as e:
|
||||
return {"status": "error", "error": str(e)}
|
||||
|
||||
def remove_agent(agent_id: str) -> Dict[str, Any]:
|
||||
"""Remove an agent."""
|
||||
try:
|
||||
db_path = os.path.expanduser('~/.assistant_db.sqlite')
|
||||
manager = AgentManager(db_path, call_api)
|
||||
success = manager.remove_agent(agent_id)
|
||||
return {"status": "success" if success else "not_found", "agent_id": agent_id}
|
||||
except Exception as e:
|
||||
return {"status": "error", "error": str(e)}
|
||||
|
||||
def collaborate_agents(orchestrator_id: str, task: str, agent_roles: List[str]) -> Dict[str, Any]:
|
||||
"""Collaborate multiple agents on a task."""
|
||||
try:
|
||||
db_path = os.path.expanduser('~/.assistant_db.sqlite')
|
||||
manager = AgentManager(db_path, call_api)
|
||||
result = manager.collaborate_agents(orchestrator_id, task, agent_roles)
|
||||
return result
|
||||
except Exception as e:
|
||||
return {"status": "error", "error": str(e)}
|
||||
@@ -0,0 +1,99 @@
|
||||
import os
|
||||
from typing import Dict, Any, List
|
||||
from pr.memory.knowledge_store import KnowledgeStore, KnowledgeEntry
|
||||
import time
|
||||
import uuid
|
||||
|
||||
def add_knowledge_entry(category: str, content: str, metadata: Dict[str, Any] = None, entry_id: str = None) -> Dict[str, Any]:
|
||||
"""Add a new entry to the knowledge base."""
|
||||
try:
|
||||
db_path = os.path.expanduser('~/.assistant_db.sqlite')
|
||||
store = KnowledgeStore(db_path)
|
||||
|
||||
if entry_id is None:
|
||||
entry_id = str(uuid.uuid4())[:16]
|
||||
|
||||
entry = KnowledgeEntry(
|
||||
entry_id=entry_id,
|
||||
category=category,
|
||||
content=content,
|
||||
metadata=metadata or {},
|
||||
created_at=time.time(),
|
||||
updated_at=time.time()
|
||||
)
|
||||
|
||||
store.add_entry(entry)
|
||||
return {"status": "success", "entry_id": entry_id}
|
||||
except Exception as e:
|
||||
return {"status": "error", "error": str(e)}
|
||||
|
||||
def get_knowledge_entry(entry_id: str) -> Dict[str, Any]:
|
||||
"""Retrieve a knowledge entry by ID."""
|
||||
try:
|
||||
db_path = os.path.expanduser('~/.assistant_db.sqlite')
|
||||
store = KnowledgeStore(db_path)
|
||||
|
||||
entry = store.get_entry(entry_id)
|
||||
if entry:
|
||||
return {"status": "success", "entry": entry.to_dict()}
|
||||
else:
|
||||
return {"status": "not_found", "entry_id": entry_id}
|
||||
except Exception as e:
|
||||
return {"status": "error", "error": str(e)}
|
||||
|
||||
def search_knowledge(query: str, category: str = None, top_k: int = 5) -> Dict[str, Any]:
|
||||
"""Search the knowledge base semantically."""
|
||||
try:
|
||||
db_path = os.path.expanduser('~/.assistant_db.sqlite')
|
||||
store = KnowledgeStore(db_path)
|
||||
|
||||
entries = store.search_entries(query, category, top_k)
|
||||
results = [entry.to_dict() for entry in entries]
|
||||
return {"status": "success", "results": results}
|
||||
except Exception as e:
|
||||
return {"status": "error", "error": str(e)}
|
||||
|
||||
def get_knowledge_by_category(category: str, limit: int = 20) -> Dict[str, Any]:
|
||||
"""Get knowledge entries by category."""
|
||||
try:
|
||||
db_path = os.path.expanduser('~/.assistant_db.sqlite')
|
||||
store = KnowledgeStore(db_path)
|
||||
|
||||
entries = store.get_by_category(category, limit)
|
||||
results = [entry.to_dict() for entry in entries]
|
||||
return {"status": "success", "entries": results}
|
||||
except Exception as e:
|
||||
return {"status": "error", "error": str(e)}
|
||||
|
||||
def update_knowledge_importance(entry_id: str, importance_score: float) -> Dict[str, Any]:
|
||||
"""Update the importance score of a knowledge entry."""
|
||||
try:
|
||||
db_path = os.path.expanduser('~/.assistant_db.sqlite')
|
||||
store = KnowledgeStore(db_path)
|
||||
|
||||
store.update_importance(entry_id, importance_score)
|
||||
return {"status": "success", "entry_id": entry_id, "importance_score": importance_score}
|
||||
except Exception as e:
|
||||
return {"status": "error", "error": str(e)}
|
||||
|
||||
def delete_knowledge_entry(entry_id: str) -> Dict[str, Any]:
|
||||
"""Delete a knowledge entry."""
|
||||
try:
|
||||
db_path = os.path.expanduser('~/.assistant_db.sqlite')
|
||||
store = KnowledgeStore(db_path)
|
||||
|
||||
success = store.delete_entry(entry_id)
|
||||
return {"status": "success" if success else "not_found", "entry_id": entry_id}
|
||||
except Exception as e:
|
||||
return {"status": "error", "error": str(e)}
|
||||
|
||||
def get_knowledge_statistics() -> Dict[str, Any]:
|
||||
"""Get statistics about the knowledge base."""
|
||||
try:
|
||||
db_path = os.path.expanduser('~/.assistant_db.sqlite')
|
||||
store = KnowledgeStore(db_path)
|
||||
|
||||
stats = store.get_statistics()
|
||||
return {"status": "success", "statistics": stats}
|
||||
except Exception as e:
|
||||
return {"status": "error", "error": str(e)}
|
||||
+7
-32
@@ -3,41 +3,16 @@ from typing import Dict, Any
|
||||
from pr.ui.colors import Colors
|
||||
|
||||
def display_tool_call(tool_name, arguments, status="running", result=None):
|
||||
status_icons = {
|
||||
"running": ("⚙", Colors.YELLOW),
|
||||
"success": ("✓", Colors.GREEN),
|
||||
"error": ("✗", Colors.RED)
|
||||
}
|
||||
if status == "running":
|
||||
return
|
||||
|
||||
icon, color = status_icons.get(status, ("•", Colors.WHITE))
|
||||
args_str = ", ".join([f"{k}={str(v)[:20]}" for k, v in list(arguments.items())[:2]])
|
||||
line = f"{tool_name}({args_str})"
|
||||
|
||||
print(f"\n{Colors.BOLD}{'═' * 80}{Colors.RESET}")
|
||||
print(f"{color}{icon} {Colors.BOLD}{Colors.CYAN}TOOL: {tool_name}{Colors.RESET}")
|
||||
print(f"{Colors.BOLD}{'─' * 80}{Colors.RESET}")
|
||||
if len(line) > 80:
|
||||
line = line[:77] + "..."
|
||||
|
||||
if arguments:
|
||||
print(f"{Colors.YELLOW}Parameters:{Colors.RESET}")
|
||||
for key, value in arguments.items():
|
||||
value_str = str(value)
|
||||
if len(value_str) > 100:
|
||||
value_str = value_str[:100] + "..."
|
||||
print(f" {Colors.CYAN}• {key}:{Colors.RESET} {value_str}")
|
||||
|
||||
if result is not None and status != "running":
|
||||
print(f"\n{Colors.YELLOW}Result:{Colors.RESET}")
|
||||
result_str = json.dumps(result, indent=2) if isinstance(result, dict) else str(result)
|
||||
|
||||
if len(result_str) > 500:
|
||||
result_str = result_str[:500] + f"\n{Colors.GRAY}... (truncated){Colors.RESET}"
|
||||
|
||||
if status == "success":
|
||||
print(f"{Colors.GREEN}{result_str}{Colors.RESET}")
|
||||
elif status == "error":
|
||||
print(f"{Colors.RED}{result_str}{Colors.RESET}")
|
||||
else:
|
||||
print(result_str)
|
||||
|
||||
print(f"{Colors.BOLD}{'═' * 80}{Colors.RESET}\n")
|
||||
print(f"{Colors.GRAY}{line}{Colors.RESET}")
|
||||
|
||||
def print_autonomous_header(task):
|
||||
print(f"{Colors.BOLD}Task:{Colors.RESET} {task}")
|
||||
|
||||
Reference in New Issue
Block a user