Skip to content

Commit f1d6b17

Browse files
authored
♻️ The agent import performance improvement: add existing tool check
2 parents 12f0f35 + f8b73bd commit f1d6b17

File tree

11 files changed

+263
-897
lines changed

11 files changed

+263
-897
lines changed

backend/config_service.py

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import uvicorn
22
import logging
33
import warnings
4-
import asyncio
54

65
from consts.const import APP_VERSION
76

@@ -12,30 +11,14 @@
1211

1312
from apps.config_app import app
1413
from utils.logging_utils import configure_logging, configure_elasticsearch_logging
15-
from services.tool_configuration_service import initialize_tools_on_startup
14+
1615

1716
configure_logging(logging.INFO)
1817
configure_elasticsearch_logging()
1918
logger = logging.getLogger("config_service")
2019

2120

22-
async def startup_initialization():
23-
"""
24-
Perform initialization tasks during server startup
25-
"""
21+
if __name__ == "__main__":
2622
logger.info("Starting server initialization...")
2723
logger.info(f"APP version is: {APP_VERSION}")
28-
try:
29-
# Initialize tools on startup - service layer handles detailed logging
30-
await initialize_tools_on_startup()
31-
logger.info("Server initialization completed successfully!")
32-
33-
except Exception as e:
34-
logger.error(f"Server initialization failed: {str(e)}")
35-
# Don't raise the exception to allow server to start even if initialization fails
36-
logger.warning("Server will continue to start despite initialization issues")
37-
38-
39-
if __name__ == "__main__":
40-
asyncio.run(startup_initialization())
4124
uvicorn.run(app, host="0.0.0.0", port=5010, log_level="info")

backend/runtime_service.py

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import uvicorn
22
import logging
33
import warnings
4-
import asyncio
54

65
from consts.const import APP_VERSION
76

@@ -12,31 +11,16 @@
1211

1312
from apps.runtime_app import app
1413
from utils.logging_utils import configure_logging, configure_elasticsearch_logging
15-
from services.tool_configuration_service import initialize_tools_on_startup
14+
1615

1716
configure_logging(logging.INFO)
1817
configure_elasticsearch_logging()
1918
logger = logging.getLogger("runtime_service")
2019

2120

22-
async def startup_initialization():
23-
"""
24-
Perform initialization tasks during server startup
25-
"""
21+
if __name__ == "__main__":
2622
logger.info("Starting server initialization...")
2723
logger.info(f"APP version is: {APP_VERSION}")
28-
try:
29-
# Initialize tools on startup - service layer handles detailed logging
30-
await initialize_tools_on_startup()
31-
logger.info("Server initialization completed successfully!")
32-
except Exception as e:
33-
logger.error(f"Server initialization failed: {str(e)}")
34-
# Don't raise the exception to allow server to start even if initialization fails
35-
logger.warning("Server will continue to start despite initialization issues")
36-
37-
38-
if __name__ == "__main__":
39-
asyncio.run(startup_initialization())
4024
uvicorn.run(app, host="0.0.0.0", port=5014, log_level="info")
4125

4226

backend/services/tool_configuration_service.py

Lines changed: 1 addition & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
import jsonref
1212
from mcpadapt.smolagents_adapter import _sanitize_function_name
1313

14-
from consts.const import DEFAULT_USER_ID, LOCAL_MCP_SERVER, DATA_PROCESS_SERVICE
14+
from consts.const import LOCAL_MCP_SERVER, DATA_PROCESS_SERVICE
1515
from consts.exceptions import MCPConnectionError, ToolExecutionException, NotFoundException
1616
from consts.model import ToolInstanceInfoRequest, ToolInfo, ToolSourceEnum, ToolValidateRequest
1717
from database.remote_mcp_db import get_mcp_records_by_tenant, get_mcp_server_by_name_and_tenant
@@ -22,7 +22,6 @@
2222
update_tool_table_from_scan_tool_list,
2323
search_last_tool_instance_by_tool_id,
2424
)
25-
from database.user_tenant_db import get_all_tenant_ids
2625
from services.file_management_service import get_llm_model
2726
from services.vectordatabase_service import get_embedding_model, get_vector_db_core
2827
from services.tenant_config_service import get_selected_knowledge_list, build_knowledge_name_mapping
@@ -367,71 +366,6 @@ async def list_all_tools(tenant_id: str):
367366
return formatted_tools
368367

369368

370-
async def initialize_tools_on_startup():
371-
"""
372-
Initialize and scan all tools during server startup for all tenants
373-
374-
This function scans all available tools (local, LangChain, and MCP)
375-
and updates the database with the latest tool information for all tenants.
376-
"""
377-
378-
logger.info("Starting tool initialization on server startup...")
379-
380-
try:
381-
# Get all tenant IDs from the database
382-
tenant_ids = get_all_tenant_ids()
383-
384-
if not tenant_ids:
385-
logger.warning("No tenants found in database, skipping tool initialization")
386-
return
387-
388-
logger.info(f"Found {len(tenant_ids)} tenants: {tenant_ids}")
389-
390-
total_tools = 0
391-
successful_tenants = 0
392-
failed_tenants = []
393-
394-
# Process each tenant
395-
for tenant_id in tenant_ids:
396-
try:
397-
logger.info(f"Initializing tools for tenant: {tenant_id}")
398-
399-
# Add timeout to prevent hanging during startup
400-
try:
401-
await asyncio.wait_for(
402-
update_tool_list(tenant_id=tenant_id, user_id=DEFAULT_USER_ID),
403-
timeout=60.0 # 60 seconds timeout per tenant
404-
)
405-
406-
# Get the count of tools for this tenant
407-
tools_info = query_all_tools(tenant_id)
408-
tenant_tool_count = len(tools_info)
409-
total_tools += tenant_tool_count
410-
successful_tenants += 1
411-
412-
logger.info(f"Tenant {tenant_id}: {tenant_tool_count} tools initialized")
413-
414-
except asyncio.TimeoutError:
415-
logger.error(f"Tool initialization timed out for tenant {tenant_id}")
416-
failed_tenants.append(f"{tenant_id} (timeout)")
417-
418-
except Exception as e:
419-
logger.error(f"Tool initialization failed for tenant {tenant_id}: {str(e)}")
420-
failed_tenants.append(f"{tenant_id} (error: {str(e)})")
421-
422-
# Log final results
423-
logger.info("Tool initialization completed!")
424-
logger.info(f"Total tools available across all tenants: {total_tools}")
425-
logger.info(f"Successfully processed: {successful_tenants}/{len(tenant_ids)} tenants")
426-
427-
if failed_tenants:
428-
logger.warning(f"Failed tenants: {', '.join(failed_tenants)}")
429-
430-
except Exception as e:
431-
logger.error(f"❌ Tool initialization failed: {str(e)}")
432-
raise
433-
434-
435369
def load_last_tool_config_impl(tool_id: int, tenant_id: str, user_id: str):
436370
"""
437371
Load the last tool configuration for a given tool ID

doc/docs/en/user-guide/agent-development.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ If you have an existing agent configuration, you can also import it:
1919
> - **Import anyway**: Keep the duplicate name; the imported agent will be in an unavailable state and requires manual modification of the Agent name and variable name before it can be used
2020
> - **Regenerate and import**: The system will call the LLM to rename the Agent, which will consume a certain amount of model tokens and may take longer
2121
22+
> 📌 **Important:** For agents created via import, if their tools include `knowledge_base_search` or other knowledge base search tools, these tools will only search **knowledge bases that the currently logged-in user is allowed to access in this environment**. The original knowledge base configuration in the exported agent will *not* be automatically inherited, so actual search results and answer quality may differ from what the original author observed.
23+
2224
<div style="display: flex; justify-content: left;">
2325
<img src="./assets/agent-development/duplicated_import.png" style="width: 80%; height: auto;" />
2426
</div>

doc/docs/zh/user-guide/agent-development.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
> - **直接导入**:保留重复名称,导入后的智能体会处于不可用状态,需手动修改 Agent 名称和变量名后才能使用
2020
> - **重新生成并导入**:系统将调用 LLM 对 Agent 进行重命名,会消耗一定的模型 token 数,可能耗时较长
2121
22+
> 📌 **重要说明**:通过导入创建的智能体,如果其工具中包含 `knowledge_base_search` 等知识库检索工具,这些工具只会检索**当前登录用户在本环境中有权限访问的知识库**。导入文件中原有的知识库配置不会自动继承,因此实际检索结果和回答效果,可能与智能体原作者环境下的表现存在差异。
23+
2224
<div style="display: flex; justify-content: left;">
2325
<img src="./assets/agent-development/duplicated_import.png" style="width: 80%; height: auto;" />
2426
</div>

0 commit comments

Comments
 (0)