"""Tool router functions for hierarchical agent architecture. This module provides meta-tools that route tasks to specialized sub-agents. The main agent uses these routers instead of accessing all tools directly. """ import logging from typing import Optional from langchain_core.tools import tool logger = logging.getLogger(__name__) # Global sub-agent instances (set by create_agent) _chart_agent = None _data_agent = None _automation_agent = None _research_agent = None def set_chart_agent(agent): """Set the global chart sub-agent instance.""" global _chart_agent _chart_agent = agent def set_data_agent(agent): """Set the global data sub-agent instance.""" global _data_agent _data_agent = agent def set_automation_agent(agent): """Set the global automation sub-agent instance.""" global _automation_agent _automation_agent = agent def set_research_agent(agent): """Set the global research sub-agent instance.""" global _research_agent _research_agent = agent @tool async def use_chart_analysis(task: str) -> str: """Analyze charts, compute indicators, execute Python code, and create visualizations. This tool delegates to a specialized chart analysis agent that has access to: - Chart data retrieval (get_chart_data) - Python execution environment with pandas, numpy, matplotlib, talib - Technical indicator tools (add/remove indicators, search indicators) - Shape drawing tools (create/update/delete shapes on charts) Use this when the user wants to: - Analyze price action or patterns - Calculate technical indicators (RSI, MACD, Bollinger Bands, etc.) - Execute custom Python analysis on OHLCV data - Generate charts and visualizations - Draw trendlines, support/resistance, or other shapes - Perform statistical analysis on market data Args: task: Detailed description of the chart analysis task. Include: - What to analyze (which symbol, timeframe if different from current) - What indicators or calculations to perform - What visualizations to create - Any specific questions to answer Returns: The chart agent's analysis results, including computed values, plot URLs if visualizations were created, and interpretation. Examples: - "Calculate RSI(14) for the current chart and tell me if it's overbought" - "Draw a trendline connecting the last 3 swing lows" - "Compute Bollinger Bands (20, 2) and create a chart showing price vs bands" - "Analyze the last 100 bars and identify key support/resistance levels" - "Execute Python: calculate correlation between BTC and ETH over the last 30 days" """ if not _chart_agent: return "Error: Chart analysis agent not initialized" logger.info(f"Routing to chart agent: {task[:100]}...") result = await _chart_agent.execute(task) return result @tool async def use_data_access(task: str) -> str: """Search for symbols and retrieve market data from exchanges. This tool delegates to a specialized data access agent that has access to: - Symbol search across multiple exchanges - Historical OHLCV data retrieval - Symbol metadata and info - Available data sources and exchanges Use this when the user wants to: - Search for a trading symbol or ticker - Get historical price data - Find out what exchanges support a symbol - Retrieve symbol metadata (price scale, supported resolutions, etc.) - Check what data sources are available Args: task: Detailed description of the data access task. Include: - What symbol or instrument to search for - What data to retrieve (time range, resolution) - What metadata is needed Returns: The data agent's response with requested symbols, data, or metadata. Examples: - "Search for Bitcoin symbols on Binance" - "Get the last 100 hours of BTC/USDT 1-hour data from Binance" - "Find all symbols matching 'ETH' on all exchanges" - "Get detailed info about symbol BTC/USDT on Binance" - "List all available data sources" """ if not _data_agent: return "Error: Data access agent not initialized" logger.info(f"Routing to data agent: {task[:100]}...") result = await _data_agent.execute(task) return result @tool async def use_automation(task: str) -> str: """Schedule recurring tasks, create triggers, and manage automation. This tool delegates to a specialized automation agent that has access to: - Scheduled agent prompts (cron and interval-based) - One-time agent prompt execution - Trigger management (list, cancel scheduled jobs) - System stats and monitoring Use this when the user wants to: - Schedule a recurring task (hourly, daily, weekly, etc.) - Run a one-time background analysis - Set up automated monitoring or alerts - List or cancel existing scheduled tasks - Check trigger system status Args: task: Detailed description of the automation task. Include: - What should happen (what analysis or action) - When it should happen (schedule, frequency) - Any priorities or conditions Returns: The automation agent's response with job IDs, confirmation, or status information. Examples: - "Schedule a task to check BTC price every 5 minutes" - "Run a one-time analysis of ETH volume in the background" - "Set up a daily report at 9 AM with market summary" - "Show me all my scheduled tasks" - "Cancel the hourly BTC monitor job" """ if not _automation_agent: return "Error: Automation agent not initialized" logger.info(f"Routing to automation agent: {task[:100]}...") result = await _automation_agent.execute(task) return result @tool async def use_research(task: str) -> str: """Search the web, academic papers, and external APIs for information. This tool delegates to a specialized research agent that has access to: - Web search (DuckDuckGo) - Academic paper search (arXiv) - Wikipedia lookup - HTTP requests to public APIs Use this when the user wants to: - Search for current news or events - Find academic papers on trading strategies - Look up financial concepts or terms - Fetch data from external public APIs - Research market trends or sentiment Args: task: Detailed description of the research task. Include: - What information to find - What sources to search (web, arxiv, wikipedia, APIs) - What to focus on or filter Returns: The research agent's findings with sources, summaries, and links. Examples: - "Search arXiv for papers on reinforcement learning for trading" - "Look up 'technical analysis' on Wikipedia" - "Search the web for latest Ethereum news" - "Fetch current BTC price from CoinGecko API" - "Find recent papers on market microstructure" """ if not _research_agent: return "Error: Research agent not initialized" logger.info(f"Routing to research agent: {task[:100]}...") result = await _research_agent.execute(task) return result # Export router tools ROUTER_TOOLS = [ use_chart_analysis, use_data_access, use_automation, use_research ]