mirror of
https://github.com/TauricResearch/TradingAgents.git
synced 2026-09-27 23:12:39 +03:00
refactor(cli): move the live view to cli/display.py and the prompts to cli/prompts.py
- display.py holds the message buffer, layout, status tables and report panels, the analyst wall-time tracker (CLI-only, from graph/analyst_execution) and the one Console - utils.py is renamed prompts.py, which is what it holds; its analyst list is ANALYST_CHOICES, apart from display's ANALYST_ORDER - get_initial_analyst_node, a one-line helper with one caller, is inlined - the wall-time tracker tests sit with the other display tests, and tests import cli.prompts as prompts
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
from collections.abc import Iterable
|
||||
from dataclasses import dataclass
|
||||
from time import monotonic
|
||||
|
||||
from tradingagents.agents.analysts import fundamentals_analyst, market_analyst, news_analyst
|
||||
|
||||
@@ -73,64 +72,3 @@ def build_analyst_execution_plan(
|
||||
return AnalystExecutionPlan(specs=specs)
|
||||
|
||||
|
||||
def get_initial_analyst_node(plan: AnalystExecutionPlan) -> str:
|
||||
return plan.specs[0].agent_node
|
||||
|
||||
|
||||
class AnalystWallTimeTracker:
|
||||
def __init__(self, plan: AnalystExecutionPlan):
|
||||
self.plan = plan
|
||||
self._started_at: dict[str, float] = {}
|
||||
self._wall_times: dict[str, float] = {}
|
||||
|
||||
def mark_started(self, analyst_key: str, started_at: float | None = None) -> None:
|
||||
if analyst_key not in ANALYST_NODE_SPECS:
|
||||
raise ValueError(f"unknown analyst key: {analyst_key}")
|
||||
self._started_at.setdefault(analyst_key, monotonic() if started_at is None else started_at)
|
||||
|
||||
def mark_completed(
|
||||
self,
|
||||
analyst_key: str,
|
||||
completed_at: float | None = None,
|
||||
) -> None:
|
||||
if analyst_key not in ANALYST_NODE_SPECS:
|
||||
raise ValueError(f"unknown analyst key: {analyst_key}")
|
||||
if analyst_key in self._wall_times:
|
||||
return
|
||||
started_at = self._started_at.get(analyst_key)
|
||||
if started_at is None:
|
||||
return
|
||||
finished_at = monotonic() if completed_at is None else completed_at
|
||||
self._wall_times[analyst_key] = max(0.0, finished_at - started_at)
|
||||
|
||||
def format_summary(self) -> str:
|
||||
parts = []
|
||||
for spec in self.plan.specs:
|
||||
duration = self._wall_times.get(spec.key)
|
||||
if duration is not None:
|
||||
label = spec.agent_node.removesuffix(" Analyst")
|
||||
parts.append(f"{label} {duration:.2f}s")
|
||||
if not parts:
|
||||
return "Analyst wall time: pending"
|
||||
return "Analyst wall time: " + " | ".join(parts)
|
||||
|
||||
|
||||
def sync_analyst_tracker_from_chunk(
|
||||
tracker: AnalystWallTimeTracker,
|
||||
chunk: dict[str, str],
|
||||
now: float | None = None,
|
||||
) -> None:
|
||||
current_time = monotonic() if now is None else now
|
||||
active_found = False
|
||||
|
||||
for spec in tracker.plan.specs:
|
||||
has_report = bool(chunk.get(spec.report_key))
|
||||
|
||||
if has_report:
|
||||
tracker.mark_started(spec.key, started_at=current_time)
|
||||
tracker.mark_completed(spec.key, completed_at=current_time)
|
||||
continue
|
||||
|
||||
if not active_found:
|
||||
tracker.mark_started(spec.key, started_at=current_time)
|
||||
active_found = True
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
A single source of truth for which environment variable holds the API
|
||||
key for each supported LLM provider. Used by the CLI's interactive key
|
||||
prompt (cli/utils.ensure_api_key) and by anything else that needs to
|
||||
prompt (cli/prompts.ensure_api_key) and by anything else that needs to
|
||||
ask "does this provider require a key, and which env var is it?".
|
||||
|
||||
When adding a new provider, register its env var here so the CLI flow
|
||||
|
||||
@@ -182,7 +182,7 @@ MODEL_OPTIONS: ProviderModeOptions = {
|
||||
# endpoint is now configurable via OLLAMA_BASE_URL, so the same labels
|
||||
# apply whether the user runs ollama-serve on localhost or against a
|
||||
# remote host. The actual resolved endpoint is surfaced separately by
|
||||
# cli.utils.confirm_ollama_endpoint() right after provider selection.
|
||||
# cli.prompts.confirm_ollama_endpoint() right after provider selection.
|
||||
# "Custom model ID" lets users pick any model they have pulled via
|
||||
# `ollama pull` beyond the three suggested defaults.
|
||||
"ollama": {
|
||||
|
||||
Reference in New Issue
Block a user