agentmem-sdk 0.1.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.
- agentmem_sdk-0.1.0/LICENSE +21 -0
- agentmem_sdk-0.1.0/PKG-INFO +421 -0
- agentmem_sdk-0.1.0/README.md +366 -0
- agentmem_sdk-0.1.0/pyproject.toml +56 -0
- agentmem_sdk-0.1.0/setup.cfg +4 -0
- agentmem_sdk-0.1.0/src/agentmem/__init__.py +68 -0
- agentmem_sdk-0.1.0/src/agentmem/adapters/__init__.py +6 -0
- agentmem_sdk-0.1.0/src/agentmem/adapters/base.py +6 -0
- agentmem_sdk-0.1.0/src/agentmem/adapters/callback.py +10 -0
- agentmem_sdk-0.1.0/src/agentmem/adapters/context_surfaces.py +322 -0
- agentmem_sdk-0.1.0/src/agentmem/adapters/supabase.py +75 -0
- agentmem_sdk-0.1.0/src/agentmem/client.py +145 -0
- agentmem_sdk-0.1.0/src/agentmem/errors.py +26 -0
- agentmem_sdk-0.1.0/src/agentmem/memory.py +445 -0
- agentmem_sdk-0.1.0/src/agentmem/retrieval.py +43 -0
- agentmem_sdk-0.1.0/src/agentmem/types.py +18 -0
- agentmem_sdk-0.1.0/src/agentmem_sdk.egg-info/PKG-INFO +421 -0
- agentmem_sdk-0.1.0/src/agentmem_sdk.egg-info/SOURCES.txt +24 -0
- agentmem_sdk-0.1.0/src/agentmem_sdk.egg-info/dependency_links.txt +1 -0
- agentmem_sdk-0.1.0/src/agentmem_sdk.egg-info/requires.txt +10 -0
- agentmem_sdk-0.1.0/src/agentmem_sdk.egg-info/top_level.txt +1 -0
- agentmem_sdk-0.1.0/tests/test_adapters.py +12 -0
- agentmem_sdk-0.1.0/tests/test_live.py +230 -0
- agentmem_sdk-0.1.0/tests/test_memory.py +71 -0
- agentmem_sdk-0.1.0/tests/test_module_api.py +14 -0
- agentmem_sdk-0.1.0/tests/test_retrieval.py +98 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Jimmy Nagles
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,421 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: agentmem-sdk
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Agent context SDK — persistent memory and structured retrieval for any AI application. Powered by Redis.
|
|
5
|
+
Author-email: Jimmy Nagles <jimmynagles@gmail.com>
|
|
6
|
+
License: MIT License
|
|
7
|
+
|
|
8
|
+
Copyright (c) 2026 Jimmy Nagles
|
|
9
|
+
|
|
10
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
11
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
12
|
+
in the Software without restriction, including without limitation the rights
|
|
13
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
14
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
15
|
+
furnished to do so, subject to the following conditions:
|
|
16
|
+
|
|
17
|
+
The above copyright notice and this permission notice shall be included in all
|
|
18
|
+
copies or substantial portions of the Software.
|
|
19
|
+
|
|
20
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
21
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
22
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
23
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
24
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
25
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
26
|
+
SOFTWARE.
|
|
27
|
+
|
|
28
|
+
Project-URL: Homepage, https://github.com/JimmyNagles/agentmem
|
|
29
|
+
Project-URL: Repository, https://github.com/JimmyNagles/agentmem
|
|
30
|
+
Project-URL: Issues, https://github.com/JimmyNagles/agentmem/issues
|
|
31
|
+
Keywords: ai,agent,memory,redis,vector-search,llm,retrieval,embeddings,semantic-search
|
|
32
|
+
Classifier: Development Status :: 4 - Beta
|
|
33
|
+
Classifier: Intended Audience :: Developers
|
|
34
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
35
|
+
Classifier: Operating System :: OS Independent
|
|
36
|
+
Classifier: Programming Language :: Python :: 3
|
|
37
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
38
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
39
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
40
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
41
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
42
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
43
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
44
|
+
Requires-Python: >=3.9
|
|
45
|
+
Description-Content-Type: text/markdown
|
|
46
|
+
License-File: LICENSE
|
|
47
|
+
Provides-Extra: redis
|
|
48
|
+
Requires-Dist: redis>=5.0; extra == "redis"
|
|
49
|
+
Provides-Extra: supabase
|
|
50
|
+
Requires-Dist: supabase>=2.0; extra == "supabase"
|
|
51
|
+
Provides-Extra: all
|
|
52
|
+
Requires-Dist: redis>=5.0; extra == "all"
|
|
53
|
+
Requires-Dist: supabase>=2.0; extra == "all"
|
|
54
|
+
Dynamic: license-file
|
|
55
|
+
|
|
56
|
+
# agentmem
|
|
57
|
+
|
|
58
|
+
Agent context SDK for Python. Give any AI app persistent memory and structured retrieval.
|
|
59
|
+
|
|
60
|
+
Inspired by [Redis Agent Memory Server](https://github.com/redis/agent-memory-server) and [Redis Context Surfaces](https://github.com/redis/context-engine-demos).
|
|
61
|
+
|
|
62
|
+
## Quick Start
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
pip install agentmem
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Add to your `.env`:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
AGENTMEM_REDIS_URL=redis://default:password@host:port
|
|
72
|
+
OPENAI_API_KEY=sk-...
|
|
73
|
+
AGENTMEM_APP_ID=my-app
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Use it:
|
|
77
|
+
|
|
78
|
+
```python
|
|
79
|
+
import agentmem
|
|
80
|
+
|
|
81
|
+
agentmem.init()
|
|
82
|
+
|
|
83
|
+
# Store something the app learned
|
|
84
|
+
agentmem.remember("User prefers numbered lists over bullets", scope="user-42")
|
|
85
|
+
|
|
86
|
+
# Later, before generating a response
|
|
87
|
+
corrections = agentmem.recall("formatting preferences", scope="user-42")
|
|
88
|
+
# ["User prefers numbered lists over bullets"]
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
That's it. Three env vars, three lines of code. Memory persists in Redis Cloud with semantic vector search.
|
|
92
|
+
|
|
93
|
+
## What This Is
|
|
94
|
+
|
|
95
|
+
`agentmem` is a package your agent app imports. It is not an agent. It does not run prompts, call models, or orchestrate tools.
|
|
96
|
+
|
|
97
|
+
It does two things:
|
|
98
|
+
|
|
99
|
+
1. **Memory** — store things the app learned (`remember`), search them by meaning later (`recall`)
|
|
100
|
+
2. **Retrieval** — query the app's own data through adapters (`register_source`, `retrieve`)
|
|
101
|
+
|
|
102
|
+
Memory is what the app *learned*. Retrieval is what the app can *look up*. They're separate capabilities. Your app composes them however it wants.
|
|
103
|
+
|
|
104
|
+
## How Memory Works
|
|
105
|
+
|
|
106
|
+
When you call `remember("User prefers numbered lists")`:
|
|
107
|
+
|
|
108
|
+
1. agentmem sends the text to OpenAI to generate an embedding (a list of numbers that captures the meaning)
|
|
109
|
+
2. The embedding + text are stored in your Redis Cloud database
|
|
110
|
+
|
|
111
|
+
When you call `recall("formatting preferences")`:
|
|
112
|
+
|
|
113
|
+
1. agentmem generates an embedding for the query
|
|
114
|
+
2. Redis finds the stored memories with the most similar meaning
|
|
115
|
+
3. Returns them ranked by relevance
|
|
116
|
+
|
|
117
|
+
That's why "formatting preferences" finds "User prefers numbered lists" — they mean similar things even though the words are different.
|
|
118
|
+
|
|
119
|
+
**Why do I need an OpenAI key?** Redis stores and searches vectors but doesn't generate them. Something has to convert text into numbers. OpenAI does that. If you use the AMS backend instead (see below), AMS handles the OpenAI key internally and your app doesn't need one.
|
|
120
|
+
|
|
121
|
+
## Memory Backends
|
|
122
|
+
|
|
123
|
+
### Direct Redis Cloud (recommended)
|
|
124
|
+
|
|
125
|
+
Connects straight to Redis Cloud. Your app generates embeddings via OpenAI and stores them in Redis. No middleware, no server to deploy.
|
|
126
|
+
|
|
127
|
+
```python
|
|
128
|
+
from agentmem import AgentMem
|
|
129
|
+
|
|
130
|
+
mem = AgentMem(
|
|
131
|
+
redis_url="redis://default:password@host:port",
|
|
132
|
+
app_id="my-app",
|
|
133
|
+
openai_api_key="sk-...",
|
|
134
|
+
)
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Requires:
|
|
138
|
+
- Redis Cloud account with search module (free tier works)
|
|
139
|
+
- OpenAI API key (for embeddings)
|
|
140
|
+
|
|
141
|
+
### Via Redis Agent Memory Server (AMS)
|
|
142
|
+
|
|
143
|
+
Connects to [AMS](https://github.com/redis/agent-memory-server), which handles embeddings and Redis for you. Your app does NOT need an OpenAI key — AMS has its own.
|
|
144
|
+
|
|
145
|
+
```python
|
|
146
|
+
mem = AgentMem(
|
|
147
|
+
base_url="http://localhost:8000",
|
|
148
|
+
app_id="my-app",
|
|
149
|
+
)
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
Requires AMS running (Docker or hosted).
|
|
153
|
+
|
|
154
|
+
### Local in-memory (for development)
|
|
155
|
+
|
|
156
|
+
No server, no credentials. Memories live in process memory and disappear on restart.
|
|
157
|
+
|
|
158
|
+
```python
|
|
159
|
+
mem = AgentMem(app_id="my-app")
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
## Retrieval
|
|
163
|
+
|
|
164
|
+
Retrieval lets the app query its own data at runtime. Register a data source with an adapter, then call `retrieve()`.
|
|
165
|
+
|
|
166
|
+
### ContextSurfacesAdapter
|
|
167
|
+
|
|
168
|
+
Query data through [Redis Context Surfaces](https://github.com/redis/context-engine-demos). Context Surfaces reads your Redis data model and auto-generates search tools — `search_product_by_text`, `filter_order_by_status`, `get_customer_by_id`, etc. No OpenAI key needed — Context Surfaces handles everything.
|
|
169
|
+
|
|
170
|
+
```python
|
|
171
|
+
from agentmem.adapters.context_surfaces import ContextSurfacesAdapter
|
|
172
|
+
|
|
173
|
+
mem.register_source("products", ContextSurfacesAdapter(
|
|
174
|
+
agent_key="cs_agent_...",
|
|
175
|
+
tool_name="search_product_by_text",
|
|
176
|
+
))
|
|
177
|
+
|
|
178
|
+
results = mem.retrieve("wireless headphones", source="products")
|
|
179
|
+
# [{"name": "Wireless Headphones Pro", "price": 79.99, ...}]
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
Requires a Context Surface connected to your Redis Cloud. See [Context Surfaces Setup](#context-surfaces-setup) below.
|
|
183
|
+
|
|
184
|
+
### SupabaseAdapter
|
|
185
|
+
|
|
186
|
+
Query a Supabase table with text search and scope filtering. For apps that keep data in Supabase.
|
|
187
|
+
|
|
188
|
+
```python
|
|
189
|
+
from agentmem.adapters.supabase import SupabaseAdapter
|
|
190
|
+
|
|
191
|
+
mem.register_source("orders", SupabaseAdapter(
|
|
192
|
+
url="https://xxx.supabase.co",
|
|
193
|
+
key="sb_secret_...",
|
|
194
|
+
table="orders",
|
|
195
|
+
search_columns=["description", "notes"],
|
|
196
|
+
return_columns=["id", "status", "total"],
|
|
197
|
+
scope_column="user_id",
|
|
198
|
+
))
|
|
199
|
+
|
|
200
|
+
results = mem.retrieve("shipping delay", source="orders", scope="user-42")
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
### CallbackAdapter
|
|
204
|
+
|
|
205
|
+
Wrap any function as a retrieval source. For custom data access logic.
|
|
206
|
+
|
|
207
|
+
```python
|
|
208
|
+
from agentmem.adapters.callback import CallbackAdapter
|
|
209
|
+
|
|
210
|
+
def search_tickets(query, scope, limit):
|
|
211
|
+
return my_db.search(query, user_id=scope, limit=limit)
|
|
212
|
+
|
|
213
|
+
mem.register_source("tickets", CallbackAdapter(fn=search_tickets))
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
### Custom adapters
|
|
217
|
+
|
|
218
|
+
Any class that implements `BaseAdapter`:
|
|
219
|
+
|
|
220
|
+
```python
|
|
221
|
+
from agentmem.adapters.base import BaseAdapter
|
|
222
|
+
|
|
223
|
+
class MyAdapter(BaseAdapter):
|
|
224
|
+
def retrieve(self, query, scope=None, limit=5):
|
|
225
|
+
return self.db.search(query, tenant=scope, max_results=limit)
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
## Using Memory + Retrieval Together
|
|
229
|
+
|
|
230
|
+
```python
|
|
231
|
+
import agentmem
|
|
232
|
+
from agentmem.adapters.callback import CallbackAdapter
|
|
233
|
+
|
|
234
|
+
agentmem.init() # reads AGENTMEM_REDIS_URL + OPENAI_API_KEY from env
|
|
235
|
+
|
|
236
|
+
agentmem.register_source("tickets", CallbackAdapter(fn=search_tickets))
|
|
237
|
+
|
|
238
|
+
# Before generating a response — gather context from both layers
|
|
239
|
+
memories = agentmem.recall("customer preferences", scope="user-42")
|
|
240
|
+
tickets = agentmem.retrieve("billing question", source="tickets", scope="user-42")
|
|
241
|
+
|
|
242
|
+
prompt = f"""
|
|
243
|
+
LEARNED ABOUT THIS USER:
|
|
244
|
+
{chr(10).join(f'- {m}' for m in memories)}
|
|
245
|
+
|
|
246
|
+
RECENT TICKETS:
|
|
247
|
+
{chr(10).join(str(t) for t in tickets)}
|
|
248
|
+
|
|
249
|
+
Now respond to their question: ...
|
|
250
|
+
"""
|
|
251
|
+
|
|
252
|
+
# After the interaction — store anything worth keeping
|
|
253
|
+
agentmem.remember("User is on the Pro plan and prefers email support", scope="user-42")
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
## Environment Variables
|
|
257
|
+
|
|
258
|
+
```bash
|
|
259
|
+
# Direct Redis (recommended for production)
|
|
260
|
+
AGENTMEM_REDIS_URL=redis://default:password@host:port
|
|
261
|
+
OPENAI_API_KEY=sk-... # only needed for direct Redis, not for AMS
|
|
262
|
+
|
|
263
|
+
# OR via AMS (alternative — no OpenAI key needed in your app)
|
|
264
|
+
AGENTMEM_BASE_URL=http://localhost:8000
|
|
265
|
+
|
|
266
|
+
# Common
|
|
267
|
+
AGENTMEM_APP_ID=my-app
|
|
268
|
+
AGENTMEM_TIMEOUT=5.0 # optional, default 5 seconds
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
```python
|
|
272
|
+
import agentmem
|
|
273
|
+
agentmem.init() # reads from env vars automatically
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
## API
|
|
277
|
+
|
|
278
|
+
### Core
|
|
279
|
+
|
|
280
|
+
| Function | Signature |
|
|
281
|
+
|----------|-----------|
|
|
282
|
+
| `init()` | `init(base_url=None, app_id=None, redis_url=None, openai_api_key=None, timeout=None, on_error=None)` |
|
|
283
|
+
| `AgentMem()` | `AgentMem(base_url=None, app_id="default", redis_url=None, openai_api_key=None, timeout=5.0, on_error=None)` |
|
|
284
|
+
|
|
285
|
+
Backend selection: `redis_url` → direct Redis. `base_url` → AMS. Neither → in-memory.
|
|
286
|
+
|
|
287
|
+
### Memory
|
|
288
|
+
|
|
289
|
+
| Function | Signature | Returns |
|
|
290
|
+
|----------|-----------|---------|
|
|
291
|
+
| `remember()` | `remember(text, scope=None, topics=None, metadata=None)` | `bool` |
|
|
292
|
+
| `recall()` | `recall(query, scope=None, limit=5)` | `list[str]` |
|
|
293
|
+
|
|
294
|
+
- `scope` — partition memories by tenant, user, project, workspace
|
|
295
|
+
- `topics` — semantic tags stored with the memory (for future filtering)
|
|
296
|
+
- `metadata` — structured context stored alongside (max 4KB, must be JSON-serializable)
|
|
297
|
+
- `recall()` matches by meaning, not exact words
|
|
298
|
+
|
|
299
|
+
### Retrieval
|
|
300
|
+
|
|
301
|
+
| Function | Signature | Returns |
|
|
302
|
+
|----------|-----------|---------|
|
|
303
|
+
| `register_source()` | `register_source(name, adapter)` | `None` |
|
|
304
|
+
| `retrieve()` | `retrieve(query, source, scope=None, limit=5)` | `list[dict]` |
|
|
305
|
+
|
|
306
|
+
### Properties
|
|
307
|
+
|
|
308
|
+
| Property | Type | Description |
|
|
309
|
+
|----------|------|-------------|
|
|
310
|
+
| `.last_error` | `Exception or None` | Set on failure, cleared on success |
|
|
311
|
+
| `.initialized` | `bool` | False if init failed |
|
|
312
|
+
|
|
313
|
+
## Failure Behavior
|
|
314
|
+
|
|
315
|
+
agentmem never crashes the host app.
|
|
316
|
+
|
|
317
|
+
**Runtime errors** (Redis down, adapter timeout, network failure):
|
|
318
|
+
- `remember()` returns `False`
|
|
319
|
+
- `recall()` returns `[]`
|
|
320
|
+
- `retrieve()` returns `[]`
|
|
321
|
+
- Error stored in `last_error` and passed to `on_error` callback
|
|
322
|
+
|
|
323
|
+
**Programmer errors** (invalid arguments):
|
|
324
|
+
- Non-JSON-serializable metadata → `MemoryValidationError`
|
|
325
|
+
- Metadata over 4KB → `MemoryValidationError`
|
|
326
|
+
- Missing adapter config → `ConfigurationError`
|
|
327
|
+
|
|
328
|
+
```python
|
|
329
|
+
def on_err(method, exc):
|
|
330
|
+
print(f"agentmem {method} failed: {exc}")
|
|
331
|
+
|
|
332
|
+
mem = AgentMem(app_id="my-app", on_error=on_err)
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
## Context Surfaces Setup
|
|
336
|
+
|
|
337
|
+
To use the `ContextSurfacesAdapter`, you need a Context Surface connected to your Redis Cloud database. This is a one-time setup.
|
|
338
|
+
|
|
339
|
+
### Using the CLI
|
|
340
|
+
|
|
341
|
+
```bash
|
|
342
|
+
pip install context-surfaces # requires Python 3.11+
|
|
343
|
+
|
|
344
|
+
# Create a surface pointing at your Redis Cloud
|
|
345
|
+
ctxctl surface create \
|
|
346
|
+
--name "my-surface" \
|
|
347
|
+
--models ./models.py \
|
|
348
|
+
--redis-addr "host:port" \
|
|
349
|
+
--redis-password "$REDIS_PASSWORD" \
|
|
350
|
+
--admin-key "$CTX_ADMIN_KEY"
|
|
351
|
+
|
|
352
|
+
# Create an agent key for querying
|
|
353
|
+
ctxctl agent create \
|
|
354
|
+
--surface-id "$SURFACE_ID" \
|
|
355
|
+
--name "my-agent" \
|
|
356
|
+
--admin-key "$CTX_ADMIN_KEY"
|
|
357
|
+
|
|
358
|
+
# Verify — list auto-generated tools
|
|
359
|
+
ctxctl tools list --agent-key "$AGENT_KEY"
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
### Using the ContextSurfaceManager (Python)
|
|
363
|
+
|
|
364
|
+
```python
|
|
365
|
+
from agentmem.adapters.context_surfaces import ContextSurfaceManager
|
|
366
|
+
|
|
367
|
+
mgr = ContextSurfaceManager(admin_key="cs_admin_...")
|
|
368
|
+
|
|
369
|
+
surfaces = mgr.list_surfaces()
|
|
370
|
+
tools = mgr.list_tools(agent_key="cs_agent_...")
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
### Getting credentials
|
|
374
|
+
|
|
375
|
+
- `CTX_ADMIN_KEY` — found in Redis Cloud dashboard under Context Surfaces → Access Management → API Keys
|
|
376
|
+
- `AGENT_KEY` — created when you run `ctxctl agent create`
|
|
377
|
+
- `REDIS_PASSWORD` — found in Redis Cloud dashboard under your database → Security
|
|
378
|
+
|
|
379
|
+
## Where Credentials Go
|
|
380
|
+
|
|
381
|
+
| Credential | Where | When needed |
|
|
382
|
+
|-----------|-------|-------------|
|
|
383
|
+
| `AGENTMEM_REDIS_URL` | Your app `.env` | Direct Redis memory |
|
|
384
|
+
| `OPENAI_API_KEY` | Your app `.env` | Direct Redis memory (not needed for AMS) |
|
|
385
|
+
| `AGENTMEM_BASE_URL` | Your app `.env` | AMS memory (alternative to direct Redis) |
|
|
386
|
+
| `AGENTMEM_APP_ID` | Your app `.env` | Always |
|
|
387
|
+
| `CTX_ADMIN_KEY` | Setup only | Creating Context Surfaces (one-time) |
|
|
388
|
+
| Agent key (`cs_agent_...`) | Your app code or `.env` | Querying Context Surfaces |
|
|
389
|
+
| Supabase URL/key | Your app code or `.env` | SupabaseAdapter |
|
|
390
|
+
|
|
391
|
+
## Install (development)
|
|
392
|
+
|
|
393
|
+
```bash
|
|
394
|
+
# From a local checkout
|
|
395
|
+
pip install -e /path/to/agentmem
|
|
396
|
+
|
|
397
|
+
# With Redis support
|
|
398
|
+
pip install -e /path/to/agentmem[redis]
|
|
399
|
+
|
|
400
|
+
# With Supabase support
|
|
401
|
+
pip install -e /path/to/agentmem[supabase]
|
|
402
|
+
|
|
403
|
+
# Everything
|
|
404
|
+
pip install -e /path/to/agentmem[all]
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
## Testing
|
|
408
|
+
|
|
409
|
+
```bash
|
|
410
|
+
PYTHONPATH=src python3 -m unittest discover -s tests
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
## What This Package Does Not Do
|
|
414
|
+
|
|
415
|
+
- Run an LLM
|
|
416
|
+
- Act as an autonomous agent
|
|
417
|
+
- Manage tool orchestration
|
|
418
|
+
- Automatically crawl or index your database
|
|
419
|
+
- Merge memory and retrieval into one magic result
|
|
420
|
+
|
|
421
|
+
You own the application logic. agentmem gives you memory and retrieval primitives.
|