From ff0aa69d5f29f32c7a542bfbadf84866bd99ef23 Mon Sep 17 00:00:00 2001 From: manji Date: Wed, 20 May 2026 07:13:55 +0000 Subject: [PATCH] fix(session): use second-level timestamp granularity in legacy dedup key The _normalized_message_timestamp_for_key helper was preserving microsecond precision (%.6f). When the same message is persisted by both the WebUI sidecar JSON writer and the Hermes agent state.db writer, their timestamps can differ by a few microseconds, causing _session_message_merge_key to produce different keys for the same logical message and letting both copies survive the dedup pass in merge_session_messages_append_only. Truncating to second-level granularity collapses sub-second drift to the same key, so the duplicate is suppressed correctly. Fixes #2616 --- api/models.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/api/models.py b/api/models.py index 233af200..0cbc1214 100644 --- a/api/models.py +++ b/api/models.py @@ -2495,9 +2495,10 @@ def _normalized_message_timestamp_for_key(value): timestamp = float(value) except (TypeError, ValueError): return str(value) - if timestamp.is_integer(): - return str(int(timestamp)) - return ("%.6f" % timestamp).rstrip("0").rstrip(".") + # Truncate to second-level granularity so that sub-second drift between + # the sidecar JSON write and the state.db created_at write does not cause + # the legacy dedup key to differ for the same logical message. + return str(int(timestamp)) def _message_timestamp_as_float(msg):