fix MCP tool name limits

This commit is contained in:
Danny Avila 2026-06-07 09:22:29 -04:00
parent d8427ffc5e
commit 1349a2cd2d
13 changed files with 682 additions and 61 deletions

View file

@ -27,6 +27,8 @@ const {
buildMCPAuthRunStepEvent,
buildMCPAuthRunStepDeltaEvent,
buildMCPAuthRunStepCompletedEvent,
resolveToolNameMaxLength,
resolveToolNameForExecution,
isFileAuthoringToolDefinition,
ASK_USER_QUESTION_TOOL_NAME,
} = require('@librechat/api');
@ -561,6 +563,10 @@ async function loadToolDefinitionsWrapper({
}
const appConfig = req.config;
const toolNameMaxLength = resolveToolNameMaxLength({
appConfig,
provider: agent.provider,
});
const enabledCapabilities = await resolveAgentCapabilities(req, appConfig, agent.id);
const checkCapability = (capability) => enabledCapabilities.has(capability);
@ -885,6 +891,7 @@ async function loadToolDefinitionsWrapper({
programmaticToolsEnabled,
codeExecutionEnabled,
provider: agent.provider,
toolNameMaxLength,
},
{
isBuiltInTool,
@ -967,6 +974,7 @@ async function loadToolDefinitionsWrapper({
programmaticToolsEnabled,
codeExecutionEnabled,
provider: agent.provider,
toolNameMaxLength,
},
{
isBuiltInTool,
@ -1127,6 +1135,10 @@ async function loadAgentTools({
}
const appConfig = req.config;
const toolNameMaxLength = resolveToolNameMaxLength({
appConfig,
provider: agent.provider,
});
const enabledCapabilities = await resolveAgentCapabilities(req, appConfig, agent.id);
const checkCapability = (capability) => {
const enabled = enabledCapabilities.has(capability);
@ -1233,6 +1245,7 @@ async function loadAgentTools({
programmaticToolsEnabled,
codeExecutionEnabled,
authHeaders: () => getCodeApiAuthHeaders(req),
toolNameMaxLength,
});
const agentTools = [];
@ -1487,6 +1500,8 @@ async function loadToolsForExecution({
}) {
const appConfig = req.config;
const allLoadedTools = [];
const runtimeToolMap = new Map();
const runtimeNamesByLoadName = new Map();
const mcpRequestScopedConnections = requestScopedConnections ?? getMCPRequestContext(req, res);
const configurable = { userMCPAuthMap, requestScopedConnections: mcpRequestScopedConnections };
/** Per-agent set of tools that received the injected `run_in_background`
@ -1496,6 +1511,31 @@ async function loadToolsForExecution({
configurable.backgroundToolNames = backgroundToolNames;
}
const addRuntimeNameForLoadName = (loadName, runtimeName) => {
if (!loadName || !runtimeName) {
return;
}
const runtimeNames = runtimeNamesByLoadName.get(loadName) ?? new Set();
runtimeNames.add(runtimeName);
runtimeNamesByLoadName.set(loadName, runtimeNames);
};
const addLoadedTool = (tool) => {
allLoadedTools.push(tool);
if (!tool?.name) {
return;
}
runtimeToolMap.set(tool.name, tool);
const runtimeNames = runtimeNamesByLoadName.get(tool.name);
if (!runtimeNames) {
return;
}
for (const runtimeName of runtimeNames) {
runtimeToolMap.set(runtimeName, tool);
}
};
const isToolSearch = toolNames.includes(AgentConstants.TOOL_SEARCH);
const ptcToolNames = [
AgentConstants.BASH_PROGRAMMATIC_TOOL_CALLING,
@ -1543,7 +1583,7 @@ async function loadToolsForExecution({
mode: 'local',
toolRegistry,
});
allLoadedTools.push(toolSearchTool);
addLoadedTool(toolSearchTool);
configurable.toolRegistry = toolRegistry;
}
@ -1559,7 +1599,7 @@ async function loadToolsForExecution({
authHeaders: () => getCodeApiAuthHeaders(req),
});
ptcTool.name = name;
allLoadedTools.push(ptcTool);
addLoadedTool(ptcTool);
}
} catch (error) {
logger.error('[loadToolsForExecution] Error creating PTC tool:', error);
@ -1582,7 +1622,7 @@ async function loadToolsForExecution({
authHeaders: () => getCodeApiAuthHeaders(req),
statefulSessions: statefulCodeSessions,
});
allLoadedTools.push(bashTool);
addLoadedTool(bashTool);
} catch (error) {
logger.error('[loadToolsForExecution] Failed to create bash_tool', error);
}
@ -1630,9 +1670,21 @@ async function loadToolsForExecution({
? [...new Set([...allowedNonSpecialToolNames, ...ptcOrchestratedToolNames])]
: allowedNonSpecialToolNames;
const resolvedToolNamesToLoad = [];
for (const name of allToolNamesToLoad) {
const resolvedName = resolveToolNameForExecution(name, toolRegistry);
addRuntimeNameForLoadName(resolvedName, name);
addRuntimeNameForLoadName(resolvedName, resolvedName);
resolvedToolNamesToLoad.push(resolvedName);
if (resolvedName !== name) {
logger.debug(`[loadToolsForExecution] Resolved tool name "${name}" -> "${resolvedName}"`);
}
}
const uniqueToolNamesToLoad = [...new Set(resolvedToolNamesToLoad)];
const actionToolNames = [];
const regularToolNames = [];
for (const name of allToolNamesToLoad) {
for (const name of uniqueToolNamesToLoad) {
(isActionTool(name) ? actionToolNames : regularToolNames).push(name);
}
@ -1667,7 +1719,9 @@ async function loadToolsForExecution({
});
if (loadedTools) {
allLoadedTools.push(...loadedTools);
for (const tool of loadedTools) {
addLoadedTool(tool);
}
}
}
@ -1681,7 +1735,9 @@ async function loadToolsForExecution({
jobCreatedAt,
actionToolNames,
});
allLoadedTools.push(...actionTools);
for (const tool of actionTools) {
addLoadedTool(tool);
}
} else if (actionToolNames.length > 0 && agent && !actionsEnabled) {
logger.warn(
`[loadToolsForExecution] Capability "${AgentCapabilities.actions}" disabled. ` +
@ -1691,13 +1747,12 @@ async function loadToolsForExecution({
if (isPTC && allLoadedTools.length > 0) {
const ptcToolMap = new Map();
for (const tool of allLoadedTools) {
for (const [name, tool] of runtimeToolMap.entries()) {
if (
tool.name &&
tool.name !== AgentConstants.PROGRAMMATIC_TOOL_CALLING &&
tool.name !== AgentConstants.BASH_PROGRAMMATIC_TOOL_CALLING
name !== AgentConstants.PROGRAMMATIC_TOOL_CALLING &&
name !== AgentConstants.BASH_PROGRAMMATIC_TOOL_CALLING
) {
ptcToolMap.set(tool.name, tool);
ptcToolMap.set(name, tool);
}
}
configurable.ptcToolMap = ptcToolMap;
@ -1706,6 +1761,7 @@ async function loadToolsForExecution({
return {
configurable,
loadedTools: allLoadedTools,
toolMap: runtimeToolMap,
};
}