827 lines
30 KiB
Python
827 lines
30 KiB
Python
"""
|
|
Tool Registry - Single Source of Truth for All Trading Tools
|
|
|
|
This registry defines ALL tools with their complete metadata:
|
|
- Which agents use them
|
|
- Which vendors provide them (with actual function references)
|
|
- Vendor priority for fallback
|
|
- Function signatures
|
|
|
|
Adding a new tool: Just add one entry here, everything else is auto-generated.
|
|
"""
|
|
|
|
from typing import Any, Dict, List, Optional
|
|
|
|
from tradingagents.dataflows.alpha_vantage import (
|
|
get_balance_sheet as get_alpha_vantage_balance_sheet,
|
|
)
|
|
from tradingagents.dataflows.alpha_vantage import (
|
|
get_cashflow as get_alpha_vantage_cashflow,
|
|
)
|
|
from tradingagents.dataflows.alpha_vantage import (
|
|
get_fundamentals as get_alpha_vantage_fundamentals,
|
|
)
|
|
from tradingagents.dataflows.alpha_vantage import (
|
|
get_income_statement as get_alpha_vantage_income_statement,
|
|
)
|
|
from tradingagents.dataflows.alpha_vantage import (
|
|
get_insider_sentiment as get_alpha_vantage_insider_sentiment,
|
|
)
|
|
from tradingagents.dataflows.alpha_vantage import (
|
|
get_stock as get_alpha_vantage_stock,
|
|
)
|
|
from tradingagents.dataflows.alpha_vantage import (
|
|
get_top_gainers_losers as get_alpha_vantage_movers,
|
|
)
|
|
from tradingagents.dataflows.alpha_vantage_analysts import (
|
|
get_alpha_vantage_analyst_changes,
|
|
)
|
|
from tradingagents.dataflows.alpha_vantage_volume import (
|
|
get_alpha_vantage_unusual_volume,
|
|
get_cached_average_volume,
|
|
get_cached_average_volume_batch,
|
|
)
|
|
from tradingagents.dataflows.finnhub_api import (
|
|
get_earnings_calendar as get_finnhub_earnings_calendar,
|
|
)
|
|
from tradingagents.dataflows.finnhub_api import (
|
|
get_ipo_calendar as get_finnhub_ipo_calendar,
|
|
)
|
|
from tradingagents.dataflows.finnhub_api import (
|
|
get_recommendation_trends as get_finnhub_recommendation_trends,
|
|
)
|
|
from tradingagents.dataflows.finviz_scraper import (
|
|
get_finviz_insider_buying,
|
|
get_finviz_short_interest,
|
|
)
|
|
from tradingagents.dataflows.openai import (
|
|
get_fundamentals_openai,
|
|
get_global_news_openai,
|
|
get_stock_news_openai,
|
|
)
|
|
from tradingagents.dataflows.reddit_api import (
|
|
get_reddit_discussions,
|
|
get_reddit_news,
|
|
get_reddit_trending_tickers,
|
|
)
|
|
from tradingagents.dataflows.reddit_api import (
|
|
get_reddit_global_news as get_reddit_api_global_news,
|
|
)
|
|
from tradingagents.dataflows.tradier_api import (
|
|
get_tradier_unusual_options,
|
|
)
|
|
from tradingagents.dataflows.twitter_data import (
|
|
get_tweets as get_twitter_tweets,
|
|
)
|
|
from tradingagents.dataflows.y_finance import (
|
|
get_balance_sheet as get_yfinance_balance_sheet,
|
|
)
|
|
from tradingagents.dataflows.y_finance import (
|
|
get_cashflow as get_yfinance_cashflow,
|
|
)
|
|
from tradingagents.dataflows.y_finance import (
|
|
get_fundamentals as get_yfinance_fundamentals,
|
|
)
|
|
from tradingagents.dataflows.y_finance import (
|
|
get_income_statement as get_yfinance_income_statement,
|
|
)
|
|
from tradingagents.dataflows.y_finance import (
|
|
get_insider_transactions as get_yfinance_insider_transactions,
|
|
)
|
|
from tradingagents.dataflows.y_finance import (
|
|
get_options_activity as get_yfinance_options_activity,
|
|
)
|
|
|
|
# Import all vendor implementations
|
|
from tradingagents.dataflows.y_finance import (
|
|
get_technical_analysis,
|
|
get_YFin_data_online,
|
|
)
|
|
from tradingagents.dataflows.y_finance import (
|
|
validate_ticker as validate_ticker_yfinance,
|
|
)
|
|
from tradingagents.dataflows.y_finance import (
|
|
validate_tickers_batch as validate_tickers_batch_yfinance,
|
|
)
|
|
from tradingagents.utils.logger import get_logger
|
|
|
|
logger = get_logger(__name__)
|
|
|
|
# ============================================================================
|
|
# TOOL REGISTRY - SINGLE SOURCE OF TRUTH
|
|
# ============================================================================
|
|
|
|
TOOL_REGISTRY: Dict[str, Dict[str, Any]] = {
|
|
# ========== CORE STOCK APIs ==========
|
|
"get_stock_data": {
|
|
"description": "Retrieve stock price data (OHLCV) for a given ticker symbol",
|
|
"category": "core_stock_apis",
|
|
"agents": ["market"],
|
|
"vendors": {
|
|
"yfinance": get_YFin_data_online,
|
|
"alpha_vantage": get_alpha_vantage_stock,
|
|
},
|
|
"vendor_priority": ["yfinance"],
|
|
"parameters": {
|
|
"symbol": {"type": "str", "description": "Ticker symbol of the company (e.g., AAPL)"},
|
|
"start_date": {"type": "str", "description": "Start date in yyyy-mm-dd format"},
|
|
"end_date": {"type": "str", "description": "End date in yyyy-mm-dd format"},
|
|
},
|
|
"returns": "str: Formatted dataframe containing stock price data",
|
|
},
|
|
"validate_ticker": {
|
|
"description": "Validate if a ticker symbol exists and is tradeable",
|
|
"category": "core_stock_apis",
|
|
"agents": [],
|
|
"vendors": {
|
|
"yfinance": validate_ticker_yfinance,
|
|
},
|
|
"vendor_priority": ["yfinance"],
|
|
"parameters": {
|
|
"symbol": {"type": "str", "description": "Ticker symbol to validate"},
|
|
},
|
|
"returns": "bool: True if valid, False otherwise",
|
|
},
|
|
"validate_tickers_batch": {
|
|
"description": "Validate multiple ticker symbols using Yahoo Finance quote endpoint",
|
|
"category": "core_stock_apis",
|
|
"agents": [],
|
|
"vendors": {
|
|
"yfinance": validate_tickers_batch_yfinance,
|
|
},
|
|
"vendor_priority": ["yfinance"],
|
|
"parameters": {
|
|
"symbols": {"type": "list[str]", "description": "Ticker symbols to validate"},
|
|
},
|
|
"returns": "dict: valid/invalid ticker lists",
|
|
},
|
|
"get_average_volume": {
|
|
"description": "Get average trading volume over a recent window (cached, with fallback download)",
|
|
"category": "core_stock_apis",
|
|
"agents": [],
|
|
"vendors": {
|
|
"volume_cache": get_cached_average_volume,
|
|
},
|
|
"vendor_priority": ["volume_cache"],
|
|
"parameters": {
|
|
"symbol": {"type": "str", "description": "Ticker symbol"},
|
|
"lookback_days": {"type": "int", "description": "Days to average", "default": 20},
|
|
"curr_date": {
|
|
"type": "str",
|
|
"description": "Current date, YYYY-mm-dd",
|
|
"default": None,
|
|
},
|
|
"cache_key": {"type": "str", "description": "Cache key/universe", "default": "default"},
|
|
"fallback_download": {
|
|
"type": "bool",
|
|
"description": "Download if cache missing",
|
|
"default": True,
|
|
},
|
|
},
|
|
"returns": "dict: average and latest volume metadata",
|
|
},
|
|
"get_average_volume_batch": {
|
|
"description": "Get average trading volumes for multiple tickers using cached data",
|
|
"category": "core_stock_apis",
|
|
"agents": [],
|
|
"vendors": {
|
|
"volume_cache": get_cached_average_volume_batch,
|
|
},
|
|
"vendor_priority": ["volume_cache"],
|
|
"parameters": {
|
|
"symbols": {"type": "list[str]", "description": "Ticker symbols"},
|
|
"lookback_days": {"type": "int", "description": "Days to average", "default": 20},
|
|
"curr_date": {
|
|
"type": "str",
|
|
"description": "Current date, YYYY-mm-dd",
|
|
"default": None,
|
|
},
|
|
"cache_key": {"type": "str", "description": "Cache key/universe", "default": "default"},
|
|
"fallback_download": {
|
|
"type": "bool",
|
|
"description": "Download if cache missing",
|
|
"default": True,
|
|
},
|
|
},
|
|
"returns": "dict: mapping of ticker to volume metadata",
|
|
},
|
|
# ========== TECHNICAL INDICATORS ==========
|
|
# "get_indicators": {
|
|
# "description": "Get concise technical analysis with signals, trends, and key indicator interpretations",
|
|
# "category": "technical_indicators",
|
|
# "agents": ["market"],
|
|
# "vendors": {
|
|
# "yfinance": get_technical_analysis,
|
|
# },
|
|
# "vendor_priority": ["yfinance"],
|
|
# "parameters": {
|
|
# "symbol": {"type": "str", "description": "Ticker symbol"},
|
|
# "curr_date": {"type": "str", "description": "Current trading date, YYYY-mm-dd"},
|
|
# },
|
|
# "returns": "str: Concise analysis with RSI signals, MACD crossovers, MA trends, Bollinger position, and ATR volatility",
|
|
# },
|
|
"get_indicators": {
|
|
"description": "Get concise technical analysis with signals, trends, and key indicator interpretations",
|
|
"category": "technical_indicators",
|
|
"agents": ["market"],
|
|
"vendors": {
|
|
"yfinance": get_technical_analysis,
|
|
},
|
|
"vendor_priority": ["yfinance"],
|
|
"parameters": {
|
|
"symbol": {"type": "str", "description": "Ticker symbol"},
|
|
"curr_date": {"type": "str", "description": "Current trading date, YYYY-mm-dd"},
|
|
},
|
|
"returns": "str: Concise analysis with RSI signals, MACD crossovers, MA trends, Bollinger position, and ATR volatility",
|
|
},
|
|
# ========== FUNDAMENTAL DATA ==========
|
|
"get_fundamentals": {
|
|
"description": "Retrieve comprehensive fundamental data for a ticker",
|
|
"category": "fundamental_data",
|
|
"agents": ["fundamentals"],
|
|
"vendors": {
|
|
"yfinance": get_yfinance_fundamentals,
|
|
"alpha_vantage": get_alpha_vantage_fundamentals,
|
|
"openai": get_fundamentals_openai,
|
|
},
|
|
"vendor_priority": ["yfinance", "openai"],
|
|
"parameters": {
|
|
"ticker": {"type": "str", "description": "Ticker symbol"},
|
|
"curr_date": {"type": "str", "description": "Current date, yyyy-mm-dd"},
|
|
},
|
|
"returns": "str: Comprehensive fundamental data report",
|
|
},
|
|
"get_balance_sheet": {
|
|
"description": "Retrieve balance sheet data for a ticker",
|
|
"category": "fundamental_data",
|
|
"agents": ["fundamentals"],
|
|
"vendors": {
|
|
"alpha_vantage": get_alpha_vantage_balance_sheet,
|
|
"yfinance": get_yfinance_balance_sheet,
|
|
},
|
|
"vendor_priority": ["alpha_vantage", "yfinance"],
|
|
"parameters": {
|
|
"ticker": {"type": "str", "description": "Ticker symbol"},
|
|
},
|
|
"returns": "str: Balance sheet data",
|
|
},
|
|
"get_cashflow": {
|
|
"description": "Retrieve cash flow statement for a ticker",
|
|
"category": "fundamental_data",
|
|
"agents": ["fundamentals"],
|
|
"vendors": {
|
|
"alpha_vantage": get_alpha_vantage_cashflow,
|
|
"yfinance": get_yfinance_cashflow,
|
|
},
|
|
"vendor_priority": ["alpha_vantage", "yfinance"],
|
|
"parameters": {
|
|
"ticker": {"type": "str", "description": "Ticker symbol"},
|
|
},
|
|
"returns": "str: Cash flow statement data",
|
|
},
|
|
"get_income_statement": {
|
|
"description": "Retrieve income statement for a ticker",
|
|
"category": "fundamental_data",
|
|
"agents": ["fundamentals"],
|
|
"vendors": {
|
|
"alpha_vantage": get_alpha_vantage_income_statement,
|
|
"yfinance": get_yfinance_income_statement,
|
|
},
|
|
"vendor_priority": ["alpha_vantage", "yfinance"],
|
|
"parameters": {
|
|
"ticker": {"type": "str", "description": "Ticker symbol"},
|
|
},
|
|
"returns": "str: Income statement data",
|
|
},
|
|
"get_recommendation_trends": {
|
|
"description": "Retrieve analyst recommendation trends",
|
|
"category": "fundamental_data",
|
|
"agents": ["fundamentals"],
|
|
"vendors": {
|
|
"finnhub": get_finnhub_recommendation_trends,
|
|
},
|
|
"vendor_priority": ["finnhub"],
|
|
"parameters": {
|
|
"ticker": {"type": "str", "description": "Ticker symbol"},
|
|
},
|
|
"returns": "str: Analyst recommendation trends",
|
|
},
|
|
# ========== NEWS & INSIDER DATA ==========
|
|
"get_news": {
|
|
"description": "Retrieve news articles for a specific ticker",
|
|
"category": "news_data",
|
|
"agents": ["news", "social"],
|
|
"vendors": {
|
|
# "alpha_vantage": get_alpha_vantage_news,
|
|
"reddit": get_reddit_news,
|
|
"openai": get_stock_news_openai,
|
|
# "google": get_google_news,
|
|
},
|
|
"vendor_priority": ["reddit", "openai"],
|
|
"execution_mode": "aggregate",
|
|
"aggregate_vendors": ["reddit", "openai"],
|
|
"parameters": {
|
|
"query": {"type": "str", "description": "Search query or ticker symbol"},
|
|
"start_date": {"type": "str", "description": "Start date, yyyy-mm-dd"},
|
|
"end_date": {"type": "str", "description": "End date, yyyy-mm-dd"},
|
|
},
|
|
"returns": "str: News articles and analysis",
|
|
},
|
|
"get_global_news": {
|
|
"description": "Retrieve global market news and macroeconomic updates",
|
|
"category": "news_data",
|
|
"agents": ["news"],
|
|
"vendors": {
|
|
"openai": get_global_news_openai,
|
|
# "google": get_global_news_google,
|
|
"reddit": get_reddit_api_global_news,
|
|
# "alpha_vantage": get_alpha_vantage_global_news,
|
|
},
|
|
"vendor_priority": ["openai", "google", "reddit"],
|
|
"execution_mode": "aggregate",
|
|
"parameters": {
|
|
"date": {"type": "str", "description": "Date for news, yyyy-mm-dd"},
|
|
"look_back_days": {"type": "int", "description": "Days to look back", "default": 7},
|
|
"limit": {
|
|
"type": "int",
|
|
"description": "Number of articles/topics to return",
|
|
"default": 5,
|
|
},
|
|
},
|
|
"returns": "str: Global news and macro updates",
|
|
},
|
|
"get_insider_sentiment": {
|
|
"description": "Retrieve insider trading sentiment analysis",
|
|
"category": "news_data",
|
|
"agents": ["news"],
|
|
"vendors": {
|
|
"alpha_vantage": get_alpha_vantage_insider_sentiment,
|
|
},
|
|
"vendor_priority": ["alpha_vantage"],
|
|
"parameters": {
|
|
"ticker": {"type": "str", "description": "Ticker symbol"},
|
|
},
|
|
"returns": "str: Insider sentiment analysis",
|
|
},
|
|
"get_insider_transactions": {
|
|
"description": "Retrieve insider transaction history",
|
|
"category": "news_data",
|
|
"agents": ["news"],
|
|
"vendors": {
|
|
"yfinance": get_yfinance_insider_transactions,
|
|
},
|
|
"vendor_priority": ["yfinance"],
|
|
"parameters": {
|
|
"ticker": {"type": "str", "description": "Ticker symbol"},
|
|
},
|
|
"returns": "str: Insider transaction history",
|
|
},
|
|
# ========== DISCOVERY TOOLS ==========
|
|
# (Used by discovery mode, not bound to regular analysis agents)
|
|
"get_trending_tickers": {
|
|
"description": "Get trending stock tickers from social media",
|
|
"category": "discovery",
|
|
"agents": [],
|
|
"vendors": {
|
|
"reddit": get_reddit_trending_tickers,
|
|
},
|
|
"vendor_priority": ["reddit"],
|
|
"parameters": {
|
|
"limit": {"type": "int", "description": "Number of tickers to return", "default": 15},
|
|
},
|
|
"returns": "str: List of trending tickers with sentiment",
|
|
},
|
|
"get_market_movers": {
|
|
"description": "Get top market gainers and losers",
|
|
"category": "discovery",
|
|
"agents": [],
|
|
"vendors": {
|
|
"alpha_vantage": get_alpha_vantage_movers,
|
|
},
|
|
"vendor_priority": ["alpha_vantage"],
|
|
"parameters": {
|
|
"limit": {"type": "int", "description": "Number of movers to return", "default": 10},
|
|
},
|
|
"returns": "str: Top gainers and losers",
|
|
},
|
|
"get_tweets": {
|
|
"description": "Get tweets related to stocks or market topics",
|
|
"category": "discovery",
|
|
"agents": [],
|
|
"vendors": {
|
|
"twitter": get_twitter_tweets,
|
|
},
|
|
"vendor_priority": ["twitter"],
|
|
"parameters": {
|
|
"query": {"type": "str", "description": "Search query"},
|
|
"count": {"type": "int", "description": "Number of tweets", "default": 20},
|
|
},
|
|
"returns": "str: Tweets matching the query",
|
|
},
|
|
"get_earnings_calendar": {
|
|
"description": "Get upcoming earnings announcements (catalysts for volatility)",
|
|
"category": "discovery",
|
|
"agents": [],
|
|
"vendors": {
|
|
"finnhub": get_finnhub_earnings_calendar,
|
|
},
|
|
"vendor_priority": ["finnhub"],
|
|
"parameters": {
|
|
"from_date": {"type": "str", "description": "Start date in yyyy-mm-dd format"},
|
|
"to_date": {"type": "str", "description": "End date in yyyy-mm-dd format"},
|
|
},
|
|
"returns": "str: Formatted earnings calendar with EPS and revenue estimates",
|
|
},
|
|
"get_ipo_calendar": {
|
|
"description": "Get upcoming and recent IPOs (new listing opportunities)",
|
|
"category": "discovery",
|
|
"agents": [],
|
|
"vendors": {
|
|
"finnhub": get_finnhub_ipo_calendar,
|
|
},
|
|
"vendor_priority": ["finnhub"],
|
|
"parameters": {
|
|
"from_date": {"type": "str", "description": "Start date in yyyy-mm-dd format"},
|
|
"to_date": {"type": "str", "description": "End date in yyyy-mm-dd format"},
|
|
},
|
|
"returns": "str: Formatted IPO calendar with pricing and share details",
|
|
},
|
|
"get_unusual_volume": {
|
|
"description": "Find stocks with unusual volume but minimal price movement (accumulation signal)",
|
|
"category": "discovery",
|
|
"agents": [],
|
|
"vendors": {
|
|
"alpha_vantage": get_alpha_vantage_unusual_volume,
|
|
},
|
|
"vendor_priority": ["alpha_vantage"],
|
|
"parameters": {
|
|
"date": {
|
|
"type": "str",
|
|
"description": "Analysis date in yyyy-mm-dd format",
|
|
"default": None,
|
|
},
|
|
"min_volume_multiple": {
|
|
"type": "float",
|
|
"description": "Minimum volume multiple vs average",
|
|
"default": 3.0,
|
|
},
|
|
"max_price_change": {
|
|
"type": "float",
|
|
"description": "Maximum price change percentage",
|
|
"default": 5.0,
|
|
},
|
|
"top_n": {
|
|
"type": "int",
|
|
"description": "Number of top results to return",
|
|
"default": 20,
|
|
},
|
|
},
|
|
"returns": "str: Formatted report of stocks with unusual volume patterns",
|
|
},
|
|
"get_unusual_options_activity": {
|
|
"description": "Analyze options activity for specific tickers as confirmation signal (not for primary discovery)",
|
|
"category": "discovery",
|
|
"agents": [],
|
|
"vendors": {
|
|
"yfinance": get_yfinance_options_activity,
|
|
"tradier": get_tradier_unusual_options,
|
|
},
|
|
"vendor_priority": ["yfinance"],
|
|
"parameters": {
|
|
"ticker": {"type": "str", "description": "Ticker symbol to analyze"},
|
|
"num_expirations": {
|
|
"type": "int",
|
|
"description": "Number of nearest expiration dates to analyze",
|
|
"default": 3,
|
|
},
|
|
"curr_date": {
|
|
"type": "str",
|
|
"description": "Analysis date for reference",
|
|
"default": None,
|
|
},
|
|
},
|
|
"returns": "str: Formatted report of options activity with put/call ratios",
|
|
},
|
|
"get_analyst_rating_changes": {
|
|
"description": "Track recent analyst upgrades/downgrades and price target changes",
|
|
"category": "discovery",
|
|
"agents": [],
|
|
"vendors": {
|
|
"alpha_vantage": get_alpha_vantage_analyst_changes,
|
|
},
|
|
"vendor_priority": ["alpha_vantage"],
|
|
"parameters": {
|
|
"lookback_days": {
|
|
"type": "int",
|
|
"description": "Number of days to look back",
|
|
"default": 7,
|
|
},
|
|
"change_types": {
|
|
"type": "list",
|
|
"description": "Types of changes to track",
|
|
"default": ["upgrade", "downgrade", "initiated"],
|
|
},
|
|
"top_n": {"type": "int", "description": "Number of top results", "default": 20},
|
|
},
|
|
"returns": "str: Formatted report of recent analyst rating changes with freshness indicators",
|
|
},
|
|
"get_short_interest": {
|
|
"description": "Discover stocks with high short interest by scraping Finviz screener (squeeze candidates)",
|
|
"category": "discovery",
|
|
"agents": [],
|
|
"vendors": {
|
|
"finviz": get_finviz_short_interest,
|
|
},
|
|
"vendor_priority": ["finviz"],
|
|
"parameters": {
|
|
"min_short_interest_pct": {
|
|
"type": "float",
|
|
"description": "Minimum short interest % of float",
|
|
"default": 10.0,
|
|
},
|
|
"min_days_to_cover": {
|
|
"type": "float",
|
|
"description": "Minimum days to cover ratio",
|
|
"default": 2.0,
|
|
},
|
|
"top_n": {"type": "int", "description": "Number of top results", "default": 20},
|
|
},
|
|
"returns": "str: Formatted report of discovered high short interest stocks with squeeze potential",
|
|
},
|
|
"get_insider_buying": {
|
|
"description": "Discover stocks with significant insider buying activity (leading indicator)",
|
|
"category": "discovery",
|
|
"agents": [],
|
|
"vendors": {
|
|
"finviz": get_finviz_insider_buying,
|
|
},
|
|
"vendor_priority": ["finviz"],
|
|
"parameters": {
|
|
"transaction_type": {
|
|
"type": "str",
|
|
"description": "Transaction type: 'buy', 'sell', or 'any'",
|
|
"default": "buy",
|
|
},
|
|
"top_n": {"type": "int", "description": "Number of top results", "default": 20},
|
|
"lookback_days": {"type": "int", "description": "Days to look back", "default": 3},
|
|
"min_value": {
|
|
"type": "int",
|
|
"description": "Minimum transaction value",
|
|
"default": 25000,
|
|
},
|
|
},
|
|
"returns": "str: Formatted report of stocks with recent insider buying/selling activity",
|
|
},
|
|
"get_reddit_discussions": {
|
|
"description": "Get Reddit discussions about a specific ticker",
|
|
"category": "news_data",
|
|
"agents": ["social"],
|
|
"vendors": {
|
|
"reddit": get_reddit_discussions,
|
|
},
|
|
"vendor_priority": ["reddit"],
|
|
"parameters": {
|
|
"symbol": {"type": "str", "description": "Ticker symbol"},
|
|
"from_date": {"type": "str", "description": "Start date, yyyy-mm-dd"},
|
|
"to_date": {"type": "str", "description": "End date, yyyy-mm-dd"},
|
|
},
|
|
"returns": "str: Reddit discussions and sentiment",
|
|
},
|
|
"get_options_activity": {
|
|
"description": "Get options activity for a specific ticker (volume, open interest, put/call ratios, unusual activity)",
|
|
"category": "discovery",
|
|
"agents": ["fundamentals"],
|
|
"vendors": {
|
|
"yfinance": get_yfinance_options_activity,
|
|
"tradier": get_tradier_unusual_options,
|
|
},
|
|
"vendor_priority": ["yfinance"],
|
|
"parameters": {
|
|
"ticker": {"type": "str", "description": "Ticker symbol"},
|
|
"num_expirations": {
|
|
"type": "int",
|
|
"description": "Number of nearest expiration dates to analyze",
|
|
"default": 3,
|
|
},
|
|
"curr_date": {
|
|
"type": "str",
|
|
"description": "Current date for reference",
|
|
"default": None,
|
|
},
|
|
},
|
|
"returns": "str: Options activity report with volume, OI, P/C ratios, and unusual activity",
|
|
},
|
|
}
|
|
|
|
|
|
# ============================================================================
|
|
# HELPER FUNCTIONS
|
|
# ============================================================================
|
|
|
|
|
|
def get_tools_for_agent(agent_name: str) -> List[str]:
|
|
"""Get list of tool names available to a specific agent.
|
|
|
|
Args:
|
|
agent_name: Name of the agent (e.g., "market", "news", "fundamentals")
|
|
|
|
Returns:
|
|
List of tool names that the agent can use
|
|
"""
|
|
return [
|
|
tool_name
|
|
for tool_name, metadata in TOOL_REGISTRY.items()
|
|
if agent_name in metadata["agents"]
|
|
]
|
|
|
|
|
|
def get_tool_metadata(tool_name: str) -> Optional[Dict[str, Any]]:
|
|
"""Get complete metadata for a specific tool.
|
|
|
|
Args:
|
|
tool_name: Name of the tool
|
|
|
|
Returns:
|
|
Tool metadata dictionary, or None if tool doesn't exist
|
|
"""
|
|
return TOOL_REGISTRY.get(tool_name)
|
|
|
|
|
|
def get_all_tools() -> List[str]:
|
|
"""Get list of all available tool names.
|
|
|
|
Returns:
|
|
List of all tool names in the registry
|
|
"""
|
|
return list(TOOL_REGISTRY.keys())
|
|
|
|
|
|
def get_tools_by_category(category: str) -> List[str]:
|
|
"""Get all tools in a specific category.
|
|
|
|
Args:
|
|
category: Category name (e.g., "fundamental_data", "news_data")
|
|
|
|
Returns:
|
|
List of tool names in that category
|
|
"""
|
|
return [
|
|
tool_name
|
|
for tool_name, metadata in TOOL_REGISTRY.items()
|
|
if metadata["category"] == category
|
|
]
|
|
|
|
|
|
def get_vendor_config(tool_name: str) -> Dict[str, Any]:
|
|
"""Get vendor configuration for a tool.
|
|
|
|
Args:
|
|
tool_name: Name of the tool
|
|
|
|
Returns:
|
|
Dict with "vendors" (dict of vendor functions) and "vendor_priority" (list)
|
|
"""
|
|
metadata = get_tool_metadata(tool_name)
|
|
if not metadata:
|
|
return {"vendors": {}, "vendor_priority": []}
|
|
|
|
return {
|
|
"vendors": metadata.get("vendors", {}),
|
|
"vendor_priority": metadata.get("vendor_priority", []),
|
|
}
|
|
|
|
|
|
# ============================================================================
|
|
# AGENT-TOOL MAPPING
|
|
# ============================================================================
|
|
|
|
|
|
def get_agent_tool_mapping() -> Dict[str, List[str]]:
|
|
"""Get complete mapping of agents to their tools.
|
|
|
|
Returns:
|
|
Dictionary mapping agent names to lists of tool names
|
|
"""
|
|
mapping = {}
|
|
|
|
# Collect all agents mentioned in registry
|
|
all_agents = set()
|
|
for metadata in TOOL_REGISTRY.values():
|
|
all_agents.update(metadata["agents"])
|
|
|
|
# Build mapping for each agent
|
|
for agent in all_agents:
|
|
mapping[agent] = get_tools_for_agent(agent)
|
|
|
|
return mapping
|
|
|
|
|
|
# ============================================================================
|
|
# VALIDATION
|
|
# ============================================================================
|
|
|
|
|
|
def validate_registry() -> List[str]:
|
|
"""Validate the tool registry for common issues.
|
|
|
|
Returns:
|
|
List of warning/error messages (empty if all valid)
|
|
"""
|
|
issues = []
|
|
|
|
for tool_name, metadata in TOOL_REGISTRY.items():
|
|
# Check required fields
|
|
required_fields = [
|
|
"description",
|
|
"category",
|
|
"agents",
|
|
"vendors",
|
|
"vendor_priority",
|
|
"parameters",
|
|
"returns",
|
|
]
|
|
for field in required_fields:
|
|
if field not in metadata:
|
|
issues.append(f"{tool_name}: Missing required field '{field}'")
|
|
|
|
# Check vendor configuration
|
|
if not metadata.get("vendor_priority"):
|
|
issues.append(f"{tool_name}: No vendors specified in vendor_priority")
|
|
|
|
if not metadata.get("vendors"):
|
|
issues.append(f"{tool_name}: No vendor functions specified")
|
|
|
|
# Verify vendor_priority matches vendors dict
|
|
vendor_priority = metadata.get("vendor_priority", [])
|
|
vendors = metadata.get("vendors", {})
|
|
for vendor_name in vendor_priority:
|
|
if vendor_name not in vendors:
|
|
issues.append(
|
|
f"{tool_name}: Vendor '{vendor_name}' in priority list but not in vendors dict"
|
|
)
|
|
|
|
# Check parameters
|
|
if not isinstance(metadata.get("parameters"), dict):
|
|
issues.append(f"{tool_name}: Parameters must be a dictionary")
|
|
|
|
# Validate execution_mode if present
|
|
if "execution_mode" in metadata:
|
|
execution_mode = metadata["execution_mode"]
|
|
if execution_mode not in ["fallback", "aggregate"]:
|
|
issues.append(
|
|
f"{tool_name}: Invalid execution_mode '{execution_mode}', must be 'fallback' or 'aggregate'"
|
|
)
|
|
|
|
# Validate aggregate_vendors if present
|
|
if "aggregate_vendors" in metadata:
|
|
aggregate_vendors = metadata["aggregate_vendors"]
|
|
if not isinstance(aggregate_vendors, list):
|
|
issues.append(f"{tool_name}: aggregate_vendors must be a list")
|
|
else:
|
|
for vendor_name in aggregate_vendors:
|
|
if vendor_name not in vendors:
|
|
issues.append(
|
|
f"{tool_name}: aggregate_vendor '{vendor_name}' not in vendors dict"
|
|
)
|
|
|
|
# Warn if aggregate_vendors specified but execution_mode is not aggregate
|
|
if metadata.get("execution_mode") != "aggregate":
|
|
issues.append(
|
|
f"{tool_name}: aggregate_vendors specified but execution_mode is not 'aggregate'"
|
|
)
|
|
|
|
return issues
|
|
|
|
|
|
if __name__ == "__main__":
|
|
# Example usage and validation
|
|
logger.info("=" * 70)
|
|
logger.info("TOOL REGISTRY OVERVIEW")
|
|
logger.info("=" * 70)
|
|
|
|
logger.info(f"Total tools: {len(TOOL_REGISTRY)}")
|
|
|
|
logger.info("Tools by category:")
|
|
categories = set(m["category"] for m in TOOL_REGISTRY.values())
|
|
for category in sorted(categories):
|
|
tools = get_tools_by_category(category)
|
|
logger.info(f" {category}: {len(tools)} tools")
|
|
for tool in tools:
|
|
logger.debug(f" - {tool}")
|
|
|
|
logger.info("Agent-Tool Mapping:")
|
|
mapping = get_agent_tool_mapping()
|
|
for agent, tools in sorted(mapping.items()):
|
|
logger.info(f" {agent}: {len(tools)} tools")
|
|
for tool in tools:
|
|
logger.debug(f" - {tool}")
|
|
|
|
logger.info("Validation:")
|
|
issues = validate_registry()
|
|
if issues:
|
|
logger.warning("⚠️ Issues found:")
|
|
for issue in issues:
|
|
logger.warning(f" - {issue}")
|
|
else:
|
|
logger.info("✅ Registry is valid!")
|