UTF-8 encoding to fix error with saving documents on Windows
This commit is contained in:
parent
f362a160c3
commit
3fc9609387
42
cli/main.py
42
cli/main.py
|
|
@ -1,11 +1,27 @@
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
import datetime
|
import datetime
|
||||||
|
import sys
|
||||||
import typer
|
import typer
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from functools import wraps
|
from functools import wraps
|
||||||
from rich.console import Console
|
from rich.console import Console
|
||||||
from dotenv import load_dotenv
|
from dotenv import load_dotenv
|
||||||
|
|
||||||
|
def configure_stdio_encoding() -> None:
|
||||||
|
"""Force UTF-8 for terminal output on Windows-friendly Python streams."""
|
||||||
|
for stream_name in ("stdout", "stderr"):
|
||||||
|
stream = getattr(sys, stream_name, None)
|
||||||
|
if stream is None or not hasattr(stream, "reconfigure"):
|
||||||
|
continue
|
||||||
|
try:
|
||||||
|
stream.reconfigure(encoding="utf-8", errors="replace")
|
||||||
|
except ValueError:
|
||||||
|
# Some redirected streams do not allow reconfiguration.
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
configure_stdio_encoding()
|
||||||
|
|
||||||
# Load environment variables from .env file
|
# Load environment variables from .env file
|
||||||
load_dotenv()
|
load_dotenv()
|
||||||
from rich.panel import Panel
|
from rich.panel import Panel
|
||||||
|
|
@ -623,19 +639,19 @@ def save_report_to_disk(final_state, ticker: str, save_path: Path):
|
||||||
analyst_parts = []
|
analyst_parts = []
|
||||||
if final_state.get("market_report"):
|
if final_state.get("market_report"):
|
||||||
analysts_dir.mkdir(exist_ok=True)
|
analysts_dir.mkdir(exist_ok=True)
|
||||||
(analysts_dir / "market.md").write_text(final_state["market_report"])
|
(analysts_dir / "market.md").write_text(final_state["market_report"], encoding="utf-8")
|
||||||
analyst_parts.append(("Market Analyst", final_state["market_report"]))
|
analyst_parts.append(("Market Analyst", final_state["market_report"]))
|
||||||
if final_state.get("sentiment_report"):
|
if final_state.get("sentiment_report"):
|
||||||
analysts_dir.mkdir(exist_ok=True)
|
analysts_dir.mkdir(exist_ok=True)
|
||||||
(analysts_dir / "sentiment.md").write_text(final_state["sentiment_report"])
|
(analysts_dir / "sentiment.md").write_text(final_state["sentiment_report"], encoding="utf-8")
|
||||||
analyst_parts.append(("Social Analyst", final_state["sentiment_report"]))
|
analyst_parts.append(("Social Analyst", final_state["sentiment_report"]))
|
||||||
if final_state.get("news_report"):
|
if final_state.get("news_report"):
|
||||||
analysts_dir.mkdir(exist_ok=True)
|
analysts_dir.mkdir(exist_ok=True)
|
||||||
(analysts_dir / "news.md").write_text(final_state["news_report"])
|
(analysts_dir / "news.md").write_text(final_state["news_report"], encoding="utf-8")
|
||||||
analyst_parts.append(("News Analyst", final_state["news_report"]))
|
analyst_parts.append(("News Analyst", final_state["news_report"]))
|
||||||
if final_state.get("fundamentals_report"):
|
if final_state.get("fundamentals_report"):
|
||||||
analysts_dir.mkdir(exist_ok=True)
|
analysts_dir.mkdir(exist_ok=True)
|
||||||
(analysts_dir / "fundamentals.md").write_text(final_state["fundamentals_report"])
|
(analysts_dir / "fundamentals.md").write_text(final_state["fundamentals_report"], encoding="utf-8")
|
||||||
analyst_parts.append(("Fundamentals Analyst", final_state["fundamentals_report"]))
|
analyst_parts.append(("Fundamentals Analyst", final_state["fundamentals_report"]))
|
||||||
if analyst_parts:
|
if analyst_parts:
|
||||||
content = "\n\n".join(f"### {name}\n{text}" for name, text in analyst_parts)
|
content = "\n\n".join(f"### {name}\n{text}" for name, text in analyst_parts)
|
||||||
|
|
@ -648,15 +664,15 @@ def save_report_to_disk(final_state, ticker: str, save_path: Path):
|
||||||
research_parts = []
|
research_parts = []
|
||||||
if debate.get("bull_history"):
|
if debate.get("bull_history"):
|
||||||
research_dir.mkdir(exist_ok=True)
|
research_dir.mkdir(exist_ok=True)
|
||||||
(research_dir / "bull.md").write_text(debate["bull_history"])
|
(research_dir / "bull.md").write_text(debate["bull_history"], encoding="utf-8")
|
||||||
research_parts.append(("Bull Researcher", debate["bull_history"]))
|
research_parts.append(("Bull Researcher", debate["bull_history"]))
|
||||||
if debate.get("bear_history"):
|
if debate.get("bear_history"):
|
||||||
research_dir.mkdir(exist_ok=True)
|
research_dir.mkdir(exist_ok=True)
|
||||||
(research_dir / "bear.md").write_text(debate["bear_history"])
|
(research_dir / "bear.md").write_text(debate["bear_history"], encoding="utf-8")
|
||||||
research_parts.append(("Bear Researcher", debate["bear_history"]))
|
research_parts.append(("Bear Researcher", debate["bear_history"]))
|
||||||
if debate.get("judge_decision"):
|
if debate.get("judge_decision"):
|
||||||
research_dir.mkdir(exist_ok=True)
|
research_dir.mkdir(exist_ok=True)
|
||||||
(research_dir / "manager.md").write_text(debate["judge_decision"])
|
(research_dir / "manager.md").write_text(debate["judge_decision"], encoding="utf-8")
|
||||||
research_parts.append(("Research Manager", debate["judge_decision"]))
|
research_parts.append(("Research Manager", debate["judge_decision"]))
|
||||||
if research_parts:
|
if research_parts:
|
||||||
content = "\n\n".join(f"### {name}\n{text}" for name, text in research_parts)
|
content = "\n\n".join(f"### {name}\n{text}" for name, text in research_parts)
|
||||||
|
|
@ -666,7 +682,7 @@ def save_report_to_disk(final_state, ticker: str, save_path: Path):
|
||||||
if final_state.get("trader_investment_plan"):
|
if final_state.get("trader_investment_plan"):
|
||||||
trading_dir = save_path / "3_trading"
|
trading_dir = save_path / "3_trading"
|
||||||
trading_dir.mkdir(exist_ok=True)
|
trading_dir.mkdir(exist_ok=True)
|
||||||
(trading_dir / "trader.md").write_text(final_state["trader_investment_plan"])
|
(trading_dir / "trader.md").write_text(final_state["trader_investment_plan"], encoding="utf-8")
|
||||||
sections.append(f"## III. Trading Team Plan\n\n### Trader\n{final_state['trader_investment_plan']}")
|
sections.append(f"## III. Trading Team Plan\n\n### Trader\n{final_state['trader_investment_plan']}")
|
||||||
|
|
||||||
# 4. Risk Management
|
# 4. Risk Management
|
||||||
|
|
@ -676,15 +692,15 @@ def save_report_to_disk(final_state, ticker: str, save_path: Path):
|
||||||
risk_parts = []
|
risk_parts = []
|
||||||
if risk.get("aggressive_history"):
|
if risk.get("aggressive_history"):
|
||||||
risk_dir.mkdir(exist_ok=True)
|
risk_dir.mkdir(exist_ok=True)
|
||||||
(risk_dir / "aggressive.md").write_text(risk["aggressive_history"])
|
(risk_dir / "aggressive.md").write_text(risk["aggressive_history"], encoding="utf-8")
|
||||||
risk_parts.append(("Aggressive Analyst", risk["aggressive_history"]))
|
risk_parts.append(("Aggressive Analyst", risk["aggressive_history"]))
|
||||||
if risk.get("conservative_history"):
|
if risk.get("conservative_history"):
|
||||||
risk_dir.mkdir(exist_ok=True)
|
risk_dir.mkdir(exist_ok=True)
|
||||||
(risk_dir / "conservative.md").write_text(risk["conservative_history"])
|
(risk_dir / "conservative.md").write_text(risk["conservative_history"], encoding="utf-8")
|
||||||
risk_parts.append(("Conservative Analyst", risk["conservative_history"]))
|
risk_parts.append(("Conservative Analyst", risk["conservative_history"]))
|
||||||
if risk.get("neutral_history"):
|
if risk.get("neutral_history"):
|
||||||
risk_dir.mkdir(exist_ok=True)
|
risk_dir.mkdir(exist_ok=True)
|
||||||
(risk_dir / "neutral.md").write_text(risk["neutral_history"])
|
(risk_dir / "neutral.md").write_text(risk["neutral_history"], encoding="utf-8")
|
||||||
risk_parts.append(("Neutral Analyst", risk["neutral_history"]))
|
risk_parts.append(("Neutral Analyst", risk["neutral_history"]))
|
||||||
if risk_parts:
|
if risk_parts:
|
||||||
content = "\n\n".join(f"### {name}\n{text}" for name, text in risk_parts)
|
content = "\n\n".join(f"### {name}\n{text}" for name, text in risk_parts)
|
||||||
|
|
@ -694,12 +710,12 @@ def save_report_to_disk(final_state, ticker: str, save_path: Path):
|
||||||
if risk.get("judge_decision"):
|
if risk.get("judge_decision"):
|
||||||
portfolio_dir = save_path / "5_portfolio"
|
portfolio_dir = save_path / "5_portfolio"
|
||||||
portfolio_dir.mkdir(exist_ok=True)
|
portfolio_dir.mkdir(exist_ok=True)
|
||||||
(portfolio_dir / "decision.md").write_text(risk["judge_decision"])
|
(portfolio_dir / "decision.md").write_text(risk["judge_decision"], encoding="utf-8")
|
||||||
sections.append(f"## V. Portfolio Manager Decision\n\n### Portfolio Manager\n{risk['judge_decision']}")
|
sections.append(f"## V. Portfolio Manager Decision\n\n### Portfolio Manager\n{risk['judge_decision']}")
|
||||||
|
|
||||||
# Write consolidated report
|
# Write consolidated report
|
||||||
header = f"# Trading Analysis Report: {ticker}\n\nGenerated: {datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n\n"
|
header = f"# Trading Analysis Report: {ticker}\n\nGenerated: {datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n\n"
|
||||||
(save_path / "complete_report.md").write_text(header + "\n\n".join(sections))
|
(save_path / "complete_report.md").write_text(header + "\n\n".join(sections), encoding="utf-8")
|
||||||
return save_path / "complete_report.md"
|
return save_path / "complete_report.md"
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue