diff --git a/ui/litellm-dashboard/src/components/networking.tsx b/ui/litellm-dashboard/src/components/networking.tsx index 4c21e7e911..8642a624dd 100644 --- a/ui/litellm-dashboard/src/components/networking.tsx +++ b/ui/litellm-dashboard/src/components/networking.tsx @@ -994,6 +994,7 @@ export const adminTopEndUsersCall = async ( throw error; } }; + export const adminspendByProvider = async (accessToken: String, keyToken: String | null, startTime: String | undefined, endTime: String | undefined) => { try { let url = proxyBaseUrl ? `${proxyBaseUrl}/global/spend/provider` : `/global/spend/provider`; @@ -1035,6 +1036,42 @@ export const adminspendByProvider = async (accessToken: String, keyToken: String } }; +export const adminGlobalActivity = async (accessToken: String, startTime: String | undefined, endTime: String | undefined) => { + try { + let url = proxyBaseUrl ? `${proxyBaseUrl}/global/activity` : `/global/activity`; + + if (startTime && endTime) { + url += `?start_date=${startTime}&end_date=${endTime}`; + } + + const requestOptions: { + method: string; + headers: { + Authorization: string; + }; + } = { + method: "GET", + headers: { + Authorization: `Bearer ${accessToken}`, + }, + }; + + const response = await fetch(url, requestOptions); + + if (!response.ok) { + const errorData = await response.text(); + throw new Error("Network response was not ok"); + } + const data = await response.json(); + console.log(data); + return data; + } catch (error) { + console.error("Failed to fetch spend data:", error); + throw error; + } +}; + + export const adminTopModelsCall = async (accessToken: String) => { try { let url = proxyBaseUrl diff --git a/ui/litellm-dashboard/src/components/usage.tsx b/ui/litellm-dashboard/src/components/usage.tsx index 9be20251af..390de71667 100644 --- a/ui/litellm-dashboard/src/components/usage.tsx +++ b/ui/litellm-dashboard/src/components/usage.tsx @@ -1,9 +1,16 @@ -import { BarChart, BarList, Card, Title, Table, TableHead, TableHeaderCell, TableRow, TableCell, TableBody, Metric } from "@tremor/react"; +import { BarChart, BarList, Card, Title, Table, TableHead, TableHeaderCell, TableRow, TableCell, TableBody, Metric, Subtitle } from "@tremor/react"; import React, { useState, useEffect } from "react"; import ViewUserSpend from "./view_user_spend"; -import { Grid, Col, Text, LineChart, TabPanel, TabPanels, TabGroup, TabList, Tab, Select, SelectItem, DateRangePicker, DateRangePickerValue, DonutChart} from "@tremor/react"; +import { + Grid, Col, Text, + LineChart, TabPanel, TabPanels, + TabGroup, TabList, Tab, Select, SelectItem, + DateRangePicker, DateRangePickerValue, + DonutChart, + AreaChart, +} from "@tremor/react"; import { userSpendLogsCall, keyInfoCall, @@ -17,6 +24,7 @@ import { modelAvailableCall, modelInfoCall, adminspendByProvider, + adminGlobalActivity, } from "./networking"; import { start } from "repl"; @@ -117,6 +125,7 @@ const UsagePage: React.FC = ({ const [uniqueTeamIds, setUniqueTeamIds] = useState([]); const [totalSpendPerTeam, setTotalSpendPerTeam] = useState([]); const [spendByProvider, setSpendByProvider] = useState([]); + const [globalActivity, setGlobalActivity] = useState([]); const [selectedKeyID, setSelectedKeyID] = useState(""); const [dateValue, setDateValue] = useState({ from: new Date(Date.now() - 7 * 24 * 60 * 60 * 1000), @@ -265,6 +274,10 @@ const UsagePage: React.FC = ({ console.log("spend/user result", spend_user_call); + let global_activity_response = await adminGlobalActivity(accessToken, startTime, endTime); + setGlobalActivity(global_activity_response) + + } else if (userRole == "App Owner") { await userSpendLogsCall( accessToken, @@ -330,7 +343,7 @@ const UsagePage: React.FC = ({ - + Cost Activity @@ -429,6 +442,38 @@ const UsagePage: React.FC = ({ + + + + All Up + + + API Requests {globalActivity.sum_api_requests} + console.log(v)} + /> + + + + Tokens {globalActivity.sum_total_tokens} + console.log(v)} + /> + + + + + + +