Merge pull request #19440 from BerriAI/litellm_ui_chat-autofill

[Feature] UI - Playground: Button to Fill Custom API Base
This commit is contained in:
yuneng-jiang 2026-01-20 14:23:39 -08:00 committed by GitHub
commit 2b62e9fedf
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 65 additions and 12 deletions

View file

@ -19,7 +19,7 @@ vi.mock("../networking", () => ({
// Mock scrollIntoView which is not available in jsdom
beforeEach(() => {
Element.prototype.scrollIntoView = () => {};
Element.prototype.scrollIntoView = () => { };
});
describe("ChatUI", () => {
@ -270,4 +270,43 @@ describe("ChatUI", () => {
expect(mcpSelect).not.toHaveClass("ant-select-disabled");
});
});
it("should show Fill button and populate customProxyBaseUrl when proxySettings.LITELLM_UI_API_DOC_BASE_URL is provided", async () => {
const testProxyUrl = "http://localhost:5000";
render(
<ChatUI
accessToken="1234567890"
token="1234567890"
userRole="user"
userID="1234567890"
disabledPersonalKeyCreation={false}
proxySettings={{
LITELLM_UI_API_DOC_BASE_URL: testProxyUrl,
}}
/>,
);
await waitFor(() => {
expect(screen.getByText("Test Key")).toBeInTheDocument();
});
const fillButton = screen.getByText("Fill");
expect(fillButton).toBeInTheDocument();
act(() => {
fireEvent.click(fillButton);
});
await waitFor(() => {
expect(sessionStorage.getItem("customProxyBaseUrl")).toBe(testProxyUrl);
});
await waitFor(() => {
expect(screen.queryByText("Fill")).toBeNull();
});
const customProxyInput = screen.getByPlaceholderText("Optional: Enter custom proxy URL (e.g., http://localhost:5000)");
expect(customProxyInput).toHaveValue(testProxyUrl);
});
});

View file

@ -10,6 +10,7 @@ import {
FilePdfOutlined,
InfoCircleOutlined,
KeyOutlined,
LinkOutlined,
LoadingOutlined,
PictureOutlined,
RobotOutlined,
@ -1172,9 +1173,23 @@ const ChatUI: React.FC<ChatUIProps> = ({
<div>
<div className="flex items-center justify-between mb-2">
<Text className="font-medium text-gray-700 flex items-center">
<Text className="font-medium block text-gray-700 flex items-center">
<SettingOutlined className="mr-2" /> Custom Proxy Base URL
</Text>
{proxySettings?.LITELLM_UI_API_DOC_BASE_URL && !customProxyBaseUrl && (
<Button
type="link"
size="small"
icon={<LinkOutlined />}
onClick={() => {
setCustomProxyBaseUrl(proxySettings.LITELLM_UI_API_DOC_BASE_URL || "");
sessionStorage.setItem("customProxyBaseUrl", proxySettings.LITELLM_UI_API_DOC_BASE_URL || "");
}}
className="text-gray-500 hover:text-gray-700"
>
Fill
</Button>
)}
{customProxyBaseUrl && (
<Button
type="link"
@ -1219,7 +1234,7 @@ const ChatUI: React.FC<ChatUIProps> = ({
try {
sessionStorage.removeItem("selectedModel");
sessionStorage.removeItem("selectedAgent");
} catch {}
} catch { }
}}
className="mb-4"
/>
@ -1575,7 +1590,7 @@ const ChatUI: React.FC<ChatUIProps> = ({
enabled={codeInterpreter.enabled}
onEnabledChange={codeInterpreter.setEnabled}
selectedContainerId={null}
onContainerChange={() => {}}
onContainerChange={() => { }}
selectedModel={selectedModel || ""}
/>
</div>
@ -2071,11 +2086,10 @@ const ChatUI: React.FC<ChatUIProps> = ({
}
>
<button
className={`p-1.5 rounded-md transition-colors ${
codeInterpreter.enabled
? "bg-blue-100 text-blue-600"
: "text-gray-400 hover:text-gray-600 hover:bg-gray-100"
}`}
className={`p-1.5 rounded-md transition-colors ${codeInterpreter.enabled
? "bg-blue-100 text-blue-600"
: "text-gray-400 hover:text-gray-600 hover:bg-gray-100"
}`}
onClick={() => {
codeInterpreter.toggle();
if (!codeInterpreter.enabled) {
@ -2096,9 +2110,9 @@ const ChatUI: React.FC<ChatUIProps> = ({
onKeyDown={handleKeyDown}
placeholder={
endpointType === EndpointType.CHAT ||
endpointType === EndpointType.EMBEDDINGS ||
endpointType === EndpointType.RESPONSES ||
endpointType === EndpointType.ANTHROPIC_MESSAGES
endpointType === EndpointType.EMBEDDINGS ||
endpointType === EndpointType.RESPONSES ||
endpointType === EndpointType.ANTHROPIC_MESSAGES
? "Type your message... (Shift+Enter for new line)"
: endpointType === EndpointType.A2A_AGENTS
? "Send a message to the A2A agent..."