|
1 | 1 | import asyncio |
| 2 | +import concurrent.futures |
2 | 3 | import logging |
3 | 4 | from typing import Any |
4 | 5 |
|
|
11 | 12 | logger = logging.getLogger("search_memory_tool") |
12 | 13 |
|
13 | 14 |
|
| 15 | +def _run_coroutine(coro): |
| 16 | + try: |
| 17 | + asyncio.get_running_loop() |
| 18 | + except RuntimeError: |
| 19 | + return asyncio.run(coro) |
| 20 | + with concurrent.futures.ThreadPoolExecutor(max_workers=1) as pool: |
| 21 | + return pool.submit(asyncio.run, coro).result() |
| 22 | + |
| 23 | + |
14 | 24 | class SearchMemoryTool(Tool): |
15 | 25 | name = "search_memory" |
16 | 26 | description = ( |
@@ -63,25 +73,34 @@ def __init__( |
63 | 73 | self.running_prompt_en = "Searching memory..." |
64 | 74 | self.running_prompt_zh = "搜索记忆中..." |
65 | 75 |
|
| 76 | + def _resolve_memory_levels(self) -> list[str]: |
| 77 | + """Determine which memory levels to search based on user preferences. |
| 78 | +
|
| 79 | + Conservative default: when config is unavailable, assume "never" |
| 80 | + (no agent-level sharing) to protect user privacy. |
| 81 | + """ |
| 82 | + levels = ["tenant", "user", "agent", "user_agent"] |
| 83 | + if not self.memory_user_config or self.memory_user_config.agent_share_option == "never": |
| 84 | + levels.remove("agent") |
| 85 | + if self.memory_user_config and self.agent_id in getattr(self.memory_user_config, "disable_agent_ids", []): |
| 86 | + if "agent" in levels: |
| 87 | + levels.remove("agent") |
| 88 | + if self.memory_user_config and self.agent_id in getattr(self.memory_user_config, "disable_user_agent_ids", []): |
| 89 | + if "user_agent" in levels: |
| 90 | + levels.remove("user_agent") |
| 91 | + return levels |
| 92 | + |
66 | 93 | def forward(self, query: str, top_k: int = 5) -> str: |
67 | 94 | logger.info(f"[ACTIVE MEMORY] SearchMemoryTool invoked: query={query[:200]}, top_k={top_k}, user_id={self.user_id}, agent_id={self.agent_id}") |
68 | 95 | if self.observer: |
69 | 96 | running_prompt = self.running_prompt_zh if self.observer.lang == "zh" else self.running_prompt_en |
70 | 97 | self.observer.add_message("", ProcessType.TOOL, running_prompt) |
71 | 98 |
|
72 | | - memory_levels = ["tenant", "user", "agent", "user_agent"] |
73 | | - if self.memory_user_config.agent_share_option == "never": |
74 | | - memory_levels.remove("agent") |
75 | | - if self.agent_id in getattr(self.memory_user_config, "disable_agent_ids", []): |
76 | | - if "agent" in memory_levels: |
77 | | - memory_levels.remove("agent") |
78 | | - if self.agent_id in getattr(self.memory_user_config, "disable_user_agent_ids", []): |
79 | | - if "user_agent" in memory_levels: |
80 | | - memory_levels.remove("user_agent") |
| 99 | + memory_levels = self._resolve_memory_levels() |
81 | 100 |
|
82 | 101 | try: |
83 | 102 | from ...memory.memory_service import search_memory_in_levels |
84 | | - result = asyncio.run(search_memory_in_levels( |
| 103 | + result = _run_coroutine(search_memory_in_levels( |
85 | 104 | query_text=query, |
86 | 105 | memory_config=self.memory_config, |
87 | 106 | tenant_id=self.tenant_id, |
|
0 commit comments