supermemory-agent-framework 1.0.0__tar.gz → 1.0.1__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.
- {supermemory_agent_framework-1.0.0 → supermemory_agent_framework-1.0.1}/PKG-INFO +58 -60
- {supermemory_agent_framework-1.0.0 → supermemory_agent_framework-1.0.1}/README.md +55 -57
- {supermemory_agent_framework-1.0.0 → supermemory_agent_framework-1.0.1}/pyproject.toml +2 -2
- {supermemory_agent_framework-1.0.0 → supermemory_agent_framework-1.0.1}/src/supermemory_agent_framework/context_provider.py +9 -3
- {supermemory_agent_framework-1.0.0 → supermemory_agent_framework-1.0.1}/src/supermemory_agent_framework/tools.py +67 -20
- {supermemory_agent_framework-1.0.0 → supermemory_agent_framework-1.0.1}/src/supermemory_agent_framework/utils.py +26 -11
- {supermemory_agent_framework-1.0.0 → supermemory_agent_framework-1.0.1}/.gitignore +0 -0
- {supermemory_agent_framework-1.0.0 → supermemory_agent_framework-1.0.1}/LICENSE +0 -0
- {supermemory_agent_framework-1.0.0 → supermemory_agent_framework-1.0.1}/src/supermemory_agent_framework/__init__.py +0 -0
- {supermemory_agent_framework-1.0.0 → supermemory_agent_framework-1.0.1}/src/supermemory_agent_framework/connection.py +0 -0
- {supermemory_agent_framework-1.0.0 → supermemory_agent_framework-1.0.1}/src/supermemory_agent_framework/exceptions.py +0 -0
- {supermemory_agent_framework-1.0.0 → supermemory_agent_framework-1.0.1}/src/supermemory_agent_framework/middleware.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
2
|
Name: supermemory-agent-framework
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.1
|
|
4
4
|
Summary: Memory tools and middleware for Microsoft Agent Framework with supermemory
|
|
5
5
|
Project-URL: Homepage, https://supermemory.ai
|
|
6
6
|
Project-URL: Repository, https://github.com/supermemoryai/supermemory
|
|
@@ -20,7 +20,7 @@ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
|
20
20
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
21
21
|
Requires-Python: >=3.10
|
|
22
22
|
Requires-Dist: agent-framework-core>=1.0.0rc3
|
|
23
|
-
Requires-Dist: supermemory>=3.
|
|
23
|
+
Requires-Dist: supermemory>=3.16.0
|
|
24
24
|
Requires-Dist: typing-extensions>=4.0.0
|
|
25
25
|
Description-Content-Type: text/markdown
|
|
26
26
|
|
|
@@ -35,23 +35,13 @@ This package provides both **automatic memory injection middleware** and **manua
|
|
|
35
35
|
Install using uv (recommended):
|
|
36
36
|
|
|
37
37
|
```bash
|
|
38
|
-
uv add
|
|
38
|
+
uv add supermemory-agent-framework
|
|
39
39
|
```
|
|
40
40
|
|
|
41
41
|
Or with pip:
|
|
42
42
|
|
|
43
43
|
```bash
|
|
44
|
-
pip install
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
> **Note:** The `--prerelease=allow` / `--pre` flag is required because `agent-framework-core` depends on pre-release versions of Azure packages.
|
|
48
|
-
|
|
49
|
-
For async HTTP support (recommended):
|
|
50
|
-
|
|
51
|
-
```bash
|
|
52
|
-
uv add supermemory-agent-framework[async]
|
|
53
|
-
# or
|
|
54
|
-
pip install supermemory-agent-framework[async]
|
|
44
|
+
pip install supermemory-agent-framework
|
|
55
45
|
```
|
|
56
46
|
|
|
57
47
|
## Quick Start
|
|
@@ -64,14 +54,19 @@ The easiest way to add memory capabilities is using the `SupermemoryChatMiddlewa
|
|
|
64
54
|
import asyncio
|
|
65
55
|
from agent_framework.openai import OpenAIResponsesClient
|
|
66
56
|
from supermemory_agent_framework import (
|
|
57
|
+
AgentSupermemory,
|
|
67
58
|
SupermemoryChatMiddleware,
|
|
68
59
|
SupermemoryMiddlewareOptions,
|
|
69
60
|
)
|
|
70
61
|
|
|
71
62
|
async def main():
|
|
72
|
-
|
|
73
|
-
|
|
63
|
+
connection = AgentSupermemory(
|
|
64
|
+
api_key="your-supermemory-api-key",
|
|
74
65
|
container_tag="user-123",
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
middleware = SupermemoryChatMiddleware(
|
|
69
|
+
connection,
|
|
75
70
|
options=SupermemoryMiddlewareOptions(
|
|
76
71
|
mode="full", # "profile", "query", or "full"
|
|
77
72
|
verbose=True, # Enable logging
|
|
@@ -103,13 +98,16 @@ The most idiomatic way to add memory in Agent Framework, using the same pattern
|
|
|
103
98
|
import asyncio
|
|
104
99
|
from agent_framework import AgentSession
|
|
105
100
|
from agent_framework.openai import OpenAIResponsesClient
|
|
106
|
-
from supermemory_agent_framework import SupermemoryContextProvider
|
|
101
|
+
from supermemory_agent_framework import AgentSupermemory, SupermemoryContextProvider
|
|
107
102
|
|
|
108
103
|
async def main():
|
|
109
|
-
|
|
110
|
-
provider = SupermemoryContextProvider(
|
|
111
|
-
container_tag="user-123",
|
|
104
|
+
connection = AgentSupermemory(
|
|
112
105
|
api_key="your-supermemory-api-key",
|
|
106
|
+
container_tag="user-123",
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
provider = SupermemoryContextProvider(
|
|
110
|
+
connection,
|
|
113
111
|
mode="full",
|
|
114
112
|
store_conversations=True,
|
|
115
113
|
)
|
|
@@ -139,14 +137,14 @@ For explicit tool-based memory access:
|
|
|
139
137
|
```python
|
|
140
138
|
import asyncio
|
|
141
139
|
from agent_framework.openai import OpenAIResponsesClient
|
|
142
|
-
from supermemory_agent_framework import SupermemoryTools
|
|
140
|
+
from supermemory_agent_framework import AgentSupermemory, SupermemoryTools
|
|
143
141
|
|
|
144
142
|
async def main():
|
|
145
|
-
|
|
146
|
-
tools = SupermemoryTools(
|
|
143
|
+
connection = AgentSupermemory(
|
|
147
144
|
api_key="your-supermemory-api-key",
|
|
148
|
-
|
|
145
|
+
container_tag="user-123",
|
|
149
146
|
)
|
|
147
|
+
tools = SupermemoryTools(connection)
|
|
150
148
|
|
|
151
149
|
# Create agent
|
|
152
150
|
agent = OpenAIResponsesClient().as_agent(
|
|
@@ -172,6 +170,7 @@ For maximum flexibility, use both middleware (automatic context injection) and t
|
|
|
172
170
|
import asyncio
|
|
173
171
|
from agent_framework.openai import OpenAIResponsesClient
|
|
174
172
|
from supermemory_agent_framework import (
|
|
173
|
+
AgentSupermemory,
|
|
175
174
|
SupermemoryChatMiddleware,
|
|
176
175
|
SupermemoryMiddlewareOptions,
|
|
177
176
|
SupermemoryTools,
|
|
@@ -179,14 +178,17 @@ from supermemory_agent_framework import (
|
|
|
179
178
|
|
|
180
179
|
async def main():
|
|
181
180
|
api_key = "your-supermemory-api-key"
|
|
181
|
+
connection = AgentSupermemory(
|
|
182
|
+
api_key=api_key,
|
|
183
|
+
container_tag="user-123",
|
|
184
|
+
)
|
|
182
185
|
|
|
183
186
|
middleware = SupermemoryChatMiddleware(
|
|
184
|
-
|
|
187
|
+
connection,
|
|
185
188
|
options=SupermemoryMiddlewareOptions(mode="full"),
|
|
186
|
-
api_key=api_key,
|
|
187
189
|
)
|
|
188
190
|
|
|
189
|
-
tools = SupermemoryTools(
|
|
191
|
+
tools = SupermemoryTools(connection)
|
|
190
192
|
|
|
191
193
|
agent = OpenAIResponsesClient().as_agent(
|
|
192
194
|
name="MemoryAgent",
|
|
@@ -243,11 +245,20 @@ SupermemoryMiddlewareOptions(add_memory="never")
|
|
|
243
245
|
### Complete Configuration
|
|
244
246
|
|
|
245
247
|
```python
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
248
|
+
connection = AgentSupermemory(
|
|
249
|
+
api_key="your-supermemory-api-key",
|
|
250
|
+
container_tag="user-123", # Memory scope
|
|
251
|
+
conversation_id="chat-session-456", # Groups stored conversations
|
|
252
|
+
entity_context="User is on the pro plan", # Optional fixed context
|
|
253
|
+
)
|
|
254
|
+
|
|
255
|
+
middleware = SupermemoryChatMiddleware(
|
|
256
|
+
connection,
|
|
257
|
+
options=SupermemoryMiddlewareOptions(
|
|
258
|
+
verbose=True,
|
|
259
|
+
mode="full",
|
|
260
|
+
add_memory="always",
|
|
261
|
+
),
|
|
251
262
|
)
|
|
252
263
|
```
|
|
253
264
|
|
|
@@ -258,13 +269,11 @@ SupermemoryMiddlewareOptions(
|
|
|
258
269
|
Memory tools that integrate with Agent Framework's tool system.
|
|
259
270
|
|
|
260
271
|
```python
|
|
261
|
-
|
|
272
|
+
connection = AgentSupermemory(
|
|
262
273
|
api_key="your-api-key",
|
|
263
|
-
|
|
264
|
-
"project_id": "my-project", # or use container_tags
|
|
265
|
-
"base_url": "https://custom.com", # optional
|
|
266
|
-
}
|
|
274
|
+
container_tag="user-123",
|
|
267
275
|
)
|
|
276
|
+
tools = SupermemoryTools(connection)
|
|
268
277
|
|
|
269
278
|
# Get FunctionTool instances for Agent.run()
|
|
270
279
|
agent_tools = tools.get_tools()
|
|
@@ -275,26 +284,19 @@ result = await tools.add_memory("User prefers dark mode")
|
|
|
275
284
|
result = await tools.get_profile()
|
|
276
285
|
```
|
|
277
286
|
|
|
287
|
+
`search_memories` uses v4 hybrid search, so results can contain either a
|
|
288
|
+
structured memory or a source chunk. The old Python-only `include_full_docs`
|
|
289
|
+
argument is deprecated and ignored because v4 search does not return full
|
|
290
|
+
source documents; it is not exposed to the model as a tool parameter.
|
|
291
|
+
|
|
278
292
|
### SupermemoryChatMiddleware
|
|
279
293
|
|
|
280
294
|
Chat middleware for automatic memory injection.
|
|
281
295
|
|
|
282
296
|
```python
|
|
283
297
|
middleware = SupermemoryChatMiddleware(
|
|
284
|
-
|
|
298
|
+
connection, # Shared AgentSupermemory connection
|
|
285
299
|
options=SupermemoryMiddlewareOptions(...),
|
|
286
|
-
api_key="your-api-key", # Or set SUPERMEMORY_API_KEY env var
|
|
287
|
-
)
|
|
288
|
-
```
|
|
289
|
-
|
|
290
|
-
### with_supermemory_middleware()
|
|
291
|
-
|
|
292
|
-
Convenience function for creating middleware:
|
|
293
|
-
|
|
294
|
-
```python
|
|
295
|
-
middleware = with_supermemory_middleware(
|
|
296
|
-
"user-123",
|
|
297
|
-
SupermemoryMiddlewareOptions(mode="full"),
|
|
298
300
|
)
|
|
299
301
|
```
|
|
300
302
|
|
|
@@ -304,11 +306,9 @@ Context provider for the Agent Framework session pipeline (like Mem0):
|
|
|
304
306
|
|
|
305
307
|
```python
|
|
306
308
|
provider = SupermemoryContextProvider(
|
|
307
|
-
|
|
308
|
-
api_key="your-api-key", # Or set SUPERMEMORY_API_KEY env var
|
|
309
|
+
connection, # Shared AgentSupermemory connection
|
|
309
310
|
mode="full", # "profile", "query", or "full"
|
|
310
311
|
store_conversations=True, # Save conversations after each run
|
|
311
|
-
conversation_id="chat-456", # Optional grouping ID
|
|
312
312
|
context_prompt="## Memories\n...", # Custom header for injected memories
|
|
313
313
|
verbose=True, # Enable logging
|
|
314
314
|
)
|
|
@@ -318,6 +318,7 @@ provider = SupermemoryContextProvider(
|
|
|
318
318
|
|
|
319
319
|
```python
|
|
320
320
|
from supermemory_agent_framework import (
|
|
321
|
+
AgentSupermemory,
|
|
321
322
|
SupermemoryConfigurationError,
|
|
322
323
|
SupermemoryAPIError,
|
|
323
324
|
SupermemoryNetworkError,
|
|
@@ -325,7 +326,7 @@ from supermemory_agent_framework import (
|
|
|
325
326
|
)
|
|
326
327
|
|
|
327
328
|
try:
|
|
328
|
-
|
|
329
|
+
connection = AgentSupermemory(container_tag="user-123")
|
|
329
330
|
except SupermemoryConfigurationError as e:
|
|
330
331
|
print(f"Configuration issue: {e}")
|
|
331
332
|
```
|
|
@@ -348,11 +349,8 @@ except SupermemoryConfigurationError as e:
|
|
|
348
349
|
|
|
349
350
|
### Required
|
|
350
351
|
- `agent-framework-core>=1.0.0rc3` - Microsoft Agent Framework
|
|
351
|
-
- `supermemory>=3.
|
|
352
|
-
- `
|
|
353
|
-
|
|
354
|
-
### Optional
|
|
355
|
-
- `aiohttp>=3.8.0` - Async HTTP requests (recommended)
|
|
352
|
+
- `supermemory>=3.16.0` - Supermemory client with v4 hybrid search support
|
|
353
|
+
- `typing-extensions>=4.0.0` - Typing compatibility helpers
|
|
356
354
|
|
|
357
355
|
## Development
|
|
358
356
|
|
|
@@ -9,23 +9,13 @@ This package provides both **automatic memory injection middleware** and **manua
|
|
|
9
9
|
Install using uv (recommended):
|
|
10
10
|
|
|
11
11
|
```bash
|
|
12
|
-
uv add
|
|
12
|
+
uv add supermemory-agent-framework
|
|
13
13
|
```
|
|
14
14
|
|
|
15
15
|
Or with pip:
|
|
16
16
|
|
|
17
17
|
```bash
|
|
18
|
-
pip install
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
> **Note:** The `--prerelease=allow` / `--pre` flag is required because `agent-framework-core` depends on pre-release versions of Azure packages.
|
|
22
|
-
|
|
23
|
-
For async HTTP support (recommended):
|
|
24
|
-
|
|
25
|
-
```bash
|
|
26
|
-
uv add supermemory-agent-framework[async]
|
|
27
|
-
# or
|
|
28
|
-
pip install supermemory-agent-framework[async]
|
|
18
|
+
pip install supermemory-agent-framework
|
|
29
19
|
```
|
|
30
20
|
|
|
31
21
|
## Quick Start
|
|
@@ -38,14 +28,19 @@ The easiest way to add memory capabilities is using the `SupermemoryChatMiddlewa
|
|
|
38
28
|
import asyncio
|
|
39
29
|
from agent_framework.openai import OpenAIResponsesClient
|
|
40
30
|
from supermemory_agent_framework import (
|
|
31
|
+
AgentSupermemory,
|
|
41
32
|
SupermemoryChatMiddleware,
|
|
42
33
|
SupermemoryMiddlewareOptions,
|
|
43
34
|
)
|
|
44
35
|
|
|
45
36
|
async def main():
|
|
46
|
-
|
|
47
|
-
|
|
37
|
+
connection = AgentSupermemory(
|
|
38
|
+
api_key="your-supermemory-api-key",
|
|
48
39
|
container_tag="user-123",
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
middleware = SupermemoryChatMiddleware(
|
|
43
|
+
connection,
|
|
49
44
|
options=SupermemoryMiddlewareOptions(
|
|
50
45
|
mode="full", # "profile", "query", or "full"
|
|
51
46
|
verbose=True, # Enable logging
|
|
@@ -77,13 +72,16 @@ The most idiomatic way to add memory in Agent Framework, using the same pattern
|
|
|
77
72
|
import asyncio
|
|
78
73
|
from agent_framework import AgentSession
|
|
79
74
|
from agent_framework.openai import OpenAIResponsesClient
|
|
80
|
-
from supermemory_agent_framework import SupermemoryContextProvider
|
|
75
|
+
from supermemory_agent_framework import AgentSupermemory, SupermemoryContextProvider
|
|
81
76
|
|
|
82
77
|
async def main():
|
|
83
|
-
|
|
84
|
-
provider = SupermemoryContextProvider(
|
|
85
|
-
container_tag="user-123",
|
|
78
|
+
connection = AgentSupermemory(
|
|
86
79
|
api_key="your-supermemory-api-key",
|
|
80
|
+
container_tag="user-123",
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
provider = SupermemoryContextProvider(
|
|
84
|
+
connection,
|
|
87
85
|
mode="full",
|
|
88
86
|
store_conversations=True,
|
|
89
87
|
)
|
|
@@ -113,14 +111,14 @@ For explicit tool-based memory access:
|
|
|
113
111
|
```python
|
|
114
112
|
import asyncio
|
|
115
113
|
from agent_framework.openai import OpenAIResponsesClient
|
|
116
|
-
from supermemory_agent_framework import SupermemoryTools
|
|
114
|
+
from supermemory_agent_framework import AgentSupermemory, SupermemoryTools
|
|
117
115
|
|
|
118
116
|
async def main():
|
|
119
|
-
|
|
120
|
-
tools = SupermemoryTools(
|
|
117
|
+
connection = AgentSupermemory(
|
|
121
118
|
api_key="your-supermemory-api-key",
|
|
122
|
-
|
|
119
|
+
container_tag="user-123",
|
|
123
120
|
)
|
|
121
|
+
tools = SupermemoryTools(connection)
|
|
124
122
|
|
|
125
123
|
# Create agent
|
|
126
124
|
agent = OpenAIResponsesClient().as_agent(
|
|
@@ -146,6 +144,7 @@ For maximum flexibility, use both middleware (automatic context injection) and t
|
|
|
146
144
|
import asyncio
|
|
147
145
|
from agent_framework.openai import OpenAIResponsesClient
|
|
148
146
|
from supermemory_agent_framework import (
|
|
147
|
+
AgentSupermemory,
|
|
149
148
|
SupermemoryChatMiddleware,
|
|
150
149
|
SupermemoryMiddlewareOptions,
|
|
151
150
|
SupermemoryTools,
|
|
@@ -153,14 +152,17 @@ from supermemory_agent_framework import (
|
|
|
153
152
|
|
|
154
153
|
async def main():
|
|
155
154
|
api_key = "your-supermemory-api-key"
|
|
155
|
+
connection = AgentSupermemory(
|
|
156
|
+
api_key=api_key,
|
|
157
|
+
container_tag="user-123",
|
|
158
|
+
)
|
|
156
159
|
|
|
157
160
|
middleware = SupermemoryChatMiddleware(
|
|
158
|
-
|
|
161
|
+
connection,
|
|
159
162
|
options=SupermemoryMiddlewareOptions(mode="full"),
|
|
160
|
-
api_key=api_key,
|
|
161
163
|
)
|
|
162
164
|
|
|
163
|
-
tools = SupermemoryTools(
|
|
165
|
+
tools = SupermemoryTools(connection)
|
|
164
166
|
|
|
165
167
|
agent = OpenAIResponsesClient().as_agent(
|
|
166
168
|
name="MemoryAgent",
|
|
@@ -217,11 +219,20 @@ SupermemoryMiddlewareOptions(add_memory="never")
|
|
|
217
219
|
### Complete Configuration
|
|
218
220
|
|
|
219
221
|
```python
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
222
|
+
connection = AgentSupermemory(
|
|
223
|
+
api_key="your-supermemory-api-key",
|
|
224
|
+
container_tag="user-123", # Memory scope
|
|
225
|
+
conversation_id="chat-session-456", # Groups stored conversations
|
|
226
|
+
entity_context="User is on the pro plan", # Optional fixed context
|
|
227
|
+
)
|
|
228
|
+
|
|
229
|
+
middleware = SupermemoryChatMiddleware(
|
|
230
|
+
connection,
|
|
231
|
+
options=SupermemoryMiddlewareOptions(
|
|
232
|
+
verbose=True,
|
|
233
|
+
mode="full",
|
|
234
|
+
add_memory="always",
|
|
235
|
+
),
|
|
225
236
|
)
|
|
226
237
|
```
|
|
227
238
|
|
|
@@ -232,13 +243,11 @@ SupermemoryMiddlewareOptions(
|
|
|
232
243
|
Memory tools that integrate with Agent Framework's tool system.
|
|
233
244
|
|
|
234
245
|
```python
|
|
235
|
-
|
|
246
|
+
connection = AgentSupermemory(
|
|
236
247
|
api_key="your-api-key",
|
|
237
|
-
|
|
238
|
-
"project_id": "my-project", # or use container_tags
|
|
239
|
-
"base_url": "https://custom.com", # optional
|
|
240
|
-
}
|
|
248
|
+
container_tag="user-123",
|
|
241
249
|
)
|
|
250
|
+
tools = SupermemoryTools(connection)
|
|
242
251
|
|
|
243
252
|
# Get FunctionTool instances for Agent.run()
|
|
244
253
|
agent_tools = tools.get_tools()
|
|
@@ -249,26 +258,19 @@ result = await tools.add_memory("User prefers dark mode")
|
|
|
249
258
|
result = await tools.get_profile()
|
|
250
259
|
```
|
|
251
260
|
|
|
261
|
+
`search_memories` uses v4 hybrid search, so results can contain either a
|
|
262
|
+
structured memory or a source chunk. The old Python-only `include_full_docs`
|
|
263
|
+
argument is deprecated and ignored because v4 search does not return full
|
|
264
|
+
source documents; it is not exposed to the model as a tool parameter.
|
|
265
|
+
|
|
252
266
|
### SupermemoryChatMiddleware
|
|
253
267
|
|
|
254
268
|
Chat middleware for automatic memory injection.
|
|
255
269
|
|
|
256
270
|
```python
|
|
257
271
|
middleware = SupermemoryChatMiddleware(
|
|
258
|
-
|
|
272
|
+
connection, # Shared AgentSupermemory connection
|
|
259
273
|
options=SupermemoryMiddlewareOptions(...),
|
|
260
|
-
api_key="your-api-key", # Or set SUPERMEMORY_API_KEY env var
|
|
261
|
-
)
|
|
262
|
-
```
|
|
263
|
-
|
|
264
|
-
### with_supermemory_middleware()
|
|
265
|
-
|
|
266
|
-
Convenience function for creating middleware:
|
|
267
|
-
|
|
268
|
-
```python
|
|
269
|
-
middleware = with_supermemory_middleware(
|
|
270
|
-
"user-123",
|
|
271
|
-
SupermemoryMiddlewareOptions(mode="full"),
|
|
272
274
|
)
|
|
273
275
|
```
|
|
274
276
|
|
|
@@ -278,11 +280,9 @@ Context provider for the Agent Framework session pipeline (like Mem0):
|
|
|
278
280
|
|
|
279
281
|
```python
|
|
280
282
|
provider = SupermemoryContextProvider(
|
|
281
|
-
|
|
282
|
-
api_key="your-api-key", # Or set SUPERMEMORY_API_KEY env var
|
|
283
|
+
connection, # Shared AgentSupermemory connection
|
|
283
284
|
mode="full", # "profile", "query", or "full"
|
|
284
285
|
store_conversations=True, # Save conversations after each run
|
|
285
|
-
conversation_id="chat-456", # Optional grouping ID
|
|
286
286
|
context_prompt="## Memories\n...", # Custom header for injected memories
|
|
287
287
|
verbose=True, # Enable logging
|
|
288
288
|
)
|
|
@@ -292,6 +292,7 @@ provider = SupermemoryContextProvider(
|
|
|
292
292
|
|
|
293
293
|
```python
|
|
294
294
|
from supermemory_agent_framework import (
|
|
295
|
+
AgentSupermemory,
|
|
295
296
|
SupermemoryConfigurationError,
|
|
296
297
|
SupermemoryAPIError,
|
|
297
298
|
SupermemoryNetworkError,
|
|
@@ -299,7 +300,7 @@ from supermemory_agent_framework import (
|
|
|
299
300
|
)
|
|
300
301
|
|
|
301
302
|
try:
|
|
302
|
-
|
|
303
|
+
connection = AgentSupermemory(container_tag="user-123")
|
|
303
304
|
except SupermemoryConfigurationError as e:
|
|
304
305
|
print(f"Configuration issue: {e}")
|
|
305
306
|
```
|
|
@@ -322,11 +323,8 @@ except SupermemoryConfigurationError as e:
|
|
|
322
323
|
|
|
323
324
|
### Required
|
|
324
325
|
- `agent-framework-core>=1.0.0rc3` - Microsoft Agent Framework
|
|
325
|
-
- `supermemory>=3.
|
|
326
|
-
- `
|
|
327
|
-
|
|
328
|
-
### Optional
|
|
329
|
-
- `aiohttp>=3.8.0` - Async HTTP requests (recommended)
|
|
326
|
+
- `supermemory>=3.16.0` - Supermemory client with v4 hybrid search support
|
|
327
|
+
- `typing-extensions>=4.0.0` - Typing compatibility helpers
|
|
330
328
|
|
|
331
329
|
## Development
|
|
332
330
|
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "supermemory-agent-framework"
|
|
7
|
-
version = "1.0.
|
|
7
|
+
version = "1.0.1"
|
|
8
8
|
description = "Memory tools and middleware for Microsoft Agent Framework with supermemory"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "MIT"
|
|
@@ -25,7 +25,7 @@ classifiers = [
|
|
|
25
25
|
requires-python = ">=3.10"
|
|
26
26
|
dependencies = [
|
|
27
27
|
"agent-framework-core>=1.0.0rc3",
|
|
28
|
-
"supermemory>=3.
|
|
28
|
+
"supermemory>=3.16.0",
|
|
29
29
|
"typing-extensions>=4.0.0",
|
|
30
30
|
]
|
|
31
31
|
|
|
@@ -7,9 +7,15 @@ This is the idiomatic way to integrate persistent memory in Agent Framework,
|
|
|
7
7
|
following the same pattern as the built-in Mem0 integration.
|
|
8
8
|
"""
|
|
9
9
|
|
|
10
|
-
from typing import Any, Literal
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
from typing import Any, Literal
|
|
11
|
+
|
|
12
|
+
try:
|
|
13
|
+
from agent_framework import BaseContextProvider # type: ignore[attr-defined]
|
|
14
|
+
except ImportError:
|
|
15
|
+
# Renamed in agent-framework-core 1.0.0 stable; the interface is
|
|
16
|
+
# unchanged (source_id __init__, before_run/after_run hooks with
|
|
17
|
+
# identical keyword-only signatures).
|
|
18
|
+
from agent_framework import ContextProvider as BaseContextProvider
|
|
13
19
|
|
|
14
20
|
from .connection import AgentSupermemory
|
|
15
21
|
from .utils import (
|
|
@@ -4,7 +4,8 @@ Provides FunctionTool-compatible tools that can be passed to Agent.run(tools=[..
|
|
|
4
4
|
"""
|
|
5
5
|
|
|
6
6
|
import json
|
|
7
|
-
|
|
7
|
+
import warnings
|
|
8
|
+
from typing import Annotated, Any, Optional, TypedDict
|
|
8
9
|
|
|
9
10
|
from agent_framework import FunctionTool, tool
|
|
10
11
|
|
|
@@ -37,6 +38,25 @@ class ProfileResult(TypedDict, total=False):
|
|
|
37
38
|
error: str | None
|
|
38
39
|
|
|
39
40
|
|
|
41
|
+
def _to_jsonable(value: Any) -> Any:
|
|
42
|
+
"""Convert generated SDK models into JSON-compatible structures."""
|
|
43
|
+
if isinstance(value, dict):
|
|
44
|
+
return {key: _to_jsonable(item) for key, item in value.items()}
|
|
45
|
+
if isinstance(value, (list, tuple)):
|
|
46
|
+
return [_to_jsonable(item) for item in value]
|
|
47
|
+
|
|
48
|
+
model_dump = getattr(value, "model_dump", None)
|
|
49
|
+
if callable(model_dump):
|
|
50
|
+
try:
|
|
51
|
+
return _to_jsonable(model_dump(mode="json"))
|
|
52
|
+
except TypeError:
|
|
53
|
+
# Compatibility with pydantic-like models whose model_dump does not
|
|
54
|
+
# accept Pydantic v2's ``mode`` argument.
|
|
55
|
+
return _to_jsonable(model_dump())
|
|
56
|
+
|
|
57
|
+
return value
|
|
58
|
+
|
|
59
|
+
|
|
40
60
|
class SupermemoryTools:
|
|
41
61
|
"""Memory tools for Microsoft Agent Framework.
|
|
42
62
|
|
|
@@ -64,27 +84,37 @@ class SupermemoryTools:
|
|
|
64
84
|
async def search_memories(
|
|
65
85
|
self,
|
|
66
86
|
information_to_get: Annotated[
|
|
67
|
-
str, "Terms to search for in
|
|
87
|
+
str, "Terms to search for in stored memories and source content"
|
|
68
88
|
],
|
|
69
|
-
include_full_docs:
|
|
70
|
-
bool,
|
|
71
|
-
"Whether to include full document content. Defaults to true for better AI context.",
|
|
72
|
-
] = True,
|
|
89
|
+
include_full_docs: Optional[bool] = None,
|
|
73
90
|
limit: Annotated[int, "Maximum number of results to return"] = 10,
|
|
74
91
|
) -> str:
|
|
75
|
-
"""Search
|
|
92
|
+
"""Search stored memories and source chunks.
|
|
93
|
+
|
|
94
|
+
``include_full_docs`` remains a deprecated Python-only argument for
|
|
95
|
+
source compatibility. V4 search cannot return full source documents.
|
|
96
|
+
"""
|
|
97
|
+
if include_full_docs is not None:
|
|
98
|
+
warnings.warn(
|
|
99
|
+
"include_full_docs is deprecated and ignored because v4 search "
|
|
100
|
+
"does not return full source documents",
|
|
101
|
+
DeprecationWarning,
|
|
102
|
+
stacklevel=2,
|
|
103
|
+
)
|
|
104
|
+
|
|
76
105
|
try:
|
|
77
|
-
response = await self._client.search.
|
|
106
|
+
response = await self._client.search.memories(
|
|
78
107
|
q=information_to_get,
|
|
79
|
-
|
|
108
|
+
container_tag=self._connection.container_tag,
|
|
80
109
|
limit=limit,
|
|
81
|
-
|
|
82
|
-
|
|
110
|
+
threshold=0.6,
|
|
111
|
+
search_mode="hybrid",
|
|
83
112
|
)
|
|
113
|
+
results = response.results or []
|
|
84
114
|
result: MemorySearchResult = {
|
|
85
115
|
"success": True,
|
|
86
|
-
"results":
|
|
87
|
-
"count": len(
|
|
116
|
+
"results": [_to_jsonable(item) for item in results],
|
|
117
|
+
"count": len(results),
|
|
88
118
|
}
|
|
89
119
|
return json.dumps(result, default=str)
|
|
90
120
|
except Exception as error:
|
|
@@ -107,7 +137,7 @@ class SupermemoryTools:
|
|
|
107
137
|
)
|
|
108
138
|
result: MemoryAddResult = {
|
|
109
139
|
"success": True,
|
|
110
|
-
"memory": response,
|
|
140
|
+
"memory": _to_jsonable(response),
|
|
111
141
|
}
|
|
112
142
|
return json.dumps(result, default=str)
|
|
113
143
|
except Exception as error:
|
|
@@ -130,9 +160,13 @@ class SupermemoryTools:
|
|
|
130
160
|
response = await self._client.profile(**kwargs)
|
|
131
161
|
result: dict[str, Any] = {
|
|
132
162
|
"success": True,
|
|
133
|
-
"profile":
|
|
163
|
+
"profile": (
|
|
164
|
+
_to_jsonable(response.profile)
|
|
165
|
+
if hasattr(response, "profile")
|
|
166
|
+
else None
|
|
167
|
+
),
|
|
134
168
|
"search_results": (
|
|
135
|
-
response.search_results
|
|
169
|
+
_to_jsonable(response.search_results)
|
|
136
170
|
if hasattr(response, "search_results")
|
|
137
171
|
else None
|
|
138
172
|
),
|
|
@@ -152,11 +186,11 @@ class SupermemoryTools:
|
|
|
152
186
|
tool(
|
|
153
187
|
name="search_memories",
|
|
154
188
|
description=(
|
|
155
|
-
"Search
|
|
156
|
-
"
|
|
157
|
-
"
|
|
189
|
+
"Search stored memories and source chunks for relevant facts, preferences, "
|
|
190
|
+
"history, and context. Use proactively whenever prior context could help; "
|
|
191
|
+
"hybrid results can contain either a memory or a source chunk."
|
|
158
192
|
),
|
|
159
|
-
)(self.
|
|
193
|
+
)(self._search_memories_tool),
|
|
160
194
|
tool(
|
|
161
195
|
name="add_memory",
|
|
162
196
|
description=(
|
|
@@ -174,3 +208,16 @@ class SupermemoryTools:
|
|
|
174
208
|
),
|
|
175
209
|
)(self.get_profile),
|
|
176
210
|
]
|
|
211
|
+
|
|
212
|
+
async def _search_memories_tool(
|
|
213
|
+
self,
|
|
214
|
+
information_to_get: Annotated[
|
|
215
|
+
str, "Terms to search for in stored memories and source content"
|
|
216
|
+
],
|
|
217
|
+
limit: Annotated[int, "Maximum number of results to return"] = 10,
|
|
218
|
+
) -> str:
|
|
219
|
+
"""Model-facing search wrapper that omits deprecated arguments."""
|
|
220
|
+
return await self.search_memories(
|
|
221
|
+
information_to_get=information_to_get,
|
|
222
|
+
limit=limit,
|
|
223
|
+
)
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"""Utility functions for Supermemory Agent Framework integration."""
|
|
2
2
|
|
|
3
3
|
import json
|
|
4
|
+
import re
|
|
4
5
|
from typing import Any, Optional, Protocol
|
|
5
6
|
|
|
6
7
|
DEFAULT_CONTEXT_PROMPT = "The following are retrieved memories about the user."
|
|
@@ -92,17 +93,31 @@ def deduplicate_memories(
|
|
|
92
93
|
def extract_memory_text(item: Any) -> Optional[str]:
|
|
93
94
|
if item is None:
|
|
94
95
|
return None
|
|
95
|
-
if isinstance(item, dict):
|
|
96
|
-
memory = item.get("memory")
|
|
97
|
-
if isinstance(memory, str):
|
|
98
|
-
trimmed = memory.strip()
|
|
99
|
-
return trimmed if trimmed else None
|
|
100
|
-
return None
|
|
101
96
|
if isinstance(item, str):
|
|
102
97
|
trimmed = item.strip()
|
|
103
98
|
return trimmed if trimmed else None
|
|
99
|
+
if isinstance(item, dict):
|
|
100
|
+
for field in ("memory", "chunk", "content"):
|
|
101
|
+
value = item.get(field)
|
|
102
|
+
if isinstance(value, str) and value.strip():
|
|
103
|
+
return value.strip()
|
|
104
|
+
return None
|
|
105
|
+
# Stainless SDK returns pydantic models (attribute access, snake_case).
|
|
106
|
+
for field in ("memory", "chunk", "content"):
|
|
107
|
+
value = getattr(item, field, None)
|
|
108
|
+
if isinstance(value, str) and value.strip():
|
|
109
|
+
return value.strip()
|
|
104
110
|
return None
|
|
105
111
|
|
|
112
|
+
def comparison_key(memory: str) -> str:
|
|
113
|
+
"""Remove Mono's dynamic-profile date decoration for comparison only."""
|
|
114
|
+
return re.sub(
|
|
115
|
+
r"^(?:\[Recent\]\s*)?\[\d{4}-\d{2}-\d{2}\]\s*",
|
|
116
|
+
"",
|
|
117
|
+
memory,
|
|
118
|
+
count=1,
|
|
119
|
+
).strip()
|
|
120
|
+
|
|
106
121
|
static_memories: list[str] = []
|
|
107
122
|
seen_memories: set[str] = set()
|
|
108
123
|
|
|
@@ -110,21 +125,21 @@ def deduplicate_memories(
|
|
|
110
125
|
memory = extract_memory_text(item)
|
|
111
126
|
if memory is not None:
|
|
112
127
|
static_memories.append(memory)
|
|
113
|
-
seen_memories.add(memory)
|
|
128
|
+
seen_memories.add(comparison_key(memory))
|
|
114
129
|
|
|
115
130
|
dynamic_memories: list[str] = []
|
|
116
131
|
for item in dynamic_items:
|
|
117
132
|
memory = extract_memory_text(item)
|
|
118
|
-
if memory is not None and memory not in seen_memories:
|
|
133
|
+
if memory is not None and comparison_key(memory) not in seen_memories:
|
|
119
134
|
dynamic_memories.append(memory)
|
|
120
|
-
seen_memories.add(memory)
|
|
135
|
+
seen_memories.add(comparison_key(memory))
|
|
121
136
|
|
|
122
137
|
search_memories: list[str] = []
|
|
123
138
|
for item in search_items:
|
|
124
139
|
memory = extract_memory_text(item)
|
|
125
|
-
if memory is not None and memory not in seen_memories:
|
|
140
|
+
if memory is not None and comparison_key(memory) not in seen_memories:
|
|
126
141
|
search_memories.append(memory)
|
|
127
|
-
seen_memories.add(memory)
|
|
142
|
+
seen_memories.add(comparison_key(memory))
|
|
128
143
|
|
|
129
144
|
return DeduplicatedMemories(
|
|
130
145
|
static=static_memories,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|