reme-ai 0.1.3__py3-none-any.whl → 0.1.5__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.
- reme_ai/__init__.py +1 -1
- reme_ai/app.py +1 -1
- reme_ai/config/default.yaml +56 -5
- reme_ai/constants/common_constants.py +0 -2
- reme_ai/constants/language_constants.py +1 -1
- reme_ai/enumeration/language_enum.py +14 -0
- reme_ai/react/simple_react_op.py +11 -8
- reme_ai/retrieve/personal/extract_time_op.py +2 -3
- reme_ai/retrieve/personal/fuse_rerank_op.py +1 -1
- reme_ai/retrieve/personal/print_memory_op.py +1 -1
- reme_ai/retrieve/personal/read_message_op.py +1 -1
- reme_ai/retrieve/personal/retrieve_memory_op.py +34 -4
- reme_ai/retrieve/personal/semantic_rank_op.py +4 -4
- reme_ai/retrieve/personal/set_query_op.py +1 -1
- reme_ai/retrieve/task/build_query_op.py +2 -2
- reme_ai/retrieve/task/merge_memory_op.py +1 -1
- reme_ai/retrieve/task/rerank_memory_op.py +4 -4
- reme_ai/retrieve/task/rewrite_memory_op.py +6 -6
- reme_ai/service/__init__.py +0 -0
- reme_ai/service/base_memory_service.py +112 -0
- reme_ai/service/personal_memory_service.py +128 -0
- reme_ai/service/task_memory_service.py +126 -0
- reme_ai/summary/personal/contra_repeat_op.py +2 -2
- reme_ai/summary/personal/get_observation_op.py +4 -4
- reme_ai/summary/personal/get_observation_with_time_op.py +4 -4
- reme_ai/summary/personal/get_reflection_subject_op.py +4 -4
- reme_ai/summary/personal/info_filter_op.py +4 -4
- reme_ai/summary/personal/load_today_memory_op.py +6 -7
- reme_ai/summary/personal/long_contra_repeat_op.py +4 -4
- reme_ai/summary/personal/update_insight_op.py +4 -4
- reme_ai/summary/task/__init__.py +0 -1
- reme_ai/summary/task/comparative_extraction_op.py +9 -7
- reme_ai/summary/task/failure_extraction_op.py +7 -5
- reme_ai/summary/task/memory_deduplication_op.py +6 -6
- reme_ai/summary/task/memory_validation_op.py +8 -6
- reme_ai/summary/task/simple_comparative_summary_op.py +6 -4
- reme_ai/summary/task/simple_summary_op.py +6 -4
- reme_ai/summary/task/success_extraction_op.py +7 -5
- reme_ai/summary/task/trajectory_preprocess_op.py +3 -32
- reme_ai/summary/task/trajectory_segmentation_op.py +6 -4
- reme_ai/utils/datetime_handler.py +1 -1
- reme_ai/vector_store/delete_memory_op.py +1 -1
- reme_ai/vector_store/recall_vector_store_op.py +3 -3
- reme_ai/vector_store/update_memory_freq_op.py +1 -1
- reme_ai/vector_store/update_memory_utility_op.py +1 -1
- reme_ai/vector_store/update_vector_store_op.py +3 -3
- reme_ai/vector_store/vector_store_action_op.py +21 -18
- {reme_ai-0.1.3.dist-info → reme_ai-0.1.5.dist-info}/METADATA +298 -133
- reme_ai-0.1.5.dist-info/RECORD +87 -0
- reme_ai/enumeration/language_constants.py +0 -215
- reme_ai/summary/task/pdf_preprocess_op_wrapper.py +0 -50
- reme_ai/utils/miner_u_pdf_processor.py +0 -726
- reme_ai-0.1.3.dist-info/RECORD +0 -85
- {reme_ai-0.1.3.dist-info → reme_ai-0.1.5.dist-info}/WHEEL +0 -0
- {reme_ai-0.1.3.dist-info → reme_ai-0.1.5.dist-info}/entry_points.txt +0 -0
- {reme_ai-0.1.3.dist-info → reme_ai-0.1.5.dist-info}/licenses/LICENSE +0 -0
- {reme_ai-0.1.3.dist-info → reme_ai-0.1.5.dist-info}/top_level.txt +0 -0
@@ -10,7 +10,7 @@ from reme_ai.schema.memory import BaseMemory
|
|
10
10
|
class MemoryDeduplicationOp(BaseOp):
|
11
11
|
file_path: str = __file__
|
12
12
|
|
13
|
-
def
|
13
|
+
async def async_execute(self):
|
14
14
|
"""Remove duplicate task memories"""
|
15
15
|
# Get task memories to deduplicate
|
16
16
|
task_memories: List[BaseMemory] = self.context.memory_list
|
@@ -22,7 +22,7 @@ class MemoryDeduplicationOp(BaseOp):
|
|
22
22
|
logger.info(f"Starting deduplication for {len(task_memories)} task memories")
|
23
23
|
|
24
24
|
# Perform deduplication
|
25
|
-
deduplicated_task_memories = self._deduplicate_task_memories(task_memories)
|
25
|
+
deduplicated_task_memories = await self._deduplicate_task_memories(task_memories)
|
26
26
|
|
27
27
|
logger.info(
|
28
28
|
f"Deduplication complete: {len(deduplicated_task_memories)} deduplicated task memories out of {len(task_memories)}")
|
@@ -30,7 +30,7 @@ class MemoryDeduplicationOp(BaseOp):
|
|
30
30
|
# Update context
|
31
31
|
self.context.memory_list = deduplicated_task_memories
|
32
32
|
|
33
|
-
def _deduplicate_task_memories(self, task_memories: List[BaseMemory]) -> List[BaseMemory]:
|
33
|
+
async def _deduplicate_task_memories(self, task_memories: List[BaseMemory]) -> List[BaseMemory]:
|
34
34
|
"""Remove duplicate task memories"""
|
35
35
|
if not task_memories:
|
36
36
|
return task_memories
|
@@ -41,7 +41,7 @@ class MemoryDeduplicationOp(BaseOp):
|
|
41
41
|
unique_task_memories = []
|
42
42
|
|
43
43
|
# Get existing task memory embeddings
|
44
|
-
existing_embeddings = self._get_existing_task_memory_embeddings(workspace_id)
|
44
|
+
existing_embeddings = await self._get_existing_task_memory_embeddings(workspace_id)
|
45
45
|
|
46
46
|
for task_memory in task_memories:
|
47
47
|
# Generate embedding for current task memory
|
@@ -67,14 +67,14 @@ class MemoryDeduplicationOp(BaseOp):
|
|
67
67
|
|
68
68
|
return unique_task_memories
|
69
69
|
|
70
|
-
def _get_existing_task_memory_embeddings(self, workspace_id: str) -> List[List[float]]:
|
70
|
+
async def _get_existing_task_memory_embeddings(self, workspace_id: str) -> List[List[float]]:
|
71
71
|
"""Get embeddings of existing task memories"""
|
72
72
|
try:
|
73
73
|
if not hasattr(self.context, 'vector_store') or not self.context.vector_store or not workspace_id:
|
74
74
|
return []
|
75
75
|
|
76
76
|
# Query existing task memory nodes
|
77
|
-
existing_nodes = self.context.vector_store.
|
77
|
+
existing_nodes = await self.context.vector_store.async_search(
|
78
78
|
query="...", # Empty query to get all
|
79
79
|
workspace_id=workspace_id,
|
80
80
|
top_k=self.op_params.get("max_existing_task_memories", 1000)
|
@@ -3,6 +3,8 @@ import re
|
|
3
3
|
from typing import List, Dict, Any
|
4
4
|
|
5
5
|
from flowllm import C, BaseLLMOp
|
6
|
+
from flowllm.enumeration.role import Role
|
7
|
+
from flowllm.schema.message import Message as FlowMessage
|
6
8
|
from loguru import logger
|
7
9
|
|
8
10
|
from reme_ai.schema import Message
|
@@ -13,7 +15,7 @@ from reme_ai.schema.memory import BaseMemory
|
|
13
15
|
class MemoryValidationOp(BaseLLMOp):
|
14
16
|
file_path: str = __file__
|
15
17
|
|
16
|
-
def
|
18
|
+
async def async_execute(self):
|
17
19
|
"""Validate quality of extracted task memories"""
|
18
20
|
|
19
21
|
task_memories: List[BaseMemory] = []
|
@@ -31,7 +33,7 @@ class MemoryValidationOp(BaseLLMOp):
|
|
31
33
|
validated_task_memories = []
|
32
34
|
|
33
35
|
for task_memory in task_memories:
|
34
|
-
validation_result = self._validate_single_task_memory(task_memory)
|
36
|
+
validation_result = await self._validate_single_task_memory(task_memory)
|
35
37
|
if validation_result and validation_result.get("is_valid", False):
|
36
38
|
task_memory.score = validation_result.get("score", 0.0)
|
37
39
|
validated_task_memories.append(task_memory)
|
@@ -45,13 +47,13 @@ class MemoryValidationOp(BaseLLMOp):
|
|
45
47
|
self.context.response.answer = json.dumps([x.model_dump() for x in validated_task_memories])
|
46
48
|
self.context.response.metadata["memory_list"] = validated_task_memories
|
47
49
|
|
48
|
-
def _validate_single_task_memory(self, task_memory: BaseMemory) -> Dict[str, Any]:
|
50
|
+
async def _validate_single_task_memory(self, task_memory: BaseMemory) -> Dict[str, Any]:
|
49
51
|
"""Validate single task memory"""
|
50
|
-
validation_info = self._llm_validate_task_memory(task_memory)
|
52
|
+
validation_info = await self._llm_validate_task_memory(task_memory)
|
51
53
|
logger.info(f"Validating: {validation_info}")
|
52
54
|
return validation_info
|
53
55
|
|
54
|
-
def _llm_validate_task_memory(self, task_memory: BaseMemory) -> Dict[str, Any]:
|
56
|
+
async def _llm_validate_task_memory(self, task_memory: BaseMemory) -> Dict[str, Any]:
|
55
57
|
"""Validate task memory using LLM"""
|
56
58
|
try:
|
57
59
|
prompt = self.prompt_format(
|
@@ -96,7 +98,7 @@ class MemoryValidationOp(BaseLLMOp):
|
|
96
98
|
"reason": f"Parse error: {str(e_inner)}"
|
97
99
|
}
|
98
100
|
|
99
|
-
return self.llm.
|
101
|
+
return await self.llm.achat(messages=[FlowMessage(role=Role.USER, content=prompt)], callback_fn=parse_validation)
|
100
102
|
|
101
103
|
except Exception as e:
|
102
104
|
logger.error(f"LLM validation failed: {e}")
|
@@ -2,6 +2,8 @@ import json
|
|
2
2
|
from typing import List, Dict
|
3
3
|
|
4
4
|
from flowllm import C, BaseLLMOp
|
5
|
+
from flowllm.enumeration.role import Role
|
6
|
+
from flowllm.schema.message import Message as FlowMessage
|
5
7
|
from loguru import logger
|
6
8
|
|
7
9
|
from reme_ai.schema import Message, Trajectory
|
@@ -13,7 +15,7 @@ from reme_ai.utils.op_utils import merge_messages_content
|
|
13
15
|
class SimpleComparativeSummaryOp(BaseLLMOp):
|
14
16
|
file_path: str = __file__
|
15
17
|
|
16
|
-
def compare_summary_trajectory(self, trajectory_a: Trajectory, trajectory_b: Trajectory) -> List[BaseMemory]:
|
18
|
+
async def compare_summary_trajectory(self, trajectory_a: Trajectory, trajectory_b: Trajectory) -> List[BaseMemory]:
|
17
19
|
summary_prompt = self.prompt_format(prompt_name="summary_prompt",
|
18
20
|
execution_process_a=merge_messages_content(trajectory_a.messages),
|
19
21
|
execution_process_b=merge_messages_content(trajectory_b.messages),
|
@@ -42,9 +44,9 @@ class SimpleComparativeSummaryOp(BaseLLMOp):
|
|
42
44
|
logger.exception(f"parse content failed!\n{content}")
|
43
45
|
raise e
|
44
46
|
|
45
|
-
return self.llm.
|
47
|
+
return await self.llm.achat(messages=[FlowMessage(role=Role.USER, content=summary_prompt)], callback_fn=parse_content)
|
46
48
|
|
47
|
-
def
|
49
|
+
async def async_execute(self):
|
48
50
|
trajectories: list = self.context.get("trajectories", [])
|
49
51
|
trajectories: List[Trajectory] = [Trajectory(**x) if isinstance(x, dict) else x for x in trajectories]
|
50
52
|
|
@@ -61,7 +63,7 @@ class SimpleComparativeSummaryOp(BaseLLMOp):
|
|
61
63
|
continue
|
62
64
|
|
63
65
|
if task_trajectories[0].score > task_trajectories[-1].score:
|
64
|
-
task_memories = self.compare_summary_trajectory(trajectory_a=task_trajectories[0],
|
66
|
+
task_memories = await self.compare_summary_trajectory(trajectory_a=task_trajectories[0],
|
65
67
|
trajectory_b=task_trajectories[-1])
|
66
68
|
memory_list.extend(task_memories)
|
67
69
|
|
@@ -2,6 +2,8 @@ import json
|
|
2
2
|
from typing import List
|
3
3
|
|
4
4
|
from flowllm import C, BaseLLMOp
|
5
|
+
from flowllm.enumeration.role import Role
|
6
|
+
from flowllm.schema.message import Message as FlowMessage
|
5
7
|
from loguru import logger
|
6
8
|
|
7
9
|
from reme_ai.schema import Message, Trajectory
|
@@ -13,7 +15,7 @@ from reme_ai.utils.op_utils import merge_messages_content
|
|
13
15
|
class SimpleSummaryOp(BaseLLMOp):
|
14
16
|
file_path: str = __file__
|
15
17
|
|
16
|
-
def summary_trajectory(self, trajectory: Trajectory) -> List[BaseMemory]:
|
18
|
+
async def summary_trajectory(self, trajectory: Trajectory) -> List[BaseMemory]:
|
17
19
|
execution_process = merge_messages_content(trajectory.messages)
|
18
20
|
success_score_threshold: float = self.op_params.get("success_score_threshold", 0.9)
|
19
21
|
logger.info(f"success_score_threshold={success_score_threshold}")
|
@@ -49,15 +51,15 @@ class SimpleSummaryOp(BaseLLMOp):
|
|
49
51
|
logger.exception(f"parse content failed!\n{content}")
|
50
52
|
raise e
|
51
53
|
|
52
|
-
return self.llm.
|
54
|
+
return await self.llm.achat(messages=[FlowMessage(role=Role.USER, content=summary_prompt)], callback_fn=parse_content)
|
53
55
|
|
54
|
-
def
|
56
|
+
async def async_execute(self):
|
55
57
|
trajectories: list = self.context.trajectories
|
56
58
|
trajectories: List[Trajectory] = [Trajectory(**x) if isinstance(x, dict) else x for x in trajectories]
|
57
59
|
|
58
60
|
memory_list: List[BaseMemory] = []
|
59
61
|
for trajectory in trajectories:
|
60
|
-
memories = self.summary_trajectory(trajectory)
|
62
|
+
memories = await self.summary_trajectory(trajectory)
|
61
63
|
if memories:
|
62
64
|
memory_list.extend(memories)
|
63
65
|
|
@@ -1,6 +1,8 @@
|
|
1
1
|
from typing import List
|
2
2
|
|
3
3
|
from flowllm import C, BaseLLMOp
|
4
|
+
from flowllm.enumeration.role import Role
|
5
|
+
from flowllm.schema.message import Message as FlowMessage
|
4
6
|
from loguru import logger
|
5
7
|
|
6
8
|
from reme_ai.schema import Message, Trajectory
|
@@ -12,7 +14,7 @@ from reme_ai.utils.op_utils import merge_messages_content, parse_json_experience
|
|
12
14
|
class SuccessExtractionOp(BaseLLMOp):
|
13
15
|
file_path: str = __file__
|
14
16
|
|
15
|
-
def
|
17
|
+
async def async_execute(self):
|
16
18
|
"""Extract task memories from successful trajectories"""
|
17
19
|
success_trajectories: List[Trajectory] = self.context.success_trajectories
|
18
20
|
|
@@ -29,11 +31,11 @@ class SuccessExtractionOp(BaseLLMOp):
|
|
29
31
|
if "segments" in trajectory.metadata:
|
30
32
|
# Process segmented step sequences
|
31
33
|
for segment in trajectory.metadata["segments"]:
|
32
|
-
task_memories = self._extract_success_task_memory_from_steps(segment, trajectory)
|
34
|
+
task_memories = await self._extract_success_task_memory_from_steps(segment, trajectory)
|
33
35
|
success_task_memories.extend(task_memories)
|
34
36
|
else:
|
35
37
|
# Process entire trajectory
|
36
|
-
task_memories = self._extract_success_task_memory_from_steps(trajectory.messages, trajectory)
|
38
|
+
task_memories = await self._extract_success_task_memory_from_steps(trajectory.messages, trajectory)
|
37
39
|
success_task_memories.extend(task_memories)
|
38
40
|
|
39
41
|
logger.info(f"Extracted {len(success_task_memories)} success task memories")
|
@@ -41,7 +43,7 @@ class SuccessExtractionOp(BaseLLMOp):
|
|
41
43
|
# Add task memories to context
|
42
44
|
self.context.success_task_memories = success_task_memories
|
43
45
|
|
44
|
-
def _extract_success_task_memory_from_steps(self, steps: List[Message], trajectory: Trajectory) -> List[BaseMemory]:
|
46
|
+
async def _extract_success_task_memory_from_steps(self, steps: List[Message], trajectory: Trajectory) -> List[BaseMemory]:
|
45
47
|
"""Extract task memory from successful step sequences"""
|
46
48
|
step_content = merge_messages_content(steps)
|
47
49
|
context = get_trajectory_context(trajectory, steps)
|
@@ -70,4 +72,4 @@ class SuccessExtractionOp(BaseLLMOp):
|
|
70
72
|
|
71
73
|
return task_memories
|
72
74
|
|
73
|
-
return self.llm.
|
75
|
+
return await self.llm.achat(messages=[FlowMessage(role=Role.USER, content=prompt)], callback_fn=parse_task_memories)
|
@@ -1,4 +1,3 @@
|
|
1
|
-
import json
|
2
1
|
from typing import List, Dict
|
3
2
|
|
4
3
|
from flowllm import C, BaseOp
|
@@ -11,18 +10,10 @@ from reme_ai.schema import Trajectory
|
|
11
10
|
class TrajectoryPreprocessOp(BaseOp):
|
12
11
|
file_path: str = __file__
|
13
12
|
|
14
|
-
def
|
13
|
+
async def async_execute(self):
|
15
14
|
"""Preprocess trajectories: validate and classify"""
|
16
15
|
trajectories: list = self.context.get("trajectories", [])
|
17
|
-
|
18
|
-
new_trajectories: List[Trajectory] = []
|
19
|
-
for x in trajectories:
|
20
|
-
if isinstance(x, dict):
|
21
|
-
x["messages"] = self._modify_tool_calls(x["messages"])
|
22
|
-
new_trajectories.append(Trajectory(**x))
|
23
|
-
else:
|
24
|
-
new_trajectories.append(x)
|
25
|
-
trajectories = new_trajectories
|
16
|
+
trajectories: List[Trajectory] = [Trajectory(**x) if isinstance(x, dict) else x for x in trajectories]
|
26
17
|
|
27
18
|
# Classify trajectories
|
28
19
|
classified = self._classify_trajectories(trajectories)
|
@@ -53,24 +44,4 @@ class TrajectoryPreprocessOp(BaseOp):
|
|
53
44
|
'success': success_trajectories,
|
54
45
|
'failure': failure_trajectories,
|
55
46
|
'all': trajectories
|
56
|
-
}
|
57
|
-
|
58
|
-
def _modify_tool_calls(self, messages: List[Dict]) -> List[Dict]:
|
59
|
-
new_messages = []
|
60
|
-
|
61
|
-
for msg in messages:
|
62
|
-
if 'tool_calls' in msg:
|
63
|
-
processed_tool_calls = []
|
64
|
-
for tool_call in msg['tool_calls']:
|
65
|
-
tool_type = tool_call.get("type", "function")
|
66
|
-
nested_data = tool_call.get(tool_type, {})
|
67
|
-
tool_call.update({
|
68
|
-
"arguments": json.loads(nested_data.get("arguments", "")),
|
69
|
-
"name": nested_data.get("name", "")
|
70
|
-
})
|
71
|
-
tool_call.pop(tool_type)
|
72
|
-
processed_tool_calls.append(tool_call)
|
73
|
-
msg['tool_calls'] = processed_tool_calls
|
74
|
-
new_messages.append(msg)
|
75
|
-
|
76
|
-
return new_messages
|
47
|
+
}
|
@@ -3,6 +3,8 @@ import re
|
|
3
3
|
from typing import List
|
4
4
|
|
5
5
|
from flowllm import C, BaseLLMOp
|
6
|
+
from flowllm.enumeration.role import Role
|
7
|
+
from flowllm.schema.message import Message as FlowMessage
|
6
8
|
from loguru import logger
|
7
9
|
|
8
10
|
from reme_ai.schema import Message, Trajectory
|
@@ -12,7 +14,7 @@ from reme_ai.schema import Message, Trajectory
|
|
12
14
|
class TrajectorySegmentationOp(BaseLLMOp):
|
13
15
|
file_path: str = __file__
|
14
16
|
|
15
|
-
def
|
17
|
+
async def async_execute(self):
|
16
18
|
"""Segment trajectories into meaningful steps"""
|
17
19
|
# Get trajectories from context
|
18
20
|
all_trajectories: List[Trajectory] = self.context.get("all_trajectories", [])
|
@@ -30,7 +32,7 @@ class TrajectorySegmentationOp(BaseLLMOp):
|
|
30
32
|
# Add segmentation info to trajectories
|
31
33
|
segmented_count = 0
|
32
34
|
for trajectory in target_trajectories:
|
33
|
-
segments = self._llm_segment_trajectory(trajectory)
|
35
|
+
segments = await self._llm_segment_trajectory(trajectory)
|
34
36
|
trajectory.metadata["segments"] = segments
|
35
37
|
segmented_count += 1
|
36
38
|
|
@@ -51,7 +53,7 @@ class TrajectorySegmentationOp(BaseLLMOp):
|
|
51
53
|
else:
|
52
54
|
return all_trajectories
|
53
55
|
|
54
|
-
def _llm_segment_trajectory(self, trajectory: Trajectory) -> List[List[Message]]:
|
56
|
+
async def _llm_segment_trajectory(self, trajectory: Trajectory) -> List[List[Message]]:
|
55
57
|
"""Use LLM for trajectory segmentation"""
|
56
58
|
trajectory_content = self._format_trajectory_content(trajectory)
|
57
59
|
|
@@ -80,7 +82,7 @@ class TrajectorySegmentationOp(BaseLLMOp):
|
|
80
82
|
|
81
83
|
return segments if segments else [trajectory.messages]
|
82
84
|
|
83
|
-
return self.llm.
|
85
|
+
return await self.llm.achat(messages=[FlowMessage(role=Role.USER, content=prompt)], callback_fn=parse_segmentation,
|
84
86
|
default_value=[trajectory.messages])
|
85
87
|
|
86
88
|
@staticmethod
|
@@ -2,8 +2,8 @@ import datetime
|
|
2
2
|
import re
|
3
3
|
from typing import List
|
4
4
|
|
5
|
+
from reme_ai.constants.language_constants import LanguageEnum
|
5
6
|
from reme_ai.constants.language_constants import WEEKDAYS, DATATIME_WORD_LIST, MONTH_DICT
|
6
|
-
from reme_ai.enumeration.language_constants import LanguageEnum
|
7
7
|
|
8
8
|
|
9
9
|
class DatetimeHandler(object):
|
@@ -8,7 +8,7 @@ from flowllm.schema.vector_node import VectorNode
|
|
8
8
|
class DeleteMemoryOp(BaseLLMOp):
|
9
9
|
file_path: str = __file__
|
10
10
|
|
11
|
-
def
|
11
|
+
async def async_execute(self):
|
12
12
|
workspace_id: str = self.context.workspace_id
|
13
13
|
freq_threshold: int = self.context.freq_threshold
|
14
14
|
utility_threshold: float = self.context.utility_threshold
|
@@ -10,15 +10,15 @@ from reme_ai.schema.memory import BaseMemory, vector_node_to_memory
|
|
10
10
|
@C.register_op()
|
11
11
|
class RecallVectorStoreOp(BaseLLMOp):
|
12
12
|
|
13
|
-
def
|
13
|
+
async def async_execute(self):
|
14
14
|
recall_key: str = self.op_params.get("recall_key", "query")
|
15
|
-
top_k: int = self.
|
15
|
+
top_k: int = self.context.get("top_k", 3)
|
16
16
|
|
17
17
|
query: str = self.context[recall_key]
|
18
18
|
assert query, "query should be not empty!"
|
19
19
|
|
20
20
|
workspace_id: str = self.context.workspace_id
|
21
|
-
nodes: List[VectorNode] = self.vector_store.
|
21
|
+
nodes: List[VectorNode] = await self.vector_store.async_search(query=query, workspace_id=workspace_id, top_k=top_k)
|
22
22
|
memory_list: List[BaseMemory] = []
|
23
23
|
memory_content_list: List[str] = []
|
24
24
|
for node in nodes:
|
@@ -10,7 +10,7 @@ from reme_ai.schema.memory import BaseMemory, dict_to_memory
|
|
10
10
|
class UpdateMemoryFreqOp(BaseOp):
|
11
11
|
file_path: str = __file__
|
12
12
|
|
13
|
-
def
|
13
|
+
async def async_execute(self):
|
14
14
|
memory_dicts: List[dict] = self.context.memory_dicts
|
15
15
|
|
16
16
|
if not memory_dicts:
|
@@ -10,7 +10,7 @@ from reme_ai.schema.memory import BaseMemory
|
|
10
10
|
class UpdateMemoryUtilityOp(BaseOp):
|
11
11
|
file_path: str = __file__
|
12
12
|
|
13
|
-
def
|
13
|
+
async def async_execute(self):
|
14
14
|
memory_dicts: List[dict] = self.context.memory_dicts
|
15
15
|
update_utility = self.context.update_utility
|
16
16
|
|
@@ -11,18 +11,18 @@ from reme_ai.schema.memory import BaseMemory
|
|
11
11
|
@C.register_op()
|
12
12
|
class UpdateVectorStoreOp(BaseLLMOp):
|
13
13
|
|
14
|
-
def
|
14
|
+
async def async_execute(self):
|
15
15
|
workspace_id: str = self.context.workspace_id
|
16
16
|
|
17
17
|
deleted_memory_ids: List[str] = self.context.response.metadata.get("deleted_memory_ids", [])
|
18
18
|
if deleted_memory_ids:
|
19
|
-
self.vector_store.
|
19
|
+
await self.vector_store.async_delete(node_ids=deleted_memory_ids, workspace_id=workspace_id)
|
20
20
|
logger.info(f"delete memory_ids={json.dumps(deleted_memory_ids, indent=2)}")
|
21
21
|
|
22
22
|
insert_memory_list: List[BaseMemory] = self.context.response.metadata.get("memory_list", [])
|
23
23
|
if insert_memory_list:
|
24
24
|
insert_nodes: List[VectorNode] = [x.to_vector_node() for x in insert_memory_list]
|
25
|
-
self.vector_store.
|
25
|
+
await self.vector_store.async_insert(nodes=insert_nodes, workspace_id=workspace_id)
|
26
26
|
logger.info(f"insert insert_node.size={len(insert_nodes)}")
|
27
27
|
|
28
28
|
# Store results in context
|
@@ -7,22 +7,22 @@ from reme_ai.schema.memory import vector_node_to_memory, dict_to_memory, BaseMem
|
|
7
7
|
@C.register_op()
|
8
8
|
class VectorStoreActionOp(BaseLLMOp):
|
9
9
|
|
10
|
-
def
|
10
|
+
async def async_execute(self):
|
11
11
|
workspace_id: str = self.context.workspace_id
|
12
12
|
action: str = self.context.action
|
13
|
-
|
13
|
+
result = ""
|
14
14
|
if action == "copy":
|
15
15
|
src_workspace_id: str = self.context.src_workspace_id
|
16
|
-
result = self.vector_store.
|
17
|
-
|
16
|
+
result = await self.vector_store.async_copy_workspace(src_workspace_id=src_workspace_id,
|
17
|
+
dest_workspace_id=workspace_id)
|
18
18
|
|
19
19
|
elif action == "delete":
|
20
|
-
if self.vector_store.
|
21
|
-
result = self.vector_store.
|
20
|
+
if await self.vector_store.async_exist_workspace(workspace_id):
|
21
|
+
result = await self.vector_store.async_delete_workspace(workspace_id=workspace_id)
|
22
22
|
|
23
23
|
elif action == "delete_ids":
|
24
24
|
memory_ids: list = self.context.memory_ids
|
25
|
-
result = self.vector_store.
|
25
|
+
result = await self.vector_store.async_delete(workspace_id=workspace_id, node_ids=memory_ids)
|
26
26
|
|
27
27
|
elif action == "dump":
|
28
28
|
path: str = self.context.path
|
@@ -30,9 +30,16 @@ class VectorStoreActionOp(BaseLLMOp):
|
|
30
30
|
def node_to_memory(node: VectorNode) -> dict:
|
31
31
|
return vector_node_to_memory(node).model_dump()
|
32
32
|
|
33
|
-
result = self.vector_store.
|
34
|
-
|
35
|
-
|
33
|
+
result = await self.vector_store.async_dump_workspace(workspace_id=workspace_id,
|
34
|
+
path=path,
|
35
|
+
callback_fn=node_to_memory)
|
36
|
+
|
37
|
+
elif action == "list":
|
38
|
+
def node_to_memory(node: VectorNode) -> dict:
|
39
|
+
return vector_node_to_memory(node).model_dump()
|
40
|
+
|
41
|
+
result = await self.vector_store.async_iter_workspace_nodes(workspace_id=workspace_id)
|
42
|
+
result = [node_to_memory(node) for node in result]
|
36
43
|
|
37
44
|
elif action == "load":
|
38
45
|
path: str = self.context.path
|
@@ -41,15 +48,11 @@ class VectorStoreActionOp(BaseLLMOp):
|
|
41
48
|
memory: BaseMemory = dict_to_memory(memory_dict=memory_dict)
|
42
49
|
return memory.to_vector_node()
|
43
50
|
|
44
|
-
result = self.vector_store.
|
45
|
-
|
46
|
-
|
51
|
+
result = await self.vector_store.async_load_workspace(workspace_id=workspace_id,
|
52
|
+
path=path,
|
53
|
+
callback_fn=memory_dict_to_node)
|
47
54
|
|
48
55
|
else:
|
49
56
|
raise ValueError(f"invalid action={action}")
|
50
57
|
|
51
|
-
|
52
|
-
if isinstance(result, dict):
|
53
|
-
self.context.response.metadata["action_result"] = result
|
54
|
-
else:
|
55
|
-
self.context.response.metadata["action_result"] = {"result": str(result)}
|
58
|
+
self.context.response.metadata["action_result"] = result
|