mirror of
https://github.com/TauricResearch/TradingAgents.git
synced 2026-06-16 21:06:15 +03:00
chore(lint): make the repository ruff-clean under the strict select
Clear the deferred full-repo lint backlog so the whole tree passes the strict ruff select (E,W,F,I,B,UP,C4,SIM). Mechanical fixes dominate: import sorting, pep585/604 annotations, dropped dead imports, and whitespace. The few semantic changes are behavior-preserving: declare __all__ on the agent_utils and alpha_vantage re-export hubs; expand 'from x import *' to explicit names; use immutable tuple defaults instead of mutable list defaults; contextlib.suppress for try/except/pass; and narrow an over-broad assertRaises.
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import getpass
|
||||
|
||||
import requests
|
||||
from rich.console import Console
|
||||
from rich.panel import Panel
|
||||
|
||||
100
cli/main.py
100
cli/main.py
@@ -1,38 +1,53 @@
|
||||
from typing import Optional
|
||||
import os
|
||||
import datetime
|
||||
import typer
|
||||
import questionary
|
||||
from pathlib import Path
|
||||
from functools import wraps
|
||||
from rich.console import Console
|
||||
from rich.panel import Panel
|
||||
from rich.spinner import Spinner
|
||||
from rich.live import Live
|
||||
from rich.columns import Columns
|
||||
from rich.markdown import Markdown
|
||||
from rich.layout import Layout
|
||||
from rich.text import Text
|
||||
from rich.table import Table
|
||||
from collections import deque
|
||||
import os
|
||||
import time
|
||||
from rich.tree import Tree
|
||||
from collections import deque
|
||||
from functools import wraps
|
||||
from pathlib import Path
|
||||
|
||||
import typer
|
||||
from rich import box
|
||||
from rich.align import Align
|
||||
from rich.console import Console
|
||||
from rich.layout import Layout
|
||||
from rich.live import Live
|
||||
from rich.markdown import Markdown
|
||||
from rich.panel import Panel
|
||||
from rich.rule import Rule
|
||||
from rich.spinner import Spinner
|
||||
from rich.table import Table
|
||||
from rich.text import Text
|
||||
|
||||
from tradingagents.graph.trading_graph import TradingAgentsGraph
|
||||
from cli.announcements import display_announcements, fetch_announcements
|
||||
from cli.stats_handler import StatsCallbackHandler
|
||||
from cli.utils import (
|
||||
ask_anthropic_effort,
|
||||
ask_gemini_thinking_config,
|
||||
ask_glm_region,
|
||||
ask_minimax_region,
|
||||
ask_openai_reasoning_effort,
|
||||
ask_output_language,
|
||||
ask_qwen_region,
|
||||
confirm_ollama_endpoint,
|
||||
detect_asset_type,
|
||||
ensure_api_key,
|
||||
get_ticker,
|
||||
prompt_openai_compatible_url,
|
||||
resolve_backend_url,
|
||||
select_analysts,
|
||||
select_deep_thinking_agent,
|
||||
select_llm_provider,
|
||||
select_research_depth,
|
||||
select_shallow_thinking_agent,
|
||||
)
|
||||
from tradingagents.default_config import DEFAULT_CONFIG
|
||||
from tradingagents.graph.analyst_execution import (
|
||||
AnalystWallTimeTracker,
|
||||
build_analyst_execution_plan,
|
||||
get_initial_analyst_node,
|
||||
sync_analyst_tracker_from_chunk,
|
||||
)
|
||||
from tradingagents.default_config import DEFAULT_CONFIG
|
||||
from cli.models import AnalystType
|
||||
from cli.utils import *
|
||||
from cli.announcements import fetch_announcements, display_announcements
|
||||
from cli.stats_handler import StatsCallbackHandler
|
||||
from tradingagents.graph.trading_graph import TradingAgentsGraph
|
||||
|
||||
console = Console()
|
||||
|
||||
@@ -169,7 +184,7 @@ class MessageBuffer:
|
||||
if content is not None:
|
||||
latest_section = section
|
||||
latest_content = content
|
||||
|
||||
|
||||
if latest_section and latest_content:
|
||||
# Format the current section for display
|
||||
section_titles = {
|
||||
@@ -466,7 +481,7 @@ def update_display(layout, spinner_text=None, stats_handler=None, start_time=Non
|
||||
def get_user_selections():
|
||||
"""Get all user selections before starting the analysis display."""
|
||||
# Display ASCII art welcome message
|
||||
with open(Path(__file__).parent / "static" / "welcome.txt", "r", encoding="utf-8") as f:
|
||||
with open(Path(__file__).parent / "static" / "welcome.txt", encoding="utf-8") as f:
|
||||
welcome_ascii = f.read()
|
||||
|
||||
# Create welcome box content
|
||||
@@ -922,9 +937,12 @@ def update_analyst_statuses(message_buffer, chunk, wall_time_tracker=None):
|
||||
message_buffer.update_agent_status(agent_name, "pending")
|
||||
|
||||
# When all analysts complete, transition research team to in_progress
|
||||
if not found_active and selected:
|
||||
if message_buffer.agent_status.get("Bull Researcher") == "pending":
|
||||
message_buffer.update_agent_status("Bull Researcher", "in_progress")
|
||||
if (
|
||||
not found_active
|
||||
and selected
|
||||
and message_buffer.agent_status.get("Bull Researcher") == "pending"
|
||||
):
|
||||
message_buffer.update_agent_status("Bull Researcher", "in_progress")
|
||||
|
||||
def extract_content_string(content):
|
||||
"""Extract string content from various message formats.
|
||||
@@ -1064,7 +1082,7 @@ def run_analysis(checkpoint: bool = False):
|
||||
with open(log_file, "a", encoding="utf-8") as f:
|
||||
f.write(f"{timestamp} [{message_type}] {content}\n")
|
||||
return wrapper
|
||||
|
||||
|
||||
def save_tool_call_decorator(obj, func_name):
|
||||
func = getattr(obj, func_name)
|
||||
@wraps(func)
|
||||
@@ -1097,7 +1115,7 @@ def run_analysis(checkpoint: bool = False):
|
||||
# Now start the display layout
|
||||
layout = create_layout()
|
||||
|
||||
with Live(layout, refresh_per_second=4) as live:
|
||||
with Live(layout, refresh_per_second=4):
|
||||
# Initial display
|
||||
update_display(layout, stats_handler=stats_handler, start_time=start_time)
|
||||
|
||||
@@ -1232,16 +1250,15 @@ def run_analysis(checkpoint: bool = False):
|
||||
message_buffer.update_report_section(
|
||||
"final_trade_decision", f"### Neutral Analyst Analysis\n{neu_hist}"
|
||||
)
|
||||
if judge:
|
||||
if message_buffer.agent_status.get("Portfolio Manager") != "completed":
|
||||
message_buffer.update_agent_status("Portfolio Manager", "in_progress")
|
||||
message_buffer.update_report_section(
|
||||
"final_trade_decision", f"### Portfolio Manager Decision\n{judge}"
|
||||
)
|
||||
message_buffer.update_agent_status("Aggressive Analyst", "completed")
|
||||
message_buffer.update_agent_status("Conservative Analyst", "completed")
|
||||
message_buffer.update_agent_status("Neutral Analyst", "completed")
|
||||
message_buffer.update_agent_status("Portfolio Manager", "completed")
|
||||
if judge and message_buffer.agent_status.get("Portfolio Manager") != "completed":
|
||||
message_buffer.update_agent_status("Portfolio Manager", "in_progress")
|
||||
message_buffer.update_report_section(
|
||||
"final_trade_decision", f"### Portfolio Manager Decision\n{judge}"
|
||||
)
|
||||
message_buffer.update_agent_status("Aggressive Analyst", "completed")
|
||||
message_buffer.update_agent_status("Conservative Analyst", "completed")
|
||||
message_buffer.update_agent_status("Neutral Analyst", "completed")
|
||||
message_buffer.update_agent_status("Portfolio Manager", "completed")
|
||||
|
||||
# Update the display
|
||||
update_display(layout, stats_handler=stats_handler, start_time=start_time)
|
||||
@@ -1253,7 +1270,6 @@ def run_analysis(checkpoint: bool = False):
|
||||
final_state = {}
|
||||
for chunk in trace:
|
||||
final_state.update(chunk)
|
||||
decision = graph.process_signal(final_state["final_trade_decision"])
|
||||
|
||||
# Update all agent statuses to completed
|
||||
for agent in message_buffer.agent_status:
|
||||
@@ -1265,7 +1281,7 @@ def run_analysis(checkpoint: bool = False):
|
||||
message_buffer.add_message("System", analyst_wall_time_tracker.format_summary())
|
||||
|
||||
# Update final report sections
|
||||
for section in message_buffer.report_sections.keys():
|
||||
for section in message_buffer.report_sections:
|
||||
if section in final_state:
|
||||
message_buffer.update_report_section(section, final_state[section])
|
||||
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
from enum import Enum
|
||||
from typing import List, Optional, Dict
|
||||
from pydantic import BaseModel
|
||||
|
||||
|
||||
class AnalystType(str, Enum):
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import threading
|
||||
from typing import Any, Dict, List, Union
|
||||
from typing import Any
|
||||
|
||||
from langchain_core.callbacks import BaseCallbackHandler
|
||||
from langchain_core.outputs import LLMResult
|
||||
from langchain_core.messages import AIMessage
|
||||
from langchain_core.outputs import LLMResult
|
||||
|
||||
|
||||
class StatsCallbackHandler(BaseCallbackHandler):
|
||||
@@ -19,8 +19,8 @@ class StatsCallbackHandler(BaseCallbackHandler):
|
||||
|
||||
def on_llm_start(
|
||||
self,
|
||||
serialized: Dict[str, Any],
|
||||
prompts: List[str],
|
||||
serialized: dict[str, Any],
|
||||
prompts: list[str],
|
||||
**kwargs: Any,
|
||||
) -> None:
|
||||
"""Increment LLM call counter when an LLM starts."""
|
||||
@@ -29,8 +29,8 @@ class StatsCallbackHandler(BaseCallbackHandler):
|
||||
|
||||
def on_chat_model_start(
|
||||
self,
|
||||
serialized: Dict[str, Any],
|
||||
messages: List[List[Any]],
|
||||
serialized: dict[str, Any],
|
||||
messages: list[list[Any]],
|
||||
**kwargs: Any,
|
||||
) -> None:
|
||||
"""Increment LLM call counter when a chat model starts."""
|
||||
@@ -57,7 +57,7 @@ class StatsCallbackHandler(BaseCallbackHandler):
|
||||
|
||||
def on_tool_start(
|
||||
self,
|
||||
serialized: Dict[str, Any],
|
||||
serialized: dict[str, Any],
|
||||
input_str: str,
|
||||
**kwargs: Any,
|
||||
) -> None:
|
||||
@@ -65,7 +65,7 @@ class StatsCallbackHandler(BaseCallbackHandler):
|
||||
with self._lock:
|
||||
self.tool_calls += 1
|
||||
|
||||
def get_stats(self) -> Dict[str, Any]:
|
||||
def get_stats(self) -> dict[str, Any]:
|
||||
"""Return current statistics."""
|
||||
with self._lock:
|
||||
return {
|
||||
|
||||
13
cli/utils.py
13
cli/utils.py
@@ -1,6 +1,5 @@
|
||||
import os
|
||||
from pathlib import Path
|
||||
from typing import List, Optional, Tuple, Dict
|
||||
|
||||
import questionary
|
||||
from dotenv import find_dotenv, set_key
|
||||
@@ -89,8 +88,8 @@ def detect_asset_type(ticker: str) -> AssetType:
|
||||
|
||||
|
||||
def filter_analysts_for_asset_type(
|
||||
analysts: List[AnalystType], asset_type: AssetType
|
||||
) -> List[AnalystType]:
|
||||
analysts: list[AnalystType], asset_type: AssetType
|
||||
) -> list[AnalystType]:
|
||||
if asset_type != AssetType.CRYPTO:
|
||||
return analysts
|
||||
return [
|
||||
@@ -133,7 +132,7 @@ def get_analysis_date() -> str:
|
||||
return date.strip()
|
||||
|
||||
|
||||
def select_analysts(asset_type: AssetType = AssetType.STOCK) -> List[AnalystType]:
|
||||
def select_analysts(asset_type: AssetType = AssetType.STOCK) -> list[AnalystType]:
|
||||
"""Select analysts using an interactive checkbox."""
|
||||
available_analysts = filter_analysts_for_asset_type(
|
||||
[value for _, value in ANALYST_ORDER],
|
||||
@@ -197,7 +196,7 @@ def select_research_depth() -> int:
|
||||
return choice
|
||||
|
||||
|
||||
def _fetch_openrouter_models() -> List[Tuple[str, str]]:
|
||||
def _fetch_openrouter_models() -> list[tuple[str, str]]:
|
||||
"""Fetch available models from the OpenRouter API."""
|
||||
import requests
|
||||
try:
|
||||
@@ -377,7 +376,7 @@ def select_llm_provider() -> tuple[str, str | None]:
|
||||
]
|
||||
),
|
||||
).ask()
|
||||
|
||||
|
||||
if choice is None:
|
||||
console.print("\n[red]No LLM provider selected. Exiting...[/red]")
|
||||
exit(1)
|
||||
@@ -556,7 +555,7 @@ def confirm_ollama_endpoint(url: str) -> None:
|
||||
)
|
||||
|
||||
|
||||
def ensure_api_key(provider: str) -> Optional[str]:
|
||||
def ensure_api_key(provider: str) -> str | None:
|
||||
"""Make sure the API key for `provider` is available in the environment.
|
||||
|
||||
If the env var is already set, returns its value untouched. Otherwise
|
||||
|
||||
Reference in New Issue
Block a user