fix(page.tsx): create pattern for loading in ui config before making network requests

ensures requests are formatted correctly
This commit is contained in:
Krrish Dholakia 2025-06-02 15:13:49 -07:00
parent f3784b7b02
commit 36f18411d0
4 changed files with 57 additions and 12 deletions

View file

@ -8,7 +8,7 @@ from litellm.types.proxy.discovery_endpoints.ui_discovery_endpoints import (
router = APIRouter()
@router.get(".well-known/litellm-ui-config", response_model=UiDiscoveryEndpoints)
@router.get("/.well-known/litellm-ui-config", response_model=UiDiscoveryEndpoints)
@router.get(
"/litellm/.well-known/litellm-ui-config", response_model=UiDiscoveryEndpoints
) # if mounted at root path

View file

@ -17,6 +17,7 @@ import {
userUpdateUserCall,
getOnboardingCredentials,
claimOnboardingToken,
getUiConfig,
} from "@/components/networking";
import { jwtDecode } from "jwt-decode";
import { Form, Button as Button2, message } from "antd";
@ -33,11 +34,20 @@ export default function Onboarding() {
const [userID, setUserID] = useState<string | null>(null);
const [loginUrl, setLoginUrl] = useState<string>("");
const [jwtToken, setJwtToken] = useState<string>("");
const [getUiConfigLoading, setGetUiConfigLoading] = useState<boolean>(true);
useEffect(() => {
if (!inviteID) {
getUiConfig().then((data) => { // get the information for constructing the proxy base url, and then set the token and auth loading
console.log("ui config in onboarding.tsx:", data);
setGetUiConfigLoading(false);
});
}, []);
useEffect(() => {
if (!inviteID || getUiConfigLoading) { // wait for the ui config to be loaded
return;
}
getOnboardingCredentials(inviteID).then((data) => {
const login_url = data.login_url;
console.log("login_url:", login_url);

View file

@ -26,7 +26,7 @@ import ChatUI from "@/components/chat_ui";
import Sidebar from "@/components/leftnav";
import Usage from "@/components/usage";
import CacheDashboard from "@/components/cache_dashboard";
import { proxyBaseUrl, setGlobalLitellmHeaderName, updateProxyBaseUrl } from "@/components/networking";
import { getUiConfig, proxyBaseUrl, setGlobalLitellmHeaderName } from "@/components/networking";
import { Organization } from "@/components/networking";
import GuardrailsPanel from "@/components/guardrails";
import TransformRequestPanel from "@/components/transform_request";
@ -149,8 +149,11 @@ export default function CreateKeyPage() {
useEffect(() => {
const token = getCookie("token");
setToken(token);
setAuthLoading(false);
getUiConfig().then((data) => { // get the information for constructing the proxy base url, and then set the token and auth loading
console.log("ui config in page.tsx:", data);
setToken(token);
setAuthLoading(false);
});
}, []);
useEffect(() => {
@ -164,6 +167,7 @@ export default function CreateKeyPage() {
return;
}
const decoded = jwtDecode(token) as { [key: string]: any };
if (decoded) {
// cast decoded to dictionary
@ -214,12 +218,12 @@ export default function CreateKeyPage() {
if (decoded.user_id) {
setUserID(decoded.user_id);
}
if (decoded.server_root_path) {
updateProxyBaseUrl(decoded.server_root_path);
}
}
}, [token]);
useEffect(() => {
if (accessToken && userID && userRole) {

View file

@ -14,9 +14,19 @@ if (isLocal != true) {
console.log = function() {};
}
export const updateProxyBaseUrl = (serverRootPath: string) => {
proxyBaseUrl = isLocal ? "http://localhost:4000" : window.location.origin
proxyBaseUrl += serverRootPath;
const updateProxyBaseUrl = (serverRootPath: string, receivedProxyBaseUrl: string | null = null) => {
/**
* Special function for updating the proxy base url. Should only be called by getUiConfig.
*/
const defaultProxyBaseUrl = isLocal ? "http://localhost:4000" : window.location.origin;
let initialProxyBaseUrl = receivedProxyBaseUrl || defaultProxyBaseUrl;
console.log("proxyBaseUrl:", proxyBaseUrl);
console.log("serverRootPath:", serverRootPath);
if (serverRootPath.length > 0 && !initialProxyBaseUrl.endsWith(serverRootPath) && serverRootPath != "/") {
initialProxyBaseUrl += serverRootPath;
proxyBaseUrl = initialProxyBaseUrl;
}
console.log("Updated proxyBaseUrl:", proxyBaseUrl);
};
export const getProxyBaseUrl = () => {
@ -72,6 +82,11 @@ export interface CredentialItem {
};
}
export interface LiteLLMWellKnownUiConfig {
server_root_path: string;
proxy_base_url: string | null;
}
export interface CredentialsResponse {
credentials: CredentialItem[];
}
@ -104,6 +119,20 @@ export function setGlobalLitellmHeaderName(headerName: string = "Authorization")
globalLitellmHeaderName = headerName;
}
export const getUiConfig = async () => {
console.log("Getting UI config");
/**Special route to get the proxy base url and server root path */
const url = `${proxyBaseUrl}/litellm/.well-known/litellm-ui-config`;
const response = await fetch(url);
const jsonData: LiteLLMWellKnownUiConfig = await response.json();
/**
* Update the proxy base url and server root path
*/
console.log("jsonData in getUiConfig:", jsonData);
updateProxyBaseUrl(jsonData.server_root_path, jsonData.proxy_base_url);
return jsonData;
}
export const getOpenAPISchema = async () => {
const url = proxyBaseUrl ? `${proxyBaseUrl}/openapi.json` : `/openapi.json`;
const response = await fetch(url);
@ -4285,6 +4314,8 @@ export const getProxyUISettings = async (
* Get all the models user has access to
*/
try {
console.log("Getting proxy UI settings");
console.log("proxyBaseUrl in getProxyUISettings:", proxyBaseUrl);
let url = proxyBaseUrl
? `${proxyBaseUrl}/sso/get/ui_settings`
: `/sso/get/ui_settings`;