mirror of
https://github.com/openswarm-ai/openswarm.git
synced 2026-09-10 11:47:43 +02:00
[eric] agents: an invisible thinking pill no longer breaks the repeat-card dedup
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014wtspwSFzZmjCx9UNPAorQ
This commit is contained in:
co-authored by
Claude Opus 5
parent
6f313a445c
commit
7c04c755ae
@@ -34,6 +34,12 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
|
||||
@typechecked
|
||||
def p_renders_as_nothing(msg: Message) -> bool:
|
||||
"""An empty thinking pill occupies the tail while showing the user nothing, which silently broke the dedup below (live drill 2026-08-20: three identical cards)."""
|
||||
return msg.role == "thinking" and not str(msg.content or "").strip()
|
||||
|
||||
|
||||
@typechecked
|
||||
def absorb_repeat_card(session: AgentSession, error_msg: Message) -> None:
|
||||
"""Append the error card, unless the branch tail is already the IDENTICAL card with nothing
|
||||
@@ -47,7 +53,8 @@ def absorb_repeat_card(session: AgentSession, error_msg: Message) -> None:
|
||||
because each retry's hidden prompt had displaced the previous card from the tail."""
|
||||
p_tail = [m for m in session.messages
|
||||
if getattr(m, "branch_id", None) in (None, session.active_branch_id)
|
||||
and not getattr(m, "hidden", False)]
|
||||
and not getattr(m, "hidden", False)
|
||||
and not p_renders_as_nothing(m)]
|
||||
if p_tail and p_tail[-1].role == "system" and p_tail[-1].content == error_msg.content:
|
||||
error_msg.id = p_tail[-1].id
|
||||
p_tail[-1].timestamp = error_msg.timestamp
|
||||
|
||||
@@ -220,7 +220,10 @@ async def handle_assistant_message(
|
||||
content=p_copy,
|
||||
branch_id=session.active_branch_id,
|
||||
)
|
||||
session.messages.append(p_card)
|
||||
# A retry ladder re-failing the same way must bump one card, not stack clones; the live
|
||||
# drill produced three before this line existed.
|
||||
from backend.apps.agents.manager.run.handle_run_error import absorb_repeat_card
|
||||
absorb_repeat_card(session, p_card)
|
||||
logger.warning(
|
||||
f"Agent {session_id}: provider returned {p_provider_error.kind} "
|
||||
f"(status={p_provider_error.status}, lane={p_provider_error.lane}) as assistant "
|
||||
|
||||
@@ -78,3 +78,34 @@ def test_a_real_user_message_still_earns_a_fresh_card():
|
||||
|
||||
shown = [m for m in s.messages if m.role == "system"]
|
||||
assert len(shown) == 2, "each real ask gets its own honest answer"
|
||||
|
||||
|
||||
def test_an_empty_thinking_pill_does_not_break_the_dedup():
|
||||
"""Found by the live provider-error drill 2026-08-20, invisible to every unit test here.
|
||||
|
||||
Each retry leaves a non-hidden `thinking` message with empty content sitting in the tail. It
|
||||
renders as nothing, but it displaced the previous card from the tail scan, so a re-failing
|
||||
ladder stacked three identical cards on screen while this suite stayed green.
|
||||
"""
|
||||
s = AgentSession(name="t", model="sonnet")
|
||||
first = p_card("Lost the connection to the model.")
|
||||
absorb_repeat_card(s, first)
|
||||
s.messages.append(Message(role="thinking", content="", branch_id="main"))
|
||||
repeat = p_card("Lost the connection to the model.")
|
||||
absorb_repeat_card(s, repeat)
|
||||
p_cards = [m for m in s.messages if m.role == "system"]
|
||||
assert len(p_cards) == 1, "an invisible pill must not earn the user a duplicate card"
|
||||
assert repeat.id == first.id
|
||||
|
||||
|
||||
def test_a_thinking_pill_with_real_content_still_breaks_the_dedup():
|
||||
"""NEGATIVE CONTROL. Only the EMPTY pill is invisible; real thinking is content the user saw,
|
||||
so a card after it is genuinely new and must not be absorbed into the older one."""
|
||||
s = AgentSession(name="t", model="sonnet")
|
||||
first = p_card("Lost the connection to the model.")
|
||||
absorb_repeat_card(s, first)
|
||||
s.messages.append(Message(role="thinking", content="Let me try that again.", branch_id="main"))
|
||||
repeat = p_card("Lost the connection to the model.")
|
||||
absorb_repeat_card(s, repeat)
|
||||
p_cards = [m for m in s.messages if m.role == "system"]
|
||||
assert len(p_cards) == 2, "visible thinking separates the two failures"
|
||||
|
||||
Reference in New Issue
Block a user