13
13
from langchain_core .embeddings import Embeddings
14
14
from langchain_core .vectorstores import VectorStore
15
15
from langchain_redis .vectorstores import RedisVectorStore
16
+ from redisvl .query import RangeQuery , VectorQuery
16
17
17
18
from agent_memory_server .filters import (
18
19
CreatedAt ,
@@ -885,10 +886,6 @@ async def search_memories(
885
886
# If server-side recency is requested, attempt RedisVL query first (DB-level path)
886
887
if server_side_recency :
887
888
try :
888
- from datetime import UTC as _UTC , datetime as _dt
889
-
890
- from redisvl .query import AggregateQuery , RangeQuery , VectorQuery
891
-
892
889
index = getattr (self .vectorstore , "_index" , None )
893
890
if index is not None :
894
891
# Embed the query text to vector
@@ -911,73 +908,24 @@ async def search_memories(
911
908
k = limit ,
912
909
)
913
910
914
- # Aggregate with APPLY/SORTBY boosted score
915
- agg = AggregateQuery (knn .query , filter_expression = redis_filter )
916
- agg .load (
917
- [
918
- "id_" ,
919
- "session_id" ,
920
- "user_id" ,
921
- "namespace" ,
922
- "created_at" ,
923
- "last_accessed" ,
924
- "updated_at" ,
925
- "pinned" ,
926
- "access_count" ,
927
- "topics" ,
928
- "entities" ,
929
- "memory_hash" ,
930
- "discrete_memory_extracted" ,
931
- "memory_type" ,
932
- "persisted_at" ,
933
- "extracted_from" ,
934
- "event_date" ,
935
- "text" ,
936
- "__vector_score" ,
937
- ]
911
+ # Aggregate with APPLY/SORTBY boosted score via helper
912
+ from datetime import UTC as _UTC , datetime as _dt
913
+
914
+ from agent_memory_server .utils .redis_query import (
915
+ RecencyAggregationQuery ,
938
916
)
939
917
940
918
now_ts = int (_dt .now (_UTC ).timestamp ())
941
- w_sem = (
942
- float (recency_params .get ("w_sem" , 0.8 ))
943
- if recency_params
944
- else 0.8
945
- )
946
- w_rec = (
947
- float (recency_params .get ("w_recency" , 0.2 ))
948
- if recency_params
949
- else 0.2
950
- )
951
- wf = float (recency_params .get ("wf" , 0.6 )) if recency_params else 0.6
952
- wa = float (recency_params .get ("wa" , 0.4 )) if recency_params else 0.4
953
- hl_la = (
954
- float (recency_params .get ("half_life_last_access_days" , 7.0 ))
955
- if recency_params
956
- else 7.0
957
- )
958
- hl_cr = (
959
- float (recency_params .get ("half_life_created_days" , 30.0 ))
960
- if recency_params
961
- else 30.0
919
+ agg = (
920
+ RecencyAggregationQuery .from_vector_query (
921
+ knn , filter_expression = redis_filter
922
+ )
923
+ .load_default_fields ()
924
+ .apply_recency (now_ts = now_ts , params = recency_params or {})
925
+ .sort_by_boosted_desc ()
926
+ .paginate (offset , limit )
962
927
)
963
928
964
- agg .apply (
965
- f"max(0, ({ now_ts } - @last_accessed)/86400.0)" ,
966
- AS = "days_since_access" ,
967
- ).apply (
968
- f"max(0, ({ now_ts } - @created_at)/86400.0)" ,
969
- AS = "days_since_created" ,
970
- ).apply (
971
- f"pow(2, -@days_since_access/{ hl_la } )" , AS = "freshness"
972
- ).apply (
973
- f"pow(2, -@days_since_created/{ hl_cr } )" , AS = "novelty"
974
- ).apply (f"{ wf } *@freshness+{ wa } *@novelty" , AS = "recency" ).apply (
975
- "1-(@__vector_score/2)" , AS = "sim"
976
- ).apply (f"{ w_sem } *@sim+{ w_rec } *@recency" , AS = "boosted_score" )
977
-
978
- agg .sort_by ([("boosted_score" , "DESC" )])
979
- agg .limit (offset , limit )
980
-
981
929
raw = (
982
930
await index .aaggregate (agg )
983
931
if hasattr (index , "aaggregate" )
0 commit comments