diff --git a/tradingagents/ui/pages/todays_picks.py b/tradingagents/ui/pages/todays_picks.py index 5e8a0696..c54314ff 100644 --- a/tradingagents/ui/pages/todays_picks.py +++ b/tradingagents/ui/pages/todays_picks.py @@ -404,7 +404,11 @@ def render(): rank = rec.get("rank", idx + 1) score = rec.get("final_score", 0) confidence = rec.get("confidence", 0) - strategy = (rec.get("strategy_match") or rec.get("pipeline") or "unknown").replace("_", " ").title() + strategy = ( + (rec.get("strategy_match") or rec.get("pipeline") or "unknown") + .replace("_", " ") + .title() + ) entry_price = rec.get("entry_price", 0) reason = rec.get("reason", "No thesis provided.") company_name = rec.get("company_name", "") diff --git a/tradingagents/ui/theme.py b/tradingagents/ui/theme.py index 1bcfee12..5b19674a 100644 --- a/tradingagents/ui/theme.py +++ b/tradingagents/ui/theme.py @@ -5,6 +5,8 @@ Bloomberg/TradingView-inspired aesthetic with green/amber accents. Uses CSS variables for consistency and injects custom fonts. """ +import html as _html + # -- Color Tokens -- COLORS = { "bg_primary": "#0a0e17", @@ -588,36 +590,45 @@ def signal_card( strat_badge = "badge-blue" strat_css = "strat-volume" - # Risk level badge - risk_badge_html = "" - if risk_level: - risk_lower = risk_level.lower() - if risk_lower == "low": - risk_badge_html = f'{risk_level.title()}' - elif risk_lower == "moderate": - risk_badge_html = f'{risk_level.title()}' - elif risk_lower == "high": - risk_badge_html = f'{risk_level.title()}' - elif risk_lower == "speculative": - risk_badge_html = f'{risk_level.title()}' - entry_str = f"${entry_price:.2f}" if entry_price else "N/A" conf_pct = confidence * 10 + # Escape all LLM-generated text to prevent HTML injection / rendering breaks + safe_reason = _html.escape(reason) + safe_company = _html.escape(company_name) + safe_desc = _html.escape(description) + safe_strategy = _html.escape(strategy) + safe_risk = _html.escape(risk_level) + + # Risk level badge (built after escaping) + risk_badge_html = "" + if safe_risk: + risk_lower = safe_risk.lower() + if risk_lower == "low": + risk_badge_html = f'{safe_risk.title()}' + elif risk_lower == "moderate": + risk_badge_html = f'{safe_risk.title()}' + elif risk_lower == "high": + risk_badge_html = f'{safe_risk.title()}' + elif risk_lower == "speculative": + risk_badge_html = f'{safe_risk.title()}' + name_html = ( - f'{company_name}' + f'{safe_company}' if company_name and company_name != ticker else "" ) desc_html = ( f'