Skip to content

Commit 958fee2

Browse files
authored
♻️ The agent import performance improvement #1905
2 parents 143bd44 + 1b23132 commit 958fee2

File tree

10 files changed

+1249
-1080
lines changed

10 files changed

+1249
-1080
lines changed

backend/services/agent_service.py

Lines changed: 8 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
update_related_agents
4242
)
4343
from database.model_management_db import get_model_by_model_id, get_model_id_by_display_name
44-
from database.remote_mcp_db import check_mcp_name_exists, get_mcp_server_by_name_and_tenant
44+
from database.remote_mcp_db import get_mcp_server_by_name_and_tenant
4545
from database.tool_db import (
4646
check_tool_is_available,
4747
create_or_update_tool_by_tool_info,
@@ -53,8 +53,6 @@
5353
)
5454
from services.conversation_management_service import save_conversation_assistant, save_conversation_user
5555
from services.memory_config_service import build_memory_context
56-
from services.remote_mcp_service import add_remote_mcp_server_list
57-
from services.tool_configuration_service import update_tool_list
5856
from utils.auth_utils import get_current_user_info, get_user_language
5957
from utils.config_utils import tenant_config_manager
6058
from utils.memory_utils import build_memory_config
@@ -899,52 +897,17 @@ async def import_agent_impl(
899897
force_import: bool = False
900898
):
901899
"""
902-
Import agent using DFS
900+
Import agent using DFS.
901+
902+
Note:
903+
MCP server registration and tool list refresh are now handled
904+
on the frontend / dedicated MCP configuration flows.
905+
The backend import logic only consumes the tools that already
906+
exist for the current tenant.
903907
"""
904908
user_id, tenant_id, _ = get_current_user_info(authorization)
905909
agent_id = agent_info.agent_id
906910

907-
# First, add MCP servers if any
908-
if agent_info.mcp_info:
909-
for mcp_info in agent_info.mcp_info:
910-
if mcp_info.mcp_server_name and mcp_info.mcp_url:
911-
try:
912-
# Check if MCP name already exists
913-
if check_mcp_name_exists(mcp_name=mcp_info.mcp_server_name, tenant_id=tenant_id):
914-
# Get existing MCP server info to compare URLs
915-
existing_mcp = get_mcp_server_by_name_and_tenant(mcp_name=mcp_info.mcp_server_name,
916-
tenant_id=tenant_id)
917-
if existing_mcp and existing_mcp == mcp_info.mcp_url:
918-
# Same name and URL, skip
919-
logger.info(
920-
f"MCP server {mcp_info.mcp_server_name} with same URL already exists, skipping")
921-
continue
922-
else:
923-
# Same name but different URL, add import prefix
924-
import_mcp_name = f"import_{mcp_info.mcp_server_name}"
925-
logger.info(
926-
f"MCP server {mcp_info.mcp_server_name} exists with different URL, using name: {import_mcp_name}")
927-
mcp_server_name = import_mcp_name
928-
else:
929-
# Name doesn't exist, use original name
930-
mcp_server_name = mcp_info.mcp_server_name
931-
932-
await add_remote_mcp_server_list(
933-
tenant_id=tenant_id,
934-
user_id=user_id,
935-
remote_mcp_server=mcp_info.mcp_url,
936-
remote_mcp_server_name=mcp_server_name
937-
)
938-
except Exception as e:
939-
raise Exception(
940-
f"Failed to add MCP server {mcp_info.mcp_server_name}: {str(e)}")
941-
942-
# Then, update tool list to include new MCP tools
943-
try:
944-
await update_tool_list(tenant_id=tenant_id, user_id=user_id)
945-
except Exception as e:
946-
raise Exception(f"Failed to update tool list: {str(e)}")
947-
948911
agent_stack = deque([agent_id])
949912
agent_id_set = set()
950913
mapping_agent_id = {}

frontend/app/[locale]/agents/components/AgentSetupOrchestrator.tsx

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,14 @@ import {
1717
searchToolConfig,
1818
updateToolConfig,
1919
} from "@/services/agentConfigService";
20-
import { useAgentImport } from "@/hooks/useAgentImport";
20+
import { useAgentImport, ImportAgentData } from "@/hooks/useAgentImport";
2121
import {
2222
Agent,
2323
AgentSetupOrchestratorProps,
2424
Tool,
2525
ToolParam,
2626
} from "@/types/agentConfig";
27+
import AgentImportWizard from "@/components/agent/AgentImportWizard";
2728
import log from "@/lib/logger";
2829

2930
import SubAgentPool from "./agent/SubAgentPool";
@@ -104,6 +105,10 @@ export default function AgentSetupOrchestrator({
104105
const [importingAction, setImportingAction] = useState<
105106
"force" | "regenerate" | null
106107
>(null);
108+
109+
// Agent import wizard states
110+
const [importWizardVisible, setImportWizardVisible] = useState(false);
111+
const [importWizardData, setImportWizardData] = useState<ImportAgentData | null>(null);
107112
// Use generation state passed from parent component, not local state
108113

109114
// Delete confirmation popup status
@@ -1589,7 +1594,7 @@ export default function AgentSetupOrchestrator({
15891594
[runNormalImport, runForceImport]
15901595
);
15911596

1592-
// Handle importing agent
1597+
// Handle importing agent - use AgentImportWizard for ExportAndImportDataFormat
15931598
const handleImportAgent = (t: TFunction) => {
15941599
// Create a hidden file input element
15951600
const fileInput = document.createElement("input");
@@ -1618,6 +1623,20 @@ export default function AgentSetupOrchestrator({
16181623
return;
16191624
}
16201625

1626+
// Check if it's ExportAndImportDataFormat (has agent_id and agent_info)
1627+
if (agentInfo.agent_id && agentInfo.agent_info && typeof agentInfo.agent_info === "object") {
1628+
// Use AgentImportWizard for full agent import with configuration
1629+
const importData: ImportAgentData = {
1630+
agent_id: agentInfo.agent_id,
1631+
agent_info: agentInfo.agent_info,
1632+
mcp_info: agentInfo.mcp_info || [],
1633+
};
1634+
setImportWizardData(importData);
1635+
setImportWizardVisible(true);
1636+
return;
1637+
}
1638+
1639+
// Fallback to legacy import logic for other formats
16211640
const normalizeValue = (value?: string | null) =>
16221641
typeof value === "string" ? value.trim() : "";
16231642

@@ -1700,6 +1719,13 @@ export default function AgentSetupOrchestrator({
17001719
fileInput.click();
17011720
};
17021721

1722+
// Handle import completion from wizard
1723+
const handleImportComplete = () => {
1724+
refreshAgentList(t, false);
1725+
setImportWizardVisible(false);
1726+
setImportWizardData(null);
1727+
};
1728+
17031729
const handleConfirmedDuplicateImport = useCallback(async () => {
17041730
if (!pendingImportData) {
17051731
return;
@@ -2256,6 +2282,23 @@ export default function AgentSetupOrchestrator({
22562282
{t("businessLogic.config.import.duplicateDescription")}
22572283
</p>
22582284
</Modal>
2285+
{/* Agent Import Wizard */}
2286+
<AgentImportWizard
2287+
visible={importWizardVisible}
2288+
onCancel={() => {
2289+
setImportWizardVisible(false);
2290+
setImportWizardData(null);
2291+
}}
2292+
initialData={importWizardData}
2293+
onImportComplete={handleImportComplete}
2294+
title={undefined} // Use default title
2295+
agentDisplayName={
2296+
importWizardData?.agent_info?.[String(importWizardData.agent_id)]?.display_name
2297+
}
2298+
agentDescription={
2299+
importWizardData?.agent_info?.[String(importWizardData.agent_id)]?.description
2300+
}
2301+
/>
22592302
{/* Auto unselect knowledge_base_search notice when embedding not configured */}
22602303
<Modal
22612304
title={t("embedding.agentToolAutoDeselectModal.title")}

frontend/app/[locale]/agents/components/McpConfigModal.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,8 @@ export default function McpConfigModal({
164164
content: t("mcpConfig.delete.confirmContent", {
165165
name: server.service_name,
166166
}),
167+
okText: t("common.delete", "Delete"),
168+
cancelText: t("common.cancel", "Cancel"),
167169
okType: "danger",
168170
cancelButtonProps: { disabled: updatingTools },
169171
okButtonProps: { disabled: updatingTools, loading: updatingTools },

0 commit comments

Comments
 (0)