- Wrap each event-type branch (LLM start/end, tool start/end) in try/except
to prevent a single unexpected object shape from crashing the streaming loop
- Add _safe_dict() helper to guard response_metadata and usage_metadata
access — some providers return non-dict types (bound methods, etc.)
- Fix potential_text extraction: check for None AND callable before using
- Ensure all event IDs use .get() with fallback to prevent KeyError
- Fix test file: remove hardcoded /Users/Ahmet/ path, add edge-case tests
for non-dict metadata, tool events, and unknown event types
- All 725 unit tests pass, TypeScript compiles clean
Co-authored-by: aguzererler <6199053+aguzererler@users.noreply.github.com>
Agent-Logs-Url: https://github.com/aguzererler/TradingAgents/sessions/fe6575b5-c03b-4037-bd98-a94303ae8313
1. Run buttons: only the triggered button shows spinner, others disabled
2. Backend: enhanced prompt extraction with multiple fallback paths
(data.messages, data.input.messages, data.input, data.kwargs.messages)
and raw dump fallback; improved response extraction for edge cases
3. Portfolio viewer: new PortfolioViewer component with holdings table,
trade history, and summary tabs; portfolio dropdown with auto-load;
Wallet sidebar icon now navigates to portfolio page
4. Parameter inputs: collapsible panel with date/ticker/portfolio_id;
validation prevents running without required fields per run type
Co-authored-by: aguzererler <6199053+aguzererler@users.noreply.github.com>
Agent-Logs-Url: https://github.com/aguzererler/TradingAgents/sessions/ffa268c8-e97c-4335-9bce-19bba583bea9
Backend:
- Extract full prompt from all LLM messages (not just first)
- Add prompt/response fields to streamed event payloads
- Improve model name extraction with multiple fallback strategies
- Add run_portfolio and run_auto streaming methods
- Wire portfolio/auto in websocket router
- New tool_result event type for tool completion
Frontend:
- Add full event detail modal with tabs (Prompt, Response, Summary, Metrics)
- Show actual prompt content in drawer instead of "Prompting unknown..."
- Add Scan, Pipeline, Portfolio, Auto buttons to control panel
- Fix node animation: completed nodes never revert to running
- Handle tool_result type for marking tool nodes as done
- Drawer events have "Full Detail →" button to open modal
Co-authored-by: aguzererler <6199053+aguzererler@users.noreply.github.com>
Agent-Logs-Url: https://github.com/aguzererler/TradingAgents/sessions/7997c579-ab7e-4071-afd0-18703a8e5618
The agent_os/, agent_os/backend/, agent_os/backend/routes/, and
agent_os/backend/services/ directories were missing __init__.py,
causing `from agent_os.backend.routes import ...` to fail with
ModuleNotFoundError when running `python agent_os/backend/main.py`.
Co-authored-by: aguzererler <6199053+aguzererler@users.noreply.github.com>
Agent-Logs-Url: https://github.com/aguzererler/TradingAgents/sessions/4b002166-5cc2-4a75-aa01-14d7b5d8d8bc
1. Terminal: remove inline prompts/full text; show short summary per event;
click any event to open detail drawer with full request/response/model/metrics
2. Fix node "thinking" animation: shimmer only when status=running;
on_chat_model_end (result) transitions node to completed, animation stops
3. Link nodes to events: clicking a graph node opens the drawer showing
all events for that node (prompts, tool calls, results)
4. Upgrade Vite 5→8.0.1, @vitejs/plugin-react→5.2.0;
update tsconfig moduleResolution to "bundler" for Vite 8 compat
Co-authored-by: aguzererler <6199053+aguzererler@users.noreply.github.com>
Agent-Logs-Url: https://github.com/aguzererler/TradingAgents/sessions/93c31c35-9509-4254-96fd-6f47aad07927
Backend:
- Replace bare print() with structured logging module
- Include LLM prompt snippets and response content in streamed events
- Extract proper node names from LangGraph metadata (langgraph_node)
- Add latency tracking (start/end time per node)
- Add tool input/output content in events
- Add system log event type for informational messages
- Stream on_tool_end events for tool results
Frontend:
- Fix node disappearing/reappearing: use useNodesState/useEdgesState + useEffect
for incremental updates instead of useMemo that rebuilt all nodes on each event
- Fix duplicate node creation: use useRef to track seen node IDs persistently
- Fix useAgentStream reconnection loop: remove stale `status` from connect deps
- Use statusRef to avoid stale closure in onclose handler
- Add auto-scroll to terminal, event count, type labels/colors
- Show prompt snippets, tool I/O, and response content in terminal
- Handle 'log' event type
Packages:
- Update all npm deps to latest compatible minor versions
- Remove node_modules from git tracking, add to .gitignore
Co-authored-by: aguzererler <6199053+aguzererler@users.noreply.github.com>
Agent-Logs-Url: https://github.com/aguzererler/TradingAgents/sessions/5c511c4e-5172-4eda-b6de-aefa1859e8ac
- add root agent_os/README.md with system architecture and setup guides
- update DESIGN.md with port 8088 migration and network configurations
- document real-time DAG rendering and high-fidelity risk metrics
- move backend port from 8001 to 8088
- update frontend to use 127.0.0.1 explicitly instead of localhost
- add request/response logging middleware to backend
- fix explicit CORS origin matching for browser compatibility
- update portfolio summary route to check 'summary/' directory for scan results
- enhance LangGraph event mapping to extract functional node names from metadata
- fix initial state keys for ScannerGraph to match TradingAgents internals
- add /api/portfolios/{id}/summary endpoint to backend
- parse Sharpe and Drawdown from latest portfolio snapshots
- parse Market Regime from macro_scan/scan_summary.json
- update MetricHeader to fetch real-time metrics with polling
- pass portfolio_id to dashboard and trigger methods
- scaffold Vite + React + TypeScript frontend with Chakra UI and React Flow
- implement AgentGraph, MetricHeader, and Dashboard components
- connect FastAPI to live LangGraph events via astream_events
- implement real-time event mapping for 'scan' and 'pipeline'
- refactor run storage for shared access between REST and WebSockets
- implement FastAPI backend with REST and WebSocket streaming
- add node-level metrics (tokens, latency) to event protocol
- design literal graph and top 3 metrics (Sharpe, Regime, Drawdown)
- scaffold React frontend with Chakra UI and useAgentStream hook
- add DESIGN.md and .env.example
In langchain_core >=1.0 plain Generation no longer stores a .message
attribute - that only exists on ChatGeneration. Tests were constructing
Generation(message=AIMessage(...)) which silently dropped the message,
making hasattr(generation, "message") return False and skipping the
token-counting path (all usage assertions failed with 0).
- Replace Generation(message=...) with ChatGeneration(message=AIMessage(...))
in test_stats_handler_on_llm_end_with_usage and thread_safety test
- Use UsageMetadata(input_tokens=N, output_tokens=N, total_tokens=N)
instead of bare dict (total_tokens is required in langchain_core 1.2+)
- Pass usage_metadata via AIMessage constructor instead of post-init
attribute assignment (avoids pydantic validation bypass)
- Keep Generation(text=...) in test_stats_handler_on_llm_end_no_usage
(correctly tests the "no usage" branch — plain Generation has no .message)
Co-authored-by: aguzererler <6199053+aguzererler@users.noreply.github.com>
Agent-Logs-Url: https://github.com/aguzererler/TradingAgents/sessions/ce079791-08ef-4f2e-9f31-a1ae6a26b4cb
Before this change, the pipeline showed a generic 'Analyzing...' spinner
for the entire multi-ticker run with no way to know which ticker was
processing or whether anything was actually working.
Changes:
- macro_bridge.py:
- run_ticker_analysis: logs '▶ Starting', '✓ complete in Xs', '✗ FAILED'
with elapsed time per ticker using logger.info/logger.error
- run_all_tickers: replaced asyncio.gather (swallows all progress) with
asyncio.as_completed + optional on_ticker_done(result, done, total)
callback; uses asyncio.Semaphore for max_concurrent control
- Added time and Callable imports
- cli/main.py run_pipeline:
- Replaced Live(Spinner) with Rich Progress bar (spinner + bar + counter
+ elapsed time)
- Prints '▷ Queued: TICKER' before analysis starts for each ticker
- on_ticker_done callback prints '✓ TICKER (N/M, Xs elapsed) → decision'
or '✗ TICKER failed ...' immediately as each ticker finishes
- Prints total elapsed time when all tickers complete
The pipeline was emitting hundreds of errors:
'Invalid number of return arguments after parsing column name: Date'
Root cause: after _clean_dataframe() lowercases all columns, stockstats.wrap()
promotes 'date' to the DataFrame index. Subsequent df['Date'] access caused
stockstats to try parsing 'Date' as a technical indicator name.
- stockstats_utils.py + y_finance.py: use df.index.strftime() instead of
df['Date'] after wrap()
- Eliminates duplicated 30-line download+cache boilerplate in two places
- Cache filename is always derived from today's date — hardcoded stale date
'2015-01-01-2025-03-25' in local mode is gone
- Corruption/truncation detection: files <50 rows or unparseable are deleted
and re-fetched rather than silently returning bad data
- Drops on_bad_lines='skip' — malformed CSVs now raise instead of silently
dropping rows that would distort indicator calculations
- Defined in stockstats_utils.py; raised instead of print()+return ''
- get_stockstats_indicator now raises YFinanceError on failure so errors
surface to callers rather than delivering empty strings to LLM agents
- interface.py route_to_vendor now catches YFinanceError alongside
AlphaVantageError and FinnhubError — failures appear in observability
telemetry and can trigger vendor fallback
- _filter_csv_by_date_range: replaced df.columns[0] positional assumption
with explicit search for 'time'/'timestamp'/'date' column
- ValueError re-raised (not swallowed) so bad API response shape is visible
- Replaced all print() calls in changed files with logging.getLogger()
- Added logging import + logger to alpha_vantage_common
- tests/unit/test_incident_fixes.py: 12 new unit tests covering all fixes
(dynamic cache filename, corruption re-fetch, YFinanceError propagation,
explicit column lookup, empty download raises)
- tests/integration/test_stockstats_live.py: 11 live tests against real
yfinance API (all major indicators, weekend N/A, regression guard)
- All 70 tests pass (59 unit + 11 live integration)
- y_finance.py: replace print() with logger.warning() in bulk-stats fallback
- macro_bridge.py: add elapsed_seconds field to TickerResult, populate in
run_ticker_analysis (success + error paths)
- cli/main.py: move inline 'import time as _time' and rich.progress imports
to module level; use result.elapsed_seconds for accurate per-ticker timing
Co-authored-by: aguzererler <6199053+aguzererler@users.noreply.github.com>
Agent-Logs-Url: https://github.com/aguzererler/TradingAgents/sessions/68fcf34c-8d55-4436-b743-f79fff68713f
Before this change, the pipeline showed a generic 'Analyzing...' spinner
for the entire multi-ticker run with no way to know which ticker was
processing or whether anything was actually working.
Changes:
- macro_bridge.py:
- run_ticker_analysis: logs '▶ Starting', '✓ complete in Xs', '✗ FAILED'
with elapsed time per ticker using logger.info/logger.error
- run_all_tickers: replaced asyncio.gather (swallows all progress) with
asyncio.as_completed + optional on_ticker_done(result, done, total)
callback; uses asyncio.Semaphore for max_concurrent control
- Added time and Callable imports
- cli/main.py run_pipeline:
- Replaced Live(Spinner) with Rich Progress bar (spinner + bar + counter
+ elapsed time)
- Prints '▷ Queued: TICKER' before analysis starts for each ticker
- on_ticker_done callback prints '✓ TICKER (N/M, Xs elapsed) → decision'
or '✗ TICKER failed ...' immediately as each ticker finishes
- Prints total elapsed time when all tickers complete
## Problem (Incident Post-mortem)
The pipeline was emitting hundreds of errors:
'Invalid number of return arguments after parsing column name: Date'
Root cause: after _clean_dataframe() lowercases all columns, stockstats.wrap()
promotes 'date' to the DataFrame index. Subsequent df['Date'] access caused
stockstats to try parsing 'Date' as a technical indicator name.
## Fixes
### 1. Fix df['Date'] stockstats bug (already shipped in prior commit)
- stockstats_utils.py + y_finance.py: use df.index.strftime() instead of
df['Date'] after wrap()
### 2. Extract _load_or_fetch_ohlcv() — single OHLCV authority
- Eliminates duplicated 30-line download+cache boilerplate in two places
- Cache filename is always derived from today's date — hardcoded stale date
'2015-01-01-2025-03-25' in local mode is gone
- Corruption/truncation detection: files <50 rows or unparseable are deleted
and re-fetched rather than silently returning bad data
- Drops on_bad_lines='skip' — malformed CSVs now raise instead of silently
dropping rows that would distort indicator calculations
### 3. YFinanceError typed exception
- Defined in stockstats_utils.py; raised instead of print()+return ''
- get_stockstats_indicator now raises YFinanceError on failure so errors
surface to callers rather than delivering empty strings to LLM agents
- interface.py route_to_vendor now catches YFinanceError alongside
AlphaVantageError and FinnhubError — failures appear in observability
telemetry and can trigger vendor fallback
### 4. Explicit date column discovery in alpha_vantage_common
- _filter_csv_by_date_range: replaced df.columns[0] positional assumption
with explicit search for 'time'/'timestamp'/'date' column
- ValueError re-raised (not swallowed) so bad API response shape is visible
### 5. Structured logging
- Replaced all print() calls in changed files with logging.getLogger()
- Added logging import + logger to alpha_vantage_common
## Tests
- tests/unit/test_incident_fixes.py: 12 new unit tests covering all fixes
(dynamic cache filename, corruption re-fetch, YFinanceError propagation,
explicit column lookup, empty download raises)
- tests/integration/test_stockstats_live.py: 11 live tests against real
yfinance API (all major indicators, weekend N/A, regression guard)
- All 70 tests pass (59 unit + 11 live integration)
- Removed unused `import time` from `tradingagents/agents/analysts/news_analyst.py`
- Verified file syntax with `py_compile`
- Confirmed that the import was successfully removed
Co-authored-by: aguzererler <6199053+aguzererler@users.noreply.github.com>
Implement comprehensive unit tests for the `_safe_fmt` utility function
to ensure robust handling of numeric formatting and edge cases.
- Test None values and custom fallbacks
- Test various numeric types (int, float, string)
- Test custom format strings
- Test error handling for invalid types
Co-authored-by: aguzererler <6199053+aguzererler@users.noreply.github.com>
Replaced the inefficient `iterrows()` loop with vectorized operations:
`df.set_index("Date")[indicator].fillna("N/A").astype(str).to_dict()`
This change improves performance while maintaining the exact original behavior for NaN values and string conversion.
Co-authored-by: aguzererler <6199053+aguzererler@users.noreply.github.com>
Removed the unused `json` import in `tradingagents/agents/analysts/market_analyst.py` to reduce visual clutter and namespace pollution.
Co-authored-by: aguzererler <6199053+aguzererler@users.noreply.github.com>
Adds a comprehensive test suite for the StatsCallbackHandler in cli/stats_handler.py,
covering call counting, token usage extraction, and thread safety.
Co-authored-by: aguzererler <6199053+aguzererler@users.noreply.github.com>
- Use `--file` instead of `--text` for adding sources to avoid ARG_MAX issues and argument injection.
- Add `--` separator to prevent positional arguments from being misinterpreted as flags.
- Reorder arguments to place options before positional ones.
- Update unit tests and add new security-focused tests.
Co-authored-by: aguzererler <6199053+aguzererler@users.noreply.github.com>