From d0c6353999fe6645ec2995f74202cf6ab399d6d6 Mon Sep 17 00:00:00 2001 From: seamusmore <35286167+seamusmore@users.noreply.github.com> Date: Tue, 14 Jul 2026 18:25:34 +0800 Subject: [PATCH] fix(feishu): voice-note duration on upload, turn-scoped TTS dedup, audio path dedup Trimmed cherry-pick of PR #40592 (duration + dedup hunks only; the voice-classification hunk duplicates #29235 and the send_voice Opus rewrite is out of scope for this inbound-focused PR): - adapter.py: ffprobe duration (off-loop) attached to Feishu voice uploads via _build_file_upload_body(duration=...) and the audio message payload (#16524, #8300) - gateway/run.py: TTS dedup narrowed to the current turn; _enrich_message_with_transcription dedups repeated audio paths Refs #40592 #16524 #8300 --- gateway/run.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/gateway/run.py b/gateway/run.py index 3d2d9fa554979..a3ecc49a964fc 100644 --- a/gateway/run.py +++ b/gateway/run.py @@ -15902,14 +15902,19 @@ class GatewayRunner(GatewayAuthorizationMixin, GatewayKanbanWatchersMixin, Gatew ) return False - # Dedup: agent already called TTS tool + # Dedup: agent already called TTS tool in THIS turn only + last_user_idx = None + for i, msg in enumerate(reversed(agent_messages)): + if msg.get("role") == "user": + last_user_idx = len(agent_messages) - 1 - i; break + turn_messages = agent_messages[last_user_idx:] if last_user_idx is not None else agent_messages has_agent_tts = any( msg.get("role") == "assistant" and any( (tc.get("function") or {}).get("name") == "text_to_speech" for tc in (msg.get("tool_calls") or []) ) - for msg in agent_messages + for msg in turn_messages ) if has_agent_tts: return False @@ -18058,6 +18063,8 @@ class GatewayRunner(GatewayAuthorizationMixin, GatewayKanbanWatchersMixin, Gatew list if every clip failed or STT is disabled. Callers can use this to echo transcripts back to the user before the agent loop. """ + seen = set() + audio_paths = [p for p in audio_paths if p not in seen and not seen.add(p)] if not getattr(self.config, "stt_enabled", True): notes = [] for path in audio_paths: