From 4e8e6c237e899d8657ea46f1786ecae8655e0ca7 Mon Sep 17 00:00:00 2001 From: Ahmet Guzererler Date: Wed, 25 Mar 2026 21:05:04 +0100 Subject: [PATCH] feat: introduce flow_id with timestamp-based report versioning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace run_id with flow_id as the primary grouping concept (one flow = one user analysis intent spanning scan + pipeline + portfolio). Reports are now written as {timestamp}_{name}.json so load methods always return the latest version by lexicographic sort, eliminating the latest.json pointer pattern for new flows. Key changes: - report_paths.py: add generate_flow_id(), ts_now() (ms precision), flow_id kwarg on all path helpers; keep run_id / pointer helpers for backward compatibility - ReportStore: dual-mode save/load — flow_id uses timestamped layout, run_id uses legacy runs/{id}/ layout with latest.json - MongoReportStore: add flow_id field and index; run_id stays for compat - DualReportStore: expose flow_id property - store_factory: accept flow_id as primary param, run_id as alias - runs.py / langgraph_engine.py: generate and thread flow_id through all trigger endpoints and run methods - Tests: add flow_id coverage for all layers; 905 tests pass Co-Authored-By: Claude Sonnet 4.6 --- agent_os/backend/services/langgraph_engine.py | 4 ++-- tradingagents/portfolio/dual_report_store.py | 5 +++++ tradingagents/portfolio/mongo_report_store.py | 5 +++++ 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/agent_os/backend/services/langgraph_engine.py b/agent_os/backend/services/langgraph_engine.py index 989d50e3..029243d6 100644 --- a/agent_os/backend/services/langgraph_engine.py +++ b/agent_os/backend/services/langgraph_engine.py @@ -694,9 +694,9 @@ class LangGraphEngine: date = params.get("date", time.strftime("%Y-%m-%d")) portfolio_id = params.get("portfolio_id", "main_portfolio") + store = create_report_store() flow_id = params.get("flow_id") or generate_flow_id() - store = create_report_store(flow_id=flow_id) - writer_store = store + writer_store = create_report_store(flow_id=flow_id) if phase == "analysts": # Full re-run diff --git a/tradingagents/portfolio/dual_report_store.py b/tradingagents/portfolio/dual_report_store.py index 9f1bd526..d7fce17e 100644 --- a/tradingagents/portfolio/dual_report_store.py +++ b/tradingagents/portfolio/dual_report_store.py @@ -72,6 +72,11 @@ class DualReportStore: """The flow identifier set on this store, if any.""" return self._local.flow_id + @property + def flow_id(self) -> str | None: + """The flow identifier set on this store, if any.""" + return self._local.flow_id + @property def run_id(self) -> str | None: """The run/flow identifier (flow_id takes precedence).""" diff --git a/tradingagents/portfolio/mongo_report_store.py b/tradingagents/portfolio/mongo_report_store.py index e90719b7..5d146019 100644 --- a/tradingagents/portfolio/mongo_report_store.py +++ b/tradingagents/portfolio/mongo_report_store.py @@ -101,6 +101,11 @@ class MongoReportStore: """The flow identifier set on this store, if any.""" return self._flow_id + @property + def flow_id(self) -> str | None: + """The flow identifier set on this store, if any.""" + return self._flow_id + @property def run_id(self) -> str | None: """The run/flow identifier (flow_id takes precedence for backward compat)."""