Files
TradingAgents/tradingagents/agents/managers/research_manager.py
T
Yijia-Xiao d7b40a2a5c fix(graph): resolve instrument identity to stop wrong-company hallucination
Agents had no ground-truth ticker→company mapping, so the market analyst
could pattern-match a price chart to the wrong company (e.g. TOTDY read as
"TotalEnergies"), and every downstream agent inherited the bad framing.

Resolve identity once at run start via a cached, fail-open yfinance lookup
and inject company/sector/exchange into the shared instrument context that
all twelve agents consume, with an explicit do-not-substitute instruction.
Resolution runs on both the propagate() and CLI entry points.

Also replaces the bare "Continue" message-clear placeholder, which some
OpenAI-compatible providers interpreted as the user task, with a
context-anchored placeholder carrying the resolved identity and date.

#814 #888
2026-05-30 23:56:32 +00:00

68 lines
2.4 KiB
Python

"""Research Manager: turns the bull/bear debate into a structured investment plan for the trader."""
from __future__ import annotations
from tradingagents.agents.schemas import ResearchPlan, render_research_plan
from tradingagents.agents.utils.agent_utils import (
get_instrument_context_from_state,
get_language_instruction,
)
from tradingagents.agents.utils.structured import (
bind_structured,
invoke_structured_or_freetext,
)
def create_research_manager(llm):
structured_llm = bind_structured(llm, ResearchPlan, "Research Manager")
def research_manager_node(state) -> dict:
instrument_context = get_instrument_context_from_state(state)
history = state["investment_debate_state"].get("history", "")
investment_debate_state = state["investment_debate_state"]
prompt = f"""As the Research Manager and debate facilitator, your role is to critically evaluate this round of debate and deliver a clear, actionable investment plan for the trader.
{instrument_context}
---
**Rating Scale** (use exactly one):
- **Buy**: Strong conviction in the bull thesis; recommend taking or growing the position
- **Overweight**: Constructive view; recommend gradually increasing exposure
- **Hold**: Balanced view; recommend maintaining the current position
- **Underweight**: Cautious view; recommend trimming exposure
- **Sell**: Strong conviction in the bear thesis; recommend exiting or avoiding the position
Commit to a clear stance whenever the debate's strongest arguments warrant one; reserve Hold for situations where the evidence on both sides is genuinely balanced.
---
**Debate History:**
{history}""" + get_language_instruction()
investment_plan = invoke_structured_or_freetext(
structured_llm,
llm,
prompt,
render_research_plan,
"Research Manager",
)
new_investment_debate_state = {
"judge_decision": investment_plan,
"history": investment_debate_state.get("history", ""),
"bear_history": investment_debate_state.get("bear_history", ""),
"bull_history": investment_debate_state.get("bull_history", ""),
"current_response": investment_plan,
"count": investment_debate_state["count"],
}
return {
"investment_debate_state": new_investment_debate_state,
"investment_plan": investment_plan,
}
return research_manager_node