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.
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.4
1
+ Metadata-Version: 2.5
2
2
  Name: supermemory-agent-framework
3
- Version: 1.0.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.1.0
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 --prerelease=allow supermemory-agent-framework
38
+ uv add supermemory-agent-framework
39
39
  ```
40
40
 
41
41
  Or with pip:
42
42
 
43
43
  ```bash
44
- pip install --pre supermemory-agent-framework
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
- # Create Supermemory middleware
73
- middleware = SupermemoryChatMiddleware(
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
- # Create context provider
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
- # Create memory tools
146
- tools = SupermemoryTools(
143
+ connection = AgentSupermemory(
147
144
  api_key="your-supermemory-api-key",
148
- config={"project_id": "my-project"},
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
- container_tag="user-123",
187
+ connection,
185
188
  options=SupermemoryMiddlewareOptions(mode="full"),
186
- api_key=api_key,
187
189
  )
188
190
 
189
- tools = SupermemoryTools(api_key=api_key)
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
- SupermemoryMiddlewareOptions(
247
- conversation_id="chat-session-456", # Group messages into conversations
248
- verbose=True, # Enable detailed logging
249
- mode="full", # Use both profile and query
250
- add_memory="always" # Auto-save conversations
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
- tools = SupermemoryTools(
272
+ connection = AgentSupermemory(
262
273
  api_key="your-api-key",
263
- config={
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
- container_tag="user-123", # Memory scope identifier
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
- container_tag="user-123",
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
- middleware = SupermemoryChatMiddleware("user-123")
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.1.0` - Supermemory client
352
- - `requests>=2.25.0` - HTTP requests (fallback)
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 --prerelease=allow supermemory-agent-framework
12
+ uv add supermemory-agent-framework
13
13
  ```
14
14
 
15
15
  Or with pip:
16
16
 
17
17
  ```bash
18
- pip install --pre supermemory-agent-framework
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
- # Create Supermemory middleware
47
- middleware = SupermemoryChatMiddleware(
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
- # Create context provider
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
- # Create memory tools
120
- tools = SupermemoryTools(
117
+ connection = AgentSupermemory(
121
118
  api_key="your-supermemory-api-key",
122
- config={"project_id": "my-project"},
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
- container_tag="user-123",
161
+ connection,
159
162
  options=SupermemoryMiddlewareOptions(mode="full"),
160
- api_key=api_key,
161
163
  )
162
164
 
163
- tools = SupermemoryTools(api_key=api_key)
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
- SupermemoryMiddlewareOptions(
221
- conversation_id="chat-session-456", # Group messages into conversations
222
- verbose=True, # Enable detailed logging
223
- mode="full", # Use both profile and query
224
- add_memory="always" # Auto-save conversations
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
- tools = SupermemoryTools(
246
+ connection = AgentSupermemory(
236
247
  api_key="your-api-key",
237
- config={
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
- container_tag="user-123", # Memory scope identifier
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
- container_tag="user-123",
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
- middleware = SupermemoryChatMiddleware("user-123")
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.1.0` - Supermemory client
326
- - `requests>=2.25.0` - HTTP requests (fallback)
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.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.1.0",
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, Optional
11
-
12
- from agent_framework import BaseContextProvider
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
- from typing import Annotated, Any, TypedDict
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 the user's memories"
87
+ str, "Terms to search for in stored memories and source content"
68
88
  ],
69
- include_full_docs: Annotated[
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 (recall) memories/details/information about the user or other facts or entities. Run when explicitly asked or when context about user's past choices would be helpful."""
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.execute(
106
+ response = await self._client.search.memories(
78
107
  q=information_to_get,
79
- container_tags=[self._connection.container_tag],
108
+ container_tag=self._connection.container_tag,
80
109
  limit=limit,
81
- chunk_threshold=0.6,
82
- include_full_docs=include_full_docs,
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": response.results,
87
- "count": len(response.results) if response.results else 0,
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": response.profile if hasattr(response, "profile") else None,
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 (recall) memories/details/information about the user or other "
156
- "facts or entities. Run when explicitly asked or when context about "
157
- "user's past choices would be helpful."
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.search_memories),
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,