fix(qqbot): stop routing file uploads through STT pipeline - #35705
fix(qqbot): stop routing file uploads through STT pipeline#35705Zioywishing wants to merge 5 commits into
Conversation
The _is_voice_content_type() heuristic matched audio file extensions (.wav, .mp3, .ogg, etc.) even when the QQ Bot API explicitly reported content_type='file'. This caused files sent via QQ's file-transfer feature to be routed through the speech-to-text pipeline instead of being saved as regular attachments. The QQ Bot API already distinguishes voice messages (content_type= 'voice') from file uploads (content_type='file'), so filename-based extension sniffing is unnecessary and harmful. Removed the _VOICE_EXTENSIONS fallback; now only content_type is checked. Closes #XXXX
Update TestIsVoiceContentType to match the new behavior: - Empty content_type with audio extensions → False (no sniffing) - File upload with audio extension → False - Added test_file_upload_with_audio_extension for the reported bug case
…r explicit file uploads Refined the fix: instead of removing extension-based fallback entirely, only skip it when content_type is explicitly 'file' (or image/video). Empty or unknown content_types still fall back to extension matching as a defensive measure. - content_type='voice' or 'audio/*' → True (API signal) - content_type='file' → False (file transfer, never voice) - content_type='' → extension fallback (defensive) - content_type=unknown → extension fallback (defensive) Added _looks_like_voice() module-level helper and comprehensive tests.
Minimal fix: add 'if ct == "file": return False' before extension matching. The original fallback logic is preserved for empty/unknown content_types. Only the bug case (file uploads with audio extensions) is fixed. Removed the over-engineered _looks_like_voice helper.
tonydwb
left a comment
There was a problem hiding this comment.
Code Review Summary
Verdict: Approved
Overview
Clean fix for QQ Bot audio file uploads being incorrectly routed through the STT pipeline. The _is_voice_content_type() function's extension-based heuristic matched .wav/.mp3/etc. file uploads (content_type="file") as voice, causing file loss after failed STT.
Looks Good
- Correct logic:
content_type="file"explicitly returns False, overriding extension fallback - Minimal change: Only the
_VOICE_EXTENSIONStuple and early-return guard changed - Comprehensive tests: Tests for
content_type="file"with various audio extensions all return False - No regression: Voice messages with
content_type="voice"oraudio/*still work - Low blast radius: Single helper function, narrow scope
- Real-world verified: Confirmed against actual QQ Bot message logs
Reviewed by Hermes Agent
|
Thanks for the focused QQBot fix. The premise is confirmed on current main: Automated hermes-sweeper review. |
|
Merged into main via consolidated salvage PR #73515 (merge Your contribution is credited to you in git history. Thank you! Closing this PR as merged-via-salvage. |
Summary
Fixes #35704
Add a guard clause in
_is_voice_content_type()to prevent audio file uploads from being misrouted through the STT pipeline.Problem
When a user sends an audio file (
.wav,.mp3,.ogg, etc.) via QQ's file transfer feature, thecontent_typeis"file"— but the extension-based heuristic in_is_voice_content_type()still matches, causing the file to be consumed by the STT pipeline instead of being saved as a regular attachment.Fix
if ct == "file": return Falsebefore the extension checkcontent_type="file") are never matched by the extension heuristic, even if the filename has an audio extensioncontent_type="voice") and raw audio types (audio/*) continue to work as beforeBefore/After
Before: File
audio-30251.instrumental..wavwithcontent_type="file"→ matched by.wavextension → routed to STT →[Voice] [语音识别失败]→ file lostAfter: File
audio-30251.instrumental..wavwithcontent_type="file"→ early returnFalse→ saved as regular file attachment ✓Testing
Verified with actual QQ Bot message logs:
content_type=voice, filename=xxx.amr→ still correctly routed to STT ✓content_type=file, filename=audio-30251.instrumental..wav→ now saved as file ✓