stage-350: apply Opus SHOULD-FIX — tighten _partial_already_present dedup scope

Opus flagged that PR #2151's cancel-handler partial-dedup loop used a
substring check that was too broad: any short prior assistant reply
('OK', 'Here is the answer:') would dedup a longer new partial containing
it, silently dropping the partial and resurrecting the #893 data-loss bug.

Tightened to only dedup against actual prior _partial=True markers with
exact (whitespace-stripped) content match. Three new regression tests
added (short-non-partial-prefix-does-not-dedup, exact-partial-match-still-
dedups, same-content-non-partial-does-not-dedup).

10/10 partial-cancel tests pass after the fix. Also updated CHANGELOG with
the conflict-resolution notes for #2151 vs #2136 and the #2178 test-fix.
This commit is contained in:
Hermes Agent
2026-05-13 21:11:01 +00:00
parent 66ffc7d44b
commit 7209e89ef4
3 changed files with 131 additions and 3 deletions
+11 -3
View File
@@ -4669,10 +4669,18 @@ def cancel_stream(stream_id: str) -> bool:
_partial_already_present = False
if _stripped:
for _m in _cs.messages:
if not isinstance(_m, dict) or _m.get('role') != 'assistant' or _m.get('_error'):
# Stage-350 Opus SHOULD-FIX (#2151): only dedup
# against actual prior _partial markers from the
# same stream, with exact content match. The original
# substring check (`_stripped in _existing or
# _existing in _stripped`) was too broad — any short
# prior assistant reply (e.g. "OK", "Here is the
# answer:") becomes a substring of many later partial
# bodies and could silently drop the new partial,
# resurrecting the #893 data-loss bug on long sessions.
if not isinstance(_m, dict) or not _m.get('_partial'):
continue
_existing = str(_m.get('content') or '').strip()
if _existing and (_stripped in _existing or _existing in _stripped):
if str(_m.get('content') or '').strip() == _stripped:
_partial_already_present = True
break
if (_stripped or _has_reasoning or _has_tools) and not _partial_already_present: