Repository Public MIT
1import type { LucideIcon } from "lucide-react";2import {3 Building2, FileText, Activity, Calculator, Users, Briefcase, Globe, Newspaper,4 DollarSign, Search, PieChart, Leaf, Code2, LineChart, Database, Image as ImageIcon,5 Wrench, Landmark, Coins,6} from "lucide-react";7import { humanizeTool } from "./format";89export type ToolFamily =10 | "market" | "fundamentals" | "technical" | "quant" | "analyst" | "insider" | "macro"11 | "news" | "dividends" | "screening" | "etf" | "esg" | "export" | "web" | "python" | "crypto" | "other";1213export const TOOL_FAMILY_META: Record<ToolFamily, { label: string; icon: LucideIcon; chip: string; dot: string }> = {14 market: { label: "Marché", icon: LineChart, chip: "bg-sky-500/10 text-sky-700 dark:text-sky-300 border-sky-500/25", dot: "bg-sky-500" },15 fundamentals: { label: "Fondamentaux", icon: FileText, chip: "bg-indigo-500/10 text-indigo-700 dark:text-indigo-300 border-indigo-500/25", dot: "bg-indigo-500" },16 technical: { label: "Technique", icon: Activity, chip: "bg-emerald-500/10 text-emerald-700 dark:text-emerald-300 border-emerald-500/25", dot: "bg-emerald-500" },17 quant: { label: "Quant / Python", icon: Calculator, chip: "bg-orange-500/10 text-orange-700 dark:text-orange-300 border-orange-500/25", dot: "bg-orange-500" },18 analyst: { label: "Analystes", icon: Users, chip: "bg-violet-500/10 text-violet-700 dark:text-violet-300 border-violet-500/25", dot: "bg-violet-500" },19 insider: { label: "Initiés", icon: Briefcase, chip: "bg-rose-500/10 text-rose-700 dark:text-rose-300 border-rose-500/25", dot: "bg-rose-500" },20 macro: { label: "Macro", icon: Landmark, chip: "bg-teal-500/10 text-teal-700 dark:text-teal-300 border-teal-500/25", dot: "bg-teal-500" },21 news: { label: "Actualités", icon: Newspaper, chip: "bg-amber-500/10 text-amber-700 dark:text-amber-300 border-amber-500/25", dot: "bg-amber-500" },22 dividends: { label: "Dividendes", icon: DollarSign, chip: "bg-green-500/10 text-green-700 dark:text-green-300 border-green-500/25", dot: "bg-green-500" },23 screening: { label: "Screening", icon: Search, chip: "bg-pink-500/10 text-pink-700 dark:text-pink-300 border-pink-500/25", dot: "bg-pink-500" },24 etf: { label: "ETF", icon: PieChart, chip: "bg-purple-500/10 text-purple-700 dark:text-purple-300 border-purple-500/25", dot: "bg-purple-500" },25 esg: { label: "ESG", icon: Leaf, chip: "bg-lime-500/10 text-lime-700 dark:text-lime-300 border-lime-500/25", dot: "bg-lime-500" },26 export: { label: "Export", icon: ImageIcon, chip: "bg-cyan-500/10 text-cyan-700 dark:text-cyan-300 border-cyan-500/25", dot: "bg-cyan-500" },27 web: { label: "Web", icon: Globe, chip: "bg-blue-500/10 text-blue-700 dark:text-blue-300 border-blue-500/25", dot: "bg-blue-500" },28 python: { label: "Python", icon: Code2, chip: "bg-yellow-500/10 text-yellow-700 dark:text-yellow-300 border-yellow-500/25", dot: "bg-yellow-500" },29 crypto: { label: "Crypto", icon: Coins, chip: "bg-fuchsia-500/10 text-fuchsia-700 dark:text-fuchsia-300 border-fuchsia-500/25", dot: "bg-fuchsia-500" },30 other: { label: "Outil", icon: Wrench, chip: "bg-slate-500/10 text-slate-700 dark:text-slate-300 border-slate-500/25", dot: "bg-slate-500" },31};3233const EXPLICIT_NAMES: Record<string, string> = {34 get_company_profile: "Profil d'entreprise",35 get_income_statement: "Compte de résultat",36 get_balance_sheet: "Bilan",37 get_cash_flow: "Flux de trésorerie",38 get_key_metrics: "Métriques clés",39 get_financial_ratios: "Ratios financiers",40 get_financial_growth: "Croissance financière",41 get_stock_quote: "Cotation",42 get_historical_price: "Prix historiques",43 get_intraday_price: "Intraday",44 get_rsi: "RSI", get_macd: "MACD", get_ema: "EMA", get_sma: "SMA", get_adx: "ADX",45 get_williams_r: "Williams %R", get_cci: "CCI", get_stochastic: "Stochastique",46 get_financial_news: "Actualités",47 get_press_releases: "Communiqués",48 get_stock_news_sentiment: "Sentiment news",49 get_social_sentiment: "Sentiment social",50 get_economic_calendar: "Calendrier économique",51 get_earnings_calendar: "Calendrier des résultats",52 get_ipo_calendar: "Calendrier IPO",53 get_insider_trading: "Transactions d'initiés",54 get_congressional_trading: "Trading du Congrès",55 get_senate_trading: "Trading du Sénat",56 get_institutional_holders: "Détenteurs institutionnels",57 get_forex_quote: "Forex",58 get_forex_historical: "Forex historique",59 get_commodity_quotes: "Commodités",60 get_treasury_rates: "Taux du Trésor",61 get_economic_indicator: "Indicateur macro",62 get_analyst_estimates: "Estimations d'analystes",63 get_earnings_surprises: "Surprises de résultats",64 get_price_target: "Objectifs de prix",65 get_price_target_summary: "Résumé objectifs de prix",66 get_upgrades_downgrades: "Révisions d'analystes",67 get_dividend_history: "Dividendes",68 get_stock_split_history: "Splits",69 get_sec_filings: "Dépôts SEC",70 get_cot_report: "Rapport COT",71 get_esg_score: "Score ESG",72 get_stock_screener: "Screener",73 search_companies: "Recherche d'entreprises",74 get_stock_peers: "Pairs",75 get_etf_holdings: "Composition ETF",76 get_etf_sector_weightings: "Secteurs ETF",77 get_etf_country_weightings: "Pays ETF",78 get_crypto_quote: "Crypto",79 run_monte_carlo_simulation: "Monte Carlo",80 calculate_options_price: "Pricing d'options",81 estimate_garch_volatility: "Volatilité GARCH",82 calculate_var: "Value at Risk",83 optimize_portfolio: "Optimisation de portefeuille",84 analyze_risk_metrics: "Métriques de risque",85 create_plot: "Graphique",86 execute_custom_python: "Python personnalisé",87 execute_custom_python_analysis: "Analyse Python",88 key_metrics_ttm: "Métriques clés (TTM)",89 get_key_metrics_ttm: "Métriques clés (TTM)",90 price_target_consensus: "Consensus prix cible",91 get_price_target_consensus: "Consensus prix cible",92 stock_price_change: "Variation du prix",93 get_stock_price_change: "Variation du prix",94 grades_summary: "Notes des analystes",95 revenue_product_segmentation: "Revenus par produit",96 get_revenue_product_segmentation: "Revenus par produit",97 execute_python: "Python",98 web_search_exa: "Recherche web",99 exa_search: "Recherche web",100 tavily_search: "Recherche Tavily",101 firecrawl_scrape: "Lecture de page",102 firecrawl_crawl: "Exploration de site",103 get_market_hours: "Heures de marché",104 get_company_outlook: "Perspectives",105 download_fmp_data: "Téléchargement de données",106 save_excel: "Export Excel",107 generate_slides: "Slides",108 export_pdf: "Export PDF",109};110111export function toolFamily(tool: string): ToolFamily {112 const t = tool.toLowerCase();113 if (/monte_carlo|garch|_var\b|calculate_var|optimize_portfolio|risk_metrics|options_price|volatility_surface/.test(t)) return "quant";114 if (/python|create_plot|plot/.test(t)) return "python";115 if (/rsi|macd|ema|sma|adx|williams|cci|stochastic|technical/.test(t)) return "technical";116 if (/income|balance|cash_flow|key_metrics|ratios|growth|profile|outlook|fundamental|peers|financial_statement/.test(t)) return "fundamentals";117 if (/analyst|estimate|price_target|upgrade|surprise|grades|rating/.test(t)) return "analyst";118 if (/insider|congress|senate|institutional|holders|13f/.test(t)) return "insider";119 if (/news|press|sentiment/.test(t)) return "news";120 if (/dividend|split/.test(t)) return "dividends";121 if (/economic|treasury|forex|commodit|cot_|macro|gdp|cpi|inflation/.test(t)) return "macro";122 if (/screener|search_companies|search_symbol|search_by_cik|search/.test(t)) return "screening";123 if (/etf|fund/.test(t)) return "etf";124 if (/esg/.test(t)) return "esg";125 if (/crypto|bitcoin/.test(t)) return "crypto";126 if (/exa|tavily|firecrawl|web|scrape|crawl/.test(t)) return "web";127 if (/pdf|excel|slides|docx|download|export|word/.test(t)) return "export";128 if (/quote|price|intraday|historical|market_hours|gainers|losers|actives|chart/.test(t)) return "market";129 return "other";130}131132export function toolLabel(tool: string): string {133 return EXPLICIT_NAMES[tool] ?? humanizeTool(tool);134}135136export function toolMeta(tool: string) {137 const family = toolFamily(tool);138 const meta = TOOL_FAMILY_META[family];139 return { ...meta, family, label: toolLabel(tool) };140}141142/** Résumé compact de l'input d'un outil (ex: « AAPL · 1y »). */143export function summarizeToolInput(input: unknown): string {144 if (!input || typeof input !== "object") return "";145 const obj = input as Record<string, unknown>;146 const keys = ["symbol", "symbols", "ticker", "tickers", "query", "url", "period", "interval", "from", "to", "limit", "strike", "expiration", "num_simulations", "time_horizon", "initial_investment"];147 const parts: string[] = [];148 for (const k of keys) {149 const v = obj[k];150 if (v == null || v === "") continue;151 if (Array.isArray(v)) parts.push(v.slice(0, 5).join(", ") + (v.length > 5 ? "…" : ""));152 else if (typeof v === "string") parts.push(v.length > 48 ? v.slice(0, 45) + "…" : v);153 else if (typeof v === "number") parts.push(String(v));154 if (parts.length >= 3) break;155 }156 return parts.join(" · ");157}158159export const DATA_SOURCES: { name: string; desc: string; icon: LucideIcon }[] = [160 { name: "Financial Modeling Prep", desc: "200+ endpoints : cotations, états financiers, analystes, initiés, macro", icon: Database },161 { name: "EODHD", desc: "Historique mondial, fondamentaux, options UnicornBay", icon: Globe },162 { name: "Exa · Tavily · Firecrawl", desc: "Recherche sémantique, agrégation d'actualités, lecture de pages", icon: Search },163 { name: "Python (pandas, numpy, scipy, statsmodels)", desc: "Monte Carlo, GARCH, VaR, optimisation, graphiques matplotlib", icon: Code2 },164];165