v3_ai_assistant / py /agents /profile_settings.py
Julian Vanecek
Initial commit: AI Assistant Multi-Agent System for HuggingFace Spaces
bb80caa
"""
Profile Settings Agent using LangChain
"""
import json
import logging
from typing import Dict, List, Optional, Any
from pathlib import Path
from agents.base_agent import BaseAgent
from langchain.tools import tool
from pydantic import BaseModel, Field
from tools import agent_tools
logger = logging.getLogger(__name__)
# Pydantic models for structured tools
class PreferenceSetting(BaseModel):
"""Model for preference updates."""
setting_name: str = Field(description="Name of the setting to update")
new_value: str = Field(description="New value for the setting")
class NotificationSetting(BaseModel):
"""Model for notification settings."""
email_updates: Optional[bool] = Field(None, description="Enable email updates")
system_alerts: Optional[bool] = Field(None, description="Enable system alerts")
newsletter: Optional[bool] = Field(None, description="Subscribe to newsletter")
class ProfileSettingsAgent(BaseAgent):
"""Profile settings agent using LangChain tools."""
def __init__(self, llm: Optional[Any] = None):
# Initialize base agent with slightly higher temperature for more natural responses
super().__init__(agent_id="profile_settings", llm=llm, temperature=0.3)
def _custom_init(self, **kwargs):
"""Custom initialization for profile settings."""
# Initialize dummy profile database
self.profile_db = self._init_profile_db()
# Track pending changes
self.pending_changes = {}
self.awaiting_confirmation = False
def _init_profile_db(self) -> Dict:
"""Initialize dummy profile database."""
db_path = Path(__file__).parent.parent / "data" / "profiles.json"
if db_path.exists():
with open(db_path, 'r') as f:
return json.load(f)
# Default profile
return {
"users": {
"default_user": {
"name": "Default User",
"email": "user@example.com",
"preferences": {
"default_product": "harmony",
"default_version": "1.8",
"preferred_model": "gpt-4o",
"temperature": 0.0,
"max_tokens": 4000,
"theme": "light",
"language": "en"
},
"notifications": {
"email_updates": True,
"system_alerts": True,
"newsletter": False
}
}
}
}
def _create_tools(self) -> List:
"""Create tools for profile management."""
tools = []
# Tool to view profile
@tool
def view_profile() -> str:
"""View current user profile and settings."""
# Mock implementation - just return example data
return """**Your Current Profile:**
**Name:** John Doe
**Email:** john.doe@example.com
**Preferences:**
- Default Product: harmony
- Default Version: 1.8
- Preferred Model: gpt-4o
- Temperature: 0.0
- Max Tokens: 4000
- Theme: light
- Language: en
**Notification Settings:**
- Email Updates: Enabled
- System Alerts: Enabled
- Newsletter: Disabled"""
tools.append(view_profile)
# Tool to update preferences
@tool
def update_preference(setting_name: str, new_value: str) -> str:
"""Update a user preference setting. Requires confirmation."""
# Mock implementation - accept any setting
return f"I've updated your {setting_name} to '{new_value}'. Change applied successfully! (mock)"
tools.append(update_preference)
# Tool to update notifications
@tool
def update_notifications(email_updates: Optional[bool] = None,
system_alerts: Optional[bool] = None,
newsletter: Optional[bool] = None) -> str:
"""Update notification settings. Requires confirmation."""
changes = []
if email_updates is not None:
changes.append(f"Email updates: {'Enabled' if email_updates else 'Disabled'}")
if system_alerts is not None:
changes.append(f"System alerts: {'Enabled' if system_alerts else 'Disabled'}")
if newsletter is not None:
changes.append(f"Newsletter: {'Enabled' if newsletter else 'Disabled'}")
if not changes:
return "No changes specified."
# Mock response
return f"Updated notification settings:\n" + "\n".join(f" - {c}" for c in changes) + "\n\nChanges applied successfully! (mock)"
tools.append(update_notifications)
# Add switching tools for all other agents
tools.extend(agent_tools.create_switching_tools_for_agent(self.agent_id))
return tools
def _get_system_prompt(self) -> str:
"""Get the system prompt for profile settings agent."""
# Build tool descriptions and switching agents
tool_descriptions, switching_agents = self._build_tool_descriptions_and_agents()
return f"""You are a basic profile settings agent. You handle user profile and preference updates.
What you do:
- View profile settings
- Update any setting when asked (all updates are mock)
- Transfer to other agents when needed
Transfer immediately for:
- Documentation/how-to questions → switch_to_document_reader
- Technical questions → switch_to_document_reader
- Network configuration → switch_to_network_config
- Other non-settings questions → appropriate agent
CRITICAL Tool Usage:
- To use a tool, you must CALL it properly, not just write its name
- When switching agents, ONLY use the switching tool - no additional text
- The tool invocation format is handled by the system - just use the tool normally
Keep responses simple and always include "(mock)" for changes.
Available tools:
{chr(10).join(tool_descriptions)}"""
def _enhance_response(self, response: Dict[str, Any], result: Dict[str, Any]):
"""Add pending changes status to response."""
# Add pending changes status
response["has_pending_changes"] = len(self.pending_changes) > 0