From 9c7c388970cbf0b3c46496159f7b28e8b320ce2c Mon Sep 17 00:00:00 2001 From: Foolllll-J Date: Wed, 10 Jun 2026 21:34:23 +0800 Subject: [PATCH 1/2] fix: handle data URI audio refs in audio preprocessing and truncate warning log --- astrbot/core/provider/sources/openai_source.py | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/astrbot/core/provider/sources/openai_source.py b/astrbot/core/provider/sources/openai_source.py index 8aa2778f1b..a0ea369c92 100644 --- a/astrbot/core/provider/sources/openai_source.py +++ b/astrbot/core/provider/sources/openai_source.py @@ -357,6 +357,17 @@ def _extract_audio_part_info(self, part: dict) -> str | None: async def _audio_ref_to_local_path(self, audio_ref: str) -> tuple[str, list[Path]]: cleanup_paths: list[Path] = [] + if audio_ref.startswith("data:"): + m = re.match(r"^data:audio/(\w+);base64,(.+)$", audio_ref) + if m: + suffix = f".{m.group(1)}" + audio_bytes = base64.b64decode(m.group(2)) + temp_dir = Path(get_astrbot_temp_path()) + temp_dir.mkdir(parents=True, exist_ok=True) + target_path = temp_dir / f"provider_audio_{uuid.uuid4().hex}{suffix}" + target_path.write_bytes(audio_bytes) + cleanup_paths.append(target_path) + return str(target_path), cleanup_paths if audio_ref.startswith("http"): suffix = Path(urlparse(audio_ref).path).suffix or ".wav" temp_dir = Path(get_astrbot_temp_path()) @@ -384,7 +395,8 @@ async def _resolve_audio_part(self, audio_ref: str) -> dict | None: audio_format = "wav" audio_bytes = Path(audio_path).read_bytes() except Exception as exc: - logger.warning("音频 %s 预处理失败,将忽略。错误: %s", audio_ref, exc) + truncated = audio_ref[:256] if len(audio_ref) > 256 else audio_ref + logger.warning("音频 %s 预处理失败,将忽略。错误: %s", truncated, exc) return None finally: for cleanup_path in cleanup_paths: From aea1a1a33b985a7f46a860b9e1ff6a6321f8a8ac Mon Sep 17 00:00:00 2001 From: Foolllll <62875591+Foolllll-J@users.noreply.github.com> Date: Thu, 11 Jun 2026 13:59:48 +0800 Subject: [PATCH 2/2] fix: improve audio data URI parsing robustness and performance in OpenAI provider Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- astrbot/core/provider/sources/openai_source.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/astrbot/core/provider/sources/openai_source.py b/astrbot/core/provider/sources/openai_source.py index a0ea369c92..ef2af2be9f 100644 --- a/astrbot/core/provider/sources/openai_source.py +++ b/astrbot/core/provider/sources/openai_source.py @@ -358,16 +358,21 @@ def _extract_audio_part_info(self, part: dict) -> str | None: async def _audio_ref_to_local_path(self, audio_ref: str) -> tuple[str, list[Path]]: cleanup_paths: list[Path] = [] if audio_ref.startswith("data:"): - m = re.match(r"^data:audio/(\w+);base64,(.+)$", audio_ref) - if m: + try: + header, base64_data = audio_ref.split(",", 1) + m = re.match(r"^data:audio/(\w+);base64$", header) + if not m: + raise ValueError("Invalid audio data URI header format") suffix = f".{m.group(1)}" - audio_bytes = base64.b64decode(m.group(2)) + audio_bytes = base64.b64decode(base64_data) temp_dir = Path(get_astrbot_temp_path()) temp_dir.mkdir(parents=True, exist_ok=True) target_path = temp_dir / f"provider_audio_{uuid.uuid4().hex}{suffix}" target_path.write_bytes(audio_bytes) cleanup_paths.append(target_path) return str(target_path), cleanup_paths + except Exception as e: + raise ValueError(f"Failed to decode audio data URI: {e}") from e if audio_ref.startswith("http"): suffix = Path(urlparse(audio_ref).path).suffix or ".wav" temp_dir = Path(get_astrbot_temp_path())