fix(core): Record.path was incorrectly treated as required under Pydantic v2 (#7048)

* fix: make Record.path optional for pydantic v2 compatibility

* fix: preserve telegram voice record path
This commit is contained in:
No-22-Github
2026-03-29 22:59:22 +08:00
committed by GitHub
parent 2b435e0c89
commit f75c2d30b4
3 changed files with 39 additions and 5 deletions

View File

@@ -122,7 +122,7 @@ class Record(BaseMessageComponent):
# Original text content (e.g. TTS source text), used as caption in fallback scenarios
text: str | None = None
# 额外
path: str | None
path: str | None = None
def __init__(self, file: str | None, **_) -> None:
for k in _:

View File

@@ -458,9 +458,9 @@ class TelegramPlatformAdapter(Platform):
)
path_wav = await convert_audio_to_wav(temp_path, path_wav)
message.message = [
Comp.Record(file=path_wav, url=path_wav),
]
record = Comp.Record(file=path_wav, url=path_wav)
record.path = path_wav
message.message = [record]
elif update.message.photo:
photo = update.message.photo[-1] # get the largest photo

View File

@@ -1,7 +1,7 @@
import asyncio
import importlib
import sys
from unittest.mock import MagicMock, patch
from unittest.mock import AsyncMock, MagicMock, patch
import pytest
@@ -106,3 +106,37 @@ async def test_telegram_video_caption_populates_message_text_and_plain():
isinstance(component, Comp.Plain) and component.text == "这段视频讲了什么"
for component in result.message
)
@pytest.mark.asyncio
async def test_telegram_voice_message_creates_record_component(tmp_path):
TelegramPlatformAdapter = _load_telegram_adapter()
adapter = TelegramPlatformAdapter(
make_platform_config("telegram"),
{},
asyncio.Queue(),
)
voice = create_mock_file("https://api.telegram.org/file/test/voice.oga")
update = create_mock_update(
message_text=None,
voice=voice,
)
wav_path = tmp_path / "voice.oga.wav"
convert_message_globals = adapter.convert_message.__func__.__globals__
with patch.dict(
convert_message_globals,
{
"get_astrbot_temp_path": MagicMock(return_value=str(tmp_path)),
"download_file": AsyncMock(),
"convert_audio_to_wav": AsyncMock(return_value=str(wav_path)),
},
):
result = await adapter.convert_message(update, _build_context())
assert result is not None
assert len(result.message) == 1
assert isinstance(result.message[0], Comp.Record)
assert result.message[0].file == str(wav_path)
assert result.message[0].path == str(wav_path)
assert result.message[0].url == str(wav_path)