mirror of
https://github.com/HKUDS/nanobot.git
synced 2026-04-26 04:45:59 +00:00
fix(wecom): use reply_stream for progress messages to avoid errcode=40008
The plain reply() uses cmd="reply" which does not support "text" msgtype and causes WeCom API to return errcode=40008 (invalid message type). Unify both progress and final text messages to use reply_stream() (cmd="aibot_respond_msg"), differentiating via finish flag. Fixes #2999
This commit is contained in:
parent
0d03f10fa0
commit
9f433cab01
@ -513,23 +513,21 @@ class WecomChannel(BaseChannel):
|
|||||||
return
|
return
|
||||||
|
|
||||||
if frame:
|
if frame:
|
||||||
if is_progress:
|
# Both progress and final messages must use reply_stream (cmd="aibot_respond_msg").
|
||||||
# Progress messages (thinking text): send as plain reply, no streaming
|
# The plain reply() uses cmd="reply" which does not support "text" msgtype
|
||||||
await self._client.reply(frame, {
|
# and causes errcode=40008 from WeCom API.
|
||||||
"msgtype": "text",
|
stream_id = self._generate_req_id("stream")
|
||||||
"text": {"content": content},
|
await self._client.reply_stream(
|
||||||
})
|
frame,
|
||||||
logger.debug("WeCom progress sent to {}", msg.chat_id)
|
stream_id,
|
||||||
else:
|
content,
|
||||||
# Final response: use streaming reply for better UX
|
finish=not is_progress,
|
||||||
stream_id = self._generate_req_id("stream")
|
)
|
||||||
await self._client.reply_stream(
|
logger.debug(
|
||||||
frame,
|
"WeCom {} sent to {}",
|
||||||
stream_id,
|
"progress" if is_progress else "message",
|
||||||
content,
|
msg.chat_id,
|
||||||
finish=True,
|
)
|
||||||
)
|
|
||||||
logger.debug("WeCom message sent to {}", msg.chat_id)
|
|
||||||
else:
|
else:
|
||||||
# No frame (e.g. cron push): proactive send only supports markdown
|
# No frame (e.g. cron push): proactive send only supports markdown
|
||||||
await self._client.send_message(msg.chat_id, {
|
await self._client.send_message(msg.chat_id, {
|
||||||
|
|||||||
@ -317,20 +317,21 @@ async def test_send_text_with_frame() -> None:
|
|||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
async def test_send_progress_with_frame() -> None:
|
async def test_send_progress_with_frame() -> None:
|
||||||
"""When metadata has _progress, send uses reply (not reply_stream)."""
|
"""When metadata has _progress, send uses reply_stream with finish=False."""
|
||||||
channel = WecomChannel(WecomConfig(bot_id="b", secret="s", allow_from=["*"]), MessageBus())
|
channel = WecomChannel(WecomConfig(bot_id="b", secret="s", allow_from=["*"]), MessageBus())
|
||||||
client = _FakeWeComClient()
|
client = _FakeWeComClient()
|
||||||
channel._client = client
|
channel._client = client
|
||||||
|
channel._generate_req_id = lambda x: f"req_{x}"
|
||||||
channel._chat_frames["chat1"] = _FakeFrame()
|
channel._chat_frames["chat1"] = _FakeFrame()
|
||||||
|
|
||||||
await channel.send(
|
await channel.send(
|
||||||
OutboundMessage(channel="wecom", chat_id="chat1", content="thinking...", metadata={"_progress": True})
|
OutboundMessage(channel="wecom", chat_id="chat1", content="thinking...", metadata={"_progress": True})
|
||||||
)
|
)
|
||||||
|
|
||||||
client.reply.assert_called_once()
|
client.reply_stream.assert_called_once()
|
||||||
client.reply_stream.assert_not_called()
|
call_args = client.reply_stream.call_args
|
||||||
call_args = client.reply.call_args
|
assert call_args[0][2] == "thinking..." # content arg
|
||||||
assert call_args[0][1]["text"]["content"] == "thinking..."
|
assert call_args[1]["finish"] is False
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user