Files
maxclaw_agent/main.py
T

190 lines
6.7 KiB
Python

#!/usr/bin/env python3
"""
MaxClaw Agent - A configurable agent harness using DeepAgents
Supports multiple LLM providers via LangChain's init_chat_model
Enhanced with unified provider tools and custom tools
"""
import os
import sys
from typing import Optional, List
from deepagents import create_deep_agent
from langchain.chat_models import init_chat_model
from langchain_core.messages import HumanMessage, SystemMessage
from langchain.tools import Tool
# Import custom tools
try:
from tools import get_proxmox_tools
from tools.provider_tools import get_provider_tools, get_all_provider_tools
TOOLS_AVAILABLE = True
except ImportError:
TOOLS_AVAILABLE = False
print("Warning: Custom tools not available. Install required dependencies.")
def load_model_from_config():
"""
Load the LLM model based on configuration.
Configuration can come from environment variables or a config file.
For simplicity, we'll use environment variables.
Expected environment variables:
- OPENAI_API_KEY: For OpenAI models
- OLLAMA_BASE_URL: For Ollama (e.g., https://ollama.solarpi.net)
- MODEL_PROVIDER: One of "openai", "ollama", "openrouter", etc.
- MODEL_NAME: The specific model name (e.g., "gpt-4o", "gemma2:9b")
"""
provider = os.getenv("MODEL_PROVIDER", "openai").lower()
model_name = os.getenv("MODEL_NAME", "gpt-4o")
# Configure based on provider
if provider == "openai":
# Uses OPENAI_API_KEY from environment
return init_chat_model(f"openai:{model_name}")
elif provider == "ollama":
# For Ollama, we need to specify the base URL
base_url = os.getenv("OLLAMA_BASE_URL", "http://localhost:11434")
return init_chat_model(f"ollama:{model_name}", base_url=base_url)
elif provider == "openrouter":
# For OpenRouter, we need OPENROUTER_API_KEY and optionally base URL
# Note: LangChain's init_chat_model for openrouter might require specific setup
# As of now, we assume it's supported via openai-compatible API
base_url = os.getenv("OPENROUTER_BASE_URL", "https://openrouter.ai/api/v1")
api_key = os.getenv("OPENROUTER_API_KEY")
if not api_key:
raise ValueError("OPENROUTER_API_KEY environment variable is required for OpenRouter")
# Using openai-compatible API
return init_chat_model(
f"openai:{model_name}",
base_url=base_url,
api_key=api_key
)
else:
# Fallback to openai for unknown providers (or add more as needed)
return init_chat_model(f"openai:{model_name}")
def get_custom_tools() -> List[Tool]:
"""
Get custom tools for the MaxClaw agent
Returns:
List of custom tools
"""
custom_tools = []
if not TOOLS_AVAILABLE:
return custom_tools
# Add Proxmox tools if configured
proxmox_host = os.getenv("PROXMOX_HOST")
if proxmox_host:
proxmox_user = os.getenv("PROXMOX_USER", "root")
proxmox_password = os.getenv("PROXMOX_PASSWORD")
proxmox_token = os.getenv("PROXMOX_TOKEN")
try:
proxmox_tools = get_proxmox_tools(
host=proxmox_host,
user=proxmox_user,
password=proxmox_password,
api_token=proxmox_token
)
custom_tools.extend(proxmox_tools)
print(f"✅ Added {len(proxmox_tools)} Proxmox tools")
except Exception as e:
print(f"⚠️ Could not load Proxmox tools: {e}")
# Add unified provider tools for all configured providers
try:
provider_tools = get_all_provider_tools()
custom_tools.extend(provider_tools)
print(f"✅ Added {len(provider_tools)} provider tools")
except Exception as e:
print(f"⚠️ Could not load provider tools: {e}")
return custom_tools
def create_maxclaw_agent(system_prompt: Optional[str] = None):
"""
Create and return a DeepAgent instance with configurable model.
"""
if system_prompt is None:
system_prompt = """You are MaxClaw, a helpful AI agent that can plan, use tools,
manage context, and delegate to subagents. You are designed to be configurable
to work with various LLM providers.
You have access to:
1. Unified provider tools for managing LLM providers (list models, test connections, etc.)
2. Custom tools for managing Proxmox virtual machines
3. Standard DeepAgents tools (planning, filesystem, shell, subagents)
Use these tools when asked about:
- LLM provider management (listing models, testing connections, setting defaults)
- System administration and virtualization
- AI model management and configuration"""
model = load_model_from_config()
# Get custom tools
custom_tools = get_custom_tools()
# Create the agent with custom tools
agent = create_deep_agent(
model=model,
tools=custom_tools, # Add custom tools to the agent
system_prompt=system_prompt
)
return agent
def main():
"""
Main entry point for the MaxClaw agent.
"""
print("🚀 Initializing MaxClaw Agent...")
try:
agent = create_maxclaw_agent()
print("✅ Agent initialized successfully!")
# Show available tools
print("\n🔧 Available tools:")
print(" • Provider tools: list models, test connections, set defaults")
print(" • Proxmox tools: manage VMs, snapshots, resources")
print(" • Standard tools: planning, filesystem, shell, subagents")
print("\n💬 You can now interact with the agent. Type 'exit' to quit.")
print("💡 Try asking:")
print(" - 'List available models for my provider'")
print(" - 'Test connection to Ollama'")
print(" - 'Show me Proxmox VMs'")
print(" - 'What's the default model for OpenAI?'")
while True:
user_input = input("\n👤 You: ").strip()
if user_input.lower() in ['exit', 'quit']:
print("👋 Goodbye!")
break
if not user_input:
continue
# Invoke the agent
try:
result = agent.invoke({"messages": [HumanMessage(content=user_input)]})
# Extract the AI's response
ai_message = result["messages"][-1]
print(f"\n🤖 MaxClaw: {ai_message.content}")
except Exception as e:
print(f"\n❌ Error: {str(e)}")
except Exception as e:
print(f"❌ Failed to initialize agent: {str(e)}")
sys.exit(1)
if __name__ == "__main__":
main()