mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-06-02 07:11:49 +00:00
feat(hindsight): default recall_types to observation only
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").
This commit is contained in:
parent
321ce94e25
commit
490b3e76b1
3 changed files with 52 additions and 2 deletions
|
|
@ -197,10 +197,32 @@ class TestConfig:
|
|||
assert provider._recall_max_input_chars == 800
|
||||
assert provider._tags is None
|
||||
assert provider._recall_tags is None
|
||||
# Default recall narrowed to observation-only; world/experience are
|
||||
# aggregate facts that often crowd out concrete-event signal during
|
||||
# auto-recall. Users opt back in via the recall_types config key.
|
||||
assert provider._recall_types == ["observation"]
|
||||
assert provider._bank_mission == ""
|
||||
assert provider._bank_retain_mission is None
|
||||
assert provider._retain_context == "conversation between Hermes Agent and the User"
|
||||
|
||||
def test_recall_types_default_is_observation_only(self, provider):
|
||||
"""Auto-recall must filter to observation by default."""
|
||||
assert provider._recall_types == ["observation"]
|
||||
|
||||
def test_recall_types_explicit_list_overrides_default(self, provider_with_config):
|
||||
p = provider_with_config(recall_types=["world", "experience", "observation"])
|
||||
assert p._recall_types == ["world", "experience", "observation"]
|
||||
|
||||
def test_recall_types_csv_string_accepted(self, provider_with_config):
|
||||
"""For parity with recall_tags, comma-separated strings work too."""
|
||||
p = provider_with_config(recall_types="observation, world")
|
||||
assert p._recall_types == ["observation", "world"]
|
||||
|
||||
def test_recall_types_empty_list_falls_back_to_default(self, provider_with_config):
|
||||
"""An empty list shouldn't disable the filter (would be wider than default)."""
|
||||
p = provider_with_config(recall_types=[])
|
||||
assert p._recall_types == ["observation"]
|
||||
|
||||
def test_custom_config_values(self, provider_with_config):
|
||||
p = provider_with_config(
|
||||
retain_tags=["tag1", "tag2"],
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue