3131
3232from langgraph .store .redis .base import (
3333 REDIS_KEY_SEPARATOR ,
34- STORE_PREFIX ,
35- STORE_VECTOR_PREFIX ,
3634 BaseRedisStore ,
3735 RedisDocument ,
3836 _decode_ns ,
@@ -74,8 +72,10 @@ def __init__(
7472 redis_client : Optional [AsyncRedis ] = None ,
7573 index : Optional [IndexConfig ] = None ,
7674 connection_args : Optional [dict [str , Any ]] = None ,
77- ttl : Optional [dict [ str , Any ] ] = None ,
75+ ttl : Optional [TTLConfig ] = None ,
7876 cluster_mode : Optional [bool ] = None ,
77+ store_prefix : str = "store" ,
78+ vector_prefix : str = "store_vectors" ,
7979 ) -> None :
8080 """Initialize store with Redis connection and optional index config."""
8181 if redis_url is None and redis_client is None :
@@ -84,29 +84,7 @@ def __init__(
8484 # Initialize base classes
8585 AsyncBatchedBaseStore .__init__ (self )
8686
87- # Set up store configuration
88- self .index_config = index
89- self .ttl_config = ttl
90-
91- if self .index_config :
92- self .index_config = self .index_config .copy ()
93- self .embeddings = ensure_embeddings (
94- self .index_config .get ("embed" ),
95- )
96- fields = (
97- self .index_config .get ("text_fields" , ["$" ])
98- or self .index_config .get ("fields" , ["$" ])
99- or []
100- )
101- if isinstance (fields , str ):
102- fields = [fields ]
103-
104- self .index_config ["__tokenized_fields" ] = [
105- (p , tokenize_path (p )) if p != "$" else (p , p )
106- for p in (self .index_config .get ("fields" ) or ["$" ])
107- ]
108-
109- # Configure client
87+ # Configure client first
11088 self .configure_client (
11189 redis_url = redis_url ,
11290 redis_client = redis_client ,
@@ -116,16 +94,60 @@ def __init__(
11694 # Validate and store cluster_mode; None means auto-detect later
11795 if cluster_mode is not None and not isinstance (cluster_mode , bool ):
11896 raise TypeError ("cluster_mode must be a boolean or None" )
119- self .cluster_mode : Optional [bool ] = cluster_mode
12097
121- # Create store index
98+ # Initialize BaseRedisStore with prefix parameters
99+ BaseRedisStore .__init__ (
100+ self ,
101+ conn = self ._redis ,
102+ index = index ,
103+ ttl = ttl ,
104+ cluster_mode = cluster_mode ,
105+ store_prefix = store_prefix ,
106+ vector_prefix = vector_prefix ,
107+ )
108+
109+ # Update store_index to async version
110+ from copy import deepcopy
111+
112+ store_schema = {
113+ "index" : {
114+ "name" : self .store_prefix ,
115+ "prefix" : self .store_prefix + REDIS_KEY_SEPARATOR ,
116+ "storage_type" : "json" ,
117+ },
118+ "fields" : [
119+ {"name" : "prefix" , "type" : "text" },
120+ {"name" : "key" , "type" : "tag" },
121+ {"name" : "created_at" , "type" : "numeric" },
122+ {"name" : "updated_at" , "type" : "numeric" },
123+ {"name" : "ttl_minutes" , "type" : "numeric" },
124+ {"name" : "expires_at" , "type" : "numeric" },
125+ ],
126+ }
122127 self .store_index = AsyncSearchIndex .from_dict (
123- self . SCHEMAS [ 0 ] , redis_client = self ._redis
128+ store_schema , redis_client = self ._redis
124129 )
125130
126131 # Configure vector index if needed
127132 if self .index_config :
128- vector_schema = self .SCHEMAS [1 ].copy ()
133+ # Create custom vector schema with instance prefix
134+ vector_schema = {
135+ "index" : {
136+ "name" : self .vector_prefix ,
137+ "prefix" : self .vector_prefix + REDIS_KEY_SEPARATOR ,
138+ "storage_type" : "json" ,
139+ },
140+ "fields" : [
141+ {"name" : "prefix" , "type" : "text" },
142+ {"name" : "key" , "type" : "tag" },
143+ {"name" : "field_name" , "type" : "tag" },
144+ {"name" : "embedding" , "type" : "vector" },
145+ {"name" : "created_at" , "type" : "numeric" },
146+ {"name" : "updated_at" , "type" : "numeric" },
147+ {"name" : "ttl_minutes" , "type" : "numeric" },
148+ {"name" : "expires_at" , "type" : "numeric" },
149+ ],
150+ }
129151 vector_fields = vector_schema .get ("fields" , [])
130152 vector_field = None
131153 for f in vector_fields :
@@ -301,10 +323,18 @@ async def from_conn_string(
301323 conn_string : str ,
302324 * ,
303325 index : Optional [IndexConfig ] = None ,
304- ttl : Optional [dict [str , Any ]] = None ,
326+ ttl : Optional [TTLConfig ] = None ,
327+ store_prefix : str = "store" ,
328+ vector_prefix : str = "store_vectors" ,
305329 ) -> AsyncIterator [AsyncRedisStore ]:
306330 """Create store from Redis connection string."""
307- async with cls (redis_url = conn_string , index = index , ttl = ttl ) as store :
331+ async with cls (
332+ redis_url = conn_string ,
333+ index = index ,
334+ ttl = ttl ,
335+ store_prefix = store_prefix ,
336+ vector_prefix = vector_prefix ,
337+ ) as store :
308338 await store .setup ()
309339 # Set client information after setup
310340 await store .aset_client_info ()
@@ -460,7 +490,7 @@ async def _batch_get_ops(
460490 # Also add vector keys for the same document
461491 doc_uuid = doc_id .split (":" )[- 1 ]
462492 vector_key = (
463- f"{ STORE_VECTOR_PREFIX } { REDIS_KEY_SEPARATOR } { doc_uuid } "
493+ f"{ self . vector_prefix } { REDIS_KEY_SEPARATOR } { doc_uuid } "
464494 )
465495 refresh_keys_by_idx [idx ].append (vector_key )
466496
@@ -624,7 +654,9 @@ async def _batch_put_ops(
624654 doc_ids [(namespace , op .key )] = generated_doc_id
625655 # Track TTL for this document if specified
626656 if hasattr (op , "ttl" ) and op .ttl is not None :
627- main_key = f"{ STORE_PREFIX } { REDIS_KEY_SEPARATOR } { generated_doc_id } "
657+ main_key = (
658+ f"{ self .store_prefix } { REDIS_KEY_SEPARATOR } { generated_doc_id } "
659+ )
628660 ttl_tracking [main_key ] = ([], op .ttl )
629661
630662 # Load store docs with explicit keys
@@ -638,7 +670,7 @@ async def _batch_put_ops(
638670 doc .pop ("expires_at" , None )
639671
640672 store_docs .append (doc )
641- redis_key = f"{ STORE_PREFIX } { REDIS_KEY_SEPARATOR } { doc_id } "
673+ redis_key = f"{ self . store_prefix } { REDIS_KEY_SEPARATOR } { doc_id } "
642674 store_keys .append (redis_key )
643675
644676 if store_docs :
@@ -674,11 +706,11 @@ async def _batch_put_ops(
674706 "updated_at" : datetime .now (timezone .utc ).timestamp (),
675707 }
676708 )
677- redis_vector_key = f"{ STORE_VECTOR_PREFIX } { REDIS_KEY_SEPARATOR } { doc_id } "
709+ redis_vector_key = f"{ self . vector_prefix } { REDIS_KEY_SEPARATOR } { doc_id } "
678710 vector_keys .append (redis_vector_key )
679711
680712 # Add this vector key to the related keys list for TTL
681- main_key = f"{ STORE_PREFIX } { REDIS_KEY_SEPARATOR } { doc_id } "
713+ main_key = f"{ self . store_prefix } { REDIS_KEY_SEPARATOR } { doc_id } "
682714 if main_key in ttl_tracking :
683715 ttl_tracking [main_key ][0 ].append (redis_vector_key )
684716
@@ -740,7 +772,9 @@ async def _batch_search_ops(
740772 )
741773 if doc_id :
742774 doc_uuid = doc_id .split (":" )[1 ]
743- store_key = f"{ STORE_PREFIX } { REDIS_KEY_SEPARATOR } { doc_uuid } "
775+ store_key = (
776+ f"{ self .store_prefix } { REDIS_KEY_SEPARATOR } { doc_uuid } "
777+ )
744778 result_map [store_key ] = doc
745779 # Fetch individually in cluster mode
746780 store_doc_item = await self ._redis .json ().get (store_key ) # type: ignore
@@ -760,7 +794,9 @@ async def _batch_search_ops(
760794 )
761795 if doc_id :
762796 doc_uuid = doc_id .split (":" )[1 ]
763- store_key = f"{ STORE_PREFIX } { REDIS_KEY_SEPARATOR } { doc_uuid } "
797+ store_key = (
798+ f"{ self .store_prefix } { REDIS_KEY_SEPARATOR } { doc_uuid } "
799+ )
764800 result_map [store_key ] = doc
765801 pipeline .json ().get (store_key )
766802 store_docs_raw = await pipeline .execute ()
@@ -825,7 +861,7 @@ async def _batch_search_ops(
825861 # Also find associated vector keys with same ID
826862 doc_id = store_key .split (":" )[- 1 ]
827863 vector_key = (
828- f"{ STORE_VECTOR_PREFIX } { REDIS_KEY_SEPARATOR } { doc_id } "
864+ f"{ self . vector_prefix } { REDIS_KEY_SEPARATOR } { doc_id } "
829865 )
830866 refresh_keys .append (vector_key )
831867
@@ -897,7 +933,7 @@ async def _batch_search_ops(
897933 # Also find associated vector keys with same ID
898934 doc_id = doc .id .split (":" )[- 1 ]
899935 vector_key = (
900- f"{ STORE_VECTOR_PREFIX } { REDIS_KEY_SEPARATOR } { doc_id } "
936+ f"{ self . vector_prefix } { REDIS_KEY_SEPARATOR } { doc_id } "
901937 )
902938 refresh_keys .append (vector_key )
903939
0 commit comments