agenticmem 0.1.2.4__py3-none-any.whl → 0.1.3.8__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of agenticmem might be problematic. Click here for more details.
- agenticmem/__init__.py +5 -1
- agenticmem/client.py +247 -75
- agenticmem-0.1.3.8.dist-info/METADATA +72 -0
- agenticmem-0.1.3.8.dist-info/RECORD +6 -0
- agenticmem-0.1.2.4.dist-info/METADATA +0 -145
- agenticmem-0.1.2.4.dist-info/RECORD +0 -6
- {agenticmem-0.1.2.4.dist-info → agenticmem-0.1.3.8.dist-info}/WHEEL +0 -0
agenticmem/__init__.py
CHANGED
|
@@ -2,7 +2,7 @@ __app_name__ = "agenticmem"
|
|
|
2
2
|
__version__ = "0.1.1"
|
|
3
3
|
|
|
4
4
|
|
|
5
|
-
from
|
|
5
|
+
from .client import AgenticMemClient
|
|
6
6
|
from agenticmem_commons.api_schema.service_schemas import (
|
|
7
7
|
UserActionType,
|
|
8
8
|
ProfileTimeToLive,
|
|
@@ -31,6 +31,8 @@ from agenticmem_commons.config_schema import (
|
|
|
31
31
|
ProfileExtractorConfig,
|
|
32
32
|
FeedbackAggregatorConfig,
|
|
33
33
|
AgentFeedbackConfig,
|
|
34
|
+
AgentSuccessConfig,
|
|
35
|
+
ToolUseConfig,
|
|
34
36
|
Config,
|
|
35
37
|
)
|
|
36
38
|
|
|
@@ -63,5 +65,7 @@ __all__ = [
|
|
|
63
65
|
"ProfileExtractorConfig",
|
|
64
66
|
"FeedbackAggregatorConfig",
|
|
65
67
|
"AgentFeedbackConfig",
|
|
68
|
+
"AgentSuccessConfig",
|
|
69
|
+
"ToolUseConfig",
|
|
66
70
|
"Config",
|
|
67
71
|
]
|
agenticmem/client.py
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
import os
|
|
2
2
|
import aiohttp
|
|
3
|
+
import asyncio
|
|
3
4
|
from urllib.parse import urljoin
|
|
4
5
|
import requests
|
|
6
|
+
from concurrent.futures import ThreadPoolExecutor
|
|
5
7
|
from typing import Optional, Union
|
|
6
8
|
from agenticmem_commons.api_schema.retriever_schema import (
|
|
7
9
|
SearchInteractionRequest,
|
|
@@ -18,6 +20,13 @@ from agenticmem_commons.api_schema.retriever_schema import (
|
|
|
18
20
|
GetFeedbacksResponse,
|
|
19
21
|
)
|
|
20
22
|
|
|
23
|
+
from dotenv import load_dotenv
|
|
24
|
+
|
|
25
|
+
# Load environment variables from .env file
|
|
26
|
+
load_dotenv()
|
|
27
|
+
|
|
28
|
+
IS_TEST_ENV = os.environ.get("IS_TEST_ENV", "false").strip() == "true"
|
|
29
|
+
|
|
21
30
|
if IS_TEST_ENV:
|
|
22
31
|
BACKEND_URL = "http://127.0.0.1:8000" # Local server for testing
|
|
23
32
|
else:
|
|
@@ -40,6 +49,9 @@ from agenticmem_commons.config_schema import Config
|
|
|
40
49
|
class AgenticMemClient:
|
|
41
50
|
"""Client for interacting with the AgenticMem API."""
|
|
42
51
|
|
|
52
|
+
# Shared thread pool for all instances to maximize efficiency
|
|
53
|
+
_thread_pool = ThreadPoolExecutor(max_workers=4, thread_name_prefix="agenticmem")
|
|
54
|
+
|
|
43
55
|
def __init__(self, api_key: str = "", url_endpoint: str = ""):
|
|
44
56
|
"""Initialize the AgenticMem client.
|
|
45
57
|
|
|
@@ -50,24 +62,83 @@ class AgenticMemClient:
|
|
|
50
62
|
self.base_url = url_endpoint if url_endpoint else BACKEND_URL
|
|
51
63
|
self.session = requests.Session()
|
|
52
64
|
|
|
65
|
+
def _get_auth_headers(self) -> dict:
|
|
66
|
+
"""Get authentication headers for API requests.
|
|
67
|
+
|
|
68
|
+
Returns:
|
|
69
|
+
dict: Headers with authorization and content-type
|
|
70
|
+
"""
|
|
71
|
+
if self.api_key:
|
|
72
|
+
return {
|
|
73
|
+
"Authorization": f"Bearer {self.api_key}",
|
|
74
|
+
"Content-Type": "application/json",
|
|
75
|
+
}
|
|
76
|
+
return {}
|
|
77
|
+
|
|
78
|
+
def _convert_to_model(self, data: Union[dict, object], model_class):
|
|
79
|
+
"""Convert dict to model instance if needed.
|
|
80
|
+
|
|
81
|
+
Args:
|
|
82
|
+
data: Either a dict or already an instance of model_class
|
|
83
|
+
model_class: The target class to convert to
|
|
84
|
+
|
|
85
|
+
Returns:
|
|
86
|
+
An instance of model_class
|
|
87
|
+
"""
|
|
88
|
+
if isinstance(data, dict):
|
|
89
|
+
return model_class(**data)
|
|
90
|
+
return data
|
|
91
|
+
|
|
92
|
+
def _fire_and_forget(self, sync_func, async_func, *args, **kwargs):
|
|
93
|
+
"""Execute a request in fire-and-forget mode.
|
|
94
|
+
|
|
95
|
+
This method optimizes execution based on context:
|
|
96
|
+
- In async contexts (e.g., FastAPI): Uses existing event loop (most efficient)
|
|
97
|
+
- In sync contexts: Uses shared thread pool (avoids thread creation overhead)
|
|
98
|
+
|
|
99
|
+
Args:
|
|
100
|
+
sync_func: Synchronous function to call
|
|
101
|
+
async_func: Asynchronous function to call
|
|
102
|
+
*args: Positional arguments to pass to the function
|
|
103
|
+
**kwargs: Keyword arguments to pass to the function
|
|
104
|
+
"""
|
|
105
|
+
try:
|
|
106
|
+
loop = asyncio.get_running_loop()
|
|
107
|
+
|
|
108
|
+
# We're in an async context - use the event loop
|
|
109
|
+
async def fire_and_forget():
|
|
110
|
+
try:
|
|
111
|
+
await async_func(*args, **kwargs)
|
|
112
|
+
except Exception:
|
|
113
|
+
# Silently ignore errors in fire-and-forget mode
|
|
114
|
+
pass
|
|
115
|
+
|
|
116
|
+
loop.create_task(fire_and_forget())
|
|
117
|
+
except RuntimeError:
|
|
118
|
+
# No running loop - we're in sync context, use thread pool
|
|
119
|
+
def send_request():
|
|
120
|
+
try:
|
|
121
|
+
sync_func(*args, **kwargs)
|
|
122
|
+
except Exception:
|
|
123
|
+
# Silently ignore errors in fire-and-forget mode
|
|
124
|
+
pass
|
|
125
|
+
|
|
126
|
+
self._thread_pool.submit(send_request)
|
|
127
|
+
|
|
53
128
|
async def _make_async_request(
|
|
54
129
|
self, method: str, endpoint: str, headers: Optional[dict] = None, **kwargs
|
|
55
130
|
):
|
|
56
131
|
"""Make an async HTTP request to the API."""
|
|
57
132
|
url = urljoin(self.base_url, endpoint)
|
|
58
133
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
"Authorization": f"Bearer {self.api_key}",
|
|
64
|
-
"Content-Type": "application/json",
|
|
65
|
-
}
|
|
66
|
-
)
|
|
134
|
+
# Merge auth headers with any provided headers
|
|
135
|
+
request_headers = self._get_auth_headers()
|
|
136
|
+
if headers:
|
|
137
|
+
request_headers.update(headers)
|
|
67
138
|
|
|
68
139
|
async with aiohttp.ClientSession() as async_session:
|
|
69
140
|
response = await async_session.request(
|
|
70
|
-
method, url, headers=
|
|
141
|
+
method, url, headers=request_headers, **kwargs
|
|
71
142
|
)
|
|
72
143
|
response.raise_for_status()
|
|
73
144
|
return await response.json()
|
|
@@ -87,22 +158,20 @@ class AgenticMemClient:
|
|
|
87
158
|
dict: API response
|
|
88
159
|
"""
|
|
89
160
|
url = urljoin(self.base_url, endpoint)
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
"Authorization": f"Bearer {self.api_key}",
|
|
94
|
-
"Content-Type": "application/json",
|
|
95
|
-
}
|
|
96
|
-
)
|
|
161
|
+
|
|
162
|
+
# Merge auth headers with any provided headers
|
|
163
|
+
request_headers = self._get_auth_headers()
|
|
97
164
|
if headers:
|
|
98
|
-
|
|
165
|
+
request_headers.update(headers)
|
|
166
|
+
|
|
167
|
+
self.session.headers.update(request_headers)
|
|
99
168
|
response = self.session.request(method, url, **kwargs)
|
|
100
169
|
response.raise_for_status()
|
|
101
170
|
return response.json()
|
|
102
171
|
|
|
103
|
-
|
|
104
|
-
"""
|
|
105
|
-
response =
|
|
172
|
+
def login(self, email: str, password: str) -> Token:
|
|
173
|
+
"""Login to the AgenticMem API."""
|
|
174
|
+
response = self._make_request(
|
|
106
175
|
"POST",
|
|
107
176
|
"/token",
|
|
108
177
|
data={"username": email, "password": password},
|
|
@@ -113,23 +182,52 @@ class AgenticMemClient:
|
|
|
113
182
|
)
|
|
114
183
|
return Token(**response)
|
|
115
184
|
|
|
116
|
-
|
|
185
|
+
def _publish_interaction_sync(
|
|
186
|
+
self, request: PublishUserInteractionRequest
|
|
187
|
+
) -> PublishUserInteractionResponse:
|
|
188
|
+
"""Internal sync method to publish interaction."""
|
|
189
|
+
response = self._make_request(
|
|
190
|
+
"POST",
|
|
191
|
+
"/api/publish_interaction",
|
|
192
|
+
json=request.model_dump(),
|
|
193
|
+
)
|
|
194
|
+
return PublishUserInteractionResponse(**response)
|
|
195
|
+
|
|
196
|
+
async def _publish_interaction_async(
|
|
197
|
+
self, request: PublishUserInteractionRequest
|
|
198
|
+
) -> PublishUserInteractionResponse:
|
|
199
|
+
"""Internal async method to publish interaction."""
|
|
200
|
+
response = await self._make_async_request(
|
|
201
|
+
"POST",
|
|
202
|
+
"/api/publish_interaction",
|
|
203
|
+
json=request.model_dump(),
|
|
204
|
+
)
|
|
205
|
+
return PublishUserInteractionResponse(**response)
|
|
206
|
+
|
|
207
|
+
def publish_interaction(
|
|
117
208
|
self,
|
|
118
209
|
request_id: str,
|
|
119
210
|
user_id: str,
|
|
120
211
|
interaction_requests: list[Union[InteractionRequest, dict]],
|
|
121
212
|
source: str = "",
|
|
122
213
|
agent_version: str = "",
|
|
123
|
-
|
|
214
|
+
wait_for_response: bool = False,
|
|
215
|
+
) -> Optional[PublishUserInteractionResponse]:
|
|
124
216
|
"""Publish user interactions.
|
|
125
217
|
|
|
218
|
+
This method is optimized for resource efficiency:
|
|
219
|
+
- In async contexts (e.g., FastAPI): Uses existing event loop (most efficient)
|
|
220
|
+
- In sync contexts: Uses shared thread pool (avoids thread creation overhead)
|
|
221
|
+
|
|
126
222
|
Args:
|
|
127
223
|
request_id (str): The request ID
|
|
128
224
|
user_id (str): The user ID
|
|
129
225
|
interaction_requests (List[InteractionRequest]): List of interaction requests
|
|
130
226
|
source (str, optional): The source of the interaction
|
|
227
|
+
agent_version (str, optional): The agent version
|
|
228
|
+
wait_for_response (bool, optional): If True, wait for response. If False, send request without waiting. Defaults to False.
|
|
131
229
|
Returns:
|
|
132
|
-
PublishUserInteractionResponse: Response containing success status and message
|
|
230
|
+
Optional[PublishUserInteractionResponse]: Response containing success status and message if wait_for_response=True, None otherwise
|
|
133
231
|
"""
|
|
134
232
|
interaction_requests = [
|
|
135
233
|
(
|
|
@@ -146,14 +244,18 @@ class AgenticMemClient:
|
|
|
146
244
|
source=source,
|
|
147
245
|
agent_version=agent_version,
|
|
148
246
|
)
|
|
149
|
-
response = await self._make_async_request(
|
|
150
|
-
"POST",
|
|
151
|
-
"/api/publish_interaction",
|
|
152
|
-
json=request.model_dump(),
|
|
153
|
-
)
|
|
154
|
-
return PublishUserInteractionResponse(**response)
|
|
155
247
|
|
|
156
|
-
|
|
248
|
+
if wait_for_response:
|
|
249
|
+
# Synchronous blocking call
|
|
250
|
+
return self._publish_interaction_sync(request)
|
|
251
|
+
else:
|
|
252
|
+
# Non-blocking fire-and-forget
|
|
253
|
+
self._fire_and_forget(
|
|
254
|
+
self._publish_interaction_sync, self._publish_interaction_async, request
|
|
255
|
+
)
|
|
256
|
+
return None
|
|
257
|
+
|
|
258
|
+
def search_interactions(
|
|
157
259
|
self,
|
|
158
260
|
request: Union[SearchInteractionRequest, dict],
|
|
159
261
|
) -> SearchInteractionResponse:
|
|
@@ -165,16 +267,15 @@ class AgenticMemClient:
|
|
|
165
267
|
Returns:
|
|
166
268
|
SearchInteractionResponse: Response containing matching interactions
|
|
167
269
|
"""
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
response = await self._make_async_request(
|
|
270
|
+
request = self._convert_to_model(request, SearchInteractionRequest)
|
|
271
|
+
response = self._make_request(
|
|
171
272
|
"POST",
|
|
172
273
|
"/api/search_interactions",
|
|
173
274
|
json=request.model_dump(),
|
|
174
275
|
)
|
|
175
276
|
return SearchInteractionResponse(**response)
|
|
176
277
|
|
|
177
|
-
|
|
278
|
+
def search_profiles(
|
|
178
279
|
self,
|
|
179
280
|
request: Union[SearchUserProfileRequest, dict],
|
|
180
281
|
) -> SearchUserProfileResponse:
|
|
@@ -186,61 +287,135 @@ class AgenticMemClient:
|
|
|
186
287
|
Returns:
|
|
187
288
|
SearchUserProfileResponse: Response containing matching profiles
|
|
188
289
|
"""
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
response = await self._make_async_request(
|
|
290
|
+
request = self._convert_to_model(request, SearchUserProfileRequest)
|
|
291
|
+
response = self._make_request(
|
|
192
292
|
"POST", "/api/search_profiles", json=request.model_dump()
|
|
193
293
|
)
|
|
194
294
|
return SearchUserProfileResponse(**response)
|
|
195
295
|
|
|
196
|
-
|
|
197
|
-
self,
|
|
296
|
+
def _delete_profile_sync(
|
|
297
|
+
self, request: DeleteUserProfileRequest
|
|
298
|
+
) -> DeleteUserProfileResponse:
|
|
299
|
+
"""Internal sync method to delete profile."""
|
|
300
|
+
response = self._make_request(
|
|
301
|
+
"DELETE",
|
|
302
|
+
"/api/delete_profile",
|
|
303
|
+
json=request.model_dump(),
|
|
304
|
+
)
|
|
305
|
+
return DeleteUserProfileResponse(**response)
|
|
306
|
+
|
|
307
|
+
async def _delete_profile_async(
|
|
308
|
+
self, request: DeleteUserProfileRequest
|
|
198
309
|
) -> DeleteUserProfileResponse:
|
|
310
|
+
"""Internal async method to delete profile."""
|
|
311
|
+
response = await self._make_async_request(
|
|
312
|
+
"DELETE",
|
|
313
|
+
"/api/delete_profile",
|
|
314
|
+
json=request.model_dump(),
|
|
315
|
+
)
|
|
316
|
+
return DeleteUserProfileResponse(**response)
|
|
317
|
+
|
|
318
|
+
def delete_profile(
|
|
319
|
+
self,
|
|
320
|
+
user_id: str,
|
|
321
|
+
profile_id: str = "",
|
|
322
|
+
search_query: str = "",
|
|
323
|
+
wait_for_response: bool = False,
|
|
324
|
+
) -> Optional[DeleteUserProfileResponse]:
|
|
199
325
|
"""Delete user profiles.
|
|
200
326
|
|
|
327
|
+
This method is optimized for resource efficiency:
|
|
328
|
+
- In async contexts (e.g., FastAPI): Uses existing event loop (most efficient)
|
|
329
|
+
- In sync contexts: Uses shared thread pool (avoids thread creation overhead)
|
|
330
|
+
|
|
201
331
|
Args:
|
|
202
332
|
user_id (str): The user ID
|
|
203
333
|
profile_id (str, optional): Specific profile ID to delete
|
|
204
334
|
search_query (str, optional): Query to match profiles for deletion
|
|
335
|
+
wait_for_response (bool, optional): If True, wait for response. If False, send request without waiting. Defaults to False.
|
|
205
336
|
|
|
206
337
|
Returns:
|
|
207
|
-
DeleteUserProfileResponse: Response containing success status and message
|
|
338
|
+
Optional[DeleteUserProfileResponse]: Response containing success status and message if wait_for_response=True, None otherwise
|
|
208
339
|
"""
|
|
209
340
|
request = DeleteUserProfileRequest(
|
|
210
341
|
user_id=user_id,
|
|
211
342
|
profile_id=profile_id,
|
|
212
343
|
search_query=search_query,
|
|
213
344
|
)
|
|
214
|
-
|
|
215
|
-
|
|
345
|
+
|
|
346
|
+
if wait_for_response:
|
|
347
|
+
# Synchronous blocking call
|
|
348
|
+
return self._delete_profile_sync(request)
|
|
349
|
+
else:
|
|
350
|
+
# Non-blocking fire-and-forget
|
|
351
|
+
self._fire_and_forget(
|
|
352
|
+
self._delete_profile_sync, self._delete_profile_async, request
|
|
353
|
+
)
|
|
354
|
+
return None
|
|
355
|
+
|
|
356
|
+
def _delete_interaction_sync(
|
|
357
|
+
self, request: DeleteUserInteractionRequest
|
|
358
|
+
) -> DeleteUserInteractionResponse:
|
|
359
|
+
"""Internal sync method to delete interaction."""
|
|
360
|
+
response = self._make_request(
|
|
361
|
+
"DELETE",
|
|
362
|
+
"/api/delete_interaction",
|
|
363
|
+
json=request.model_dump(),
|
|
216
364
|
)
|
|
217
|
-
return
|
|
365
|
+
return DeleteUserInteractionResponse(**response)
|
|
218
366
|
|
|
219
|
-
async def
|
|
220
|
-
self,
|
|
367
|
+
async def _delete_interaction_async(
|
|
368
|
+
self, request: DeleteUserInteractionRequest
|
|
221
369
|
) -> DeleteUserInteractionResponse:
|
|
370
|
+
"""Internal async method to delete interaction."""
|
|
371
|
+
response = await self._make_async_request(
|
|
372
|
+
"DELETE",
|
|
373
|
+
"/api/delete_interaction",
|
|
374
|
+
json=request.model_dump(),
|
|
375
|
+
)
|
|
376
|
+
return DeleteUserInteractionResponse(**response)
|
|
377
|
+
|
|
378
|
+
def delete_interaction(
|
|
379
|
+
self, user_id: str, interaction_id: str, wait_for_response: bool = False
|
|
380
|
+
) -> Optional[DeleteUserInteractionResponse]:
|
|
222
381
|
"""Delete a user interaction.
|
|
223
382
|
|
|
383
|
+
This method is optimized for resource efficiency:
|
|
384
|
+
- In async contexts (e.g., FastAPI): Uses existing event loop (most efficient)
|
|
385
|
+
- In sync contexts: Uses shared thread pool (avoids thread creation overhead)
|
|
386
|
+
|
|
224
387
|
Args:
|
|
225
388
|
user_id (str): The user ID
|
|
226
389
|
interaction_id (str): The interaction ID to delete
|
|
390
|
+
wait_for_response (bool, optional): If True, wait for response. If False, send request without waiting. Defaults to False.
|
|
227
391
|
|
|
228
392
|
Returns:
|
|
229
|
-
DeleteUserInteractionResponse: Response containing success status and message
|
|
393
|
+
Optional[DeleteUserInteractionResponse]: Response containing success status and message if wait_for_response=True, None otherwise
|
|
230
394
|
"""
|
|
231
395
|
request = DeleteUserInteractionRequest(
|
|
232
396
|
user_id=user_id, interaction_id=interaction_id
|
|
233
397
|
)
|
|
234
|
-
response = await self._make_async_request(
|
|
235
|
-
"DELETE", "/api/delete_interaction", json=request.model_dump()
|
|
236
|
-
)
|
|
237
|
-
return DeleteUserInteractionResponse(**response)
|
|
238
398
|
|
|
239
|
-
|
|
240
|
-
|
|
399
|
+
if wait_for_response:
|
|
400
|
+
# Synchronous blocking call
|
|
401
|
+
return self._delete_interaction_sync(request)
|
|
402
|
+
else:
|
|
403
|
+
# Non-blocking fire-and-forget
|
|
404
|
+
self._fire_and_forget(
|
|
405
|
+
self._delete_interaction_sync, self._delete_interaction_async, request
|
|
406
|
+
)
|
|
407
|
+
return None
|
|
408
|
+
|
|
409
|
+
def get_profile_change_log(self) -> ProfileChangeLogResponse:
|
|
410
|
+
"""Get profile change log.
|
|
411
|
+
|
|
412
|
+
Returns:
|
|
413
|
+
ProfileChangeLogResponse: Response containing profile change log
|
|
414
|
+
"""
|
|
415
|
+
response = self._make_request("GET", "/api/profile_change_log")
|
|
241
416
|
return ProfileChangeLogResponse(**response)
|
|
242
417
|
|
|
243
|
-
|
|
418
|
+
def get_interactions(
|
|
244
419
|
self,
|
|
245
420
|
request: Union[GetInteractionsRequest, dict],
|
|
246
421
|
) -> GetInteractionsResponse:
|
|
@@ -252,16 +427,15 @@ class AgenticMemClient:
|
|
|
252
427
|
Returns:
|
|
253
428
|
GetInteractionsResponse: Response containing list of interactions
|
|
254
429
|
"""
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
response = await self._make_async_request(
|
|
430
|
+
request = self._convert_to_model(request, GetInteractionsRequest)
|
|
431
|
+
response = self._make_request(
|
|
258
432
|
"POST",
|
|
259
433
|
"/api/get_interactions",
|
|
260
434
|
json=request.model_dump(),
|
|
261
435
|
)
|
|
262
436
|
return GetInteractionsResponse(**response)
|
|
263
437
|
|
|
264
|
-
|
|
438
|
+
def get_profiles(
|
|
265
439
|
self,
|
|
266
440
|
request: Union[GetUserProfilesRequest, dict],
|
|
267
441
|
) -> GetUserProfilesResponse:
|
|
@@ -273,16 +447,15 @@ class AgenticMemClient:
|
|
|
273
447
|
Returns:
|
|
274
448
|
GetUserProfilesResponse: Response containing list of profiles
|
|
275
449
|
"""
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
response = await self._make_async_request(
|
|
450
|
+
request = self._convert_to_model(request, GetUserProfilesRequest)
|
|
451
|
+
response = self._make_request(
|
|
279
452
|
"POST",
|
|
280
453
|
"/api/get_profiles",
|
|
281
454
|
json=request.model_dump(),
|
|
282
455
|
)
|
|
283
456
|
return GetUserProfilesResponse(**response)
|
|
284
457
|
|
|
285
|
-
|
|
458
|
+
def set_config(self, config: Union[Config, dict]) -> dict:
|
|
286
459
|
"""Set configuration for the organization.
|
|
287
460
|
|
|
288
461
|
Args:
|
|
@@ -291,28 +464,27 @@ class AgenticMemClient:
|
|
|
291
464
|
Returns:
|
|
292
465
|
dict: Response containing success status and message
|
|
293
466
|
"""
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
response = await self._make_async_request(
|
|
467
|
+
config = self._convert_to_model(config, Config)
|
|
468
|
+
response = self._make_request(
|
|
297
469
|
"POST",
|
|
298
470
|
"/api/set_config",
|
|
299
471
|
json=config.model_dump(),
|
|
300
472
|
)
|
|
301
473
|
return response
|
|
302
474
|
|
|
303
|
-
|
|
475
|
+
def get_config(self) -> Config:
|
|
304
476
|
"""Get configuration for the organization.
|
|
305
477
|
|
|
306
478
|
Returns:
|
|
307
479
|
Config: The current configuration
|
|
308
480
|
"""
|
|
309
|
-
response =
|
|
481
|
+
response = self._make_request(
|
|
310
482
|
"GET",
|
|
311
483
|
"/api/get_config",
|
|
312
484
|
)
|
|
313
485
|
return Config(**response)
|
|
314
486
|
|
|
315
|
-
|
|
487
|
+
def get_raw_feedbacks(
|
|
316
488
|
self,
|
|
317
489
|
request: Optional[Union[GetRawFeedbacksRequest, dict]] = None,
|
|
318
490
|
) -> GetRawFeedbacksResponse:
|
|
@@ -326,16 +498,16 @@ class AgenticMemClient:
|
|
|
326
498
|
"""
|
|
327
499
|
if request is None:
|
|
328
500
|
request = GetRawFeedbacksRequest()
|
|
329
|
-
|
|
330
|
-
request =
|
|
331
|
-
response =
|
|
501
|
+
else:
|
|
502
|
+
request = self._convert_to_model(request, GetRawFeedbacksRequest)
|
|
503
|
+
response = self._make_request(
|
|
332
504
|
"POST",
|
|
333
505
|
"/api/get_raw_feedbacks",
|
|
334
506
|
json=request.model_dump(),
|
|
335
507
|
)
|
|
336
508
|
return GetRawFeedbacksResponse(**response)
|
|
337
509
|
|
|
338
|
-
|
|
510
|
+
def get_feedbacks(
|
|
339
511
|
self,
|
|
340
512
|
request: Optional[Union[GetFeedbacksRequest, dict]] = None,
|
|
341
513
|
) -> GetFeedbacksResponse:
|
|
@@ -349,9 +521,9 @@ class AgenticMemClient:
|
|
|
349
521
|
"""
|
|
350
522
|
if request is None:
|
|
351
523
|
request = GetFeedbacksRequest()
|
|
352
|
-
|
|
353
|
-
request =
|
|
354
|
-
response =
|
|
524
|
+
else:
|
|
525
|
+
request = self._convert_to_model(request, GetFeedbacksRequest)
|
|
526
|
+
response = self._make_request(
|
|
355
527
|
"POST",
|
|
356
528
|
"/api/get_feedbacks",
|
|
357
529
|
json=request.model_dump(),
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
|
+
Name: agenticmem
|
|
3
|
+
Version: 0.1.3.8
|
|
4
|
+
Summary: A Python client for the AgenticMem API
|
|
5
|
+
License: MIT
|
|
6
|
+
Author: AgenticMem Team
|
|
7
|
+
Requires-Python: >=3.10,<4.0
|
|
8
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
9
|
+
Classifier: Programming Language :: Python :: 3
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
14
|
+
Requires-Dist: agenticmem-commons (==0.1.3.8)
|
|
15
|
+
Requires-Dist: aiohttp (>=3.12.9,<4.0.0)
|
|
16
|
+
Requires-Dist: griffe (==0.48.0)
|
|
17
|
+
Requires-Dist: mkdocs-with-pdf (>=0.9.3,<0.10.0)
|
|
18
|
+
Requires-Dist: mkdocstrings[python] (>=0.18.0)
|
|
19
|
+
Requires-Dist: pydantic (>=2.0.0,<3.0.0)
|
|
20
|
+
Requires-Dist: python-dateutil (>=2.8.0,<3.0.0)
|
|
21
|
+
Requires-Dist: requests (>=2.25.0,<3.0.0)
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
|
|
24
|
+
# /user_profiler/agenticmem/agenticmem_client
|
|
25
|
+
Description: Python SDK for remote async access to AgenticMem API
|
|
26
|
+
|
|
27
|
+
## Main Entry Points
|
|
28
|
+
|
|
29
|
+
- **Client**: `agenticmem/client.py` - `AgenticMemClient`
|
|
30
|
+
- **Utils**: `agenticmem/client_utils.py` - Helper utilities
|
|
31
|
+
|
|
32
|
+
## Purpose
|
|
33
|
+
|
|
34
|
+
1. **Remote API access** - Async SDK for applications to call AgenticMem backend
|
|
35
|
+
2. **Authentication** - Handle login and Bearer token management
|
|
36
|
+
3. **Type-safe interface** - Auto-parsing responses into Pydantic models
|
|
37
|
+
|
|
38
|
+
## API Methods
|
|
39
|
+
|
|
40
|
+
**Authentication:**
|
|
41
|
+
- `login(email, password)` - Get auth token
|
|
42
|
+
|
|
43
|
+
**Publishing:**
|
|
44
|
+
- `publish_interaction(request_id, user_id, interactions, source, agent_version)` - Publish interactions (triggers profile/feedback/evaluation)
|
|
45
|
+
|
|
46
|
+
**Profiles:**
|
|
47
|
+
- `search_profiles(request)` - Semantic search
|
|
48
|
+
- `get_profiles(request)` - Get all for user
|
|
49
|
+
- `delete_profile(user_id, profile_id, search_query)` - Delete profiles
|
|
50
|
+
- `get_profile_change_log()` - Get history
|
|
51
|
+
|
|
52
|
+
**Interactions:**
|
|
53
|
+
- `search_interactions(request)` - Semantic search
|
|
54
|
+
- `get_interactions(request)` - Get all for user
|
|
55
|
+
- `delete_interaction(user_id, interaction_id)` - Delete interaction
|
|
56
|
+
|
|
57
|
+
**Feedback:**
|
|
58
|
+
- `get_raw_feedbacks(request)` - Raw feedback from interactions
|
|
59
|
+
- `get_feedbacks(request)` - Aggregated feedback with status
|
|
60
|
+
|
|
61
|
+
**Configuration:**
|
|
62
|
+
- `set_config(config)` - Update org config (extractors, evaluators, storage)
|
|
63
|
+
- `get_config()` - Get current config
|
|
64
|
+
|
|
65
|
+
## Architecture Pattern
|
|
66
|
+
|
|
67
|
+
- **All async** - Uses `aiohttp` for HTTP requests
|
|
68
|
+
- **Type-safe** - Pydantic models from `agenticmem_commons`
|
|
69
|
+
- **Auto-parsing** - Responses → Pydantic models
|
|
70
|
+
- **Flexible input** - Accepts Pydantic models or dicts
|
|
71
|
+
- **Bearer auth** - Automatic token handling
|
|
72
|
+
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
agenticmem/__init__.py,sha256=nSrWdD87z0hbmqVzZxt4xiSccgKyAQOkXosvZlte1ps,1794
|
|
2
|
+
agenticmem/client.py,sha256=v7B16F8X-r7vF1tFi_BVJw1KjB7vK3118VhRREBqvY8,18542
|
|
3
|
+
agenticmem/client_utils.py,sha256=kWTWlyO7s768v38ef41nRDq87Qmb60NX2vmZTVlCB6g,297
|
|
4
|
+
agenticmem-0.1.3.8.dist-info/METADATA,sha256=j1tny6rIA2zyt5nGVmpT6Znep0k8L2JE67eXwGWUCEU,2564
|
|
5
|
+
agenticmem-0.1.3.8.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
|
|
6
|
+
agenticmem-0.1.3.8.dist-info/RECORD,,
|
|
@@ -1,145 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.3
|
|
2
|
-
Name: agenticmem
|
|
3
|
-
Version: 0.1.2.4
|
|
4
|
-
Summary: A Python client for the AgenticMem API
|
|
5
|
-
License: MIT
|
|
6
|
-
Author: AgenticMem Team
|
|
7
|
-
Requires-Python: >=3.10,<4.0
|
|
8
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
9
|
-
Classifier: Programming Language :: Python :: 3
|
|
10
|
-
Classifier: Programming Language :: Python :: 3.10
|
|
11
|
-
Classifier: Programming Language :: Python :: 3.11
|
|
12
|
-
Classifier: Programming Language :: Python :: 3.12
|
|
13
|
-
Classifier: Programming Language :: Python :: 3.13
|
|
14
|
-
Requires-Dist: agenticmem-commons (==0.1.3.6)
|
|
15
|
-
Requires-Dist: aiohttp (>=3.12.9,<4.0.0)
|
|
16
|
-
Requires-Dist: griffe (==0.48.0)
|
|
17
|
-
Requires-Dist: mkdocstrings[python] (>=0.18.0)
|
|
18
|
-
Requires-Dist: pydantic (>=2.0.0,<3.0.0)
|
|
19
|
-
Requires-Dist: python-dateutil (>=2.8.0,<3.0.0)
|
|
20
|
-
Requires-Dist: requests (>=2.25.0,<3.0.0)
|
|
21
|
-
Description-Content-Type: text/markdown
|
|
22
|
-
|
|
23
|
-
# AgenticMem Python Client
|
|
24
|
-
|
|
25
|
-
A Python client library for interacting with the AgenticMem API. This client provides easy-to-use interfaces for managing user interactions and profiles.
|
|
26
|
-
|
|
27
|
-
## Installation
|
|
28
|
-
|
|
29
|
-
```bash
|
|
30
|
-
pip install agenticmem
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
## Quick Start
|
|
34
|
-
|
|
35
|
-
```python
|
|
36
|
-
from agenticmem import AgenticMemClient
|
|
37
|
-
from agenticmem_commons.api_schema.service_schemas import InteractionRequest
|
|
38
|
-
from agenticmem_commons.api_schema.retriever_schema import (
|
|
39
|
-
SearchInteractionRequest,
|
|
40
|
-
SearchUserProfileRequest,
|
|
41
|
-
GetInteractionsRequest,
|
|
42
|
-
GetUserProfilesRequest
|
|
43
|
-
)
|
|
44
|
-
from datetime import datetime
|
|
45
|
-
|
|
46
|
-
# Initialize the client
|
|
47
|
-
client = AgenticMemClient(api_key="your_api_key")
|
|
48
|
-
|
|
49
|
-
# Optional: Login with email/password
|
|
50
|
-
token = client.login(email="user@example.com", password="password123")
|
|
51
|
-
|
|
52
|
-
# Publish a user interaction
|
|
53
|
-
interaction = InteractionRequest(
|
|
54
|
-
created_at=int(datetime.utcnow().timestamp()),
|
|
55
|
-
content="User clicked on product X",
|
|
56
|
-
user_action="click",
|
|
57
|
-
user_action_description="Clicked on product details button"
|
|
58
|
-
)
|
|
59
|
-
|
|
60
|
-
response = client.publish_interaction(
|
|
61
|
-
user_id="user123",
|
|
62
|
-
request_id="req456",
|
|
63
|
-
interaction_requests=[interaction]
|
|
64
|
-
)
|
|
65
|
-
print(f"Published interaction: {response.success} - {response.message}")
|
|
66
|
-
|
|
67
|
-
# Search user profiles
|
|
68
|
-
profiles_request = SearchUserProfileRequest(
|
|
69
|
-
user_id="user123",
|
|
70
|
-
search_query="recent interactions",
|
|
71
|
-
top_k=5
|
|
72
|
-
)
|
|
73
|
-
profiles = client.search_profiles(profiles_request)
|
|
74
|
-
for profile in profiles.profiles:
|
|
75
|
-
print(f"Profile {profile.profile_id}: {profile.profile_content}")
|
|
76
|
-
|
|
77
|
-
# Get user profiles directly
|
|
78
|
-
profiles_request = GetUserProfilesRequest(
|
|
79
|
-
user_id="user123"
|
|
80
|
-
)
|
|
81
|
-
profiles = client.get_profiles(profiles_request)
|
|
82
|
-
for profile in profiles.profiles:
|
|
83
|
-
print(f"Profile: {profile}")
|
|
84
|
-
|
|
85
|
-
# Search interactions
|
|
86
|
-
interactions_request = SearchInteractionRequest(
|
|
87
|
-
user_id="user123",
|
|
88
|
-
start_time=int(datetime(2024, 1, 1).timestamp()),
|
|
89
|
-
end_time=int(datetime.utcnow().timestamp())
|
|
90
|
-
)
|
|
91
|
-
interactions = client.search_interactions(interactions_request)
|
|
92
|
-
for interaction in interactions.interactions:
|
|
93
|
-
print(f"Interaction {interaction.interaction_id}: {interaction.content}")
|
|
94
|
-
|
|
95
|
-
# Get interactions directly
|
|
96
|
-
interactions_request = GetInteractionsRequest(
|
|
97
|
-
user_id="user123"
|
|
98
|
-
)
|
|
99
|
-
interactions = client.get_interactions(interactions_request)
|
|
100
|
-
for interaction in interactions.interactions:
|
|
101
|
-
print(f"Interaction: {interaction}")
|
|
102
|
-
|
|
103
|
-
# Get profile change log
|
|
104
|
-
change_log = client.get_profile_change_log()
|
|
105
|
-
print(f"Profile changes: {change_log}")
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
## Features
|
|
109
|
-
|
|
110
|
-
- Authentication
|
|
111
|
-
- API key authentication
|
|
112
|
-
- Email/password login
|
|
113
|
-
- User interaction management
|
|
114
|
-
- Publish user interactions
|
|
115
|
-
- Delete specific interactions
|
|
116
|
-
- Search interactions with time range and filters
|
|
117
|
-
- Get direct list of interactions
|
|
118
|
-
- User profile management
|
|
119
|
-
- Search user profiles with customizable queries
|
|
120
|
-
- Get direct list of user profiles
|
|
121
|
-
- Delete specific profiles or profiles matching a search query
|
|
122
|
-
- View profile change log history
|
|
123
|
-
|
|
124
|
-
## API Response Types
|
|
125
|
-
|
|
126
|
-
All API methods return strongly-typed responses:
|
|
127
|
-
|
|
128
|
-
- `login()` returns `Token`
|
|
129
|
-
- `publish_interaction()` returns `PublishUserInteractionResponse`
|
|
130
|
-
- `search_interactions()` returns `SearchInteractionResponse`
|
|
131
|
-
- `get_interactions()` returns `GetInteractionsResponse`
|
|
132
|
-
- `search_profiles()` returns `SearchUserProfileResponse`
|
|
133
|
-
- `get_profiles()` returns `GetUserProfilesResponse`
|
|
134
|
-
- `delete_profile()` returns `DeleteUserProfileResponse`
|
|
135
|
-
- `delete_interaction()` returns `DeleteUserInteractionResponse`
|
|
136
|
-
- `get_profile_change_log()` returns `ProfileChangeLogResponse`
|
|
137
|
-
|
|
138
|
-
## Documentation
|
|
139
|
-
|
|
140
|
-
For detailed documentation, please visit [docs link].
|
|
141
|
-
|
|
142
|
-
## License
|
|
143
|
-
|
|
144
|
-
MIT License
|
|
145
|
-
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
agenticmem/__init__.py,sha256=g5Xq7CEO4d7jIxkGRQg4z71MFQmL2UMeJtnP9GoMzAY,1714
|
|
2
|
-
agenticmem/client.py,sha256=xz7eG4o0JrMq0LjvHlAIHjZnjuaOq2k5wsqixi8cLuk,12007
|
|
3
|
-
agenticmem/client_utils.py,sha256=kWTWlyO7s768v38ef41nRDq87Qmb60NX2vmZTVlCB6g,297
|
|
4
|
-
agenticmem-0.1.2.4.dist-info/METADATA,sha256=swSTv3f58QaaSZm-MbKQdjgbDDrJ9lFIW2ZgaLL_eSg,4461
|
|
5
|
-
agenticmem-0.1.2.4.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
|
|
6
|
-
agenticmem-0.1.2.4.dist-info/RECORD,,
|
|
File without changes
|