From 05b60ffb35ce441d54a1ae9debe8e213e5b36c81 Mon Sep 17 00:00:00 2001 From: claude-dev Date: Tue, 21 Apr 2026 13:42:51 +0000 Subject: [PATCH] Fix: Timer springt beim Seiten-Reload nicht mehr zurueck MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bei Research-Multi-Pass (3 Durchlaeufe) und bei Retry-Versuchen wird pro Pass/Retry ein neuer refresh_log-Eintrag mit frischem started_at angelegt. /incidents/refreshing gab dadurch beim Reload den spaeteren started_at zurueck statt des urspruenglichen Session-Starts — der Frontend-Timer sprang auf 0:00 zurueck. Orchestrator traegt jetzt _current_task_started_at in-memory, gesetzt beim Queue-Pickup und geraeumt im finally. /incidents/refreshing liefert diesen Session-Start fuer den aktuell laufenden Task (Fallback: letzter refresh_log-Eintrag, falls der Server zwischenzeitlich neu gestartet wurde). --- src/agents/orchestrator.py | 7 +++++++ src/routers/incidents.py | 19 ++++++++++++++++++- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/agents/orchestrator.py b/src/agents/orchestrator.py index 2036a31..255e5c5 100644 --- a/src/agents/orchestrator.py +++ b/src/agents/orchestrator.py @@ -395,6 +395,10 @@ class AgentOrchestrator: self._queue: asyncio.Queue = asyncio.Queue() self._running = False self._current_task: Optional[int] = None + # Session-Start des aktuellen Tasks (UTC ISO mit 'Z'). Ueberspannt Multi-Pass + # und Retries innerhalb derselben Queue-Abarbeitung — verhindert, dass der + # Frontend-Timer beim Seiten-Reload auf den Pass/Retry-Start zurueckspringt. + self._current_task_started_at: Optional[str] = None self._ws_manager = None self._queued_ids: set[int] = set() self._cancel_requested: set[int] = set() @@ -515,6 +519,8 @@ class AgentOrchestrator: user_id = None self._queued_ids.discard(incident_id) self._current_task = incident_id + # Session-Start EINMAL setzen — bleibt ueber Multi-Pass/Retry hinweg stabil + self._current_task_started_at = datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%SZ') self._cancel_event = asyncio.Event() _cancel_event_var.set(self._cancel_event) logger.info(f"Starte Refresh für Lage {incident_id} (Trigger: {trigger_type})") @@ -590,6 +596,7 @@ class AgentOrchestrator: }, _vis, _cb, _tid) finally: self._current_task = None + self._current_task_started_at = None self._cancel_event = None _cancel_event_var.set(None) self._queue.task_done() diff --git a/src/routers/incidents.py b/src/routers/incidents.py index 1c1fd99..9a7c8ad 100644 --- a/src/routers/incidents.py +++ b/src/routers/incidents.py @@ -168,12 +168,29 @@ async def get_refreshing_incidents( from agents.orchestrator import orchestrator queued_ids = list(orchestrator._queued_ids) if hasattr(orchestrator, '_queued_ids') else [] current_task = orchestrator._current_task if hasattr(orchestrator, '_current_task') else None + # Session-Start des aktuell laufenden Tasks — stabil ueber Multi-Pass/Retry hinweg. + # Verhindert, dass der Frontend-Timer beim Reload auf den letzten Log-Eintrag + # (pass 2/3 oder retry n) zurueckspringt. + current_started_at = ( + orchestrator._current_task_started_at + if hasattr(orchestrator, '_current_task_started_at') else None + ) + + details = {} + for row in rows: + iid = row["incident_id"] + started_at = ( + current_started_at + if (iid == current_task and current_started_at) + else row["started_at"] + ) + details[str(iid)] = {"started_at": started_at} return { "refreshing": [row["incident_id"] for row in rows], "queued": queued_ids, "current": current_task, - "details": {str(row["incident_id"]): {"started_at": row["started_at"]} for row in rows}, + "details": details, }