Murder.Ai / game /llm_manager.py
Justxd22's picture
Implement AI Detective functionality with spectator mode and voice integration
86a82e2
import os
import google.generativeai as genai
from dotenv import load_dotenv
load_dotenv()
# Configure the API
API_KEY = os.getenv("GEMINI_API_KEY")
if API_KEY:
genai.configure(api_key=API_KEY)
class GeminiAgent:
def __init__(self, model_name="gemini-2.5-flash", system_instruction=None):
self.model_name = model_name
self.system_instruction = system_instruction
self.chat_session = None
self.history = []
if API_KEY:
self.model = genai.GenerativeModel(
model_name=model_name,
system_instruction=system_instruction
)
self.chat_session = self.model.start_chat(history=[])
else:
print("Warning: No GEMINI_API_KEY found. Agent will run in mock mode.")
self.model = None
def generate_response(self, user_input):
if not self.model:
return f"[MOCK] I received: {user_input}. (Set GEMINI_API_KEY to get real responses)"
try:
response = self.chat_session.send_message(user_input)
return response.text
except Exception as e:
return f"Error generating response: {str(e)}"
class LLMManager:
def __init__(self):
self.agents = {}
self.prompts = self._load_prompts()
def _load_prompts(self):
prompts = {}
prompt_dir = os.path.join(os.path.dirname(os.path.dirname(__file__)), "prompts")
for filename in ["murderer.txt", "witness.txt", "detective.txt", "alibi_agent.txt"]:
key = filename.replace(".txt", "")
try:
with open(os.path.join(prompt_dir, filename), "r") as f:
prompts[key] = f.read()
except FileNotFoundError:
print(f"Warning: Prompt file {filename} not found.")
prompts[key] = ""
return prompts
def create_agent(self, agent_id, role, context_data):
"""
Creates a new GeminiAgent for a specific character.
agent_id: Unique ID (e.g., 'suspect_1', 'detective')
role: 'murderer', 'witness', 'detective', 'alibi_agent'
context_data: Dict to fill in the prompt templates (name, victim_name, etc.)
"""
# Select base prompt template
if role == "murderer":
base_prompt = self.prompts.get("murderer", "")
elif role == "detective":
base_prompt = self.prompts.get("detective", "")
elif role == "alibi_agent":
base_prompt = self.prompts.get("alibi_agent", "")
else:
base_prompt = self.prompts.get("witness", "")
# Fill template
try:
system_instruction = base_prompt.format(**context_data)
except KeyError as e:
print(f"Warning: Missing key {e} in context data for {agent_id}")
system_instruction = base_prompt # Fallback
# Create agent
agent = GeminiAgent(system_instruction=system_instruction)
self.agents[agent_id] = agent
return agent
def get_agent(self, agent_id):
return self.agents.get(agent_id)
def get_response(self, agent_id, user_input):
agent = self.get_agent(agent_id)
if agent:
return agent.generate_response(user_input)
return "Error: Agent not found."
def get_response_raw(self, prompt):
"""Stateless generation for AI Detective logic."""
if not API_KEY:
return '{"thought": "Mock thought", "action": "chat", "suspect_id": "suspect_1", "message": "Hello"}'
try:
model = genai.GenerativeModel('gemini-2.5-flash')
response = model.generate_content(prompt)
return response.text
except Exception as e:
return f"Error: {str(e)}"