mirror of
https://github.com/BerriAI/litellm.git
synced 2025-04-27 03:34:10 +00:00
build(ui/general_settings.tsx): support updating global max parallel requests on the ui
This commit is contained in:
parent
ed9fe2e122
commit
92dbe5f7fe
4 changed files with 491 additions and 110 deletions
|
@ -714,6 +714,20 @@ class DynamoDBArgs(LiteLLMBase):
|
|||
class ConfigFieldUpdate(LiteLLMBase):
|
||||
field_name: str
|
||||
field_value: Any
|
||||
config_type: Literal["general_settings"]
|
||||
|
||||
|
||||
class ConfigFieldDelete(LiteLLMBase):
|
||||
config_type: Literal["general_settings"]
|
||||
field_name: str
|
||||
|
||||
|
||||
class ConfigList(LiteLLMBase):
|
||||
field_name: str
|
||||
field_type: str
|
||||
field_description: str
|
||||
field_value: Any
|
||||
stored_in_db: Optional[bool]
|
||||
|
||||
|
||||
class ConfigGeneralSettings(LiteLLMBase):
|
||||
|
@ -763,7 +777,11 @@ class ConfigGeneralSettings(LiteLLMBase):
|
|||
description="override user_api_key_auth with your own auth script - https://docs.litellm.ai/docs/proxy/virtual_keys#custom-auth",
|
||||
)
|
||||
max_parallel_requests: Optional[int] = Field(
|
||||
None, description="maximum parallel requests for each api key"
|
||||
None,
|
||||
description="maximum parallel requests for each api key",
|
||||
)
|
||||
global_max_parallel_requests: Optional[int] = Field(
|
||||
None, description="global max parallel requests to allow for a proxy instance."
|
||||
)
|
||||
infer_model_from_keys: Optional[bool] = Field(
|
||||
None,
|
||||
|
|
|
@ -567,9 +567,9 @@ async def user_api_key_auth(
|
|||
#### ELSE ####
|
||||
if master_key is None:
|
||||
if isinstance(api_key, str):
|
||||
return UserAPIKeyAuth(api_key=api_key)
|
||||
return UserAPIKeyAuth(api_key=api_key, user_role="proxy_admin")
|
||||
else:
|
||||
return UserAPIKeyAuth()
|
||||
return UserAPIKeyAuth(user_role="proxy_admin")
|
||||
elif api_key is None: # only require api key if master key is set
|
||||
raise Exception("No api key passed in.")
|
||||
elif api_key == "":
|
||||
|
@ -660,6 +660,7 @@ async def user_api_key_auth(
|
|||
verbose_proxy_logger.debug("Token from db: %s", valid_token)
|
||||
elif valid_token is not None:
|
||||
verbose_proxy_logger.debug("API Key Cache Hit!")
|
||||
|
||||
user_id_information = None
|
||||
if valid_token:
|
||||
# Got Valid Token from Cache, DB
|
||||
|
@ -1188,6 +1189,17 @@ async def user_api_key_auth(
|
|||
# No token was found when looking up in the DB
|
||||
raise Exception("Invalid token passed")
|
||||
if valid_token_dict is not None:
|
||||
if user_id_information is not None and _is_user_proxy_admin(
|
||||
user_id_information
|
||||
):
|
||||
return UserAPIKeyAuth(
|
||||
api_key=api_key, user_role="proxy_admin", **valid_token_dict
|
||||
)
|
||||
elif _has_user_setup_sso() and route in LiteLLMRoutes.sso_only_routes.value:
|
||||
return UserAPIKeyAuth(
|
||||
api_key=api_key, user_role="app_owner", **valid_token_dict
|
||||
)
|
||||
else:
|
||||
return UserAPIKeyAuth(api_key=api_key, **valid_token_dict)
|
||||
else:
|
||||
raise Exception()
|
||||
|
@ -2796,7 +2808,19 @@ class ProxyConfig:
|
|||
"Error setting env variable: %s - %s", k, str(e)
|
||||
)
|
||||
|
||||
# general_settings
|
||||
# router settings
|
||||
if llm_router is not None and prisma_client is not None:
|
||||
db_router_settings = await prisma_client.db.litellm_config.find_first(
|
||||
where={"param_name": "router_settings"}
|
||||
)
|
||||
if (
|
||||
db_router_settings is not None
|
||||
and db_router_settings.param_value is not None
|
||||
):
|
||||
_router_settings = db_router_settings.param_value
|
||||
llm_router.update_settings(**_router_settings)
|
||||
|
||||
## ALERTING ## [TODO] move this to the _update_general_settings() block
|
||||
_general_settings = config_data.get("general_settings", {})
|
||||
if "alerting" in _general_settings:
|
||||
general_settings["alerting"] = _general_settings["alerting"]
|
||||
|
@ -2820,17 +2844,23 @@ class ProxyConfig:
|
|||
alert_to_webhook_url=general_settings["alert_to_webhook_url"]
|
||||
)
|
||||
|
||||
# router settings
|
||||
if llm_router is not None and prisma_client is not None:
|
||||
db_router_settings = await prisma_client.db.litellm_config.find_first(
|
||||
where={"param_name": "router_settings"}
|
||||
)
|
||||
if (
|
||||
db_router_settings is not None
|
||||
and db_router_settings.param_value is not None
|
||||
):
|
||||
_router_settings = db_router_settings.param_value
|
||||
llm_router.update_settings(**_router_settings)
|
||||
async def _update_general_settings(self, db_general_settings: Optional[Json]):
|
||||
"""
|
||||
Pull from DB, read general settings value
|
||||
"""
|
||||
if db_general_settings is None:
|
||||
return
|
||||
_general_settings = dict(db_general_settings)
|
||||
## MAX PARALLEL REQUESTS ##
|
||||
if "max_parallel_requests" in _general_settings:
|
||||
general_settings["max_parallel_requests"] = _general_settings[
|
||||
"max_parallel_requests"
|
||||
]
|
||||
|
||||
if "global_max_parallel_requests" in _general_settings:
|
||||
general_settings["global_max_parallel_requests"] = _general_settings[
|
||||
"global_max_parallel_requests"
|
||||
]
|
||||
|
||||
async def add_deployment(
|
||||
self,
|
||||
|
@ -2838,7 +2868,7 @@ class ProxyConfig:
|
|||
proxy_logging_obj: ProxyLogging,
|
||||
):
|
||||
"""
|
||||
- Check db for new models (last 10 most recently updated)
|
||||
- Check db for new models
|
||||
- Check if model id's in router already
|
||||
- If not, add to router
|
||||
"""
|
||||
|
@ -2851,9 +2881,21 @@ class ProxyConfig:
|
|||
)
|
||||
verbose_proxy_logger.debug(f"llm_router: {llm_router}")
|
||||
new_models = await prisma_client.db.litellm_proxymodeltable.find_many()
|
||||
# update llm router
|
||||
await self._update_llm_router(
|
||||
new_models=new_models, proxy_logging_obj=proxy_logging_obj
|
||||
)
|
||||
|
||||
db_general_settings = await prisma_client.db.litellm_config.find_first(
|
||||
where={"param_name": "general_settings"}
|
||||
)
|
||||
|
||||
# update general settings
|
||||
if db_general_settings is not None:
|
||||
await self._update_general_settings(
|
||||
db_general_settings=db_general_settings.param_value,
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
verbose_proxy_logger.error(
|
||||
"{}\nTraceback:{}".format(str(e), traceback.format_exc())
|
||||
|
@ -3053,27 +3095,6 @@ async def generate_key_helper_fn(
|
|||
data=key_data, table_name="key"
|
||||
)
|
||||
key_data["token_id"] = getattr(create_key_response, "token", None)
|
||||
elif custom_db_client is not None:
|
||||
if table_name is None or table_name == "user":
|
||||
## CREATE USER (If necessary)
|
||||
verbose_proxy_logger.debug(
|
||||
"CustomDBClient: Creating User= %s", user_data
|
||||
)
|
||||
user_row = await custom_db_client.insert_data(
|
||||
value=user_data, table_name="user"
|
||||
)
|
||||
if user_row is None:
|
||||
# GET USER ROW
|
||||
user_row = await custom_db_client.get_data(
|
||||
key=user_id, table_name="user" # type: ignore
|
||||
)
|
||||
|
||||
## use default user model list if no key-specific model list provided
|
||||
if len(user_row.models) > 0 and len(key_data["models"]) == 0: # type: ignore
|
||||
key_data["models"] = user_row.models
|
||||
## CREATE KEY
|
||||
verbose_proxy_logger.debug("CustomDBClient: Creating Key= %s", key_data)
|
||||
await custom_db_client.insert_data(value=key_data, table_name="key")
|
||||
except Exception as e:
|
||||
traceback.print_exc()
|
||||
if isinstance(e, HTTPException):
|
||||
|
@ -9673,13 +9694,88 @@ async def get_config_general_settings(
|
|||
)
|
||||
|
||||
|
||||
@router.get(
|
||||
"/config/list",
|
||||
tags=["config.yaml"],
|
||||
dependencies=[Depends(user_api_key_auth)],
|
||||
)
|
||||
async def get_config_list(
|
||||
config_type: Literal["general_settings"],
|
||||
user_api_key_dict: UserAPIKeyAuth = Depends(user_api_key_auth),
|
||||
) -> List[ConfigList]:
|
||||
"""
|
||||
List the available fields + current values for a given type of setting (currently just 'general_settings'user_api_key_dict: UserAPIKeyAuth = Depends(user_api_key_auth),)
|
||||
"""
|
||||
global prisma_client, general_settings
|
||||
|
||||
## VALIDATION ##
|
||||
"""
|
||||
- Check if prisma_client is None
|
||||
- Check if user allowed to call this endpoint (admin-only)
|
||||
- Check if param in general settings
|
||||
"""
|
||||
if prisma_client is None:
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
detail={"error": CommonProxyErrors.db_not_connected_error.value},
|
||||
)
|
||||
|
||||
if user_api_key_dict.user_role != "proxy_admin":
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
detail={
|
||||
"error": "{}, your role={}".format(
|
||||
CommonProxyErrors.not_allowed_access.value,
|
||||
user_api_key_dict.user_role,
|
||||
)
|
||||
},
|
||||
)
|
||||
|
||||
## get general settings from db
|
||||
db_general_settings = await prisma_client.db.litellm_config.find_first(
|
||||
where={"param_name": "general_settings"}
|
||||
)
|
||||
|
||||
if db_general_settings is not None and db_general_settings.param_value is not None:
|
||||
db_general_settings_dict = dict(db_general_settings.param_value)
|
||||
else:
|
||||
db_general_settings_dict = {}
|
||||
|
||||
allowed_args = {
|
||||
"max_parallel_requests": {"type": "Integer"},
|
||||
"global_max_parallel_requests": {"type": "Integer"},
|
||||
}
|
||||
|
||||
return_val = []
|
||||
|
||||
for field_name, field_info in ConfigGeneralSettings.model_fields.items():
|
||||
if field_name in allowed_args:
|
||||
|
||||
_stored_in_db = None
|
||||
if field_name in db_general_settings_dict:
|
||||
_stored_in_db = True
|
||||
elif field_name in general_settings:
|
||||
_stored_in_db = False
|
||||
|
||||
_response_obj = ConfigList(
|
||||
field_name=field_name,
|
||||
field_type=allowed_args[field_name]["type"],
|
||||
field_description=field_info.description or "",
|
||||
field_value=general_settings.get(field_name, None),
|
||||
stored_in_db=_stored_in_db,
|
||||
)
|
||||
return_val.append(_response_obj)
|
||||
|
||||
return return_val
|
||||
|
||||
|
||||
@router.post(
|
||||
"/config/field/delete",
|
||||
tags=["config.yaml"],
|
||||
dependencies=[Depends(user_api_key_auth)],
|
||||
)
|
||||
async def delete_config_general_settings(
|
||||
field_name: str,
|
||||
data: ConfigFieldDelete,
|
||||
user_api_key_dict: UserAPIKeyAuth = Depends(user_api_key_auth),
|
||||
):
|
||||
"""
|
||||
|
@ -9701,13 +9797,18 @@ async def delete_config_general_settings(
|
|||
if user_api_key_dict.user_role != "proxy_admin":
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
detail={"error": CommonProxyErrors.not_allowed_access.value},
|
||||
detail={
|
||||
"error": "{}, your role={}".format(
|
||||
CommonProxyErrors.not_allowed_access.value,
|
||||
user_api_key_dict.user_role,
|
||||
)
|
||||
},
|
||||
)
|
||||
|
||||
if field_name not in ConfigGeneralSettings.model_fields:
|
||||
if data.field_name not in ConfigGeneralSettings.model_fields:
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
detail={"error": "Invalid field={} passed in.".format(field_name)},
|
||||
detail={"error": "Invalid field={} passed in.".format(data.field_name)},
|
||||
)
|
||||
|
||||
## get general settings from db
|
||||
|
@ -9719,14 +9820,14 @@ async def delete_config_general_settings(
|
|||
if db_general_settings is None or db_general_settings.param_value is None:
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
detail={"error": "Field name={} not in config".format(field_name)},
|
||||
detail={"error": "Field name={} not in config".format(data.field_name)},
|
||||
)
|
||||
else:
|
||||
general_settings = dict(db_general_settings.param_value)
|
||||
|
||||
## update db
|
||||
|
||||
general_settings.pop(field_name)
|
||||
general_settings.pop(data.field_name, None)
|
||||
|
||||
response = await prisma_client.db.litellm_config.upsert(
|
||||
where={"param_name": "general_settings"},
|
||||
|
|
|
@ -34,9 +34,20 @@ import {
|
|||
import {
|
||||
getCallbacksCall,
|
||||
setCallbacksCall,
|
||||
getGeneralSettingsCall,
|
||||
serviceHealthCheck,
|
||||
updateConfigFieldSetting,
|
||||
deleteConfigFieldSetting,
|
||||
} from "./networking";
|
||||
import { Modal, Form, Input, Select, Button as Button2, message } from "antd";
|
||||
import {
|
||||
Modal,
|
||||
Form,
|
||||
Input,
|
||||
Select,
|
||||
Button as Button2,
|
||||
message,
|
||||
InputNumber,
|
||||
} from "antd";
|
||||
import {
|
||||
InformationCircleIcon,
|
||||
PencilAltIcon,
|
||||
|
@ -44,6 +55,9 @@ import {
|
|||
StatusOnlineIcon,
|
||||
TrashIcon,
|
||||
RefreshIcon,
|
||||
CheckCircleIcon,
|
||||
XCircleIcon,
|
||||
QuestionMarkCircleIcon,
|
||||
} from "@heroicons/react/outline";
|
||||
import StaticGenerationSearchParamsBailoutProvider from "next/dist/client/components/static-generation-searchparams-bailout-provider";
|
||||
import AddFallbacks from "./add_fallbacks";
|
||||
|
@ -123,6 +137,14 @@ interface routingStrategyArgs {
|
|||
lowest_latency_buffer?: number;
|
||||
}
|
||||
|
||||
interface generalSettingsItem {
|
||||
field_name: string;
|
||||
field_type: string;
|
||||
field_value: any;
|
||||
field_description: string;
|
||||
stored_in_db: boolean | null;
|
||||
}
|
||||
|
||||
const defaultLowestLatencyArgs: routingStrategyArgs = {
|
||||
ttl: 3600,
|
||||
lowest_latency_buffer: 0,
|
||||
|
@ -194,6 +216,12 @@ const GeneralSettings: React.FC<GeneralSettingsPageProps> = ({
|
|||
const [routerSettings, setRouterSettings] = useState<{ [key: string]: any }>(
|
||||
{}
|
||||
);
|
||||
const [generalSettingsDict, setGeneralSettingsDict] = useState<{
|
||||
[key: string]: any;
|
||||
}>({});
|
||||
const [generalSettings, setGeneralSettings] = useState<generalSettingsItem[]>(
|
||||
[]
|
||||
);
|
||||
const [isModalVisible, setIsModalVisible] = useState(false);
|
||||
const [form] = Form.useForm();
|
||||
const [selectedCallback, setSelectedCallback] = useState<string | null>(null);
|
||||
|
@ -225,6 +253,10 @@ const GeneralSettings: React.FC<GeneralSettingsPageProps> = ({
|
|||
let router_settings = data.router_settings;
|
||||
setRouterSettings(router_settings);
|
||||
});
|
||||
getGeneralSettingsCall(accessToken).then((data) => {
|
||||
let general_settings = data;
|
||||
setGeneralSettings(general_settings);
|
||||
});
|
||||
}, [accessToken, userRole, userID]);
|
||||
|
||||
const handleAddCallback = () => {
|
||||
|
@ -271,6 +303,61 @@ const GeneralSettings: React.FC<GeneralSettingsPageProps> = ({
|
|||
}
|
||||
};
|
||||
|
||||
const handleInputChange = (fieldName: string, newValue: any) => {
|
||||
// Update the value in the state
|
||||
const updatedSettings = generalSettings.map((setting) =>
|
||||
setting.field_name === fieldName
|
||||
? { ...setting, field_value: newValue }
|
||||
: setting
|
||||
);
|
||||
setGeneralSettings(updatedSettings);
|
||||
};
|
||||
|
||||
const handleUpdateField = (fieldName: string, idx: number) => {
|
||||
if (!accessToken) {
|
||||
return;
|
||||
}
|
||||
|
||||
let fieldValue = generalSettings[idx].field_value;
|
||||
|
||||
if (fieldValue == null || fieldValue == undefined) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
updateConfigFieldSetting(accessToken, fieldName, fieldValue);
|
||||
// update value in state
|
||||
|
||||
const updatedSettings = generalSettings.map((setting) =>
|
||||
setting.field_name === fieldName
|
||||
? { ...setting, stored_in_db: true }
|
||||
: setting
|
||||
);
|
||||
setGeneralSettings(updatedSettings);
|
||||
} catch (error) {
|
||||
// do something
|
||||
}
|
||||
};
|
||||
|
||||
const handleResetField = (fieldName: string, idx: number) => {
|
||||
if (!accessToken) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
deleteConfigFieldSetting(accessToken, fieldName);
|
||||
// update value in state
|
||||
|
||||
const updatedSettings = generalSettings.map((setting) =>
|
||||
setting.field_name === fieldName
|
||||
? { ...setting, stored_in_db: null, field_value: null }
|
||||
: setting
|
||||
);
|
||||
setGeneralSettings(updatedSettings);
|
||||
} catch (error) {
|
||||
// do something
|
||||
}
|
||||
};
|
||||
|
||||
const handleSaveChanges = (router_settings: any) => {
|
||||
if (!accessToken) {
|
||||
return;
|
||||
|
@ -493,7 +580,81 @@ const GeneralSettings: React.FC<GeneralSettingsPageProps> = ({
|
|||
/>
|
||||
</TabPanel>
|
||||
<TabPanel>
|
||||
<h1>General settings for litellm proxy</h1>
|
||||
<Card>
|
||||
<Table>
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<TableHeaderCell>Setting</TableHeaderCell>
|
||||
<TableHeaderCell>Value</TableHeaderCell>
|
||||
<TableHeaderCell>Status</TableHeaderCell>
|
||||
<TableHeaderCell>Action</TableHeaderCell>
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
{generalSettings.map((value, index) => (
|
||||
<TableRow key={index}>
|
||||
<TableCell>
|
||||
<Text>{value.field_name}</Text>
|
||||
<p
|
||||
style={{
|
||||
fontSize: "0.65rem",
|
||||
color: "#808080",
|
||||
fontStyle: "italic",
|
||||
}}
|
||||
className="mt-1"
|
||||
>
|
||||
{value.field_description}
|
||||
</p>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
{value.field_type == "Integer" ? (
|
||||
<InputNumber
|
||||
step={1}
|
||||
value={value.field_value}
|
||||
onChange={(newValue) =>
|
||||
handleInputChange(value.field_name, newValue)
|
||||
} // Handle value change
|
||||
/>
|
||||
) : null}
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
{value.stored_in_db == true ? (
|
||||
<Badge icon={CheckCircleIcon} className="text-white">
|
||||
In DB
|
||||
</Badge>
|
||||
) : value.stored_in_db == false ? (
|
||||
<Badge className="text-gray bg-white outline">
|
||||
In Config
|
||||
</Badge>
|
||||
) : (
|
||||
<Badge className="text-gray bg-white outline">
|
||||
Not Set
|
||||
</Badge>
|
||||
)}
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Button
|
||||
onClick={() =>
|
||||
handleUpdateField(value.field_name, index)
|
||||
}
|
||||
>
|
||||
Update
|
||||
</Button>
|
||||
<Icon
|
||||
icon={TrashIcon}
|
||||
color="red"
|
||||
onClick={() =>
|
||||
handleResetField(value.field_name, index)
|
||||
}
|
||||
>
|
||||
Reset
|
||||
</Icon>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</Card>
|
||||
</TabPanel>
|
||||
</TabPanels>
|
||||
</TabGroup>
|
||||
|
|
|
@ -14,15 +14,17 @@ export interface Model {
|
|||
|
||||
export const modelCostMap = async () => {
|
||||
try {
|
||||
const response = await fetch('https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json');
|
||||
const response = await fetch(
|
||||
"https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json"
|
||||
);
|
||||
const jsonData = await response.json();
|
||||
console.log(`received data: ${jsonData}`)
|
||||
return jsonData
|
||||
console.log(`received data: ${jsonData}`);
|
||||
return jsonData;
|
||||
} catch (error) {
|
||||
console.error("Failed to get model cost map:", error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export const modelCreateCall = async (
|
||||
accessToken: string,
|
||||
|
@ -50,19 +52,21 @@ export const modelCreateCall = async (
|
|||
|
||||
const data = await response.json();
|
||||
console.log("API Response:", data);
|
||||
message.success("Model created successfully. Wait 60s and refresh on 'All Models' page");
|
||||
message.success(
|
||||
"Model created successfully. Wait 60s and refresh on 'All Models' page"
|
||||
);
|
||||
return data;
|
||||
} catch (error) {
|
||||
console.error("Failed to create key:", error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export const modelDeleteCall = async (
|
||||
accessToken: string,
|
||||
model_id: string,
|
||||
model_id: string
|
||||
) => {
|
||||
console.log(`model_id in model delete call: ${model_id}`)
|
||||
console.log(`model_id in model delete call: ${model_id}`);
|
||||
try {
|
||||
const url = proxyBaseUrl ? `${proxyBaseUrl}/model/delete` : `/model/delete`;
|
||||
const response = await fetch(url, {
|
||||
|
@ -72,7 +76,7 @@ export const modelDeleteCall = async (
|
|||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
"id": model_id,
|
||||
id: model_id,
|
||||
}),
|
||||
});
|
||||
|
||||
|
@ -91,7 +95,7 @@ export const modelDeleteCall = async (
|
|||
console.error("Failed to create key:", error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export const keyCreateCall = async (
|
||||
accessToken: string,
|
||||
|
@ -280,8 +284,7 @@ export const teamDeleteCall = async (accessToken: String, teamID: String) => {
|
|||
console.error("Failed to delete key:", error);
|
||||
throw error;
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
export const userInfoCall = async (
|
||||
accessToken: String,
|
||||
|
@ -300,7 +303,7 @@ export const userInfoCall = async (
|
|||
url = `${url}?user_id=${userID}`;
|
||||
}
|
||||
console.log("in userInfoCall viewAll=", viewAll);
|
||||
if (viewAll && page_size && (page != null) && (page != undefined)) {
|
||||
if (viewAll && page_size && page != null && page != undefined) {
|
||||
url = `${url}?view_all=true&page=${page}&page_size=${page_size}`;
|
||||
}
|
||||
//message.info("Requesting user data");
|
||||
|
@ -329,10 +332,9 @@ export const userInfoCall = async (
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
export const teamInfoCall = async (
|
||||
accessToken: String,
|
||||
teamID: String | null,
|
||||
teamID: String | null
|
||||
) => {
|
||||
try {
|
||||
let url = proxyBaseUrl ? `${proxyBaseUrl}/team/info` : `/team/info`;
|
||||
|
@ -364,10 +366,7 @@ export const teamInfoCall = async (
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
export const getTotalSpendCall = async (
|
||||
accessToken: String,
|
||||
) => {
|
||||
export const getTotalSpendCall = async (accessToken: String) => {
|
||||
/**
|
||||
* Get all models on proxy
|
||||
*/
|
||||
|
@ -435,7 +434,6 @@ export const modelInfoCall = async (
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
export const modelMetricsCall = async (
|
||||
accessToken: String,
|
||||
userID: String,
|
||||
|
@ -450,7 +448,7 @@ export const modelMetricsCall = async (
|
|||
try {
|
||||
let url = proxyBaseUrl ? `${proxyBaseUrl}/model/metrics` : `/model/metrics`;
|
||||
if (modelGroup) {
|
||||
url = `${url}?_selected_model_group=${modelGroup}&startTime=${startTime}&endTime=${endTime}`
|
||||
url = `${url}?_selected_model_group=${modelGroup}&startTime=${startTime}&endTime=${endTime}`;
|
||||
}
|
||||
// message.info("Requesting model data");
|
||||
const response = await fetch(url, {
|
||||
|
@ -476,8 +474,6 @@ export const modelMetricsCall = async (
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
export const modelMetricsSlowResponsesCall = async (
|
||||
accessToken: String,
|
||||
userID: String,
|
||||
|
@ -490,9 +486,11 @@ export const modelMetricsSlowResponsesCall = async (
|
|||
* Get all models on proxy
|
||||
*/
|
||||
try {
|
||||
let url = proxyBaseUrl ? `${proxyBaseUrl}/model/metrics/slow_responses` : `/model/metrics/slow_responses`;
|
||||
let url = proxyBaseUrl
|
||||
? `${proxyBaseUrl}/model/metrics/slow_responses`
|
||||
: `/model/metrics/slow_responses`;
|
||||
if (modelGroup) {
|
||||
url = `${url}?_selected_model_group=${modelGroup}&startTime=${startTime}&endTime=${endTime}`
|
||||
url = `${url}?_selected_model_group=${modelGroup}&startTime=${startTime}&endTime=${endTime}`;
|
||||
}
|
||||
|
||||
// message.info("Requesting model data");
|
||||
|
@ -519,7 +517,6 @@ export const modelMetricsSlowResponsesCall = async (
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
export const modelExceptionsCall = async (
|
||||
accessToken: String,
|
||||
userID: String,
|
||||
|
@ -532,10 +529,12 @@ export const modelExceptionsCall = async (
|
|||
* Get all models on proxy
|
||||
*/
|
||||
try {
|
||||
let url = proxyBaseUrl ? `${proxyBaseUrl}/model/metrics/exceptions` : `/model/metrics/exceptions`;
|
||||
let url = proxyBaseUrl
|
||||
? `${proxyBaseUrl}/model/metrics/exceptions`
|
||||
: `/model/metrics/exceptions`;
|
||||
|
||||
if (modelGroup) {
|
||||
url = `${url}?_selected_model_group=${modelGroup}&startTime=${startTime}&endTime=${endTime}`
|
||||
url = `${url}?_selected_model_group=${modelGroup}&startTime=${startTime}&endTime=${endTime}`;
|
||||
}
|
||||
const response = await fetch(url, {
|
||||
method: "GET",
|
||||
|
@ -560,7 +559,6 @@ export const modelExceptionsCall = async (
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
export const modelAvailableCall = async (
|
||||
accessToken: String,
|
||||
userID: String,
|
||||
|
@ -625,7 +623,6 @@ export const keySpendLogsCall = async (accessToken: String, token: String) => {
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
export const teamSpendLogsCall = async (accessToken: String) => {
|
||||
try {
|
||||
const url = proxyBaseUrl
|
||||
|
@ -654,7 +651,6 @@ export const teamSpendLogsCall = async (accessToken: String) => {
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
export const tagsSpendLogsCall = async (
|
||||
accessToken: String,
|
||||
startTime: String | undefined,
|
||||
|
@ -666,7 +662,7 @@ export const tagsSpendLogsCall = async (
|
|||
: `/global/spend/tags`;
|
||||
|
||||
if (startTime && endTime) {
|
||||
url = `${url}?start_date=${startTime}&end_date=${endTime}`
|
||||
url = `${url}?start_date=${startTime}&end_date=${endTime}`;
|
||||
}
|
||||
|
||||
console.log("in tagsSpendLogsCall:", url);
|
||||
|
@ -692,7 +688,6 @@ export const tagsSpendLogsCall = async (
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
export const userSpendLogsCall = async (
|
||||
accessToken: String,
|
||||
token: String,
|
||||
|
@ -806,7 +801,11 @@ export const adminTopEndUsersCall = async (
|
|||
|
||||
let body = "";
|
||||
if (keyToken) {
|
||||
body = JSON.stringify({ api_key: keyToken, startTime: startTime, endTime: endTime });
|
||||
body = JSON.stringify({
|
||||
api_key: keyToken,
|
||||
startTime: startTime,
|
||||
endTime: endTime,
|
||||
});
|
||||
} else {
|
||||
body = JSON.stringify({ startTime: startTime, endTime: endTime });
|
||||
}
|
||||
|
@ -1079,7 +1078,6 @@ export const teamCreateCall = async (
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
export const keyUpdateCall = async (
|
||||
accessToken: string,
|
||||
formValues: Record<string, any> // Assuming formValues is an object
|
||||
|
@ -1347,9 +1345,10 @@ export const slackBudgetAlertsHealthCheck = async (accessToken: String) => {
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
export const serviceHealthCheck= async (accessToken: String, service: String) => {
|
||||
export const serviceHealthCheck = async (
|
||||
accessToken: String,
|
||||
service: String
|
||||
) => {
|
||||
try {
|
||||
let url = proxyBaseUrl
|
||||
? `${proxyBaseUrl}/health/services?service=${service}`
|
||||
|
@ -1373,7 +1372,9 @@ export const serviceHealthCheck= async (accessToken: String, service: String) =>
|
|||
}
|
||||
|
||||
const data = await response.json();
|
||||
message.success(`Test request to ${service} made - check logs/alerts on ${service} to verify`);
|
||||
message.success(
|
||||
`Test request to ${service} made - check logs/alerts on ${service} to verify`
|
||||
);
|
||||
// You can add additional logic here based on the response if needed
|
||||
return data;
|
||||
} catch (error) {
|
||||
|
@ -1382,9 +1383,6 @@ export const serviceHealthCheck= async (accessToken: String, service: String) =>
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
export const getCallbacksCall = async (
|
||||
accessToken: String,
|
||||
userID: String,
|
||||
|
@ -1394,7 +1392,9 @@ export const getCallbacksCall = async (
|
|||
* Get all the models user has access to
|
||||
*/
|
||||
try {
|
||||
let url = proxyBaseUrl ? `${proxyBaseUrl}/get/config/callbacks` : `/get/config/callbacks`;
|
||||
let url = proxyBaseUrl
|
||||
? `${proxyBaseUrl}/get/config/callbacks`
|
||||
: `/get/config/callbacks`;
|
||||
|
||||
//message.info("Requesting model data");
|
||||
const response = await fetch(url, {
|
||||
|
@ -1421,11 +1421,117 @@ export const getCallbacksCall = async (
|
|||
}
|
||||
};
|
||||
|
||||
export const getGeneralSettingsCall = async (accessToken: String) => {
|
||||
try {
|
||||
let url = proxyBaseUrl
|
||||
? `${proxyBaseUrl}/config/list?config_type=general_settings`
|
||||
: `/config/list?config_type=general_settings`;
|
||||
|
||||
//message.info("Requesting model data");
|
||||
const response = await fetch(url, {
|
||||
method: "GET",
|
||||
headers: {
|
||||
Authorization: `Bearer ${accessToken}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const errorData = await response.text();
|
||||
message.error(errorData, 10);
|
||||
throw new Error("Network response was not ok");
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
//message.info("Received model data");
|
||||
return data;
|
||||
// Handle success - you might want to update some state or UI based on the created key
|
||||
} catch (error) {
|
||||
console.error("Failed to get callbacks:", error);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
export const updateConfigFieldSetting = async (
|
||||
accessToken: String,
|
||||
fieldName: string,
|
||||
fieldValue: any
|
||||
) => {
|
||||
try {
|
||||
let url = proxyBaseUrl
|
||||
? `${proxyBaseUrl}/config/field/update`
|
||||
: `/config/field/update`;
|
||||
|
||||
let formData = {
|
||||
field_name: fieldName,
|
||||
field_value: fieldValue,
|
||||
config_type: "general_settings",
|
||||
};
|
||||
//message.info("Requesting model data");
|
||||
const response = await fetch(url, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${accessToken}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify(formData),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const errorData = await response.text();
|
||||
message.error(errorData, 10);
|
||||
throw new Error("Network response was not ok");
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
//message.info("Received model data");
|
||||
message.success("Successfully updated value!");
|
||||
return data;
|
||||
// Handle success - you might want to update some state or UI based on the created key
|
||||
} catch (error) {
|
||||
console.error("Failed to set callbacks:", error);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
export const deleteConfigFieldSetting = async (
|
||||
accessToken: String,
|
||||
fieldName: String
|
||||
) => {
|
||||
try {
|
||||
let url = proxyBaseUrl
|
||||
? `${proxyBaseUrl}/config/field/delete`
|
||||
: `/config/field/delete`;
|
||||
|
||||
let formData = {
|
||||
field_name: fieldName,
|
||||
config_type: "general_settings",
|
||||
};
|
||||
//message.info("Requesting model data");
|
||||
const response = await fetch(url, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${accessToken}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify(formData),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const errorData = await response.text();
|
||||
message.error(errorData, 10);
|
||||
throw new Error("Network response was not ok");
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
message.success("Field reset on proxy");
|
||||
return data;
|
||||
// Handle success - you might want to update some state or UI based on the created key
|
||||
} catch (error) {
|
||||
console.error("Failed to get callbacks:", error);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
export const setCallbacksCall = async (
|
||||
accessToken: String,
|
||||
formValues: Record<string, any>
|
||||
|
@ -1464,9 +1570,7 @@ export const setCallbacksCall = async (
|
|||
}
|
||||
};
|
||||
|
||||
export const healthCheckCall = async (
|
||||
accessToken: String,
|
||||
) => {
|
||||
export const healthCheckCall = async (accessToken: String) => {
|
||||
/**
|
||||
* Get all the models user has access to
|
||||
*/
|
||||
|
@ -1497,6 +1601,3 @@ export const healthCheckCall = async (
|
|||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue