"""Researcher Agent — gathers information and analyzes topics. Handles steps that involve research, analysis, or information gathering. Uses the LLM to generate insights and summaries. """ from __future__ import annotations import logging from typing import Any from .agent_base import BaseAgent from ..memory.goal_memory import Goal logger = logging.getLogger(__name__) class ResearcherAgent(BaseAgent): """Researches topics and gathers information for goal steps.""" def __init__(self, goal_memory, persistent_memory=None, generate_fn=None): super().__init__( name="researcher", role="Researcher", description="Gathers information, analyzes topics, and generates insights", goal_memory=goal_memory, persistent_memory=persistent_memory, generate_fn=generate_fn, poll_interval_s=3.0, ) def _can_handle(self, goal: Goal) -> bool: """Researcher handles goals related to research/analysis.""" keywords = ["research", "analyze", "investigate", "study", "learn", "understand", "explore", "gather", "find", "search", "compare", "evaluate"] text = (goal.title + " " + goal.description).lower() return any(kw in text for kw in keywords) def process_goal(self, goal: Goal) -> dict[str, Any]: """Execute a research step.""" if goal.current_step >= len(goal.steps): return {"success": True, "output": "No more steps"} step = goal.steps[goal.current_step] prompt = ( f"You are a research agent. Execute this step:\n" f"Goal: {goal.title}\n" f"Step: {step['title']}\n" f"Description: {step['description']}\n" f"Research and provide a concise summary of findings.\n" ) response = self._generate(prompt) # Store findings in persistent memory if self.persistent_memory and response: self.persistent_memory.add_episodic( "research", f"Research for '{goal.title}': {response[:200]}", importance=0.7, tags=["research", goal.title[:20]] ) return {"success": True, "output": response[:200]}