diff --git a/tests/test_reporting.py b/tests/test_reporting.py index 67fccef9b..b69858e1a 100644 --- a/tests/test_reporting.py +++ b/tests/test_reporting.py @@ -1,6 +1,7 @@ """Report parity: the shared writer produces the report tree for the CLI and the programmatic API alike (#1037).""" +import re from types import SimpleNamespace import pytest @@ -119,3 +120,16 @@ def test_the_report_header_names_the_rating(tmp_path, decision, rating): header = write_report_tree(state, "NVDA", tmp_path, settings=SETTINGS).read_text().split("## ")[0] assert f"- Rating: {rating}" in header + + +@pytest.mark.unit +def test_the_header_names_the_analysts_as_users_select_them(tmp_path): + settings = {**SETTINGS, "analysts": ["market", "social", "news"]} + + write_report_tree(_state(), "NVDA", tmp_path, settings=settings, html=True) + + markdown = (tmp_path / "complete_report.md").read_text(encoding="utf-8") + assert "market, sentiment, news" in markdown and "social" not in markdown + page = (tmp_path / "complete_report.html").read_text(encoding="utf-8") + fields = re.findall(r'([^<]*)', page) + assert {"market", "sentiment", "news"} <= set(fields) and "social" not in page diff --git a/tradingagents/report_html.py b/tradingagents/report_html.py index 99987b456..a304b25c6 100644 --- a/tradingagents/report_html.py +++ b/tradingagents/report_html.py @@ -13,6 +13,7 @@ from importlib.resources import files from markdown_it import MarkdownIt from tradingagents.agents.rating import run_rating +from tradingagents.reporting import analyst_names # Ratings by direction, so the page can show which way the call leans. _TONE = {"Buy": "up", "Overweight": "up", "Hold": "level", "Underweight": "down", "Sell": "down"} @@ -228,7 +229,7 @@ def _run_details(final_state: dict, settings: dict | None) -> list[tuple[str, st for tier in ("deep", "quick"): provider = s(f"{tier}_think_provider") or s("llm_provider", "?") details.append((f"{tier.capitalize()} model", _fields([provider, s(f"{tier}_think_llm", "?")]))) - details.append(("Analysts", _fields(s("analysts") or []))) + details.append(("Analysts", _fields(analyst_names(s("analysts"))))) details.append(("Debate rounds", " ".join(( _group("research", _fields([s("max_debate_rounds", "?")])), _group("risk", _fields([s("max_risk_discuss_rounds", "?")])), diff --git a/tradingagents/reporting.py b/tradingagents/reporting.py index 50a414d9f..6f57e4a18 100644 --- a/tradingagents/reporting.py +++ b/tradingagents/reporting.py @@ -12,6 +12,11 @@ from pathlib import Path from tradingagents.agents.rating import run_rating +def analyst_names(keys) -> list[str]: + """The analysts as users select them: the sentiment analyst's key is "social".""" + return ["sentiment" if key == "social" else key for key in keys or []] + + def _header(ticker: str, final_state: dict, settings: dict | None) -> str: """The report's title and what produced it: analysis date, version, models, analysts, vendors.""" lines = [f"# Trading Analysis Report: {ticker}", ""] @@ -30,7 +35,7 @@ def _header(ticker: str, final_state: dict, settings: dict | None) -> str: models = (f"deep {deep_provider} {s('deep_think_llm', '?')}, " f"quick {quick_provider} {s('quick_think_llm', '?')}") lines.append(f"- TradingAgents {s('version', '?')}: {models}") - lines.append(f"- Analysts: {', '.join(s('analysts') or [])}; " + lines.append(f"- Analysts: {', '.join(analyst_names(s('analysts')))}; " f"research debate rounds {s('max_debate_rounds', '?')}, " f"risk debate rounds {s('max_risk_discuss_rounds', '?')}") vendors = {**(s("data_vendors") or {}), **(s("tool_vendors") or {})}