first commit
This commit is contained in:
374
agent_mode.py
Normal file
374
agent_mode.py
Normal file
@@ -0,0 +1,374 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Agent Mode for DarkHal 2.0
|
||||
Integrates Hal's unrestricted capabilities into the chat interface
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import json
|
||||
import asyncio
|
||||
import threading
|
||||
from typing import Optional, Callable, Dict, Any, List
|
||||
from dataclasses import dataclass
|
||||
import tkinter as tk
|
||||
from tkinter import messagebox
|
||||
|
||||
# Add agent_dhal to path
|
||||
sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'agent_dhal'))
|
||||
|
||||
# Import Hal components
|
||||
try:
|
||||
from agent_dhal.hal import create_dhal, DhalConfig, HalModelClient
|
||||
except ImportError:
|
||||
# Fallback for testing
|
||||
create_dhal = None
|
||||
DhalConfig = None
|
||||
HalModelClient = None
|
||||
print("[Agent Mode] Warning: Could not import Hal components")
|
||||
|
||||
|
||||
@dataclass
|
||||
class AgentModeConfig:
|
||||
"""Configuration for agent mode"""
|
||||
enabled: bool = False
|
||||
allow_file_operations: bool = True
|
||||
allow_shell_commands: bool = True
|
||||
allow_system_control: bool = True # mouse, keyboard
|
||||
allow_elevated_commands: bool = False # sudo, admin powershell
|
||||
require_confirmation: bool = True # Ask before dangerous operations
|
||||
model_name: str = "gpt-4"
|
||||
|
||||
|
||||
class AgentModeHandler:
|
||||
"""Handles agent mode functionality for the chat interface"""
|
||||
|
||||
def __init__(self, output_callback: Callable[[str], None] = None):
|
||||
"""
|
||||
Initialize agent mode handler
|
||||
|
||||
Args:
|
||||
output_callback: Function to call with output text
|
||||
"""
|
||||
self.config = AgentModeConfig()
|
||||
self.output_callback = output_callback or print
|
||||
self.agent = None
|
||||
self.is_initialized = False
|
||||
self._init_lock = threading.Lock()
|
||||
|
||||
def initialize_agent(self, model_path: str = None) -> bool:
|
||||
"""
|
||||
Initialize the Hal agent
|
||||
|
||||
Args:
|
||||
model_path: Path to model file or model name
|
||||
|
||||
Returns:
|
||||
True if initialized successfully
|
||||
"""
|
||||
with self._init_lock:
|
||||
if self.is_initialized:
|
||||
return True
|
||||
|
||||
try:
|
||||
if not create_dhal:
|
||||
self.output_callback("[Agent Mode] Hal components not available\n")
|
||||
return False
|
||||
|
||||
# Configure agent based on settings
|
||||
config = DhalConfig(
|
||||
name="Hal",
|
||||
system_message=self._get_system_prompt(),
|
||||
model=model_path or "gpt-4",
|
||||
temperature=0.7,
|
||||
max_tokens=2000
|
||||
)
|
||||
|
||||
# Create model client
|
||||
model_client = HalModelClient(model_name=model_path or "gpt-4")
|
||||
|
||||
# Create agent
|
||||
self.agent = create_dhal(
|
||||
name="Hal",
|
||||
system_message=self._get_system_prompt(),
|
||||
model=model_path or "gpt-4",
|
||||
model_client=model_client
|
||||
)
|
||||
|
||||
self.is_initialized = True
|
||||
self.output_callback("[Agent Mode] Hal agent initialized successfully\n")
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
self.output_callback(f"[Agent Mode] Failed to initialize: {e}\n")
|
||||
return False
|
||||
|
||||
def _get_system_prompt(self) -> str:
|
||||
"""Generate system prompt based on current permissions"""
|
||||
prompt = """You are Hal, an advanced AI assistant with direct system access.
|
||||
You can execute commands and control the system based on user requests.
|
||||
|
||||
Available capabilities:"""
|
||||
|
||||
if self.config.allow_file_operations:
|
||||
prompt += "\n- Read, write, and list files"
|
||||
if self.config.allow_shell_commands:
|
||||
prompt += "\n- Execute shell commands (bash, PowerShell)"
|
||||
prompt += "\n- Run Python code"
|
||||
if self.config.allow_system_control:
|
||||
prompt += "\n- Control mouse and keyboard"
|
||||
prompt += "\n- Send keystrokes and type text"
|
||||
if self.config.allow_elevated_commands:
|
||||
prompt += "\n- Execute elevated/admin commands"
|
||||
|
||||
prompt += "\n\nAlways explain what you're doing before executing commands."
|
||||
|
||||
if self.config.require_confirmation:
|
||||
prompt += "\nWait for user confirmation before destructive operations."
|
||||
|
||||
return prompt
|
||||
|
||||
async def process_message_async(self, message: str) -> str:
|
||||
"""
|
||||
Process a message through the agent asynchronously
|
||||
|
||||
Args:
|
||||
message: User message to process
|
||||
|
||||
Returns:
|
||||
Agent response
|
||||
"""
|
||||
if not self.is_initialized:
|
||||
return "[Agent Mode] Not initialized. Please enable agent mode first."
|
||||
|
||||
try:
|
||||
# Get response from agent
|
||||
from agent_dhal.hal import MessageContext
|
||||
|
||||
# Create a mock context for standalone usage
|
||||
class MockContext:
|
||||
def __init__(self):
|
||||
self.agent_id = "user"
|
||||
|
||||
ctx = MockContext()
|
||||
|
||||
# Process message through agent
|
||||
response = await self.agent.handle_user_message(message, ctx)
|
||||
|
||||
return response
|
||||
|
||||
except Exception as e:
|
||||
return f"[Agent Mode] Error processing message: {e}"
|
||||
|
||||
def process_message(self, message: str) -> str:
|
||||
"""
|
||||
Process a message through the agent (synchronous wrapper)
|
||||
|
||||
Args:
|
||||
message: User message to process
|
||||
|
||||
Returns:
|
||||
Agent response
|
||||
"""
|
||||
# Run async function in new event loop
|
||||
loop = asyncio.new_event_loop()
|
||||
asyncio.set_event_loop(loop)
|
||||
try:
|
||||
return loop.run_until_complete(self.process_message_async(message))
|
||||
finally:
|
||||
loop.close()
|
||||
|
||||
def enable(self, model_path: str = None) -> bool:
|
||||
"""
|
||||
Enable agent mode
|
||||
|
||||
Args:
|
||||
model_path: Path to model or model name
|
||||
|
||||
Returns:
|
||||
True if enabled successfully
|
||||
"""
|
||||
if not self.is_initialized:
|
||||
if not self.initialize_agent(model_path):
|
||||
return False
|
||||
|
||||
self.config.enabled = True
|
||||
self.output_callback("[Agent Mode] ENABLED - Hal has full system access\n")
|
||||
self._show_capabilities()
|
||||
return True
|
||||
|
||||
def disable(self):
|
||||
"""Disable agent mode"""
|
||||
self.config.enabled = False
|
||||
self.output_callback("[Agent Mode] DISABLED - Normal chat mode\n")
|
||||
|
||||
def _show_capabilities(self):
|
||||
"""Show current capabilities to user"""
|
||||
caps = []
|
||||
if self.config.allow_file_operations:
|
||||
caps.append("• File operations (read/write/list)")
|
||||
if self.config.allow_shell_commands:
|
||||
caps.append("• Shell commands (bash/PowerShell/Python)")
|
||||
if self.config.allow_system_control:
|
||||
caps.append("• Mouse & keyboard control")
|
||||
if self.config.allow_elevated_commands:
|
||||
caps.append("• Elevated/admin commands")
|
||||
|
||||
if caps:
|
||||
self.output_callback("Enabled capabilities:\n" + "\n".join(caps) + "\n")
|
||||
|
||||
def update_config(self, **kwargs):
|
||||
"""Update configuration settings"""
|
||||
for key, value in kwargs.items():
|
||||
if hasattr(self.config, key):
|
||||
setattr(self.config, key, value)
|
||||
|
||||
# Reinitialize agent if needed
|
||||
if self.is_initialized:
|
||||
self.agent.update_config(system_message=self._get_system_prompt())
|
||||
|
||||
|
||||
class AgentModeUI:
|
||||
"""UI components for agent mode"""
|
||||
|
||||
def __init__(self, parent_frame: tk.Frame, handler: AgentModeHandler):
|
||||
"""
|
||||
Create agent mode UI controls
|
||||
|
||||
Args:
|
||||
parent_frame: Parent tkinter frame
|
||||
handler: AgentModeHandler instance
|
||||
"""
|
||||
self.handler = handler
|
||||
self.parent = parent_frame
|
||||
|
||||
# Create control frame
|
||||
self.control_frame = tk.LabelFrame(parent_frame, text="🤖 Agent Mode", relief=tk.RIDGE, borderwidth=2)
|
||||
self.control_frame.pack(fill=tk.X, padx=5, pady=5)
|
||||
|
||||
# Main toggle
|
||||
self.enabled_var = tk.BooleanVar(value=False)
|
||||
self.enable_check = tk.Checkbutton(
|
||||
self.control_frame,
|
||||
text="Enable Agent Mode (FULL SYSTEM ACCESS)",
|
||||
variable=self.enabled_var,
|
||||
command=self._toggle_agent_mode,
|
||||
font=('Arial', 10, 'bold'),
|
||||
fg='red'
|
||||
)
|
||||
self.enable_check.grid(row=0, column=0, columnspan=3, sticky=tk.W, padx=5, pady=5)
|
||||
|
||||
# Permission toggles
|
||||
self.file_ops_var = tk.BooleanVar(value=True)
|
||||
tk.Checkbutton(
|
||||
self.control_frame,
|
||||
text="File Operations",
|
||||
variable=self.file_ops_var,
|
||||
command=self._update_permissions
|
||||
).grid(row=1, column=0, sticky=tk.W, padx=20, pady=2)
|
||||
|
||||
self.shell_var = tk.BooleanVar(value=True)
|
||||
tk.Checkbutton(
|
||||
self.control_frame,
|
||||
text="Shell Commands",
|
||||
variable=self.shell_var,
|
||||
command=self._update_permissions
|
||||
).grid(row=1, column=1, sticky=tk.W, padx=20, pady=2)
|
||||
|
||||
self.system_var = tk.BooleanVar(value=True)
|
||||
tk.Checkbutton(
|
||||
self.control_frame,
|
||||
text="Mouse/Keyboard",
|
||||
variable=self.system_var,
|
||||
command=self._update_permissions
|
||||
).grid(row=1, column=2, sticky=tk.W, padx=20, pady=2)
|
||||
|
||||
self.elevated_var = tk.BooleanVar(value=False)
|
||||
tk.Checkbutton(
|
||||
self.control_frame,
|
||||
text="Elevated Commands (DANGEROUS)",
|
||||
variable=self.elevated_var,
|
||||
command=self._update_permissions,
|
||||
fg='orange'
|
||||
).grid(row=2, column=0, columnspan=2, sticky=tk.W, padx=20, pady=2)
|
||||
|
||||
self.confirm_var = tk.BooleanVar(value=True)
|
||||
tk.Checkbutton(
|
||||
self.control_frame,
|
||||
text="Require Confirmation",
|
||||
variable=self.confirm_var,
|
||||
command=self._update_permissions
|
||||
).grid(row=2, column=2, sticky=tk.W, padx=20, pady=2)
|
||||
|
||||
# Status label
|
||||
self.status_label = tk.Label(
|
||||
self.control_frame,
|
||||
text="Status: DISABLED",
|
||||
font=('Arial', 9),
|
||||
fg='gray'
|
||||
)
|
||||
self.status_label.grid(row=3, column=0, columnspan=3, pady=5)
|
||||
|
||||
def _toggle_agent_mode(self):
|
||||
"""Toggle agent mode on/off"""
|
||||
if self.enabled_var.get():
|
||||
# Show warning
|
||||
result = messagebox.askyesno(
|
||||
"⚠️ Enable Agent Mode",
|
||||
"WARNING: Agent mode gives the AI unrestricted access to:\n\n"
|
||||
"• Your file system\n"
|
||||
"• Shell commands\n"
|
||||
"• Mouse and keyboard control\n"
|
||||
"• System settings\n\n"
|
||||
"Only enable if you understand the risks.\n\n"
|
||||
"Continue?",
|
||||
icon='warning'
|
||||
)
|
||||
|
||||
if result:
|
||||
# Get model path from parent if available
|
||||
model_path = None
|
||||
if hasattr(self.parent.master, 'model_var'):
|
||||
model_path = self.parent.master.model_var.get()
|
||||
|
||||
if self.handler.enable(model_path):
|
||||
self.status_label.config(text="Status: ACTIVE", fg='red')
|
||||
self._update_permissions()
|
||||
else:
|
||||
self.enabled_var.set(False)
|
||||
messagebox.showerror("Error", "Failed to initialize agent mode")
|
||||
else:
|
||||
self.enabled_var.set(False)
|
||||
else:
|
||||
self.handler.disable()
|
||||
self.status_label.config(text="Status: DISABLED", fg='gray')
|
||||
|
||||
def _update_permissions(self):
|
||||
"""Update handler permissions based on UI settings"""
|
||||
self.handler.update_config(
|
||||
allow_file_operations=self.file_ops_var.get(),
|
||||
allow_shell_commands=self.shell_var.get(),
|
||||
allow_system_control=self.system_var.get(),
|
||||
allow_elevated_commands=self.elevated_var.get(),
|
||||
require_confirmation=self.confirm_var.get()
|
||||
)
|
||||
|
||||
def is_enabled(self) -> bool:
|
||||
"""Check if agent mode is enabled"""
|
||||
return self.enabled_var.get() and self.handler.config.enabled
|
||||
|
||||
|
||||
# Example usage
|
||||
if __name__ == "__main__":
|
||||
# Test agent mode
|
||||
handler = AgentModeHandler()
|
||||
|
||||
print("Testing agent mode...")
|
||||
if handler.enable():
|
||||
response = handler.process_message("List files in the current directory")
|
||||
print(f"Response: {response}")
|
||||
|
||||
response = handler.process_message("What's 2+2? Calculate with Python")
|
||||
print(f"Response: {response}")
|
||||
|
||||
handler.disable()
|
||||
Reference in New Issue
Block a user