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:
Yijia-Xiao
2026-06-14 16:38:36 +00:00
parent cbc5f67d42
commit e3bc872982
59 changed files with 315 additions and 293 deletions

View File

@@ -1,4 +1,5 @@
import getpass
import requests
from rich.console import Console
from rich.panel import Panel

View File

@@ -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])

View File

@@ -1,6 +1,4 @@
from enum import Enum
from typing import List, Optional, Dict
from pydantic import BaseModel
class AnalystType(str, Enum):

View File

@@ -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 {

View File

@@ -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