From 79634772da0c8815766c2748a02c88a99aac4c08 Mon Sep 17 00:00:00 2001 From: QuasarRyan Date: Mon, 24 Aug 2026 11:49:22 +0800 Subject: [PATCH] fix(qqofficial): send complete stream snapshots (#2458) --- src/langbot/pkg/platform/sources/qqofficial.py | 12 ++++++------ tests/unit_tests/platform/test_qqofficial_api.py | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/langbot/pkg/platform/sources/qqofficial.py b/src/langbot/pkg/platform/sources/qqofficial.py index 598061f6c..8966f8cf6 100644 --- a/src/langbot/pkg/platform/sources/qqofficial.py +++ b/src/langbot/pkg/platform/sources/qqofficial.py @@ -650,13 +650,13 @@ class QQOfficialAdapter(abstract_platform_adapter.AbstractMessagePlatformAdapter # 用第一个 chunk 的文本建立会话(不发 "..." 避免污染前缀) ctx['session_started'] = True - # 发送内容 = 全量累积文本 - # QQ API 的 replace 模式不允许修改已下发前缀,所以: - # - 首次:发送全部文本,建立会话 - # - 后续:只能发送新增部分(append 行为) - content_to_send = ctx['accumulated_text'][ctx['sent_length'] :] - if not content_to_send and not is_final: + # `replace` mode requires every update to contain the previously + # delivered content as its prefix. `sent_length` only tells us whether + # a non-final snapshot has new content; it must not truncate the + # content sent to QQ. + if len(ctx['accumulated_text']) <= ctx['sent_length'] and not is_final: return + content_to_send = ctx['accumulated_text'] input_state = 10 if is_final else 1 diff --git a/tests/unit_tests/platform/test_qqofficial_api.py b/tests/unit_tests/platform/test_qqofficial_api.py index 704dd142c..f75504b07 100644 --- a/tests/unit_tests/platform/test_qqofficial_api.py +++ b/tests/unit_tests/platform/test_qqofficial_api.py @@ -108,7 +108,7 @@ def _stream_test_adapter(): @pytest.mark.asyncio -async def test_qq_stream_uses_cumulative_chunks_as_snapshots(): +async def test_qq_stream_replace_mode_sends_complete_snapshots(): adapter = _stream_test_adapter() adapter._stream_ctx['message-1'] = { 'user_openid': 'user-1', @@ -138,7 +138,7 @@ async def test_qq_stream_uses_cumulative_chunks_as_snapshots(): assert [call.kwargs['content'] for call in adapter.bot.send_stream_msg.await_args_list] == [ 'one', - ' two', + 'one two', ]