Skip to content

feat(hindsight): default recall_types to observation only#33983

Closed
nicoloboschi wants to merge 1 commit into
NousResearch:mainfrom
nicoloboschi:feat/hindsight-default-recall-observation
Closed

feat(hindsight): default recall_types to observation only#33983
nicoloboschi wants to merge 1 commit into
NousResearch:mainfrom
nicoloboschi:feat/hindsight-default-recall-observation

Conversation

@nicoloboschi

@nicoloboschi nicoloboschi commented May 28, 2026

Copy link
Copy Markdown
Contributor

Summary

Default recall_types on auto-recall is now ["observation"] (was previously unset → server returned every fact type).

Why

Per Hindsight's docs, observations are the consolidated knowledge layer Hindsight builds on top of raw facts: deduplicated beliefs grounded in evidence, refined as new facts arrive, with proof counts and freshness signals. Raw world / experience facts are the individual supporting evidence that feeds them.

For per-turn context injection, observations are denser per token and avoid feeding the model multiple raw facts that one observation already summarizes.

Change

Before After
_recall_types default in __init__ None ["observation"]
initialize() with no recall_types config None → all types ["observation"]
recall_types accepted formats JSON list only JSON list or comma-separated string (parity with recall_tags)
Empty list (recall_types: []) Falls through to "no filter" Falls back to default ["observation"] (avoids silently widening recall vs. the new default)
get_config_schema() Not listed Now listed and discoverable via hermes config

Per-call hindsight_recall tool invocations are unaffected — they already only forward types when the caller passes the argument explicitly.

Migration

The behavior change is called out in plugins/memory/hindsight/README.md. To restore the broad recall:

// ~/.hermes/hindsight/config.json
{
  "recall_types": "observation,world,experience"
}

(JSON list ["observation", "world", "experience"] works too.)

Test plan

  • uv run pytest tests/plugins/memory/test_hindsight_provider.py -k "recall_types or default_values"5/5 passed (updated default test + 4 new cases: explicit list override, CSV string, empty-list fallback, default check).
  • One pre-existing failure (test_get_client_passes_idle_timeout_to_hindsight_embedded) reproduces on stock main — unrelated, env issue with hindsight-client==0.6.1.

Auto-recall used to surface every fact type Hindsight had on the
session — `world`, `experience`, and `observation`. That triple-ships
the same underlying signal in three different framings: observations
are the concrete events the user said/did/asked, while world and
experience facts are aggregate summaries Hindsight derives from those
exact observations. Including all three burns most of
`recall_max_tokens` on rephrasings, crowds out events the model
actually needs to see, and produces effective duplicates in the
prompt — observations themselves are deduplicated by construction
so observation-only recall is denser per token and closer to
conversational ground truth.

Change
------
- Default `_recall_types = ["observation"]` (was `None`, which
  delegated to server-side "return everything").
- `initialize()` now treats a missing `recall_types` config the same
  way; also accepts comma-separated strings for parity with `recall_tags`.
- An explicit `recall_types=[]` config falls back to the default rather
  than disabling the filter (would silently widen recall vs. the new
  default).
- Added to `get_config_schema()` so it's discoverable via `hermes config`.

Per-call `hindsight_recall` tool invocations are unaffected — they
already only forward `types` when the caller passes the argument.

Docs / migration
----------------
plugins/memory/hindsight/README.md grows a "Behavior change" callout
explaining the why (no-duplicates, information-efficient) and how to
restore the legacy broad recall:

    "recall_types": "observation,world,experience"   # or a JSON list

in `~/.hermes/hindsight/config.json`.

Tests
-----
- `test_default_values` updated for the new default.
- New cases: explicit list override, CSV string accepted, empty list
  falls back to default (not "wider than default").
@nicoloboschi nicoloboschi force-pushed the feat/hindsight-default-recall-observation branch from 4f53457 to 76eb699 Compare May 28, 2026 16:40
@alt-glitch alt-glitch added type/feature New feature or request P3 Low — cosmetic, nice to have comp/plugins Plugin system and bundled plugins tool/memory Memory tool and memory providers labels May 28, 2026
@kshitijk4poor

Copy link
Copy Markdown
Collaborator

Merged via #34079 — your commit was cherry-picked with authorship preserved (it's now 490b3e76b on main). Thanks @nicoloboschi!

Added one small follow-up commit on top: the description/README said the per-call hindsight_recall tool was unaffected, but it reads the same self._recall_types instance attribute as auto-recall and RECALL_SCHEMA has no per-call types argument — so the new observation-only default narrows both the auto-recall prefetch and the explicit tool. Corrected the README note, config table, and schema description to reflect that. Solid change, the observation-only default is the right call for per-turn context density.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/plugins Plugin system and bundled plugins P3 Low — cosmetic, nice to have tool/memory Memory tool and memory providers type/feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants