From d16ed4e552f4b8f017cb2b9edd141dd1d9d81d32 Mon Sep 17 00:00:00 2001 From: Weilong Liao <37870767+Soulter@users.noreply.github.com> Date: Sun, 26 Apr 2026 22:21:57 +0800 Subject: [PATCH 1/3] fix: revise reasoning_key attribute to OpenRouter (#7821) --- astrbot/core/provider/sources/openrouter_source.py | 1 + 1 file changed, 1 insertion(+) diff --git a/astrbot/core/provider/sources/openrouter_source.py b/astrbot/core/provider/sources/openrouter_source.py index e49d0c929a..a308ad309d 100644 --- a/astrbot/core/provider/sources/openrouter_source.py +++ b/astrbot/core/provider/sources/openrouter_source.py @@ -20,3 +20,4 @@ def __init__( self.client._custom_headers["X-OpenRouter-Categories"] = ( "general-chat,personal-agent" # type: ignore ) + self.reasoning_key = "reasoning" From 3c1d0cd2c287e2c4d64b69c5c57a7a374abf6daa Mon Sep 17 00:00:00 2001 From: EnemyWind Date: Sun, 26 Apr 2026 23:06:54 +0800 Subject: [PATCH 2/3] =?UTF-8?q?[fix]=20=E5=B0=86Minimax=20TTS=E9=BB=98?= =?UTF-8?q?=E8=AE=A4=E8=BE=93=E5=87=BA=E6=A0=BC=E5=BC=8F=E6=94=B9=E4=B8=BA?= =?UTF-8?q?wav=E4=BB=A5=E8=A7=A3=E5=86=B3RIFF=E9=94=99=E8=AF=AF=20(#7797)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## 问题 在 QQ 官方平台插件中,处理来自 Minimax TTS 的语音时,会抛出错误:`处理语音时出错: file does not start with RIFF id`。 ## 原因 Minimax TTS 提供商 (`minimax_tts_api_source.py`) 默认配置的音频输出格式为 `mp3`,而 `qqofficial_message_event.py` 中的 `wav_to_tencent_silk` 函数要求输入为 WAV 格式(具有 RIFF 文件头)。 ## 解决方案 将 `minimax_tts_api_source.py` 文件中 `ProviderMiniMaxTTSAPI` 类的 `audio_setting` 字典的 `format` 键值,从 `"mp3"` 修改为 `"wav"`。 ## 结果 修改后,Minimax TTS 生成的音频文件将直接为 WAV 格式,从而被下游函数正确识别和处理,修复上述错误。 --- astrbot/core/provider/sources/minimax_tts_api_source.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/astrbot/core/provider/sources/minimax_tts_api_source.py b/astrbot/core/provider/sources/minimax_tts_api_source.py index f40cb968ab..7ca3697088 100644 --- a/astrbot/core/provider/sources/minimax_tts_api_source.py +++ b/astrbot/core/provider/sources/minimax_tts_api_source.py @@ -65,7 +65,7 @@ def __init__( self.audio_setting: dict = { "sample_rate": 32000, "bitrate": 128000, - "format": "mp3", + "format": "wav", } self.concat_base_url: str = f"{self.api_base}?GroupId={self.group_id}" @@ -147,7 +147,7 @@ async def _audio_play(self, audio_stream: AsyncIterator[str]) -> bytes: async def get_audio(self, text: str) -> str: temp_dir = get_astrbot_temp_path() os.makedirs(temp_dir, exist_ok=True) - path = os.path.join(temp_dir, f"minimax_tts_api_{uuid.uuid4()}.mp3") + path = os.path.join(temp_dir, f"minimax_tts_api_{uuid.uuid4()}.wav") try: # 直接将异步生成器传递给 _audio_play 方法 From bbda1e678f7cdf307c89637c17021f61251cc769 Mon Sep 17 00:00:00 2001 From: bugkeep <140229885+bugkeep@users.noreply.github.com> Date: Sun, 26 Apr 2026 23:10:58 +0800 Subject: [PATCH 3/3] fix(core): downscale oversized images (#7807) * fix(core): downscale oversized images * refactor: share image max-size check helper * Delete tests/unit/test_media_utils_compress_image.py --------- Co-authored-by: Weilong Liao <37870767+Soulter@users.noreply.github.com> --- astrbot/core/utils/media_utils.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/astrbot/core/utils/media_utils.py b/astrbot/core/utils/media_utils.py index 40f1e60495..03d7912cb6 100644 --- a/astrbot/core/utils/media_utils.py +++ b/astrbot/core/utils/media_utils.py @@ -436,19 +436,30 @@ async def compress_image( optimize = IMAGE_COMPRESS_DEFAULT_OPTIMIZE min_file_size_bytes = int(IMAGE_COMPRESS_DEFAULT_MIN_FILE_SIZE_MB * 1024 * 1024) data = None + + def _exceeds_max_size(source: bytes | Path) -> bool: + try: + fp = io.BytesIO(source) if isinstance(source, bytes) else source + with PILImage.open(fp) as opened_img: + return max(opened_img.size) > max_size + except Exception: # noqa: BLE001 + return False + # Skip compression for remote images and return the original value. if url_or_path.startswith("http"): return url_or_path elif url_or_path.startswith("data:image"): _header, encoded = url_or_path.split(",", 1) data = base64.b64decode(encoded) - if len(data) < min_file_size_bytes: + if len(data) < min_file_size_bytes and not _exceeds_max_size(data): return url_or_path else: local_path = Path(url_or_path) if not local_path.exists(): return url_or_path - if local_path.stat().st_size < min_file_size_bytes: + if local_path.stat().st_size < min_file_size_bytes and not _exceeds_max_size( + local_path + ): return url_or_path with local_path.open("rb") as f: data = f.read()