mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-19 00:01:29 +00:00
fix(ui): type transformModelData output as ModelData so the dashboard build typechecks
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
parent
b5070408e7
commit
d197ca20fa
6 changed files with 40 additions and 42 deletions
|
|
@ -11,8 +11,8 @@ const makeModel = (overrides: Partial<ModelData> = {}): ModelData =>
|
|||
model_name: "gpt-4-public",
|
||||
litellm_model_name: "openai/gpt-4",
|
||||
provider: "openai",
|
||||
input_cost: 30 as unknown as number,
|
||||
output_cost: 60 as unknown as number,
|
||||
input_cost: "30",
|
||||
output_cost: "60",
|
||||
max_tokens: 8192,
|
||||
max_input_tokens: 8192,
|
||||
litellm_params: { model: "openai/gpt-4" },
|
||||
|
|
@ -178,7 +178,7 @@ describe("AllModelsTable", () => {
|
|||
rerender(
|
||||
<AllModelsTable
|
||||
{...baseProps}
|
||||
data={[makeModel({ input_cost: null as unknown as number, output_cost: null as unknown as number })]}
|
||||
data={[makeModel({ input_cost: null, output_cost: null })]}
|
||||
/>,
|
||||
);
|
||||
expect(screen.queryByText(/^\$/)).not.toBeInTheDocument();
|
||||
|
|
@ -190,8 +190,8 @@ describe("AllModelsTable", () => {
|
|||
{...baseProps}
|
||||
data={[
|
||||
makeModel({
|
||||
input_cost: "0.00" as unknown as number,
|
||||
output_cost: "0.00" as unknown as number,
|
||||
input_cost: "0.00",
|
||||
output_cost: "0.00",
|
||||
output_cost_per_second: 0.4,
|
||||
}),
|
||||
]}
|
||||
|
|
@ -205,8 +205,8 @@ describe("AllModelsTable", () => {
|
|||
{...baseProps}
|
||||
data={[
|
||||
makeModel({
|
||||
input_cost: "0.60" as unknown as number,
|
||||
output_cost: "0.00" as unknown as number,
|
||||
input_cost: "0.60",
|
||||
output_cost: "0.00",
|
||||
output_cost_per_second: 0.015,
|
||||
}),
|
||||
]}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { PerSecondCostTier } from "@/components/model_dashboard/types";
|
||||
import { LiteLLMParams, ModelData, ModelInfo, PerSecondCostTier } from "@/components/model_dashboard/types";
|
||||
|
||||
const PER_SECOND_TIER_KEY = /^output_cost_per_second_(.+)$/;
|
||||
|
||||
|
|
@ -8,15 +8,11 @@ export const perSecondCostTiers = (modelInfo: Record<string, unknown> | null | u
|
|||
return resolution !== undefined && typeof value === "number" ? [{ resolution, cost: value }] : [];
|
||||
});
|
||||
|
||||
interface RawLitellmParams {
|
||||
model?: string;
|
||||
custom_llm_provider?: string;
|
||||
api_base?: string;
|
||||
interface RawLitellmParams extends LiteLLMParams {
|
||||
output_cost_per_second?: number;
|
||||
[key: string]: unknown;
|
||||
}
|
||||
|
||||
interface RawModelInfo {
|
||||
interface RawModelInfo extends ModelInfo {
|
||||
input_cost_per_token?: number | null;
|
||||
output_cost_per_token?: number | null;
|
||||
output_cost_per_second?: number;
|
||||
|
|
@ -25,14 +21,15 @@ interface RawModelInfo {
|
|||
[key: string]: unknown;
|
||||
}
|
||||
|
||||
interface RawModel {
|
||||
litellm_params?: RawLitellmParams;
|
||||
model_info?: RawModelInfo;
|
||||
export interface RawModel {
|
||||
model_name: string;
|
||||
litellm_params: RawLitellmParams;
|
||||
model_info: RawModelInfo;
|
||||
[key: string]: unknown;
|
||||
}
|
||||
|
||||
const costPerMillionTokens = (costPerToken: number | null | undefined) =>
|
||||
costPerToken == null ? costPerToken : (Number(costPerToken) * 1000000).toFixed(2);
|
||||
const costPerMillionTokens = (costPerToken: number | null | undefined): string | null =>
|
||||
costPerToken == null ? null : (Number(costPerToken) * 1000000).toFixed(2);
|
||||
|
||||
const resolveProvider = (
|
||||
litellmModelName: string | null | undefined,
|
||||
|
|
@ -45,24 +42,24 @@ const resolveProvider = (
|
|||
return splitModel.length === 1 ? getProviderFromModel(litellmModelName) : splitModel[0];
|
||||
};
|
||||
|
||||
const transformModel = (rawModel: RawModel, getProviderFromModel: (model: string) => string) => {
|
||||
const transformModel = (rawModel: RawModel, getProviderFromModel: (model: string) => string): ModelData => {
|
||||
const model: RawModel = JSON.parse(JSON.stringify(rawModel));
|
||||
const litellmParams = model.litellm_params;
|
||||
const modelInfo = model.model_info;
|
||||
|
||||
return {
|
||||
...model,
|
||||
provider: resolveProvider(litellmParams?.model, litellmParams?.custom_llm_provider, getProviderFromModel),
|
||||
input_cost: modelInfo ? costPerMillionTokens(modelInfo.input_cost_per_token) : null,
|
||||
output_cost: modelInfo ? costPerMillionTokens(modelInfo.output_cost_per_token) : null,
|
||||
output_cost_per_second: litellmParams?.output_cost_per_second ?? modelInfo?.output_cost_per_second ?? null,
|
||||
provider: resolveProvider(litellmParams.model, litellmParams.custom_llm_provider, getProviderFromModel),
|
||||
input_cost: costPerMillionTokens(modelInfo?.input_cost_per_token),
|
||||
output_cost: costPerMillionTokens(modelInfo?.output_cost_per_token),
|
||||
output_cost_per_second: litellmParams.output_cost_per_second ?? modelInfo?.output_cost_per_second ?? null,
|
||||
output_cost_per_second_tiers: perSecondCostTiers(modelInfo),
|
||||
litellm_model_name: litellmParams?.model,
|
||||
max_tokens: modelInfo ? modelInfo.max_tokens : "Undefined",
|
||||
max_input_tokens: modelInfo ? modelInfo.max_input_tokens : "Undefined",
|
||||
api_base: litellmParams?.api_base,
|
||||
litellm_model_name: litellmParams.model,
|
||||
max_tokens: modelInfo?.max_tokens,
|
||||
max_input_tokens: modelInfo?.max_input_tokens,
|
||||
api_base: litellmParams.api_base,
|
||||
cleanedLitellmParams: Object.fromEntries(
|
||||
Object.entries(litellmParams ?? {}).filter(([key]) => key !== "model" && key !== "api_base"),
|
||||
Object.entries(litellmParams).filter(([key]) => key !== "model" && key !== "api_base"),
|
||||
),
|
||||
};
|
||||
};
|
||||
|
|
@ -70,7 +67,7 @@ const transformModel = (rawModel: RawModel, getProviderFromModel: (model: string
|
|||
export const transformModelData = (
|
||||
rawModelData: { data?: RawModel[] | null } | null | undefined,
|
||||
getProviderFromModel: (model: string) => string,
|
||||
) => {
|
||||
): { data: ModelData[] } => {
|
||||
if (!rawModelData?.data) return { data: [] };
|
||||
|
||||
return { data: rawModelData.data.map((rawModel) => transformModel(rawModel, getProviderFromModel)) };
|
||||
|
|
|
|||
|
|
@ -270,7 +270,7 @@ const displayCost = (localModelData: any, field: TouchedPricingField): string =>
|
|||
|
||||
interface ModelInfoEditFormProps {
|
||||
localModelData: any;
|
||||
modelData: { model_info: { team_id?: string | null } & Record<string, unknown> };
|
||||
modelData: { model_info: { team_id?: string | null } };
|
||||
teamAlias: string | null;
|
||||
accessToken: string | null;
|
||||
isEditing: boolean;
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ export interface ModelInfo {
|
|||
access_groups: string[] | null;
|
||||
blocked?: boolean;
|
||||
team_public_model_name?: string;
|
||||
key?: string;
|
||||
}
|
||||
|
||||
export interface LiteLLMParams {
|
||||
|
|
@ -30,12 +31,12 @@ export interface ModelData {
|
|||
model_name: string;
|
||||
provider: string;
|
||||
litellm_model_name: string;
|
||||
input_cost: number;
|
||||
output_cost: number;
|
||||
input_cost: string | null;
|
||||
output_cost: string | null;
|
||||
output_cost_per_second?: number | null;
|
||||
output_cost_per_second_tiers?: PerSecondCostTier[];
|
||||
max_tokens: number;
|
||||
max_input_tokens: number;
|
||||
max_tokens?: number;
|
||||
max_input_tokens?: number;
|
||||
api_base?: string;
|
||||
litellm_params: LiteLLMParams;
|
||||
cleanedLitellmParams: Record<string, any>;
|
||||
|
|
|
|||
|
|
@ -365,7 +365,7 @@ export default function ModelInfoView({
|
|||
// Parse the model_info from the form values
|
||||
let updatedModelInfo;
|
||||
try {
|
||||
updatedModelInfo = values.model_info ? JSON.parse(values.model_info) : modelData.model_info;
|
||||
updatedModelInfo = values.model_info ? JSON.parse(values.model_info) : modelData?.model_info;
|
||||
// Update access_groups from the form
|
||||
if (values.model_access_group) {
|
||||
updatedModelInfo = {
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import { describe, it, expect } from "vitest";
|
|||
import { render, screen } from "@testing-library/react";
|
||||
import { ModelPricingSummary } from "./ModelPricingSummary";
|
||||
|
||||
const tokenPriced = { input_cost: "1.50" as unknown as number, output_cost: "2.00" as unknown as number };
|
||||
const tokenPriced = { input_cost: "1.50", output_cost: "2.00" };
|
||||
|
||||
describe("ModelPricingSummary", () => {
|
||||
it("shows per-million-token rates for a token priced model", () => {
|
||||
|
|
@ -16,8 +16,8 @@ describe("ModelPricingSummary", () => {
|
|||
render(
|
||||
<ModelPricingSummary
|
||||
model={{
|
||||
input_cost: "0.00" as unknown as number,
|
||||
output_cost: "0.00" as unknown as number,
|
||||
input_cost: "0.00",
|
||||
output_cost: "0.00",
|
||||
output_cost_per_second: 0.1,
|
||||
output_cost_per_second_tiers: [
|
||||
{ resolution: "1080p", cost: 0.12 },
|
||||
|
|
@ -36,8 +36,8 @@ describe("ModelPricingSummary", () => {
|
|||
render(
|
||||
<ModelPricingSummary
|
||||
model={{
|
||||
input_cost: "0.60" as unknown as number,
|
||||
output_cost: "0.00" as unknown as number,
|
||||
input_cost: "0.60",
|
||||
output_cost: "0.00",
|
||||
output_cost_per_second: 0.015,
|
||||
}}
|
||||
/>,
|
||||
|
|
@ -49,7 +49,7 @@ describe("ModelPricingSummary", () => {
|
|||
|
||||
it("renders a dash when the model has no pricing at all", () => {
|
||||
render(
|
||||
<ModelPricingSummary model={{ input_cost: null as unknown as number, output_cost: null as unknown as number }} />,
|
||||
<ModelPricingSummary model={{ input_cost: null, output_cost: null }} />,
|
||||
);
|
||||
expect(screen.getByText("-")).toBeInTheDocument();
|
||||
expect(screen.queryByText(/\$/)).not.toBeInTheDocument();
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue