fix(backend/copilot): clear inflight tool-call buffer at top of outer finally

CodeRabbit review on #12871 flagged that
`session.clear_inflight_tool_calls()` ran after usage persistence,
session upsert and transcript upload in the baseline turn
`finally`, so if any of those awaited cleanup steps raised, the
process-local scratch buffer would leak into the next turn — the
guide-read guard would observe a phantom in-flight call and skip
its gate.

Move the clear to the very first statement of the outer `finally`
so it runs unconditionally once tool execution has ended, before
any failure-prone cleanup.  Keep the documentation pointing at the
observed failure mode.
This commit is contained in:
majdyz
2026-04-21 23:06:24 +07:00
parent 4dc3d0c34c
commit 2f8d2e10da

View File

@@ -1822,6 +1822,16 @@ async def stream_chat_completion_baseline(
yield StreamError(errorText=error_msg, code="baseline_error")
# Still persist whatever we got
finally:
# In-flight tool-call announcements are only meaningful for the
# current turn; clear at the top of the outer finally so the next
# turn starts with a clean scratch buffer even if one of the
# awaited cleanup steps below (usage persistence, session upsert,
# transcript upload) raises. The buffer is a process-local scratch
# set — if we leak it into the next turn the guide-read guard would
# observe a phantom in-flight call and skip its gate, so this must
# run unconditionally.
session.clear_inflight_tool_calls()
# Pending messages are drained atomically at turn start and
# between tool rounds, so there's nothing to clear in finally.
# Any message pushed after the final drain window stays in the
@@ -1916,10 +1926,6 @@ async def stream_chat_completion_baseline(
final_text = final_text[len(recorded) :]
if final_text.strip():
session.messages.append(ChatMessage(role="assistant", content=final_text))
# In-flight tool-call announcements are only meaningful for the
# current turn; clear before persist so the next turn starts with
# a clean scratch buffer.
session.clear_inflight_tool_calls()
try:
await upsert_chat_session(session)
except Exception as persist_err: