build(ui/general_settings.tsx): support updating global max parallel requests on the ui

This commit is contained in:
Krrish Dholakia 2024-05-15 19:26:57 -07:00
parent 6a357b4275
commit 153ce0d085
4 changed files with 491 additions and 110 deletions

View file

@ -714,6 +714,20 @@ class DynamoDBArgs(LiteLLMBase):
class ConfigFieldUpdate(LiteLLMBase): class ConfigFieldUpdate(LiteLLMBase):
field_name: str field_name: str
field_value: Any 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): 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", 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( 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( infer_model_from_keys: Optional[bool] = Field(
None, None,

View file

@ -567,9 +567,9 @@ async def user_api_key_auth(
#### ELSE #### #### ELSE ####
if master_key is None: if master_key is None:
if isinstance(api_key, str): if isinstance(api_key, str):
return UserAPIKeyAuth(api_key=api_key) return UserAPIKeyAuth(api_key=api_key, user_role="proxy_admin")
else: else:
return UserAPIKeyAuth() return UserAPIKeyAuth(user_role="proxy_admin")
elif api_key is None: # only require api key if master key is set elif api_key is None: # only require api key if master key is set
raise Exception("No api key passed in.") raise Exception("No api key passed in.")
elif api_key == "": elif api_key == "":
@ -660,6 +660,7 @@ async def user_api_key_auth(
verbose_proxy_logger.debug("Token from db: %s", valid_token) verbose_proxy_logger.debug("Token from db: %s", valid_token)
elif valid_token is not None: elif valid_token is not None:
verbose_proxy_logger.debug("API Key Cache Hit!") verbose_proxy_logger.debug("API Key Cache Hit!")
user_id_information = None user_id_information = None
if valid_token: if valid_token:
# Got Valid Token from Cache, DB # Got Valid Token from Cache, DB
@ -1188,7 +1189,18 @@ async def user_api_key_auth(
# No token was found when looking up in the DB # No token was found when looking up in the DB
raise Exception("Invalid token passed") raise Exception("Invalid token passed")
if valid_token_dict is not None: if valid_token_dict is not None:
return UserAPIKeyAuth(api_key=api_key, **valid_token_dict) 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: else:
raise Exception() raise Exception()
except Exception as e: except Exception as e:
@ -2796,7 +2808,19 @@ class ProxyConfig:
"Error setting env variable: %s - %s", k, str(e) "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", {}) _general_settings = config_data.get("general_settings", {})
if "alerting" in _general_settings: if "alerting" in _general_settings:
general_settings["alerting"] = _general_settings["alerting"] general_settings["alerting"] = _general_settings["alerting"]
@ -2820,17 +2844,23 @@ class ProxyConfig:
alert_to_webhook_url=general_settings["alert_to_webhook_url"] alert_to_webhook_url=general_settings["alert_to_webhook_url"]
) )
# router settings async def _update_general_settings(self, db_general_settings: Optional[Json]):
if llm_router is not None and prisma_client is not None: """
db_router_settings = await prisma_client.db.litellm_config.find_first( Pull from DB, read general settings value
where={"param_name": "router_settings"} """
) if db_general_settings is None:
if ( return
db_router_settings is not None _general_settings = dict(db_general_settings)
and db_router_settings.param_value is not None ## MAX PARALLEL REQUESTS ##
): if "max_parallel_requests" in _general_settings:
_router_settings = db_router_settings.param_value general_settings["max_parallel_requests"] = _general_settings[
llm_router.update_settings(**_router_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( async def add_deployment(
self, self,
@ -2838,7 +2868,7 @@ class ProxyConfig:
proxy_logging_obj: ProxyLogging, 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 - Check if model id's in router already
- If not, add to router - If not, add to router
""" """
@ -2851,9 +2881,21 @@ class ProxyConfig:
) )
verbose_proxy_logger.debug(f"llm_router: {llm_router}") verbose_proxy_logger.debug(f"llm_router: {llm_router}")
new_models = await prisma_client.db.litellm_proxymodeltable.find_many() new_models = await prisma_client.db.litellm_proxymodeltable.find_many()
# update llm router
await self._update_llm_router( await self._update_llm_router(
new_models=new_models, proxy_logging_obj=proxy_logging_obj 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: except Exception as e:
verbose_proxy_logger.error( verbose_proxy_logger.error(
"{}\nTraceback:{}".format(str(e), traceback.format_exc()) "{}\nTraceback:{}".format(str(e), traceback.format_exc())
@ -3053,27 +3095,6 @@ async def generate_key_helper_fn(
data=key_data, table_name="key" data=key_data, table_name="key"
) )
key_data["token_id"] = getattr(create_key_response, "token", None) 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: except Exception as e:
traceback.print_exc() traceback.print_exc()
if isinstance(e, HTTPException): 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( @router.post(
"/config/field/delete", "/config/field/delete",
tags=["config.yaml"], tags=["config.yaml"],
dependencies=[Depends(user_api_key_auth)], dependencies=[Depends(user_api_key_auth)],
) )
async def delete_config_general_settings( async def delete_config_general_settings(
field_name: str, data: ConfigFieldDelete,
user_api_key_dict: UserAPIKeyAuth = Depends(user_api_key_auth), 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": if user_api_key_dict.user_role != "proxy_admin":
raise HTTPException( raise HTTPException(
status_code=400, 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( raise HTTPException(
status_code=400, 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 ## 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: if db_general_settings is None or db_general_settings.param_value is None:
raise HTTPException( raise HTTPException(
status_code=400, 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: else:
general_settings = dict(db_general_settings.param_value) general_settings = dict(db_general_settings.param_value)
## update db ## update db
general_settings.pop(field_name) general_settings.pop(data.field_name, None)
response = await prisma_client.db.litellm_config.upsert( response = await prisma_client.db.litellm_config.upsert(
where={"param_name": "general_settings"}, where={"param_name": "general_settings"},

View file

@ -34,9 +34,20 @@ import {
import { import {
getCallbacksCall, getCallbacksCall,
setCallbacksCall, setCallbacksCall,
getGeneralSettingsCall,
serviceHealthCheck, serviceHealthCheck,
updateConfigFieldSetting,
deleteConfigFieldSetting,
} from "./networking"; } 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 { import {
InformationCircleIcon, InformationCircleIcon,
PencilAltIcon, PencilAltIcon,
@ -44,6 +55,9 @@ import {
StatusOnlineIcon, StatusOnlineIcon,
TrashIcon, TrashIcon,
RefreshIcon, RefreshIcon,
CheckCircleIcon,
XCircleIcon,
QuestionMarkCircleIcon,
} from "@heroicons/react/outline"; } from "@heroicons/react/outline";
import StaticGenerationSearchParamsBailoutProvider from "next/dist/client/components/static-generation-searchparams-bailout-provider"; import StaticGenerationSearchParamsBailoutProvider from "next/dist/client/components/static-generation-searchparams-bailout-provider";
import AddFallbacks from "./add_fallbacks"; import AddFallbacks from "./add_fallbacks";
@ -123,6 +137,14 @@ interface routingStrategyArgs {
lowest_latency_buffer?: number; 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 = { const defaultLowestLatencyArgs: routingStrategyArgs = {
ttl: 3600, ttl: 3600,
lowest_latency_buffer: 0, lowest_latency_buffer: 0,
@ -194,6 +216,12 @@ const GeneralSettings: React.FC<GeneralSettingsPageProps> = ({
const [routerSettings, setRouterSettings] = useState<{ [key: string]: any }>( 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 [isModalVisible, setIsModalVisible] = useState(false);
const [form] = Form.useForm(); const [form] = Form.useForm();
const [selectedCallback, setSelectedCallback] = useState<string | null>(null); const [selectedCallback, setSelectedCallback] = useState<string | null>(null);
@ -225,6 +253,10 @@ const GeneralSettings: React.FC<GeneralSettingsPageProps> = ({
let router_settings = data.router_settings; let router_settings = data.router_settings;
setRouterSettings(router_settings); setRouterSettings(router_settings);
}); });
getGeneralSettingsCall(accessToken).then((data) => {
let general_settings = data;
setGeneralSettings(general_settings);
});
}, [accessToken, userRole, userID]); }, [accessToken, userRole, userID]);
const handleAddCallback = () => { 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) => { const handleSaveChanges = (router_settings: any) => {
if (!accessToken) { if (!accessToken) {
return; return;
@ -493,7 +580,81 @@ const GeneralSettings: React.FC<GeneralSettingsPageProps> = ({
/> />
</TabPanel> </TabPanel>
<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> </TabPanel>
</TabPanels> </TabPanels>
</TabGroup> </TabGroup>

View file

@ -14,15 +14,17 @@ export interface Model {
export const modelCostMap = async () => { export const modelCostMap = async () => {
try { 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(); const jsonData = await response.json();
console.log(`received data: ${jsonData}`) console.log(`received data: ${jsonData}`);
return jsonData return jsonData;
} catch (error) { } catch (error) {
console.error("Failed to get model cost map:", error); console.error("Failed to get model cost map:", error);
throw error; throw error;
} }
} };
export const modelCreateCall = async ( export const modelCreateCall = async (
accessToken: string, accessToken: string,
@ -50,19 +52,21 @@ export const modelCreateCall = async (
const data = await response.json(); const data = await response.json();
console.log("API Response:", data); 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; return data;
} catch (error) { } catch (error) {
console.error("Failed to create key:", error); console.error("Failed to create key:", error);
throw error; throw error;
} }
} };
export const modelDeleteCall = async ( export const modelDeleteCall = async (
accessToken: string, 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 { try {
const url = proxyBaseUrl ? `${proxyBaseUrl}/model/delete` : `/model/delete`; const url = proxyBaseUrl ? `${proxyBaseUrl}/model/delete` : `/model/delete`;
const response = await fetch(url, { const response = await fetch(url, {
@ -72,7 +76,7 @@ export const modelDeleteCall = async (
"Content-Type": "application/json", "Content-Type": "application/json",
}, },
body: JSON.stringify({ body: JSON.stringify({
"id": model_id, id: model_id,
}), }),
}); });
@ -91,7 +95,7 @@ export const modelDeleteCall = async (
console.error("Failed to create key:", error); console.error("Failed to create key:", error);
throw error; throw error;
} }
} };
export const keyCreateCall = async ( export const keyCreateCall = async (
accessToken: string, accessToken: string,
@ -280,8 +284,7 @@ export const teamDeleteCall = async (accessToken: String, teamID: String) => {
console.error("Failed to delete key:", error); console.error("Failed to delete key:", error);
throw error; throw error;
} }
};
}
export const userInfoCall = async ( export const userInfoCall = async (
accessToken: String, accessToken: String,
@ -300,7 +303,7 @@ export const userInfoCall = async (
url = `${url}?user_id=${userID}`; url = `${url}?user_id=${userID}`;
} }
console.log("in userInfoCall viewAll=", viewAll); 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}`; url = `${url}?view_all=true&page=${page}&page_size=${page_size}`;
} }
//message.info("Requesting user data"); //message.info("Requesting user data");
@ -329,10 +332,9 @@ export const userInfoCall = async (
} }
}; };
export const teamInfoCall = async ( export const teamInfoCall = async (
accessToken: String, accessToken: String,
teamID: String | null, teamID: String | null
) => { ) => {
try { try {
let url = proxyBaseUrl ? `${proxyBaseUrl}/team/info` : `/team/info`; 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 * Get all models on proxy
*/ */
@ -435,7 +434,6 @@ export const modelInfoCall = async (
} }
}; };
export const modelMetricsCall = async ( export const modelMetricsCall = async (
accessToken: String, accessToken: String,
userID: String, userID: String,
@ -450,7 +448,7 @@ export const modelMetricsCall = async (
try { try {
let url = proxyBaseUrl ? `${proxyBaseUrl}/model/metrics` : `/model/metrics`; let url = proxyBaseUrl ? `${proxyBaseUrl}/model/metrics` : `/model/metrics`;
if (modelGroup) { 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"); // message.info("Requesting model data");
const response = await fetch(url, { const response = await fetch(url, {
@ -476,8 +474,6 @@ export const modelMetricsCall = async (
} }
}; };
export const modelMetricsSlowResponsesCall = async ( export const modelMetricsSlowResponsesCall = async (
accessToken: String, accessToken: String,
userID: String, userID: String,
@ -490,9 +486,11 @@ export const modelMetricsSlowResponsesCall = async (
* Get all models on proxy * Get all models on proxy
*/ */
try { 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) { 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"); // message.info("Requesting model data");
@ -519,7 +517,6 @@ export const modelMetricsSlowResponsesCall = async (
} }
}; };
export const modelExceptionsCall = async ( export const modelExceptionsCall = async (
accessToken: String, accessToken: String,
userID: String, userID: String,
@ -532,10 +529,12 @@ export const modelExceptionsCall = async (
* Get all models on proxy * Get all models on proxy
*/ */
try { try {
let url = proxyBaseUrl ? `${proxyBaseUrl}/model/metrics/exceptions` : `/model/metrics/exceptions`; let url = proxyBaseUrl
? `${proxyBaseUrl}/model/metrics/exceptions`
: `/model/metrics/exceptions`;
if (modelGroup) { 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, { const response = await fetch(url, {
method: "GET", method: "GET",
@ -560,7 +559,6 @@ export const modelExceptionsCall = async (
} }
}; };
export const modelAvailableCall = async ( export const modelAvailableCall = async (
accessToken: String, accessToken: String,
userID: String, userID: String,
@ -625,7 +623,6 @@ export const keySpendLogsCall = async (accessToken: String, token: String) => {
} }
}; };
export const teamSpendLogsCall = async (accessToken: String) => { export const teamSpendLogsCall = async (accessToken: String) => {
try { try {
const url = proxyBaseUrl const url = proxyBaseUrl
@ -654,19 +651,18 @@ export const teamSpendLogsCall = async (accessToken: String) => {
} }
}; };
export const tagsSpendLogsCall = async ( export const tagsSpendLogsCall = async (
accessToken: String, accessToken: String,
startTime: String | undefined, startTime: String | undefined,
endTime: String | undefined endTime: String | undefined
) => { ) => {
try { try {
let url = proxyBaseUrl let url = proxyBaseUrl
? `${proxyBaseUrl}/global/spend/tags` ? `${proxyBaseUrl}/global/spend/tags`
: `/global/spend/tags`; : `/global/spend/tags`;
if (startTime && endTime) { if (startTime && endTime) {
url = `${url}?start_date=${startTime}&end_date=${endTime}` url = `${url}?start_date=${startTime}&end_date=${endTime}`;
} }
console.log("in tagsSpendLogsCall:", url); console.log("in tagsSpendLogsCall:", url);
@ -692,7 +688,6 @@ export const tagsSpendLogsCall = async (
} }
}; };
export const userSpendLogsCall = async ( export const userSpendLogsCall = async (
accessToken: String, accessToken: String,
token: String, token: String,
@ -806,7 +801,11 @@ export const adminTopEndUsersCall = async (
let body = ""; let body = "";
if (keyToken) { if (keyToken) {
body = JSON.stringify({ api_key: keyToken, startTime: startTime, endTime: endTime }); body = JSON.stringify({
api_key: keyToken,
startTime: startTime,
endTime: endTime,
});
} else { } else {
body = JSON.stringify({ startTime: startTime, endTime: endTime }); body = JSON.stringify({ startTime: startTime, endTime: endTime });
} }
@ -1079,7 +1078,6 @@ export const teamCreateCall = async (
} }
}; };
export const keyUpdateCall = async ( export const keyUpdateCall = async (
accessToken: string, accessToken: string,
formValues: Record<string, any> // Assuming formValues is an object formValues: Record<string, any> // Assuming formValues is an object
@ -1240,7 +1238,7 @@ export const userUpdateUserCall = async (
console.log("Form Values in userUpdateUserCall:", formValues); // Log the form values before making the API call console.log("Form Values in userUpdateUserCall:", formValues); // Log the form values before making the API call
const url = proxyBaseUrl ? `${proxyBaseUrl}/user/update` : `/user/update`; const url = proxyBaseUrl ? `${proxyBaseUrl}/user/update` : `/user/update`;
let response_body = {...formValues}; let response_body = { ...formValues };
if (userRole !== null) { if (userRole !== null) {
response_body["user_role"] = userRole; response_body["user_role"] = userRole;
} }
@ -1347,9 +1345,10 @@ export const slackBudgetAlertsHealthCheck = async (accessToken: String) => {
} }
}; };
export const serviceHealthCheck = async (
accessToken: String,
export const serviceHealthCheck= async (accessToken: String, service: String) => { service: String
) => {
try { try {
let url = proxyBaseUrl let url = proxyBaseUrl
? `${proxyBaseUrl}/health/services?service=${service}` ? `${proxyBaseUrl}/health/services?service=${service}`
@ -1373,7 +1372,9 @@ export const serviceHealthCheck= async (accessToken: String, service: String) =>
} }
const data = await response.json(); 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 // You can add additional logic here based on the response if needed
return data; return data;
} catch (error) { } catch (error) {
@ -1382,9 +1383,6 @@ export const serviceHealthCheck= async (accessToken: String, service: String) =>
} }
}; };
export const getCallbacksCall = async ( export const getCallbacksCall = async (
accessToken: String, accessToken: String,
userID: String, userID: String,
@ -1394,7 +1392,9 @@ export const getCallbacksCall = async (
* Get all the models user has access to * Get all the models user has access to
*/ */
try { 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"); //message.info("Requesting model data");
const response = await fetch(url, { 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 ( export const setCallbacksCall = async (
accessToken: String, accessToken: String,
formValues: Record<string, any> formValues: Record<string, any>
@ -1464,9 +1570,7 @@ export const setCallbacksCall = async (
} }
}; };
export const healthCheckCall = async ( export const healthCheckCall = async (accessToken: String) => {
accessToken: String,
) => {
/** /**
* Get all the models user has access to * Get all the models user has access to
*/ */
@ -1497,6 +1601,3 @@ export const healthCheckCall = async (
throw error; throw error;
} }
}; };