forked from phoenix/litellm-mirror
feat(ui/model_dashboard.tsx): show if model is config or db model
This commit is contained in:
parent
a325bf2fb8
commit
fbcda918de
4 changed files with 42 additions and 8 deletions
|
@ -2516,20 +2516,21 @@ class ProxyConfig:
|
||||||
router = litellm.Router(**router_params) # type:ignore
|
router = litellm.Router(**router_params) # type:ignore
|
||||||
return router, model_list, general_settings
|
return router, model_list, general_settings
|
||||||
|
|
||||||
def get_model_info_with_id(self, model) -> RouterModelInfo:
|
def get_model_info_with_id(self, model, db_model=False) -> RouterModelInfo:
|
||||||
"""
|
"""
|
||||||
Common logic across add + delete router models
|
Common logic across add + delete router models
|
||||||
Parameters:
|
Parameters:
|
||||||
- deployment
|
- deployment
|
||||||
|
- db_model -> flag for differentiating model stored in db vs. config -> used on UI
|
||||||
|
|
||||||
Return model info w/ id
|
Return model info w/ id
|
||||||
"""
|
"""
|
||||||
if model.model_info is not None and isinstance(model.model_info, dict):
|
if model.model_info is not None and isinstance(model.model_info, dict):
|
||||||
if "id" not in model.model_info:
|
if "id" not in model.model_info:
|
||||||
model.model_info["id"] = model.model_id
|
model.model_info["id"] = model.model_id
|
||||||
_model_info = RouterModelInfo(**model.model_info)
|
_model_info = RouterModelInfo(**model.model_info, db_model=db_model)
|
||||||
else:
|
else:
|
||||||
_model_info = RouterModelInfo(id=model.model_id)
|
_model_info = RouterModelInfo(id=model.model_id, db_model=db_model)
|
||||||
return _model_info
|
return _model_info
|
||||||
|
|
||||||
async def _delete_deployment(self, db_models: list) -> int:
|
async def _delete_deployment(self, db_models: list) -> int:
|
||||||
|
@ -2624,7 +2625,9 @@ class ProxyConfig:
|
||||||
f"Invalid model added to proxy db. Invalid litellm params. litellm_params={_litellm_params}"
|
f"Invalid model added to proxy db. Invalid litellm params. litellm_params={_litellm_params}"
|
||||||
)
|
)
|
||||||
continue # skip to next model
|
continue # skip to next model
|
||||||
_model_info = self.get_model_info_with_id(model=m)
|
_model_info = self.get_model_info_with_id(
|
||||||
|
model=m, db_model=True
|
||||||
|
) ## 👈 FLAG = True for db_models
|
||||||
|
|
||||||
added = llm_router.add_deployment(
|
added = llm_router.add_deployment(
|
||||||
deployment=Deployment(
|
deployment=Deployment(
|
||||||
|
@ -7449,6 +7452,16 @@ async def update_model(
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
if _existing_litellm_params is None:
|
if _existing_litellm_params is None:
|
||||||
|
if (
|
||||||
|
llm_router is not None
|
||||||
|
and llm_router.get_deployment(model_id=_model_id) is not None
|
||||||
|
):
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=400,
|
||||||
|
detail={
|
||||||
|
"error": "Can't edit model. Model in config. Store model in db via `/model/new`. to edit."
|
||||||
|
},
|
||||||
|
)
|
||||||
raise Exception("model not found")
|
raise Exception("model not found")
|
||||||
_existing_litellm_params_dict = dict(
|
_existing_litellm_params_dict = dict(
|
||||||
_existing_litellm_params.litellm_params
|
_existing_litellm_params.litellm_params
|
||||||
|
|
|
@ -2595,11 +2595,21 @@ class Router:
|
||||||
except:
|
except:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def get_deployment(self, model_id: str):
|
def get_deployment(self, model_id: str) -> Optional[Deployment]:
|
||||||
|
"""
|
||||||
|
Returns -> Deployment or None
|
||||||
|
|
||||||
|
Raise Exception -> if model found in invalid format
|
||||||
|
"""
|
||||||
for model in self.model_list:
|
for model in self.model_list:
|
||||||
if "model_info" in model and "id" in model["model_info"]:
|
if "model_info" in model and "id" in model["model_info"]:
|
||||||
if model_id == model["model_info"]["id"]:
|
if model_id == model["model_info"]["id"]:
|
||||||
return model
|
if isinstance(model, dict):
|
||||||
|
return Deployment(**model)
|
||||||
|
elif isinstance(model, Deployment):
|
||||||
|
return model
|
||||||
|
else:
|
||||||
|
raise Exception("Model invalid format - {}".format(type(model)))
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def get_model_info(self, id: str) -> Optional[dict]:
|
def get_model_info(self, id: str) -> Optional[dict]:
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
from typing import List, Optional, Union, Dict, Tuple, Literal
|
from typing import List, Optional, Union, Dict, Tuple, Literal
|
||||||
import httpx
|
import httpx
|
||||||
from pydantic import BaseModel, validator
|
from pydantic import BaseModel, validator, Field
|
||||||
from .completion import CompletionRequest
|
from .completion import CompletionRequest
|
||||||
from .embedding import EmbeddingRequest
|
from .embedding import EmbeddingRequest
|
||||||
import uuid, enum
|
import uuid, enum
|
||||||
|
@ -70,6 +70,9 @@ class ModelInfo(BaseModel):
|
||||||
id: Optional[
|
id: Optional[
|
||||||
str
|
str
|
||||||
] # Allow id to be optional on input, but it will always be present as a str in the model instance
|
] # Allow id to be optional on input, but it will always be present as a str in the model instance
|
||||||
|
db_model: bool = (
|
||||||
|
False # used for proxy - to separate models which are stored in the db vs. config.
|
||||||
|
)
|
||||||
|
|
||||||
def __init__(self, id: Optional[Union[str, int]] = None, **params):
|
def __init__(self, id: Optional[Union[str, int]] = None, **params):
|
||||||
if id is None:
|
if id is None:
|
||||||
|
|
|
@ -37,7 +37,7 @@ import { Badge, BadgeDelta, Button } from "@tremor/react";
|
||||||
import RequestAccess from "./request_model_access";
|
import RequestAccess from "./request_model_access";
|
||||||
import { Typography } from "antd";
|
import { Typography } from "antd";
|
||||||
import TextArea from "antd/es/input/TextArea";
|
import TextArea from "antd/es/input/TextArea";
|
||||||
import { InformationCircleIcon, PencilAltIcon, PencilIcon, StatusOnlineIcon, TrashIcon, RefreshIcon } from "@heroicons/react/outline";
|
import { InformationCircleIcon, PencilAltIcon, PencilIcon, StatusOnlineIcon, TrashIcon, RefreshIcon, CheckCircleIcon, XCircleIcon } from "@heroicons/react/outline";
|
||||||
import DeleteModelButton from "./delete_model_button";
|
import DeleteModelButton from "./delete_model_button";
|
||||||
const { Title: Title2, Link } = Typography;
|
const { Title: Title2, Link } = Typography;
|
||||||
import { UploadOutlined } from '@ant-design/icons';
|
import { UploadOutlined } from '@ant-design/icons';
|
||||||
|
@ -921,6 +921,7 @@ const handleEditSubmit = async (formValues: Record<string, any>) => {
|
||||||
<TableHeaderCell>Input Price per token ($)</TableHeaderCell>
|
<TableHeaderCell>Input Price per token ($)</TableHeaderCell>
|
||||||
<TableHeaderCell>Output Price per token ($)</TableHeaderCell>
|
<TableHeaderCell>Output Price per token ($)</TableHeaderCell>
|
||||||
<TableHeaderCell>Max Tokens</TableHeaderCell>
|
<TableHeaderCell>Max Tokens</TableHeaderCell>
|
||||||
|
<TableHeaderCell>Status</TableHeaderCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
</TableHead>
|
</TableHead>
|
||||||
<TableBody>
|
<TableBody>
|
||||||
|
@ -929,6 +930,7 @@ const handleEditSubmit = async (formValues: Record<string, any>) => {
|
||||||
selectedModelGroup === "all" || model.model_name === selectedModelGroup || selectedModelGroup === null || selectedModelGroup === undefined || selectedModelGroup === ""
|
selectedModelGroup === "all" || model.model_name === selectedModelGroup || selectedModelGroup === null || selectedModelGroup === undefined || selectedModelGroup === ""
|
||||||
)
|
)
|
||||||
.map((model: any, index: number) => (
|
.map((model: any, index: number) => (
|
||||||
|
|
||||||
<TableRow key={index}>
|
<TableRow key={index}>
|
||||||
<TableCell>
|
<TableCell>
|
||||||
<Text>{model.model_name}</Text>
|
<Text>{model.model_name}</Text>
|
||||||
|
@ -958,6 +960,12 @@ const handleEditSubmit = async (formValues: Record<string, any>) => {
|
||||||
<TableCell>{model.input_cost}</TableCell>
|
<TableCell>{model.input_cost}</TableCell>
|
||||||
<TableCell>{model.output_cost}</TableCell>
|
<TableCell>{model.output_cost}</TableCell>
|
||||||
<TableCell>{model.max_tokens}</TableCell>
|
<TableCell>{model.max_tokens}</TableCell>
|
||||||
|
<TableCell>
|
||||||
|
{
|
||||||
|
model.model_info.db_model ? <Badge icon={CheckCircleIcon} className="text-white">DB Model</Badge> : <Badge icon={XCircleIcon} className="text-black">Config Model</Badge>
|
||||||
|
}
|
||||||
|
|
||||||
|
</TableCell>
|
||||||
<TableCell>
|
<TableCell>
|
||||||
<Icon
|
<Icon
|
||||||
icon={PencilAltIcon}
|
icon={PencilAltIcon}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue