Skip to content

fix: flush un-retained turns in SessionEnd hook before daemon stop#1205

Open
octo-patch wants to merge 1 commit intovectorize-io:mainfrom
octo-patch:fix/issue-1145-session-end-flush
Open

fix: flush un-retained turns in SessionEnd hook before daemon stop#1205
octo-patch wants to merge 1 commit intovectorize-io:mainfrom
octo-patch:fix/issue-1145-session-end-flush

Conversation

@octo-patch
Copy link
Copy Markdown
Contributor

Fixes #1145

Problem

When retainEveryNTurns > 1 (e.g. the default of 10), the Stop hook skips retain on non-multiple turns. Turns between the last multiple and session end are silently dropped — a typical 27-turn session retains only up to turn 20, losing turns 21-27 completely.

Solution

session_end.py now calls _flush_remaining_turns() before stopping the daemon:

  • Reads turn_count from state (without incrementing) and checks turn_count % retain_every_n != 0
  • Skips when retainEveryNTurns == 1 — Stop hook already covers every turn
  • Skips when turn_count % retainEveryNTurns == 0 — the last Stop hook already retained
  • Uses session_id as document_id so the flush upserts the same document as prior full-session retains (last write wins, no duplicate storage)
  • Adds flush_reason: session_end to metadata for observability
  • Guarded by config.get("autoRetain") — no-op when auto-retain is disabled

Testing

Added TestSessionEndHook (4 tests) to test_hooks.py:

  • test_flushes_remaining_turns_on_session_end — verifies flush fires when turn 1/3 was skipped
  • test_skips_flush_when_retain_every_n_is_one — no extra retain when already retained every turn
  • test_skips_flush_when_last_stop_already_retained — no double-retain after turn 3/3
  • test_skips_flush_when_auto_retain_disabled — respects autoRetain: false

All 137 existing tests continue to pass.

…ixes vectorize-io#1145)

When retainEveryNTurns > 1, the Stop hook skips retain on non-multiple turns
so turns between the last multiple and session end are silently dropped.

SessionEnd now calls _flush_remaining_turns() before stopping the daemon:
- reads turn_count from state without incrementing it
- skips flush when retainEveryNTurns == 1 (Stop hook covers all turns)
- skips flush when turn_count % retainEveryNTurns == 0 (Stop hook already retained)
- uses session_id as document_id so the flush upserts the same document as
  prior full-session retains (deduplicates; last write wins)
- includes flush_reason=session_end in metadata for observability

Added four tests in TestSessionEndHook covering the flush/skip conditions.
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.

hindsight-memory: SessionEnd hook does not flush un-retained turns before daemon stop

1 participant