Skip to content

fix(reflect): a full context no longer skips the required recall step (#4563) - #5292

Merged
nicoloboschi merged 1 commit into
mainfrom
fix/4563-forced-recall-fits
Oct 6, 2026
Merged

nicoloboschi merged 1 commit into
mainfrom
fix/4563-forced-recall-fits

Conversation

@nicoloboschi

Copy link
Copy Markdown
Collaborator

Fixes #4563. Supersedes #4747.

What users saw

Reflect (and mental-model refresh) first reads summaries, then is required to check raw memories. When the summaries were long enough to fill the context budget, reflect stopped and answered right away. The raw-memory check never ran, so answers could miss newer facts and corrections.

What changes

  • When a required step is still pending and the conversation is over budget, earlier tool results are blanked in what the model sees (oldest first) until the call fits. The full results stay in the evidence history.
  • Once the required steps finish, the answer is written from the full evidence, not the shortened conversation.
  • If blanking is not enough, the old behaviour applies (answer from what was gathered). No new error paths.
  • Single-chunk final synthesis uses the splitter's chunk, so one oversized result is cut to fit instead of dropped.

What was dropped from #4747

#4747 turned a model ignoring the "call recall now" instruction, a low step limit, or a provider context error into hard 500s. That broke 3 existing tests (a no-tools model got a misleading error) and could fail every reflect under a lowered step limit. The ignored-instruction case is already handled on main by retrying the step (#5236).

Tests

  • New regression test_big_observations_do_not_skip_forced_recall (both "recall on the last turn" and "turns to spare"): red on main (recall never called), green here.
  • test_reflect_agent.py, test_reflect_split_synthesis.py, test_mental_model_no_answer_preserved.py, test_reflect_document_answer.py: 153 passed.

…#4563)

When an earlier retrieval step (observations, mental models) returned enough
text to hit the context budget, reflect stopped and answered right away, so
the forced raw-fact recall never ran and the answer could miss newer facts
and corrections.

Now, when a forced step is still pending and the conversation is over budget,
the earlier tool results are blanked in the model-facing conversation (oldest
first) until the call fits. The full results stay in the evidence history,
and once the forced steps finish the answer is written from that full
history, not from the shortened conversation. If blanking is not enough, the
old behaviour applies (answer from what was gathered); no new error paths.

Also: single-chunk final synthesis now uses the splitter's chunk, which
token-cuts an indivisible oversized result instead of dropping it.

Supersedes #4747, keeping its compaction idea and dropping its new hard
failures (noncompliance and step-limit errors).
@nicoloboschi
nicoloboschi force-pushed the fix/4563-forced-recall-fits branch from 3549bef to a4d4278 Compare October 6, 2026 11:07
@nicoloboschi
nicoloboschi merged commit cc755b5 into main Oct 6, 2026
232 of 234 checks passed
@nicoloboschi
nicoloboschi deleted the fix/4563-forced-recall-fits branch October 6, 2026 11:38
@nicoloboschi nicoloboschi mentioned this pull request Nov 3, 2026
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.

Context guard abandons pending forced retrieval step during mental-model refresh, synthesizing from observations only

1 participant