merge upstream main into analyst-phase1-observability

This commit is contained in:
CadeYu committed 2026-03-31 10:04:35 +08:00
commit 4300b68f19
40 files changed
+779 -479

No files matched your search

+1 -1
View File
@@ -59,7 +59,7 @@ class ConditionalLogic:
if (
state["risk_debate_state"]["count"] >= 3 * self.max_risk_discuss_rounds
): # 3 rounds of back-and-forth between 3 agents
return "Risk Judge"
return "Portfolio Manager"
if state["risk_debate_state"]["latest_speaker"].startswith("Aggressive"):
return "Conservative Analyst"
if state["risk_debate_state"]["latest_speaker"].startswith("Conservative"):
+4 -4
View File
@@ -110,12 +110,12 @@ Adhere strictly to these instructions, and ensure your output is detailed, accur
)
invest_judge_memory.add_situations([(situation, result)])
def reflect_risk_manager(self, current_state, returns_losses, risk_manager_memory):
"""Reflect on risk manager's decision and update memory."""
def reflect_portfolio_manager(self, current_state, returns_losses, portfolio_manager_memory):
"""Reflect on portfolio manager's decision and update memory."""
situation = self._extract_current_situation(current_state)
judge_decision = current_state["risk_debate_state"]["judge_decision"]
result = self._reflect_on_component(
"RISK JUDGE", judge_decision, situation, returns_losses
"PORTFOLIO MANAGER", judge_decision, situation, returns_losses
)
risk_manager_memory.add_situations([(situation, result)])
portfolio_manager_memory.add_situations([(situation, result)])
+9 -9
View File
@@ -24,7 +24,7 @@ class GraphSetup:
bear_memory,
trader_memory,
invest_judge_memory,
risk_manager_memory,
portfolio_manager_memory,
conditional_logic: ConditionalLogic,
analyst_concurrency_limit: int = 1,
):
@@ -36,7 +36,7 @@ class GraphSetup:
self.bear_memory = bear_memory
self.trader_memory = trader_memory
self.invest_judge_memory = invest_judge_memory
self.risk_manager_memory = risk_manager_memory
self.portfolio_manager_memory = portfolio_manager_memory
self.conditional_logic = conditional_logic
self.analyst_concurrency_limit = analyst_concurrency_limit
@@ -80,8 +80,8 @@ class GraphSetup:
aggressive_analyst = create_aggressive_debator(self.quick_thinking_llm)
neutral_analyst = create_neutral_debator(self.quick_thinking_llm)
conservative_analyst = create_conservative_debator(self.quick_thinking_llm)
risk_manager_node = create_risk_manager(
self.deep_thinking_llm, self.risk_manager_memory
portfolio_manager_node = create_portfolio_manager(
self.deep_thinking_llm, self.portfolio_manager_memory
)
# Create workflow
@@ -101,7 +101,7 @@ class GraphSetup:
workflow.add_node("Aggressive Analyst", aggressive_analyst)
workflow.add_node("Neutral Analyst", neutral_analyst)
workflow.add_node("Conservative Analyst", conservative_analyst)
workflow.add_node("Risk Judge", risk_manager_node)
workflow.add_node("Portfolio Manager", portfolio_manager_node)
# Define edges
# Start with the first analyst
@@ -151,7 +151,7 @@ class GraphSetup:
self.conditional_logic.should_continue_risk_analysis,
{
"Conservative Analyst": "Conservative Analyst",
"Risk Judge": "Risk Judge",
"Portfolio Manager": "Portfolio Manager",
},
)
workflow.add_conditional_edges(
@@ -159,7 +159,7 @@ class GraphSetup:
self.conditional_logic.should_continue_risk_analysis,
{
"Neutral Analyst": "Neutral Analyst",
"Risk Judge": "Risk Judge",
"Portfolio Manager": "Portfolio Manager",
},
)
workflow.add_conditional_edges(
@@ -167,11 +167,11 @@ class GraphSetup:
self.conditional_logic.should_continue_risk_analysis,
{
"Aggressive Analyst": "Aggressive Analyst",
"Risk Judge": "Risk Judge",
"Portfolio Manager": "Portfolio Manager",
},
)
workflow.add_edge("Risk Judge", END)
workflow.add_edge("Portfolio Manager", END)
# Compile and return
return workflow.compile()
+4 -2
View File
@@ -18,12 +18,14 @@ class SignalProcessor:
full_signal: Complete trading signal text
Returns:
Extracted decision (BUY, SELL, or HOLD)
Extracted rating (BUY, OVERWEIGHT, HOLD, UNDERWEIGHT, or SELL)
"""
messages = [
(
"system",
"You are an efficient assistant designed to analyze paragraphs or financial reports provided by a group of analysts. Your task is to extract the investment decision: SELL, BUY, or HOLD. Provide only the extracted decision (SELL, BUY, or HOLD) as your output, without adding any additional text or information.",
"You are an efficient assistant that extracts the trading decision from analyst reports. "
"Extract the rating as exactly one of: BUY, OVERWEIGHT, HOLD, UNDERWEIGHT, SELL. "
"Output only the single rating word, nothing else.",
),
("human", full_signal),
]
+9 -4
View File
@@ -99,7 +99,7 @@ class TradingAgentsGraph:
self.bear_memory = FinancialSituationMemory("bear_memory", self.config)
self.trader_memory = FinancialSituationMemory("trader_memory", self.config)
self.invest_judge_memory = FinancialSituationMemory("invest_judge_memory", self.config)
self.risk_manager_memory = FinancialSituationMemory("risk_manager_memory", self.config)
self.portfolio_manager_memory = FinancialSituationMemory("portfolio_manager_memory", self.config)
# Create tool nodes
self.tool_nodes = self._create_tool_nodes()
@@ -117,7 +117,7 @@ class TradingAgentsGraph:
self.bear_memory,
self.trader_memory,
self.invest_judge_memory,
self.risk_manager_memory,
self.portfolio_manager_memory,
self.conditional_logic,
analyst_concurrency_limit=self.config.get("analyst_concurrency_limit", 1),
)
@@ -149,6 +149,11 @@ class TradingAgentsGraph:
if reasoning_effort:
kwargs["reasoning_effort"] = reasoning_effort
elif provider == "anthropic":
effort = self.config.get("anthropic_effort")
if effort:
kwargs["effort"] = effort
return kwargs
def _create_tool_nodes(self) -> Dict[str, ToolNode]:
@@ -279,8 +284,8 @@ class TradingAgentsGraph:
self.reflector.reflect_invest_judge(
self.curr_state, returns_losses, self.invest_judge_memory
)
self.reflector.reflect_risk_manager(
self.curr_state, returns_losses, self.risk_manager_memory
self.reflector.reflect_portfolio_manager(
self.curr_state, returns_losses, self.portfolio_manager_memory
)
def process_signal(self, full_signal):