fix(hindsight): pass retain_async=True to aretain_batch in tool handler - #60648
fix(hindsight): pass retain_async=True to aretain_batch in tool handler#60648yingliang-zhang wants to merge 2 commits into
Conversation
Duplicate of #22836 (earliest open, canonical). Both route |
|
Thanks for the triage @alt-glitch. I've analyzed all three competing PRs and want to clarify the differences: #22836 (by @spirotot, May 9) — The earliest PR. It targets an older version of #60648 (this PR, Jul 8) — Minimal fix against current main. The tool handler already calls #37838 (by @kkangg1, Jul 8) — Adds Summary: #60648 is the correct minimal fix for current main. #22836 was the canonical fix but its refactoring has been partially superseded by upstream changes and now conflicts. #37838 doesn't actually work due to the pop. I'll close #37838 as superseded by this PR. A maintainer can pick between #22836 (needs rebase) and #60648 (clean, minimal). |
teknium1
left a comment
There was a problem hiding this comment.
Thanks for targeting the current aretain_batch call site; the missing call-level flag is present on current main at plugins/memory/hindsight/__init__.py:1721.
Problems
retain_async=Truehard-codes behavior that is configurable today. The provider loadsself._retain_asyncfrom config atplugins/memory/hindsight/__init__.py:1354, andsync_turn()forwards that value toaretain_batch()atplugins/memory/hindsight/__init__.py:1681-1686. A user withretain_async: falsewould have tool retains behave differently from auto-retains.- The changed behavior lacks a tool-handler regression test.
tests/plugins/memory/test_hindsight_provider.py:641-653exercises this path but does not assert the call-level flag; the existingsync_turntest demonstrates both configuration values are meaningful attests/plugins/memory/test_hindsight_provider.py:951-962.
Suggested changes
- Pass a captured
self._retain_asyncvalue as the call-level argument instead of a literal. - Add default-true and configured-false assertions for
hindsight_retain.
Automated hermes-sweeper review.
6f5edaf to
ec5c54a
Compare
|
Thanks for the review @teknium1. Addressed the feedback: Pushed to the PR branch. |
ec5c54a to
ee05d63
Compare
ee05d63 to
fc066b3
Compare
9508bb6 to
04a40fc
Compare
|
Thanks for the triage note. We're keeping this PR open. While #22836 targets the same |
…rd-coded True Sweeper feedback on NousResearch#60648: hard-coding retain_async=True ignores the user's retain_async config setting. Read self._retain_async (loaded from config.yaml at init) for consistency with the sync_turn path, which already uses the same pattern at line 1664.
04a40fc to
5f06cd0
Compare
Problem
The
hindsight_retaintool handler callsclient.aretain_batch()withoutretain_async, defaulting to synchronous mode. On banks with significant data, the LLM fact-extraction call can take 60–600+ seconds, far exceeding the 120s_DEFAULT_TIMEOUT. This produces an opaqueTimeoutErrorwith an empty message:"Failed to store memory: ".The auto-retain path (
sync_turn, ~L1685) correctly passesretain_async=retain_async_flag(True) toaretain_batch. The tool call path (~L1721) does not, despite the comment at ~L1715 stating "aretain_batch takes bank_id/retain_async as call args, not item keys".Fix
Add
retain_async=Trueto thearetain_batchcall in the tool handler, consistent with the auto-retain path. The tool now returns immediately after the server accepts the request, matchingsync_turnbehavior.Why not #37838?
PR #37838 adds
retain_async=Trueto_build_retain_kwargs()instead. However, this is ineffective becauseitem.pop("retain_async", None)at ~L1717 immediately removes it from the item dict beforearetain_batchis called — the value never reaches the server.This PR passes
retain_async=Truedirectly toaretain_batchas a call argument, which is the correct approach.Closes #29079 (Embedded Hindsight retain reports failure while async retain later appears in recall).
Related: #14950 (per-operation timeout), #42466 (cron retain race).
Supersedes approach in #37838.