""" Base configuration and utilities for LangChain agents in FinRyver """ import os from typing import Optional from langchain_openai import ChatOpenAI from langchain.agents import AgentExecutor, create_openai_tools_agent from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder from langchain.tools import Tool from langchain_core.messages import HumanMessage, SystemMessage import logging # Load environment variables try: from dotenv import load_dotenv load_dotenv() except ImportError: pass # dotenv is optional logger = logging.getLogger(__name__) class FinRyverAgentConfig: """Configuration class for FinRyver agents""" def __init__(self): self.openrouter_api_key = os.getenv("OPENROUTER_API_KEY") self.model_name = os.getenv("AGENT_MODEL", "gpt-3.5-turbo") self.temperature = float(os.getenv("AGENT_TEMPERATURE", "0.1")) self.max_tokens = int(os.getenv("AGENT_MAX_TOKENS", "2000")) def get_llm(self) -> ChatOpenAI: """Get configured LLM instance""" if not self.openrouter_api_key: logger.warning("OPENROUTER_API_KEY not found. Agent functionality may be limited.") return None return ChatOpenAI( api_key=self.openrouter_api_key, base_url="https://openrouter.ai/api/v1", model=self.model_name, temperature=self.temperature, max_tokens=self.max_tokens ) def create_financial_agent_prompt(role: str, goal: str, context: str = "") -> ChatPromptTemplate: """Create a standardized prompt template for financial agents""" system_message = f""" You are a {role} working with financial data analysis and reporting. Your primary goal: {goal} Context: {context} You have access to various tools to help you analyze financial data, generate reports, and ensure compliance with accounting standards. Always provide clear, accurate, and professional responses. When working with financial data: - Ensure all calculations are accurate - Follow GAAP/IFRS standards where applicable - Provide clear explanations for your analysis - Flag any anomalies or inconsistencies - Always validate data before proceeding If you need clarification or additional information, ask specific questions. """ return ChatPromptTemplate.from_messages([ ("system", system_message), MessagesPlaceholder(variable_name="chat_history", optional=True), ("human", "{input}"), MessagesPlaceholder(variable_name="agent_scratchpad") ]) def create_agent_executor( role: str, goal: str, tools: list, context: str = "", llm: Optional[ChatOpenAI] = None ) -> AgentExecutor: """Create a configured agent executor""" if llm is None: config = FinRyverAgentConfig() llm = config.get_llm() if llm is None: raise ValueError("LLM configuration failed. Check your API keys.") prompt = create_financial_agent_prompt(role, goal, context) agent = create_openai_tools_agent( llm=llm, tools=tools, prompt=prompt ) return AgentExecutor( agent=agent, tools=tools, verbose=True, max_iterations=5, early_stopping_method="generate" )