mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-09 03:18:44 +00:00
Merge pull request #18835 from BerriAI/litellm_ui_build_fix_00
[Infra] Fixing UI Build
This commit is contained in:
commit
1d19974737
3 changed files with 128 additions and 94 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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"]);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue