import logging from abc import ABC, abstractmethod from typing import Any from .schemas import TeamRole from .state import AgentState logger = logging.getLogger("agents") class BaseAgent(ABC): """ Abstract Base Class for all agents (Specialists and Auxiliary). Enforces a strict `.process()` interface for LangGraph nodes. """ role: TeamRole | None = None @abstractmethod async def process(self, state: AgentState) -> dict[str, Any]: """ Process the given state and return updates to be merged into the AgentState. Should handle its own LLM interactions, prompts, and schema validation. """ pass def get_context_for_prompt(self, state: AgentState) -> str: """Utility for extracting the combined readable context for prompts.""" parts = [] if state.get("context"): parts.append(state["context"]) if state.get("prd_context"): prd = state["prd_context"] # Formatting logic to render parts of the PRD context if needed # E.g., user stories, constraints. if isinstance(prd, dict) and "full_text" in prd: parts.append(prd["full_text"]) # Could also include RAG retrieval_context if applicable if state.get("retrieval_context"): parts.append("--- REFERENCE DOCUMENTS ---") parts.append(state["retrieval_context"]) return "\n\n".join(parts)