feat(hindsight): probe API for update_mode='append' to dedupe across processes - #20222
Merged
teknium1 merged 1 commit intoMay 5, 2026
Merged
Conversation
…cross processes
Mirrors the pattern already shipping in hindsight-integrations/openclaw:
probe `<api_url>/version` once per process, gate on Hindsight ≥ 0.5.0.
When supported, retains use a stable session-scoped `document_id`
(`session_id`) plus `update_mode='append'` so cross-process retains for
the same session merge into one document instead of producing
N-different-process-stamped duplicates. When unsupported (or probe
fails), fall back to the existing per-process unique
`f"{session_id}-{start_ts}"` document_id with no `update_mode` — the
resume-overwrite fix (NousResearch#6654) keeps working unchanged on legacy servers.
Closes the dedup half of NousResearch#20115. The proposed `document_id_strategy`
config knob isn't needed: auto-detection via the same /version probe
the OpenClaw plugin already uses gives the same outcome with no extra
config burden, and the choice is purely a function of what the server
can do.
Plumbing
--------
- Module-level helpers (`_meets_minimum_version`, `_fetch_hindsight_api_version`,
`_check_api_supports_update_mode_append`) cache the result per api_url
so every provider in the process gets one /version round-trip.
- One-time WARN logged when the API is older than 0.5.0, telling the
user to upgrade for cross-session deduplication.
- New instance helper `_resolve_retain_target(fallback_doc_id)` returns
`(document_id, update_mode)` based on cached capability. Wired into
`sync_turn` and the `on_session_switch` flush path.
- For local_embedded mode, the probe URL is taken from the running
client (`client.url`) so we hit the actual daemon port rather than
the configured default.
- `update_mode` is set on the per-item dict; `aretain_batch` already
threads `item['update_mode']` into the API call.
Tests
-----
- `TestUpdateModeAppendCapability` (5 cases): legacy fallback, modern
stable+append, per-url cache, one-time warn, flush-on-switch resolves
against the OLD session.
- Existing `_make_hindsight_provider` factory in the manager-side test
file extended to seed `_mode`/`_api_url`/`_api_key`/`_client` and stub
`_resolve_retain_target` so the bypass-init pattern keeps working.
E2E verified against installed `~/.hermes/hermes-agent`:
- Legacy probe (unreachable host) → `legacy-session-<ts>` doc_id,
no `update_mode`.
- Modern probe (live local_embedded 0.5.6 daemon) → stable
`modern-session` doc_id + `update_mode='append'`.
- `test_hermes_embedded_smoke.py` passes (90s).
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.
Mirrors the pattern already shipping in
hindsight-integrations/openclaw: probe<api_url>/versiononce per process and gate on Hindsight ≥ 0.5.0. When the API supportsupdate_mode='append', retains use a stable session-scopeddocument_id(justsession_id) so cross-process retains for the same session merge into one document. When unsupported or the probe fails, fall back to the existing per-process uniquef"{session_id}-{start_ts}"doc_id and don't passupdate_mode— the resume-overwrite fix (#6654) keeps working unchanged on legacy servers.Closes the dedup half of #20115. The proposed
document_id_strategyconfig knob isn't needed: auto-detection via the same/versionprobe the OpenClaw plugin already uses gives the same outcome with no extra config burden, and the choice is purely a function of what the server can do.Plumbing
_meets_minimum_version,_fetch_hindsight_api_version,_check_api_supports_update_mode_append) cache the result perapi_urlso every provider in the process pays one/versionround-trip total.WARNwhen the API is older than 0.5.0, nudging the user to upgrade for cross-session dedup._resolve_retain_target(fallback_doc_id) -> (document_id, update_mode)wired intosync_turnand theon_session_switchflush path.local_embeddedthe probe URL is taken from the live client (client.url) so we hit the actual daemon port, not the configured default.update_modeis set on the per-item dict;Hindsight.aretain_batchalready threadsitem['update_mode']through.Test plan
uv run pytest tests/plugins/memory/test_hindsight_provider.py tests/agent/test_memory_session_switch.py— 108/108 passed.TestUpdateModeAppendCapability(5 cases): legacy fallback, modern stable+append, per-URL cache, one-time WARN, flush-on-switch resolves against the OLD session.End-to-end against installed
~/.hermes/hermes-agenthindsight-embed 0.5.6document_idlegacy-session-20260505_144153_663958modern-sessionitem.update_modeNone(not set)"append"test_hermes_embedded_smoke.pypasses in 90s.