Skip to content

Commit

Permalink
Add UI Support for Admins to Call /cache/ping and View Cache Analytics (
Browse files Browse the repository at this point in the history
#8475) (#8519)

* [Bug] UI: Newly created key does not display on the View Key Page (#8039)

- Fixed issue where all keys appeared blank for admin users.
- Implemented filtering of data via team settings to ensure all keys are displayed correctly.

* Fix:
- Updated the validator to allow model editing when `keyTeam.team_alias === "Default Team"`.
- Ensured other teams still follow the original validation rules.

* - added some classes in global.css
- added text wrap in output of request,response and metadata in index.tsx
- fixed styles of table in table.tsx

* - added full payload when we open single log entry
- added Combined Info Card in index.tsx

* fix: keys not showing on refresh for internal user

* merge

* main merge

* cache page

* ca remove

* terms change

* fix:places caching inside exp
  • Loading branch information
tahaali-dev authored and krrishdholakia committed Feb 14, 2025
1 parent 45063c4 commit 54d16bd
Show file tree
Hide file tree
Showing 3 changed files with 124 additions and 7 deletions.
96 changes: 89 additions & 7 deletions ui/litellm-dashboard/src/components/cache_dashboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,28 @@ import {
DateRangePickerValue,
MultiSelect,
MultiSelectItem,
Button,
TabPanel,
TabPanels,
TabGroup,
TabList,
Tab,
TextInput,
Icon,
Text,
} from "@tremor/react";

import {
Button as Button2,
message,
} from "antd";
import {
RefreshIcon,
} from "@heroicons/react/outline";
import {
adminGlobalCacheActivity,
cachingHealthCheckCall,
healthCheckCall,
} from "./networking";

const formatDateWithoutTZ = (date: Date | undefined) => {
Expand Down Expand Up @@ -86,6 +104,8 @@ const CacheDashboard: React.FC<CachePageProps> = ({
to: new Date(),
});

const [lastRefreshed, setLastRefreshed] = useState("");
const [healthCheckResponse, setHealthCheckResponse] = useState<string>("");

useEffect(() => {
if (!accessToken || !dateValue) {
Expand All @@ -96,6 +116,9 @@ const CacheDashboard: React.FC<CachePageProps> = ({
setData(response);
};
fetchData();

const currentDate = new Date();
setLastRefreshed(currentDate.toLocaleString());
}, [accessToken]);

const uniqueApiKeys = Array.from(new Set(data.map((item) => item?.api_key ?? "")));
Expand Down Expand Up @@ -208,8 +231,50 @@ const CacheDashboard: React.FC<CachePageProps> = ({

}, [selectedApiKeys, selectedModels, dateValue, data]);


const handleRefreshClick = () => {
// Update the 'lastRefreshed' state to the current date and time
const currentDate = new Date();
setLastRefreshed(currentDate.toLocaleString());
};

const runCachingHealthCheck = async () => {
try {
message.info("Running cache health check...");
setHealthCheckResponse("");
const response = await cachingHealthCheckCall(accessToken !== null ? accessToken : "");
console.log("CACHING HEALTH CHECK RESPONSE", response);
setHealthCheckResponse(response);
} catch (error) {
console.error("Error running health check:", error);
setHealthCheckResponse("Error running health check");
}
};

return (
<Card>
<TabGroup className="gap-2 p-8 h-full w-full mt-2 mb-8">
<TabList className="flex justify-between mt-2 w-full items-center">
<div className="flex">
<Tab>Cache Analytics</Tab>
<Tab>
<pre>Cache Health</pre>
</Tab>
</div>

<div className="flex items-center space-x-2">
{lastRefreshed && <Text>Last Refreshed: {lastRefreshed}</Text>}
<Icon
icon={RefreshIcon} // Modify as necessary for correct icon name
variant="shadow"
size="xs"
className="self-center"
onClick={handleRefreshClick}
/>
</div>
</TabList>
<TabPanels>
<TabPanel>
<Card>
<Grid numItems={3} className="gap-4 mt-4">
<Col>
<MultiSelect
Expand Down Expand Up @@ -251,7 +316,7 @@ const CacheDashboard: React.FC<CachePageProps> = ({
</Grid>

<div className="grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3 mt-4">
<Card>
<Card>
<p className="text-tremor-default font-medium text-tremor-content dark:text-dark-tremor-content">
Cache Hit Ratio
</p>
Expand Down Expand Up @@ -314,11 +379,28 @@ const CacheDashboard: React.FC<CachePageProps> = ({


</Card>





</TabPanel>
<TabPanel>
<Card className="mt-4">
<Text>
Cache health will run a very small request through API /cache/ping
configured on litellm
</Text>

<Button onClick={runCachingHealthCheck} className="mt-4">Run cache health</Button>
{healthCheckResponse && (
<pre className="mt-4" style={{
whiteSpace: 'pre-wrap',
wordWrap: 'break-word',
maxWidth: '100%'
}}>
{JSON.stringify(healthCheckResponse, null, 2)}
</pre>
)}
</Card>
</TabPanel>
</TabPanels>
</TabGroup>
);
};

Expand Down
3 changes: 3 additions & 0 deletions ui/litellm-dashboard/src/components/leftnav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ const menuItems: MenuItem[] = [
{ key: "14", page: "api_ref", label: "API Reference", icon: <ApiOutlined /> },
{ key: "16", page: "model-hub", label: "Model Hub", icon: <AppstoreOutlined /> },
{ key: "15", page: "logs", label: "Logs", icon: <LineChartOutlined />, roles: all_admin_roles },


{
key: "experimental",
page: "experimental",
Expand All @@ -68,6 +70,7 @@ const menuItems: MenuItem[] = [
{ key: "9", page: "caching", label: "Caching", icon: <DatabaseOutlined />, roles: all_admin_roles },
{ key: "10", page: "budgets", label: "Budgets", icon: <BankOutlined />, roles: all_admin_roles },
{ key: "11", page: "guardrails", label: "Guardrails", icon: <SafetyOutlined />, roles: all_admin_roles },

]
},
{
Expand Down
32 changes: 32 additions & 0 deletions ui/litellm-dashboard/src/components/networking.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3210,6 +3210,38 @@ export const healthCheckCall = async (accessToken: String) => {
}
};

export const cachingHealthCheckCall = async (accessToken: String) => {
/**
* Get all the models user has access to
*/
try {
let url = proxyBaseUrl ? `${proxyBaseUrl}/cache/ping` : `/cache/ping`;

//message.info("Requesting model data");
const response = await fetch(url, {
method: "GET",
headers: {
[globalLitellmHeaderName]: `Bearer ${accessToken}`,
"Content-Type": "application/json",
},
});

if (!response.ok) {
const errorData = await response.text();
handleError(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 call /cache/ping:", error);
throw error;
}
};

export const getProxyUISettings = async (
accessToken: String,
) => {
Expand Down

0 comments on commit 54d16bd

Please sign in to comment.