Skip to content

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

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

fix(memory/hindsight): make HINDSIGHT_* env vars overlay config.json (#51166)#51375
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
Contributor

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
Collaborator

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
Contributor

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
Contributor

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
Contributor

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
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