hermes - 💡(How to fix) Fix [Feature]: memory_patch tool — regex-based replace for built-in memory entries

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

Root Cause

  1. Reduces tool-call overhead: Eliminates the view→copy→replace pattern (2-3 calls → 1 call)
  2. More robust memory maintenance: Agents can update entries even when wording/whitespace drifted
  3. Consistency: Pattern is identical to tools/patch in Hermes, which already supports regex. Users who know patch can transfer the mental model directly.
  4. Complements existing issues:
    • #28424 (auto-compact) handles space management
    • #15471 (frequency tracking) handles eviction priority
    • This addresses the update/replace reliability problem directly

Fix Action

Fix / Workaround

Add a new tool action: patch (or alternatively a standalone memory_patch tool) that uses regex matching instead of exact matching:

memory(action="patch", pattern="VPs rules.*magangquest", new_text="updated content")

Minimal implementation sketch:

def memory_patch(pattern: str, target: str, replacement: str) -> dict:
    entries = load_memory()
    regex = re.compile(pattern, re.IGNORECASE | re.DOTALL)
    for i, entry in enumerate(entries):
        if regex.search(entry):
            entries[i] = regex.sub(replacement, entry, count=1)
            save_memory(entries)
            return {"success": True, "matched_entry": i}
    # Fuzzy fallback: return candidates
    return {"success": False, "candidates": fuzzy_top_k(pattern, entries, k=3)}

Code Example

memory(action="replace", old_text="exact substring here", new_text="replacement")

---

memory(action="patch", pattern="VPs rules.*magangquest", new_text="updated content")

---

def memory_patch(pattern: str, target: str, replacement: str) -> dict:
    entries = load_memory()
    regex = re.compile(pattern, re.IGNORECASE | re.DOTALL)
    for i, entry in enumerate(entries):
        if regex.search(entry):
            entries[i] = regex.sub(replacement, entry, count=1)
            save_memory(entries)
            return {"success": True, "matched_entry": i}
    # Fuzzy fallback: return candidates
    return {"success": False, "candidates": fuzzy_top_k(pattern, entries, k=3)}
RAW_BUFFERClick to expand / collapse

Problem

The built-in memory tool has three actions: add, replace, remove.

Both replace and remove require an exact match of old_text — a substring that must be character-for-character identical to the target entry:

memory(action="replace", old_text="exact substring here", new_text="replacement")

This fails frequently because:

  1. Spacing/indentation drift: Minor whitespace or line-break differences cause silent no-match errors.
  2. Wording evolution: The agent paraphrases slightly differently each time it writes an inner representation of a concept, and the old old_text pattern no longer matches.
  3. No partial/fuzzy support: Even 1 extra space, missing period, or different casing breaks the match.

Agents work around this by reading the full memory content first, copying the exact text, then issuing the replace. This is:

  • Slow: 2 tool calls minimum (view + replace)
  • Token-wasting: Full memory content re-read just to get the exact string
  • Still fragile: Unicode normalization, zero-width chars, or invisible differences still cause failures

Proposal

Add a new tool action: patch (or alternatively a standalone memory_patch tool) that uses regex matching instead of exact matching:

memory(action="patch", pattern="VPs rules.*magangquest", new_text="updated content")

Key differences from replace:

  • pattern accepts a regex (or simple wildcard) instead of requiring exact text substrings
  • On match: replaces the matched text within the entry (not the whole entry), preserving formatting
  • Returns {"matched": true, "replaced_snippet": "..."} on success
  • Returns the top 3 candidate snippets with confidence scores when the match is ambiguous

Minimal implementation sketch:

def memory_patch(pattern: str, target: str, replacement: str) -> dict:
    entries = load_memory()
    regex = re.compile(pattern, re.IGNORECASE | re.DOTALL)
    for i, entry in enumerate(entries):
        if regex.search(entry):
            entries[i] = regex.sub(replacement, entry, count=1)
            save_memory(entries)
            return {"success": True, "matched_entry": i}
    # Fuzzy fallback: return candidates
    return {"success": False, "candidates": fuzzy_top_k(pattern, entries, k=3)}

Non-goals

  • Not a full "update N entries at once" batch tool (future work)
  • Not replacing action=replace — exact match still useful for precision

Why This Matters

  1. Reduces tool-call overhead: Eliminates the view→copy→replace pattern (2-3 calls → 1 call)
  2. More robust memory maintenance: Agents can update entries even when wording/whitespace drifted
  3. Consistency: Pattern is identical to tools/patch in Hermes, which already supports regex. Users who know patch can transfer the mental model directly.
  4. Complements existing issues:
    • #28424 (auto-compact) handles space management
    • #15471 (frequency tracking) handles eviction priority
    • This addresses the update/replace reliability problem directly

Environment

  • Hermes Agent v0.15.1 (2026-05-29)
  • Built-in memory tool in tools/memory_tool.py (compiled)

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

hermes - 💡(How to fix) Fix [Feature]: memory_patch tool — regex-based replace for built-in memory entries