fix(memory): enforce independent built-in store controls - #90550
kshitijk4poor wants to merge 3 commits into
Conversation
Reuse the built-in store predicate during agent initialization and evaluate the config-backed memory tool check immediately after edits instead of applying the generic external-probe TTL.
Use Hermes's shared truthy-value parser so quoted false memory flags disable both built-in stores as expected.
Normalize malformed memory config during initialization and bind per-target write permissions to the session MemoryStore so direct and staged writes cannot update a disabled built-in store.
e106b0a to
269ebeb
Compare
HexLab98
left a comment
There was a problem hiding this comment.
This looks right to me. The flag unification is a good catch — agent_init defaulted missing flags to False while check_memory_requirements defaulted them to True, so a failed config read still advertised the tool with store=None. The quoted-"false" fix and the per-store write gate both close real holes. One minor thing inline, non-blocking.
| def _memory_target_error(store: "MemoryStore", target: str) -> Optional[Dict[str, Any]]: | ||
| """Return a shared validation error for an invalid or disabled target.""" | ||
| if target not in {"memory", "user"}: | ||
| return {"success": False, "error": f"Invalid memory target '{target}'."} |
There was a problem hiding this comment.
Minor: this path no longer goes through tool_error(), so the error body loses _bound_error_text()’s 2048-char cap (tools/registry.py:33). target is model-supplied and interpolated directly. It also drops the "Use 'memory' or 'user'" hint that told the model how to recover.
|
Had a look through this against the current main behavior and the one-store-only cases. This is a solid follow-up to #90559. The shared flag handling, narrowed tool schema, and write gates fix real inconsistencies that were still left after the original issue was resolved. I also ran the new targeted coverage locally on the current head and all 20 tests passed. HexLab's note about keeping the recovery hint and using the standard error path is worth addressing, but I don't see it as merge-blocking. This looks good to merge. |
|
Merged via PR #91262 with your three commits cherry-picked onto current main and your authorship preserved in git log. Also folded in HexLab98's review note on top (bounded invalid-target error + restored recovery hint). Thanks for the thorough follow-up to #90413 — the flag unification and per-store write gates closed real holes. |
Summary
Built-in memory and the user profile now behave as genuinely independent stores across tool availability, schemas, initialization, and writes.
Current
mainalready contains the original both-disabled fix from #90413 plus profile-onlyUSER_PROFILE_GUIDANCEfrom481bc9391e. This PR adds the remaining runtime hardening.Changes
memorytool when eithermemory_enabledoruser_profile_enabledis enabled; remove it only when both are off."false"through Hermes's shared truthy-value helper.targetenum and description to the enabled store in one-store-only configurations.MemoryStore; reject direct and staged writes to a disabled file.memory:sections so tool availability and store initialization cannot diverge.Validation
Credit
Builds on HexLab98's original diagnosis and implementation in #90413. The original both-disabled behavior is already present on current
main; this PR closes the residual independent-store gaps found during salvage review.