Skip to content

fix(s_full): consecutive user messages + microcompact read_file regression#247

Open
voidborne-d wants to merge 1 commit intoshareAI-lab:mainfrom
voidborne-d:fix/s-full-teammate-consecutive-user-msgs-and-microcompact
Open

fix(s_full): consecutive user messages + microcompact read_file regression#247
voidborne-d wants to merge 1 commit intoshareAI-lab:mainfrom
voidborne-d:fix/s-full-teammate-consecutive-user-msgs-and-microcompact

Conversation

@voidborne-d
Copy link
Copy Markdown

Problem

Three bugs in s_full.py that cause runtime crashes or degraded agent behaviour:

1. microcompact clears read_file results (regression from s06)

s06_context_compact.py's micro_compact correctly preserves read_file outputs via PRESERVE_RESULT_TOOLS, because compacting them forces the agent to re-read files it already has in context — wasting a tool call and API tokens each time. But s_full.py's simplified microcompact clears ALL old tool_result content indiscriminately:

# s_full.py (before fix)
for part in indices[:-3]:
    if isinstance(part.get("content"), str) and len(part["content"]) > 100:
        part["content"] = "[cleared]"  # ← clears read_file results too

This directly contributes to the looping behaviour reported in #62 — the agent reads a file, microcompact clears it, the agent needs the content again, re-reads it, microcompact clears it again, etc.

Fix: Port the tool_name_map lookup and _PRESERVE_RESULT_TOOLS set from s06 into s_full's microcompact.

2. Teammate _loop produces consecutive user messages (→ Anthropic 400 error)

When inbox messages arrive during the work phase, each one is appended as a separate user message. If multiple inbox messages arrive simultaneously, or if the last message is already a user turn (tool_results), this creates consecutive user messages that violate the Anthropic API's strict alternation requirement:

# Before fix: produces user, user, user
messages.append({"role": "assistant", "content": response.content})
# ... tool_results appended as user ...
# Next iteration: inbox arrives
for msg in inbox:
    messages.append({"role": "user", "content": json.dumps(msg)})  # ← consecutive user

Same issue exists in:

  • Idle-phase inbox handling (each inbox message = separate user append)
  • Auto-claim injection (appends user turn when last message may already be user)

Fix: Merge all inbox messages into a single turn; insert assistant placeholder when the last message is already a user turn.

3. agent_loop bg notifications + inbox injection can stack user messages

Both background notification drain and inbox check independently append user messages before the LLM call. If both fire in the same iteration, or if the previous iteration ended with a user turn (tool_results), two+ consecutive user messages result.

Fix: Merge both into a single injection and fold into the existing user turn when possible (string concatenation for text content, text-part append for list content).

Tests

12 new regression tests in tests/test_s_full_message_alternation.py:

Test Class Tests Covers
TestMicrocompactPreservesReadFile 3 read_file preservation, bash clearing, short-result immunity
TestAgentLoopAlternation 2 bg+inbox merge after assistant turn, folding into tool_results
TestTeammateAlternation 2 inbox after tool_results, auto-claim after tool_results
TestSourceAudit 5 _PRESERVE_RESULT_TOOLS presence, tool_name_map, alternation guards, append count

All 27 tests pass (15 existing + 12 new):

PYTHONPATH=. python3 -m pytest tests/ -v
# 27 passed in 0.81s

Closes #62 (micro_compact looping) and addresses the alternation violations described in #234 and #239 (s_full.py production readiness).

…ssion

Three fixes in s_full.py:

1. microcompact clears read_file results (regression from s06)
   s06's micro_compact preserves read_file outputs via PRESERVE_RESULT_TOOLS,
   but s_full's simplified microcompact clears ALL old tool_result content
   indiscriminately. This forces the agent to re-read files it already has
   in context, wasting tool calls and API tokens. Fix: port the tool_name_map
   lookup + _PRESERVE_RESULT_TOOLS set from s06.

2. Teammate _loop produces consecutive user messages
   When inbox messages arrive during the work phase, each one is appended as
   a separate user message. If multiple inbox messages arrive, or if the last
   message is already a user turn (tool_results), this creates consecutive
   user messages that violate the Anthropic API's strict alternation
   requirement (400 error). Same issue in idle-phase inbox handling and
   auto-claim injection. Fix: merge inbox messages into a single turn and
   insert assistant placeholders when last message is already user.

3. agent_loop bg notifications + inbox injection can stack user messages
   Both bg drain and inbox check independently append user messages before
   the LLM call. If both fire in the same iteration, or if the previous
   iteration ended with a user turn (tool_results), two+ consecutive user
   messages result. Fix: merge both into a single injection and fold into
   existing user turn when possible.

12 regression tests covering microcompact preservation, message alternation
in all three contexts, and source code audit.
@vercel
Copy link
Copy Markdown

vercel bot commented Apr 20, 2026

@voidborne-d is attempting to deploy a commit to the crazyboym's projects Team on Vercel.

A member of the Team first needs to authorize it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

s06 micro_compact may lead to agent looping

1 participant