mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-04-26 01:01:40 +00:00
fix: mem0 API v2 compat, prefetch context fencing, secret redaction (#5423)
Consolidated salvage from PRs #5301 (qaqcvc), #5339 (lance0), #5058 and #5098 (maymuneth). Mem0 API v2 compatibility (#5301): - All reads use filters={user_id: ...} instead of bare user_id= kwarg - All writes use filters with user_id + agent_id for attribution - Response unwrapping for v2 dict format {results: [...]} - Split _read_filters() vs _write_filters() — reads are user-scoped only for cross-session recall, writes include agent_id - Preserved 'hermes-user' default (no breaking change for existing users) - Omitted run_id scoping from #5301 — cross-session memory is Mem0's core value, session-scoping reads would defeat that purpose Memory prefetch context fencing (#5339): - Wraps prefetched memory in <memory-context> fenced blocks with system note marking content as recalled context, NOT user input - Sanitizes provider output to strip fence-escape sequences, preventing injection where memory content breaks out of the fence - API-call-time only — never persisted to session history Secret redaction (#5058, #5098): - Added prefix patterns for Groq (gsk_), Matrix (syt_), RetainDB (retaindb_), Hindsight (hsk-), Mem0 (mem0_), ByteRover (brv_)
This commit is contained in:
parent
786970925e
commit
9ca954a274
8 changed files with 348 additions and 12 deletions
|
|
@ -207,6 +207,23 @@ class Mem0MemoryProvider(MemoryProvider):
|
|||
self._agent_id = self._config.get("agent_id", "hermes")
|
||||
self._rerank = self._config.get("rerank", True)
|
||||
|
||||
def _read_filters(self) -> Dict[str, Any]:
|
||||
"""Filters for search/get_all — scoped to user only for cross-session recall."""
|
||||
return {"user_id": self._user_id}
|
||||
|
||||
def _write_filters(self) -> Dict[str, Any]:
|
||||
"""Filters for add — scoped to user + agent for attribution."""
|
||||
return {"user_id": self._user_id, "agent_id": self._agent_id}
|
||||
|
||||
@staticmethod
|
||||
def _unwrap_results(response: Any) -> list:
|
||||
"""Normalize Mem0 API response — v2 wraps results in {"results": [...]}."""
|
||||
if isinstance(response, dict):
|
||||
return response.get("results", [])
|
||||
if isinstance(response, list):
|
||||
return response
|
||||
return []
|
||||
|
||||
def system_prompt_block(self) -> str:
|
||||
return (
|
||||
"# Mem0 Memory\n"
|
||||
|
|
@ -232,12 +249,12 @@ class Mem0MemoryProvider(MemoryProvider):
|
|||
def _run():
|
||||
try:
|
||||
client = self._get_client()
|
||||
results = client.search(
|
||||
results = self._unwrap_results(client.search(
|
||||
query=query,
|
||||
user_id=self._user_id,
|
||||
filters=self._read_filters(),
|
||||
rerank=self._rerank,
|
||||
top_k=5,
|
||||
)
|
||||
))
|
||||
if results:
|
||||
lines = [r.get("memory", "") for r in results if r.get("memory")]
|
||||
with self._prefetch_lock:
|
||||
|
|
@ -262,7 +279,7 @@ class Mem0MemoryProvider(MemoryProvider):
|
|||
{"role": "user", "content": user_content},
|
||||
{"role": "assistant", "content": assistant_content},
|
||||
]
|
||||
client.add(messages, user_id=self._user_id, agent_id=self._agent_id)
|
||||
client.add(messages, **self._write_filters())
|
||||
self._record_success()
|
||||
except Exception as e:
|
||||
self._record_failure()
|
||||
|
|
@ -291,7 +308,7 @@ class Mem0MemoryProvider(MemoryProvider):
|
|||
|
||||
if tool_name == "mem0_profile":
|
||||
try:
|
||||
memories = client.get_all(user_id=self._user_id)
|
||||
memories = self._unwrap_results(client.get_all(filters=self._read_filters()))
|
||||
self._record_success()
|
||||
if not memories:
|
||||
return json.dumps({"result": "No memories stored yet."})
|
||||
|
|
@ -308,10 +325,12 @@ class Mem0MemoryProvider(MemoryProvider):
|
|||
rerank = args.get("rerank", False)
|
||||
top_k = min(int(args.get("top_k", 10)), 50)
|
||||
try:
|
||||
results = client.search(
|
||||
query=query, user_id=self._user_id,
|
||||
rerank=rerank, top_k=top_k,
|
||||
)
|
||||
results = self._unwrap_results(client.search(
|
||||
query=query,
|
||||
filters=self._read_filters(),
|
||||
rerank=rerank,
|
||||
top_k=top_k,
|
||||
))
|
||||
self._record_success()
|
||||
if not results:
|
||||
return json.dumps({"result": "No relevant memories found."})
|
||||
|
|
@ -328,8 +347,7 @@ class Mem0MemoryProvider(MemoryProvider):
|
|||
try:
|
||||
client.add(
|
||||
[{"role": "user", "content": conclusion}],
|
||||
user_id=self._user_id,
|
||||
agent_id=self._agent_id,
|
||||
**self._write_filters(),
|
||||
infer=False,
|
||||
)
|
||||
self._record_success()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue