mirror of
https://github.com/TauricResearch/TradingAgents.git
synced 2026-09-26 22:42:40 +03:00
fix(cli): say whether a checkpointed run resumed or started fresh
- the announcement existed but the run path never called it - tested through run_analysis rather than by calling the helper directly
This commit is contained in:
@@ -1174,6 +1174,7 @@ def run_analysis(checkpoint: bool | None = None, portfolio=None):
|
||||
)
|
||||
if checkpoint_tid is not None:
|
||||
args.setdefault("config", {}).setdefault("configurable", {})["thread_id"] = checkpoint_tid
|
||||
_announce_checkpoint_state(graph, selections["ticker"], selections["analysis_date"])
|
||||
|
||||
# Stream the analysis. On resume, feed None so LangGraph continues the
|
||||
# interrupted run instead of re-appending the initial state (#1249); the
|
||||
|
||||
@@ -95,23 +95,6 @@ def test_every_command_is_registered_when_run_as_a_module():
|
||||
assert "--start" in plain
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_the_cli_says_whether_a_run_resumed(monkeypatch):
|
||||
"""The README promises the user can tell a resumed run from a fresh one.
|
||||
The graph logs it, but nothing configures logging, so it was never shown."""
|
||||
import cli.main as m
|
||||
|
||||
messages = []
|
||||
monkeypatch.setattr(m.message_buffer, "add_message",
|
||||
lambda kind, text: messages.append(text), raising=False)
|
||||
|
||||
m._announce_checkpoint_state(type("G", (), {"_resuming": True})(), "NVDA", "2026-01-10")
|
||||
m._announce_checkpoint_state(type("G", (), {"_resuming": False})(), "NVDA", "2026-01-10")
|
||||
|
||||
assert any("resum" in text.lower() for text in messages)
|
||||
assert any("fresh" in text.lower() for text in messages)
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_backtest_can_continue_an_interrupted_sweep(runner, monkeypatch, tmp_path):
|
||||
"""Resuming is what makes a long sweep practical, and the Python API has it."""
|
||||
|
||||
@@ -64,10 +64,12 @@ def test_record_decision_skips_a_run_without_a_decision(tmp_path):
|
||||
class _FakeGraph:
|
||||
"""Records the lifecycle calls run_analysis makes."""
|
||||
|
||||
def __init__(self):
|
||||
def __init__(self, resuming=None):
|
||||
self.calls = []
|
||||
self.graph = self
|
||||
self.propagator = self
|
||||
self.resuming = resuming # None: checkpointing off
|
||||
self._resuming = False
|
||||
|
||||
def create_run_state(self, ticker, trade_date, asset_type="stock", portfolio=None):
|
||||
self.calls.append(("create_run_state", ticker, trade_date))
|
||||
@@ -84,7 +86,8 @@ class _FakeGraph:
|
||||
return {}
|
||||
|
||||
def begin_checkpoint(self, *a, **k):
|
||||
return None
|
||||
self._resuming = bool(self.resuming)
|
||||
return None if self.resuming is None else "thread"
|
||||
|
||||
def checkpoint_input(self, state):
|
||||
return state
|
||||
@@ -136,14 +139,14 @@ class _FakeBuffer:
|
||||
self.agent_status[agent] = status
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_cli_run_uses_the_decision_log_like_propagate(tmp_path, monkeypatch):
|
||||
def _run_cli(monkeypatch, tmp_path, fake):
|
||||
"""Drive run_analysis against ``fake``; returns the message buffer."""
|
||||
import cli.main as m
|
||||
from cli.models import AnalystType
|
||||
|
||||
fake = _FakeGraph()
|
||||
buffer = _FakeBuffer()
|
||||
monkeypatch.setattr(m, "TradingAgentsGraph", lambda *a, **k: fake)
|
||||
monkeypatch.setattr(m, "message_buffer", _FakeBuffer())
|
||||
monkeypatch.setattr(m, "message_buffer", buffer)
|
||||
monkeypatch.setattr(m, "create_layout", lambda: None)
|
||||
monkeypatch.setattr(m, "update_display", lambda *a, **k: None)
|
||||
monkeypatch.setattr(m, "Live", _NullLive)
|
||||
@@ -155,8 +158,14 @@ def test_cli_run_uses_the_decision_log_like_propagate(tmp_path, monkeypatch):
|
||||
"data_cache_dir": str(tmp_path / "cache"), "results_dir": str(tmp_path / "results"),
|
||||
})
|
||||
monkeypatch.setattr(m.typer, "prompt", lambda *a, **k: "N")
|
||||
|
||||
m.run_analysis()
|
||||
return buffer
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_cli_run_uses_the_decision_log_like_propagate(tmp_path, monkeypatch):
|
||||
fake = _FakeGraph()
|
||||
_run_cli(monkeypatch, tmp_path, fake)
|
||||
|
||||
assert fake.calls == [
|
||||
("create_run_state", "NVDA", "2026-01-10"),
|
||||
@@ -165,3 +174,19 @@ def test_cli_run_uses_the_decision_log_like_propagate(tmp_path, monkeypatch):
|
||||
("record_decision", "NVDA", "2026-01-10", "Rating: Buy\n\nBuy NVDA."),
|
||||
("clear_checkpoint",),
|
||||
]
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
@pytest.mark.parametrize("resuming, said", [(True, "resuming"), (False, "starting fresh")])
|
||||
def test_the_cli_run_says_whether_it_resumed(tmp_path, monkeypatch, resuming, said):
|
||||
"""The README promises the run view tells a resumed run from a fresh one."""
|
||||
buffer = _run_cli(monkeypatch, tmp_path, _FakeGraph(resuming=resuming))
|
||||
|
||||
assert any(said in text.lower() for _, kind, text in buffer.messages if kind == "System")
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_a_run_without_checkpointing_says_nothing_about_resuming(tmp_path, monkeypatch):
|
||||
buffer = _run_cli(monkeypatch, tmp_path, _FakeGraph())
|
||||
|
||||
assert not any("resum" in text.lower() or "fresh" in text.lower() for _, _, text in buffer.messages)
|
||||
|
||||
Reference in New Issue
Block a user