Skip to content

Commit 32036e2

Browse files
feat(ui/): add common rate limit type form, for reuse for tpm/rpm across create + edit key
1 parent 20b6f01 commit 32036e2

File tree

3 files changed

+124
-76
lines changed

3 files changed

+124
-76
lines changed
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
import React from "react"
2+
import { Form, Select, Tooltip } from "antd"
3+
import { InfoCircleOutlined } from "@ant-design/icons"
4+
5+
const { Option } = Select
6+
7+
interface RateLimitTypeFormItemProps {
8+
/** The type of rate limit - either 'tpm' or 'rpm' */
9+
type: 'tpm' | 'rpm'
10+
/** The form field name */
11+
name: string
12+
/** Whether to show detailed descriptions (default: true) */
13+
showDetailedDescriptions?: boolean
14+
/** Additional CSS classes */
15+
className?: string
16+
/** Initial value for the field */
17+
initialValue?: string | null
18+
/** Form instance for setting field values */
19+
form?: any
20+
/** Custom onChange handler */
21+
onChange?: (value: string) => void
22+
}
23+
24+
export const RateLimitTypeFormItem: React.FC<RateLimitTypeFormItemProps> = ({
25+
type,
26+
name,
27+
showDetailedDescriptions = true,
28+
className = "",
29+
initialValue = null,
30+
form,
31+
onChange
32+
}) => {
33+
const limitTypeUpper = type.toUpperCase()
34+
const limitTypeLower = type.toLowerCase()
35+
36+
const handleChange = (value: string) => {
37+
if (form) {
38+
form.setFieldValue(name, value)
39+
}
40+
if (onChange) {
41+
onChange(value)
42+
}
43+
}
44+
45+
const tooltipTitle = `Select 'guaranteed_throughput' to prevent overallocating ${limitTypeUpper} limit when the key belongs to a Team with specific ${limitTypeUpper} limits.`
46+
47+
return (
48+
<Form.Item
49+
label={
50+
<span>
51+
{limitTypeUpper} Rate Limit Type{' '}
52+
<Tooltip title={tooltipTitle}>
53+
<InfoCircleOutlined style={{ marginLeft: '4px' }} />
54+
</Tooltip>
55+
</span>
56+
}
57+
name={name}
58+
initialValue={initialValue}
59+
className={className}
60+
>
61+
<Select
62+
defaultValue={showDetailedDescriptions ? "default" : undefined}
63+
placeholder="Select rate limit type"
64+
style={{ width: "100%" }}
65+
optionLabelProp={showDetailedDescriptions ? "label" : undefined}
66+
onChange={handleChange}
67+
>
68+
{showDetailedDescriptions ? (
69+
<>
70+
<Option value="best_effort_throughput" label="Default">
71+
<div style={{ padding: '4px 0' }}>
72+
<div style={{ fontWeight: 500 }}>Default</div>
73+
<div style={{ fontSize: '11px', color: '#6b7280', marginTop: '2px' }}>
74+
Best effort throughput - no error if we're overallocating {limitTypeLower} (Team/Key Limits checked at runtime).
75+
</div>
76+
</div>
77+
</Option>
78+
<Option value="guaranteed_throughput" label="Guaranteed throughput">
79+
<div style={{ padding: '4px 0' }}>
80+
<div style={{ fontWeight: 500 }}>Guaranteed throughput</div>
81+
<div style={{ fontSize: '11px', color: '#6b7280', marginTop: '2px' }}>
82+
Guaranteed throughput - raise an error if we're overallocating {limitTypeLower} (also checks model-specific limits)
83+
</div>
84+
</div>
85+
</Option>
86+
</>
87+
) : (
88+
<>
89+
<Option value="best_effort_throughput">Best effort throughput</Option>
90+
<Option value="guaranteed_throughput">Guaranteed throughput</Option>
91+
</>
92+
)}
93+
</Select>
94+
</Form.Item>
95+
)
96+
}
97+
98+
export default RateLimitTypeFormItem

ui/litellm-dashboard/src/components/organisms/create_key_button.tsx

Lines changed: 13 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import MCPServerSelector from "../mcp_server_management/MCPServerSelector"
3535
import ModelAliasManager from "../common_components/ModelAliasManager"
3636
import NotificationsManager from "../molecules/notifications_manager"
3737
import KeyLifecycleSettings from "../common_components/KeyLifecycleSettings"
38+
import RateLimitTypeFormItem from "../common_components/RateLimitTypeFormItem"
3839

3940
const { Option } = Select;
4041

@@ -810,46 +811,14 @@ const CreateKey: React.FC<CreateKeyProps> = ({
810811
>
811812
<NumericalInput step={1} width={400} />
812813
</Form.Item>
813-
<Form.Item
814-
label={
815-
<span>
816-
TPM Rate Limit Type {' '}
817-
<Tooltip title="Select 'guaranteed_throughput' to prevent overallocating TPM limit when the key belongs to a Team with specific TPM limits.">
818-
<InfoCircleOutlined style={{ marginLeft: '4px' }} />
819-
</Tooltip>
820-
</span>
821-
}
814+
<RateLimitTypeFormItem
815+
type="tpm"
822816
name="tpm_limit_type"
823-
initialValue={null}
824817
className="mt-4"
825-
>
826-
<Select
827-
defaultValue="default"
828-
placeholder="Select rate limit type"
829-
style={{ width: "100%" }}
830-
optionLabelProp="label"
831-
onChange={(value) => {
832-
form.setFieldValue('tpm_limit_type', value);
833-
}}
834-
>
835-
<Option value="best_effort_throughput" label="Default">
836-
<div style={{ padding: '4px 0' }}>
837-
<div style={{ fontWeight: 500 }}>Default</div>
838-
<div style={{ fontSize: '11px', color: '#6b7280', marginTop: '2px' }}>
839-
Best effort throughput - no error if we're overallocating tpm (Team/Key Limits checked at runtim).
840-
</div>
841-
</div>
842-
</Option>
843-
<Option value="guaranteed_throughput" label="Guaranteed throughput">
844-
<div style={{ padding: '4px 0' }}>
845-
<div style={{ fontWeight: 500 }}>Guaranteed throughput</div>
846-
<div style={{ fontSize: '11px', color: '#6b7280', marginTop: '2px' }}>
847-
Guaranteed throughput - raise an error if we're overallocating tpm (also checks model-specific limits)
848-
</div>
849-
</div>
850-
</Option>
851-
</Select>
852-
</Form.Item>
818+
initialValue={null}
819+
form={form}
820+
showDetailedDescriptions={true}
821+
/>
853822
<Form.Item
854823
className="mt-4"
855824
label={
@@ -881,46 +850,14 @@ const CreateKey: React.FC<CreateKeyProps> = ({
881850
>
882851
<NumericalInput step={1} width={400} />
883852
</Form.Item>
884-
<Form.Item
885-
label={
886-
<span>
887-
RPM Rate Limit Type {' '}
888-
<Tooltip title="Select 'guaranteed_throughput' to prevent overallocating RPM limit when the key belongs to a Team with specific RPM limits.">
889-
<InfoCircleOutlined style={{ marginLeft: '4px' }} />
890-
</Tooltip>
891-
</span>
892-
}
853+
<RateLimitTypeFormItem
854+
type="rpm"
893855
name="rpm_limit_type"
894-
initialValue={null}
895856
className="mt-4"
896-
>
897-
<Select
898-
defaultValue="default"
899-
placeholder="Select rate limit type"
900-
style={{ width: "100%" }}
901-
optionLabelProp="label"
902-
onChange={(value) => {
903-
form.setFieldValue('rpm_limit_type', value);
904-
}}
905-
>
906-
<Option value="best_effort_throughput" label="Default">
907-
<div style={{ padding: '4px 0' }}>
908-
<div style={{ fontWeight: 500 }}>Default</div>
909-
<div style={{ fontSize: '11px', color: '#6b7280', marginTop: '2px' }}>
910-
Best effort throughput - no error if we're overallocating rpm (Team/Key Limits checked at runtim).
911-
</div>
912-
</div>
913-
</Option>
914-
<Option value="guaranteed_throughput" label="Guaranteed throughput">
915-
<div style={{ padding: '4px 0' }}>
916-
<div style={{ fontWeight: 500 }}>Guaranteed throughput</div>
917-
<div style={{ fontSize: '11px', color: '#6b7280', marginTop: '2px' }}>
918-
Guaranteed throughput - raise an error if we're overallocating rpm (also checks model-specific limits)
919-
</div>
920-
</div>
921-
</Option>
922-
</Select>
923-
</Form.Item>
857+
initialValue={null}
858+
form={form}
859+
showDetailedDescriptions={true}
860+
/>
924861
<Form.Item
925862
label={
926863
<span>

ui/litellm-dashboard/src/components/templates/key_edit_view.tsx

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { fetchMCPAccessGroups } from "../networking"
1313
import { mapInternalToDisplayNames, mapDisplayToInternalNames } from "../callback_info_helpers"
1414
import GuardrailSelector from "@/components/guardrails/GuardrailSelector"
1515
import KeyLifecycleSettings from "../common_components/KeyLifecycleSettings"
16+
import RateLimitTypeFormItem from "../common_components/RateLimitTypeFormItem"
1617

1718
interface KeyEditViewProps {
1819
keyData: KeyResponse
@@ -222,10 +223,22 @@ export function KeyEditView({
222223
<NumericalInput min={0} />
223224
</Form.Item>
224225

226+
<RateLimitTypeFormItem
227+
type="tpm"
228+
name="tpm_limit_type"
229+
showDetailedDescriptions={false}
230+
/>
231+
225232
<Form.Item label="RPM Limit" name="rpm_limit">
226233
<NumericalInput min={0} />
227234
</Form.Item>
228235

236+
<RateLimitTypeFormItem
237+
type="rpm"
238+
name="rpm_limit_type"
239+
showDetailedDescriptions={false}
240+
/>
241+
229242
<Form.Item label="Max Parallel Requests" name="max_parallel_requests">
230243
<NumericalInput min={0} />
231244
</Form.Item>

0 commit comments

Comments
 (0)