agentmemo-py 1.0.0__tar.gz
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.
- agentmemo_py-1.0.0/PKG-INFO +63 -0
- agentmemo_py-1.0.0/README.md +48 -0
- agentmemo_py-1.0.0/agentmemo/__init__.py +132 -0
- agentmemo_py-1.0.0/agentmemo_py.egg-info/PKG-INFO +63 -0
- agentmemo_py-1.0.0/agentmemo_py.egg-info/SOURCES.txt +8 -0
- agentmemo_py-1.0.0/agentmemo_py.egg-info/dependency_links.txt +1 -0
- agentmemo_py-1.0.0/agentmemo_py.egg-info/requires.txt +3 -0
- agentmemo_py-1.0.0/agentmemo_py.egg-info/top_level.txt +1 -0
- agentmemo_py-1.0.0/pyproject.toml +25 -0
- agentmemo_py-1.0.0/setup.cfg +4 -0
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: agentmemo-py
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Persistent memory for AI agents — store, retrieve, and recall context across sessions.
|
|
5
|
+
Author-email: "Dr. Nadeem Shaikh" <nadeembyit@gmail.com>
|
|
6
|
+
License: Apache-2.0
|
|
7
|
+
Project-URL: Homepage, https://agentmemo.dev
|
|
8
|
+
Project-URL: Documentation, https://agentmemo.dev/docs
|
|
9
|
+
Project-URL: Repository, https://github.com/skullbase-ecom/agentmemo
|
|
10
|
+
Keywords: ai,agent,memory,llm,mcp,semantic-search,agentmemo
|
|
11
|
+
Requires-Python: >=3.8
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
Provides-Extra: async
|
|
14
|
+
Requires-Dist: httpx>=0.24; extra == "async"
|
|
15
|
+
|
|
16
|
+
# agentmemo
|
|
17
|
+
|
|
18
|
+
Persistent memory for AI agents. Store, semantically retrieve, and recall context across sessions. Pure standard library (no required dependencies).
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
pip install agentmemo
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Quick start
|
|
25
|
+
|
|
26
|
+
```python
|
|
27
|
+
from agentmemo import MemoryClient
|
|
28
|
+
|
|
29
|
+
# Get a free key (or pass an existing one)
|
|
30
|
+
key = MemoryClient.signup("my-agent")["api_key"]
|
|
31
|
+
mem = MemoryClient(key)
|
|
32
|
+
|
|
33
|
+
# Store
|
|
34
|
+
mem.store(
|
|
35
|
+
user_id="user_123",
|
|
36
|
+
agent_id="assistant",
|
|
37
|
+
content="User prefers dark mode and works in TypeScript.",
|
|
38
|
+
tags=["preference"],
|
|
39
|
+
importance=8,
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
# Retrieve semantically
|
|
43
|
+
hits = mem.search(user_id="user_123", query="what are the user's preferences?")
|
|
44
|
+
|
|
45
|
+
# Context for an LLM system prompt
|
|
46
|
+
ctx = mem.context(user_id="user_123", format="anthropic")["context"]
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## API
|
|
50
|
+
|
|
51
|
+
- `store(user_id, agent_id, content, metadata=None, ttl_seconds=None, tags=None, namespace="default", importance=5, outcome="unknown", detect_conflicts=False)`
|
|
52
|
+
- `search(user_id, query, agent_id=None, limit=10, namespace=None, tags=None, min_importance=None)`
|
|
53
|
+
- `delete(id=None, user_id=None, agent_id=None)`
|
|
54
|
+
- `context(user_id, agent_id=None, max_tokens=2000, format="raw")`
|
|
55
|
+
- `feedback(memory_id, outcome, confidence=1.0)`
|
|
56
|
+
- `batch(memories)`
|
|
57
|
+
- `stats(user_id=None)`, `usage()`
|
|
58
|
+
- `MemoryClient.signup(name)` — static, returns a free API key
|
|
59
|
+
- Async: `await mem.async_store(...)`, `await mem.async_search(...)` (requires `pip install agentmemo[async]`)
|
|
60
|
+
|
|
61
|
+
Errors raise `AgentMemoError` with `.status`, `.code`, `.body`.
|
|
62
|
+
|
|
63
|
+
Docs: https://agentmemo.dev/docs · Apache-2.0 · Built by Dr. Nadeem Shaikh
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# agentmemo
|
|
2
|
+
|
|
3
|
+
Persistent memory for AI agents. Store, semantically retrieve, and recall context across sessions. Pure standard library (no required dependencies).
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
pip install agentmemo
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
## Quick start
|
|
10
|
+
|
|
11
|
+
```python
|
|
12
|
+
from agentmemo import MemoryClient
|
|
13
|
+
|
|
14
|
+
# Get a free key (or pass an existing one)
|
|
15
|
+
key = MemoryClient.signup("my-agent")["api_key"]
|
|
16
|
+
mem = MemoryClient(key)
|
|
17
|
+
|
|
18
|
+
# Store
|
|
19
|
+
mem.store(
|
|
20
|
+
user_id="user_123",
|
|
21
|
+
agent_id="assistant",
|
|
22
|
+
content="User prefers dark mode and works in TypeScript.",
|
|
23
|
+
tags=["preference"],
|
|
24
|
+
importance=8,
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
# Retrieve semantically
|
|
28
|
+
hits = mem.search(user_id="user_123", query="what are the user's preferences?")
|
|
29
|
+
|
|
30
|
+
# Context for an LLM system prompt
|
|
31
|
+
ctx = mem.context(user_id="user_123", format="anthropic")["context"]
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## API
|
|
35
|
+
|
|
36
|
+
- `store(user_id, agent_id, content, metadata=None, ttl_seconds=None, tags=None, namespace="default", importance=5, outcome="unknown", detect_conflicts=False)`
|
|
37
|
+
- `search(user_id, query, agent_id=None, limit=10, namespace=None, tags=None, min_importance=None)`
|
|
38
|
+
- `delete(id=None, user_id=None, agent_id=None)`
|
|
39
|
+
- `context(user_id, agent_id=None, max_tokens=2000, format="raw")`
|
|
40
|
+
- `feedback(memory_id, outcome, confidence=1.0)`
|
|
41
|
+
- `batch(memories)`
|
|
42
|
+
- `stats(user_id=None)`, `usage()`
|
|
43
|
+
- `MemoryClient.signup(name)` — static, returns a free API key
|
|
44
|
+
- Async: `await mem.async_store(...)`, `await mem.async_search(...)` (requires `pip install agentmemo[async]`)
|
|
45
|
+
|
|
46
|
+
Errors raise `AgentMemoError` with `.status`, `.code`, `.body`.
|
|
47
|
+
|
|
48
|
+
Docs: https://agentmemo.dev/docs · Apache-2.0 · Built by Dr. Nadeem Shaikh
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
"""AgentMemo Python SDK — persistent memory for AI agents.
|
|
2
|
+
|
|
3
|
+
Sync client uses only the standard library (urllib). Optional async methods use
|
|
4
|
+
httpx if installed.
|
|
5
|
+
"""
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
import json
|
|
9
|
+
import urllib.request
|
|
10
|
+
import urllib.error
|
|
11
|
+
import urllib.parse
|
|
12
|
+
from typing import Any, Optional
|
|
13
|
+
|
|
14
|
+
__version__ = "1.0.0"
|
|
15
|
+
__all__ = ["MemoryClient", "AgentMemoError"]
|
|
16
|
+
|
|
17
|
+
DEFAULT_BASE_URL = "https://agentmemo.dev"
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class AgentMemoError(Exception):
|
|
21
|
+
def __init__(self, message: str, status: int = 0, code: Optional[str] = None, body: Any = None):
|
|
22
|
+
super().__init__(message)
|
|
23
|
+
self.status = status
|
|
24
|
+
self.code = code
|
|
25
|
+
self.body = body
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class MemoryClient:
|
|
29
|
+
def __init__(self, api_key: str, base_url: str = DEFAULT_BASE_URL):
|
|
30
|
+
if not api_key:
|
|
31
|
+
raise AgentMemoError("api_key is required", code="no_api_key")
|
|
32
|
+
self.api_key = api_key
|
|
33
|
+
self.base_url = base_url.rstrip("/")
|
|
34
|
+
|
|
35
|
+
# ---- internal -------------------------------------------------------
|
|
36
|
+
def _req(self, method: str, path: str, body: Optional[dict] = None) -> dict:
|
|
37
|
+
url = self.base_url + path
|
|
38
|
+
data = json.dumps(body).encode() if body is not None else None
|
|
39
|
+
headers = {"Authorization": f"Bearer {self.api_key}"}
|
|
40
|
+
if data is not None:
|
|
41
|
+
headers["Content-Type"] = "application/json"
|
|
42
|
+
req = urllib.request.Request(url, data=data, headers=headers, method=method)
|
|
43
|
+
try:
|
|
44
|
+
with urllib.request.urlopen(req) as resp:
|
|
45
|
+
return json.loads(resp.read().decode() or "{}")
|
|
46
|
+
except urllib.error.HTTPError as e:
|
|
47
|
+
payload = {}
|
|
48
|
+
try:
|
|
49
|
+
payload = json.loads(e.read().decode() or "{}")
|
|
50
|
+
except Exception:
|
|
51
|
+
pass
|
|
52
|
+
msg = payload.get("error") if isinstance(payload, dict) else str(e)
|
|
53
|
+
raise AgentMemoError(msg or "request failed", e.code, payload.get("code"), payload)
|
|
54
|
+
|
|
55
|
+
@staticmethod
|
|
56
|
+
def _qs(params: dict) -> str:
|
|
57
|
+
clean = {k: v for k, v in params.items() if v is not None}
|
|
58
|
+
return urllib.parse.urlencode(clean)
|
|
59
|
+
|
|
60
|
+
# ---- API ------------------------------------------------------------
|
|
61
|
+
def store(self, user_id: str, agent_id: str, content: str, metadata: dict = None,
|
|
62
|
+
ttl_seconds: int = None, tags: list = None, namespace: str = "default",
|
|
63
|
+
importance: int = 5, outcome: str = "unknown", detect_conflicts: bool = False) -> dict:
|
|
64
|
+
return self._req("POST", "/memory/store", {
|
|
65
|
+
"user_id": user_id, "agent_id": agent_id, "content": content,
|
|
66
|
+
"metadata": metadata, "ttl_seconds": ttl_seconds, "tags": tags,
|
|
67
|
+
"namespace": namespace, "importance": importance, "outcome": outcome,
|
|
68
|
+
"detect_conflicts": detect_conflicts,
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
def search(self, user_id: str, query: str, agent_id: str = None, limit: int = 10,
|
|
72
|
+
namespace: str = None, tags: list = None, min_importance: int = None) -> dict:
|
|
73
|
+
qs = self._qs({
|
|
74
|
+
"user_id": user_id, "q": query, "agent_id": agent_id, "limit": limit,
|
|
75
|
+
"namespace": namespace, "tags": ",".join(tags) if tags else None,
|
|
76
|
+
"min_importance": min_importance,
|
|
77
|
+
})
|
|
78
|
+
return self._req("GET", "/memory/retrieve?" + qs)
|
|
79
|
+
|
|
80
|
+
def delete(self, id: str = None, user_id: str = None, agent_id: str = None) -> dict:
|
|
81
|
+
return self._req("DELETE", "/memory/forget?" + self._qs({"id": id, "user_id": user_id, "agent_id": agent_id}))
|
|
82
|
+
|
|
83
|
+
def context(self, user_id: str, agent_id: str = None, max_tokens: int = 2000, format: str = "raw") -> dict:
|
|
84
|
+
return self._req("GET", "/memory/context?" + self._qs({
|
|
85
|
+
"user_id": user_id, "agent_id": agent_id, "max_tokens": max_tokens, "format": format}))
|
|
86
|
+
|
|
87
|
+
def feedback(self, memory_id: str, outcome: str, confidence: float = 1.0) -> dict:
|
|
88
|
+
return self._req("POST", "/memory/feedback", {"memory_id": memory_id, "outcome": outcome, "confidence": confidence})
|
|
89
|
+
|
|
90
|
+
def batch(self, memories: list) -> dict:
|
|
91
|
+
return self._req("POST", "/memory/batch", {"memories": memories})
|
|
92
|
+
|
|
93
|
+
def stats(self, user_id: str = None) -> dict:
|
|
94
|
+
return self._req("GET", "/memory/stats?" + self._qs({"user_id": user_id}))
|
|
95
|
+
|
|
96
|
+
def usage(self) -> dict:
|
|
97
|
+
return self._req("GET", "/usage")
|
|
98
|
+
|
|
99
|
+
# ---- async (requires httpx) ----------------------------------------
|
|
100
|
+
async def async_store(self, **kwargs) -> dict:
|
|
101
|
+
return await self._async_req("POST", "/memory/store", self._store_body(**kwargs))
|
|
102
|
+
|
|
103
|
+
async def async_search(self, user_id: str, query: str, **kwargs) -> dict:
|
|
104
|
+
qs = self._qs({"user_id": user_id, "q": query, **kwargs})
|
|
105
|
+
return await self._async_req("GET", "/memory/retrieve?" + qs)
|
|
106
|
+
|
|
107
|
+
def _store_body(self, user_id, agent_id, content, **kw):
|
|
108
|
+
return {"user_id": user_id, "agent_id": agent_id, "content": content, **kw}
|
|
109
|
+
|
|
110
|
+
async def _async_req(self, method: str, path: str, body: Optional[dict] = None) -> dict:
|
|
111
|
+
try:
|
|
112
|
+
import httpx # optional dependency
|
|
113
|
+
except ImportError as e: # pragma: no cover
|
|
114
|
+
raise AgentMemoError("async methods require 'httpx' (pip install httpx)") from e
|
|
115
|
+
headers = {"Authorization": f"Bearer {self.api_key}"}
|
|
116
|
+
async with httpx.AsyncClient(base_url=self.base_url) as client:
|
|
117
|
+
resp = await client.request(method, path, json=body, headers=headers)
|
|
118
|
+
data = resp.json() if resp.content else {}
|
|
119
|
+
if resp.status_code >= 400:
|
|
120
|
+
raise AgentMemoError(data.get("error", "request failed"), resp.status_code, data.get("code"), data)
|
|
121
|
+
return data
|
|
122
|
+
|
|
123
|
+
@staticmethod
|
|
124
|
+
def signup(name: str, base_url: str = DEFAULT_BASE_URL) -> dict:
|
|
125
|
+
req = urllib.request.Request(
|
|
126
|
+
base_url.rstrip("/") + "/signup",
|
|
127
|
+
data=json.dumps({"name": name}).encode(),
|
|
128
|
+
headers={"Content-Type": "application/json"},
|
|
129
|
+
method="POST",
|
|
130
|
+
)
|
|
131
|
+
with urllib.request.urlopen(req) as resp:
|
|
132
|
+
return json.loads(resp.read().decode() or "{}")
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: agentmemo-py
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Persistent memory for AI agents — store, retrieve, and recall context across sessions.
|
|
5
|
+
Author-email: "Dr. Nadeem Shaikh" <nadeembyit@gmail.com>
|
|
6
|
+
License: Apache-2.0
|
|
7
|
+
Project-URL: Homepage, https://agentmemo.dev
|
|
8
|
+
Project-URL: Documentation, https://agentmemo.dev/docs
|
|
9
|
+
Project-URL: Repository, https://github.com/skullbase-ecom/agentmemo
|
|
10
|
+
Keywords: ai,agent,memory,llm,mcp,semantic-search,agentmemo
|
|
11
|
+
Requires-Python: >=3.8
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
Provides-Extra: async
|
|
14
|
+
Requires-Dist: httpx>=0.24; extra == "async"
|
|
15
|
+
|
|
16
|
+
# agentmemo
|
|
17
|
+
|
|
18
|
+
Persistent memory for AI agents. Store, semantically retrieve, and recall context across sessions. Pure standard library (no required dependencies).
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
pip install agentmemo
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Quick start
|
|
25
|
+
|
|
26
|
+
```python
|
|
27
|
+
from agentmemo import MemoryClient
|
|
28
|
+
|
|
29
|
+
# Get a free key (or pass an existing one)
|
|
30
|
+
key = MemoryClient.signup("my-agent")["api_key"]
|
|
31
|
+
mem = MemoryClient(key)
|
|
32
|
+
|
|
33
|
+
# Store
|
|
34
|
+
mem.store(
|
|
35
|
+
user_id="user_123",
|
|
36
|
+
agent_id="assistant",
|
|
37
|
+
content="User prefers dark mode and works in TypeScript.",
|
|
38
|
+
tags=["preference"],
|
|
39
|
+
importance=8,
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
# Retrieve semantically
|
|
43
|
+
hits = mem.search(user_id="user_123", query="what are the user's preferences?")
|
|
44
|
+
|
|
45
|
+
# Context for an LLM system prompt
|
|
46
|
+
ctx = mem.context(user_id="user_123", format="anthropic")["context"]
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## API
|
|
50
|
+
|
|
51
|
+
- `store(user_id, agent_id, content, metadata=None, ttl_seconds=None, tags=None, namespace="default", importance=5, outcome="unknown", detect_conflicts=False)`
|
|
52
|
+
- `search(user_id, query, agent_id=None, limit=10, namespace=None, tags=None, min_importance=None)`
|
|
53
|
+
- `delete(id=None, user_id=None, agent_id=None)`
|
|
54
|
+
- `context(user_id, agent_id=None, max_tokens=2000, format="raw")`
|
|
55
|
+
- `feedback(memory_id, outcome, confidence=1.0)`
|
|
56
|
+
- `batch(memories)`
|
|
57
|
+
- `stats(user_id=None)`, `usage()`
|
|
58
|
+
- `MemoryClient.signup(name)` — static, returns a free API key
|
|
59
|
+
- Async: `await mem.async_store(...)`, `await mem.async_search(...)` (requires `pip install agentmemo[async]`)
|
|
60
|
+
|
|
61
|
+
Errors raise `AgentMemoError` with `.status`, `.code`, `.body`.
|
|
62
|
+
|
|
63
|
+
Docs: https://agentmemo.dev/docs · Apache-2.0 · Built by Dr. Nadeem Shaikh
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
agentmemo
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "agentmemo-py"
|
|
7
|
+
version = "1.0.0"
|
|
8
|
+
description = "Persistent memory for AI agents — store, retrieve, and recall context across sessions."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.8"
|
|
11
|
+
license = { text = "Apache-2.0" }
|
|
12
|
+
authors = [{ name = "Dr. Nadeem Shaikh", email = "nadeembyit@gmail.com" }]
|
|
13
|
+
keywords = ["ai", "agent", "memory", "llm", "mcp", "semantic-search", "agentmemo"]
|
|
14
|
+
dependencies = []
|
|
15
|
+
|
|
16
|
+
[project.optional-dependencies]
|
|
17
|
+
async = ["httpx>=0.24"]
|
|
18
|
+
|
|
19
|
+
[project.urls]
|
|
20
|
+
Homepage = "https://agentmemo.dev"
|
|
21
|
+
Documentation = "https://agentmemo.dev/docs"
|
|
22
|
+
Repository = "https://github.com/skullbase-ecom/agentmemo"
|
|
23
|
+
|
|
24
|
+
[tool.setuptools]
|
|
25
|
+
packages = ["agentmemo"]
|