@@ -1664,37 +1664,63 @@ def _stats_visualize(args) -> None:
16641664
16651665 # --- Attempt DAG generation ---
16661666 dag_generated = False
1667- taskfile_path = None
16681667
1669- # Find the first accessible taskfile_path from runs (most recent first)
1668+ # Prefer DB-based DAG (no taskfile on disk needed); fall back to taskfile if unavailable.
16701669 runs = data ["runs" ]
1671- for run in runs :
1672- candidate = run .get ("taskfile_path" )
1673- if candidate and not candidate .startswith ("TM1:" ) and os .path .isfile (candidate ):
1674- taskfile_path = candidate
1675- break
1670+ workflow_runs = [r for r in runs if (r .get ("workflow" ) or "" ) == args .workflow ]
1671+ latest_run = workflow_runs [0 ] if workflow_runs else None
16761672
1677- if taskfile_path :
1673+ dag_generated_from_db = False
1674+ if latest_run :
16781675 try :
1679- from rushti .taskfile_ops import visualize_dag
1680-
1681- # Ensure output directory exists
1682- Path (dag_path ).parent .mkdir (parents = True , exist_ok = True )
1683-
1684- visualize_dag (
1685- source = taskfile_path ,
1686- output_path = dag_path ,
1687- dashboard_url = dashboard_filename ,
1688- )
1689- dag_generated = True
1690- print (f"DAG visualization generated: { dag_path } " )
1676+ from rushti .taskfile_ops import visualize_dag_from_db_results
1677+
1678+ latest_run_id = latest_run ["run_id" ]
1679+ latest_task_results = [
1680+ tr for tr in data ["task_results" ] if tr ["run_id" ] == latest_run_id
1681+ ]
1682+
1683+ if latest_task_results :
1684+ Path (dag_path ).parent .mkdir (parents = True , exist_ok = True )
1685+ visualize_dag_from_db_results (
1686+ task_results = latest_task_results ,
1687+ output_path = dag_path ,
1688+ dashboard_url = dashboard_filename ,
1689+ )
1690+ dag_generated = True
1691+ dag_generated_from_db = True
1692+ print (f"DAG visualization generated: { dag_path } " )
16911693 except Exception as e :
1692- logger .warning (f"Could not generate DAG visualization: { e } " )
1693- print (f"Warning: DAG visualization skipped ({ e } )" )
1694- else :
1695- print (
1696- "Warning: No accessible taskfile found in run history, skipping DAG visualization"
1697- )
1694+ logger .warning (f"Could not generate DAG from DB: { e } " )
1695+
1696+ if not dag_generated_from_db :
1697+ # Fall back to taskfile on disk (most recent accessible one for this workflow)
1698+ taskfile_path = None
1699+ for run in workflow_runs :
1700+ candidate = run .get ("taskfile_path" )
1701+ if candidate and not candidate .startswith ("TM1:" ) and os .path .isfile (candidate ):
1702+ taskfile_path = candidate
1703+ break
1704+
1705+ if taskfile_path :
1706+ try :
1707+ from rushti .taskfile_ops import visualize_dag
1708+
1709+ Path (dag_path ).parent .mkdir (parents = True , exist_ok = True )
1710+ visualize_dag (
1711+ source = taskfile_path ,
1712+ output_path = dag_path ,
1713+ dashboard_url = dashboard_filename ,
1714+ )
1715+ dag_generated = True
1716+ print (f"DAG visualization generated from taskfile: { dag_path } " )
1717+ except Exception as e :
1718+ logger .warning (f"Could not generate DAG visualization: { e } " )
1719+ print (f"Warning: DAG visualization skipped ({ e } )" )
1720+ else :
1721+ print (
1722+ "Warning: No DB task results or accessible taskfile found, skipping DAG visualization"
1723+ )
16981724
16991725 # --- Generate dashboard ---
17001726 output_file = generate_dashboard (
0 commit comments