6
6
7
7
import asyncio
8
8
import re
9
- from collections .abc import AsyncIterator
9
+ from collections .abc import AsyncIterator , Sequence
10
10
from typing import TYPE_CHECKING , Any , Literal , TypedDict
11
11
12
12
if TYPE_CHECKING :
13
13
from typing_extensions import Self
14
14
15
15
import httpx
16
- import ulid
17
16
from pydantic import BaseModel
17
+ from ulid import ULID
18
18
19
19
from .exceptions import MemoryClientError , MemoryServerError , MemoryValidationError
20
20
from .filters import (
@@ -416,7 +416,7 @@ async def set_working_memory_data(
416
416
async def add_memories_to_working_memory (
417
417
self ,
418
418
session_id : str ,
419
- memories : list [ClientMemoryRecord | MemoryRecord ],
419
+ memories : Sequence [ClientMemoryRecord | MemoryRecord ],
420
420
namespace : str | None = None ,
421
421
replace : bool = False ,
422
422
) -> WorkingMemoryResponse :
@@ -459,14 +459,14 @@ async def add_memories_to_working_memory(
459
459
460
460
# Determine final memories list
461
461
if replace or not existing_memory :
462
- final_memories = memories
462
+ final_memories = list ( memories )
463
463
else :
464
- final_memories = existing_memory .memories + memories
464
+ final_memories = existing_memory .memories + list ( memories )
465
465
466
466
# Auto-generate IDs for memories that don't have them
467
467
for memory in final_memories :
468
468
if not memory .id :
469
- memory .id = str (ulid . ULID ())
469
+ memory .id = str (ULID ())
470
470
471
471
# Create new working memory with the memories
472
472
working_memory = WorkingMemory (
@@ -482,7 +482,7 @@ async def add_memories_to_working_memory(
482
482
return await self .put_working_memory (session_id , working_memory )
483
483
484
484
async def create_long_term_memory (
485
- self , memories : list [ClientMemoryRecord | MemoryRecord ]
485
+ self , memories : Sequence [ClientMemoryRecord | MemoryRecord ]
486
486
) -> AckResponse :
487
487
"""
488
488
Create long-term memories for later retrieval.
@@ -541,6 +541,29 @@ async def create_long_term_memory(
541
541
self ._handle_http_error (e .response )
542
542
raise
543
543
544
+ async def delete_long_term_memories (self , memory_ids : Sequence [str ]) -> AckResponse :
545
+ """
546
+ Delete long-term memories.
547
+
548
+ Args:
549
+ memory_ids: List of memory IDs to delete
550
+
551
+ Returns:
552
+ AckResponse indicating success
553
+ """
554
+ params = {"memory_ids" : list (memory_ids )}
555
+
556
+ try :
557
+ response = await self ._client .delete (
558
+ "/v1/long-term-memory" ,
559
+ params = params ,
560
+ )
561
+ response .raise_for_status ()
562
+ return AckResponse (** response .json ())
563
+ except httpx .HTTPStatusError as e :
564
+ self ._handle_http_error (e .response )
565
+ raise
566
+
544
567
async def search_long_term_memory (
545
568
self ,
546
569
text : str ,
@@ -666,8 +689,8 @@ async def search_long_term_memory(
666
689
async def search_memory_tool (
667
690
self ,
668
691
query : str ,
669
- topics : list [str ] | None = None ,
670
- entities : list [str ] | None = None ,
692
+ topics : Sequence [str ] | None = None ,
693
+ entities : Sequence [str ] | None = None ,
671
694
memory_type : str | None = None ,
672
695
max_results : int = 5 ,
673
696
min_relevance : float | None = None ,
@@ -722,8 +745,8 @@ async def search_memory_tool(
722
745
from .filters import Entities , MemoryType , Topics
723
746
724
747
# Convert simple parameters to filter objects
725
- topics_filter = Topics (any = topics ) if topics else None
726
- entities_filter = Entities (any = entities ) if entities else None
748
+ topics_filter = Topics (any = list ( topics ) ) if topics else None
749
+ entities_filter = Entities (any = list ( entities ) ) if entities else None
727
750
memory_type_filter = MemoryType (eq = memory_type ) if memory_type else None
728
751
user_id_filter = UserId (eq = user_id ) if user_id else None
729
752
@@ -940,8 +963,8 @@ async def add_memory_tool(
940
963
session_id : str ,
941
964
text : str ,
942
965
memory_type : str ,
943
- topics : list [str ] | None = None ,
944
- entities : list [str ] | None = None ,
966
+ topics : Sequence [str ] | None = None ,
967
+ entities : Sequence [str ] | None = None ,
945
968
namespace : str | None = None ,
946
969
user_id : str | None = None ,
947
970
) -> dict [str , Any ]:
@@ -982,8 +1005,8 @@ async def add_memory_tool(
982
1005
memory = ClientMemoryRecord (
983
1006
text = text ,
984
1007
memory_type = MemoryTypeEnum (memory_type ),
985
- topics = topics ,
986
- entities = entities ,
1008
+ topics = list ( topics ) if topics else None ,
1009
+ entities = list ( entities ) if entities else None ,
987
1010
namespace = namespace or self .config .default_namespace ,
988
1011
user_id = user_id ,
989
1012
)
@@ -1172,7 +1195,7 @@ def get_update_memory_data_tool_schema(cls) -> dict[str, Any]:
1172
1195
}
1173
1196
1174
1197
@classmethod
1175
- def get_all_memory_tool_schemas (cls ) -> list [dict [str , Any ]]:
1198
+ def get_all_memory_tool_schemas (cls ) -> Sequence [dict [str , Any ]]:
1176
1199
"""
1177
1200
Get all memory-related tool schemas for easy LLM integration.
1178
1201
@@ -1200,7 +1223,7 @@ def get_all_memory_tool_schemas(cls) -> list[dict[str, Any]]:
1200
1223
]
1201
1224
1202
1225
@classmethod
1203
- def get_all_memory_tool_schemas_anthropic (cls ) -> list [dict [str , Any ]]:
1226
+ def get_all_memory_tool_schemas_anthropic (cls ) -> Sequence [dict [str , Any ]]:
1204
1227
"""
1205
1228
Get all memory-related tool schemas in Anthropic format.
1206
1229
@@ -1470,11 +1493,11 @@ async def resolve_tool_call(
1470
1493
1471
1494
async def resolve_tool_calls (
1472
1495
self ,
1473
- tool_calls : list [dict [str , Any ]],
1496
+ tool_calls : Sequence [dict [str , Any ]],
1474
1497
session_id : str ,
1475
1498
namespace : str | None = None ,
1476
1499
user_id : str | None = None ,
1477
- ) -> list [ToolCallResolutionResult ]:
1500
+ ) -> Sequence [ToolCallResolutionResult ]:
1478
1501
"""
1479
1502
Resolve multiple tool calls from any LLM provider format.
1480
1503
@@ -1713,11 +1736,11 @@ async def _resolve_update_memory_data(
1713
1736
1714
1737
async def resolve_function_calls (
1715
1738
self ,
1716
- function_calls : list [dict [str , Any ]],
1739
+ function_calls : Sequence [dict [str , Any ]],
1717
1740
session_id : str ,
1718
1741
namespace : str | None = None ,
1719
1742
user_id : str | None = None ,
1720
- ) -> list [ToolCallResolutionResult ]:
1743
+ ) -> Sequence [ToolCallResolutionResult ]:
1721
1744
"""
1722
1745
Resolve multiple function calls in batch.
1723
1746
@@ -1765,7 +1788,7 @@ async def resolve_function_calls(
1765
1788
async def promote_working_memories_to_long_term (
1766
1789
self ,
1767
1790
session_id : str ,
1768
- memory_ids : list [str ] | None = None ,
1791
+ memory_ids : Sequence [str ] | None = None ,
1769
1792
namespace : str | None = None ,
1770
1793
) -> AckResponse :
1771
1794
"""
@@ -1805,10 +1828,10 @@ async def promote_working_memories_to_long_term(
1805
1828
1806
1829
async def bulk_create_long_term_memories (
1807
1830
self ,
1808
- memory_batches : list [ list [ClientMemoryRecord | MemoryRecord ]],
1831
+ memory_batches : Sequence [ Sequence [ClientMemoryRecord | MemoryRecord ]],
1809
1832
batch_size : int = 100 ,
1810
1833
delay_between_batches : float = 0.1 ,
1811
- ) -> list [AckResponse ]:
1834
+ ) -> Sequence [AckResponse ]:
1812
1835
"""
1813
1836
Create multiple batches of memories with proper rate limiting.
1814
1837
@@ -2104,6 +2127,8 @@ async def memory_prompt(
2104
2127
"""
2105
2128
Hydrate a user query with memory context and return a prompt ready to send to an LLM.
2106
2129
2130
+ NOTE: `long_term_search` uses the same filter options as `search_long_term_memories`.
2131
+
2107
2132
Args:
2108
2133
query: The input text to find relevant context for
2109
2134
session_id: Optional session ID to include session messages
@@ -2163,9 +2188,17 @@ async def memory_prompt(
2163
2188
2164
2189
# Add long-term search parameters if provided
2165
2190
if long_term_search is not None :
2191
+ if "namespace" not in long_term_search :
2192
+ if namespace is not None :
2193
+ long_term_search ["namespace" ] = {"eq" : namespace }
2194
+ elif self .config .default_namespace is not None :
2195
+ long_term_search ["namespace" ] = {
2196
+ "eq" : self .config .default_namespace
2197
+ }
2166
2198
payload ["long_term_search" ] = long_term_search
2167
2199
2168
2200
try :
2201
+ print ("Payload: " , payload )
2169
2202
response = await self ._client .post (
2170
2203
"/v1/memory/prompt" ,
2171
2204
json = payload ,
0 commit comments