mirror of
https://github.com/HKUDS/nanobot.git
synced 2026-04-10 05:03:41 +00:00
fix(feishu): preserve tool hints in final card content
Tool hints should be kept as permanent content in the streaming card so users can see which tools were called (matching the standalone card behavior). Previously, hints were stripped when new deltas arrived or when the stream ended, causing tool call information to disappear. Now: - New delta: hint becomes permanent content, delta appends after it - New tool hint: replaces the previous hint (unchanged) - Resuming/stream_end: hint is preserved in the final text Updated 3 tests to verify hint preservation semantics. Made-with: Cursor
This commit is contained in:
parent
a4bb1923ac
commit
586d4e2411
@ -1287,9 +1287,7 @@ class FeishuChannel(BaseChannel):
|
||||
# next segment appends to the same card.
|
||||
buf = self._stream_bufs.get(chat_id)
|
||||
if buf and buf.card_id and buf.text:
|
||||
if buf.tool_hint_len > 0:
|
||||
buf.text = buf.text[:-buf.tool_hint_len]
|
||||
buf.tool_hint_len = 0
|
||||
buf.tool_hint_len = 0
|
||||
buf.sequence += 1
|
||||
await loop.run_in_executor(
|
||||
None, self._stream_update_text_sync, buf.card_id, buf.text, buf.sequence,
|
||||
@ -1299,9 +1297,7 @@ class FeishuChannel(BaseChannel):
|
||||
buf = self._stream_bufs.pop(chat_id, None)
|
||||
if not buf or not buf.text:
|
||||
return
|
||||
if buf.tool_hint_len > 0:
|
||||
buf.text = buf.text[:-buf.tool_hint_len]
|
||||
buf.tool_hint_len = 0
|
||||
buf.tool_hint_len = 0
|
||||
if buf.card_id:
|
||||
buf.sequence += 1
|
||||
await loop.run_in_executor(
|
||||
@ -1338,7 +1334,6 @@ class FeishuChannel(BaseChannel):
|
||||
buf = _FeishuStreamBuf()
|
||||
self._stream_bufs[chat_id] = buf
|
||||
if buf.tool_hint_len > 0:
|
||||
buf.text = buf.text[:-buf.tool_hint_len]
|
||||
buf.tool_hint_len = 0
|
||||
buf.text += delta
|
||||
if not buf.text.strip():
|
||||
|
||||
@ -316,8 +316,8 @@ class TestToolHintInlineStreaming:
|
||||
ch._client.im.v1.message.create.assert_not_called()
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_tool_hint_stripped_on_next_delta(self):
|
||||
"""When new delta arrives, the previously appended tool hint is removed."""
|
||||
async def test_tool_hint_preserved_on_next_delta(self):
|
||||
"""When new delta arrives, the tool hint is kept as permanent content and delta appends after it."""
|
||||
ch = _make_channel()
|
||||
suffix = "\n\n---\n🔧 web_fetch(\"url\")"
|
||||
ch._stream_bufs["oc_chat1"] = _FeishuStreamBuf(
|
||||
@ -330,7 +330,9 @@ class TestToolHintInlineStreaming:
|
||||
await ch.send_delta("oc_chat1", " continued")
|
||||
|
||||
buf = ch._stream_bufs["oc_chat1"]
|
||||
assert buf.text == "Partial answer continued"
|
||||
assert "Partial answer" in buf.text
|
||||
assert "🔧 web_fetch" in buf.text
|
||||
assert buf.text.endswith(" continued")
|
||||
assert buf.tool_hint_len == 0
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@ -377,8 +379,8 @@ class TestToolHintInlineStreaming:
|
||||
assert buf.text.endswith("🔧 $ git status")
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_tool_hint_stripped_on_resuming_flush(self):
|
||||
"""When _resuming flushes the buffer, tool hint suffix is cleaned."""
|
||||
async def test_tool_hint_preserved_on_resuming_flush(self):
|
||||
"""When _resuming flushes the buffer, tool hint is kept as permanent content."""
|
||||
ch = _make_channel()
|
||||
suffix = "\n\n---\n🔧 $ cd /project"
|
||||
ch._stream_bufs["oc_chat1"] = _FeishuStreamBuf(
|
||||
@ -391,12 +393,13 @@ class TestToolHintInlineStreaming:
|
||||
await ch.send_delta("oc_chat1", "", metadata={"_stream_end": True, "_resuming": True})
|
||||
|
||||
buf = ch._stream_bufs["oc_chat1"]
|
||||
assert buf.text == "Partial answer"
|
||||
assert "Partial answer" in buf.text
|
||||
assert "🔧 $ cd /project" in buf.text
|
||||
assert buf.tool_hint_len == 0
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_tool_hint_stripped_on_final_stream_end(self):
|
||||
"""When final _stream_end closes the card, tool hint suffix is cleaned from text."""
|
||||
async def test_tool_hint_preserved_on_final_stream_end(self):
|
||||
"""When final _stream_end closes the card, tool hint is kept in the final text."""
|
||||
ch = _make_channel()
|
||||
suffix = "\n\n---\n🔧 web_fetch(\"url\")"
|
||||
ch._stream_bufs["oc_chat1"] = _FeishuStreamBuf(
|
||||
@ -411,7 +414,7 @@ class TestToolHintInlineStreaming:
|
||||
|
||||
assert "oc_chat1" not in ch._stream_bufs
|
||||
update_call = ch._client.cardkit.v1.card_element.content.call_args[0][0]
|
||||
assert "🔧" not in update_call.body.content
|
||||
assert "🔧" in update_call.body.content
|
||||
|
||||
|
||||
class TestSendMessageReturnsId:
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user