Gate Adanos social sentiment behind explicit config

This commit is contained in:
Alex Schneider 2026-03-25 20:28:29 +01:00
parent 1a06904b5f
commit c3bce5f360
5 changed files with 49 additions and 20 deletions

View File

@ -7,15 +7,21 @@ from tradingagents.dataflows import adanos_social, interface
class SocialSentimentToolTests(unittest.TestCase):
def test_route_to_vendor_supports_social_data(self):
with patch.dict(
interface.VENDOR_METHODS["get_social_sentiment"],
{"adanos": lambda ticker, curr_date, look_back_days: f"{ticker}|{curr_date}|{look_back_days}"},
clear=True,
):
result = interface.route_to_vendor("get_social_sentiment", "NVDA", "2026-01-15", 5)
with patch("tradingagents.dataflows.interface.get_vendor", return_value="adanos"):
with patch.dict(
interface.VENDOR_METHODS["get_social_sentiment"],
{"adanos": lambda ticker, curr_date, look_back_days: f"{ticker}|{curr_date}|{look_back_days}"},
clear=True,
):
result = interface.route_to_vendor("get_social_sentiment", "NVDA", "2026-01-15", 5)
self.assertEqual(result, "NVDA|2026-01-15|5")
def test_route_to_vendor_requires_explicit_social_vendor(self):
with patch("tradingagents.dataflows.interface.get_vendor", return_value="default"):
with self.assertRaises(RuntimeError):
interface.route_to_vendor("get_social_sentiment", "NVDA", "2026-01-15", 5)
def test_social_tool_routes_to_vendor(self):
with patch("tradingagents.agents.utils.social_data_tools.route_to_vendor", return_value="ok") as mock_route:
result = social_tool.invoke(

View File

@ -2,7 +2,7 @@ from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
import time
import json
from tradingagents.agents.utils.agent_utils import build_instrument_context, get_news, get_social_sentiment
from tradingagents.dataflows.config import get_config
from tradingagents.dataflows.interface import is_tool_configured
def create_social_media_analyst(llm):
@ -10,13 +10,22 @@ def create_social_media_analyst(llm):
current_date = state["trade_date"]
instrument_context = build_instrument_context(state["company_of_interest"])
tools = [
get_social_sentiment,
get_news,
]
social_tool_enabled = is_tool_configured("get_social_sentiment")
tools = [get_news]
social_tool_guidance = (
"Use the get_news(query, start_date, end_date) tool to search for company-specific news and public discussion context."
)
if social_tool_enabled:
tools.insert(0, get_social_sentiment)
social_tool_guidance = (
"Use the get_social_sentiment(ticker, curr_date, look_back_days) tool for structured multi-source sentiment data when it is available, "
"and use the get_news(query, start_date, end_date) tool to search for company-specific news and public discussion context."
)
system_message = (
"You are a social media and company specific news researcher/analyst tasked with analyzing social media posts, recent company news, and public sentiment for a specific company over the past week. You will be given a company's name your objective is to write a comprehensive long report detailing your analysis, insights, and implications for traders and investors on this company's current state after looking at social media and what people are saying about that company, analyzing sentiment data of what people feel each day about the company, and looking at recent company news. Use the get_social_sentiment(ticker, curr_date, look_back_days) tool for structured multi-source sentiment data when it is available, and use the get_news(query, start_date, end_date) tool to search for company-specific news and public discussion context. Try to look at all sources possible from social media to sentiment to news. Provide specific, actionable insights with supporting evidence to help traders make informed decisions."
"You are a social media and company specific news researcher/analyst tasked with analyzing social media posts, recent company news, and public sentiment for a specific company over the past week. You will be given a company's name your objective is to write a comprehensive long report detailing your analysis, insights, and implications for traders and investors on this company's current state after looking at social media and what people are saying about that company, analyzing sentiment data of what people feel each day about the company, and looking at recent company news. "
+ social_tool_guidance
+ " Try to look at all sources possible from social media to sentiment to news. Provide specific, actionable insights with supporting evidence to help traders make informed decisions."
+ """ Make sure to append a Markdown table at the end of the report to organize key points in the report, organized and easy to read."""
)

View File

@ -143,10 +143,25 @@ def get_vendor(category: str, method: str = None) -> str:
# Fall back to category-level configuration
return config.get("data_vendors", {}).get(category, "default")
def is_tool_configured(method: str) -> bool:
"""Return True when a tool has an explicit non-default vendor configured."""
category = get_category_for_method(method)
vendor_config = get_vendor(category, method)
configured_vendors = [
vendor.strip().lower()
for vendor in str(vendor_config or "").split(",")
if vendor.strip()
]
return any(vendor not in {"default", "none", "disabled"} for vendor in configured_vendors)
def route_to_vendor(method: str, *args, **kwargs):
"""Route method calls to appropriate vendor implementation with fallback support."""
category = get_category_for_method(method)
vendor_config = get_vendor(category, method)
if method == "get_social_sentiment" and not is_tool_configured(method):
raise RuntimeError("No configured vendor for 'get_social_sentiment'")
primary_vendors = [v.strip() for v in vendor_config.split(',')]
if method not in VENDOR_METHODS:

View File

@ -27,7 +27,7 @@ DEFAULT_CONFIG = {
"technical_indicators": "yfinance", # Options: alpha_vantage, yfinance
"fundamental_data": "yfinance", # Options: alpha_vantage, yfinance
"news_data": "yfinance", # Options: alpha_vantage, yfinance
"social_data": "default", # Options: default, adanos
"social_data": "default", # Options: default (disabled), adanos
},
# Tool-level configuration (takes precedence over category-level)
"tool_vendors": {

View File

@ -19,6 +19,7 @@ from tradingagents.agents.utils.agent_states import (
RiskDebateState,
)
from tradingagents.dataflows.config import set_config
from tradingagents.dataflows.interface import is_tool_configured
# Import the new abstract tool methods from agent_utils
from tradingagents.agents.utils.agent_utils import (
@ -158,6 +159,10 @@ class TradingAgentsGraph:
def _create_tool_nodes(self) -> Dict[str, ToolNode]:
"""Create tool nodes for different data sources using abstract methods."""
social_tools = [get_news]
if is_tool_configured("get_social_sentiment"):
social_tools.insert(0, get_social_sentiment)
return {
"market": ToolNode(
[
@ -167,13 +172,7 @@ class TradingAgentsGraph:
get_indicators,
]
),
"social": ToolNode(
[
# Dedicated social sentiment first, then news context
get_social_sentiment,
get_news,
]
),
"social": ToolNode(social_tools),
"news": ToolNode(
[
# News and insider information