Skip to content

fix(memory/hindsight): make HINDSIGHT_* env vars overlay config.json (#51166) - #51375

Closed
mkslzk wants to merge 1 commit into
NousResearch:mainfrom
mkslzk:fix/51166-hindsight-bank-id-env-var
Closed

mkslzk wants to merge 1 commit into
NousResearch:mainfrom
mkslzk:fix/51166-hindsight-bank-id-env-var

Conversation

@mkslzk

@mkslzk mkslzk commented Jun 23, 2026

Copy link
Copy Markdown

Summary

_load_config() in the Hindsight memory plugin short-circuited with return json.loads(...) whenever a ~/.hermes/hindsight/config.json existed, so the HINDSIGHT_BANK_ID (and HINDSIGHT_MODE, HINDSIGHT_API_KEY, HINDSIGHT_BUDGET, ...) env vars in a profile's .env were silently ignored.

The user reported setting HINDSIGHT_BANK_ID=nihai-tcm in the profile .env but the plugin still loaded bank hermes (the value from config.json) and routed every auto retain/recall to the wrong bank.

Fix

HINDSIGHT_* env vars are now treated as a per-process overlay on top of the loaded config. JSON remains the source of truth when no env var is set; unsetting the env var is the operator-facing way to let the JSON value win.

HINDSIGHT_BANK_ID is surfaced at both config.bank_id (the read site in HindsightMemoryProvider.__init__ at line 1287) and the legacy config.banks.hermes.bankId location so both lookup shapes work regardless of which path seeded the config.

Tests

  • 5 new regression tests in tests/plugins/memory/test_hindsight_load_config.py
  • All 128 existing Hindsight tests still green
  • Manual repro confirmed via real _load_config() call

Related

…ousResearch#51166)

`_load_config()` in the Hindsight memory plugin short-circuited with
`return json.loads(...)` whenever a `~/.hermes/hindsight/config.json`
existed, so the HINDSIGHT_BANK_ID (and HINDSIGHT_MODE, HINDSIGHT_API_KEY,
HINDSIGHT_BUDGET, ...) env vars in a profile's .env were silently
ignored. The user set `HINDSIGHT_BANK_ID=nihai-tcm` but the plugin
loaded bank `hermes` (or whatever the JSON had) and routed every
auto retain/recall to the wrong bank.

After the fix, HINDSIGHT_* env vars are treated as a per-process
overlay on top of the loaded config. JSON is still the source of
truth when no env var is set; unsetting the env var is the
operator-facing way to let the JSON value win.

HINDSIGHT_BANK_ID is surfaced at both `config.bank_id` (the read site
in HindsightMemoryProvider.__init__ at line 1287) and the legacy
`config.banks.hermes.bankId` location so both lookup shapes work
regardless of which path seeded the config.

Covered by 5 regression tests in
`tests/plugins/memory/test_hindsight_load_config.py`:

- env var wins when config.json exists (the headline NousResearch#51166 case)
- all HINDSIGHT_* overlay env vars (mode, apiKey, budget) work
- JSON value still wins when env var is unset
- env vars seed the config when no config.json exists
- env-var bank_id is reachable through the read site's lookup chain

All 128 existing Hindsight tests remain green.
@alt-glitch alt-glitch added type/bug Something isn't working comp/plugins Plugin system and bundled plugins tool/memory Memory tool and memory providers P3 Low — cosmetic, nice to have labels Jun 23, 2026
@alt-glitch

Copy link
Copy Markdown

This was generated by AI during triage.

Competing fix for #51166 alongside #51173 (@westkite1201). #51173 takes a narrow config.get("bank_id") or HINDSIGHT_BANK_ID fallback; this PR is the broader per-process overlay of all HINDSIGHT_* env vars on top of config.json. Same goal, different scope/mechanism — flagging the cluster so a maintainer can pick.

@tonydwb tonydwb left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review Summary

Verdict: Approved

Important fix for the Hindsight memory plugin: HINDSIGHT_* env vars now overlay matching keys on the loaded config, so a per-profile .env like HINDSIGHT_BANK_ID=nihai-tcm is honored regardless of whether a config.json exists on disk.

Looks Good

  • The env-var overlay pattern is clean: load JSON first, then overlay env vars on top
  • HINDSIGHT_BANK_ID is surfaced at both top-level bank_id and nested banks.hermes.bankId for backward compatibility
  • 153 lines of regression tests cover: env var wins over JSON, JSON wins when no env var, bank-id reaches the read site
  • Well-documented with clear comments explaining the #51166 bug and the fix

Reviewed by Hermes Agent

@yanjiaxi0123-collab

Copy link
Copy Markdown

When can we go live?

@teknium1 teknium1 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for addressing a real current-main configuration bug: _load_config() still returns existing JSON before environment fallback (plugins/memory/hindsight/__init__.py:360-363), and bank resolution defaults to hermes when JSON has no bank ID (plugins/memory/hindsight/__init__.py:1286-1299).

Problems

  • The claimed general overlay omits documented HINDSIGHT_API_URL (plugins/memory/hindsight/README.md:140); persisted api_url still wins at plugins/memory/hindsight/__init__.py:1283.
  • tests/plugins/memory/test_hindsight_load_config.py:72-73 is tautological because line 70 already proves the second or condition.
  • The new tests do not initialize HindsightMemoryProvider through the production resolution path at plugins/memory/hindsight/__init__.py:1243-1299.

Suggested changes

  • Either narrow the patch to HINDSIGHT_BANK_ID, or include and test every documented override claimed by the new precedence rule.
  • Add an initialized-provider regression using an existing profile config that lacks bank_id, and replace the tautological assertion with direct representation checks.

Automated hermes-sweeper review.

"HINDSIGHT_RETAIN_SOURCE": "retain_source",
"HINDSIGHT_RETAIN_USER_PREFIX": "retain_user_prefix",
"HINDSIGHT_RETAIN_ASSISTANT_PREFIX": "retain_assistant_prefix",
"HINDSIGHT_BUDGET": "budget",

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This map claims to overlay matching HINDSIGHT_* values, but it omits documented HINDSIGHT_API_URL (README.md:140). With persisted api_url, current initialization still ignores that override at initialize() line 1283. Please either add and test this mapping or narrow the patch's stated scope.

# *resolved* bank is the env-var one, not the JSON one.
assert cfg.get("bank_id") == "nihai-tcm"
# The JSON-stored bank must NOT silently win.
assert cfg.get("banks", {}).get("hermes", {}).get("bankId") != "nihai-tcm" or \

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This assertion is vacuous: line 70 has already established cfg.get("bank_id") == "nihai-tcm", making the second or branch true regardless of the nested value. Assert the intended nested value directly, or remove this check and test the initialized provider's resolved bank.

@teknium1 teknium1 added sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform area/memory Memory subsystem: store, providers, sync, background reviews labels Jul 15, 2026
@teknium1

Copy link
Copy Markdown
Collaborator

Closing: the bundled Hindsight provider this PR patches has moved out of this repo.

Thanks @mkslzk for this contribution. In #119888 (merge 9d799e0531c; removal commit 4cbf862abe4) the in-tree plugins/memory/hindsight/ provider was removed — Hindsight now installs from the plugin catalog and its code lives in vectorize-io/hindsight hindsight-integrations/hermes (maintained by @nicoloboschi). There is no longer any code in this repo for the Hindsight half of this PR to patch, so we are closing every open PR against the bundled provider rather than leaving them stranded.

Triage notes:

If you believe this was closed in error, comment and we will reopen.

(Bulk-closed in the hindsight-move close pass.)

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

Labels

area/memory Memory subsystem: store, providers, sync, background reviews comp/plugins Plugin system and bundled plugins P3 Low — cosmetic, nice to have sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades tool/memory Memory tool and memory providers type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants