Merge pull request #9271 from BerriAI/litellm_rc_03_14_2025_patch_1
Litellm rc 03 14 2025 patch 1
This commit is contained in:
commit
82f31beee5
File diff suppressed because one or more lines are too long
@ -85,7 +85,7 @@ def get_key_models(
|
||||
|
||||
|
||||
def get_team_models(
|
||||
user_api_key_dict: UserAPIKeyAuth,
|
||||
team_models: List[str],
|
||||
proxy_model_list: List[str],
|
||||
model_access_groups: Dict[str, List[str]],
|
||||
) -> List[str]:
|
||||
@ -96,10 +96,10 @@ def get_team_models(
|
||||
- If model_access_groups is provided, only return models that are in the access groups
|
||||
"""
|
||||
all_models = []
|
||||
if len(user_api_key_dict.team_models) > 0:
|
||||
all_models = user_api_key_dict.team_models
|
||||
if len(team_models) > 0:
|
||||
all_models = team_models
|
||||
if SpecialModelNames.all_team_models.value in all_models:
|
||||
all_models = user_api_key_dict.team_models
|
||||
all_models = team_models
|
||||
if SpecialModelNames.all_proxy_models.value in all_models:
|
||||
all_models = proxy_model_list
|
||||
|
||||
|
||||
@ -1279,7 +1279,7 @@ async def team_info(
|
||||
--header 'Authorization: Bearer your_api_key_here'
|
||||
```
|
||||
"""
|
||||
from litellm.proxy.proxy_server import llm_router, prisma_client
|
||||
from litellm.proxy.proxy_server import prisma_client
|
||||
|
||||
try:
|
||||
if prisma_client is None:
|
||||
@ -1352,9 +1352,9 @@ async def team_info(
|
||||
else:
|
||||
_team_info = LiteLLM_TeamTable()
|
||||
|
||||
## UNFURL 'all-proxy-models' into the team_info.models list ##
|
||||
if llm_router is not None:
|
||||
_team_info = _unfurl_all_proxy_models(_team_info, llm_router)
|
||||
# ## UNFURL 'all-proxy-models' into the team_info.models list ##
|
||||
# if llm_router is not None:
|
||||
# _team_info = _unfurl_all_proxy_models(_team_info, llm_router)
|
||||
response_object = TeamInfoResponseObject(
|
||||
team_id=team_id,
|
||||
team_info=_team_info,
|
||||
@ -1556,7 +1556,7 @@ async def list_team(
|
||||
- user_id: str - Optional. If passed will only return teams that the user_id is a member of.
|
||||
- organization_id: str - Optional. If passed will only return teams that belong to the organization_id. Pass 'default_organization' to get all teams without organization_id.
|
||||
"""
|
||||
from litellm.proxy.proxy_server import llm_router, prisma_client
|
||||
from litellm.proxy.proxy_server import prisma_client
|
||||
|
||||
if not allowed_route_check_inside_route(
|
||||
user_api_key_dict=user_api_key_dict, requested_user_id=user_id
|
||||
@ -1615,11 +1615,6 @@ async def list_team(
|
||||
)
|
||||
|
||||
try:
|
||||
# unfurl all-proxy-models
|
||||
if llm_router is not None:
|
||||
team = _unfurl_all_proxy_models(
|
||||
LiteLLM_TeamTable(**team.model_dump()), llm_router
|
||||
)
|
||||
returned_responses.append(
|
||||
TeamListResponseObject(
|
||||
**team.model_dump(),
|
||||
|
||||
@ -122,7 +122,7 @@ from litellm.proxy.analytics_endpoints.analytics_endpoints import (
|
||||
router as analytics_router,
|
||||
)
|
||||
from litellm.proxy.anthropic_endpoints.endpoints import router as anthropic_router
|
||||
from litellm.proxy.auth.auth_checks import log_db_metrics
|
||||
from litellm.proxy.auth.auth_checks import get_team_object, log_db_metrics
|
||||
from litellm.proxy.auth.auth_utils import check_response_size_is_safe
|
||||
from litellm.proxy.auth.handle_jwt import JWTHandler
|
||||
from litellm.proxy.auth.litellm_license import LicenseCheck
|
||||
@ -213,7 +213,10 @@ from litellm.proxy.management_endpoints.team_callback_endpoints import (
|
||||
router as team_callback_router,
|
||||
)
|
||||
from litellm.proxy.management_endpoints.team_endpoints import router as team_router
|
||||
from litellm.proxy.management_endpoints.team_endpoints import update_team
|
||||
from litellm.proxy.management_endpoints.team_endpoints import (
|
||||
update_team,
|
||||
validate_membership,
|
||||
)
|
||||
from litellm.proxy.management_endpoints.ui_sso import (
|
||||
get_disabled_non_admin_personal_key_creation,
|
||||
)
|
||||
@ -3380,13 +3383,14 @@ class ProxyStartupEvent:
|
||||
async def model_list(
|
||||
user_api_key_dict: UserAPIKeyAuth = Depends(user_api_key_auth),
|
||||
return_wildcard_routes: Optional[bool] = False,
|
||||
team_id: Optional[str] = None,
|
||||
):
|
||||
"""
|
||||
Use `/model/info` - to get detailed model information, example - pricing, mode, etc.
|
||||
|
||||
This is just for compatibility with openai projects like aider.
|
||||
"""
|
||||
global llm_model_list, general_settings, llm_router
|
||||
global llm_model_list, general_settings, llm_router, prisma_client, user_api_key_cache, proxy_logging_obj
|
||||
all_models = []
|
||||
model_access_groups: Dict[str, List[str]] = defaultdict(list)
|
||||
## CHECK IF MODEL RESTRICTIONS ARE SET AT KEY/TEAM LEVEL ##
|
||||
@ -3401,19 +3405,33 @@ async def model_list(
|
||||
model_access_groups=model_access_groups,
|
||||
)
|
||||
|
||||
team_models: List[str] = user_api_key_dict.team_models
|
||||
|
||||
if team_id:
|
||||
team_object = await get_team_object(
|
||||
team_id=team_id,
|
||||
prisma_client=prisma_client,
|
||||
user_api_key_cache=user_api_key_cache,
|
||||
proxy_logging_obj=proxy_logging_obj,
|
||||
)
|
||||
validate_membership(user_api_key_dict=user_api_key_dict, team_table=team_object)
|
||||
team_models = team_object.models
|
||||
|
||||
team_models = get_team_models(
|
||||
user_api_key_dict=user_api_key_dict,
|
||||
team_models=team_models,
|
||||
proxy_model_list=proxy_model_list,
|
||||
model_access_groups=model_access_groups,
|
||||
)
|
||||
|
||||
all_models = get_complete_model_list(
|
||||
key_models=key_models,
|
||||
key_models=key_models if not team_models else [],
|
||||
team_models=team_models,
|
||||
proxy_model_list=proxy_model_list,
|
||||
user_model=user_model,
|
||||
infer_model_from_keys=general_settings.get("infer_model_from_keys", False),
|
||||
return_wildcard_routes=return_wildcard_routes,
|
||||
)
|
||||
|
||||
return dict(
|
||||
data=[
|
||||
{
|
||||
@ -6117,7 +6135,7 @@ async def model_info_v1( # noqa: PLR0915
|
||||
model_access_groups=model_access_groups,
|
||||
)
|
||||
team_models = get_team_models(
|
||||
user_api_key_dict=user_api_key_dict,
|
||||
team_models=user_api_key_dict.team_models,
|
||||
proxy_model_list=proxy_model_list,
|
||||
model_access_groups=model_access_groups,
|
||||
)
|
||||
@ -6344,7 +6362,7 @@ async def model_group_info(
|
||||
model_access_groups=model_access_groups,
|
||||
)
|
||||
team_models = get_team_models(
|
||||
user_api_key_dict=user_api_key_dict,
|
||||
team_models=user_api_key_dict.team_models,
|
||||
proxy_model_list=proxy_model_list,
|
||||
model_access_groups=model_access_groups,
|
||||
)
|
||||
|
||||
@ -939,8 +939,9 @@ def test_get_team_models():
|
||||
model_access_groups["default"].extend(["gpt-4o-mini"])
|
||||
model_access_groups["team2"].extend(["gpt-3.5-turbo"])
|
||||
|
||||
team_models = user_api_key_dict.team_models
|
||||
result = get_team_models(
|
||||
user_api_key_dict=user_api_key_dict,
|
||||
team_models=team_models,
|
||||
proxy_model_list=proxy_model_list,
|
||||
model_access_groups=model_access_groups,
|
||||
)
|
||||
|
||||
@ -91,28 +91,31 @@ const getPredefinedTags = (data: any[] | null) => {
|
||||
return uniqueTags;
|
||||
}
|
||||
|
||||
export const getTeamModels = (team: Team | null, allAvailableModels: string[]): string[] => {
|
||||
let tempModelsToPick = [];
|
||||
|
||||
if (team) {
|
||||
if (team.models.length > 0) {
|
||||
if (team.models.includes("all-proxy-models")) {
|
||||
// if the team has all-proxy-models show all available models
|
||||
tempModelsToPick = allAvailableModels;
|
||||
} else {
|
||||
// show team models
|
||||
tempModelsToPick = team.models;
|
||||
}
|
||||
} else {
|
||||
// show all available models if the team has no models set
|
||||
tempModelsToPick = allAvailableModels;
|
||||
export const fetchTeamModels = async (userID: string, userRole: string, accessToken: string, teamID: string): Promise<string[]> => {
|
||||
try {
|
||||
if (userID === null || userRole === null) {
|
||||
return [];
|
||||
}
|
||||
} else {
|
||||
// no team set, show all available models
|
||||
tempModelsToPick = allAvailableModels;
|
||||
}
|
||||
|
||||
return unfurlWildcardModelsInList(tempModelsToPick, allAvailableModels);
|
||||
if (accessToken !== null) {
|
||||
const model_available = await modelAvailableCall(
|
||||
accessToken,
|
||||
userID,
|
||||
userRole,
|
||||
true,
|
||||
teamID
|
||||
);
|
||||
let available_model_names = model_available["data"].map(
|
||||
(element: { id: string }) => element.id
|
||||
);
|
||||
console.log("available_model_names:", available_model_names);
|
||||
return available_model_names;
|
||||
}
|
||||
return [];
|
||||
} catch (error) {
|
||||
console.error("Error fetching user models:", error);
|
||||
return [];
|
||||
}
|
||||
};
|
||||
|
||||
export const fetchUserModels = async (userID: string, userRole: string, accessToken: string, setUserModels: (models: string[]) => void) => {
|
||||
@ -182,6 +185,7 @@ const CreateKey: React.FC<CreateKeyProps> = ({
|
||||
}
|
||||
}, [accessToken, userID, userRole]);
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
const fetchGuardrails = async () => {
|
||||
try {
|
||||
@ -277,10 +281,14 @@ const CreateKey: React.FC<CreateKeyProps> = ({
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const models = getTeamModels(selectedCreateKeyTeam, userModels);
|
||||
setModelsToPick(models);
|
||||
if (userID && userRole && accessToken && selectedCreateKeyTeam) {
|
||||
fetchTeamModels(userID, userRole, accessToken, selectedCreateKeyTeam.team_id).then((models) => {
|
||||
let allModels = Array.from(new Set([...selectedCreateKeyTeam.models, ...models]));
|
||||
setModelsToPick(allModels);
|
||||
});
|
||||
}
|
||||
form.setFieldValue('models', []);
|
||||
}, [selectedCreateKeyTeam, userModels]);
|
||||
}, [selectedCreateKeyTeam]);
|
||||
|
||||
// Add a callback function to handle user creation
|
||||
const handleUserCreated = (userId: string) => {
|
||||
|
||||
@ -2,7 +2,7 @@ import React, { useState, useEffect } from "react";
|
||||
import { Form, Input, InputNumber, Select } from "antd";
|
||||
import { Button, TextInput } from "@tremor/react";
|
||||
import { KeyResponse } from "./key_team_helpers/key_list";
|
||||
import { getTeamModels } from "../components/create_key_button";
|
||||
import { fetchTeamModels } from "../components/create_key_button";
|
||||
import { modelAvailableCall } from "./networking";
|
||||
|
||||
interface KeyEditViewProps {
|
||||
@ -45,31 +45,36 @@ export function KeyEditView({
|
||||
const [form] = Form.useForm();
|
||||
const [userModels, setUserModels] = useState<string[]>([]);
|
||||
const team = teams?.find(team => team.team_id === keyData.team_id);
|
||||
const availableModels = getTeamModels(team, userModels);
|
||||
|
||||
const [availableModels, setAvailableModels] = useState<string[]>([]);
|
||||
|
||||
useEffect(() => {
|
||||
const fetchUserModels = async () => {
|
||||
const fetchModels = async () => {
|
||||
if (!userID || !userRole || !accessToken) return;
|
||||
|
||||
try {
|
||||
if (accessToken && userID && userRole) {
|
||||
if (keyData.team_id === null) {
|
||||
// Fetch user models if no team
|
||||
const model_available = await modelAvailableCall(
|
||||
accessToken,
|
||||
userID,
|
||||
userID,
|
||||
userRole
|
||||
);
|
||||
let available_model_names = model_available["data"].map(
|
||||
const available_model_names = model_available["data"].map(
|
||||
(element: { id: string }) => element.id
|
||||
);
|
||||
console.log("available_model_names:", available_model_names);
|
||||
setUserModels(available_model_names);
|
||||
setAvailableModels(available_model_names);
|
||||
} else if (team?.team_id) {
|
||||
// Fetch team models if team exists
|
||||
const models = await fetchTeamModels(userID, userRole, accessToken, team.team_id);
|
||||
setAvailableModels(Array.from(new Set([...team.models, ...models])));
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error fetching user models:", error);
|
||||
console.error("Error fetching models:", error);
|
||||
}
|
||||
};
|
||||
|
||||
fetchUserModels();
|
||||
}, []);
|
||||
fetchModels();
|
||||
}, [userID, userRole, accessToken, team, keyData.team_id]);
|
||||
|
||||
// Convert API budget duration to form format
|
||||
const getBudgetDuration = (duration: string | null) => {
|
||||
|
||||
@ -1284,6 +1284,7 @@ export const modelInfoV1Call = async (accessToken: String, modelId: String) => {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
export const modelHubCall = async (accessToken: String) => {
|
||||
/**
|
||||
* Get all models on proxy
|
||||
@ -1581,7 +1582,8 @@ export const modelAvailableCall = async (
|
||||
accessToken: String,
|
||||
userID: String,
|
||||
userRole: String,
|
||||
return_wildcard_routes: boolean = false
|
||||
return_wildcard_routes: boolean = false,
|
||||
teamID: String | null = null
|
||||
) => {
|
||||
/**
|
||||
* Get all the models user has access to
|
||||
@ -1589,8 +1591,15 @@ export const modelAvailableCall = async (
|
||||
console.log("in /models calls, globalLitellmHeaderName", globalLitellmHeaderName)
|
||||
try {
|
||||
let url = proxyBaseUrl ? `${proxyBaseUrl}/models` : `/models`;
|
||||
const params = new URLSearchParams();
|
||||
if (return_wildcard_routes === true) {
|
||||
url += `?return_wildcard_routes=True`;
|
||||
params.append('return_wildcard_routes', 'True');
|
||||
}
|
||||
if (teamID) {
|
||||
params.append('team_id', teamID.toString());
|
||||
}
|
||||
if (params.toString()) {
|
||||
url += `?${params.toString()}`;
|
||||
}
|
||||
|
||||
//message.info("Requesting model data");
|
||||
|
||||
Loading…
Reference in New Issue
Block a user