Fix answer in think (#17998)

This commit is contained in:
Wang Qi
2026-08-07 17:30:14 +08:00
committed by GitHub
parent a805105352
commit 2fef38f955

View File

@@ -2027,7 +2027,7 @@ async def rag_agent(dialog, messages, stream=True, **kwargs):
else:
stream_iter = chat_mdl.async_chat_streamly_delta(rag_tools.sys_prompt(), agent_messages, gen_conf, images=image_files)
async for kind, value, state in _stream_with_think_delta(stream_iter):
event_queue.put_nowait(("stream", kind, value, state))
event_queue.put_nowait(("stream", kind, value, state.in_think if state is not None else False))
except Exception:
logging.exception("rag_agent: agentic stream failed")
finally:
@@ -2039,6 +2039,7 @@ async def rag_agent(dialog, messages, stream=True, **kwargs):
answer_started = False
think_closed = False
outer_tool_started = False
pending_outer_text = []
async def _close_think_and_flush_answer():
nonlocal answer_started, think_closed
@@ -2064,6 +2065,9 @@ async def rag_agent(dialog, messages, stream=True, **kwargs):
continue
if item[0] == "tool_started":
outer_tool_started = True
for value in pending_outer_text:
yield {"answer": value, "reference": {}, "audio_binary": None, "final": False}
pending_outer_text.clear()
continue
if item[0] == "answer":
if not answer_started:
@@ -2080,8 +2084,15 @@ async def rag_agent(dialog, messages, stream=True, **kwargs):
yield {"answer": value, "reference": {}, "audio_binary": None, "final": False}
continue
if item[0] == "stream_done":
if not outer_tool_started and pending_outer_text:
async for output in _close_think_and_flush_answer():
yield output
for value in pending_outer_text:
answer_deltas.append(value)
yield {"answer": value, "reference": {}, "audio_binary": tts(tts_mdl, value), "final": False}
pending_outer_text.clear()
break
_, kind, value, state = item
_, kind, value, in_think = item
if kind != "text" or not value:
# The outer model's think markers are folded into the one
# block opened above; they must not create extra markers.
@@ -2093,17 +2104,18 @@ async def rag_agent(dialog, messages, stream=True, **kwargs):
# Once that section is closed and the terminal tool has
# started, subsequent text is the aggregate tool result and is
# intentionally ignored.
if state is not None and state.in_think:
if in_think:
value = re.sub(r"</?think>", "", value)
if value:
yield {"answer": value, "reference": {}, "audio_binary": None, "final": False}
elif not outer_tool_started:
# Some providers omit explicit reasoning metadata and
# emit plain text before the tool call. Preserve it as
# outer thinking for compatibility with async_chat.
# emit plain text before the tool call. Keep it pending
# until we know whether a tool call or a direct answer
# follows, so a direct answer is not left in <think>.
value = re.sub(r"</?think>", "", value)
if value:
yield {"answer": value, "reference": {}, "audio_binary": None, "final": False}
pending_outer_text.append(value)
if not think_closed:
async for output in _close_think_and_flush_answer():
yield output