mnemo-agent 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- mnemo/__init__.py +4 -0
- mnemo/adapters/__init__.py +0 -0
- mnemo/adapters/letta_adapter.py +81 -0
- mnemo/adapters/mem0_adapter.py +69 -0
- mnemo/cli.py +912 -0
- mnemo/models.py +94 -0
- mnemo/search.py +99 -0
- mnemo/server.py +236 -0
- mnemo/storage.py +161 -0
- mnemo_agent-0.1.0.dist-info/METADATA +319 -0
- mnemo_agent-0.1.0.dist-info/RECORD +15 -0
- mnemo_agent-0.1.0.dist-info/WHEEL +5 -0
- mnemo_agent-0.1.0.dist-info/entry_points.txt +2 -0
- mnemo_agent-0.1.0.dist-info/licenses/LICENSE +21 -0
- mnemo_agent-0.1.0.dist-info/top_level.txt +1 -0
mnemo/__init__.py
ADDED
|
File without changes
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"""Letta adapter — calls real API when letta-client is installed, stubs otherwise."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import Any
|
|
6
|
+
|
|
7
|
+
from mnemo.models import AgentDump, Fact
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def _require_letta() -> Any:
|
|
11
|
+
try:
|
|
12
|
+
from letta_client import Letta # type: ignore
|
|
13
|
+
return Letta
|
|
14
|
+
except ImportError:
|
|
15
|
+
raise ImportError(
|
|
16
|
+
"letta adapter requires: pip install letta-client\n"
|
|
17
|
+
"Or: pip install 'mnemo[letta]'"
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def dump_from_letta(base_url: str, agent_id: str, agent_name: str) -> AgentDump:
|
|
22
|
+
"""Fetch memories from a Letta agent and return a normalized AgentDump."""
|
|
23
|
+
Letta = _require_letta()
|
|
24
|
+
client = Letta(base_url=base_url)
|
|
25
|
+
|
|
26
|
+
# Letta: GET /v1/agents/{agent_id}/memory/messages or /core_memory
|
|
27
|
+
try:
|
|
28
|
+
memory_blocks = client.agents.memory.retrieve(agent_id=agent_id)
|
|
29
|
+
except Exception as exc:
|
|
30
|
+
raise RuntimeError(f"Letta API error: {exc}") from exc
|
|
31
|
+
|
|
32
|
+
facts: list[Fact] = []
|
|
33
|
+
|
|
34
|
+
# Letta returns human/persona/custom memory blocks
|
|
35
|
+
for block in getattr(memory_blocks, "blocks", []):
|
|
36
|
+
label = getattr(block, "label", "memory")
|
|
37
|
+
value = getattr(block, "value", "")
|
|
38
|
+
block_id = str(getattr(block, "id", ""))
|
|
39
|
+
|
|
40
|
+
if not value:
|
|
41
|
+
continue
|
|
42
|
+
|
|
43
|
+
# Treat each newline-separated line as a separate fact
|
|
44
|
+
for line in str(value).splitlines():
|
|
45
|
+
line = line.strip()
|
|
46
|
+
if not line:
|
|
47
|
+
continue
|
|
48
|
+
facts.append(
|
|
49
|
+
Fact(
|
|
50
|
+
entity=agent_id,
|
|
51
|
+
attribute=label,
|
|
52
|
+
value=line,
|
|
53
|
+
source="letta",
|
|
54
|
+
confidence=1.0,
|
|
55
|
+
metadata={"block_id": block_id, "agent_id": agent_id},
|
|
56
|
+
)
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
return AgentDump(agent=agent_name, source="letta", facts=facts)
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def load_to_letta(dump: AgentDump, base_url: str, agent_id: str) -> int:
|
|
63
|
+
"""Append facts to a Letta agent's core memory. Returns count pushed."""
|
|
64
|
+
Letta = _require_letta()
|
|
65
|
+
client = Letta(base_url=base_url)
|
|
66
|
+
|
|
67
|
+
pushed = 0
|
|
68
|
+
for fact in dump.facts:
|
|
69
|
+
try:
|
|
70
|
+
client.agents.core_memory.modify(
|
|
71
|
+
agent_id=agent_id,
|
|
72
|
+
label="human",
|
|
73
|
+
value=fact.to_text(),
|
|
74
|
+
append=True,
|
|
75
|
+
)
|
|
76
|
+
pushed += 1
|
|
77
|
+
except Exception as exc: # noqa: BLE001
|
|
78
|
+
import click
|
|
79
|
+
click.echo(f" ⚠ Failed to push fact {fact.id}: {exc}", err=True)
|
|
80
|
+
|
|
81
|
+
return pushed
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"""Mem0 adapter — calls real API when mem0ai is installed, stubs otherwise."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import Any
|
|
6
|
+
|
|
7
|
+
from mnemo.models import AgentDump, Fact
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def _require_mem0() -> Any:
|
|
11
|
+
try:
|
|
12
|
+
import mem0ai # type: ignore
|
|
13
|
+
return mem0ai
|
|
14
|
+
except ImportError:
|
|
15
|
+
raise ImportError(
|
|
16
|
+
"mem0 adapter requires: pip install mem0ai\n"
|
|
17
|
+
"Or: pip install 'mnemo[mem0]'"
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def dump_from_mem0(api_key: str, user_id: str, agent: str) -> AgentDump:
|
|
22
|
+
"""Fetch all memories from Mem0 and return a normalized AgentDump."""
|
|
23
|
+
mem0 = _require_mem0()
|
|
24
|
+
client = mem0.MemoryClient(api_key=api_key)
|
|
25
|
+
|
|
26
|
+
raw_memories: list[dict] = client.get_all(user_id=user_id)
|
|
27
|
+
|
|
28
|
+
facts: list[Fact] = []
|
|
29
|
+
for mem in raw_memories:
|
|
30
|
+
# Mem0 returns: {id, memory, user_id, metadata, created_at, ...}
|
|
31
|
+
# We normalize to entity=user_id, attribute="memory", value=text
|
|
32
|
+
facts.append(
|
|
33
|
+
Fact(
|
|
34
|
+
id=str(mem.get("id", "")),
|
|
35
|
+
entity=user_id,
|
|
36
|
+
attribute="memory",
|
|
37
|
+
value=str(mem.get("memory", "")),
|
|
38
|
+
source="mem0",
|
|
39
|
+
confidence=float(mem.get("score", 1.0)),
|
|
40
|
+
metadata={
|
|
41
|
+
k: v
|
|
42
|
+
for k, v in mem.items()
|
|
43
|
+
if k not in ("id", "memory", "user_id", "score")
|
|
44
|
+
},
|
|
45
|
+
)
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
return AgentDump(agent=agent, source="mem0", facts=facts)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def load_to_mem0(dump: AgentDump, api_key: str, user_id: str) -> int:
|
|
52
|
+
"""Push facts from a dump into Mem0. Returns count of facts pushed."""
|
|
53
|
+
mem0 = _require_mem0()
|
|
54
|
+
client = mem0.MemoryClient(api_key=api_key)
|
|
55
|
+
|
|
56
|
+
pushed = 0
|
|
57
|
+
for fact in dump.facts:
|
|
58
|
+
try:
|
|
59
|
+
client.add(
|
|
60
|
+
messages=[{"role": "user", "content": fact.to_text()}],
|
|
61
|
+
user_id=user_id,
|
|
62
|
+
metadata={"mnemo_id": fact.id, **fact.metadata},
|
|
63
|
+
)
|
|
64
|
+
pushed += 1
|
|
65
|
+
except Exception as exc: # noqa: BLE001
|
|
66
|
+
import click
|
|
67
|
+
click.echo(f" ⚠ Failed to push fact {fact.id}: {exc}", err=True)
|
|
68
|
+
|
|
69
|
+
return pushed
|