Merge pull request #3197 from BerriAI/litellm_ui_flow_for_non_admins

[UI] - simplify "Create Key" for non admins
This commit is contained in:
Ishaan Jaff 2024-04-20 16:31:32 -07:00 committed by GitHub
commit cc4e66d04a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 154 additions and 17 deletions

View file

@ -2,7 +2,7 @@
import React, { useState, useEffect, useRef } from "react";
import { Button, TextInput, Grid, Col } from "@tremor/react";
import { Card, Metric, Text, Title, Subtitle } from "@tremor/react";
import { Card, Metric, Text, Title, Subtitle, Accordion, AccordionHeader, AccordionBody, } from "@tremor/react";
import { CopyToClipboard } from 'react-copy-to-clipboard';
import {
Button as Button2,
@ -116,7 +116,7 @@ const CreateKey: React.FC<CreateKeyProps> = ({
wrapperCol={{ span: 16 }}
labelAlign="left"
>
{userRole === "App Owner" || userRole === "Admin" || userRole === "App User" ? (
{userRole === "App Owner" || userRole === "Admin" ? (
<>
<Form.Item
label="Key Name"
@ -248,16 +248,143 @@ const CreateKey: React.FC<CreateKeyProps> = ({
</>
) : (
<>
<Form.Item label="Key Name" name="key_alias">
<Form.Item
label="Key Name"
name="key_alias"
rules={[{ required: true, message: 'Please input a key name' }]}
help="required"
>
<Input />
</Form.Item>
<Form.Item label="Team ID (Contact Group)" name="team_id">
<Input placeholder="default team (create a new team)" />
<Form.Item
label="Team ID"
name="team_id"
hidden={true}
initialValue={team ? team["team_id"] : null}
valuePropName="team_id"
className="mt-8"
>
<Input value={team ? team["team_alias"] : ""} disabled />
</Form.Item>
<Form.Item label="Description" name="description">
<Input.TextArea placeholder="Enter description" rows={4} />
<Form.Item
label="Models"
name="models"
rules={[{ required: true, message: 'Please select a model' }]}
help="required"
>
<Select
mode="multiple"
placeholder="Select models"
style={{ width: "100%" }}
>
<Option key="all-team-models" value="all-team-models">
All Team Models
</Option>
{team && team.models ? (
team.models.includes("all-proxy-models") ? (
userModels.map((model: string) => (
(
<Option key={model} value={model}>
{model}
</Option>
)
))
) : (
team.models.map((model: string) => (
<Option key={model} value={model}>
{model}
</Option>
))
)
) : (
userModels.map((model: string) => (
<Option key={model} value={model}>
{model}
</Option>
))
)}
</Select>
</Form.Item>
<Accordion className="mt-8">
<AccordionHeader>
<b>Optional Settings</b>
</AccordionHeader>
<AccordionBody>
<Form.Item
className="mt-8"
label="Max Budget (USD)"
name="max_budget"
help={`Budget cannot exceed team max budget: $${team?.max_budget !== null && team?.max_budget !== undefined ? team?.max_budget : 'unlimited'}`}
rules={[
{
validator: async (_, value) => {
if (value && team && team.max_budget !== null && value > team.max_budget) {
throw new Error(`Budget cannot exceed team max budget: $${team.max_budget}`);
}
},
},
]}
>
<InputNumber step={0.01} precision={2} width={200} />
</Form.Item>
<Form.Item
className="mt-8"
label="Reset Budget"
name="budget_duration"
help={`Team Reset Budget: ${team?.budget_duration !== null && team?.budget_duration !== undefined ? team?.budget_duration : 'None'}`}
>
<Select defaultValue={null} placeholder="n/a">
<Select.Option value="24h">daily</Select.Option>
<Select.Option value="30d">monthly</Select.Option>
</Select>
</Form.Item>
<Form.Item
className="mt-8"
label="Tokens per minute Limit (TPM)"
name="tpm_limit"
help={`TPM cannot exceed team TPM limit: ${team?.tpm_limit !== null && team?.tpm_limit !== undefined ? team?.tpm_limit : 'unlimited'}`}
rules={[
{
validator: async (_, value) => {
if (value && team && team.tpm_limit !== null && value > team.tpm_limit) {
throw new Error(`TPM limit cannot exceed team TPM limit: ${team.tpm_limit}`);
}
},
},
]}
>
<InputNumber step={1} width={400} />
</Form.Item>
<Form.Item
className="mt-8"
label="Requests per minute Limit (RPM)"
name="rpm_limit"
help={`RPM cannot exceed team RPM limit: ${team?.rpm_limit !== null && team?.rpm_limit !== undefined ? team?.rpm_limit : 'unlimited'}`}
rules={[
{
validator: async (_, value) => {
if (value && team && team.rpm_limit !== null && value > team.rpm_limit) {
throw new Error(`RPM limit cannot exceed team RPM limit: ${team.rpm_limit}`);
}
},
},
]}
>
<InputNumber step={1} width={400} />
</Form.Item>
<Form.Item label="Expire Key (eg: 30s, 30h, 30d)" name="duration" className="mt-8">
<Input />
</Form.Item>
<Form.Item label="Metadata" name="metadata">
<Input.TextArea rows={4} placeholder="Enter metadata as JSON" />
</Form.Item>
</AccordionBody>
</Accordion>
</>
)}
<div style={{ textAlign: "right", marginTop: "10px" }}>

View file

@ -4,6 +4,7 @@ import { Select, SelectItem, Text, Title } from "@tremor/react";
interface DashboardTeamProps {
teams: Object[] | null;
setSelectedTeam: React.Dispatch<React.SetStateAction<any | null>>;
userRole: string | null;
}
type TeamInterface = {
@ -15,6 +16,7 @@ type TeamInterface = {
const DashboardTeam: React.FC<DashboardTeamProps> = ({
teams,
setSelectedTeam,
userRole,
}) => {
const defaultTeam: TeamInterface = {
models: [],
@ -25,19 +27,27 @@ const DashboardTeam: React.FC<DashboardTeamProps> = ({
const [value, setValue] = useState(defaultTeam);
const updatedTeams = teams ? [...teams, defaultTeam] : [defaultTeam];
let updatedTeams;
if (userRole === "App User") {
// Non-Admin SSO users should only see their own team - they should not see "Default Team"
updatedTeams = teams;
} else {
updatedTeams = teams ? [...teams, defaultTeam] : [defaultTeam];
}
return (
<div className="mt-5 mb-5">
<Title>Select Team</Title>
<Text>
If you belong to multiple teams, this setting controls which team is
used by default when creating new API Keys.
</Text>
<Text className="mt-3 mb-3">
<b>Default Team:</b> If no team_id is set for a key, it will be grouped under here.
</Text>
{userRole !== "App User" && (
<>
<Text>
If you belong to multiple teams, this setting controls which team is used by default when creating new API Keys.
</Text>
<Text className="mt-3 mb-3">
<b>Default Team:</b> If no team_id is set for a key, it will be grouped under here.
</Text>
</>
)}
{updatedTeams && updatedTeams.length > 0 ? (
<Select defaultValue="0">
{updatedTeams.map((team: any, index) => (

View file

@ -257,7 +257,7 @@ const UserDashboard: React.FC<UserDashboardProps> = ({
data={keys}
setData={setKeys}
/>
<DashboardTeam teams={teams} setSelectedTeam={setSelectedTeam} />
<DashboardTeam teams={teams} setSelectedTeam={setSelectedTeam} userRole={userRole}/>
</Col>
</Grid>
</div>