mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-13 23:11:40 +00:00
Add Custom Tooltips to Model Mapping Table (#13294)
* descriptive tooltips * atomic folder structure * undo changes * import fix * reorder
This commit is contained in:
parent
9761ba7c7a
commit
43af255b45
4 changed files with 118 additions and 11 deletions
|
|
@ -1,12 +1,11 @@
|
|||
import React, { useEffect, useState } from "react";
|
||||
import { Form, Table, Input } from "antd";
|
||||
import { Text, TextInput } from "@tremor/react";
|
||||
import { Row, Col } from "antd";
|
||||
import { Form, Table } from "antd";
|
||||
import { TextInput } from "@tremor/react";
|
||||
import { Tooltip } from "../atoms/index";
|
||||
|
||||
const ConditionalPublicModelName: React.FC = () => {
|
||||
// Access the form instance
|
||||
const form = Form.useFormInstance();
|
||||
const [tableKey, setTableKey] = useState(0); // Add a key to force table re-render
|
||||
const [tableKey, setTableKey] = useState(0);// Add a key to force table re-render
|
||||
|
||||
// Watch the 'model' field for changes and ensure it's always an array
|
||||
const modelValue = Form.useWatch('model', form) || [];
|
||||
|
|
@ -14,7 +13,6 @@ const ConditionalPublicModelName: React.FC = () => {
|
|||
const customModelName = Form.useWatch('custom_model_name', form);
|
||||
const showPublicModelName = !selectedModels.includes('all-wildcard');
|
||||
|
||||
|
||||
// Force table to re-render when custom model name changes
|
||||
useEffect(() => {
|
||||
if (customModelName && selectedModels.includes('custom')) {
|
||||
|
|
@ -71,9 +69,39 @@ const ConditionalPublicModelName: React.FC = () => {
|
|||
|
||||
if (!showPublicModelName) return null;
|
||||
|
||||
const publicNameTooltipContent = (
|
||||
<>
|
||||
<div className="mb-2 font-normal">
|
||||
The name you specify in your API calls to LiteLLM Proxy
|
||||
</div>
|
||||
<div className="mb-2 font-normal">
|
||||
<strong>Example:</strong> If you name your public model <code className="bg-gray-700 px-1 py-0.5 rounded text-xs">example-name</code>
|
||||
, and choose <code className="bg-gray-700 px-1 py-0.5 rounded text-xs">openai/qwen-plus-latest</code> as the LiteLLM model
|
||||
</div>
|
||||
<div className="mb-2 font-normal">
|
||||
<strong>Usage:</strong> You make an API call to the LiteLLM proxy with <code className="bg-gray-700 px-1 py-0.5 rounded text-xs">model = "example-name"</code>
|
||||
</div>
|
||||
<div className="font-normal">
|
||||
<strong>Result:</strong> LiteLLM sends <code className="bg-gray-700 px-1 py-0.5 rounded text-xs">qwen-plus-latest</code> to the provider
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
|
||||
const liteLLMModelTooltipContent = (
|
||||
<div>The model name LiteLLM will send to the LLM API</div>
|
||||
);
|
||||
|
||||
const columns = [
|
||||
{
|
||||
title: 'Public Name',
|
||||
title: (
|
||||
<span className="flex items-center">
|
||||
Public Model Name
|
||||
<Tooltip
|
||||
content={publicNameTooltipContent}
|
||||
width="500px"
|
||||
/>
|
||||
</span>
|
||||
),
|
||||
dataIndex: 'public_name',
|
||||
key: 'public_name',
|
||||
render: (text: string, record: any, index: number) => {
|
||||
|
|
@ -90,7 +118,15 @@ const ConditionalPublicModelName: React.FC = () => {
|
|||
}
|
||||
},
|
||||
{
|
||||
title: 'LiteLLM Model',
|
||||
title: (
|
||||
<span className="flex items-center">
|
||||
LiteLLM Model Name
|
||||
<Tooltip
|
||||
content={liteLLMModelTooltipContent}
|
||||
width="360px"
|
||||
/>
|
||||
</span>
|
||||
),
|
||||
dataIndex: 'litellm_model',
|
||||
key: 'litellm_model',
|
||||
}
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ const LiteLLMModelNameField: React.FC<LiteLLMModelNameFieldProps> = ({
|
|||
<>
|
||||
<Form.Item
|
||||
label="LiteLLM Model Name(s)"
|
||||
tooltip="Actual model name used for making litellm.completion() / litellm.embedding() call."
|
||||
tooltip="The model name LiteLLM will send to the LLM API"
|
||||
className="mb-0"
|
||||
>
|
||||
<Form.Item
|
||||
|
|
@ -145,9 +145,9 @@ const LiteLLMModelNameField: React.FC<LiteLLMModelNameFieldProps> = ({
|
|||
</Form.Item>
|
||||
<Row>
|
||||
<Col span={10}></Col>
|
||||
<Col span={10}>
|
||||
<Col span={14}>
|
||||
<Text className="mb-3 mt-1">
|
||||
Actual model name used for making litellm.completion() call. We loadbalance models with the same public name
|
||||
The model name LiteLLM will send to the LLM API
|
||||
</Text>
|
||||
</Col>
|
||||
</Row>
|
||||
|
|
|
|||
70
ui/litellm-dashboard/src/components/atoms/Tooltip.tsx
Normal file
70
ui/litellm-dashboard/src/components/atoms/Tooltip.tsx
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
import React, { useState, useRef } from "react"
|
||||
import { QuestionCircleOutlined } from "@ant-design/icons"
|
||||
|
||||
interface TooltipProps {
|
||||
content: React.ReactNode
|
||||
children?: React.ReactNode
|
||||
width?: string
|
||||
className?: string
|
||||
}
|
||||
|
||||
export const Tooltip: React.FC<TooltipProps> = ({ content, children, width = "auto", className = "" }) => {
|
||||
const [showTooltip, setShowTooltip] = useState(false)
|
||||
const [tooltipPosition, setTooltipPosition] = useState<"top" | "bottom">("top")
|
||||
const tooltipRef = useRef<HTMLDivElement>(null)
|
||||
|
||||
// Function to check if tooltip would fit above
|
||||
const checkTooltipPosition = () => {
|
||||
if (tooltipRef.current) {
|
||||
const rect = tooltipRef.current.getBoundingClientRect()
|
||||
const tooltipHeight = 300 // Approximate height of the tooltip
|
||||
const spaceAbove = rect.top
|
||||
const spaceBelow = window.innerHeight - rect.bottom
|
||||
|
||||
if (spaceAbove < tooltipHeight && spaceBelow > tooltipHeight) {
|
||||
setTooltipPosition("bottom")
|
||||
} else {
|
||||
setTooltipPosition("top")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="relative inline-block" ref={tooltipRef}>
|
||||
{children || (
|
||||
<QuestionCircleOutlined
|
||||
className="ml-1 text-gray-500 cursor-help"
|
||||
onMouseEnter={() => {
|
||||
checkTooltipPosition()
|
||||
setShowTooltip(true)
|
||||
}}
|
||||
onMouseLeave={() => setShowTooltip(false)}
|
||||
/>
|
||||
)}
|
||||
{showTooltip && (
|
||||
<div
|
||||
className={`absolute left-1/2 -translate-x-1/2 z-50 bg-black/90 text-white p-2 rounded-md text-sm font-normal shadow-lg ${className}`}
|
||||
style={{
|
||||
[tooltipPosition === "top" ? "bottom" : "top"]: "100%",
|
||||
width: width,
|
||||
marginBottom: tooltipPosition === "top" ? "8px" : "0",
|
||||
marginTop: tooltipPosition === "bottom" ? "8px" : "0",
|
||||
}}
|
||||
>
|
||||
{content}
|
||||
<div
|
||||
className="absolute left-1/2 -translate-x-1/2 w-0 h-0"
|
||||
style={{
|
||||
top: tooltipPosition === "top" ? "100%" : "auto",
|
||||
bottom: tooltipPosition === "bottom" ? "100%" : "auto",
|
||||
borderTop: tooltipPosition === "top" ? "6px solid rgba(0, 0, 0, 0.9)" : "6px solid transparent",
|
||||
borderBottom: tooltipPosition === "bottom" ? "6px solid rgba(0, 0, 0, 0.9)" : "6px solid transparent",
|
||||
borderLeft: "6px solid transparent",
|
||||
borderRight: "6px solid transparent",
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
1
ui/litellm-dashboard/src/components/atoms/index.ts
Normal file
1
ui/litellm-dashboard/src/components/atoms/index.ts
Normal file
|
|
@ -0,0 +1 @@
|
|||
export { Tooltip } from './Tooltip';
|
||||
Loading…
Add table
Reference in a new issue