Commit Graph

287 Commits

Author SHA1 Message Date
copilot-swe-agent[bot] 362d148a26 Initial plan 2026-03-23 00:39:42 +00:00
Ahmet Guzererler 86e414f8f1 feat: Implement `init-portfolio` CLI command and add WebSocket streaming support. 2026-03-22 22:55:48 +01:00
Ahmet Guzererler a9c565ec36 docs: finalize AgentOS documentation
- 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
2026-03-22 22:54:20 +01:00
Ahmet Guzererler 2116c14d07 fix: prevent multiple run triggers from button clicks
- add isTriggering state to Dashboard
- disable button immediately upon click
- update isLoading prop to include trigger state
2026-03-22 22:51:35 +01:00
Ahmet Guzererler 7dd7a5c0b6 fix: migrate backend to port 8088 and use 127.0.0.1 to avoid macOS system conflicts
- 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
2026-03-22 22:51:09 +01:00
Ahmet Guzererler c9e5e8989f fix: align report paths and improve node name mapping for live streaming
- 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
2026-03-22 22:46:21 +01:00
Ahmet Guzererler d5df6b93a4 feat: connect Top 3 Metrics to real data from Supabase and macro scans
- 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
2026-03-22 22:14:27 +01:00
Ahmet Guzererler 078d7e2f2a feat: implement AgentOS frontend and live backend integration
- 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
2026-03-22 22:12:33 +01:00
Ahmet Guzererler a26c93463a feat: initialize AgentOS observability foundation
- 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
2026-03-22 21:54:13 +01:00
ahmet guzererler b2fe6ec8c3
Merge pull request #86 from aguzererler/copilot/review-comments
fix: four follow-up issues from PR #85 dataflows hardening
2026-03-22 10:05:09 +01:00
copilot-swe-agent[bot] 48004c654d Merge remote-tracking branch 'origin/main' into copilot/review-comments
# Conflicts:
#	cli/main.py
#	tests/cli/test_stats_handler.py
#	tradingagents/pipeline/macro_bridge.py
2026-03-22 07:44:49 +00:00
copilot-swe-agent[bot] 0e3edcdf5a fix: update test_stats_handler.py for langchain_core >=1.0 compatibility
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
2026-03-22 06:58:38 +00:00
copilot-swe-agent[bot] a8b909e2ca merge: resolve conflicts with origin/main (PR #85 merged)
- cli/main.py: keep module-level rich.progress imports + result.elapsed_seconds
  (our review fixes); take main's extract_content_string (no ast.literal_eval)
- y_finance.py: take main's vectorized _get_stock_stats_bulk (better perf);
  keep our logger.warning() fix in the fallback path
- macro_bridge.py: keep our elapsed_seconds assignments (2 paths)

Co-authored-by: aguzererler <6199053+aguzererler@users.noreply.github.com>
Agent-Logs-Url: https://github.com/aguzererler/TradingAgents/sessions/6e4151b2-17e3-473b-bf24-872a2656cd3f
2026-03-22 06:52:39 +00:00
ahmet guzererler cef65d922d
Merge pull request #85 from aguzererler/fix/dataflows-incident-hardened-error-handling
fix: harden dataflows layer against silent failures and data corruption
2026-03-22 07:43:33 +01:00
Ahmet Guzererler 8364b7c9a0 feat: add per-ticker progress logging to pipeline
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
2026-03-22 07:23:34 +01:00
Ahmet Guzererler 2201afd33a fix: harden dataflows layer against silent failures and data corruption
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)
2026-03-22 07:23:14 +01:00
copilot-swe-agent[bot] 9ff531f293 fix: address review feedback on PR #85 dataflows hardening
- 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
2026-03-22 06:02:39 +00:00
copilot-swe-agent[bot] d2808c2252 Initial plan 2026-03-22 05:54:10 +00:00
ahmet guzererler 0b2bd82422
Merge pull request #78 from aguzererler/test-stats-handler-2915727675949458763 2026-03-22 06:50:41 +01:00
ahmet guzererler 3781e02c9a
Merge pull request #79 from aguzererler/fix-unused-import-json-489751189438099946 2026-03-22 06:50:04 +01:00
ahmet guzererler 0287835319
Merge pull request #80 from aguzererler/optimize-df-to-dict-10261400249095050914 2026-03-22 06:49:38 +01:00
ahmet guzererler f293f6447c
Merge pull request #81 from aguzererler/fix-is-empty-dos-vulnerability-11032456762221174271 2026-03-22 06:49:05 +01:00
ahmet guzererler 26bbe853c1
Merge pull request #77 from aguzererler/security-fix-nlm-subprocess-injection-14014624082945194366 2026-03-22 06:48:34 +01:00
ahmet guzererler 918ba6e9cd
Merge pull request #82 from aguzererler/testing-improvement-safe-fmt-16856446375371467929 2026-03-22 06:47:51 +01:00
Ahmet Guzererler 9ddf489c28 feat: add per-ticker progress logging to pipeline
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
2026-03-22 00:20:35 +01:00
Ahmet Guzererler eafdce3121 fix: harden dataflows layer against silent failures and data corruption
## 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)
2026-03-22 00:07:32 +01:00
ahmet guzererler d4a8ea38c1
Merge pull request #84 from aguzererler/copilot/standardize-env-variables
Standardize env/config loading: single entry point in `default_config.py`
2026-03-21 23:46:35 +01:00
copilot-swe-agent[bot] 4a3aa5ca3c refactor: centralize env loading in default_config.py; fix .env.example
Co-authored-by: aguzererler <6199053+aguzererler@users.noreply.github.com>
Agent-Logs-Url: https://github.com/aguzererler/TradingAgents/sessions/b62cf290-b389-45bf-b644-08b2360a1f76
2026-03-21 22:33:06 +00:00
Ahmet Guzererler 5ec87923e9 fix: allow .env variables to override DEFAULT_CONFIG values
Merged origin/main and resolved all 8 conflicting files:
- CLAUDE.md: merged MISTAKES.md ref + Project Tracking section + env override docs
- cli/main.py: kept top-level json import, kept try/except in run_pipeline
- tool_runner.py: kept descriptive comments for MAX_TOOL_ROUNDS
- alpha_vantage_common.py: kept thread-safe rate limiter, robust error handling
- interface.py: kept broader exception catch (AlphaVantageError + ConnectionError + TimeoutError)
- default_config.py: kept _env()/_env_int() env var overrides with load_dotenv() at module level
- scanner_graph.py: kept debug mode fix (stream for debug, invoke for result)
- macro_bridge.py: kept get_running_loop() over deprecated get_event_loop()

Co-authored-by: aguzererler <6199053+aguzererler@users.noreply.github.com>
2026-03-21 23:26:37 +01:00
ahmet guzererler 7cc47b6627
Merge pull request #83 from aguzererler/fix-unused-import-time-6733591745228634997
🧹 [remove unused import time in news_analyst.py]
2026-03-21 23:25:01 +01:00
copilot-swe-agent[bot] ac2230de11 Initial plan 2026-03-21 22:24:38 +00:00
google-labs-jules[bot] 049f03e7cd 🧹 remove unused import time in news_analyst.py
- 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>
2026-03-21 22:20:30 +00:00
google-labs-jules[bot] 6b6e813928 🧪 Add unit tests for _safe_fmt in finnhub_scanner
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>
2026-03-21 22:20:19 +00:00
google-labs-jules[bot] 2192a32d03 🔒 Fix Denial of Service vulnerability in is_empty
Co-authored-by: aguzererler <6199053+aguzererler@users.noreply.github.com>
2026-03-21 22:19:58 +00:00
google-labs-jules[bot] ed23290b5f Optimize DataFrame to dict conversion in _get_stock_stats_bulk
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>
2026-03-21 22:19:22 +00:00
google-labs-jules[bot] 93f47ca474 🧹 Remove Unused Import: json
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>
2026-03-21 22:19:07 +00:00
google-labs-jules[bot] 0bb7ae1cd8 🧪 Add unit tests for StatsCallbackHandler
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>
2026-03-21 22:18:51 +00:00
google-labs-jules[bot] 98f51a4b16 Fix security vulnerability in NotebookLM sync subprocess calls
- 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>
2026-03-21 22:17:55 +00:00
ahmet guzererler 822b786fbe
Merge pull request #71 from aguzererler/perf-optimize-completed-reports-count-11317210005896921131
 [Performance] Optimize redundant iteration in get_completed_reports_count
2026-03-21 23:03:55 +01:00
ahmet guzererler e0b882ed75
Merge pull request #75 from aguzererler/optimize-sell-batching-17320376887335337420
 Batch database writes for portfolio SELL operations
2026-03-21 23:02:52 +01:00
ahmet guzererler 6aa7351d12
Merge pull request #74 from aguzererler/optimize-percentile-risk-metrics-3721557834418496366
 Optimize percentile calculation in risk metrics
2026-03-21 23:02:25 +01:00
ahmet guzererler 415ab75415
Merge pull request #73 from aguzererler/perf/optimize-team-filtering-5153644847450952095
 [optimize team filtering loop performance]
2026-03-21 23:01:11 +01:00
ahmet guzererler 28f35a54ed
Merge pull request #72 from aguzererler/fix-macro-bridge-concurrency-3956784745339794663
 Optimize synchronous API execution concurrency in macro_bridge.py
2026-03-21 22:58:14 +01:00
ahmet guzererler becac49192
Merge pull request #76 from aguzererler/perf-opt-df-cols-1934091478908671805
 Optimize DataFrame column lowercasing in stockstats_utils.py
2026-03-21 22:50:18 +01:00
google-labs-jules[bot] 1886391997 Optimize DataFrame column lowercasing in stockstats_utils.py
Co-authored-by: aguzererler <6199053+aguzererler@users.noreply.github.com>
2026-03-21 21:47:43 +00:00
ahmet guzererler 442b38dff4
Merge pull request #69 from aguzererler/copilot/review-financial-tools-implementation
Financial tools analysis doc and fix YoY revenue growth off-by-one
2026-03-21 22:41:55 +01:00
google-labs-jules[bot] 1ed46937d7 perf(portfolio): batch database writes during bulk SELL executions
Replaces the O(N) database operations in the `TradeExecutor`'s
`execute_decisions` SELL loop with a single `batch_remove_holdings`
call to the repository. The new repository method calculates updates
in memory, resolves duplicate operations on the same ticker, and issues
the updates via newly implemented `psycopg2.extras.execute_batch`
routines on the `SupabaseClient`.

Co-authored-by: aguzererler <6199053+aguzererler@users.noreply.github.com>
2026-03-21 20:06:45 +00:00
google-labs-jules[bot] e14d07ea81 perf(risk_metrics): optimize _percentile using heapq
Optimize the _percentile calculation to use heapq.nsmallest or heapq.nlargest when requesting small extreme percentiles (like 5% VaR) from large lists, falling back to sorted() only when necessary. This avoids fully sorting the entire array.

Co-authored-by: aguzererler <6199053+aguzererler@users.noreply.github.com>
2026-03-21 20:05:29 +00:00
google-labs-jules[bot] 6d7e7c2944 Optimize team filtering loop performance
Co-authored-by: aguzererler <6199053+aguzererler@users.noreply.github.com>
2026-03-21 19:59:02 +00:00
google-labs-jules[bot] c39e34c389 Optimize synchronous API execution inside async loop in macro_bridge.py
Co-authored-by: aguzererler <6199053+aguzererler@users.noreply.github.com>
2026-03-21 19:56:23 +00:00