reme-ai 0.1.4__py3-none-any.whl → 0.1.7__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. reme_ai/__init__.py +1 -1
  2. reme_ai/app.py +1 -1
  3. reme_ai/config/default.yaml +40 -5
  4. reme_ai/react/simple_react_op.py +11 -8
  5. reme_ai/retrieve/personal/extract_time_op.py +2 -3
  6. reme_ai/retrieve/personal/fuse_rerank_op.py +1 -1
  7. reme_ai/retrieve/personal/print_memory_op.py +1 -1
  8. reme_ai/retrieve/personal/read_message_op.py +1 -1
  9. reme_ai/retrieve/personal/retrieve_memory_op.py +34 -4
  10. reme_ai/retrieve/personal/semantic_rank_op.py +4 -4
  11. reme_ai/retrieve/personal/set_query_op.py +1 -1
  12. reme_ai/retrieve/task/build_query_op.py +2 -2
  13. reme_ai/retrieve/task/merge_memory_op.py +1 -1
  14. reme_ai/retrieve/task/rerank_memory_op.py +4 -4
  15. reme_ai/retrieve/task/rewrite_memory_op.py +6 -6
  16. reme_ai/service/__init__.py +0 -0
  17. reme_ai/service/base_memory_service.py +112 -0
  18. reme_ai/service/personal_memory_service.py +128 -0
  19. reme_ai/service/task_memory_service.py +126 -0
  20. reme_ai/summary/personal/contra_repeat_op.py +2 -2
  21. reme_ai/summary/personal/get_observation_op.py +4 -4
  22. reme_ai/summary/personal/get_observation_with_time_op.py +4 -4
  23. reme_ai/summary/personal/get_reflection_subject_op.py +4 -4
  24. reme_ai/summary/personal/info_filter_op.py +4 -4
  25. reme_ai/summary/personal/load_today_memory_op.py +6 -7
  26. reme_ai/summary/personal/long_contra_repeat_op.py +4 -4
  27. reme_ai/summary/personal/update_insight_op.py +4 -4
  28. reme_ai/summary/task/comparative_extraction_op.py +9 -7
  29. reme_ai/summary/task/failure_extraction_op.py +7 -5
  30. reme_ai/summary/task/memory_deduplication_op.py +6 -6
  31. reme_ai/summary/task/memory_validation_op.py +8 -6
  32. reme_ai/summary/task/simple_comparative_summary_op.py +6 -4
  33. reme_ai/summary/task/simple_summary_op.py +6 -4
  34. reme_ai/summary/task/success_extraction_op.py +7 -5
  35. reme_ai/summary/task/trajectory_preprocess_op.py +1 -1
  36. reme_ai/summary/task/trajectory_segmentation_op.py +6 -4
  37. reme_ai/vector_store/delete_memory_op.py +1 -1
  38. reme_ai/vector_store/recall_vector_store_op.py +3 -3
  39. reme_ai/vector_store/update_memory_freq_op.py +1 -1
  40. reme_ai/vector_store/update_memory_utility_op.py +1 -1
  41. reme_ai/vector_store/update_vector_store_op.py +3 -3
  42. reme_ai/vector_store/vector_store_action_op.py +21 -18
  43. {reme_ai-0.1.4.dist-info → reme_ai-0.1.7.dist-info}/METADATA +8 -6
  44. reme_ai-0.1.7.dist-info/RECORD +87 -0
  45. reme_ai-0.1.4.dist-info/RECORD +0 -83
  46. {reme_ai-0.1.4.dist-info → reme_ai-0.1.7.dist-info}/WHEEL +0 -0
  47. {reme_ai-0.1.4.dist-info → reme_ai-0.1.7.dist-info}/entry_points.txt +0 -0
  48. {reme_ai-0.1.4.dist-info → reme_ai-0.1.7.dist-info}/licenses/LICENSE +0 -0
  49. {reme_ai-0.1.4.dist-info → reme_ai-0.1.7.dist-info}/top_level.txt +0 -0
reme_ai/__init__.py CHANGED
@@ -3,4 +3,4 @@ from reme_ai import retrieve
3
3
  from reme_ai import summary
4
4
  from reme_ai import vector_store
5
5
 
6
- __version__ = "0.1.4"
6
+ __version__ = "0.1.7"
reme_ai/app.py CHANGED
@@ -7,7 +7,7 @@ from reme_ai.config.config_parser import ConfigParser
7
7
 
8
8
  def main():
9
9
  with BaseService.get_service(*sys.argv[1:], parser=ConfigParser) as service:
10
- service()
10
+ service(logo="ReMe")
11
11
 
12
12
 
13
13
  if __name__ == "__main__":
@@ -1,4 +1,3 @@
1
- # default config.yaml
2
1
  backend: http
3
2
  language: ""
4
3
  thread_pool_max_workers: 32
@@ -18,6 +17,9 @@ http:
18
17
  flow:
19
18
  retrieve_task_memory:
20
19
  flow_content: build_query_op >> recall_vector_store_op >> rerank_memory_op >> rewrite_memory_op
20
+ stream: false
21
+ use_async: true
22
+ service_type: http+mcp
21
23
  description: "Retrieves the most relevant top-k memory experiences from historical data based on the current query to enhance task-solving capabilities"
22
24
  input_schema:
23
25
  query:
@@ -27,6 +29,9 @@ flow:
27
29
 
28
30
  summary_task_memory:
29
31
  flow_content: trajectory_preprocess_op >> (success_extraction_op|failure_extraction_op|comparative_extraction_op) >> memory_validation_op >> update_vector_store_op
32
+ stream: false
33
+ use_async: true
34
+ service_type: http+mcp
30
35
  description: "Summarizes conversation trajectories or messages into structured memory representations for long-term storage"
31
36
  input_schema:
32
37
  trajectories:
@@ -36,6 +41,9 @@ flow:
36
41
 
37
42
  retrieve_personal_memory:
38
43
  flow_content: set_query_op >> (extract_time_op | (retrieve_memory_op >> semantic_rank_op)) >> fuse_rerank_op
44
+ stream: false
45
+ use_async: true
46
+ service_type: http+mcp
39
47
  description: "Retrieves the most relevant personal memories from historical data based on the query to enhance response quality"
40
48
  input_schema:
41
49
  query:
@@ -45,6 +53,9 @@ flow:
45
53
 
46
54
  summary_personal_memory:
47
55
  flow_content: info_filter_op >> (get_observation_op | get_observation_with_time_op | load_today_memory_op) >> contra_repeat_op >> update_vector_store_op
56
+ stream: false
57
+ use_async: true
58
+ service_type: http+mcp
48
59
  description: "Consolidates user observations and memories by filtering information and removing redundancies for efficient storage"
49
60
  input_schema:
50
61
  trajectories:
@@ -54,6 +65,9 @@ flow:
54
65
 
55
66
  retrieve_task_memory_simple:
56
67
  flow_content: build_query_op >> recall_vector_store_op >> merge_memory_op
68
+ stream: false
69
+ use_async: true
70
+ service_type: http+mcp
57
71
  description: "Retrieves the most relevant top-k memory experiences from historical data based on the current query with simplified processing"
58
72
  input_schema:
59
73
  query:
@@ -63,6 +77,9 @@ flow:
63
77
 
64
78
  summary_task_memory_simple:
65
79
  flow_content: simple_summary_op >> update_vector_store_op
80
+ stream: false
81
+ use_async: true
82
+ service_type: http+mcp
66
83
  description: "Summarizes conversation trajectories or messages into memories using a simplified approach"
67
84
  input_schema:
68
85
  trajectories:
@@ -72,16 +89,22 @@ flow:
72
89
 
73
90
  vector_store:
74
91
  flow_content: vector_store_action_op
92
+ stream: false
93
+ use_async: true
94
+ service_type: http+mcp
75
95
  description: "Directly operates on the vector store with various management actions"
76
96
  input_schema:
77
97
  action:
78
98
  type: "str"
79
99
  description: "vector store operations"
80
100
  required: true
81
- enum: [ copy, delete, delete_ids, dump, load ]
101
+ enum: [ copy, delete, delete_ids, dump, load, list]
82
102
 
83
103
  record_task_memory:
84
104
  flow_content: update_memory_freq_op >> update_memory_utility_op >> update_vector_store_op
105
+ stream: false
106
+ use_async: true
107
+ service_type: http+mcp
85
108
  description: "Update the freq & utility attributes of retrieved task memories"
86
109
  input_schema:
87
110
  workspace_id:
@@ -99,6 +122,9 @@ flow:
99
122
 
100
123
  delete_task_memory:
101
124
  flow_content: delete_memory_op >> update_vector_store_op
125
+ stream: false
126
+ use_async: true
127
+ service_type: http+mcp
102
128
  description: "Delete task memories when utility/freq < utility_threshold and freq >= freq_threshold"
103
129
  input_schema:
104
130
  workspace_id:
@@ -116,6 +142,9 @@ flow:
116
142
 
117
143
  react:
118
144
  flow_content: simple_react_op
145
+ stream: false
146
+ use_async: true
147
+ service_type: http+mcp
119
148
  description: "React to the current task with an agent"
120
149
  input_schema:
121
150
  query:
@@ -142,11 +171,18 @@ op:
142
171
  llm:
143
172
  default:
144
173
  backend: openai_compatible
145
- # model_name: qwen3-30b-a3b-thinking-2507
146
174
  model_name: qwen3-30b-a3b-instruct-2507
147
175
  params:
148
176
  temperature: 0.6
149
177
 
178
+ qwen3_30b_instruct:
179
+ backend: openai_compatible
180
+ model_name: qwen3-30b-a3b-instruct-2507
181
+
182
+ qwen3_30b_thinking:
183
+ backend: openai_compatible
184
+ model_name: qwen3-30b-a3b-thinking-2507
185
+
150
186
  embedding_model:
151
187
  default:
152
188
  backend: openai_compatible
@@ -156,8 +192,7 @@ embedding_model:
156
192
 
157
193
  vector_store:
158
194
  default:
159
- backend: elasticsearch
195
+ backend: memory
160
196
  embedding_model: default
161
197
  # params:
162
198
  # hosts: "http://localhost:9200"
163
- # hosts: "http://11.160.132.46:8200"
@@ -1,21 +1,24 @@
1
+ import asyncio
2
+
1
3
  from flowllm import C
2
4
  from flowllm.context.flow_context import FlowContext
3
- from flowllm.op.agent.react_v2_op import ReactV2Op
5
+ from flowllm.op.llm.react_llm_op import ReactLLMOp
4
6
 
5
7
 
6
8
  @C.register_op()
7
- class SimpleReactOp(ReactV2Op):
9
+ class SimpleReactOp(ReactLLMOp):
8
10
  ...
9
11
 
10
12
 
11
- if __name__ == "__main__":
13
+ async def main():
12
14
  from reme_ai.config.config_parser import ConfigParser
13
15
 
14
- C.set_default_service_config(parser=ConfigParser).init_by_service_config()
16
+ C.set_service_config(parser=ConfigParser, config_name="config=default").init_by_service_config()
15
17
  context = FlowContext(query="茅台和五粮现在股价多少?")
16
18
 
17
19
  op = SimpleReactOp()
18
- op(context=context)
19
- # from reme_ai.schema import Message
20
- # result = op.llm.chat(messages=[Message(**{"role": "user", "content": "你叫什么名字?"})])
21
- # print("!!!", result)
20
+ await op.async_call(context=context)
21
+ print(context.response.answer)
22
+
23
+ if __name__ == "__main__":
24
+ asyncio.run(main())
@@ -23,10 +23,9 @@ class ExtractTimeOp(BaseLLMOp):
23
23
  """
24
24
 
25
25
  def get_language_value(self, value_dict: dict):
26
-
27
26
  return value_dict.get(self.language, value_dict.get("en"))
28
27
 
29
- def execute(self):
28
+ async def async_execute(self):
30
29
  """
31
30
  Executes the primary logic of identifying and extracting time data from an LLM's response.
32
31
 
@@ -59,7 +58,7 @@ class ExtractTimeOp(BaseLLMOp):
59
58
  logger.info(f"Extracting time from query: {query[:100]}...")
60
59
 
61
60
  # Invoke the LLM to generate a response
62
- response = self.llm.chat([Message(role=Role.USER, content=full_prompt)])
61
+ response = await self.llm.achat([Message(role=Role.USER, content=full_prompt)])
63
62
 
64
63
  # Handle empty or unsuccessful responses
65
64
  if not response or not response.content:
@@ -45,7 +45,7 @@ class FuseRerankOp(BaseLLMOp):
45
45
  memory.metadata["match_msg_flag"] = str(int(match_msg_flag))
46
46
  return match_event_flag, match_msg_flag
47
47
 
48
- def execute(self):
48
+ async def async_execute(self):
49
49
  """
50
50
  Executes the reranking process on memories considering their scores, types, and temporal relevance.
51
51
 
@@ -13,7 +13,7 @@ class PrintMemoryOp(BaseOp):
13
13
  """
14
14
  file_path: str = __file__
15
15
 
16
- def execute(self):
16
+ async def async_execute(self):
17
17
  """
18
18
  Executes the primary function, it involves:
19
19
  1. Fetches the memories.
@@ -12,7 +12,7 @@ class ReadMessageOp(BaseOp):
12
12
  """
13
13
  file_path: str = __file__
14
14
 
15
- def execute(self):
15
+ async def async_execute(self):
16
16
  """
17
17
  Executes the primary function to fetch unmemorized chat messages.
18
18
  """
@@ -1,13 +1,43 @@
1
- from flowllm import C
1
+ from typing import List
2
2
 
3
- from reme_ai.vector_store import RecallVectorStoreOp
3
+ from flowllm import C, BaseLLMOp
4
+ from flowllm.schema.vector_node import VectorNode
5
+ from loguru import logger
6
+
7
+ from reme_ai.schema.memory import BaseMemory, vector_node_to_memory
4
8
 
5
9
 
6
10
  @C.register_op()
7
- class RetrieveMemoryOp(RecallVectorStoreOp):
11
+ class RetrieveMemoryOp(BaseLLMOp):
8
12
  """
9
13
  Retrieves memories based on specified criteria such as status, type, and timestamp.
10
14
  Processes these memories concurrently, sorts them by similarity, and logs the activity,
11
15
  facilitating efficient memory retrieval operations within a given scope.
12
16
  """
13
- file_path: str = __file__
17
+
18
+ async def async_execute(self):
19
+ recall_key: str = self.op_params.get("recall_key", "query")
20
+ top_k: int = self.context.get("top_k", 3)
21
+
22
+ query: str = self.context[recall_key]
23
+ assert query, "query should be not empty!"
24
+
25
+ workspace_id: str = self.context.workspace_id
26
+ nodes: List[VectorNode] = await self.vector_store.async_search(query=query,
27
+ workspace_id=workspace_id,
28
+ top_k=top_k)
29
+ memory_list: List[BaseMemory] = []
30
+ memory_content_list: List[str] = []
31
+ for node in nodes:
32
+ memory: BaseMemory = vector_node_to_memory(node)
33
+ if memory.content not in memory_content_list:
34
+ memory_list.append(memory)
35
+ memory_content_list.append(memory.content)
36
+ logger.info(f"retrieve memory.size={len(memory_list)}")
37
+
38
+ threshold_score: float | None = self.op_params.get("threshold_score", None)
39
+ if threshold_score is not None:
40
+ memory_list = [mem for mem in memory_list if mem.score >= threshold_score or mem.score is None]
41
+ logger.info(f"after filter by threshold_score size={len(memory_list)}")
42
+
43
+ self.context.response.metadata["memory_list"] = memory_list
@@ -19,7 +19,7 @@ class SemanticRankOp(BaseLLMOp):
19
19
  """
20
20
  file_path: str = __file__
21
21
 
22
- def execute(self):
22
+ async def async_execute(self):
23
23
  """
24
24
  Executes the primary workflow of the SemanticRankOp which includes:
25
25
  - Retrieves query and memory list from context.
@@ -56,7 +56,7 @@ class SemanticRankOp(BaseLLMOp):
56
56
  logger.info(f"After deduplication: {len(memory_list)} memories")
57
57
 
58
58
  # Perform semantic ranking using LLM
59
- ranked_memories = self._semantic_rank_memories(query, memory_list)
59
+ ranked_memories = await self._semantic_rank_memories(query, memory_list)
60
60
  if ranked_memories:
61
61
  memory_list = ranked_memories
62
62
 
@@ -71,7 +71,7 @@ class SemanticRankOp(BaseLLMOp):
71
71
  # Save ranked memories back to context
72
72
  self.context.response.metadata["memory_list"] = memory_list
73
73
 
74
- def _semantic_rank_memories(self, query: str, memories: List[BaseMemory]) -> List[BaseMemory]:
74
+ async def _semantic_rank_memories(self, query: str, memories: List[BaseMemory]) -> List[BaseMemory]:
75
75
  """
76
76
  Use LLM to semantically rank memories based on relevance to the query
77
77
  """
@@ -93,7 +93,7 @@ Memories:
93
93
  Please respond in JSON format:
94
94
  {{"rankings": [{{"index": 0, "score": 0.8}}, {{"index": 1, "score": 0.6}}, ...]}}"""
95
95
 
96
- response = self.llm.chat([Message(role=Role.USER, content=prompt)])
96
+ response = await self.llm.achat([Message(role=Role.USER, content=prompt)])
97
97
 
98
98
  if not response or not response.content:
99
99
  logger.warning("LLM ranking failed, using original order")
@@ -14,7 +14,7 @@ class SetQueryOp(BaseOp):
14
14
  into the context, utilizing either provided parameters or details from the context.
15
15
  """
16
16
 
17
- def execute(self):
17
+ async def async_execute(self):
18
18
  """
19
19
  Executes the operation's primary function, which involves determining the query and its
20
20
  timestamp, then storing these values within the context.
@@ -9,7 +9,7 @@ from reme_ai.schema import Message, Role
9
9
  class BuildQueryOp(BaseLLMOp):
10
10
  file_path: str = __file__
11
11
 
12
- def execute(self):
12
+ async def async_execute(self):
13
13
  if "query" in self.context:
14
14
  query = self.context.query
15
15
 
@@ -17,7 +17,7 @@ class BuildQueryOp(BaseLLMOp):
17
17
  if self.op_params.get("enable_llm_build", True):
18
18
  execution_process = merge_messages_content(self.context.messages)
19
19
  prompt = self.prompt_format(prompt_name="query_build", execution_process=execution_process)
20
- message = self.llm.chat(messages=[Message(role=Role.USER, content=prompt)])
20
+ message = await self.llm.achat(messages=[Message(role=Role.USER, content=prompt)])
21
21
  query = message.content
22
22
 
23
23
  else:
@@ -9,7 +9,7 @@ from reme_ai.schema.memory import BaseMemory
9
9
  @C.register_op()
10
10
  class MergeMemoryOp(BaseOp):
11
11
 
12
- def execute(self):
12
+ async def async_execute(self):
13
13
  memory_list: List[BaseMemory] = self.context.response.metadata["memory_list"]
14
14
 
15
15
  if not memory_list:
@@ -17,7 +17,7 @@ class RerankMemoryOp(BaseLLMOp):
17
17
  """
18
18
  file_path: str = __file__
19
19
 
20
- def execute(self):
20
+ async def async_execute(self):
21
21
  """Execute rerank operation"""
22
22
  memory_list: List[BaseMemory] = self.context.response.metadata["memory_list"]
23
23
  retrieval_query: str = self.context.query
@@ -36,7 +36,7 @@ class RerankMemoryOp(BaseLLMOp):
36
36
 
37
37
  # Step 1: LLM reranking (optional)
38
38
  if enable_llm_rerank:
39
- memory_list = self._llm_rerank(retrieval_query, memory_list)
39
+ memory_list = await self._llm_rerank(retrieval_query, memory_list)
40
40
  logger.info(f"After LLM reranking: {len(memory_list)} memories")
41
41
 
42
42
  # Step 2: Score-based filtering (optional)
@@ -51,7 +51,7 @@ class RerankMemoryOp(BaseLLMOp):
51
51
  # Store results in context
52
52
  self.context.response.metadata["memory_list"] = reranked_memories
53
53
 
54
- def _llm_rerank(self, query: str, candidates: List[BaseMemory]) -> List[BaseMemory]:
54
+ async def _llm_rerank(self, query: str, candidates: List[BaseMemory]) -> List[BaseMemory]:
55
55
  """LLM-based reranking of candidate experiences"""
56
56
  if not candidates:
57
57
  return candidates
@@ -65,7 +65,7 @@ class RerankMemoryOp(BaseLLMOp):
65
65
  candidates=candidates_text,
66
66
  num_candidates=len(candidates))
67
67
 
68
- response = self.llm.chat([Message(role=Role.USER, content=prompt)])
68
+ response = await self.llm.achat([Message(role=Role.USER, content=prompt)])
69
69
 
70
70
  # Parse reranking results
71
71
  reranked_indices = self._parse_rerank_response(response.content)
@@ -17,7 +17,7 @@ class RewriteMemoryOp(BaseLLMOp):
17
17
  """
18
18
  file_path: str = __file__
19
19
 
20
- def execute(self):
20
+ async def async_execute(self):
21
21
  """Execute rewrite operation"""
22
22
  memory_list: List[BaseMemory] = self.context.response.metadata["memory_list"]
23
23
  query: str = self.context.query
@@ -32,13 +32,13 @@ class RewriteMemoryOp(BaseLLMOp):
32
32
  logger.info(f"Generating context from {len(memory_list)} memories")
33
33
 
34
34
  # Generate initial context message
35
- rewritten_memory = self._generate_context_message(query, messages, memory_list)
35
+ rewritten_memory = await self._generate_context_message(query, messages, memory_list)
36
36
 
37
37
  # Store results in context
38
38
  self.context.response.answer = rewritten_memory
39
39
  self.context.response.metadata["memory_list"] = [memory.model_dump() for memory in memory_list]
40
40
 
41
- def _generate_context_message(self, query: str, messages: List[Message], memories: List[BaseMemory]) -> str:
41
+ async def _generate_context_message(self, query: str, messages: List[Message], memories: List[BaseMemory]) -> str:
42
42
  """Generate context message from retrieved memories"""
43
43
  if not memories:
44
44
  return ""
@@ -49,7 +49,7 @@ class RewriteMemoryOp(BaseLLMOp):
49
49
  formatted_memories = self._format_memories_for_context(memories)
50
50
 
51
51
  if self.op_params.get("enable_llm_rewrite", True):
52
- context_content = self._rewrite_context(query, formatted_memories, messages)
52
+ context_content = await self._rewrite_context(query, formatted_memories, messages)
53
53
  else:
54
54
  context_content = formatted_memories
55
55
 
@@ -59,7 +59,7 @@ class RewriteMemoryOp(BaseLLMOp):
59
59
  logger.error(f"Error generating context message: {e}")
60
60
  return self._format_memories_for_context(memories)
61
61
 
62
- def _rewrite_context(self, query: str, context_content: str, messages: List[Message]) -> str:
62
+ async def _rewrite_context(self, query: str, context_content: str, messages: List[Message]) -> str:
63
63
  """LLM-based context rewriting to make experiences more relevant and actionable"""
64
64
  if not context_content:
65
65
  return context_content
@@ -74,7 +74,7 @@ class RewriteMemoryOp(BaseLLMOp):
74
74
  current_context=current_context,
75
75
  original_context=context_content)
76
76
 
77
- response = self.llm.chat([Message(role=Role.USER, content=prompt)])
77
+ response = await self.llm.achat([Message(role=Role.USER, content=prompt)])
78
78
 
79
79
  # Extract rewritten context
80
80
  rewritten_context = self._parse_json_response(response.content, "rewritten_context")
File without changes
@@ -0,0 +1,112 @@
1
+ from abc import abstractmethod, ABC
2
+ from typing import Optional, Dict, Any
3
+
4
+ from pydantic import Field
5
+
6
+
7
+ class BaseMemoryService(ABC):
8
+
9
+ def __init__(self):
10
+ self.session_id_dict: dict = {}
11
+
12
+ def add_session_memory_id(self, session_id: str, memory_id):
13
+ if session_id not in self.session_id_dict:
14
+ self.session_id_dict[session_id] = []
15
+
16
+ self.session_id_dict[session_id].append(memory_id)
17
+
18
+ @abstractmethod
19
+ async def start(self) -> None:
20
+ """Starts the service, initializing any necessary resources or
21
+ connections."""
22
+
23
+ @abstractmethod
24
+ async def stop(self) -> None:
25
+ """Stops the service, releasing any acquired resources."""
26
+
27
+ @abstractmethod
28
+ async def health(self) -> bool:
29
+ """
30
+ Checks the health of the service.
31
+
32
+ Returns:
33
+ True if the service is healthy, False otherwise.
34
+ """
35
+
36
+ async def __aenter__(self):
37
+ """Async context manager entry."""
38
+ await self.start()
39
+ return self
40
+
41
+ async def __aexit__(self, exc_type, exc_val, exc_tb):
42
+ """Async context manager exit."""
43
+ await self.stop()
44
+ return False
45
+
46
+ @abstractmethod
47
+ async def add_memory(
48
+ self,
49
+ user_id: str,
50
+ messages: list,
51
+ session_id: Optional[str] = None,
52
+ ) -> None:
53
+ """
54
+ Adds messages to the memory service.
55
+
56
+ Args:
57
+ user_id: The user id.
58
+ messages: The messages to add.
59
+ session_id: The session id, which is optional.
60
+ """
61
+
62
+ @abstractmethod
63
+ async def search_memory(
64
+ self,
65
+ user_id: str,
66
+ messages: list,
67
+ filters: Optional[Dict[str, Any]] = Field(
68
+ description="Associated filters for the messages, "
69
+ "such as top_k, score etc.",
70
+ default=None,
71
+ ),
72
+ ) -> list:
73
+ """
74
+ Searches messages from the memory service.
75
+
76
+ Args:
77
+ user_id: The user id.
78
+ messages: The user query or the query with history messages,
79
+ both in the format of list of messages. If messages is a list,
80
+ the search will be based on the content of the last message.
81
+ filters: The filters used to search memory
82
+ """
83
+
84
+ @abstractmethod
85
+ async def list_memory(
86
+ self,
87
+ user_id: str,
88
+ filters: Optional[Dict[str, Any]] = Field(
89
+ description="Associated filters for the messages, "
90
+ "such as top_k, score etc.",
91
+ default=None,
92
+ ),
93
+ ) -> list:
94
+ """
95
+ Lists the memory items for a given user with filters, such as
96
+ page_num, page_size, etc.
97
+
98
+ Args:
99
+ user_id: The user id.
100
+ filters: The filters for the memory items.
101
+ """
102
+
103
+ @abstractmethod
104
+ async def delete_memory(
105
+ self,
106
+ user_id: str,
107
+ session_id: Optional[str] = None,
108
+ ) -> None:
109
+ """
110
+ Deletes the memory items for a given user with certain session id,
111
+ or all the memory items for a given user.
112
+ """