diff --git a/companion/codex_display/metrics.py b/companion/codex_display/metrics.py index 3a22883..d99936e 100644 --- a/companion/codex_display/metrics.py +++ b/companion/codex_display/metrics.py @@ -109,14 +109,12 @@ def datetime_offset_seconds(now: Optional[int] = None) -> int: def thread_is_active(thread: Dict[str, Any]) -> bool: - status = thread.get("status") or {} - if status.get("type") == "active": - return True - path = thread.get("path") - if not path or not os.path.isfile(path): - return False - return rollout_is_active(path) + if path and os.path.isfile(path): + return rollout_is_active(path) + + status = thread.get("status") or {} + return status.get("type") == "active" def rollout_is_active( diff --git a/companion/tests/test_metrics.py b/companion/tests/test_metrics.py index d3b2921..2d987a7 100644 --- a/companion/tests/test_metrics.py +++ b/companion/tests/test_metrics.py @@ -8,6 +8,7 @@ build_snapshot, rollout_is_active, rollout_turn_state, + thread_is_active, ) @@ -133,6 +134,15 @@ def test_rollout_completion_is_not_active(self): path = self._write_rollout(["task_started", "task_complete"]) self.assertFalse(rollout_is_active(path)) + def test_rollout_completion_overrides_stale_active_status(self): + path = self._write_rollout(["task_started", "task_complete"]) + + self.assertFalse( + thread_is_active( + {"status": {"type": "active"}, "path": path} + ) + ) + def test_rollout_ignores_trailing_non_event_records(self): handle = tempfile.NamedTemporaryFile(delete=False) self.addCleanup(lambda: os.unlink(handle.name))