Skip to content

Commit fcc6be4

Browse files
committed
Merge remote-tracking branch 'origin/develop' into xyc/agent-northbound-0820
# Conflicts: # test/backend/services/test_prompt_service.py
2 parents 784f1c0 + ce9b72b commit fcc6be4

File tree

14 files changed

+1185
-298
lines changed

14 files changed

+1185
-298
lines changed

backend/agents/create_agent_info.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
from services.remote_mcp_service import get_remote_mcp_server_list
77
from utils.auth_utils import get_current_user_id
88

9-
from database.agent_db import search_agent_info_by_agent_id, search_tools_for_sub_agent, \
10-
query_sub_agents_id_list
9+
from database.agent_db import search_agent_info_by_agent_id, query_sub_agents_id_list
10+
from database.tool_db import search_tools_for_sub_agent
1111
from services.elasticsearch_service import ElasticSearchService, elastic_core, get_embedding_model
1212
from services.tenant_config_service import get_selected_knowledge_list
1313
from utils.prompt_template_utils import get_agent_prompt_template

backend/apps/tool_config_app.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from fastapi import HTTPException, APIRouter
22
from fastapi.responses import JSONResponse
33
import logging
4-
from database.agent_db import query_all_tools
4+
from database.tool_db import query_all_tools
55
from consts.model import ToolInstanceInfoRequest, ToolInstanceSearchRequest
66
from services.tool_configuration_service import search_tool_info_impl, update_tool_info_impl, update_tool_list
77
from fastapi import Header

backend/database/agent_db.py

Lines changed: 13 additions & 213 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
1-
import re
21
import logging
3-
from typing import List
42

53
from database.client import get_db_session, as_dict, filter_property
6-
from database.db_models import ToolInfo, AgentInfo, ToolInstance, AgentRelation
4+
from database.db_models import AgentInfo, ToolInstance, AgentRelation
75

86
logger = logging.getLogger("agent_db")
97

@@ -112,120 +110,6 @@ def update_agent(agent_id, agent_info, tenant_id, user_id):
112110
setattr(agent, key, value)
113111
agent.updated_by = user_id
114112

115-
def create_tool(tool_info):
116-
"""
117-
Create ToolInstance in the database based on tenant_id and agent_id, optional user_id.
118-
:param tool_info: Dictionary containing tool information
119-
120-
:return: Created or updated ToolInstance object
121-
"""
122-
with get_db_session() as session:
123-
# Create a new ToolInstance
124-
new_tool_instance = ToolInstance(**filter_property(tool_info, ToolInstance))
125-
session.add(new_tool_instance)
126-
127-
def create_or_update_tool_by_tool_info(tool_info, tenant_id: str, user_id: str):
128-
"""
129-
Create or update a ToolInstance in the database based on tenant_id and agent_id, optional user_id.
130-
131-
:param tool_info: Dictionary containing tool information
132-
:param tenant_id: Tenant ID for filtering, mandatory
133-
:param user_id: Optional user ID for filtering
134-
:return: Created or updated ToolInstance object
135-
"""
136-
137-
tool_info_dict = tool_info.__dict__ | {"tenant_id": tenant_id, "user_id": user_id}
138-
139-
with get_db_session() as session:
140-
# Query if there is an existing ToolInstance
141-
query = session.query(ToolInstance).filter(
142-
ToolInstance.tenant_id == tenant_id,
143-
ToolInstance.user_id == user_id,
144-
ToolInstance.agent_id == tool_info_dict['agent_id'],
145-
ToolInstance.delete_flag != 'Y',
146-
ToolInstance.tool_id == tool_info_dict['tool_id']
147-
)
148-
149-
tool_instance = query.first()
150-
151-
if tool_instance:
152-
# Update the existing ToolInstance
153-
for key, value in tool_info_dict.items():
154-
if hasattr(tool_instance, key):
155-
setattr(tool_instance, key, value)
156-
else:
157-
create_tool(tool_info_dict)
158-
159-
session.flush()
160-
return tool_instance
161-
162-
def query_all_tools(tenant_id: str):
163-
"""
164-
Query ToolInfo in the database based on tenant_id and agent_id, optional user_id.
165-
Filter tools that belong to the specific tenant_id or have tenant_id as "tenant_id"
166-
:return: List of ToolInfo objects
167-
"""
168-
with get_db_session() as session:
169-
query = session.query(ToolInfo).filter(
170-
ToolInfo.delete_flag != 'Y',
171-
ToolInfo.author == tenant_id)
172-
173-
tools = query.all()
174-
return [as_dict(tool) for tool in tools]
175-
176-
def query_tool_instances_by_id(agent_id: int, tool_id: int, tenant_id: str, user_id: str = None):
177-
"""
178-
Query ToolInstance in the database based on tenant_id and agent_id, optional user_id.
179-
:param agent_id: Agent ID for filtering, mandatory
180-
:param tool_id: Tool ID for filtering, mandatory
181-
:param tenant_id: Tenant ID for filtering, mandatory
182-
:param user_id: Optional user ID for filtering
183-
:return: List of ToolInstance objects
184-
"""
185-
with get_db_session() as session:
186-
query = session.query(ToolInstance).filter(
187-
ToolInstance.tenant_id == tenant_id,
188-
ToolInstance.agent_id == agent_id,
189-
ToolInstance.tool_id == tool_id,
190-
ToolInstance.delete_flag != 'Y')
191-
if user_id:
192-
query = query.filter(ToolInstance.user_id == user_id)
193-
tool_instance = query.first()
194-
if tool_instance:
195-
return as_dict(tool_instance)
196-
else:
197-
return None
198-
199-
def query_tools_by_ids(tool_id_list: List[int]):
200-
"""
201-
Query ToolInfo in the database based on tool_id_list.
202-
:param tool_id_list: List of tool IDs
203-
:return: List of ToolInfo objects
204-
"""
205-
with get_db_session() as session:
206-
tools = session.query(ToolInfo).filter(ToolInfo.tool_id.in_(tool_id_list)).filter(ToolInfo.delete_flag != 'Y').all()
207-
return [as_dict(tool) for tool in tools]
208-
209-
def query_all_enabled_tool_instances(agent_id: int, tenant_id: str, user_id: str = None):
210-
"""
211-
Query ToolInstance in the database based on tenant_id and agent_id, optional user_id.
212-
:param tenant_id: Tenant ID for filtering, mandatory
213-
:param user_id: Optional user ID for filtering
214-
:param agent_id: Optional agent ID for filtering
215-
:return: List of ToolInstance objects
216-
"""
217-
with get_db_session() as session:
218-
query = session.query(ToolInstance).filter(
219-
ToolInstance.tenant_id == tenant_id,
220-
ToolInstance.delete_flag != 'Y',
221-
ToolInstance.enabled,
222-
ToolInstance.agent_id == agent_id)
223-
if user_id:
224-
query = query.filter(ToolInstance.user_id == user_id)
225-
226-
tools = query.all()
227-
return [as_dict(tool) for tool in tools]
228-
229113
def delete_agent_by_id(agent_id, tenant_id: str, user_id: str):
230114
"""
231115
Delete an agent in the database.
@@ -237,95 +121,12 @@ def delete_agent_by_id(agent_id, tenant_id: str, user_id: str):
237121
with get_db_session() as session:
238122
session.query(AgentInfo).filter(AgentInfo.agent_id == agent_id,
239123
AgentInfo.tenant_id == tenant_id).update(
240-
{'delete_flag': 'Y', 'updated_by': user_id})
124+
{AgentInfo.delete_flag: 'Y', 'updated_by': user_id})
241125
session.query(ToolInstance).filter(ToolInstance.agent_id == agent_id,
242-
AgentInfo.tenant_id == tenant_id).update(
126+
ToolInstance.tenant_id == tenant_id).update(
243127
{ToolInstance.delete_flag: 'Y', 'updated_by': user_id})
128+
session.commit()
244129

245-
def update_tool_table_from_scan_tool_list(tenant_id: str, user_id: str, tool_list: List[ToolInfo]):
246-
"""
247-
scan all tools and update the tool table in PG database, remove the duplicate tools
248-
"""
249-
try:
250-
with get_db_session() as session:
251-
# get all existing tools (including complete information)
252-
existing_tools = session.query(ToolInfo).filter(ToolInfo.delete_flag != 'Y',
253-
ToolInfo.author == tenant_id).all()
254-
existing_tool_dict = {f"{tool.name}&{tool.source}": tool for tool in existing_tools}
255-
# set all tools to unavailable
256-
for tool in existing_tools:
257-
tool.is_available = False
258-
259-
for tool in tool_list:
260-
filtered_tool_data = filter_property(tool.__dict__, ToolInfo)
261-
262-
# check if the tool name is valid
263-
is_available = True if re.match(r'^[a-zA-Z_][a-zA-Z0-9_]*$', tool.name) is not None else False
264-
265-
if f"{tool.name}&{tool.source}" in existing_tool_dict:
266-
# by tool name and source to update the existing tool
267-
existing_tool = existing_tool_dict[f"{tool.name}&{tool.source}"]
268-
for key, value in filtered_tool_data.items():
269-
setattr(existing_tool, key, value)
270-
existing_tool.updated_by = user_id
271-
existing_tool.is_available = is_available
272-
else:
273-
# create new tool
274-
filtered_tool_data.update({"created_by": user_id, "updated_by": user_id, "author": tenant_id, "is_available": is_available})
275-
new_tool = ToolInfo(**filtered_tool_data)
276-
session.add(new_tool)
277-
session.flush()
278-
logger.info("Updated tool table in PG database")
279-
except Exception as e:
280-
logger.error(f"Updated tool table failed due to {e}")
281-
282-
def add_tool_field(tool_info):
283-
with get_db_session() as session:
284-
# Query if there is an existing ToolInstance
285-
query = session.query(ToolInfo).filter(ToolInfo.tool_id == tool_info["tool_id"])
286-
tool = query.first()
287-
288-
# add tool params
289-
tool_params = tool.params
290-
for ele in tool_params:
291-
ele["default"] = tool_info["params"][ele["name"]]
292-
293-
tool_info["params"] =tool_params
294-
tool_info["name"] = tool.name
295-
tool_info["description"] = tool.description
296-
tool_info["source"] = tool.source
297-
tool_info["class_name"] = tool.class_name
298-
tool_info["is_available"] = tool.is_available
299-
tool_info["usage"] = tool.usage
300-
tool_info["inputs"] = tool.inputs
301-
tool_info["output_type"] = tool.output_type
302-
return tool_info
303-
304-
def search_tools_for_sub_agent(agent_id, tenant_id):
305-
with get_db_session() as session:
306-
# Query if there is an existing ToolInstance
307-
query = session.query(ToolInstance).filter(ToolInstance.agent_id == agent_id,
308-
ToolInstance.tenant_id == tenant_id,
309-
ToolInstance.delete_flag != 'Y',
310-
ToolInstance.enabled == True)
311-
312-
tool_instances = query.all()
313-
tools_list = []
314-
for tool_instance in tool_instances:
315-
tool_instance_dict = as_dict(tool_instance)
316-
new_tool_instance_dict = add_tool_field(tool_instance_dict)
317-
318-
tools_list.append(new_tool_instance_dict)
319-
return tools_list
320-
321-
def check_tool_is_available(tool_id_list: List[int]):
322-
"""
323-
Check if the tool is available
324-
"""
325-
with get_db_session() as session:
326-
tools = session.query(ToolInfo).filter(ToolInfo.tool_id.in_(tool_id_list), ToolInfo.delete_flag != 'Y').all()
327-
return [tool.is_available for tool in tools]
328-
329130
def query_all_agent_info_by_tenant_id(tenant_id: str):
330131
"""
331132
Query all agent info by tenant id
@@ -363,13 +164,12 @@ def delete_related_agent(parent_agent_id: int, child_agent_id: int, tenant_id: s
363164
logger.error(f"Failed to delete related agent: {str(e)}")
364165
return False
365166

366-
def delete_all_related_agent(parent_agent_id: int, tenant_id: str)->bool:
367-
try:
368-
with get_db_session() as session:
369-
session.query(AgentRelation).filter(AgentRelation.parent_agent_id == parent_agent_id,
370-
AgentRelation.tenant_id == tenant_id).update(
371-
{ToolInstance.delete_flag: 'Y', 'updated_by': tenant_id})
372-
return True
373-
except Exception as e:
374-
logger.error(f"Failed to delete related agent: {str(e)}")
375-
return False
167+
def delete_agent_relationship(agent_id: int, tenant_id: str, user_id: str):
168+
with get_db_session() as session:
169+
session.query(AgentRelation).filter(AgentRelation.parent_agent_id == agent_id,
170+
AgentRelation.tenant_id == tenant_id).update(
171+
{AgentRelation.delete_flag: 'Y', 'updated_by': user_id})
172+
session.query(AgentRelation).filter(AgentRelation.selected_agent_id == agent_id,
173+
AgentRelation.tenant_id == tenant_id).update(
174+
{AgentRelation.delete_flag: 'Y', 'updated_by': user_id})
175+
session.commit()

0 commit comments

Comments
 (0)