Repository navigation
fix(reflect): preserve required recall when context fills (#4563) - #4747
Closed
PraveenKumarSridhar wants to merge 2 commits into
Closed
PraveenKumarSridhar wants to merge 2 commits into
PraveenKumarSridhar wants to merge 2 commits into
Conversation
Collaborator
|
Thanks for this! We're tracking this problem in #4563 and will fix it from there, so I'm closing this PR. We've stopped accepting pull requests from outside the team (see CONTRIBUTING.md). Any extra detail or steps to reproduce on the issue are very welcome. |
Collaborator
|
Superseded by #5292. It keeps this PR's idea (blank earlier results so the required recall still fits, then answer from the full evidence) and drops the new hard failures, which broke 3 existing tests and could fail every reflect under a lowered step limit. Retrying an ignored forced step already landed on main in #5236. |
nicoloboschi
added a commit
that referenced
this pull request
Oct 6, 2026
…#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
added a commit
that referenced
this pull request
Oct 6, 2026
…#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
added a commit
that referenced
this pull request
Oct 6, 2026
…#4563) (#5292) 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).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
fix(reflect): preserve required recall when context fills (#4563)
Fixes #4563.
Problem
During a mental-model refresh, a large
search_observationsresult can trip the Reflect context guard before the required raw-factrecallstep. The agent then synthesizes from observations alone, potentially missing newer facts and corrections.Change
recallchoice, returnsdoneor prose instead, or returns an invalid/error recall result. A named tool choice alone does not prove raw facts were retrieved.Validation
uv run --no-sync pytest tests/test_reflect_agent.py tests/test_reflect_split_synthesis.py -q -n 0 -m 'not hs_llm_core' --disable-warnings --tb=short -o log_cli=false: 96 passed, 4 live LLM tests deselected.ty check hindsight_api, andgit diff --check: passed.C.UTF-8locale or stale local Alembic revision, and parallel database tests hit a deadlock/audit timing failure. The three database failures passed in isolation; the Reflect-adjacent per-operation config test passed when rerun withLC_ALL=en_US.UTF-8.Related work
PR #4582 restores retrieval after fresh mental models. This change handles the context guard when a required retrieval step has not yet run. The two patches touch the Reflect agent and tests, so they may need conflict resolution if either merges first.
Limitations
No live LLM test was run in this worktree, and the full local API run was not green for the environment and unrelated failures noted above. A fresh mental model can still release the forced sequence under the existing policy, which PR #4582 addresses separately. The existing splitter still truncates a single indivisible result that exceeds the synthesis budget; this change keeps the complete tool result in history and trace, and ensures the bounded prefix reaches synthesis.