4141 scope_to_fields ,
4242 scope_to_query_pairs ,
4343 strip_agent_scope ,
44+ strip_read_filters ,
4445)
4546
4647Route = Callable [[str ], str ]
@@ -97,7 +98,7 @@ def expand(self, refs: list[str], scope: MemoryScope) -> list[AtomicMemoryMemory
9798 method = "POST" ,
9899 json = body ,
99100 )
100- echoed = strip_agent_scope (scope )
101+ echoed = strip_read_filters (scope )
101102 return [_to_atomic_memory (m , echoed ) for m in raw .get ("memories" , [])]
102103
103104 def list (
@@ -107,7 +108,7 @@ def list(
107108 ) -> AtomicMemoryListResultPage :
108109 opts = _coerce_list_options (options )
109110 _assert_list_options_scope_compat (scope , opts )
110- pairs : list [tuple [str , str ]] = scope_to_query_pairs (scope )
111+ pairs : list [tuple [str , str ]] = scope_to_query_pairs (scope , include_thread = True )
111112 if opts .limit is not None :
112113 pairs .append (("limit" , str (opts .limit )))
113114 if opts .offset is not None :
@@ -131,14 +132,16 @@ def list(
131132 )
132133
133134 def get (self , id : str , scope : MemoryScope ) -> AtomicMemoryMemory | None :
134- path = self ._route (f"/memories/{ quote (id , safe = '' )} ?{ urlencode (scope_to_query_pairs (scope ))} " )
135+ unfiltered_scope = strip_read_filters (scope )
136+ path = self ._route (f"/memories/{ quote (id , safe = '' )} ?{ urlencode (scope_to_query_pairs (unfiltered_scope ))} " )
135137 raw = fetch_json_or_none (self ._client , self ._http , path )
136138 if raw is None :
137139 return None
138- return _to_atomic_memory (raw , strip_agent_scope ( scope ) )
140+ return _to_atomic_memory (raw , unfiltered_scope )
139141
140142 def delete (self , id : str , scope : MemoryScope ) -> None :
141- path = self ._route (f"/memories/{ quote (id , safe = '' )} ?{ urlencode (scope_to_query_pairs (scope ))} " )
143+ unfiltered_scope = strip_read_filters (scope )
144+ path = self ._route (f"/memories/{ quote (id , safe = '' )} ?{ urlencode (scope_to_query_pairs (unfiltered_scope ))} " )
142145 try :
143146 fetch_void (self ._client , self ._http , path , method = "DELETE" )
144147 except ProviderError as exc :
@@ -160,7 +163,7 @@ def _post_ingest(
160163 ) -> AtomicMemoryIngestResult :
161164 assert_scope_allows_visibility (scope , input .visibility )
162165 body : dict [str , Any ] = {
163- ** scope_to_fields (scope ),
166+ ** scope_to_fields (scope , include_thread = True ),
164167 "conversation" : input .conversation ,
165168 "source_site" : input .source_site ,
166169 "source_url" : input .source_url or "" ,
@@ -181,7 +184,7 @@ def _post_search(
181184 scope : MemoryScope ,
182185 ) -> AtomicMemorySearchResultPage :
183186 body : dict [str , Any ] = {
184- ** scope_to_fields (scope , include_agent_scope = True ),
187+ ** scope_to_fields (scope , include_agent_scope = True , include_thread = True ),
185188 "query" : request .query ,
186189 }
187190 if request .limit is not None :
@@ -263,7 +266,7 @@ def _to_atomic_memory(raw: dict[str, Any], scope: MemoryScope) -> AtomicMemoryMe
263266 payload : dict [str , Any ] = {
264267 "id" : raw ["id" ],
265268 "content" : raw .get ("content" ) or "" ,
266- "scope" : scope ,
269+ "scope" : _build_memory_scope ( raw , scope ) ,
267270 "created_at" : _parse_iso (raw .get ("created_at" )) or _now_utc (),
268271 }
269272 if raw .get ("updated_at" ):
@@ -274,6 +277,23 @@ def _to_atomic_memory(raw: dict[str, Any], scope: MemoryScope) -> AtomicMemoryMe
274277 return AtomicMemoryMemory .model_validate (payload )
275278
276279
280+ def _build_memory_scope (raw : dict [str , Any ], requested_scope : MemoryScope ) -> MemoryScope :
281+ """Validate and project Core ``session_id`` back into namespace scope."""
282+ session_id = raw .get ("session_id" )
283+ if requested_scope .thread is not None :
284+ if not session_id :
285+ raise ValueError (
286+ "atomicmemory provider: backend response missing required `session_id` for thread-scoped request"
287+ )
288+ if session_id != requested_scope .thread :
289+ raise ValueError (
290+ "atomicmemory provider: backend response `session_id` did not match requested thread scope"
291+ )
292+ if not session_id :
293+ return requested_scope
294+ return requested_scope .model_copy (update = {"thread" : session_id })
295+
296+
277297def _to_atomic_search_result (raw : dict [str , Any ], scope : MemoryScope ) -> AtomicMemorySearchResult :
278298 similarity = _coalesce (raw .get ("semantic_similarity" ), raw .get ("similarity" ))
279299 ranking_score = _coalesce (raw .get ("ranking_score" ), raw .get ("score" ))
0 commit comments