diff --git a/litellm/proxy/proxy_server.py b/litellm/proxy/proxy_server.py index b46b9ab63..3ad67602c 100644 --- a/litellm/proxy/proxy_server.py +++ b/litellm/proxy/proxy_server.py @@ -2441,7 +2441,7 @@ class ProxyConfig: - Check if model id's in router already - If not, add to router """ - global llm_router, llm_model_list, master_key + global llm_router, llm_model_list, master_key, general_settings import base64 @@ -2541,7 +2541,7 @@ class ProxyConfig: config_data = await proxy_config.get_config() litellm_settings = config_data.get("litellm_settings", {}) or {} success_callbacks = litellm_settings.get("success_callback", None) - _added_callback = False + if success_callbacks is not None and isinstance(success_callbacks, list): for success_callback in success_callbacks: if success_callback not in litellm.success_callback: @@ -2557,6 +2557,13 @@ class ProxyConfig: verbose_proxy_logger.error( "Error setting env variable: %s - %s", k, str(e) ) + + # general_settings + _general_settings = config_data.get("general_settings", {}) + if "alerting" in _general_settings: + general_settings["alerting"] = _general_settings["alerting"] + proxy_logging_obj.alerting = general_settings["alerting"] + except Exception as e: verbose_proxy_logger.error( "{}\nTraceback:{}".format(str(e), traceback.format_exc()) @@ -8134,7 +8141,7 @@ async def update_config(config_info: ConfigYAML): Currently supports modifying General Settings + LiteLLM settings """ - global llm_router, llm_model_list, general_settings, proxy_config, proxy_logging_obj, master_key + global llm_router, llm_model_list, general_settings, proxy_config, proxy_logging_obj, master_key, prisma_client try: import base64 @@ -8202,6 +8209,12 @@ async def update_config(config_info: ConfigYAML): # Save the updated config await proxy_config.save_config(new_config=config) + # make sure the change is instantly rolled out for langfuse + if prisma_client is not None: + await proxy_config.add_deployment( + prisma_client=prisma_client, proxy_logging_obj=proxy_logging_obj + ) + # Test new connections ## Slack if "slack" in config.get("general_settings", {}).get("alerting", []): @@ -8246,6 +8259,7 @@ async def get_config(): config_data = await proxy_config.get_config() _litellm_settings = config_data.get("litellm_settings", {}) + _general_settings = config_data.get("general_settings", {}) environment_variables = config_data.get("environment_variables", {}) # check if "langfuse" in litellm_settings @@ -8288,6 +8302,27 @@ async def get_config(): {"name": _callback, "variables": _langfuse_env_vars} ) + # Check if slack alerting is on + _alerting = _general_settings.get("alerting", []) + if "slack" in _alerting: + _slack_vars = [ + "SLACK_WEBHOOK_URL", + ] + _slack_env_vars = {} + for _var in _slack_vars: + env_variable = environment_variables.get(_var, None) + if env_variable is None: + _slack_env_vars[_var] = None + else: + # decode + decrypt the value + decoded_b64 = base64.b64decode(env_variable) + _decrypted_value = decrypt_value( + value=decoded_b64, master_key=master_key + ) + _slack_env_vars[_var] = _decrypted_value + + _data_to_return.append({"name": "slack", "variables": _slack_env_vars}) + return {"status": "success", "data": _data_to_return} except Exception as e: traceback.print_exc() @@ -8362,7 +8397,7 @@ async def test_endpoint(request: Request): ) async def health_services_endpoint( user_api_key_dict: UserAPIKeyAuth = Depends(user_api_key_auth), - service: Literal["slack_budget_alerts", "langfuse"] = fastapi.Query( + service: Literal["slack_budget_alerts", "langfuse", "slack"] = fastapi.Query( description="Specify the service being hit." ), ): @@ -8378,7 +8413,7 @@ async def health_services_endpoint( raise HTTPException( status_code=400, detail={"error": "Service must be specified."} ) - if service not in ["slack_budget_alerts", "langfuse"]: + if service not in ["slack_budget_alerts", "langfuse", "slack"]: raise HTTPException( status_code=400, detail={ @@ -8405,6 +8440,10 @@ async def health_services_endpoint( if "slack" in general_settings.get("alerting", []): test_message = f"""\n🚨 `ProjectedLimitExceededError` 💸\n\n`Key Alias:` litellm-ui-test-alert \n`Expected Day of Error`: 28th March \n`Current Spend`: $100.00 \n`Projected Spend at end of month`: $1000.00 \n`Soft Limit`: $700""" await proxy_logging_obj.alerting_handler(message=test_message, level="Low") + return { + "status": "success", + "message": "Mock Slack Alert sent, verify Slack Alert Received on your channel", + } else: raise HTTPException( status_code=422, diff --git a/ui/litellm-dashboard/src/components/settings.tsx b/ui/litellm-dashboard/src/components/settings.tsx index 28e273d21..25ccb5070 100644 --- a/ui/litellm-dashboard/src/components/settings.tsx +++ b/ui/litellm-dashboard/src/components/settings.tsx @@ -147,8 +147,6 @@ const Settings: React.FC = ({ Callback Callback Env Vars - - {/* Test Callback */} @@ -159,29 +157,22 @@ const Settings: React.FC = ({
    - {Object.entries(callback.variables).map(([key, value]) => ( -
  • - {key} - -
  • - ))} + {Object.entries(callback.variables).map(([key, value]) => ( +
  • + {key} + {key === "LANGFUSE_HOST" ? ( +

    default value="https://cloud.langfuse.com"

    + ) : ( +
    + )} + +
  • +))}
-
- - - - - - - - @@ -192,6 +183,7 @@ const Settings: React.FC = ({ +