Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion astrbot/core/pipeline/result_decorate/stage.py
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,7 @@ async def process(
plain_str = "".join(parts)
if plain_str and len(plain_str) > self.t2i_word_threshold:
render_start = time.time()
url = None
try:
url = await html_renderer.render_t2i(
plain_str,
Expand All @@ -367,7 +368,6 @@ async def process(
)
except BaseException:
logger.error("文本转图片失败,使用文本发送。")
return
if time.time() - render_start > 3:
logger.warning(
"文本转图片耗时超过了 3 秒,如果觉得很慢可以在 WebUI 中关闭文本转图片模式。",
Expand Down Expand Up @@ -420,3 +420,5 @@ async def process(
# 引用回复
if self.reply_with_quote:
result.chain.insert(0, Reply(id=event.message_obj.message_id))

yield
Comment thread
sjh9714 marked this conversation as resolved.
134 changes: 134 additions & 0 deletions tests/test_qqofficial_group_message_create.py
Original file line number Diff line number Diff line change
Expand Up @@ -429,3 +429,137 @@ async def test_result_decorate_segments_qqofficial_ws_plain_result():
"第一段",
"第二段",
]


@pytest.mark.asyncio
async def test_result_decorate_yields_after_tts_fallback(monkeypatch):
stage = ResultDecorateStage()
stage.reply_prefix = ""
stage.content_safe_check_reply = False
stage.enable_segmented_reply = False
stage.only_llm_result = False
stage.content_cleanup_rule = ""
stage.show_reasoning = False
stage.tts_trigger_probability = 1
stage.reply_with_mention = False
stage.reply_with_quote = False
stage.forward_threshold = 1000
tts_provider = SimpleNamespace(
get_audio=AsyncMock(side_effect=RuntimeError("tts failed")),
)
setattr(
stage,
"ctx",
SimpleNamespace(
plugin_manager=SimpleNamespace(
context=SimpleNamespace(
get_using_tts_provider=lambda _umo: tts_provider,
),
),
astrbot_config={
"provider_tts_settings": {
"enable": True,
"use_file_service": False,
"dual_output": False,
},
"callback_api_base": "",
"t2i": False,
},
),
)
result = MessageEventResult(
chain=[Plain("hello")],
result_content_type=ResultContentType.LLM_RESULT,
)
event = SimpleNamespace(
plugins_name=None,
unified_msg_origin="qq_official:GroupMessage:group-1",
get_result=lambda: result,
get_platform_name=lambda: "qq_official",
is_stopped=lambda: False,
get_extra=lambda *_args, **_kwargs: None,
track_temporary_local_file=lambda _path: None,
)

async def should_process_tts_request(_event):
return True

monkeypatch.setattr(
"astrbot.core.pipeline.result_decorate.stage."
"SessionServiceManager.should_process_tts_request",
should_process_tts_request,
)

yielded_count = 0
async for _ in cast(Any, stage.process(cast(Any, event))):
yielded_count += 1

assert yielded_count == 1
tts_provider.get_audio.assert_awaited_once_with("hello")
assert [comp.text for comp in result.chain if isinstance(comp, Plain)] == ["hello"]


@pytest.mark.asyncio
async def test_result_decorate_yields_after_t2i_fallback(monkeypatch):
stage = ResultDecorateStage()
stage.reply_prefix = ""
stage.content_safe_check_reply = False
stage.enable_segmented_reply = False
stage.only_llm_result = False
stage.content_cleanup_rule = ""
stage.show_reasoning = False
stage.tts_trigger_probability = 1
stage.reply_with_mention = False
stage.reply_with_quote = False
stage.forward_threshold = 1000
stage.t2i_word_threshold = 5
stage.t2i_use_network = False
stage.t2i_active_template = "default"
setattr(
stage,
"ctx",
SimpleNamespace(
plugin_manager=SimpleNamespace(
context=SimpleNamespace(
get_using_tts_provider=lambda _umo: None,
),
),
astrbot_config={
"provider_tts_settings": {
"enable": False,
"use_file_service": False,
"dual_output": False,
},
"callback_api_base": "",
"t2i": True,
"t2i_use_file_service": False,
},
),
)
result = MessageEventResult(
chain=[Plain("hello fallback text")],
result_content_type=ResultContentType.LLM_RESULT,
)
event = SimpleNamespace(
plugins_name=None,
unified_msg_origin="qq_official:GroupMessage:group-1",
get_result=lambda: result,
get_platform_name=lambda: "qq_official",
is_stopped=lambda: False,
get_extra=lambda *_args, **_kwargs: None,
)
render_t2i = AsyncMock(side_effect=RuntimeError("t2i failed"))
monkeypatch.setattr(
"astrbot.core.pipeline.result_decorate.stage.html_renderer.render_t2i",
render_t2i,
)

yielded_count = 0
async for _ in cast(Any, stage.process(cast(Any, event))):
yielded_count += 1

assert yielded_count == 1
render_t2i.assert_awaited_once()
assert [comp.text for comp in result.chain if isinstance(comp, Plain)] == [
"hello fallback text",
]