mirror of
https://github.com/BerriAI/litellm.git
synced 2025-04-26 11:14:04 +00:00
fix(time_to_first_token.tsx): require enterprise license for usage
This commit is contained in:
parent
3400596dd2
commit
8d1067c81c
6 changed files with 69 additions and 38 deletions
|
@ -35,8 +35,11 @@ class LicenseCheck:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def is_premium(self) -> bool:
|
def is_premium(self) -> bool:
|
||||||
|
try:
|
||||||
if self.license_str is None:
|
if self.license_str is None:
|
||||||
return False
|
return False
|
||||||
elif self._verify(license_str=self.license_str):
|
elif self._verify(license_str=self.license_str):
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
except Exception as e:
|
||||||
|
return False
|
||||||
|
|
|
@ -174,7 +174,6 @@ except Exception as e:
|
||||||
|
|
||||||
_license_check = LicenseCheck()
|
_license_check = LicenseCheck()
|
||||||
premium_user: bool = _license_check.is_premium()
|
premium_user: bool = _license_check.is_premium()
|
||||||
|
|
||||||
ui_link = f"/ui/"
|
ui_link = f"/ui/"
|
||||||
ui_message = (
|
ui_message = (
|
||||||
f"👉 [```LiteLLM Admin Panel on /ui```]({ui_link}). Create, Edit Keys with SSO"
|
f"👉 [```LiteLLM Admin Panel on /ui```]({ui_link}). Create, Edit Keys with SSO"
|
||||||
|
@ -9587,6 +9586,7 @@ async def fallback_login(request: Request):
|
||||||
"/login", include_in_schema=False
|
"/login", include_in_schema=False
|
||||||
) # hidden since this is a helper for UI sso login
|
) # hidden since this is a helper for UI sso login
|
||||||
async def login(request: Request):
|
async def login(request: Request):
|
||||||
|
global premium_user
|
||||||
try:
|
try:
|
||||||
import multipart
|
import multipart
|
||||||
except ImportError:
|
except ImportError:
|
||||||
|
@ -9662,6 +9662,7 @@ async def login(request: Request):
|
||||||
"user_email": user_id,
|
"user_email": user_id,
|
||||||
"user_role": "app_admin", # this is the path without sso - we can assume only admins will use this
|
"user_role": "app_admin", # this is the path without sso - we can assume only admins will use this
|
||||||
"login_method": "username_password",
|
"login_method": "username_password",
|
||||||
|
"premium_user": premium_user,
|
||||||
},
|
},
|
||||||
"secret",
|
"secret",
|
||||||
algorithm="HS256",
|
algorithm="HS256",
|
||||||
|
@ -9712,7 +9713,7 @@ def get_image():
|
||||||
@app.get("/sso/callback", tags=["experimental"])
|
@app.get("/sso/callback", tags=["experimental"])
|
||||||
async def auth_callback(request: Request):
|
async def auth_callback(request: Request):
|
||||||
"""Verify login"""
|
"""Verify login"""
|
||||||
global general_settings, ui_access_mode
|
global general_settings, ui_access_mode, premium_user
|
||||||
microsoft_client_id = os.getenv("MICROSOFT_CLIENT_ID", None)
|
microsoft_client_id = os.getenv("MICROSOFT_CLIENT_ID", None)
|
||||||
google_client_id = os.getenv("GOOGLE_CLIENT_ID", None)
|
google_client_id = os.getenv("GOOGLE_CLIENT_ID", None)
|
||||||
generic_client_id = os.getenv("GENERIC_CLIENT_ID", None)
|
generic_client_id = os.getenv("GENERIC_CLIENT_ID", None)
|
||||||
|
@ -9992,6 +9993,7 @@ async def auth_callback(request: Request):
|
||||||
"user_email": user_email,
|
"user_email": user_email,
|
||||||
"user_role": user_role,
|
"user_role": user_role,
|
||||||
"login_method": "sso",
|
"login_method": "sso",
|
||||||
|
"premium_user": premium_user,
|
||||||
},
|
},
|
||||||
"secret",
|
"secret",
|
||||||
algorithm="HS256",
|
algorithm="HS256",
|
||||||
|
|
|
@ -20,6 +20,7 @@ import { Typography } from "antd";
|
||||||
const CreateKeyPage = () => {
|
const CreateKeyPage = () => {
|
||||||
const { Title, Paragraph } = Typography;
|
const { Title, Paragraph } = Typography;
|
||||||
const [userRole, setUserRole] = useState("");
|
const [userRole, setUserRole] = useState("");
|
||||||
|
const [premiumUser, setPremiumUser] = useState(false);
|
||||||
const [userEmail, setUserEmail] = useState<null | string>(null);
|
const [userEmail, setUserEmail] = useState<null | string>(null);
|
||||||
const [teams, setTeams] = useState<null | any[]>(null);
|
const [teams, setTeams] = useState<null | any[]>(null);
|
||||||
const [keys, setKeys] = useState<null | any[]>(null);
|
const [keys, setKeys] = useState<null | any[]>(null);
|
||||||
|
@ -68,6 +69,10 @@ const CreateKeyPage = () => {
|
||||||
} else {
|
} else {
|
||||||
console.log(`User Email is not set ${decoded}`);
|
console.log(`User Email is not set ${decoded}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (decoded.premium_user) {
|
||||||
|
setPremiumUser(decoded.premium_user);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [token]);
|
}, [token]);
|
||||||
|
@ -104,6 +109,7 @@ const CreateKeyPage = () => {
|
||||||
userRole={userRole}
|
userRole={userRole}
|
||||||
userEmail={userEmail}
|
userEmail={userEmail}
|
||||||
showSSOBanner={showSSOBanner}
|
showSSOBanner={showSSOBanner}
|
||||||
|
premiumUser={premiumUser}
|
||||||
/>
|
/>
|
||||||
<div className="flex flex-1 overflow-auto">
|
<div className="flex flex-1 overflow-auto">
|
||||||
<div className="mt-8">
|
<div className="mt-8">
|
||||||
|
@ -134,6 +140,7 @@ const CreateKeyPage = () => {
|
||||||
accessToken={accessToken}
|
accessToken={accessToken}
|
||||||
modelData={modelData}
|
modelData={modelData}
|
||||||
setModelData={setModelData}
|
setModelData={setModelData}
|
||||||
|
premiumUser={premiumUser}
|
||||||
/>
|
/>
|
||||||
) : page == "llm-playground" ? (
|
) : page == "llm-playground" ? (
|
||||||
<ChatUI
|
<ChatUI
|
||||||
|
|
|
@ -91,6 +91,7 @@ interface ModelDashboardProps {
|
||||||
userID: string | null;
|
userID: string | null;
|
||||||
modelData: any;
|
modelData: any;
|
||||||
setModelData: any;
|
setModelData: any;
|
||||||
|
premiumUser: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface EditModelModalProps {
|
interface EditModelModalProps {
|
||||||
|
@ -233,6 +234,7 @@ const ModelDashboard: React.FC<ModelDashboardProps> = ({
|
||||||
userID,
|
userID,
|
||||||
modelData = { data: [] },
|
modelData = { data: [] },
|
||||||
setModelData,
|
setModelData,
|
||||||
|
premiumUser,
|
||||||
}) => {
|
}) => {
|
||||||
const [pendingRequests, setPendingRequests] = useState<any[]>([]);
|
const [pendingRequests, setPendingRequests] = useState<any[]>([]);
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
|
@ -1609,6 +1611,7 @@ const ModelDashboard: React.FC<ModelDashboardProps> = ({
|
||||||
streamingModelMetricsCategories
|
streamingModelMetricsCategories
|
||||||
}
|
}
|
||||||
customTooltip={customTooltip}
|
customTooltip={customTooltip}
|
||||||
|
premiumUser={premiumUser}
|
||||||
/>
|
/>
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
</TabPanels>
|
</TabPanels>
|
||||||
|
|
|
@ -1,17 +1,19 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { LineChart } from "@tremor/react";
|
import { LineChart, Callout, Button } from "@tremor/react";
|
||||||
interface TimeToFirstTokenProps {
|
interface TimeToFirstTokenProps {
|
||||||
modelMetrics: any[];
|
modelMetrics: any[];
|
||||||
modelMetricsCategories: string[];
|
modelMetricsCategories: string[];
|
||||||
customTooltip: any;
|
customTooltip: any;
|
||||||
|
premiumUser: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const TimeToFirstToken: React.FC<TimeToFirstTokenProps> = ({
|
const TimeToFirstToken: React.FC<TimeToFirstTokenProps> = ({
|
||||||
modelMetrics,
|
modelMetrics,
|
||||||
modelMetricsCategories,
|
modelMetricsCategories,
|
||||||
customTooltip,
|
customTooltip,
|
||||||
|
premiumUser,
|
||||||
}) => {
|
}) => {
|
||||||
return (
|
return premiumUser ? (
|
||||||
<LineChart
|
<LineChart
|
||||||
title="Time to First token (s)"
|
title="Time to First token (s)"
|
||||||
className="h-72"
|
className="h-72"
|
||||||
|
@ -23,6 +25,18 @@ const TimeToFirstToken: React.FC<TimeToFirstTokenProps> = ({
|
||||||
connectNulls={true}
|
connectNulls={true}
|
||||||
customTooltip={customTooltip}
|
customTooltip={customTooltip}
|
||||||
/>
|
/>
|
||||||
|
) : (
|
||||||
|
<div>
|
||||||
|
<Callout title="Premium Feature" color="teal" className="mt-2 mb-4">
|
||||||
|
Premium features are available for users with a specific license, please
|
||||||
|
contact LiteLLM to unlock this limitation.
|
||||||
|
</Callout>
|
||||||
|
<Button variant="primary">
|
||||||
|
<a href="https://forms.gle/W3U4PZpJGFHWtHyA9" target="_blank">
|
||||||
|
Get in touch
|
||||||
|
</a>
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import type { MenuProps } from 'antd';
|
import type { MenuProps } from "antd";
|
||||||
import { Dropdown, Space } from 'antd';
|
import { Dropdown, Space } from "antd";
|
||||||
import { useSearchParams } from "next/navigation";
|
import { useSearchParams } from "next/navigation";
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
|
@ -23,28 +23,32 @@ interface NavbarProps {
|
||||||
userRole: string | null;
|
userRole: string | null;
|
||||||
userEmail: string | null;
|
userEmail: string | null;
|
||||||
showSSOBanner: boolean;
|
showSSOBanner: boolean;
|
||||||
|
premiumUser: boolean;
|
||||||
}
|
}
|
||||||
const Navbar: React.FC<NavbarProps> = ({
|
const Navbar: React.FC<NavbarProps> = ({
|
||||||
userID,
|
userID,
|
||||||
userRole,
|
userRole,
|
||||||
userEmail,
|
userEmail,
|
||||||
showSSOBanner,
|
showSSOBanner,
|
||||||
|
premiumUser,
|
||||||
}) => {
|
}) => {
|
||||||
console.log("User ID:", userID);
|
console.log("User ID:", userID);
|
||||||
console.log("userEmail:", userEmail);
|
console.log("userEmail:", userEmail);
|
||||||
console.log("showSSOBanner:", showSSOBanner);
|
console.log("showSSOBanner:", showSSOBanner);
|
||||||
|
console.log("premiumUser:", premiumUser);
|
||||||
|
|
||||||
// const userColors = require('./ui_colors.json') || {};
|
// const userColors = require('./ui_colors.json') || {};
|
||||||
const isLocal = process.env.NODE_ENV === "development";
|
const isLocal = process.env.NODE_ENV === "development";
|
||||||
const imageUrl = isLocal ? "http://localhost:4000/get_image" : "/get_image";
|
const imageUrl = isLocal ? "http://localhost:4000/get_image" : "/get_image";
|
||||||
|
|
||||||
const items: MenuProps['items'] = [
|
const items: MenuProps["items"] = [
|
||||||
{
|
{
|
||||||
key: '1',
|
key: "1",
|
||||||
label: (
|
label: (
|
||||||
<>
|
<>
|
||||||
<p>Role: {userRole}</p>
|
<p>Role: {userRole}</p>
|
||||||
<p>ID: {userID}</p>
|
<p>ID: {userID}</p>
|
||||||
|
<p>Premium User: {String(premiumUser)}</p>
|
||||||
</>
|
</>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
@ -69,19 +73,19 @@ const Navbar: React.FC<NavbarProps> = ({
|
||||||
</div>
|
</div>
|
||||||
<div className="text-right mx-4 my-2 absolute top-0 right-0 flex items-center justify-end space-x-2">
|
<div className="text-right mx-4 my-2 absolute top-0 right-0 flex items-center justify-end space-x-2">
|
||||||
{showSSOBanner ? (
|
{showSSOBanner ? (
|
||||||
|
<div
|
||||||
<div style={{
|
style={{
|
||||||
// border: '1px solid #391085',
|
// border: '1px solid #391085',
|
||||||
padding: '6px',
|
padding: "6px",
|
||||||
borderRadius: '8px', // Added border-radius property
|
borderRadius: "8px", // Added border-radius property
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<a
|
<a
|
||||||
href="https://calendly.com/d/4mp-gd3-k5k/litellm-1-1-onboarding-chat"
|
href="https://calendly.com/d/4mp-gd3-k5k/litellm-1-1-onboarding-chat"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
style={{
|
style={{
|
||||||
"fontSize": "14px",
|
fontSize: "14px",
|
||||||
"textDecoration": "underline"
|
textDecoration: "underline",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Request hosted proxy
|
Request hosted proxy
|
||||||
|
@ -89,20 +93,18 @@ const Navbar: React.FC<NavbarProps> = ({
|
||||||
</div>
|
</div>
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
<div style={{
|
<div
|
||||||
border: '1px solid #391085',
|
style={{
|
||||||
padding: '6px',
|
border: "1px solid #391085",
|
||||||
borderRadius: '8px', // Added border-radius property
|
padding: "6px",
|
||||||
|
borderRadius: "8px", // Added border-radius property
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Dropdown menu={{ items }}>
|
<Dropdown menu={{ items }}>
|
||||||
<Space>
|
<Space>{userEmail}</Space>
|
||||||
{userEmail}
|
|
||||||
</Space>
|
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</nav>
|
</nav>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue