diff --git a/ui/litellm-dashboard/src/app/page.tsx b/ui/litellm-dashboard/src/app/page.tsx index 80a3b6940ab..02e72b57971 100644 --- a/ui/litellm-dashboard/src/app/page.tsx +++ b/ui/litellm-dashboard/src/app/page.tsx @@ -3,6 +3,7 @@ import React, { Suspense, useEffect, useState } from "react"; import { useSearchParams } from "next/navigation"; import Navbar from "../components/navbar"; import UserDashboard from "../components/user_dashboard"; +import ModelDashboard from "@/components/model_dashboard"; import Sidebar from "../components/leftnav"; import Usage from "../components/usage"; import { jwtDecode } from "jwt-decode"; @@ -80,7 +81,15 @@ const CreateKeyPage = () => { userEmail={userEmail} setUserEmail={setUserEmail} /> - ) : ( + ) : page == "models" ? ( + + ) + : ( = ({ setPage }) => { setPage("api-keys")}> API Keys - setPage("usage")}> + setPage("models")}> + Models + + setPage("usage")}> Usage diff --git a/ui/litellm-dashboard/src/components/model_dashboard.tsx b/ui/litellm-dashboard/src/components/model_dashboard.tsx new file mode 100644 index 00000000000..6067fc68610 --- /dev/null +++ b/ui/litellm-dashboard/src/components/model_dashboard.tsx @@ -0,0 +1,63 @@ +import React, { useState, useEffect } from "react"; +import { Card, Title, Table, TableHead, TableRow, TableCell, TableBody } from "@tremor/react"; +import { modelInfoCall } from "./networking"; + +interface ModelDashboardProps { + accessToken: string | null; + token: string | null; + userRole: string | null; + userID: string | null; +} + +const ModelDashboard: React.FC = ({ + accessToken, + token, + userRole, + userID, +}) => { + const [modelData, setModelData] = useState({ data: [] }); + + useEffect(() => { + const fetchData = async () => { + try { + // Replace with your actual API call for model data + const modelDataResponse = await modelInfoCall(accessToken, token, userRole, userID); + + setModelData(modelDataResponse); + } catch (error) { + console.error("There was an error fetching the model data", error); + } + }; + + if (accessToken && token && userRole && userID) { + fetchData(); + } + }, [accessToken, token, userRole, userID]); + + return ( +
+ + Models Page + + + + Model Name + Model Info + + + + {modelData.data.map((model: any) => ( + + {model.model_name} + {/* {model.model_info} */} + {/* Add other TableCell for Model Info if needed */} + + ))} + +
+
+
+ ); +}; + +export default ModelDashboard; diff --git a/ui/litellm-dashboard/src/components/networking.tsx b/ui/litellm-dashboard/src/components/networking.tsx index 4521ca44661..7905ed7dbcd 100644 --- a/ui/litellm-dashboard/src/components/networking.tsx +++ b/ui/litellm-dashboard/src/components/networking.tsx @@ -137,6 +137,41 @@ export const userInfoCall = async ( } }; + + +export const modelInfoCall = async ( + accessToken: String, + userID: String, + userRole: String +) => { + try { + let url = proxyBaseUrl ? `${proxyBaseUrl}/model/info` : `/model/info`; + + message.info("Requesting model data"); + const response = await fetch(url, { + method: "GET", + headers: { + Authorization: `Bearer ${accessToken}`, + "Content-Type": "application/json", + }, + }); + + if (!response.ok) { + const errorData = await response.text(); + message.error(errorData); + throw new Error("Network response was not ok"); + } + + const data = await response.json(); + message.info("Received model data"); + return data; + // Handle success - you might want to update some state or UI based on the created key + } catch (error) { + console.error("Failed to create key:", error); + throw error; + } +}; + export const keySpendLogsCall = async (accessToken: String, token: String) => { try { const url = proxyBaseUrl ? `${proxyBaseUrl}/spend/logs` : `/spend/logs`;