-
Notifications
You must be signed in to change notification settings - Fork 4
feat(memory_collection): support AsyncMemory and add vector dimension… #38
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||
|---|---|---|---|---|
|
|
@@ -23,8 +23,8 @@ | |||
| from agentrun.utils.config import Config | ||||
|
|
||||
|
|
||||
| async def main(): | ||||
| """主函数 / Main function""" | ||||
| async def memory_collection_basic_example(): | ||||
| """MemoryCollection 基础操作示例 / MemoryCollection Basic Operations Example""" | ||||
|
|
||||
| # 创建配置 | ||||
| # Create configuration | ||||
|
|
@@ -155,8 +155,73 @@ async def main(): | |||
|
|
||||
| traceback.print_exc() | ||||
|
|
||||
| print("\n✅ 示例完成") | ||||
|
|
||||
| async def async_mem0_memory_example(): | ||||
| """异步 AsyncMemory 转换方法使用示例""" | ||||
| print("\n=== 异步转换为 mem0ai AsyncMemory 客户端 ===") | ||||
|
|
||||
| try: | ||||
| # 使用高层 API 的 to_mem0_memory_async 方法 | ||||
| # Use high-level API's to_mem0_memory_async method | ||||
| memory = await MemoryCollection.to_mem0_memory_async( | ||||
| "memoryCollection010901" | ||||
| ) | ||||
| print(f"✅ 成功创建 mem0ai AsyncMemory 客户端") | ||||
| print(f" 类型: {type(memory)}") | ||||
|
|
||||
| # 使用 mem0ai AsyncMemory 客户端进行操作 | ||||
| # Use mem0ai AsyncMemory client for operations | ||||
| user_id = "user456" | ||||
|
|
||||
| # 添加记忆 | ||||
| # Add memory | ||||
| result = await memory.add( | ||||
| "我喜欢喝咖啡和茶", | ||||
| user_id=user_id, | ||||
| metadata={"category": "beverage"}, | ||||
| ) | ||||
| print(f"\n✅ 添加记忆成功:") | ||||
| for idx, res in enumerate(result.get("results", []), 1): | ||||
| print(f" {idx}. ID: {res.get('id')}, 事件: {res.get('event')}") | ||||
|
|
||||
| # 搜索记忆 | ||||
| # Search memory | ||||
| search_results = await memory.search( | ||||
| "用户喜欢喝什么?", user_id=user_id | ||||
| ) | ||||
| print(f"\n✅ 搜索记忆结果:") | ||||
| for idx, result in enumerate(search_results.get("results", []), 1): | ||||
| print( | ||||
| f" {idx}. 内容: {result.get('memory')}, 相似度:" | ||||
| f" {result.get('score', 0):.4f}" | ||||
| ) | ||||
|
|
||||
| # 获取所有记忆 | ||||
| # Get all memories | ||||
| all_memories = await memory.get_all(user_id=user_id) | ||||
| print(f"\n✅ 获取所有记忆:") | ||||
| for idx, mem in enumerate(all_memories.get("results", []), 1): | ||||
| print(f" {idx}. {mem.get('memory')}") | ||||
|
|
||||
| except ImportError as e: | ||||
| print(f"⚠️ mem0ai 未安装: {e}") | ||||
| print(" 安装方法: pip install agentrun-sdk[mem0]") | ||||
| except Exception as e: | ||||
| print(f"❌ AsyncMemory 操作失败: {e}") | ||||
| import traceback | ||||
|
|
||||
| traceback.print_exc() | ||||
|
|
||||
|
|
||||
| if __name__ == "__main__": | ||||
| asyncio.run(main()) | ||||
| import asyncio | ||||
|
||||
| import asyncio |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -364,3 +364,106 @@ def test_from_inner_object_with_extra(self): | |
| assert ( | ||
| memory_collection.memory_collection_name == "test-memory-collection" | ||
| ) | ||
|
|
||
|
|
||
| class TestMemoryCollectionToMem0Memory: | ||
| """测试 MemoryCollection.to_mem0_memory 和 to_mem0_memory_async 方法""" | ||
|
|
||
| @patch("agentrun.memory_collection.client.MemoryCollectionControlAPI") | ||
| def test_to_mem0_memory_sync(self, mock_control_api_class): | ||
| """测试同步转换为 mem0 Memory 客户端""" | ||
| # Mock MemoryCollection 数据 | ||
| mock_control_api = MagicMock() | ||
| mock_data = MockMemoryCollectionData() | ||
| mock_control_api.get_memory_collection.return_value = mock_data | ||
| mock_control_api_class.return_value = mock_control_api | ||
|
|
||
| # Mock Memory.from_config | ||
| with patch("agentrun_mem0.Memory") as mock_memory_class: | ||
| mock_memory_instance = MagicMock() | ||
| mock_memory_class.from_config.return_value = mock_memory_instance | ||
|
|
||
| # 调用 to_mem0_memory | ||
| result = MemoryCollection.to_mem0_memory( | ||
| "test-memory-collection", | ||
| config=Config( | ||
| access_key_id="test-key", | ||
| access_key_secret="test-secret", | ||
| region_id="cn-hangzhou", | ||
| ), | ||
| ) | ||
|
|
||
| # 验证返回的是 Memory 实例 | ||
| assert result == mock_memory_instance | ||
| mock_memory_class.from_config.assert_called_once() | ||
|
|
||
| @patch("agentrun.memory_collection.client.MemoryCollectionControlAPI") | ||
| @pytest.mark.asyncio | ||
| async def test_to_mem0_memory_async(self, mock_control_api_class): | ||
| """测试异步转换为 mem0 AsyncMemory 客户端""" | ||
| # Mock MemoryCollection 数据 | ||
| mock_control_api = MagicMock() | ||
| mock_data = MockMemoryCollectionData() | ||
| mock_control_api.get_memory_collection_async = AsyncMock( | ||
| return_value=mock_data | ||
| ) | ||
| mock_control_api_class.return_value = mock_control_api | ||
|
|
||
| # Mock AsyncMemory.from_config | ||
| with patch("agentrun_mem0.AsyncMemory") as mock_async_memory_class: | ||
| mock_async_memory_instance = MagicMock() | ||
| # from_config 是异步方法,需要返回 AsyncMock | ||
| mock_async_memory_class.from_config = AsyncMock( | ||
| return_value=mock_async_memory_instance | ||
| ) | ||
|
|
||
| # 调用 to_mem0_memory_async | ||
| result = await MemoryCollection.to_mem0_memory_async( | ||
| "test-memory-collection", | ||
| config=Config( | ||
| access_key_id="test-key", | ||
| access_key_secret="test-secret", | ||
| region_id="cn-hangzhou", | ||
| ), | ||
| ) | ||
|
|
||
| # 验证返回的是 AsyncMemory 实例 | ||
| assert result == mock_async_memory_instance | ||
| mock_async_memory_class.from_config.assert_called_once() | ||
|
|
||
| @patch("agentrun.memory_collection.client.MemoryCollectionControlAPI") | ||
| def test_to_mem0_memory_import_error(self, mock_control_api_class): | ||
| """测试 mem0 包未安装时的错误处理""" | ||
| mock_control_api = MagicMock() | ||
| mock_control_api.get_memory_collection.return_value = ( | ||
| MockMemoryCollectionData() | ||
| ) | ||
| mock_control_api_class.return_value = mock_control_api | ||
|
|
||
| # Mock import 失败 | ||
| with patch("builtins.__import__", side_effect=ImportError("No module")): | ||
|
||
| with pytest.raises(ImportError) as exc_info: | ||
| MemoryCollection.to_mem0_memory("test-memory-collection") | ||
|
|
||
| assert "agentrun-mem0ai package is required" in str(exc_info.value) | ||
|
|
||
| @patch("agentrun.memory_collection.client.MemoryCollectionControlAPI") | ||
| @pytest.mark.asyncio | ||
| async def test_to_mem0_memory_async_import_error( | ||
| self, mock_control_api_class | ||
| ): | ||
| """测试异步方法 mem0 包未安装时的错误处理""" | ||
| mock_control_api = MagicMock() | ||
| mock_control_api.get_memory_collection_async = AsyncMock( | ||
| return_value=MockMemoryCollectionData() | ||
| ) | ||
| mock_control_api_class.return_value = mock_control_api | ||
|
|
||
| # Mock import 失败 | ||
| with patch("builtins.__import__", side_effect=ImportError("No module")): | ||
|
||
| with pytest.raises(ImportError) as exc_info: | ||
| await MemoryCollection.to_mem0_memory_async( | ||
| "test-memory-collection" | ||
| ) | ||
|
|
||
| assert "agentrun-mem0ai package is required" in str(exc_info.value) | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new vector dimension configuration logic (lines 623-637 and 747-761) that extracts
vector_dimensionfromvector_store_configand adds it asembedding_dimsto the embedder configuration is not covered by tests. Consider adding test cases to verify that this configuration is correctly passed to the mem0 config whenvector_dimensionis present.