diff --git a/CHANGELOG.md b/CHANGELOG.md index e10dc80..2af2a65 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to OpenOrbit are documented in this file. The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and this project uses [Semantic Versioning](https://semver.org/). +## [0.12.4] - 2026-09-25 + +### Fixed + +- Historical runs with an empty saved workflow graph now recover the current runner graph when opened. + ## [0.12.3] - 2026-09-25 ### Fixed diff --git a/backend/app/store.py b/backend/app/store.py index 9d31ca8..84ee83c 100644 --- a/backend/app/store.py +++ b/backend/app/store.py @@ -3557,7 +3557,7 @@ def _load(self, run_id: str) -> Run: def _hydrate_workflow_graph(self, run: Run) -> Run: """Attach a runner graph to historical runs when their detail is opened.""" - if run.workflow_graph or not run.build_id: + if (run.workflow_graph or {}).get("nodes") or not run.build_id: return run build = next((item for item in self.builds() if item.get("id") == run.build_id), None) if not build: diff --git a/backend/tests/test_api.py b/backend/tests/test_api.py index 3cc126c..d4ed09a 100644 --- a/backend/tests/test_api.py +++ b/backend/tests/test_api.py @@ -693,6 +693,36 @@ def test_deleting_a_completed_run_removes_its_history(tmp_path, monkeypatch): assert not (store_module.RUNS / "completed-run.json").exists() +def test_opening_a_run_hydrates_an_empty_saved_workflow_graph(tmp_path, monkeypatch): + monkeypatch.setattr(store_module, "RUNS", tmp_path / "runs") + store = store_module.ConsoleStore() + timestamp = store_module.now() + expected_graph = {"nodes": [{"id": "execute", "title": "Execute"}], "edges": []} + store._save( + Run( + id="legacy-empty-graph", + workflow_id="runner", + workflow_name="Runner", + build_id="legacy-build", + status="succeeded", + created_at=timestamp, + updated_at=timestamp, + workflow_graph={"nodes": [], "edges": []}, + ) + ) + monkeypatch.setattr( + store, + "builds", + lambda: [{"id": "legacy-build", "runner_id": "runner", "repository": "/workspace"}], + ) + monkeypatch.setattr(store, "_runner_graph_definition", lambda *_: expected_graph) + + hydrated = store.run("legacy-empty-graph") + + assert hydrated.workflow_graph == expected_graph + assert store._load("legacy-empty-graph").workflow_graph == expected_graph + + def test_completed_pipeline_run_can_be_retried(tmp_path, monkeypatch): monkeypatch.setattr(store_module, "RUNS", tmp_path / "runs") store = store_module.ConsoleStore() diff --git a/frontend/package.json b/frontend/package.json index 904113f..cedcd02 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,7 +1,7 @@ { "name": "agent-improvement-console-ui", "private": true, - "version": "0.12.3", + "version": "0.12.4", "type": "module", "scripts": { "dev": "vite", diff --git a/package.json b/package.json index cc311f2..accbe07 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "openorbit", - "version": "0.12.3", + "version": "0.12.4", "description": "Open control plane for recurring AI automations", "license": "MIT", "type": "module", diff --git a/pyproject.toml b/pyproject.toml index f139096..308e7a2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "openorbit" -version = "0.12.3" +version = "0.12.4" description = "Open control plane for recurring AI automations" readme = "README.md" license = "MIT" diff --git a/uv.lock b/uv.lock index 8e265c9..52e4c85 100644 --- a/uv.lock +++ b/uv.lock @@ -950,7 +950,7 @@ wheels = [ [[package]] name = "openorbit" -version = "0.12.3" +version = "0.12.4" source = { editable = "." } dependencies = [ { name = "fastapi" },