refactor: follow-up for salvaged PR #81692
- warn (not debug) on final text-turn flush failure: a failure here reopens the exact #81641 data-loss window with _persist_session as the only remaining retry, unlike the verify siblings which retry in-loop; include session id for triage - trim the flush-site comment to sibling proportion, pointing to the test module for the full incident narrative - test: assert _persist_session presence before indexing, so a wiring change fails with a clean assertion instead of ValueError from max()
This commit is contained in:
parent
6c2c77efba
commit
e4b2a90dad
|
|
@ -7613,25 +7613,23 @@ def run_conversation(
|
|||
continue
|
||||
|
||||
messages.append(final_msg)
|
||||
# Make the completed answer durable before leaving the loop.
|
||||
# The text already reached the user through the streaming /
|
||||
# interim display path, which is display-only and never writes
|
||||
# to state.db; the next durable write would otherwise be
|
||||
# finalize_turn's _persist_session, behind post-turn work that
|
||||
# can include micro-compaction's aux-LLM call. A session torn
|
||||
# down inside that window (ws_orphan_reap after a remote 1006
|
||||
# close, container stop) lost a reply the user had already
|
||||
# seen (#81641). Same contract the tool-call exit gets from
|
||||
# #49045 and the verify-on-stop exits above; the
|
||||
# _DB_PERSISTED_MARKER dedup keeps _persist_session idempotent.
|
||||
#
|
||||
# Unlike the tool-call exit, a failed flush must NOT abort the
|
||||
# turn: no side effect runs after this point, the answer is
|
||||
# already produced, and _persist_session retries the write.
|
||||
# Make the completed answer durable before leaving the loop —
|
||||
# a session torn down before finalize_turn's _persist_session
|
||||
# otherwise loses a reply the user already saw (#81641). Same
|
||||
# contract as the tool-call exit (#49045) and the verify exits
|
||||
# above; _DB_PERSISTED_MARKER keeps _persist_session idempotent.
|
||||
# Unlike the tool-call exit, failure must NOT abort the turn:
|
||||
# no side effect follows and _persist_session retries the write.
|
||||
# Full incident narrative: tests/run_agent/test_81641_*.py.
|
||||
try:
|
||||
agent._flush_messages_to_session_db(messages, conversation_history)
|
||||
except Exception:
|
||||
logger.debug("final text-turn flush failed", exc_info=True)
|
||||
logger.warning(
|
||||
"final text-turn flush failed (session=%s) — reply is "
|
||||
"not yet durable; relying on finalize_turn retry",
|
||||
getattr(agent, "session_id", None) or "none",
|
||||
exc_info=True,
|
||||
)
|
||||
|
||||
_turn_exit_reason = f"text_response(finish_reason={finish_reason})"
|
||||
if not agent.quiet_mode:
|
||||
|
|
|
|||
|
|
@ -138,9 +138,14 @@ class TestCompletedTextTurnIncrementalPersistence:
|
|||
f"transcript tail; observed events: {events!r}"
|
||||
)
|
||||
|
||||
final_persist = max(
|
||||
persist_indices = [
|
||||
i for i, (kind, _) in enumerate(events) if kind == "persist_session"
|
||||
]
|
||||
assert persist_indices, (
|
||||
"finalize_turn must call _persist_session after the loop exits; "
|
||||
f"observed events: {events!r}"
|
||||
)
|
||||
final_persist = persist_indices[-1]
|
||||
assert answer_flushes[0] < final_persist, (
|
||||
"The assistant row must be durable BEFORE post-loop finalization, "
|
||||
f"but the answer flush at index {answer_flushes[0]} did not precede "
|
||||
|
|
|
|||
Loading…
Reference in New Issue