feat(graph): run the analysts at the same time (#1255)

- each analyst is a graph of its own (model and tools on a private message history) that returns only its report; all start together and the research debate waits for every report
- the message-clearing nodes are gone; a checkpoint saved by the sequential layout starts fresh
- TradingAgentsGraph.stream_run streams the analysts' messages for debug mode and the CLI, whose status and timing now track the analysts side by side
This commit is contained in:
Yijia-Xiao
2026-09-25 06:35:54 +00:00
parent fc1ab1db07
commit 9968bd8dd1
15 changed files with 163 additions and 193 deletions
+18 -13
View File
@@ -129,23 +129,28 @@ class AnalystWallTimeTrackerTests(unittest.TestCase):
"Analyst wall time: News 4.00s | Market 2.25s",
)
def test_syncs_wall_time_from_sequential_chunks(self):
def test_analysts_run_together_and_finish_on_their_own_reports(self):
plan = build_analyst_execution_plan(["market", "news"])
tracker = AnalystWallTimeTracker(plan)
sync_analyst_tracker_from_chunk(tracker, {}, now=10.0)
self.assertEqual(tracker.format_summary(), "Analyst wall time: pending")
sync_analyst_tracker_from_chunk(
tracker,
{"market_report": "done"},
now=13.0,
)
self.assertEqual(tracker.format_summary(), "Analyst wall time: Market 3.00s")
sync_analyst_tracker_from_chunk(tracker, {"news_report": "done"}, now=13.0)
self.assertEqual(tracker.format_summary(), "Analyst wall time: News 3.00s")
sync_analyst_tracker_from_chunk(
tracker,
{"market_report": "done", "news_report": "done"},
now=18.0,
)
self.assertEqual(tracker.format_summary(), "Analyst wall time: Market 3.00s | News 5.00s")
sync_analyst_tracker_from_chunk(tracker, {"news_report": "done", "market_report": "done"}, now=18.0)
self.assertEqual(tracker.format_summary(), "Analyst wall time: Market 8.00s | News 3.00s")
@pytest.mark.unit
def test_every_selected_analyst_is_in_progress_until_its_report_lands():
from cli.display import MessageBuffer, update_analyst_statuses
buffer = MessageBuffer()
buffer.init_for_analysis(["market", "news", "fundamentals"])
update_analyst_statuses(buffer, {"news_report": "done"})
assert buffer.agent_status["Market Analyst"] == "in_progress"
assert buffer.agent_status["Fundamentals Analyst"] == "in_progress"
assert buffer.agent_status["News Analyst"] == "completed"