From 7aef9c6db592a9ffc0d3922bdbfd85cdaf5e9d4c Mon Sep 17 00:00:00 2001 From: Abhishek Kumar Date: Wed, 25 Feb 2026 22:59:19 +0530 Subject: [PATCH] fix: safe parse timestamp --- api/services/workflow/qa/conversation.py | 35 ++++++++++++++++++------ 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/api/services/workflow/qa/conversation.py b/api/services/workflow/qa/conversation.py index 67b1f35..f28d81a 100644 --- a/api/services/workflow/qa/conversation.py +++ b/api/services/workflow/qa/conversation.py @@ -6,6 +6,29 @@ from datetime import datetime from pipecat.utils.enums import RealtimeFeedbackType +def _safe_parse_timestamp(event: dict) -> datetime | None: + """Best-effort parse of an ISO timestamp from an event. + + Returns None if no valid timestamp is available. + """ + # Prefer payload timestamp when present + payload = event.get("payload") or {} + candidates = [ + payload.get("timestamp"), + event.get("timestamp"), + ] + + for ts in candidates: + if not ts: + continue + try: + return datetime.fromisoformat(ts) + except (ValueError, TypeError): + continue + + return None + + def build_conversation_structure(logs: list[dict]) -> list[dict]: """Transform raw call logs into a conversation structure for LLM QA analysis.""" if not logs: @@ -18,24 +41,18 @@ def build_conversation_structure(logs: list[dict]) -> list[dict]: if event["type"] == RealtimeFeedbackType.BOT_TEXT.value: speaker = "assistant" utterance_text = event["payload"]["text"] - try: - event_time = datetime.fromisoformat(event["payload"]["timestamp"]) - except KeyError: - event_time = datetime.fromisoformat(event["timestamp"]) + event_time = _safe_parse_timestamp(event) or start_time elif event["type"] == RealtimeFeedbackType.USER_TRANSCRIPTION.value and event[ "payload" ].get("final", False): speaker = "user" utterance_text = event["payload"]["text"] - try: - event_time = datetime.fromisoformat(event["payload"]["timestamp"]) - except KeyError: - event_time = datetime.fromisoformat(event["timestamp"]) + event_time = _safe_parse_timestamp(event) or start_time elif event["type"] == RealtimeFeedbackType.FUNCTION_CALL_START.value: speaker = "tool_call" payload = event["payload"] utterance_text = payload.get("function_name", "unknown") - event_time = datetime.fromisoformat(event["timestamp"]) + event_time = _safe_parse_timestamp(event) or start_time else: continue