Merge pull request #18835 from BerriAI/litellm_ui_build_fix_00

[Infra] Fixing UI Build
This commit is contained in:
yuneng-jiang 2026-01-08 13:12:56 -08:00 • committed by GitHub
commit 1d19974737
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 128 additions and 94 deletions

View file

@ -84,10 +84,7 @@ interface ChatUIProps {
};
}
const MCP_SUPPORTED_ENDPOINTS = new Set<EndpointType>([
EndpointType.CHAT,
EndpointType.RESPONSES,
]);
const MCP_SUPPORTED_ENDPOINTS = new Set<EndpointType>([EndpointType.CHAT, EndpointType.RESPONSES]);
const ChatUI: React.FC<ChatUIProps> = ({
accessToken,
@ -131,7 +128,7 @@ const ChatUI: React.FC<ChatUIProps> = ({
});
const [apiKey, setApiKey] = useState<string>(() => sessionStorage.getItem("apiKey") || "");
const [customProxyBaseUrl, setCustomProxyBaseUrl] = useState<string>(
() => sessionStorage.getItem("customProxyBaseUrl") || ""
() => sessionStorage.getItem("customProxyBaseUrl") || "",
);
const [inputMessage, setInputMessage] = useState("");
const [chatHistory, setChatHistory] = useState<MessageType[]>(() => {
@ -215,7 +212,7 @@ const ChatUI: React.FC<ChatUIProps> = ({
const [temperature, setTemperature] = useState<number>(1.0);
const [maxTokens, setMaxTokens] = useState<number>(2048);
const [useAdvancedParams, setUseAdvancedParams] = useState<boolean>(false);
// Code Interpreter state (using custom hook)
const codeInterpreter = useCodeInterpreter();
@ -244,16 +241,15 @@ const ChatUI: React.FC<ChatUIProps> = ({
try {
const response = await listMCPTools(userApiKey, serverId);
setServerToolsMap(prev => ({
setServerToolsMap((prev) => ({
...prev,
[serverId]: response.tools || []
[serverId]: response.tools || [],
}));
} catch (error) {
console.error(`Error fetching tools for server ${serverId}:`, error);
}
};
useEffect(() => {
if (isGetCodeModalVisible) {
const code = generateCodeSnippet({
@ -1007,7 +1003,7 @@ const ChatUI: React.FC<ChatUIProps> = ({
traceId,
selectedVectorStores.length > 0 ? selectedVectorStores : undefined,
selectedGuardrails.length > 0 ? selectedGuardrails : undefined,
selectedMCPTools, // Pass the selected tools array
selectedMCPServers, // Pass the selected tools array
customProxyBaseUrl || undefined,
);
} else if (endpointType === EndpointType.EMBEDDINGS) {
@ -1205,9 +1201,7 @@ const ChatUI: React.FC<ChatUIProps> = ({
icon={ApiOutlined}
/>
{customProxyBaseUrl && (
<Text className="text-xs text-gray-500 mt-1">
API calls will be sent to: {customProxyBaseUrl}
</Text>
<Text className="text-xs text-gray-500 mt-1">API calls will be sent to: {customProxyBaseUrl}</Text>
)}
</div>
@ -1382,7 +1376,11 @@ const ChatUI: React.FC<ChatUIProps> = ({
optionLabelProp="label"
>
{agentInfo.map((agent) => (
<Select.Option key={agent.agent_id} value={agent.agent_name} label={agent.agent_name || agent.agent_id}>
<Select.Option
key={agent.agent_id}
value={agent.agent_name}
label={agent.agent_name || agent.agent_id}
>
<div className="flex flex-col py-1">
<span className="font-medium">{agent.agent_name || agent.agent_id}</span>
{agent.agent_card_params?.description && (
@ -1416,10 +1414,7 @@ const ChatUI: React.FC<ChatUIProps> = ({
<div>
<Text className="font-medium block mb-2 text-gray-700 flex items-center">
<ToolOutlined className="mr-2" /> MCP Servers
<Tooltip
className="ml-1"
title="Select MCP servers to use in your conversation."
>
<Tooltip className="ml-1" title="Select MCP servers to use in your conversation.">
<InfoCircleOutlined />
</Tooltip>
</Text>
@ -1435,15 +1430,15 @@ const ChatUI: React.FC<ChatUIProps> = ({
} else {
setSelectedMCPServers(value);
// Clean up tool restrictions for removed servers
setMCPServerToolRestrictions(prev => {
setMCPServerToolRestrictions((prev) => {
const updated = { ...prev };
Object.keys(updated).forEach(serverId => {
Object.keys(updated).forEach((serverId) => {
if (!value.includes(serverId)) delete updated[serverId];
});
return updated;
});
// Load tools for newly selected servers
value.forEach(serverId => {
value.forEach((serverId) => {
if (!serverToolsMap[serverId]) {
loadServerTools(serverId);
}
@ -1474,12 +1469,8 @@ const ChatUI: React.FC<ChatUIProps> = ({
disabled={selectedMCPServers.includes("__all__")}
>
<div className="flex flex-col py-1">
<span className="font-medium">
{server.alias || server.server_name || server.server_id}
</span>
{server.description && (
<span className="text-xs text-gray-500 mt-1">{server.description}</span>
)}
<span className="font-medium">{server.alias || server.server_name || server.server_id}</span>
{server.description && <span className="text-xs text-gray-500 mt-1">{server.description}</span>}
</div>
</Select.Option>
))}
@ -1489,40 +1480,40 @@ const ChatUI: React.FC<ChatUIProps> = ({
{selectedMCPServers.length > 0 &&
!selectedMCPServers.includes("__all__") &&
MCP_SUPPORTED_ENDPOINTS.has(endpointType as EndpointType) && (
<div className="mt-3 space-y-2">
{selectedMCPServers.map(serverId => {
const server = mcpServers.find(s => s.server_id === serverId);
const tools = serverToolsMap[serverId] || [];
if (tools.length === 0) return null;
<div className="mt-3 space-y-2">
{selectedMCPServers.map((serverId) => {
const server = mcpServers.find((s) => s.server_id === serverId);
const tools = serverToolsMap[serverId] || [];
if (tools.length === 0) return null;
return (
<div key={serverId} className="border rounded p-2">
<Text className="text-xs text-gray-600 mb-1">
Limit tools for {server?.alias || server?.server_name || serverId}:
</Text>
<Select
mode="multiple"
size="small"
style={{ width: "100%" }}
placeholder="All tools (default)"
value={mcpServerToolRestrictions[serverId] || []}
onChange={(selectedTools) => {
setMCPServerToolRestrictions(prev => ({
...prev,
[serverId]: selectedTools
}));
}}
options={tools.map(tool => ({
value: tool.name,
label: tool.name
}))}
maxTagCount={2}
/>
</div>
);
})}
</div>
)}
return (
<div key={serverId} className="border rounded p-2">
<Text className="text-xs text-gray-600 mb-1">
Limit tools for {server?.alias || server?.server_name || serverId}:
</Text>
<Select
mode="multiple"
size="small"
style={{ width: "100%" }}
placeholder="All tools (default)"
value={mcpServerToolRestrictions[serverId] || []}
onChange={(selectedTools) => {
setMCPServerToolRestrictions((prev) => ({
...prev,
[serverId]: selectedTools,
}));
}}
options={tools.map((tool) => ({
value: tool.name,
label: tool.name,
}))}
maxTagCount={2}
/>
</div>
);
})}
</div>
)}
</div>
<div>
@ -2073,7 +2064,13 @@ const ChatUI: React.FC<ChatUIProps> = ({
)}
{/* Quick Code Interpreter toggle for Responses */}
{endpointType === EndpointType.RESPONSES && (
<Tooltip title={codeInterpreter.enabled ? "Code Interpreter enabled (click to disable)" : "Enable Code Interpreter"}>
<Tooltip
title={
codeInterpreter.enabled
? "Code Interpreter enabled (click to disable)"
: "Enable Code Interpreter"
}
>
<button
className={`p-1.5 rounded-md transition-colors ${
codeInterpreter.enabled

View file

@ -119,8 +119,25 @@ describe("chat_completion", () => {
it("should configure MCP tools per server with restrictions", async () => {
const selectedMCPServers = ["server-1", "server-2"];
const mcpServers = [
{ server_id: "server-1", alias: "alpha", server_name: "Alpha" },
{ server_id: "server-2", server_name: "Beta" },
{
server_id: "server-1",
alias: "alpha",
server_name: "Alpha",
url: "http://example.com",
created_at: "2024-01-01",
created_by: "test",
updated_at: "2024-01-01",
updated_by: "test",
},
{
server_id: "server-2",
server_name: "Beta",
url: "http://example.com",
created_at: "2024-01-01",
created_by: "test",
updated_at: "2024-01-01",
updated_by: "test",
},
];
const mcpServerToolRestrictions = {
"server-1": ["toolA", "toolB"],
@ -132,41 +149,43 @@ describe("chat_completion", () => {
mockUpdateUI,
"gpt-4",
"test-token",
undefined,
undefined,
undefined,
undefined,
undefined,
undefined,
undefined,
undefined,
undefined, // tags
undefined, // signal
undefined, // onReasoningContent
undefined, // onTimingData
undefined, // onUsageData
undefined, // traceId
undefined, // vector_store_ids
undefined, // guardrails
selectedMCPServers,
undefined,
undefined,
undefined,
undefined,
undefined,
undefined, // onImageGenerated
undefined, // onSearchResults
undefined, // temperature
undefined, // max_tokens
undefined, // onTotalLatency
undefined, // customBaseUrl
mcpServers,
mcpServerToolRestrictions,
);
const callArgs = mockCreate.mock.calls[0][0];
expect(callArgs.tool_choice).toBe("auto");
expect(callArgs.tools).toEqual([
{
type: "mcp",
server_label: "litellm",
server_url: "litellm_proxy/mcp/alpha",
require_approval: "never",
allowed_tools: ["toolA", "toolB"],
},
{
type: "mcp",
server_label: "litellm",
server_url: "litellm_proxy/mcp/Beta",
require_approval: "never",
allowed_tools: ["toolC"],
},
]);
expect(callArgs.tools).toHaveLength(2);
// Check first tool
const firstTool = callArgs.tools[0];
expect(firstTool.type).toBe("mcp");
expect(firstTool.server_label).toBe("litellm");
expect(firstTool.server_url).toBe("litellm_proxy/mcp/alpha");
expect(firstTool.require_approval).toBe("never");
expect(firstTool.allowed_tools).toEqual(["toolA", "toolB"]);
// Check second tool
const secondTool = callArgs.tools[1];
expect(secondTool.type).toBe("mcp");
expect(secondTool.server_label).toBe("litellm");
expect(secondTool.server_url).toBe("litellm_proxy/mcp/Beta");
expect(secondTool.require_approval).toBe("never");
expect(secondTool.allowed_tools).toEqual(["toolC"]);
});
});

View file

@ -72,8 +72,25 @@ describe("responses_api", () => {
it("should configure MCP tools per server with restrictions", async () => {
const selectedMCPServers = ["server-1", "server-2"];
const mcpServers = [
{ server_id: "server-1", alias: "alpha", server_name: "Alpha" },
{ server_id: "server-2", server_name: "Beta" },
{
server_id: "server-1",
alias: "alpha",
server_name: "Alpha",
url: "http://example.com",
created_at: "2024-01-01",
created_by: "test",
updated_at: "2024-01-01",
updated_by: "test",
},
{
server_id: "server-2",
server_name: "Beta",
url: "http://example.com",
created_at: "2024-01-01",
created_by: "test",
updated_at: "2024-01-01",
updated_by: "test",
},
];
const mcpServerToolRestrictions: Record<string, string[]> = {
"server-1": ["toolA"],
@ -99,6 +116,7 @@ describe("responses_api", () => {
undefined,
undefined,
undefined,
undefined,
mcpServers,
mcpServerToolRestrictions,
);