2626 extract_facts_from_messages ,
2727)
2828from altk_evolve .llm .guidelines .guidelines import generate_guidelines
29+ from altk_evolve .schema .conflict_resolution import EntityUpdate
2930from altk_evolve .schema .core import Entity , RecordedEntity
3031from altk_evolve .schema .exceptions import EvolveException , NamespaceNotFoundException
3132
@@ -236,6 +237,36 @@ def _parse_metadata(metadata: str | None) -> dict[str, Any]:
236237 return parsed
237238
238239
240+ def _persist_entities (
241+ namespace_id : str | None ,
242+ entities : list [Entity ],
243+ enable_conflict_resolution : bool = False ,
244+ ) -> tuple [list [EntityUpdate ], str ]:
245+ """Persist entities with a single retry if the namespace cache is stale.
246+
247+ Resolves ``namespace_id`` (falling back to the configured default), writes
248+ via ``update_entities``, and on ``NamespaceNotFoundException`` evicts the
249+ cached entry, re-resolves, and retries once. Returns the update records
250+ and the namespace actually written to.
251+ """
252+ resolved_ns = _resolve_namespace (namespace_id )
253+ try :
254+ updates = get_client ().update_entities (
255+ namespace_id = resolved_ns ,
256+ entities = entities ,
257+ enable_conflict_resolution = enable_conflict_resolution ,
258+ )
259+ except NamespaceNotFoundException :
260+ _evict_namespace (resolved_ns )
261+ resolved_ns = _resolve_namespace (namespace_id )
262+ updates = get_client ().update_entities (
263+ namespace_id = resolved_ns ,
264+ entities = entities ,
265+ enable_conflict_resolution = enable_conflict_resolution ,
266+ )
267+ return updates , resolved_ns
268+
269+
239270@mcp .tool ()
240271def get_entities (
241272 task : str ,
@@ -310,8 +341,6 @@ def store_user_facts(
310341 if not trimmed_message :
311342 return _empty_store_user_facts_response (user_id )
312343
313- resolved_ns = _resolve_namespace (None )
314-
315344 base_metadata : dict [str , Any ] = dict (metadata_dict )
316345 base_metadata ["user_id" ] = user_id
317346
@@ -330,20 +359,11 @@ def store_user_facts(
330359 if not entities :
331360 return _empty_store_user_facts_response (user_id )
332361
333- try :
334- updates = get_client ().update_entities (
335- namespace_id = resolved_ns ,
336- entities = entities ,
337- enable_conflict_resolution = enable_conflict_resolution ,
338- )
339- except NamespaceNotFoundException :
340- _evict_namespace (resolved_ns )
341- resolved_ns = _resolve_namespace (None )
342- updates = get_client ().update_entities (
343- namespace_id = resolved_ns ,
344- entities = entities ,
345- enable_conflict_resolution = enable_conflict_resolution ,
346- )
362+ updates , _ = _persist_entities (
363+ namespace_id = None ,
364+ entities = entities ,
365+ enable_conflict_resolution = enable_conflict_resolution ,
366+ )
347367
348368 serialized_updates = [
349369 {
@@ -487,20 +507,11 @@ def save_trajectory(
487507 )
488508 )
489509
490- try :
491- get_client ().update_entities (
492- namespace_id = resolved_ns ,
493- entities = entities ,
494- enable_conflict_resolution = False ,
495- )
496- except NamespaceNotFoundException :
497- _evict_namespace (resolved_ns )
498- resolved_ns = _resolve_namespace (namespace_id )
499- get_client ().update_entities (
500- namespace_id = resolved_ns ,
501- entities = entities ,
502- enable_conflict_resolution = False ,
503- )
510+ _ , resolved_ns = _persist_entities (
511+ namespace_id = namespace_id ,
512+ entities = entities ,
513+ enable_conflict_resolution = False ,
514+ )
504515 results = generate_guidelines (messages )
505516
506517 guideline_metadata_base : dict = {
@@ -574,8 +585,7 @@ def create_entity(
574585 Returns:
575586 JSON string with the entity update details (ADD/UPDATE/DELETE/NONE) and entity ID
576587 """
577- resolved_ns = _resolve_namespace (namespace_id )
578- logger .info (f"Creating entity of type: { entity_type } in namespace: { resolved_ns } " )
588+ logger .info (f"Creating entity of type: { entity_type } (namespace override: { namespace_id } )" )
579589 try :
580590 if visibility not in ("private" , "public" ):
581591 return json .dumps ({"error" : f"Invalid visibility '{ visibility } ': must be 'private' or 'public'" })
@@ -611,16 +621,11 @@ def create_entity(
611621
612622 entity = Entity (type = entity_type , content = content , metadata = metadata_dict )
613623
614- try :
615- updates = get_client ().update_entities (
616- namespace_id = resolved_ns , entities = [entity ], enable_conflict_resolution = enable_conflict_resolution
617- )
618- except NamespaceNotFoundException :
619- _evict_namespace (resolved_ns )
620- resolved_ns = _resolve_namespace (namespace_id )
621- updates = get_client ().update_entities (
622- namespace_id = resolved_ns , entities = [entity ], enable_conflict_resolution = enable_conflict_resolution
623- )
624+ updates , _ = _persist_entities (
625+ namespace_id = namespace_id ,
626+ entities = [entity ],
627+ enable_conflict_resolution = enable_conflict_resolution ,
628+ )
624629
625630 if updates :
626631 update = updates [0 ]
0 commit comments