Skip to content

Commit bdcdbb7

Browse files
committed
♻️ Backend code cleanup and import organization (database/) #1037
1 parent acedf33 commit bdcdbb7

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+1416
-914
lines changed

backend/agents/agent_run_manager.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,23 +21,27 @@ def __new__(cls):
2121

2222
def __init__(self):
2323
if not self._initialized:
24-
self.agent_runs: Dict[int, AgentRunInfo] = {} # conversation_id -> agent_run_info
24+
# conversation_id -> agent_run_info
25+
self.agent_runs: Dict[int, AgentRunInfo] = {}
2526
self._initialized = True
2627

2728
def register_agent_run(self, conversation_id: int, agent_run_info):
2829
"""register agent run instance"""
2930
with self._lock:
3031
self.agent_runs[conversation_id] = agent_run_info
31-
logger.info(f"register agent run instance, conversation_id: {conversation_id}")
32+
logger.info(
33+
f"register agent run instance, conversation_id: {conversation_id}")
3234

3335
def unregister_agent_run(self, conversation_id: int):
3436
"""unregister agent run instance"""
3537
with self._lock:
3638
if conversation_id in self.agent_runs:
3739
del self.agent_runs[conversation_id]
38-
logger.info(f"unregister agent run instance, conversation_id: {conversation_id}")
40+
logger.info(
41+
f"unregister agent run instance, conversation_id: {conversation_id}")
3942
else:
40-
logger.info(f"no agent run instance found for conversation_id: {conversation_id}")
43+
logger.info(
44+
f"no agent run instance found for conversation_id: {conversation_id}")
4145

4246
def get_agent_run_info(self, conversation_id: int):
4347
"""get agent run instance"""
@@ -48,7 +52,8 @@ def stop_agent_run(self, conversation_id: int) -> bool:
4852
agent_run_info = self.get_agent_run_info(conversation_id)
4953
if agent_run_info is not None:
5054
agent_run_info.stop_event.set()
51-
logger.info(f"agent run stopped, conversation_id: {conversation_id}")
55+
logger.info(
56+
f"agent run stopped, conversation_id: {conversation_id}")
5257
return True
5358
return False
5459

backend/agents/create_agent_info.py

Lines changed: 46 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,10 @@
2424

2525

2626
async def create_model_config_list(tenant_id):
27-
main_model_config = tenant_config_manager.get_model_config(key="LLM_ID", tenant_id=tenant_id)
28-
sub_model_config = tenant_config_manager.get_model_config(key="LLM_SECONDARY_ID", tenant_id=tenant_id)
27+
main_model_config = tenant_config_manager.get_model_config(
28+
key="LLM_ID", tenant_id=tenant_id)
29+
sub_model_config = tenant_config_manager.get_model_config(
30+
key="LLM_SECONDARY_ID", tenant_id=tenant_id)
2931

3032
return [ModelConfig(cite_name="main_model",
3133
api_key=main_model_config.get("api_key", ""),
@@ -40,10 +42,12 @@ async def create_model_config_list(tenant_id):
4042

4143

4244
async def create_agent_config(agent_id, tenant_id, user_id, language: str = 'zh', last_user_query: str = None):
43-
agent_info = search_agent_info_by_agent_id(agent_id=agent_id, tenant_id=tenant_id)
45+
agent_info = search_agent_info_by_agent_id(
46+
agent_id=agent_id, tenant_id=tenant_id)
4447

4548
# create sub agent
46-
sub_agent_id_list = query_sub_agents_id_list(main_agent_id=agent_id, tenant_id=tenant_id)
49+
sub_agent_id_list = query_sub_agents_id_list(
50+
main_agent_id=agent_id, tenant_id=tenant_id)
4751
managed_agents = []
4852
for sub_agent_id in sub_agent_id_list:
4953
sub_agent_config = await create_agent_config(
@@ -55,19 +59,22 @@ async def create_agent_config(agent_id, tenant_id, user_id, language: str = 'zh'
5559
managed_agents.append(sub_agent_config)
5660

5761
tool_list = await create_tool_config_list(agent_id, tenant_id, user_id)
58-
62+
5963
# Build system prompt: prioritize segmented fields, fallback to original prompt field if not available
6064
duty_prompt = agent_info.get("duty_prompt", "")
6165
constraint_prompt = agent_info.get("constraint_prompt", "")
6266
few_shots_prompt = agent_info.get("few_shots_prompt", "")
63-
67+
6468
# Get template content
65-
prompt_template = get_agent_prompt_template(is_manager=len(managed_agents) > 0, language=language)
69+
prompt_template = get_agent_prompt_template(
70+
is_manager=len(managed_agents) > 0, language=language)
6671

6772
# Get app information
6873
default_app_description = 'Nexent 是一个开源智能体SDK和平台' if language == 'zh' else 'Nexent is an open-source agent SDK and platform'
69-
app_name = tenant_config_manager.get_app_config('APP_NAME', tenant_id=tenant_id) or "Nexent"
70-
app_description = tenant_config_manager.get_app_config('APP_DESCRIPTION', tenant_id=tenant_id) or default_app_description
74+
app_name = tenant_config_manager.get_app_config(
75+
'APP_NAME', tenant_id=tenant_id) or "Nexent"
76+
app_description = tenant_config_manager.get_app_config(
77+
'APP_DESCRIPTION', tenant_id=tenant_id) or default_app_description
7178

7279
# Get memory list
7380
memory_context = build_memory_context(user_id, tenant_id, agent_id)
@@ -84,7 +91,8 @@ async def create_agent_config(agent_id, tenant_id, user_id, language: str = 'zh'
8491
memory_levels.remove("user_agent")
8592

8693
search_res = await search_memory_in_levels(
87-
query_text=last_user_query if last_user_query else agent_info.get("name"),
94+
query_text=last_user_query if last_user_query else agent_info.get(
95+
"name"),
8896
memory_config=memory_context.memory_config,
8997
tenant_id=memory_context.tenant_id,
9098
user_id=memory_context.user_id,
@@ -100,7 +108,8 @@ async def create_agent_config(agent_id, tenant_id, user_id, language: str = 'zh'
100108
try:
101109
for tool in tool_list:
102110
if "KnowledgeBaseSearchTool" == tool.class_name:
103-
knowledge_info_list = get_selected_knowledge_list(tenant_id=tenant_id, user_id=user_id)
111+
knowledge_info_list = get_selected_knowledge_list(
112+
tenant_id=tenant_id, user_id=user_id)
104113
if knowledge_info_list:
105114
for knowledge_info in knowledge_info_list:
106115
knowledge_name = knowledge_info.get("index_name")
@@ -109,13 +118,14 @@ async def create_agent_config(agent_id, tenant_id, user_id, language: str = 'zh'
109118
summary = message.get("summary", "")
110119
knowledge_base_summary += f"**{knowledge_name}**: {summary}\n\n"
111120
except Exception as e:
112-
logger.warning(f"Failed to get summary for knowledge base {knowledge_name}: {e}")
121+
logger.warning(
122+
f"Failed to get summary for knowledge base {knowledge_name}: {e}")
113123
else:
114124
knowledge_base_summary = "当前没有可用的知识库索引。\n" if language == 'zh' else "No knowledge base indexes are currently available.\n"
115125
break # Only process the first KnowledgeBaseSearchTool found
116126
except Exception as e:
117127
logger.error(f"Failed to build knowledge base summary: {e}")
118-
128+
119129
# Assemble system_prompt
120130
if duty_prompt or constraint_prompt or few_shots_prompt:
121131
system_prompt = Template(prompt_template["system_prompt"], undefined=StrictUndefined).render({
@@ -133,7 +143,7 @@ async def create_agent_config(agent_id, tenant_id, user_id, language: str = 'zh'
133143
})
134144
else:
135145
system_prompt = agent_info.get("prompt", "")
136-
146+
137147
agent_config = AgentConfig(
138148
name="undefined" if agent_info["name"] is None else agent_info["name"],
139149
description="undefined" if agent_info["description"] is None else agent_info["description"],
@@ -182,25 +192,27 @@ async def create_tool_config_list(agent_id, tenant_id, user_id):
182192

183193
# special logic for knowledge base search tool
184194
if tool_config.class_name == "KnowledgeBaseSearchTool":
185-
knowledge_info_list = get_selected_knowledge_list(tenant_id=tenant_id, user_id=user_id)
186-
index_names = [knowledge_info.get("index_name") for knowledge_info in knowledge_info_list]
195+
knowledge_info_list = get_selected_knowledge_list(
196+
tenant_id=tenant_id, user_id=user_id)
197+
index_names = [knowledge_info.get(
198+
"index_name") for knowledge_info in knowledge_info_list]
187199
tool_config.metadata = {"index_names": index_names,
188200
"es_core": elastic_core,
189201
"embedding_model": get_embedding_model(tenant_id=tenant_id)}
190202
tool_config_list.append(tool_config)
191-
203+
192204
return tool_config_list
193205

194206

195207
async def discover_langchain_tools():
196208
"""
197209
Discover LangChain tools implemented with the `@tool` decorator.
198-
210+
199211
Returns:
200212
list: List of discovered LangChain tool instances
201213
"""
202214
from utils.langchain_utils import discover_langchain_modules
203-
215+
204216
langchain_tools = []
205217

206218
# ----------------------------------------------
@@ -210,18 +222,21 @@ async def discover_langchain_tools():
210222
try:
211223
# Use the utility function to discover all BaseTool objects
212224
discovered_tools = discover_langchain_modules()
213-
225+
214226
for obj, filename in discovered_tools:
215227
try:
216228
# Log successful tool discovery
217-
logger.info(f"Loaded LangChain tool '{obj.name}' from {filename}")
229+
logger.info(
230+
f"Loaded LangChain tool '{obj.name}' from {filename}")
218231
langchain_tools.append(obj)
219232
except Exception as e:
220-
logger.error(f"Error processing LangChain tool from {filename}: {e}")
221-
233+
logger.error(
234+
f"Error processing LangChain tool from {filename}: {e}")
235+
222236
except Exception as e:
223-
logger.error(f"Unexpected error scanning LangChain tools directory: {e}")
224-
237+
logger.error(
238+
f"Unexpected error scanning LangChain tools directory: {e}")
239+
225240
return langchain_tools
226241

227242

@@ -269,7 +284,8 @@ def check_agent_tools(agent_config: AgentConfig):
269284
# Check current agent tools
270285
for tool in agent_config.tools:
271286
if tool.source == "mcp" and tool.usage in mcp_info_dict:
272-
used_mcp_urls.add(mcp_info_dict[tool.usage]["remote_mcp_server"])
287+
used_mcp_urls.add(
288+
mcp_info_dict[tool.usage]["remote_mcp_server"])
273289

274290
# Recursively check sub-agent
275291
for sub_agent_config in agent_config.managed_agents:
@@ -295,13 +311,15 @@ async def create_agent_run_info(agent_id, minio_files, query, history, authoriza
295311
)
296312

297313
remote_mcp_list = await get_remote_mcp_server_list(tenant_id=tenant_id)
298-
default_mcp_url = urljoin(config_manager.get_config("NEXENT_MCP_SERVER"), "sse")
314+
default_mcp_url = urljoin(
315+
config_manager.get_config("NEXENT_MCP_SERVER"), "sse")
299316
remote_mcp_list.append({
300317
"remote_mcp_server_name": "nexent",
301318
"remote_mcp_server": default_mcp_url,
302319
"status": True
303320
})
304-
remote_mcp_dict = {record["remote_mcp_server_name"]: record for record in remote_mcp_list if record["status"]}
321+
remote_mcp_dict = {record["remote_mcp_server_name"]
322+
: record for record in remote_mcp_list if record["status"]}
305323

306324
# Filter MCP servers and tools
307325
mcp_host = filter_mcp_servers_and_tools(agent_config, remote_mcp_dict)

backend/agents/preprocess_manager.py

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,10 @@ def __new__(cls):
3030

3131
def __init__(self):
3232
if not self._initialized:
33-
self.preprocess_tasks: Dict[str, PreprocessTask] = {} # task_id -> PreprocessTask
34-
self.conversation_tasks: Dict[int, Set[str]] = {} # conversation_id -> Set[task_id]
33+
# task_id -> PreprocessTask
34+
self.preprocess_tasks: Dict[str, PreprocessTask] = {}
35+
# conversation_id -> Set[task_id]
36+
self.conversation_tasks: Dict[int, Set[str]] = {}
3537
self._initialized = True
3638

3739
def register_preprocess_task(self, task_id: str, conversation_id: int, task: asyncio.Task):
@@ -40,76 +42,78 @@ def register_preprocess_task(self, task_id: str, conversation_id: int, task: asy
4042
preprocess_task = PreprocessTask(task_id, conversation_id)
4143
preprocess_task.task = task
4244
self.preprocess_tasks[task_id] = preprocess_task
43-
45+
4446
if conversation_id not in self.conversation_tasks:
4547
self.conversation_tasks[conversation_id] = set()
4648
self.conversation_tasks[conversation_id].add(task_id)
47-
48-
logger.info(f"Registered preprocess task {task_id} for conversation {conversation_id}")
49+
50+
logger.info(
51+
f"Registered preprocess task {task_id} for conversation {conversation_id}")
4952

5053
def unregister_preprocess_task(self, task_id: str):
5154
"""Unregister a preprocess task"""
5255
with self._lock:
5356
if task_id in self.preprocess_tasks:
5457
task = self.preprocess_tasks[task_id]
5558
conversation_id = task.conversation_id
56-
59+
5760
# Remove from conversation_tasks
5861
if conversation_id in self.conversation_tasks:
5962
self.conversation_tasks[conversation_id].discard(task_id)
6063
if not self.conversation_tasks[conversation_id]:
6164
del self.conversation_tasks[conversation_id]
62-
65+
6366
# Remove from preprocess_tasks
6467
del self.preprocess_tasks[task_id]
65-
68+
6669
logger.info(f"Unregistered preprocess task {task_id}")
6770

6871
def stop_preprocess_tasks(self, conversation_id: int) -> bool:
6972
"""Stop all preprocess tasks for a conversation"""
7073
with self._lock:
7174
if conversation_id not in self.conversation_tasks:
7275
return False
73-
76+
7477
task_ids = self.conversation_tasks[conversation_id].copy()
7578
stopped_count = 0
76-
79+
7780
for task_id in task_ids:
7881
if task_id in self.preprocess_tasks:
7982
task = self.preprocess_tasks[task_id]
8083
if task.is_running:
8184
task.stop_event.set()
8285
task.is_running = False
83-
86+
8487
# Cancel the asyncio task if it exists
8588
if task.task and not task.task.done():
8689
task.task.cancel()
87-
90+
8891
stopped_count += 1
89-
logger.info(f"Stopped preprocess task {task_id} for conversation {conversation_id}")
90-
92+
logger.info(
93+
f"Stopped preprocess task {task_id} for conversation {conversation_id}")
94+
9195
return stopped_count > 0
9296

9397
def is_preprocess_running(self, conversation_id: int) -> bool:
9498
"""Check if any preprocess task is running for a conversation"""
9599
with self._lock:
96100
if conversation_id not in self.conversation_tasks:
97101
return False
98-
102+
99103
for task_id in self.conversation_tasks[conversation_id]:
100104
if task_id in self.preprocess_tasks:
101105
task = self.preprocess_tasks[task_id]
102106
if task.is_running and not task.stop_event.is_set():
103107
return True
104-
108+
105109
return False
106110

107111
def get_preprocess_status(self, conversation_id: int) -> Dict:
108112
"""Get preprocess status for a conversation"""
109113
with self._lock:
110114
if conversation_id not in self.conversation_tasks:
111115
return {"running": False, "task_count": 0}
112-
116+
113117
running_tasks = []
114118
for task_id in self.conversation_tasks[conversation_id]:
115119
if task_id in self.preprocess_tasks:
@@ -119,7 +123,7 @@ def get_preprocess_status(self, conversation_id: int) -> Dict:
119123
"is_running": task.is_running,
120124
"stopped": task.stop_event.is_set()
121125
})
122-
126+
123127
return {
124128
"running": any(task["is_running"] for task in running_tasks),
125129
"task_count": len(running_tasks),

backend/apps/agent_app.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,6 @@ async def import_agent_api(request: AgentImportRequest, authorization: Optional[
139139
status_code=HTTPStatus.INTERNAL_SERVER_ERROR, detail="Agent import error.")
140140

141141

142-
143142
@router.get("/list")
144143
async def list_all_agent_info_api(authorization: Optional[str] = Header(None), request: Request = None):
145144
"""

0 commit comments

Comments
 (0)