mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-04 02:31:27 +00:00
feat(ui): mcp_server_cost_display + add_model_tab
- mcp_server_cost_display: @tremor Text \u2192 plain <p>/<span> with semantic tokens. Kept the blue summary callout + emerald cost values; file added to .eslintrc.json overrides. - add_model_tab: @tremor Tab/TabGroup/TabList/TabPanel/TabPanels \u2192 shadcn Tabs/TabsList/TabsTrigger/TabsContent. antd Form is still passed through to AddModelForm and AddAutoRouterTab which are form-driven; not migrated in this pass. Gates: TS \u2713 | Build \u2713. Co-authored-by: yuneng-jiang <yuneng-berri@users.noreply.github.com>
This commit is contained in:
parent
fab8c8ec8d
commit
56e17427cc
3 changed files with 84 additions and 62 deletions
|
|
@ -41,6 +41,7 @@
|
|||
"src/components/mcp_server_management/MCPServerSelector.tsx",
|
||||
"src/components/mcp_tools/MCPNetworkSettings.tsx",
|
||||
"src/components/mcp_tools/ByokCredentialModal.tsx",
|
||||
"src/components/mcp_tools/mcp_server_cost_display.tsx",
|
||||
"src/components/shared/usage_date_picker.tsx",
|
||||
"src/components/shared/advanced_date_picker.tsx",
|
||||
"src/components/activity_metrics.tsx",
|
||||
|
|
|
|||
|
|
@ -1,4 +1,9 @@
|
|||
import { Tab, TabGroup, TabList, TabPanel, TabPanels } from "@tremor/react";
|
||||
import {
|
||||
Tabs,
|
||||
TabsContent,
|
||||
TabsList,
|
||||
TabsTrigger,
|
||||
} from "@/components/ui/tabs";
|
||||
import type { FormInstance } from "antd";
|
||||
import { Form } from "antd";
|
||||
import type { UploadProps } from "antd/es/upload";
|
||||
|
|
@ -11,7 +16,8 @@ import AddModelForm from "./AddModelForm";
|
|||
import { handleAddAutoRouterSubmit } from "./handle_add_auto_router_submit";
|
||||
|
||||
interface AddModelTabProps {
|
||||
form: FormInstance; // For the Add Model tab
|
||||
form: FormInstance;
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
handleOk: (values?: any) => Promise<void>;
|
||||
selectedProvider: Providers;
|
||||
setSelectedProvider: (provider: Providers) => void;
|
||||
|
|
@ -43,14 +49,18 @@ const AddModelTab: React.FC<AddModelTabProps> = ({
|
|||
accessToken,
|
||||
userRole,
|
||||
}) => {
|
||||
// Create separate form instance for auto router
|
||||
const [autoRouterForm] = Form.useForm();
|
||||
|
||||
const handleAutoRouterOk = () => {
|
||||
autoRouterForm
|
||||
.validateFields()
|
||||
.then((values) => {
|
||||
handleAddAutoRouterSubmit(values, accessToken, autoRouterForm, handleOk);
|
||||
handleAddAutoRouterSubmit(
|
||||
values,
|
||||
accessToken,
|
||||
autoRouterForm,
|
||||
handleOk,
|
||||
);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Validation failed:", error);
|
||||
|
|
@ -58,40 +68,36 @@ const AddModelTab: React.FC<AddModelTabProps> = ({
|
|||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<TabGroup className="w-full">
|
||||
<TabList className="mb-4">
|
||||
<Tab>Add Model</Tab>
|
||||
<Tab>Add Auto Router</Tab>
|
||||
</TabList>
|
||||
<TabPanels>
|
||||
<TabPanel>
|
||||
<AddModelForm
|
||||
form={form}
|
||||
handleOk={handleOk}
|
||||
selectedProvider={selectedProvider}
|
||||
setSelectedProvider={setSelectedProvider}
|
||||
providerModels={providerModels}
|
||||
setProviderModelsFn={setProviderModelsFn}
|
||||
getPlaceholder={getPlaceholder}
|
||||
uploadProps={uploadProps}
|
||||
showAdvancedSettings={showAdvancedSettings}
|
||||
setShowAdvancedSettings={setShowAdvancedSettings}
|
||||
teams={teams}
|
||||
credentials={credentials}
|
||||
/>
|
||||
</TabPanel>
|
||||
<TabPanel>
|
||||
<AddAutoRouterTab
|
||||
form={autoRouterForm}
|
||||
handleOk={handleAutoRouterOk}
|
||||
accessToken={accessToken}
|
||||
userRole={userRole}
|
||||
/>
|
||||
</TabPanel>
|
||||
</TabPanels>
|
||||
</TabGroup>
|
||||
</>
|
||||
<Tabs defaultValue="add-model" className="w-full">
|
||||
<TabsList className="mb-4">
|
||||
<TabsTrigger value="add-model">Add Model</TabsTrigger>
|
||||
<TabsTrigger value="add-auto-router">Add Auto Router</TabsTrigger>
|
||||
</TabsList>
|
||||
<TabsContent value="add-model">
|
||||
<AddModelForm
|
||||
form={form}
|
||||
handleOk={handleOk}
|
||||
selectedProvider={selectedProvider}
|
||||
setSelectedProvider={setSelectedProvider}
|
||||
providerModels={providerModels}
|
||||
setProviderModelsFn={setProviderModelsFn}
|
||||
getPlaceholder={getPlaceholder}
|
||||
uploadProps={uploadProps}
|
||||
showAdvancedSettings={showAdvancedSettings}
|
||||
setShowAdvancedSettings={setShowAdvancedSettings}
|
||||
teams={teams}
|
||||
credentials={credentials}
|
||||
/>
|
||||
</TabsContent>
|
||||
<TabsContent value="add-auto-router">
|
||||
<AddAutoRouterTab
|
||||
form={autoRouterForm}
|
||||
handleOk={handleAutoRouterOk}
|
||||
accessToken={accessToken}
|
||||
userRole={userRole}
|
||||
/>
|
||||
</TabsContent>
|
||||
</Tabs>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,26 +1,30 @@
|
|||
import React from "react";
|
||||
import { Text } from "@tremor/react";
|
||||
import { MCPServerCostInfo } from "./types";
|
||||
|
||||
interface MCPServerCostDisplayProps {
|
||||
costConfig?: MCPServerCostInfo | null;
|
||||
}
|
||||
|
||||
const MCPServerCostDisplay: React.FC<MCPServerCostDisplayProps> = ({ costConfig }) => {
|
||||
const MCPServerCostDisplay: React.FC<MCPServerCostDisplayProps> = ({
|
||||
costConfig,
|
||||
}) => {
|
||||
const hasDefaultCost =
|
||||
costConfig?.default_cost_per_query !== undefined && costConfig?.default_cost_per_query !== null;
|
||||
costConfig?.default_cost_per_query !== undefined &&
|
||||
costConfig?.default_cost_per_query !== null;
|
||||
const hasToolCosts =
|
||||
costConfig?.tool_name_to_cost_per_query && Object.keys(costConfig.tool_name_to_cost_per_query).length > 0;
|
||||
costConfig?.tool_name_to_cost_per_query &&
|
||||
Object.keys(costConfig.tool_name_to_cost_per_query).length > 0;
|
||||
const hasCostConfig = hasDefaultCost || hasToolCosts;
|
||||
|
||||
if (!hasCostConfig) {
|
||||
return (
|
||||
<div className="mt-6 pt-6 border-t border-gray-200">
|
||||
<div className="mt-6 pt-6 border-t border-border">
|
||||
<div className="space-y-4">
|
||||
<div className="p-4 bg-gray-50 border border-gray-200 rounded-lg">
|
||||
<Text className="text-gray-600">
|
||||
No cost configuration set for this server. Tool calls will be charged at $0.00 per tool call.
|
||||
</Text>
|
||||
<div className="p-4 bg-muted border border-border rounded-lg">
|
||||
<p className="text-muted-foreground">
|
||||
No cost configuration set for this server. Tool calls will be
|
||||
charged at $0.00 per tool call.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -28,28 +32,35 @@ const MCPServerCostDisplay: React.FC<MCPServerCostDisplayProps> = ({ costConfig
|
|||
}
|
||||
|
||||
return (
|
||||
<div className="mt-6 pt-6 border-t border-gray-200">
|
||||
<div className="mt-6 pt-6 border-t border-border">
|
||||
<div className="space-y-4">
|
||||
{hasDefaultCost &&
|
||||
costConfig?.default_cost_per_query !== undefined &&
|
||||
costConfig?.default_cost_per_query !== null && (
|
||||
<div>
|
||||
<Text className="font-medium">Default Cost per Query</Text>
|
||||
<div className="text-green-600 font-mono">${costConfig.default_cost_per_query.toFixed(4)}</div>
|
||||
<p className="font-medium">Default Cost per Query</p>
|
||||
<div className="text-emerald-600 dark:text-emerald-400 font-mono">
|
||||
${costConfig.default_cost_per_query.toFixed(4)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{hasToolCosts && costConfig?.tool_name_to_cost_per_query && (
|
||||
<div>
|
||||
<Text className="font-medium">Tool-Specific Costs</Text>
|
||||
<p className="font-medium">Tool-Specific Costs</p>
|
||||
<div className="mt-2 space-y-2">
|
||||
{Object.entries(costConfig.tool_name_to_cost_per_query).map(
|
||||
([toolName, cost]) =>
|
||||
cost !== null &&
|
||||
cost !== undefined && (
|
||||
<div key={toolName} className="flex justify-between items-center p-3 bg-gray-50 rounded-lg">
|
||||
<Text className="font-medium">{toolName}</Text>
|
||||
<Text className="text-green-600 font-mono">${cost.toFixed(4)} per query</Text>
|
||||
<div
|
||||
key={toolName}
|
||||
className="flex justify-between items-center p-3 bg-muted rounded-lg"
|
||||
>
|
||||
<span className="font-medium">{toolName}</span>
|
||||
<span className="text-emerald-600 dark:text-emerald-400 font-mono">
|
||||
${cost.toFixed(4)} per query
|
||||
</span>
|
||||
</div>
|
||||
),
|
||||
)}
|
||||
|
|
@ -57,20 +68,24 @@ const MCPServerCostDisplay: React.FC<MCPServerCostDisplayProps> = ({ costConfig
|
|||
</div>
|
||||
)}
|
||||
|
||||
<div className="mt-4 p-4 bg-blue-50 border border-blue-200 rounded-lg">
|
||||
<Text className="text-blue-800 font-medium">Cost Summary:</Text>
|
||||
<div className="mt-4 p-4 bg-blue-50 dark:bg-blue-950/30 border border-blue-200 dark:border-blue-900 rounded-lg">
|
||||
<p className="text-blue-800 dark:text-blue-200 font-medium">
|
||||
Cost Summary:
|
||||
</p>
|
||||
<div className="mt-2 space-y-1">
|
||||
{hasDefaultCost &&
|
||||
costConfig?.default_cost_per_query !== undefined &&
|
||||
costConfig?.default_cost_per_query !== null && (
|
||||
<Text className="text-blue-700">
|
||||
• Default cost: ${costConfig.default_cost_per_query.toFixed(4)} per query
|
||||
</Text>
|
||||
<p className="text-blue-700 dark:text-blue-300">
|
||||
• Default cost: $
|
||||
{costConfig.default_cost_per_query.toFixed(4)} per query
|
||||
</p>
|
||||
)}
|
||||
{hasToolCosts && costConfig?.tool_name_to_cost_per_query && (
|
||||
<Text className="text-blue-700">
|
||||
• {Object.keys(costConfig.tool_name_to_cost_per_query).length} tool(s) with custom pricing
|
||||
</Text>
|
||||
<p className="text-blue-700 dark:text-blue-300">
|
||||
• {Object.keys(costConfig.tool_name_to_cost_per_query).length}{" "}
|
||||
tool(s) with custom pricing
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue