feat: wire chief_analyst into streaming, logging, and verdict extraction
This commit is contained in:
parent
5420ccb360
commit
1d7273d765
|
|
@ -59,6 +59,7 @@ _NODE_TO_STEP = {
|
||||||
"Conservative Analyst": "conservative_analyst",
|
"Conservative Analyst": "conservative_analyst",
|
||||||
"Neutral Analyst": "neutral_analyst",
|
"Neutral Analyst": "neutral_analyst",
|
||||||
"Risk Judge": "risk_judge",
|
"Risk Judge": "risk_judge",
|
||||||
|
"Chief Analyst": "chief_analyst",
|
||||||
}
|
}
|
||||||
|
|
||||||
_SKIP_NODES = {"tools_market", "tools_news", "tools_fundamentals", "tools_social"}
|
_SKIP_NODES = {"tools_market", "tools_news", "tools_fundamentals", "tools_social"}
|
||||||
|
|
@ -304,8 +305,13 @@ class TradingAgentsGraph:
|
||||||
# Log state
|
# Log state
|
||||||
self._log_state(trade_date, final_state)
|
self._log_state(trade_date, final_state)
|
||||||
|
|
||||||
# Return decision and processed signal
|
# Return decision and processed signal (prefer structured chief_analyst_report verdict)
|
||||||
return final_state, self.process_signal(final_state["final_trade_decision"])
|
chief_report = (final_state.get("chief_analyst_report") or {})
|
||||||
|
if chief_report.get("verdict") in {"BUY", "SELL", "HOLD"}:
|
||||||
|
decision = chief_report["verdict"]
|
||||||
|
else:
|
||||||
|
decision = self.process_signal(final_state.get("final_trade_decision", ""))
|
||||||
|
return final_state, decision
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _extract_report(step_key: str, update: dict) -> str:
|
def _extract_report(step_key: str, update: dict) -> str:
|
||||||
|
|
@ -323,6 +329,7 @@ class TradingAgentsGraph:
|
||||||
"conservative_analyst": lambda u: (u.get("risk_debate_state") or {}).get("current_conservative_response", ""),
|
"conservative_analyst": lambda u: (u.get("risk_debate_state") or {}).get("current_conservative_response", ""),
|
||||||
"neutral_analyst": lambda u: (u.get("risk_debate_state") or {}).get("current_neutral_response", ""),
|
"neutral_analyst": lambda u: (u.get("risk_debate_state") or {}).get("current_neutral_response", ""),
|
||||||
"risk_judge": lambda u: (u.get("risk_debate_state") or {}).get("judge_decision", ""),
|
"risk_judge": lambda u: (u.get("risk_debate_state") or {}).get("judge_decision", ""),
|
||||||
|
"chief_analyst": lambda u: json.dumps(u.get("chief_analyst_report") or {}),
|
||||||
}
|
}
|
||||||
return extractors[step_key](update) or ""
|
return extractors[step_key](update) or ""
|
||||||
|
|
||||||
|
|
@ -383,15 +390,20 @@ class TradingAgentsGraph:
|
||||||
final_snap = self.graph.get_state(thread_config)
|
final_snap = self.graph.get_state(thread_config)
|
||||||
final_state = final_snap.values if hasattr(final_snap, "values") else {}
|
final_state = final_snap.values if hasattr(final_snap, "values") else {}
|
||||||
|
|
||||||
raw_signal = final_state.get("final_trade_decision", "")
|
chief_report = final_state.get("chief_analyst_report") or {}
|
||||||
try:
|
if chief_report.get("verdict") in {"BUY", "SELL", "HOLD"}:
|
||||||
raw_decision = self.process_signal(raw_signal)
|
decision = chief_report["verdict"]
|
||||||
decision = raw_decision.strip().upper()
|
else:
|
||||||
if decision not in {"BUY", "SELL", "HOLD"}:
|
# Fallback for partial runs or old checkpoints without chief_analyst_report
|
||||||
logger.warning("stream_propagate: unexpected decision '%s' — defaulting to HOLD", decision)
|
try:
|
||||||
decision = "HOLD"
|
raw_signal = final_state.get("final_trade_decision", "")
|
||||||
except Exception:
|
raw_decision = self.process_signal(raw_signal)
|
||||||
raise # propagate to run_service for run:error handling
|
decision = raw_decision.strip().upper()
|
||||||
|
if decision not in {"BUY", "SELL", "HOLD"}:
|
||||||
|
logger.warning("stream_propagate: unexpected decision '%s' — defaulting to HOLD", decision)
|
||||||
|
decision = "HOLD"
|
||||||
|
except Exception:
|
||||||
|
raise # propagate to run_service for run:error handling
|
||||||
|
|
||||||
self._last_decision = decision
|
self._last_decision = decision
|
||||||
self._log_state(trade_date, final_state)
|
self._log_state(trade_date, final_state)
|
||||||
|
|
@ -426,6 +438,7 @@ class TradingAgentsGraph:
|
||||||
},
|
},
|
||||||
"investment_plan": final_state["investment_plan"],
|
"investment_plan": final_state["investment_plan"],
|
||||||
"final_trade_decision": final_state["final_trade_decision"],
|
"final_trade_decision": final_state["final_trade_decision"],
|
||||||
|
"chief_analyst_report": final_state.get("chief_analyst_report"),
|
||||||
}
|
}
|
||||||
|
|
||||||
# Save to file
|
# Save to file
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue