70 lines
2.5 KiB
Python
70 lines
2.5 KiB
Python
from typing import Dict, Union
|
|
from langchain_core.tools import tool
|
|
from rich.console import Console
|
|
from rich.panel import Panel
|
|
from rich.prompt import Confirm
|
|
from ra_aid.tools.memory import _global_memory
|
|
from ra_aid.proc.interactive import run_interactive_command
|
|
from ra_aid.text.processing import truncate_output
|
|
from ra_aid.console.cowboy_messages import get_cowboy_message
|
|
|
|
console = Console()
|
|
|
|
@tool
|
|
def run_shell_command(command: str) -> Dict[str, Union[str, int, bool]]:
|
|
"""Execute a shell command and return its output.
|
|
|
|
Assume these are available:
|
|
- rg
|
|
- tree
|
|
- standard linux utilities
|
|
|
|
Important notes:
|
|
1. Try to constrain/limit the output. Output processing is expensive, and infinite/looping output will cause us to fail.
|
|
2. When using commands like 'find', 'grep', or similar recursive search tools, always exclude common
|
|
development directories and files that can cause excessive output or slow performance:
|
|
- Version control: .git
|
|
- Dependencies: node_modules, vendor, .venv
|
|
- Cache: __pycache__, .cache
|
|
- Build: dist, build
|
|
- Environment: .env, venv, env
|
|
- IDE: .idea, .vscode
|
|
3. Avoid doing recursive lists, finds, etc. that could be slow and have a ton of output. Likewise, avoid flags like '-l' that needlessly increase the output. But if you really need to, you can.
|
|
"""
|
|
# Check if we need approval
|
|
cowboy_mode = _global_memory.get('config', {}).get('cowboy_mode', False)
|
|
|
|
if cowboy_mode:
|
|
console.print("")
|
|
console.print(" " + get_cowboy_message())
|
|
console.print("")
|
|
|
|
# Show just the command in a simple panel
|
|
console.print(Panel(command, title="🐚 Shell", border_style="bright_yellow"))
|
|
|
|
if not cowboy_mode:
|
|
if not Confirm.ask("Execute this command?", default=True):
|
|
return {
|
|
"output": "Command execution cancelled by user",
|
|
"return_code": 1,
|
|
"success": False
|
|
}
|
|
|
|
try:
|
|
print()
|
|
output, return_code = run_interactive_command(['/bin/bash', '-c', command])
|
|
print()
|
|
return {
|
|
"output": truncate_output(output.decode()) if output else "",
|
|
"return_code": return_code,
|
|
"success": return_code == 0
|
|
}
|
|
except Exception as e:
|
|
print()
|
|
console.print(Panel(str(e), title="❌ Error", border_style="red"))
|
|
return {
|
|
"output": str(e),
|
|
"return_code": 1,
|
|
"success": False
|
|
}
|