mirror of
https://github.com/FuQuan233/nonebot-plugin-llmchat.git
synced 2026-08-13 10:09:27 +00:00
✨ 支持流式回复与按行消息解析
This commit is contained in:
parent
0d6771eca6
commit
f091497613
10 changed files with 644 additions and 45 deletions
63
tests/test_output_protocol.py
Normal file
63
tests/test_output_protocol.py
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
# ruff: noqa: I001
|
||||
import unittest
|
||||
|
||||
import tests.bootstrap # noqa: F401
|
||||
from nonebot_plugin_llmchat.config import PresetConfig, ScopedConfig
|
||||
from nonebot_plugin_llmchat.output_protocol import NO_REPLY, parse_reply_segments
|
||||
from nonebot_plugin_llmchat.prompts import build_system_prompt
|
||||
from nonebot_plugin_llmchat.state import StateStore
|
||||
|
||||
|
||||
class OutputProtocolTests(unittest.TestCase):
|
||||
def test_each_nonempty_text_line_is_a_message(self):
|
||||
assert parse_reply_segments("第一条\n第二条\n\n第三条") == ["第一条", "第二条", "第三条"]
|
||||
|
||||
def test_no_reply_marker_never_becomes_a_chat_message(self):
|
||||
assert parse_reply_segments(NO_REPLY) == []
|
||||
assert parse_reply_segments(f"answer\n{NO_REPLY}") == ["answer"]
|
||||
|
||||
def test_commas_are_not_split_by_code(self):
|
||||
content = "好啊,没问题,我马上来"
|
||||
assert parse_reply_segments(content) == [content]
|
||||
|
||||
def test_fenced_code_is_one_message_without_fence_or_language(self):
|
||||
content = '我来写\n```python\nprint("hello")\nprint("world")\n```\n好了'
|
||||
assert parse_reply_segments(content) == [
|
||||
"我来写",
|
||||
'print("hello")\nprint("world")',
|
||||
"好了",
|
||||
]
|
||||
|
||||
def test_fenced_long_text_preserves_paragraphs_as_one_message(self):
|
||||
content = "前言\n```text\n第一段内容。\n\n第二段内容。\n```\n结尾"
|
||||
assert parse_reply_segments(content) == [
|
||||
"前言",
|
||||
"第一段内容。\n\n第二段内容。",
|
||||
"结尾",
|
||||
]
|
||||
|
||||
def test_unclosed_content_block_is_flushed_as_one_message(self):
|
||||
content = "```text\nline 1\n\nline 3"
|
||||
assert parse_reply_segments(content) == ["line 1\n\nline 3"]
|
||||
|
||||
def test_prompt_distinguishes_short_messages_and_atomic_content_blocks(self):
|
||||
preset = PresetConfig(name="test", api_base="x", api_key="x", model_name="x")
|
||||
config = ScopedConfig(api_presets=[preset], default_preset="test")
|
||||
prompt = build_system_prompt(
|
||||
config=config,
|
||||
state=StateStore(config).group_states[1],
|
||||
bot_names={"bot"},
|
||||
is_group=True,
|
||||
support_tools=False,
|
||||
)
|
||||
|
||||
assert "[短消息]" in prompt
|
||||
assert "一行就是一条聊天消息" in prompt
|
||||
assert "[原子内容块]" in prompt
|
||||
assert "不仅用于代码" in prompt
|
||||
assert "需要连贯阅读的长文本,必须完整放进一个内容框" in prompt
|
||||
assert "框内可以使用换行、空行和段落" in prompt
|
||||
assert "不要把长文本压成一行" in prompt
|
||||
assert "```text" in prompt
|
||||
assert "```python" in prompt
|
||||
assert NO_REPLY in prompt
|
||||
Loading…
Add table
Add a link
Reference in a new issue