From 14fac05dc9ac3e3f7632e2295cbc082a0dbfea26 Mon Sep 17 00:00:00 2001 From: Sanjay Santhanam <51058514+Sanjays2402@users.noreply.github.com> Date: Sun, 3 May 2026 23:21:19 -0700 Subject: [PATCH] fix(streaming): use truthy-check for _pending_started_at fallback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Switch the per-turn duration fallback from `is not None` to a truthy check so None, missing-attr, and an explicit 0 all uniformly fall back to time.time(). Without this, a 0 timestamp (e.g. via a buggy migration or manual file edit) would yield `time.time() - 0` ≈ wall-clock-since-epoch, displaying nonsense like 'Done in 56 years 4 months ...'. In practice pending_started_at is always set via int(time.time()) so this is a hardening fix, not a live-bug fix. Also drop the brittle source-string assertion in the regression test that pinned the literal expression. The behavioural test test_done_handler_persists_duration_on_last_assistant_message already proves the duration field is set; pinning the source line broke twice during the v0.50.290 release pipeline alone (Opus tightening + maintainer revert). Fixes #1595 Signed-off-by: Sanjay Santhanam <51058514+Sanjays2402@users.noreply.github.com> --- api/streaming.py | 6 ++++-- tests/test_turn_duration_display.py | 4 ---- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/api/streaming.py b/api/streaming.py index 9f079409..1ff71227 100644 --- a/api/streaming.py +++ b/api/streaming.py @@ -2054,8 +2054,10 @@ def _run_agent_streaming( agent.ephemeral_system_prompt = _personality_prompt _pending_started_at = getattr(s, 'pending_started_at', None) # Normal chat-start sets pending_started_at before spawning this thread; - # fallback to now only for recovered/legacy flows where that marker is absent. - _turn_started_at = _pending_started_at if _pending_started_at is not None else time.time() + # fallback to now only for recovered/legacy flows where that marker is absent + # or has been zeroed out (e.g. via a buggy migration / manual file edit). + # Truthy-check covers None, missing-attr, and 0 uniformly. + _turn_started_at = _pending_started_at if _pending_started_at else time.time() _previous_messages = list(s.messages or []) _previous_context_messages = list(_session_context_messages(s)) _pre_compression_count = getattr( diff --git a/tests/test_turn_duration_display.py b/tests/test_turn_duration_display.py index 8fc38c25..b87deb74 100644 --- a/tests/test_turn_duration_display.py +++ b/tests/test_turn_duration_display.py @@ -21,10 +21,6 @@ def test_streaming_done_payload_includes_backend_turn_duration(): "Turn duration should be measured from the persisted pending_started_at " "start time, not only from browser-local state." ) - assert "if _pending_started_at is not None else time.time()" in STREAMING_PY, ( - "The fallback should preserve explicit timestamp values and only use now " - "when pending_started_at is absent." - ) assert "recovered/legacy flows" in STREAMING_PY, ( "The missing-start fallback should be documented so it is not mistaken " "for the primary timing path."