@@ -15,7 +15,6 @@ def _estimate_tokens(text: str) -> int:
1515def _format_memories_by_relevance (
1616 results : List [SearchResult ],
1717 max_tokens : int ,
18- recency_weight : float ,
1918) -> str :
2019 """Format memories ordered by relevance, respecting token budget."""
2120 if not results :
@@ -73,7 +72,7 @@ def assemble_default(
7372 """Default strategy: system_prompt + profile + memories ordered by relevance."""
7473 system_prompt = _get_system_prompt (character )
7574 profile = _format_profile (character )
76- memories = _format_memories_by_relevance (results , max_context_tokens , recency_weight )
75+ memories = _format_memories_by_relevance (results , max_context_tokens )
7776 config = _get_agent_config (character )
7877
7978 prompt_parts = []
@@ -107,13 +106,21 @@ def assemble_conversational(
107106 profile = _format_profile (character )
108107 config = _get_agent_config (character )
109108
110- # Boost recency by reordering: mix relevance with recency
109+ # Boost recency by reordering: blend relevance with position-based recency.
110+ # Results from the API are ordered by relevance; we treat earlier positions
111+ # as "more recent" and use the index as a recency proxy (0 = most recent).
112+ n = len (results ) if results else 1
111113 sorted_results = sorted (
112- results ,
113- key = lambda r : r .relevance_score * (1.0 - recency_weight ) + recency_weight ,
114+ enumerate (results ),
115+ key = lambda pair : (
116+ pair [1 ].relevance_score * (1.0 - recency_weight )
117+ + (1.0 - pair [0 ] / n ) * recency_weight
118+ ),
114119 reverse = True ,
115120 )
116- memories = _format_memories_by_relevance (sorted_results , max_context_tokens , recency_weight )
121+ memories = _format_memories_by_relevance (
122+ [r for _ , r in sorted_results ], max_context_tokens
123+ )
117124
118125 prompt_parts = []
119126 if system_prompt :
@@ -158,7 +165,7 @@ def assemble_task_focused(
158165 results ,
159166 key = lambda r : (0 if r .category .lower () in priority_categories else 1 , - r .relevance_score ),
160167 )
161- memories = _format_memories_by_relevance (prioritized , max_context_tokens , recency_weight )
168+ memories = _format_memories_by_relevance (prioritized , max_context_tokens )
162169
163170 prompt_parts = []
164171 if system_prompt :
@@ -205,7 +212,7 @@ def assemble_concierge(
205212 results ,
206213 key = lambda r : (0 if r .category .lower () in preference_categories else 1 , - r .relevance_score ),
207214 )
208- memories = _format_memories_by_relevance (prioritized , max_context_tokens , recency_weight )
215+ memories = _format_memories_by_relevance (prioritized , max_context_tokens )
209216
210217 prompt_parts = [
211218 system_prompt or "You are a thoughtful, proactive concierge." ,
@@ -244,7 +251,7 @@ def assemble_matching(
244251
245252 # Only include a handful of highest-relevance memories
246253 top_results = results [:3 ] if results else []
247- memories = _format_memories_by_relevance (top_results , max_context_tokens // 4 , recency_weight )
254+ memories = _format_memories_by_relevance (top_results , max_context_tokens // 4 )
248255
249256 prompt_parts = [
250257 system_prompt or "" ,
0 commit comments