From 2545da777b3251db943cbcc87d3a5a737aad2a2f Mon Sep 17 00:00:00 2001 From: Krrish Dholakia Date: Fri, 21 Jun 2024 18:41:31 -0700 Subject: [PATCH 01/22] feat(dynamic_rate_limiter.py): initial commit for dynamic rate limiting Closes https://github.com/BerriAI/litellm/issues/4124 --- litellm/proxy/hooks/dynamic_rate_limiter.py | 550 ++++++++++++++++++ litellm/router.py | 36 ++ .../tests/test_dynamic_rate_limit_handler.py | 73 +++ litellm/types/router.py | 2 + 4 files changed, 661 insertions(+) create mode 100644 litellm/proxy/hooks/dynamic_rate_limiter.py create mode 100644 litellm/tests/test_dynamic_rate_limit_handler.py diff --git a/litellm/proxy/hooks/dynamic_rate_limiter.py b/litellm/proxy/hooks/dynamic_rate_limiter.py new file mode 100644 index 00000000000..87e9ed8d4a1 --- /dev/null +++ b/litellm/proxy/hooks/dynamic_rate_limiter.py @@ -0,0 +1,550 @@ +# What is this? +## Allocates dynamic tpm/rpm quota for a project based on current traffic + +import sys +import traceback +from datetime import datetime +from typing import Optional + +from fastapi import HTTPException + +import litellm +from litellm import ModelResponse, Router +from litellm._logging import verbose_proxy_logger +from litellm.caching import DualCache +from litellm.integrations.custom_logger import CustomLogger +from litellm.proxy._types import UserAPIKeyAuth +from litellm.types.router import ModelGroupInfo + + +class DynamicRateLimiterCache: + """ + Thin wrapper on DualCache for this file. + + Track number of active projects calling a model. + """ + + def __init__(self, cache: DualCache) -> None: + self.cache = cache + self.ttl = 60 # 1 min ttl + + async def async_get_cache(self, model: str) -> Optional[int]: + key_name = "{}".format(model) + response = await self.cache.async_get_cache(key=key_name) + return response + + async def async_increment_cache(self, model: str, value: int): + key_name = "{}".format(model) + await self.cache.async_increment_cache(key=key_name, value=value, ttl=self.ttl) + + +class _PROXY_DynamicRateLimitHandler(CustomLogger): + + # Class variables or attributes + def __init__(self, internal_usage_cache: DualCache): + self.internal_usage_cache = DynamicRateLimiterCache(cache=internal_usage_cache) + + def update_variables(self, llm_router: Router): + self.llm_router = llm_router + + async def check_available_tpm(self, model: str) -> Optional[int]: + """ + For a given model, get it's available tpm + + Returns + - int: if number found + - None: if not found + """ + active_projects = await self.internal_usage_cache.async_get_cache(model=model) + model_group_info: Optional[ModelGroupInfo] = ( + self.llm_router.get_model_group_info(model_group=model) + ) + + available_tpm: Optional[int] = None + if model_group_info is not None and model_group_info.tpm is not None: + if active_projects is not None: + available_tpm = int(model_group_info.tpm / active_projects) + else: + available_tpm = model_group_info.tpm + + return available_tpm + + # async def check_key_in_limits( + # self, + # user_api_key_dict: UserAPIKeyAuth, + # cache: DualCache, + # data: dict, + # call_type: str, + # max_parallel_requests: int, + # tpm_limit: int, + # rpm_limit: int, + # request_count_api_key: str, + # ): + # current = await self.internal_usage_cache.async_get_cache( + # key=request_count_api_key + # ) # {"current_requests": 1, "current_tpm": 1, "current_rpm": 10} + # if current is None: + # if max_parallel_requests == 0 or tpm_limit == 0 or rpm_limit == 0: + # # base case + # raise HTTPException( + # status_code=429, detail="Max parallel request limit reached." + # ) + # new_val = { + # "current_requests": 1, + # "current_tpm": 0, + # "current_rpm": 0, + # } + # await self.internal_usage_cache.async_set_cache( + # request_count_api_key, new_val + # ) + # elif ( + # int(current["current_requests"]) < max_parallel_requests + # and current["current_tpm"] < tpm_limit + # and current["current_rpm"] < rpm_limit + # ): + # # Increase count for this token + # new_val = { + # "current_requests": current["current_requests"] + 1, + # "current_tpm": current["current_tpm"], + # "current_rpm": current["current_rpm"], + # } + # await self.internal_usage_cache.async_set_cache( + # request_count_api_key, new_val + # ) + # else: + # raise HTTPException( + # status_code=429, + # detail=f"LiteLLM Rate Limit Handler: Crossed TPM, RPM Limit. current rpm: {current['current_rpm']}, rpm limit: {rpm_limit}, current tpm: {current['current_tpm']}, tpm limit: {tpm_limit}", + # ) + + # async def async_pre_call_hook( + # self, + # user_api_key_dict: UserAPIKeyAuth, + # cache: DualCache, + # data: dict, + # call_type: str, + # ): + # self.print_verbose("Inside Dynamic Rate Limit Handler Pre-Call Hook") + # api_key = user_api_key_dict.api_key + # max_parallel_requests = user_api_key_dict.max_parallel_requests + # if max_parallel_requests is None: + # max_parallel_requests = sys.maxsize + # global_max_parallel_requests = data.get("metadata", {}).get( + # "global_max_parallel_requests", None + # ) + # tpm_limit = getattr(user_api_key_dict, "tpm_limit", sys.maxsize) + # if tpm_limit is None: + # tpm_limit = sys.maxsize + # rpm_limit = getattr(user_api_key_dict, "rpm_limit", sys.maxsize) + # if rpm_limit is None: + # rpm_limit = sys.maxsize + + # # ------------ + # # Setup values + # # ------------ + + # if global_max_parallel_requests is not None: + # # get value from cache + # _key = "global_max_parallel_requests" + # current_global_requests = await self.internal_usage_cache.async_get_cache( + # key=_key, local_only=True + # ) + # # check if below limit + # if current_global_requests is None: + # current_global_requests = 1 + # # if above -> raise error + # if current_global_requests >= global_max_parallel_requests: + # raise HTTPException( + # status_code=429, detail="Max parallel request limit reached." + # ) + # # if below -> increment + # else: + # await self.internal_usage_cache.async_increment_cache( + # key=_key, value=1, local_only=True + # ) + + # current_date = datetime.now().strftime("%Y-%m-%d") + # current_hour = datetime.now().strftime("%H") + # current_minute = datetime.now().strftime("%M") + # precise_minute = f"{current_date}-{current_hour}-{current_minute}" + + # if api_key is not None: + # request_count_api_key = f"{api_key}::{precise_minute}::request_count" + + # # CHECK IF REQUEST ALLOWED for key + + # current = await self.internal_usage_cache.async_get_cache( + # key=request_count_api_key + # ) # {"current_requests": 1, "current_tpm": 1, "current_rpm": 10} + # self.print_verbose(f"current: {current}") + # if ( + # max_parallel_requests == sys.maxsize + # and tpm_limit == sys.maxsize + # and rpm_limit == sys.maxsize + # ): + # pass + # elif max_parallel_requests == 0 or tpm_limit == 0 or rpm_limit == 0: + # raise HTTPException( + # status_code=429, detail="Max parallel request limit reached." + # ) + # elif current is None: + # new_val = { + # "current_requests": 1, + # "current_tpm": 0, + # "current_rpm": 0, + # } + # await self.internal_usage_cache.async_set_cache( + # request_count_api_key, new_val + # ) + # elif ( + # int(current["current_requests"]) < max_parallel_requests + # and current["current_tpm"] < tpm_limit + # and current["current_rpm"] < rpm_limit + # ): + # # Increase count for this token + # new_val = { + # "current_requests": current["current_requests"] + 1, + # "current_tpm": current["current_tpm"], + # "current_rpm": current["current_rpm"], + # } + # await self.internal_usage_cache.async_set_cache( + # request_count_api_key, new_val + # ) + # else: + # raise HTTPException( + # status_code=429, detail="Max parallel request limit reached." + # ) + + # # check if REQUEST ALLOWED for user_id + # user_id = user_api_key_dict.user_id + # if user_id is not None: + # _user_id_rate_limits = await self.internal_usage_cache.async_get_cache( + # key=user_id + # ) + # # get user tpm/rpm limits + # if _user_id_rate_limits is not None and isinstance( + # _user_id_rate_limits, dict + # ): + # user_tpm_limit = _user_id_rate_limits.get("tpm_limit", None) + # user_rpm_limit = _user_id_rate_limits.get("rpm_limit", None) + # if user_tpm_limit is None: + # user_tpm_limit = sys.maxsize + # if user_rpm_limit is None: + # user_rpm_limit = sys.maxsize + + # # now do the same tpm/rpm checks + # request_count_api_key = f"{user_id}::{precise_minute}::request_count" + + # # print(f"Checking if {request_count_api_key} is allowed to make request for minute {precise_minute}") + # await self.check_key_in_limits( + # user_api_key_dict=user_api_key_dict, + # cache=cache, + # data=data, + # call_type=call_type, + # max_parallel_requests=sys.maxsize, # TODO: Support max parallel requests for a user + # request_count_api_key=request_count_api_key, + # tpm_limit=user_tpm_limit, + # rpm_limit=user_rpm_limit, + # ) + + # # TEAM RATE LIMITS + # ## get team tpm/rpm limits + # team_id = user_api_key_dict.team_id + # if team_id is not None: + # team_tpm_limit = user_api_key_dict.team_tpm_limit + # team_rpm_limit = user_api_key_dict.team_rpm_limit + + # if team_tpm_limit is None: + # team_tpm_limit = sys.maxsize + # if team_rpm_limit is None: + # team_rpm_limit = sys.maxsize + + # # now do the same tpm/rpm checks + # request_count_api_key = f"{team_id}::{precise_minute}::request_count" + + # # print(f"Checking if {request_count_api_key} is allowed to make request for minute {precise_minute}") + # await self.check_key_in_limits( + # user_api_key_dict=user_api_key_dict, + # cache=cache, + # data=data, + # call_type=call_type, + # max_parallel_requests=sys.maxsize, # TODO: Support max parallel requests for a team + # request_count_api_key=request_count_api_key, + # tpm_limit=team_tpm_limit, + # rpm_limit=team_rpm_limit, + # ) + + # # End-User Rate Limits + # # Only enforce if user passed `user` to /chat, /completions, /embeddings + # if user_api_key_dict.end_user_id: + # end_user_tpm_limit = getattr( + # user_api_key_dict, "end_user_tpm_limit", sys.maxsize + # ) + # end_user_rpm_limit = getattr( + # user_api_key_dict, "end_user_rpm_limit", sys.maxsize + # ) + + # if end_user_tpm_limit is None: + # end_user_tpm_limit = sys.maxsize + # if end_user_rpm_limit is None: + # end_user_rpm_limit = sys.maxsize + + # # now do the same tpm/rpm checks + # request_count_api_key = ( + # f"{user_api_key_dict.end_user_id}::{precise_minute}::request_count" + # ) + + # # print(f"Checking if {request_count_api_key} is allowed to make request for minute {precise_minute}") + # await self.check_key_in_limits( + # user_api_key_dict=user_api_key_dict, + # cache=cache, + # data=data, + # call_type=call_type, + # max_parallel_requests=sys.maxsize, # TODO: Support max parallel requests for an End-User + # request_count_api_key=request_count_api_key, + # tpm_limit=end_user_tpm_limit, + # rpm_limit=end_user_rpm_limit, + # ) + + # return + + # async def async_log_success_event(self, kwargs, response_obj, start_time, end_time): + # try: + # self.print_verbose("INSIDE parallel request limiter ASYNC SUCCESS LOGGING") + # global_max_parallel_requests = kwargs["litellm_params"]["metadata"].get( + # "global_max_parallel_requests", None + # ) + # user_api_key = kwargs["litellm_params"]["metadata"]["user_api_key"] + # user_api_key_user_id = kwargs["litellm_params"]["metadata"].get( + # "user_api_key_user_id", None + # ) + # user_api_key_team_id = kwargs["litellm_params"]["metadata"].get( + # "user_api_key_team_id", None + # ) + # user_api_key_end_user_id = kwargs.get("user") + + # # ------------ + # # Setup values + # # ------------ + + # if global_max_parallel_requests is not None: + # # get value from cache + # _key = "global_max_parallel_requests" + # # decrement + # await self.internal_usage_cache.async_increment_cache( + # key=_key, value=-1, local_only=True + # ) + + # current_date = datetime.now().strftime("%Y-%m-%d") + # current_hour = datetime.now().strftime("%H") + # current_minute = datetime.now().strftime("%M") + # precise_minute = f"{current_date}-{current_hour}-{current_minute}" + + # total_tokens = 0 + + # if isinstance(response_obj, ModelResponse): + # total_tokens = response_obj.usage.total_tokens + + # # ------------ + # # Update usage - API Key + # # ------------ + + # if user_api_key is not None: + # request_count_api_key = ( + # f"{user_api_key}::{precise_minute}::request_count" + # ) + + # current = await self.internal_usage_cache.async_get_cache( + # key=request_count_api_key + # ) or { + # "current_requests": 1, + # "current_tpm": total_tokens, + # "current_rpm": 1, + # } + + # new_val = { + # "current_requests": max(current["current_requests"] - 1, 0), + # "current_tpm": current["current_tpm"] + total_tokens, + # "current_rpm": current["current_rpm"] + 1, + # } + + # self.print_verbose( + # f"updated_value in success call: {new_val}, precise_minute: {precise_minute}" + # ) + # await self.internal_usage_cache.async_set_cache( + # request_count_api_key, new_val, ttl=60 + # ) # store in cache for 1 min. + + # # ------------ + # # Update usage - User + # # ------------ + # if user_api_key_user_id is not None: + # total_tokens = 0 + + # if isinstance(response_obj, ModelResponse): + # total_tokens = response_obj.usage.total_tokens + + # request_count_api_key = ( + # f"{user_api_key_user_id}::{precise_minute}::request_count" + # ) + + # current = await self.internal_usage_cache.async_get_cache( + # key=request_count_api_key + # ) or { + # "current_requests": 1, + # "current_tpm": total_tokens, + # "current_rpm": 1, + # } + + # new_val = { + # "current_requests": max(current["current_requests"] - 1, 0), + # "current_tpm": current["current_tpm"] + total_tokens, + # "current_rpm": current["current_rpm"] + 1, + # } + + # self.print_verbose( + # f"updated_value in success call: {new_val}, precise_minute: {precise_minute}" + # ) + # await self.internal_usage_cache.async_set_cache( + # request_count_api_key, new_val, ttl=60 + # ) # store in cache for 1 min. + + # # ------------ + # # Update usage - Team + # # ------------ + # if user_api_key_team_id is not None: + # total_tokens = 0 + + # if isinstance(response_obj, ModelResponse): + # total_tokens = response_obj.usage.total_tokens + + # request_count_api_key = ( + # f"{user_api_key_team_id}::{precise_minute}::request_count" + # ) + + # current = await self.internal_usage_cache.async_get_cache( + # key=request_count_api_key + # ) or { + # "current_requests": 1, + # "current_tpm": total_tokens, + # "current_rpm": 1, + # } + + # new_val = { + # "current_requests": max(current["current_requests"] - 1, 0), + # "current_tpm": current["current_tpm"] + total_tokens, + # "current_rpm": current["current_rpm"] + 1, + # } + + # self.print_verbose( + # f"updated_value in success call: {new_val}, precise_minute: {precise_minute}" + # ) + # await self.internal_usage_cache.async_set_cache( + # request_count_api_key, new_val, ttl=60 + # ) # store in cache for 1 min. + + # # ------------ + # # Update usage - End User + # # ------------ + # if user_api_key_end_user_id is not None: + # total_tokens = 0 + + # if isinstance(response_obj, ModelResponse): + # total_tokens = response_obj.usage.total_tokens + + # request_count_api_key = ( + # f"{user_api_key_end_user_id}::{precise_minute}::request_count" + # ) + + # current = await self.internal_usage_cache.async_get_cache( + # key=request_count_api_key + # ) or { + # "current_requests": 1, + # "current_tpm": total_tokens, + # "current_rpm": 1, + # } + + # new_val = { + # "current_requests": max(current["current_requests"] - 1, 0), + # "current_tpm": current["current_tpm"] + total_tokens, + # "current_rpm": current["current_rpm"] + 1, + # } + + # self.print_verbose( + # f"updated_value in success call: {new_val}, precise_minute: {precise_minute}" + # ) + # await self.internal_usage_cache.async_set_cache( + # request_count_api_key, new_val, ttl=60 + # ) # store in cache for 1 min. + + # except Exception as e: + # self.print_verbose(e) # noqa + + # async def async_log_failure_event(self, kwargs, response_obj, start_time, end_time): + # try: + # self.print_verbose(f"Inside Max Parallel Request Failure Hook") + # global_max_parallel_requests = kwargs["litellm_params"]["metadata"].get( + # "global_max_parallel_requests", None + # ) + # user_api_key = ( + # kwargs["litellm_params"].get("metadata", {}).get("user_api_key", None) + # ) + # self.print_verbose(f"user_api_key: {user_api_key}") + # if user_api_key is None: + # return + + # ## decrement call count if call failed + # if "Max parallel request limit reached" in str(kwargs["exception"]): + # pass # ignore failed calls due to max limit being reached + # else: + # # ------------ + # # Setup values + # # ------------ + + # if global_max_parallel_requests is not None: + # # get value from cache + # _key = "global_max_parallel_requests" + # current_global_requests = ( + # await self.internal_usage_cache.async_get_cache( + # key=_key, local_only=True + # ) + # ) + # # decrement + # await self.internal_usage_cache.async_increment_cache( + # key=_key, value=-1, local_only=True + # ) + + # current_date = datetime.now().strftime("%Y-%m-%d") + # current_hour = datetime.now().strftime("%H") + # current_minute = datetime.now().strftime("%M") + # precise_minute = f"{current_date}-{current_hour}-{current_minute}" + + # request_count_api_key = ( + # f"{user_api_key}::{precise_minute}::request_count" + # ) + + # # ------------ + # # Update usage + # # ------------ + # current = await self.internal_usage_cache.async_get_cache( + # key=request_count_api_key + # ) or { + # "current_requests": 1, + # "current_tpm": 0, + # "current_rpm": 0, + # } + + # new_val = { + # "current_requests": max(current["current_requests"] - 1, 0), + # "current_tpm": current["current_tpm"], + # "current_rpm": current["current_rpm"], + # } + + # self.print_verbose(f"updated_value in failure call: {new_val}") + # await self.internal_usage_cache.async_set_cache( + # request_count_api_key, new_val, ttl=60 + # ) # save in cache for up to 1 min. + # except Exception as e: + # verbose_proxy_logger.info( + # f"Inside Parallel Request Limiter: An exception occurred - {str(e)}." + # ) diff --git a/litellm/router.py b/litellm/router.py index d7e2aa12fde..87890ebffcd 100644 --- a/litellm/router.py +++ b/litellm/router.py @@ -3808,10 +3808,39 @@ class Router: model_group_info: Optional[ModelGroupInfo] = None + total_tpm: Optional[int] = None + total_rpm: Optional[int] = None + for model in self.model_list: if "model_name" in model and model["model_name"] == model_group: # model in model group found # litellm_params = LiteLLM_Params(**model["litellm_params"]) + # get model tpm + _deployment_tpm: Optional[int] = None + if _deployment_tpm is None: + _deployment_tpm = model.get("tpm", None) + if _deployment_tpm is None: + _deployment_tpm = model.get("litellm_params", {}).get("tpm", None) + if _deployment_tpm is None: + _deployment_tpm = model.get("model_info", {}).get("tpm", None) + + if _deployment_tpm is not None: + if total_tpm is None: + total_tpm = 0 + total_tpm += _deployment_tpm # type: ignore + # get model rpm + _deployment_rpm: Optional[int] = None + if _deployment_rpm is None: + _deployment_rpm = model.get("rpm", None) + if _deployment_rpm is None: + _deployment_rpm = model.get("litellm_params", {}).get("rpm", None) + if _deployment_rpm is None: + _deployment_rpm = model.get("model_info", {}).get("rpm", None) + + if _deployment_rpm is not None: + if total_rpm is None: + total_rpm = 0 + total_rpm += _deployment_rpm # type: ignore # get model info try: model_info = litellm.get_model_info(model=litellm_params.model) @@ -3925,6 +3954,13 @@ class Router: "supported_openai_params" ] + ## UPDATE WITH TOTAL TPM/RPM FOR MODEL GROUP + if total_tpm is not None and model_group_info is not None: + model_group_info.tpm = total_tpm + + if total_rpm is not None and model_group_info is not None: + model_group_info.rpm = total_rpm + return model_group_info def get_model_ids(self) -> List[str]: diff --git a/litellm/tests/test_dynamic_rate_limit_handler.py b/litellm/tests/test_dynamic_rate_limit_handler.py new file mode 100644 index 00000000000..1efe6ef260d --- /dev/null +++ b/litellm/tests/test_dynamic_rate_limit_handler.py @@ -0,0 +1,73 @@ +# What is this? +## Unit tests for 'dynamic_rate_limiter.py` +import asyncio +import os +import random +import sys +import time +import traceback +from datetime import datetime +from typing import Tuple + +from dotenv import load_dotenv + +load_dotenv() +import os + +sys.path.insert( + 0, os.path.abspath("../..") +) # Adds the parent directory to the system path +import pytest + +import litellm +from litellm import DualCache, Router +from litellm.proxy.hooks.dynamic_rate_limiter import ( + _PROXY_DynamicRateLimitHandler as DynamicRateLimitHandler, +) + +""" +Basic test cases: + +- If 1 'active' project => give all tpm +- If 2 'active' projects => divide tpm in 2 +""" + + +@pytest.fixture +def dynamic_rate_limit_handler() -> DynamicRateLimitHandler: + internal_cache = DualCache() + return DynamicRateLimitHandler(internal_usage_cache=internal_cache) + + +@pytest.mark.parametrize("num_projects", [1, 2, 100]) +@pytest.mark.asyncio +async def test_available_tpm(num_projects, dynamic_rate_limit_handler): + model = "my-fake-model" + ## SET CACHE W/ ACTIVE PROJECTS + await dynamic_rate_limit_handler.internal_usage_cache.async_increment_cache( + model=model, value=num_projects + ) + + model_tpm = 100 + llm_router = Router( + model_list=[ + { + "model_name": model, + "litellm_params": { + "model": "gpt-3.5-turbo", + "api_key": "my-key", + "api_base": "my-base", + "tpm": model_tpm, + }, + } + ] + ) + dynamic_rate_limit_handler.update_variables(llm_router=llm_router) + + ## CHECK AVAILABLE TPM PER PROJECT + + availability = await dynamic_rate_limit_handler.check_available_tpm(model=model) + + expected_availability = int(model_tpm / num_projects) + + assert availability == expected_availability diff --git a/litellm/types/router.py b/litellm/types/router.py index 206216ef0c7..7f043e4042e 100644 --- a/litellm/types/router.py +++ b/litellm/types/router.py @@ -442,6 +442,8 @@ class ModelGroupInfo(BaseModel): "chat", "embedding", "completion", "image_generation", "audio_transcription" ] ] = Field(default="chat") + tpm: Optional[int] = None + rpm: Optional[int] = None supports_parallel_function_calling: bool = Field(default=False) supports_vision: bool = Field(default=False) supports_function_calling: bool = Field(default=False) From a0286009328943afd714891370a98bd0eadf5ae3 Mon Sep 17 00:00:00 2001 From: Krrish Dholakia Date: Fri, 21 Jun 2024 20:25:40 -0700 Subject: [PATCH 02/22] feat(dynamic_rate_limiter.py): update cache with active project --- litellm/_service_logger.py | 19 +- litellm/caching.py | 158 ++++- litellm/integrations/opentelemetry.py | 8 +- litellm/proxy/hooks/dynamic_rate_limiter.py | 578 +++--------------- .../tests/test_dynamic_rate_limit_handler.py | 11 +- 5 files changed, 253 insertions(+), 521 deletions(-) diff --git a/litellm/_service_logger.py b/litellm/_service_logger.py index f2edb403e95..0aa0312b804 100644 --- a/litellm/_service_logger.py +++ b/litellm/_service_logger.py @@ -1,11 +1,12 @@ -from datetime import datetime +from datetime import datetime, timedelta +from typing import TYPE_CHECKING, Any, Optional, Union + import litellm from litellm.proxy._types import UserAPIKeyAuth -from .types.services import ServiceTypes, ServiceLoggerPayload -from .integrations.prometheus_services import PrometheusServicesLogger + from .integrations.custom_logger import CustomLogger -from datetime import timedelta -from typing import Union, Optional, TYPE_CHECKING, Any +from .integrations.prometheus_services import PrometheusServicesLogger +from .types.services import ServiceLoggerPayload, ServiceTypes if TYPE_CHECKING: from opentelemetry.trace import Span as _Span @@ -53,8 +54,8 @@ class ServiceLogging(CustomLogger): call_type: str, duration: float, parent_otel_span: Optional[Span] = None, - start_time: Optional[datetime] = None, - end_time: Optional[datetime] = None, + start_time: Optional[Union[datetime, float]] = None, + end_time: Optional[Union[datetime, float]] = None, ): """ - For counting if the redis, postgres call is successful @@ -92,8 +93,8 @@ class ServiceLogging(CustomLogger): error: Union[str, Exception], call_type: str, parent_otel_span: Optional[Span] = None, - start_time: Optional[datetime] = None, - end_time: Optional[datetime] = None, + start_time: Optional[Union[datetime, float]] = None, + end_time: Optional[Union[float, datetime]] = None, ): """ - For counting if the redis, postgres call is unsuccessful diff --git a/litellm/caching.py b/litellm/caching.py index 6b58cf52766..95cad01cfdf 100644 --- a/litellm/caching.py +++ b/litellm/caching.py @@ -7,14 +7,21 @@ # # Thank you users! We ❤️ you! - Krrish & Ishaan -import litellm -import time, logging, asyncio -import json, traceback, ast, hashlib -from typing import Optional, Literal, List, Union, Any, BinaryIO +import ast +import asyncio +import hashlib +import json +import logging +import time +import traceback +from datetime import timedelta +from typing import Any, BinaryIO, List, Literal, Optional, Union + from openai._models import BaseModel as OpenAIObject + +import litellm from litellm._logging import verbose_logger from litellm.types.services import ServiceLoggerPayload, ServiceTypes -import traceback def print_verbose(print_statement): @@ -78,6 +85,17 @@ class InMemoryCache(BaseCache): else: self.set_cache(key=cache_key, value=cache_value) + async def async_set_cache_sadd(self, key, value: List, ttl: Optional[float]): + """ + Add value to set + """ + # get the value + init_value = self.get_cache(key=key) or set() + for val in value: + init_value.add(val) + self.set_cache(key, init_value, ttl=ttl) + return value + def get_cache(self, key, **kwargs): if key in self.cache_dict: if key in self.ttl_dict: @@ -147,10 +165,12 @@ class RedisCache(BaseCache): namespace: Optional[str] = None, **kwargs, ): - from ._redis import get_redis_client, get_redis_connection_pool - from litellm._service_logger import ServiceLogging import redis + from litellm._service_logger import ServiceLogging + + from ._redis import get_redis_client, get_redis_connection_pool + redis_kwargs = {} if host is not None: redis_kwargs["host"] = host @@ -329,6 +349,7 @@ class RedisCache(BaseCache): start_time=start_time, end_time=end_time, parent_otel_span=_get_parent_otel_span_from_kwargs(kwargs), + call_type="async_set_cache", ) ) # NON blocking - notify users Redis is throwing an exception @@ -448,6 +469,80 @@ class RedisCache(BaseCache): cache_value, ) + async def async_set_cache_sadd( + self, key, value: List, ttl: Optional[float], **kwargs + ): + start_time = time.time() + try: + _redis_client = self.init_async_client() + except Exception as e: + end_time = time.time() + _duration = end_time - start_time + asyncio.create_task( + self.service_logger_obj.async_service_failure_hook( + service=ServiceTypes.REDIS, + duration=_duration, + error=e, + start_time=start_time, + end_time=end_time, + parent_otel_span=_get_parent_otel_span_from_kwargs(kwargs), + call_type="async_set_cache_sadd", + ) + ) + # NON blocking - notify users Redis is throwing an exception + verbose_logger.error( + "LiteLLM Redis Caching: async set() - Got exception from REDIS %s, Writing value=%s", + str(e), + value, + ) + raise e + + key = self.check_and_fix_namespace(key=key) + async with _redis_client as redis_client: + print_verbose( + f"Set ASYNC Redis Cache: key: {key}\nValue {value}\nttl={ttl}" + ) + try: + await redis_client.sadd(key, *value) + if ttl is not None: + _td = timedelta(seconds=ttl) + await redis_client.expire(key, _td) + print_verbose( + f"Successfully Set ASYNC Redis Cache SADD: key: {key}\nValue {value}\nttl={ttl}" + ) + end_time = time.time() + _duration = end_time - start_time + asyncio.create_task( + self.service_logger_obj.async_service_success_hook( + service=ServiceTypes.REDIS, + duration=_duration, + call_type="async_set_cache_sadd", + start_time=start_time, + end_time=end_time, + parent_otel_span=_get_parent_otel_span_from_kwargs(kwargs), + ) + ) + except Exception as e: + end_time = time.time() + _duration = end_time - start_time + asyncio.create_task( + self.service_logger_obj.async_service_failure_hook( + service=ServiceTypes.REDIS, + duration=_duration, + error=e, + call_type="async_set_cache_sadd", + start_time=start_time, + end_time=end_time, + parent_otel_span=_get_parent_otel_span_from_kwargs(kwargs), + ) + ) + # NON blocking - notify users Redis is throwing an exception + verbose_logger.error( + "LiteLLM Redis Caching: async set_cache_sadd() - Got exception from REDIS %s, Writing value=%s", + str(e), + value, + ) + async def batch_cache_write(self, key, value, **kwargs): print_verbose( f"in batch cache writing for redis buffer size={len(self.redis_batch_writing_buffer)}", @@ -886,11 +981,10 @@ class RedisSemanticCache(BaseCache): def get_cache(self, key, **kwargs): print_verbose(f"sync redis semantic-cache get_cache, kwargs: {kwargs}") - from redisvl.query import VectorQuery import numpy as np + from redisvl.query import VectorQuery # query - # get the messages messages = kwargs["messages"] prompt = "".join(message["content"] for message in messages) @@ -943,7 +1037,8 @@ class RedisSemanticCache(BaseCache): async def async_set_cache(self, key, value, **kwargs): import numpy as np - from litellm.proxy.proxy_server import llm_router, llm_model_list + + from litellm.proxy.proxy_server import llm_model_list, llm_router try: await self.index.acreate(overwrite=False) # don't overwrite existing index @@ -998,12 +1093,12 @@ class RedisSemanticCache(BaseCache): async def async_get_cache(self, key, **kwargs): print_verbose(f"async redis semantic-cache get_cache, kwargs: {kwargs}") - from redisvl.query import VectorQuery import numpy as np - from litellm.proxy.proxy_server import llm_router, llm_model_list + from redisvl.query import VectorQuery + + from litellm.proxy.proxy_server import llm_model_list, llm_router # query - # get the messages messages = kwargs["messages"] prompt = "".join(message["content"] for message in messages) @@ -1161,7 +1256,8 @@ class S3Cache(BaseCache): self.set_cache(key=key, value=value, **kwargs) def get_cache(self, key, **kwargs): - import boto3, botocore + import boto3 + import botocore try: key = self.key_prefix + key @@ -1471,7 +1567,7 @@ class DualCache(BaseCache): key, value, **kwargs ) - if self.redis_cache is not None and local_only == False: + if self.redis_cache is not None and local_only is False: result = await self.redis_cache.async_increment(key, value, **kwargs) return result @@ -1480,6 +1576,38 @@ class DualCache(BaseCache): verbose_logger.debug(traceback.format_exc()) raise e + async def async_set_cache_sadd( + self, key, value: List, local_only: bool = False, **kwargs + ) -> None: + """ + Add value to a set + + Key - the key in cache + + Value - str - the value you want to add to the set + + Returns - None + """ + try: + if self.in_memory_cache is not None: + _ = await self.in_memory_cache.async_set_cache_sadd( + key, value, ttl=kwargs.get("ttl", None) + ) + + if self.redis_cache is not None and local_only is False: + _ = await self.redis_cache.async_set_cache_sadd( + key, value, ttl=kwargs.get("ttl", None) ** kwargs + ) + + return None + except Exception as e: + verbose_logger.error( + "LiteLLM Cache: Excepton async set_cache_sadd: {}\n{}".format( + str(e), traceback.format_exc() + ) + ) + raise e + def flush_cache(self): if self.in_memory_cache is not None: self.in_memory_cache.flush_cache() diff --git a/litellm/integrations/opentelemetry.py b/litellm/integrations/opentelemetry.py index e4daff12189..fa7be1d574c 100644 --- a/litellm/integrations/opentelemetry.py +++ b/litellm/integrations/opentelemetry.py @@ -105,8 +105,8 @@ class OpenTelemetry(CustomLogger): self, payload: ServiceLoggerPayload, parent_otel_span: Optional[Span] = None, - start_time: Optional[datetime] = None, - end_time: Optional[datetime] = None, + start_time: Optional[Union[datetime, float]] = None, + end_time: Optional[Union[datetime, float]] = None, ): from datetime import datetime @@ -144,8 +144,8 @@ class OpenTelemetry(CustomLogger): self, payload: ServiceLoggerPayload, parent_otel_span: Optional[Span] = None, - start_time: Optional[datetime] = None, - end_time: Optional[datetime] = None, + start_time: Optional[Union[datetime, float]] = None, + end_time: Optional[Union[float, datetime]] = None, ): from datetime import datetime diff --git a/litellm/proxy/hooks/dynamic_rate_limiter.py b/litellm/proxy/hooks/dynamic_rate_limiter.py index 87e9ed8d4a1..dc29597f6ea 100644 --- a/litellm/proxy/hooks/dynamic_rate_limiter.py +++ b/litellm/proxy/hooks/dynamic_rate_limiter.py @@ -1,10 +1,12 @@ # What is this? ## Allocates dynamic tpm/rpm quota for a project based on current traffic +## Tracks num active projects per minute +import asyncio import sys import traceback from datetime import datetime -from typing import Optional +from typing import List, Literal, Optional, Tuple, Union from fastapi import HTTPException @@ -15,6 +17,7 @@ from litellm.caching import DualCache from litellm.integrations.custom_logger import CustomLogger from litellm.proxy._types import UserAPIKeyAuth from litellm.types.router import ModelGroupInfo +from litellm.utils import get_utc_datetime class DynamicRateLimiterCache: @@ -29,13 +32,34 @@ class DynamicRateLimiterCache: self.ttl = 60 # 1 min ttl async def async_get_cache(self, model: str) -> Optional[int]: - key_name = "{}".format(model) - response = await self.cache.async_get_cache(key=key_name) + dt = get_utc_datetime() + current_minute = dt.strftime("%H-%M") + key_name = "{}:{}".format(current_minute, model) + _response = await self.cache.async_get_cache(key=key_name) + response: Optional[int] = None + if _response is not None: + response = len(_response) return response - async def async_increment_cache(self, model: str, value: int): - key_name = "{}".format(model) - await self.cache.async_increment_cache(key=key_name, value=value, ttl=self.ttl) + async def async_set_cache_sadd(self, model: str, value: List): + """ + Add value to set. + + Parameters: + - model: str, the name of the model group + - value: str, the team id + + Returns: + - None + + Raises: + - Exception, if unable to connect to cache client (if redis caching enabled) + """ + dt = get_utc_datetime() + current_minute = dt.strftime("%H-%M") + + key_name = "{}:{}".format(current_minute, model) + await self.cache.async_set_cache_sadd(key=key_name, value=value, ttl=self.ttl) class _PROXY_DynamicRateLimitHandler(CustomLogger): @@ -47,13 +71,17 @@ class _PROXY_DynamicRateLimitHandler(CustomLogger): def update_variables(self, llm_router: Router): self.llm_router = llm_router - async def check_available_tpm(self, model: str) -> Optional[int]: + async def check_available_tpm( + self, model: str + ) -> Tuple[Optional[int], Optional[int], Optional[int]]: """ - For a given model, get it's available tpm + For a given model, get its available tpm Returns - - int: if number found - - None: if not found + - Tuple[available_tpm, model_tpm, active_projects] + - available_tpm: int or null + - model_tpm: int or null. If available tpm is int, then this will be too. + - active_projects: int or null """ active_projects = await self.internal_usage_cache.async_get_cache(model=model) model_group_info: Optional[ModelGroupInfo] = ( @@ -61,490 +89,60 @@ class _PROXY_DynamicRateLimitHandler(CustomLogger): ) available_tpm: Optional[int] = None + model_tpm: Optional[int] = None + if model_group_info is not None and model_group_info.tpm is not None: + model_tpm = model_group_info.tpm if active_projects is not None: available_tpm = int(model_group_info.tpm / active_projects) else: available_tpm = model_group_info.tpm - return available_tpm + return available_tpm, model_tpm, active_projects - # async def check_key_in_limits( - # self, - # user_api_key_dict: UserAPIKeyAuth, - # cache: DualCache, - # data: dict, - # call_type: str, - # max_parallel_requests: int, - # tpm_limit: int, - # rpm_limit: int, - # request_count_api_key: str, - # ): - # current = await self.internal_usage_cache.async_get_cache( - # key=request_count_api_key - # ) # {"current_requests": 1, "current_tpm": 1, "current_rpm": 10} - # if current is None: - # if max_parallel_requests == 0 or tpm_limit == 0 or rpm_limit == 0: - # # base case - # raise HTTPException( - # status_code=429, detail="Max parallel request limit reached." - # ) - # new_val = { - # "current_requests": 1, - # "current_tpm": 0, - # "current_rpm": 0, - # } - # await self.internal_usage_cache.async_set_cache( - # request_count_api_key, new_val - # ) - # elif ( - # int(current["current_requests"]) < max_parallel_requests - # and current["current_tpm"] < tpm_limit - # and current["current_rpm"] < rpm_limit - # ): - # # Increase count for this token - # new_val = { - # "current_requests": current["current_requests"] + 1, - # "current_tpm": current["current_tpm"], - # "current_rpm": current["current_rpm"], - # } - # await self.internal_usage_cache.async_set_cache( - # request_count_api_key, new_val - # ) - # else: - # raise HTTPException( - # status_code=429, - # detail=f"LiteLLM Rate Limit Handler: Crossed TPM, RPM Limit. current rpm: {current['current_rpm']}, rpm limit: {rpm_limit}, current tpm: {current['current_tpm']}, tpm limit: {tpm_limit}", - # ) - - # async def async_pre_call_hook( - # self, - # user_api_key_dict: UserAPIKeyAuth, - # cache: DualCache, - # data: dict, - # call_type: str, - # ): - # self.print_verbose("Inside Dynamic Rate Limit Handler Pre-Call Hook") - # api_key = user_api_key_dict.api_key - # max_parallel_requests = user_api_key_dict.max_parallel_requests - # if max_parallel_requests is None: - # max_parallel_requests = sys.maxsize - # global_max_parallel_requests = data.get("metadata", {}).get( - # "global_max_parallel_requests", None - # ) - # tpm_limit = getattr(user_api_key_dict, "tpm_limit", sys.maxsize) - # if tpm_limit is None: - # tpm_limit = sys.maxsize - # rpm_limit = getattr(user_api_key_dict, "rpm_limit", sys.maxsize) - # if rpm_limit is None: - # rpm_limit = sys.maxsize - - # # ------------ - # # Setup values - # # ------------ - - # if global_max_parallel_requests is not None: - # # get value from cache - # _key = "global_max_parallel_requests" - # current_global_requests = await self.internal_usage_cache.async_get_cache( - # key=_key, local_only=True - # ) - # # check if below limit - # if current_global_requests is None: - # current_global_requests = 1 - # # if above -> raise error - # if current_global_requests >= global_max_parallel_requests: - # raise HTTPException( - # status_code=429, detail="Max parallel request limit reached." - # ) - # # if below -> increment - # else: - # await self.internal_usage_cache.async_increment_cache( - # key=_key, value=1, local_only=True - # ) - - # current_date = datetime.now().strftime("%Y-%m-%d") - # current_hour = datetime.now().strftime("%H") - # current_minute = datetime.now().strftime("%M") - # precise_minute = f"{current_date}-{current_hour}-{current_minute}" - - # if api_key is not None: - # request_count_api_key = f"{api_key}::{precise_minute}::request_count" - - # # CHECK IF REQUEST ALLOWED for key - - # current = await self.internal_usage_cache.async_get_cache( - # key=request_count_api_key - # ) # {"current_requests": 1, "current_tpm": 1, "current_rpm": 10} - # self.print_verbose(f"current: {current}") - # if ( - # max_parallel_requests == sys.maxsize - # and tpm_limit == sys.maxsize - # and rpm_limit == sys.maxsize - # ): - # pass - # elif max_parallel_requests == 0 or tpm_limit == 0 or rpm_limit == 0: - # raise HTTPException( - # status_code=429, detail="Max parallel request limit reached." - # ) - # elif current is None: - # new_val = { - # "current_requests": 1, - # "current_tpm": 0, - # "current_rpm": 0, - # } - # await self.internal_usage_cache.async_set_cache( - # request_count_api_key, new_val - # ) - # elif ( - # int(current["current_requests"]) < max_parallel_requests - # and current["current_tpm"] < tpm_limit - # and current["current_rpm"] < rpm_limit - # ): - # # Increase count for this token - # new_val = { - # "current_requests": current["current_requests"] + 1, - # "current_tpm": current["current_tpm"], - # "current_rpm": current["current_rpm"], - # } - # await self.internal_usage_cache.async_set_cache( - # request_count_api_key, new_val - # ) - # else: - # raise HTTPException( - # status_code=429, detail="Max parallel request limit reached." - # ) - - # # check if REQUEST ALLOWED for user_id - # user_id = user_api_key_dict.user_id - # if user_id is not None: - # _user_id_rate_limits = await self.internal_usage_cache.async_get_cache( - # key=user_id - # ) - # # get user tpm/rpm limits - # if _user_id_rate_limits is not None and isinstance( - # _user_id_rate_limits, dict - # ): - # user_tpm_limit = _user_id_rate_limits.get("tpm_limit", None) - # user_rpm_limit = _user_id_rate_limits.get("rpm_limit", None) - # if user_tpm_limit is None: - # user_tpm_limit = sys.maxsize - # if user_rpm_limit is None: - # user_rpm_limit = sys.maxsize - - # # now do the same tpm/rpm checks - # request_count_api_key = f"{user_id}::{precise_minute}::request_count" - - # # print(f"Checking if {request_count_api_key} is allowed to make request for minute {precise_minute}") - # await self.check_key_in_limits( - # user_api_key_dict=user_api_key_dict, - # cache=cache, - # data=data, - # call_type=call_type, - # max_parallel_requests=sys.maxsize, # TODO: Support max parallel requests for a user - # request_count_api_key=request_count_api_key, - # tpm_limit=user_tpm_limit, - # rpm_limit=user_rpm_limit, - # ) - - # # TEAM RATE LIMITS - # ## get team tpm/rpm limits - # team_id = user_api_key_dict.team_id - # if team_id is not None: - # team_tpm_limit = user_api_key_dict.team_tpm_limit - # team_rpm_limit = user_api_key_dict.team_rpm_limit - - # if team_tpm_limit is None: - # team_tpm_limit = sys.maxsize - # if team_rpm_limit is None: - # team_rpm_limit = sys.maxsize - - # # now do the same tpm/rpm checks - # request_count_api_key = f"{team_id}::{precise_minute}::request_count" - - # # print(f"Checking if {request_count_api_key} is allowed to make request for minute {precise_minute}") - # await self.check_key_in_limits( - # user_api_key_dict=user_api_key_dict, - # cache=cache, - # data=data, - # call_type=call_type, - # max_parallel_requests=sys.maxsize, # TODO: Support max parallel requests for a team - # request_count_api_key=request_count_api_key, - # tpm_limit=team_tpm_limit, - # rpm_limit=team_rpm_limit, - # ) - - # # End-User Rate Limits - # # Only enforce if user passed `user` to /chat, /completions, /embeddings - # if user_api_key_dict.end_user_id: - # end_user_tpm_limit = getattr( - # user_api_key_dict, "end_user_tpm_limit", sys.maxsize - # ) - # end_user_rpm_limit = getattr( - # user_api_key_dict, "end_user_rpm_limit", sys.maxsize - # ) - - # if end_user_tpm_limit is None: - # end_user_tpm_limit = sys.maxsize - # if end_user_rpm_limit is None: - # end_user_rpm_limit = sys.maxsize - - # # now do the same tpm/rpm checks - # request_count_api_key = ( - # f"{user_api_key_dict.end_user_id}::{precise_minute}::request_count" - # ) - - # # print(f"Checking if {request_count_api_key} is allowed to make request for minute {precise_minute}") - # await self.check_key_in_limits( - # user_api_key_dict=user_api_key_dict, - # cache=cache, - # data=data, - # call_type=call_type, - # max_parallel_requests=sys.maxsize, # TODO: Support max parallel requests for an End-User - # request_count_api_key=request_count_api_key, - # tpm_limit=end_user_tpm_limit, - # rpm_limit=end_user_rpm_limit, - # ) - - # return - - # async def async_log_success_event(self, kwargs, response_obj, start_time, end_time): - # try: - # self.print_verbose("INSIDE parallel request limiter ASYNC SUCCESS LOGGING") - # global_max_parallel_requests = kwargs["litellm_params"]["metadata"].get( - # "global_max_parallel_requests", None - # ) - # user_api_key = kwargs["litellm_params"]["metadata"]["user_api_key"] - # user_api_key_user_id = kwargs["litellm_params"]["metadata"].get( - # "user_api_key_user_id", None - # ) - # user_api_key_team_id = kwargs["litellm_params"]["metadata"].get( - # "user_api_key_team_id", None - # ) - # user_api_key_end_user_id = kwargs.get("user") - - # # ------------ - # # Setup values - # # ------------ - - # if global_max_parallel_requests is not None: - # # get value from cache - # _key = "global_max_parallel_requests" - # # decrement - # await self.internal_usage_cache.async_increment_cache( - # key=_key, value=-1, local_only=True - # ) - - # current_date = datetime.now().strftime("%Y-%m-%d") - # current_hour = datetime.now().strftime("%H") - # current_minute = datetime.now().strftime("%M") - # precise_minute = f"{current_date}-{current_hour}-{current_minute}" - - # total_tokens = 0 - - # if isinstance(response_obj, ModelResponse): - # total_tokens = response_obj.usage.total_tokens - - # # ------------ - # # Update usage - API Key - # # ------------ - - # if user_api_key is not None: - # request_count_api_key = ( - # f"{user_api_key}::{precise_minute}::request_count" - # ) - - # current = await self.internal_usage_cache.async_get_cache( - # key=request_count_api_key - # ) or { - # "current_requests": 1, - # "current_tpm": total_tokens, - # "current_rpm": 1, - # } - - # new_val = { - # "current_requests": max(current["current_requests"] - 1, 0), - # "current_tpm": current["current_tpm"] + total_tokens, - # "current_rpm": current["current_rpm"] + 1, - # } - - # self.print_verbose( - # f"updated_value in success call: {new_val}, precise_minute: {precise_minute}" - # ) - # await self.internal_usage_cache.async_set_cache( - # request_count_api_key, new_val, ttl=60 - # ) # store in cache for 1 min. - - # # ------------ - # # Update usage - User - # # ------------ - # if user_api_key_user_id is not None: - # total_tokens = 0 - - # if isinstance(response_obj, ModelResponse): - # total_tokens = response_obj.usage.total_tokens - - # request_count_api_key = ( - # f"{user_api_key_user_id}::{precise_minute}::request_count" - # ) - - # current = await self.internal_usage_cache.async_get_cache( - # key=request_count_api_key - # ) or { - # "current_requests": 1, - # "current_tpm": total_tokens, - # "current_rpm": 1, - # } - - # new_val = { - # "current_requests": max(current["current_requests"] - 1, 0), - # "current_tpm": current["current_tpm"] + total_tokens, - # "current_rpm": current["current_rpm"] + 1, - # } - - # self.print_verbose( - # f"updated_value in success call: {new_val}, precise_minute: {precise_minute}" - # ) - # await self.internal_usage_cache.async_set_cache( - # request_count_api_key, new_val, ttl=60 - # ) # store in cache for 1 min. - - # # ------------ - # # Update usage - Team - # # ------------ - # if user_api_key_team_id is not None: - # total_tokens = 0 - - # if isinstance(response_obj, ModelResponse): - # total_tokens = response_obj.usage.total_tokens - - # request_count_api_key = ( - # f"{user_api_key_team_id}::{precise_minute}::request_count" - # ) - - # current = await self.internal_usage_cache.async_get_cache( - # key=request_count_api_key - # ) or { - # "current_requests": 1, - # "current_tpm": total_tokens, - # "current_rpm": 1, - # } - - # new_val = { - # "current_requests": max(current["current_requests"] - 1, 0), - # "current_tpm": current["current_tpm"] + total_tokens, - # "current_rpm": current["current_rpm"] + 1, - # } - - # self.print_verbose( - # f"updated_value in success call: {new_val}, precise_minute: {precise_minute}" - # ) - # await self.internal_usage_cache.async_set_cache( - # request_count_api_key, new_val, ttl=60 - # ) # store in cache for 1 min. - - # # ------------ - # # Update usage - End User - # # ------------ - # if user_api_key_end_user_id is not None: - # total_tokens = 0 - - # if isinstance(response_obj, ModelResponse): - # total_tokens = response_obj.usage.total_tokens - - # request_count_api_key = ( - # f"{user_api_key_end_user_id}::{precise_minute}::request_count" - # ) - - # current = await self.internal_usage_cache.async_get_cache( - # key=request_count_api_key - # ) or { - # "current_requests": 1, - # "current_tpm": total_tokens, - # "current_rpm": 1, - # } - - # new_val = { - # "current_requests": max(current["current_requests"] - 1, 0), - # "current_tpm": current["current_tpm"] + total_tokens, - # "current_rpm": current["current_rpm"] + 1, - # } - - # self.print_verbose( - # f"updated_value in success call: {new_val}, precise_minute: {precise_minute}" - # ) - # await self.internal_usage_cache.async_set_cache( - # request_count_api_key, new_val, ttl=60 - # ) # store in cache for 1 min. - - # except Exception as e: - # self.print_verbose(e) # noqa - - # async def async_log_failure_event(self, kwargs, response_obj, start_time, end_time): - # try: - # self.print_verbose(f"Inside Max Parallel Request Failure Hook") - # global_max_parallel_requests = kwargs["litellm_params"]["metadata"].get( - # "global_max_parallel_requests", None - # ) - # user_api_key = ( - # kwargs["litellm_params"].get("metadata", {}).get("user_api_key", None) - # ) - # self.print_verbose(f"user_api_key: {user_api_key}") - # if user_api_key is None: - # return - - # ## decrement call count if call failed - # if "Max parallel request limit reached" in str(kwargs["exception"]): - # pass # ignore failed calls due to max limit being reached - # else: - # # ------------ - # # Setup values - # # ------------ - - # if global_max_parallel_requests is not None: - # # get value from cache - # _key = "global_max_parallel_requests" - # current_global_requests = ( - # await self.internal_usage_cache.async_get_cache( - # key=_key, local_only=True - # ) - # ) - # # decrement - # await self.internal_usage_cache.async_increment_cache( - # key=_key, value=-1, local_only=True - # ) - - # current_date = datetime.now().strftime("%Y-%m-%d") - # current_hour = datetime.now().strftime("%H") - # current_minute = datetime.now().strftime("%M") - # precise_minute = f"{current_date}-{current_hour}-{current_minute}" - - # request_count_api_key = ( - # f"{user_api_key}::{precise_minute}::request_count" - # ) - - # # ------------ - # # Update usage - # # ------------ - # current = await self.internal_usage_cache.async_get_cache( - # key=request_count_api_key - # ) or { - # "current_requests": 1, - # "current_tpm": 0, - # "current_rpm": 0, - # } - - # new_val = { - # "current_requests": max(current["current_requests"] - 1, 0), - # "current_tpm": current["current_tpm"], - # "current_rpm": current["current_rpm"], - # } - - # self.print_verbose(f"updated_value in failure call: {new_val}") - # await self.internal_usage_cache.async_set_cache( - # request_count_api_key, new_val, ttl=60 - # ) # save in cache for up to 1 min. - # except Exception as e: - # verbose_proxy_logger.info( - # f"Inside Parallel Request Limiter: An exception occurred - {str(e)}." - # ) + async def async_pre_call_hook( + self, + user_api_key_dict: UserAPIKeyAuth, + cache: DualCache, + data: dict, + call_type: Literal[ + "completion", + "text_completion", + "embeddings", + "image_generation", + "moderation", + "audio_transcription", + ], + ) -> Optional[ + Union[Exception, str, dict] + ]: # raise exception if invalid, return a str for the user to receive - if rejected, or return a modified dictionary for passing into litellm + """ + - For a model group + - Check if tpm available + - Raise RateLimitError if no tpm available + """ + if "model" in data: + available_tpm, model_tpm, active_projects = await self.check_available_tpm( + model=data["model"] + ) + if available_tpm is not None and available_tpm == 0: + raise HTTPException( + status_code=429, + detail={ + "error": "Team={} over available TPM={}. Model TPM={}, Active teams={}".format( + user_api_key_dict.team_id, + available_tpm, + model_tpm, + active_projects, + ) + }, + ) + elif available_tpm is not None: + ## UPDATE CACHE WITH ACTIVE PROJECT + asyncio.create_task( + self.internal_usage_cache.async_set_cache_sadd( + model=data["model"], # type: ignore + value=[user_api_key_dict.team_id or "default_team"], + ) + ) + return None diff --git a/litellm/tests/test_dynamic_rate_limit_handler.py b/litellm/tests/test_dynamic_rate_limit_handler.py index 1efe6ef260d..71e3ac5359b 100644 --- a/litellm/tests/test_dynamic_rate_limit_handler.py +++ b/litellm/tests/test_dynamic_rate_limit_handler.py @@ -6,6 +6,7 @@ import random import sys import time import traceback +import uuid from datetime import datetime from typing import Tuple @@ -44,8 +45,10 @@ def dynamic_rate_limit_handler() -> DynamicRateLimitHandler: async def test_available_tpm(num_projects, dynamic_rate_limit_handler): model = "my-fake-model" ## SET CACHE W/ ACTIVE PROJECTS - await dynamic_rate_limit_handler.internal_usage_cache.async_increment_cache( - model=model, value=num_projects + projects = [str(uuid.uuid4()) for _ in range(num_projects)] + + await dynamic_rate_limit_handler.internal_usage_cache.async_set_cache_sadd( + model=model, value=projects ) model_tpm = 100 @@ -66,7 +69,9 @@ async def test_available_tpm(num_projects, dynamic_rate_limit_handler): ## CHECK AVAILABLE TPM PER PROJECT - availability = await dynamic_rate_limit_handler.check_available_tpm(model=model) + availability, _, _ = await dynamic_rate_limit_handler.check_available_tpm( + model=model + ) expected_availability = int(model_tpm / num_projects) From 068e8dff5b7007191bf823b9ef4dae65f6c72784 Mon Sep 17 00:00:00 2001 From: Krrish Dholakia Date: Fri, 21 Jun 2024 22:46:46 -0700 Subject: [PATCH 03/22] feat(dynamic_rate_limiter.py): passing base case --- litellm/main.py | 5 +- litellm/proxy/hooks/dynamic_rate_limiter.py | 25 +++-- litellm/router.py | 101 +++++++++++++++++- .../tests/test_dynamic_rate_limit_handler.py | 98 ++++++++++++++++- litellm/tests/test_router.py | 93 ++++++++++++++++ 5 files changed, 310 insertions(+), 12 deletions(-) diff --git a/litellm/main.py b/litellm/main.py index a76ef64a13f..307659c8a2f 100644 --- a/litellm/main.py +++ b/litellm/main.py @@ -428,7 +428,7 @@ def mock_completion( model: str, messages: List, stream: Optional[bool] = False, - mock_response: Union[str, Exception] = "This is a mock request", + mock_response: Union[str, Exception, dict] = "This is a mock request", mock_tool_calls: Optional[List] = None, logging=None, custom_llm_provider=None, @@ -477,6 +477,9 @@ def mock_completion( if time_delay is not None: time.sleep(time_delay) + if isinstance(mock_response, dict): + return ModelResponse(**mock_response) + model_response = ModelResponse(stream=stream) if stream is True: # don't try to access stream object, diff --git a/litellm/proxy/hooks/dynamic_rate_limiter.py b/litellm/proxy/hooks/dynamic_rate_limiter.py index dc29597f6ea..dfe96321555 100644 --- a/litellm/proxy/hooks/dynamic_rate_limiter.py +++ b/litellm/proxy/hooks/dynamic_rate_limiter.py @@ -80,25 +80,35 @@ class _PROXY_DynamicRateLimitHandler(CustomLogger): Returns - Tuple[available_tpm, model_tpm, active_projects] - available_tpm: int or null - - model_tpm: int or null. If available tpm is int, then this will be too. + - remaining_model_tpm: int or null. If available tpm is int, then this will be too. - active_projects: int or null """ active_projects = await self.internal_usage_cache.async_get_cache(model=model) + current_model_tpm: Optional[int] = await self.llm_router.get_model_group_usage( + model_group=model + ) model_group_info: Optional[ModelGroupInfo] = ( self.llm_router.get_model_group_info(model_group=model) ) + total_model_tpm: Optional[int] = None + if model_group_info is not None and model_group_info.tpm is not None: + total_model_tpm = model_group_info.tpm + + remaining_model_tpm: Optional[int] = None + if total_model_tpm is not None and current_model_tpm is not None: + remaining_model_tpm = total_model_tpm - current_model_tpm + elif total_model_tpm is not None: + remaining_model_tpm = total_model_tpm available_tpm: Optional[int] = None - model_tpm: Optional[int] = None - if model_group_info is not None and model_group_info.tpm is not None: - model_tpm = model_group_info.tpm + if remaining_model_tpm is not None: if active_projects is not None: - available_tpm = int(model_group_info.tpm / active_projects) + available_tpm = int(remaining_model_tpm / active_projects) else: - available_tpm = model_group_info.tpm + available_tpm = remaining_model_tpm - return available_tpm, model_tpm, active_projects + return available_tpm, remaining_model_tpm, active_projects async def async_pre_call_hook( self, @@ -121,6 +131,7 @@ class _PROXY_DynamicRateLimitHandler(CustomLogger): - Check if tpm available - Raise RateLimitError if no tpm available """ + if "model" in data: available_tpm, model_tpm, active_projects = await self.check_available_tpm( model=data["model"] diff --git a/litellm/router.py b/litellm/router.py index 87890ebffcd..9f0884ab809 100644 --- a/litellm/router.py +++ b/litellm/router.py @@ -11,6 +11,7 @@ import asyncio import concurrent import copy import datetime as datetime_og +import enum import hashlib import inspect import json @@ -90,6 +91,10 @@ from litellm.utils import ( ) +class RoutingArgs(enum.Enum): + ttl = 60 # 1min (RPM/TPM expire key) + + class Router: model_names: List = [] cache_responses: Optional[bool] = False @@ -387,6 +392,11 @@ class Router: routing_strategy=routing_strategy, routing_strategy_args=routing_strategy_args, ) + ## USAGE TRACKING ## + if isinstance(litellm._async_success_callback, list): + litellm._async_success_callback.append(self.deployment_callback_on_success) + else: + litellm._async_success_callback.append(self.deployment_callback_on_success) ## COOLDOWNS ## if isinstance(litellm.failure_callback, list): litellm.failure_callback.append(self.deployment_callback_on_failure) @@ -2636,13 +2646,69 @@ class Router: time.sleep(_timeout) if type(original_exception) in litellm.LITELLM_EXCEPTION_TYPES: - original_exception.max_retries = num_retries - original_exception.num_retries = current_attempt + setattr(original_exception, "max_retries", num_retries) + setattr(original_exception, "num_retries", current_attempt) raise original_exception ### HELPER FUNCTIONS + async def deployment_callback_on_success( + self, + kwargs, # kwargs to completion + completion_response, # response from completion + start_time, + end_time, # start/end time + ): + """ + Track remaining tpm/rpm quota for model in model_list + """ + try: + """ + Update TPM usage on success + """ + if kwargs["litellm_params"].get("metadata") is None: + pass + else: + model_group = kwargs["litellm_params"]["metadata"].get( + "model_group", None + ) + + id = kwargs["litellm_params"].get("model_info", {}).get("id", None) + if model_group is None or id is None: + return + elif isinstance(id, int): + id = str(id) + + total_tokens = completion_response["usage"]["total_tokens"] + + # ------------ + # Setup values + # ------------ + dt = get_utc_datetime() + current_minute = dt.strftime( + "%H-%M" + ) # use the same timezone regardless of system clock + + tpm_key = f"global_router:{id}:tpm:{current_minute}" + # ------------ + # Update usage + # ------------ + # update cache + + ## TPM + await self.cache.async_increment_cache( + key=tpm_key, value=total_tokens, ttl=RoutingArgs.ttl.value + ) + + except Exception as e: + verbose_router_logger.error( + "litellm.proxy.hooks.prompt_injection_detection.py::async_pre_call_hook(): Exception occured - {}\n{}".format( + str(e), traceback.format_exc() + ) + ) + pass + def deployment_callback_on_failure( self, kwargs, # kwargs to completion @@ -3963,6 +4029,35 @@ class Router: return model_group_info + async def get_model_group_usage(self, model_group: str) -> Optional[int]: + """ + Returns remaining tpm quota for model group + """ + dt = get_utc_datetime() + current_minute = dt.strftime( + "%H-%M" + ) # use the same timezone regardless of system clock + tpm_keys: List[str] = [] + for model in self.model_list: + if "model_name" in model and model["model_name"] == model_group: + tpm_keys.append( + f"global_router:{model['model_info']['id']}:tpm:{current_minute}" + ) + + ## TPM + tpm_usage_list: Optional[List] = await self.cache.async_batch_get_cache( + keys=tpm_keys + ) + tpm_usage: Optional[int] = None + if tpm_usage_list is not None: + for t in tpm_usage_list: + if isinstance(t, int): + if tpm_usage is None: + tpm_usage = 0 + tpm_usage += t + + return tpm_usage + def get_model_ids(self) -> List[str]: """ Returns list of model id's. @@ -4890,7 +4985,7 @@ class Router: def reset(self): ## clean up on close litellm.success_callback = [] - litellm.__async_success_callback = [] + litellm._async_success_callback = [] litellm.failure_callback = [] litellm._async_failure_callback = [] self.retry_policy = None diff --git a/litellm/tests/test_dynamic_rate_limit_handler.py b/litellm/tests/test_dynamic_rate_limit_handler.py index 71e3ac5359b..df9e2588106 100644 --- a/litellm/tests/test_dynamic_rate_limit_handler.py +++ b/litellm/tests/test_dynamic_rate_limit_handler.py @@ -8,7 +8,7 @@ import time import traceback import uuid from datetime import datetime -from typing import Tuple +from typing import Optional, Tuple from dotenv import load_dotenv @@ -40,6 +40,40 @@ def dynamic_rate_limit_handler() -> DynamicRateLimitHandler: return DynamicRateLimitHandler(internal_usage_cache=internal_cache) +@pytest.fixture +def mock_response() -> litellm.ModelResponse: + return litellm.ModelResponse( + **{ + "id": "chatcmpl-abc123", + "object": "chat.completion", + "created": 1699896916, + "model": "gpt-3.5-turbo-0125", + "choices": [ + { + "index": 0, + "message": { + "role": "assistant", + "content": None, + "tool_calls": [ + { + "id": "call_abc123", + "type": "function", + "function": { + "name": "get_current_weather", + "arguments": '{\n"location": "Boston, MA"\n}', + }, + } + ], + }, + "logprobs": None, + "finish_reason": "tool_calls", + } + ], + "usage": {"prompt_tokens": 5, "completion_tokens": 5, "total_tokens": 10}, + } + ) + + @pytest.mark.parametrize("num_projects", [1, 2, 100]) @pytest.mark.asyncio async def test_available_tpm(num_projects, dynamic_rate_limit_handler): @@ -76,3 +110,65 @@ async def test_available_tpm(num_projects, dynamic_rate_limit_handler): expected_availability = int(model_tpm / num_projects) assert availability == expected_availability + + +@pytest.mark.asyncio +async def test_base_case(dynamic_rate_limit_handler, mock_response): + """ + If just 1 active project + + it should get all the quota + + = allow request to go through + - update token usage + - exhaust all tpm with just 1 project + """ + model = "my-fake-model" + model_tpm = 50 + setattr( + mock_response, + "usage", + litellm.Usage(prompt_tokens=5, completion_tokens=5, total_tokens=10), + ) + + llm_router = Router( + model_list=[ + { + "model_name": model, + "litellm_params": { + "model": "gpt-3.5-turbo", + "api_key": "my-key", + "api_base": "my-base", + "tpm": model_tpm, + "mock_response": mock_response, + }, + } + ] + ) + dynamic_rate_limit_handler.update_variables(llm_router=llm_router) + + prev_availability: Optional[int] = None + for _ in range(5): + # check availability + availability, _, _ = await dynamic_rate_limit_handler.check_available_tpm( + model=model + ) + + ## assert availability updated + if prev_availability is not None and availability is not None: + assert availability == prev_availability - 10 + + print( + "prev_availability={}, availability={}".format( + prev_availability, availability + ) + ) + + prev_availability = availability + + # make call + await llm_router.acompletion( + model=model, messages=[{"role": "user", "content": "hey!"}] + ) + + await asyncio.sleep(3) diff --git a/litellm/tests/test_router.py b/litellm/tests/test_router.py index d2037dc59e3..55cf250e745 100644 --- a/litellm/tests/test_router.py +++ b/litellm/tests/test_router.py @@ -1730,3 +1730,96 @@ async def test_router_text_completion_client(): print(responses) except Exception as e: pytest.fail(f"Error occurred: {e}") + + +@pytest.fixture +def mock_response() -> litellm.ModelResponse: + return litellm.ModelResponse( + **{ + "id": "chatcmpl-abc123", + "object": "chat.completion", + "created": 1699896916, + "model": "gpt-3.5-turbo-0125", + "choices": [ + { + "index": 0, + "message": { + "role": "assistant", + "content": None, + "tool_calls": [ + { + "id": "call_abc123", + "type": "function", + "function": { + "name": "get_current_weather", + "arguments": '{\n"location": "Boston, MA"\n}', + }, + } + ], + }, + "logprobs": None, + "finish_reason": "tool_calls", + } + ], + "usage": {"prompt_tokens": 5, "completion_tokens": 5, "total_tokens": 10}, + } + ) + + +@pytest.mark.asyncio +async def test_router_model_usage(mock_response): + model = "my-fake-model" + model_tpm = 100 + setattr( + mock_response, + "usage", + litellm.Usage(prompt_tokens=5, completion_tokens=5, total_tokens=10), + ) + + print(f"mock_response: {mock_response}") + model_tpm = 100 + llm_router = Router( + model_list=[ + { + "model_name": model, + "litellm_params": { + "model": "gpt-3.5-turbo", + "api_key": "my-key", + "api_base": "my-base", + "tpm": model_tpm, + "mock_response": mock_response, + }, + } + ] + ) + + allowed_fails = 1 # allow for changing b/w minutes + + for _ in range(2): + try: + _ = await llm_router.acompletion( + model=model, messages=[{"role": "user", "content": "Hey!"}] + ) + await asyncio.sleep(3) + + initial_usage = await llm_router.get_model_group_usage(model_group=model) + + # completion call - 10 tokens + _ = await llm_router.acompletion( + model=model, messages=[{"role": "user", "content": "Hey!"}] + ) + + await asyncio.sleep(3) + updated_usage = await llm_router.get_model_group_usage(model_group=model) + + assert updated_usage == initial_usage + 10 # type: ignore + break + except Exception as e: + if allowed_fails > 0: + print( + f"Decrementing allowed_fails: {allowed_fails}.\nReceived error - {str(e)}" + ) + allowed_fails -= 1 + else: + print(f"allowed_fails: {allowed_fails}") + raise e From 532f24bfb78c2aeb2ca0b89853c9cdf01afa3478 Mon Sep 17 00:00:00 2001 From: Krrish Dholakia Date: Sat, 22 Jun 2024 00:32:29 -0700 Subject: [PATCH 04/22] refactor: instrument 'dynamic_rate_limiting' callback on proxy --- docs/my-website/docs/proxy/team_budgets.md | 37 +++++++++++ litellm/__init__.py | 4 +- litellm/litellm_core_utils/litellm_logging.py | 63 ++++++++++++++++++- litellm/proxy/_super_secret_config.yaml | 3 +- litellm/proxy/hooks/dynamic_rate_limiter.py | 1 - litellm/proxy/proxy_server.py | 9 +-- litellm/proxy/utils.py | 42 ++++++++----- litellm/utils.py | 5 +- 8 files changed, 136 insertions(+), 28 deletions(-) diff --git a/docs/my-website/docs/proxy/team_budgets.md b/docs/my-website/docs/proxy/team_budgets.md index 9bfcb35d4c6..d7f6d7fdc9c 100644 --- a/docs/my-website/docs/proxy/team_budgets.md +++ b/docs/my-website/docs/proxy/team_budgets.md @@ -152,3 +152,40 @@ litellm_remaining_team_budget_metric{team_alias="QA Prod Bot",team_id="de35b29e- ``` +### Dynamic TPM Allocation + +Prevent teams from gobbling too much quota. + +1. Setup config.yaml + +```yaml +model_list: + - model_name: my-fake-model + litellm_params: + model: gpt-3.5-turbo + api_key: my-fake-key + mock_response: hello-world + tpm: 60 + +general_settings: + callbacks: ["dynamic_rate_limiting"] +``` + +2. Start proxy + +```bash +litellm --config /path/to/config.yaml +``` + +3. Test it! + +```python +""" +- Run 2 concurrent teams calling same model +- model has 60 TPM +- Mock response returns 30 total tokens / request +- Each team will only be able to make 1 request per minute +""" + + +``` \ No newline at end of file diff --git a/litellm/__init__.py b/litellm/__init__.py index a191d46bfdb..09bc0ab5ff5 100644 --- a/litellm/__init__.py +++ b/litellm/__init__.py @@ -37,7 +37,9 @@ input_callback: List[Union[str, Callable]] = [] success_callback: List[Union[str, Callable]] = [] failure_callback: List[Union[str, Callable]] = [] service_callback: List[Union[str, Callable]] = [] -_custom_logger_compatible_callbacks_literal = Literal["lago", "openmeter", "logfire"] +_custom_logger_compatible_callbacks_literal = Literal[ + "lago", "openmeter", "logfire", "dynamic_rate_limiter" +] callbacks: List[Union[Callable, _custom_logger_compatible_callbacks_literal]] = [] _langfuse_default_tags: Optional[ List[ diff --git a/litellm/litellm_core_utils/litellm_logging.py b/litellm/litellm_core_utils/litellm_logging.py index 64e8dbfc9c3..ad92140ee3d 100644 --- a/litellm/litellm_core_utils/litellm_logging.py +++ b/litellm/litellm_core_utils/litellm_logging.py @@ -19,7 +19,7 @@ from litellm import ( turn_off_message_logging, verbose_logger, ) -from litellm.caching import S3Cache +from litellm.caching import DualCache, S3Cache from litellm.integrations.custom_logger import CustomLogger from litellm.litellm_core_utils.redact_messages import ( redact_message_input_output_from_logging, @@ -1840,7 +1840,11 @@ def set_callbacks(callback_list, function_id=None): def _init_custom_logger_compatible_class( logging_integration: litellm._custom_logger_compatible_callbacks_literal, -) -> Callable: + internal_usage_cache: Optional[DualCache], + llm_router: Optional[ + Any + ], # expect litellm.Router, but typing errors due to circular import +) -> CustomLogger: if logging_integration == "lago": for callback in _in_memory_loggers: if isinstance(callback, LagoLogger): @@ -1876,3 +1880,58 @@ def _init_custom_logger_compatible_class( _otel_logger = OpenTelemetry(config=otel_config) _in_memory_loggers.append(_otel_logger) return _otel_logger # type: ignore + elif logging_integration == "dynamic_rate_limiter": + from litellm.proxy.hooks.dynamic_rate_limiter import ( + _PROXY_DynamicRateLimitHandler, + ) + + for callback in _in_memory_loggers: + if isinstance(callback, _PROXY_DynamicRateLimitHandler): + return callback # type: ignore + + if internal_usage_cache is None: + raise Exception( + "Internal Error: Cache cannot be empty - internal_usage_cache={}".format( + internal_usage_cache + ) + ) + + dynamic_rate_limiter_obj = _PROXY_DynamicRateLimitHandler( + internal_usage_cache=internal_usage_cache + ) + + if llm_router is not None and isinstance(llm_router, litellm.Router): + dynamic_rate_limiter_obj.update_variables(llm_router=llm_router) + _in_memory_loggers.append(dynamic_rate_limiter_obj) + return dynamic_rate_limiter_obj # type: ignore + + +def get_custom_logger_compatible_class( + logging_integration: litellm._custom_logger_compatible_callbacks_literal, +) -> Optional[CustomLogger]: + if logging_integration == "lago": + for callback in _in_memory_loggers: + if isinstance(callback, LagoLogger): + return callback + elif logging_integration == "openmeter": + for callback in _in_memory_loggers: + if isinstance(callback, OpenMeterLogger): + return callback + elif logging_integration == "logfire": + if "LOGFIRE_TOKEN" not in os.environ: + raise ValueError("LOGFIRE_TOKEN not found in environment variables") + from litellm.integrations.opentelemetry import OpenTelemetry + + for callback in _in_memory_loggers: + if isinstance(callback, OpenTelemetry): + return callback # type: ignore + + elif logging_integration == "dynamic_rate_limiter": + from litellm.proxy.hooks.dynamic_rate_limiter import ( + _PROXY_DynamicRateLimitHandler, + ) + + for callback in _in_memory_loggers: + if isinstance(callback, _PROXY_DynamicRateLimitHandler): + return callback # type: ignore + return None diff --git a/litellm/proxy/_super_secret_config.yaml b/litellm/proxy/_super_secret_config.yaml index ac0aaca5c78..ef88f75f613 100644 --- a/litellm/proxy/_super_secret_config.yaml +++ b/litellm/proxy/_super_secret_config.yaml @@ -67,8 +67,7 @@ model_list: max_input_tokens: 80920 litellm_settings: - success_callback: ["langfuse"] - failure_callback: ["langfuse"] + callbacks: ["dynamic_rate_limiter"] # default_team_settings: # - team_id: proj1 # success_callback: ["langfuse"] diff --git a/litellm/proxy/hooks/dynamic_rate_limiter.py b/litellm/proxy/hooks/dynamic_rate_limiter.py index dfe96321555..c0511e30c82 100644 --- a/litellm/proxy/hooks/dynamic_rate_limiter.py +++ b/litellm/proxy/hooks/dynamic_rate_limiter.py @@ -131,7 +131,6 @@ class _PROXY_DynamicRateLimitHandler(CustomLogger): - Check if tpm available - Raise RateLimitError if no tpm available """ - if "model" in data: available_tpm, model_tpm, active_projects = await self.check_available_tpm( model=data["model"] diff --git a/litellm/proxy/proxy_server.py b/litellm/proxy/proxy_server.py index 8eac72629ad..b2eaea8f36a 100644 --- a/litellm/proxy/proxy_server.py +++ b/litellm/proxy/proxy_server.py @@ -2644,7 +2644,9 @@ async def startup_event(): redis_cache=redis_usage_cache ) # used by parallel request limiter for rate limiting keys across instances - proxy_logging_obj._init_litellm_callbacks() # INITIALIZE LITELLM CALLBACKS ON SERVER STARTUP <- do this to catch any logging errors on startup, not when calls are being made + proxy_logging_obj._init_litellm_callbacks( + llm_router=llm_router + ) # INITIALIZE LITELLM CALLBACKS ON SERVER STARTUP <- do this to catch any logging errors on startup, not when calls are being made if "daily_reports" in proxy_logging_obj.slack_alerting_instance.alert_types: asyncio.create_task( @@ -3116,11 +3118,10 @@ async def chat_completion( except Exception as e: data["litellm_status"] = "fail" # used for alerting verbose_proxy_logger.error( - "litellm.proxy.proxy_server.chat_completion(): Exception occured - {}".format( - get_error_message_str(e=e) + "litellm.proxy.proxy_server.chat_completion(): Exception occured - {}\n{}".format( + get_error_message_str(e=e), traceback.format_exc() ) ) - verbose_proxy_logger.debug(traceback.format_exc()) await proxy_logging_obj.post_call_failure_hook( user_api_key_dict=user_api_key_dict, original_exception=e, request_data=data ) diff --git a/litellm/proxy/utils.py b/litellm/proxy/utils.py index d1e1d3576f4..5acba95c2ef 100644 --- a/litellm/proxy/utils.py +++ b/litellm/proxy/utils.py @@ -229,31 +229,32 @@ class ProxyLogging: if redis_cache is not None: self.internal_usage_cache.redis_cache = redis_cache - def _init_litellm_callbacks(self): - print_verbose("INITIALIZING LITELLM CALLBACKS!") + def _init_litellm_callbacks(self, llm_router: Optional[litellm.Router] = None): self.service_logging_obj = ServiceLogging() - litellm.callbacks.append(self.max_parallel_request_limiter) - litellm.callbacks.append(self.max_budget_limiter) - litellm.callbacks.append(self.cache_control_check) - litellm.callbacks.append(self.service_logging_obj) + litellm.callbacks.append(self.max_parallel_request_limiter) # type: ignore + litellm.callbacks.append(self.max_budget_limiter) # type: ignore + litellm.callbacks.append(self.cache_control_check) # type: ignore + litellm.callbacks.append(self.service_logging_obj) # type: ignore litellm.success_callback.append( self.slack_alerting_instance.response_taking_too_long_callback ) for callback in litellm.callbacks: if isinstance(callback, str): - callback = litellm.litellm_core_utils.litellm_logging._init_custom_logger_compatible_class( - callback + callback = litellm.litellm_core_utils.litellm_logging._init_custom_logger_compatible_class( # type: ignore + callback, + internal_usage_cache=self.internal_usage_cache, + llm_router=llm_router, ) if callback not in litellm.input_callback: - litellm.input_callback.append(callback) + litellm.input_callback.append(callback) # type: ignore if callback not in litellm.success_callback: - litellm.success_callback.append(callback) + litellm.success_callback.append(callback) # type: ignore if callback not in litellm.failure_callback: - litellm.failure_callback.append(callback) + litellm.failure_callback.append(callback) # type: ignore if callback not in litellm._async_success_callback: - litellm._async_success_callback.append(callback) + litellm._async_success_callback.append(callback) # type: ignore if callback not in litellm._async_failure_callback: - litellm._async_failure_callback.append(callback) + litellm._async_failure_callback.append(callback) # type: ignore if ( len(litellm.input_callback) > 0 @@ -301,10 +302,19 @@ class ProxyLogging: try: for callback in litellm.callbacks: - if isinstance(callback, CustomLogger) and "async_pre_call_hook" in vars( - callback.__class__ + _callback: Optional[CustomLogger] = None + if isinstance(callback, str): + _callback = litellm.litellm_core_utils.litellm_logging.get_custom_logger_compatible_class( + callback + ) + else: + _callback = callback # type: ignore + if ( + _callback is not None + and isinstance(_callback, CustomLogger) + and "async_pre_call_hook" in vars(_callback.__class__) ): - response = await callback.async_pre_call_hook( + response = await _callback.async_pre_call_hook( user_api_key_dict=user_api_key_dict, cache=self.call_details["user_api_key_cache"], data=data, diff --git a/litellm/utils.py b/litellm/utils.py index 7a64200760e..b734ae465ad 100644 --- a/litellm/utils.py +++ b/litellm/utils.py @@ -340,14 +340,15 @@ def function_setup( ) try: global callback_list, add_breadcrumb, user_logger_fn, Logging + function_id = kwargs["id"] if "id" in kwargs else None if len(litellm.callbacks) > 0: for callback in litellm.callbacks: # check if callback is a string - e.g. "lago", "openmeter" if isinstance(callback, str): - callback = litellm.litellm_core_utils.litellm_logging._init_custom_logger_compatible_class( - callback + callback = litellm.litellm_core_utils.litellm_logging._init_custom_logger_compatible_class( # type: ignore + callback, internal_usage_cache=None, llm_router=None ) if any( isinstance(cb, type(callback)) From b2a1cadf8c722829d4af5b3017163c2eb7234175 Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Sat, 22 Jun 2024 08:19:17 -0700 Subject: [PATCH 05/22] test test_routes_on_litellm_proxy --- litellm/tests/test_proxy_routes.py | 52 ++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 litellm/tests/test_proxy_routes.py diff --git a/litellm/tests/test_proxy_routes.py b/litellm/tests/test_proxy_routes.py new file mode 100644 index 00000000000..6e3e9706e46 --- /dev/null +++ b/litellm/tests/test_proxy_routes.py @@ -0,0 +1,52 @@ +import os +import sys + +from dotenv import load_dotenv + +load_dotenv() +import io +import os + +# this file is to test litellm/proxy + +sys.path.insert( + 0, os.path.abspath("../..") +) # Adds the parent directory to the system path +import asyncio +import logging + +import pytest + +import litellm +from litellm.proxy._types import LiteLLMRoutes +from litellm.proxy.proxy_server import router + +# Configure logging +logging.basicConfig( + level=logging.DEBUG, # Set the desired logging level + format="%(asctime)s - %(levelname)s - %(message)s", +) + + +def test_routes_on_litellm_proxy(): + """ + Goal of this test: Test that we have all the critical OpenAI Routes on the Proxy server Fast API router + + + this prevents accidentelly deleting /threads, or /batches etc + """ + _all_routes = [] + for route in router.routes: + + _path_as_str = str(route.path) + if ":path" in _path_as_str: + # remove the :path + _path_as_str = _path_as_str.replace(":path", "") + _all_routes.append(_path_as_str) + + print("ALL ROUTES on LiteLLM Proxy:", _all_routes) + print("\n\n") + print("ALL OPENAI ROUTES:", LiteLLMRoutes.openai_routes.value) + + for route in LiteLLMRoutes.openai_routes.value: + assert route in _all_routes From 204f7725ee75b1749a9d526ce9a81e95f1702b39 Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Sat, 22 Jun 2024 08:47:43 -0700 Subject: [PATCH 06/22] ui - read jwts from cookie --- .../src/components/user_dashboard.tsx | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/ui/litellm-dashboard/src/components/user_dashboard.tsx b/ui/litellm-dashboard/src/components/user_dashboard.tsx index 5aa0c92dd53..ec66bcea0fa 100644 --- a/ui/litellm-dashboard/src/components/user_dashboard.tsx +++ b/ui/litellm-dashboard/src/components/user_dashboard.tsx @@ -24,6 +24,14 @@ type UserSpendData = { max_budget?: number | null; }; +function getCookie(name: string) { + console.log("COOKIES", document.cookie) + const cookieValue = document.cookie + .split('; ') + .find(row => row.startsWith(name + '=')); + return cookieValue ? cookieValue.split('=')[1] : null; +} + interface UserDashboardProps { userID: string | null; userRole: string | null; @@ -66,7 +74,8 @@ const UserDashboard: React.FC = ({ const viewSpend = searchParams.get("viewSpend"); const router = useRouter(); - const token = searchParams.get("token"); + const token = getCookie('token'); + const [accessToken, setAccessToken] = useState(null); const [teamSpend, setTeamSpend] = useState(null); const [userModels, setUserModels] = useState([]); From 03d1d9229d1bca36a410ded26e338c540e0daa73 Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Sat, 22 Jun 2024 08:50:26 -0700 Subject: [PATCH 07/22] ui - use cookies to return JWTs --- litellm/proxy/proxy_server.py | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/litellm/proxy/proxy_server.py b/litellm/proxy/proxy_server.py index 021b59e295f..f3aeaddf983 100644 --- a/litellm/proxy/proxy_server.py +++ b/litellm/proxy/proxy_server.py @@ -7514,8 +7514,10 @@ async def login(request: Request): "secret", algorithm="HS256", ) - litellm_dashboard_ui += "?userID=" + user_id + "&token=" + jwt_token - return RedirectResponse(url=litellm_dashboard_ui, status_code=303) + litellm_dashboard_ui += "?userID=" + user_id + redirect_response = RedirectResponse(url=litellm_dashboard_ui, status_code=303) + redirect_response.set_cookie(key="token", value=jwt_token) + return redirect_response elif _user_row is not None: """ When sharing invite links @@ -7576,8 +7578,12 @@ async def login(request: Request): "secret", algorithm="HS256", ) - litellm_dashboard_ui += "?userID=" + user_id + "&token=" + jwt_token - return RedirectResponse(url=litellm_dashboard_ui, status_code=303) + litellm_dashboard_ui += "?userID=" + user_id + redirect_response = RedirectResponse( + url=litellm_dashboard_ui, status_code=303 + ) + redirect_response.set_cookie(key="token", value=jwt_token) + return redirect_response else: raise ProxyException( message=f"Invalid credentials used to access UI. Passed in username: {username}, passed in password: {password}.\nNot valid credentials for {username}", @@ -8120,8 +8126,10 @@ async def auth_callback(request: Request): "secret", algorithm="HS256", ) - litellm_dashboard_ui += "?userID=" + user_id + "&token=" + jwt_token - return RedirectResponse(url=litellm_dashboard_ui) + litellm_dashboard_ui += "?userID=" + user_id + redirect_response = RedirectResponse(url=litellm_dashboard_ui, status_code=303) + redirect_response.set_cookie(key="token", value=jwt_token) + return redirect_response #### INVITATION MANAGEMENT #### From c86efa55a5620cef8fbc243919db596a338c662d Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Sat, 22 Jun 2024 08:58:31 -0700 Subject: [PATCH 08/22] use hash of master key encode the jwt --- litellm/proxy/proxy_server.py | 34 ++++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/litellm/proxy/proxy_server.py b/litellm/proxy/proxy_server.py index f3aeaddf983..630aa3f3e15 100644 --- a/litellm/proxy/proxy_server.py +++ b/litellm/proxy/proxy_server.py @@ -7502,6 +7502,12 @@ async def login(request: Request): litellm_dashboard_ui += "/ui/" import jwt + if litellm_master_key_hash is None: + raise HTTPException( + status_code=500, + detail={"error": "No master key set, please set LITELLM_MASTER_KEY"}, + ) + jwt_token = jwt.encode( { "user_id": user_id, @@ -7511,7 +7517,7 @@ async def login(request: Request): "login_method": "username_password", "premium_user": premium_user, }, - "secret", + litellm_master_key_hash, algorithm="HS256", ) litellm_dashboard_ui += "?userID=" + user_id @@ -7566,6 +7572,14 @@ async def login(request: Request): litellm_dashboard_ui += "/ui/" import jwt + if litellm_master_key_hash is None: + raise HTTPException( + status_code=500, + detail={ + "error": "No master key set, please set LITELLM_MASTER_KEY" + }, + ) + jwt_token = jwt.encode( { "user_id": user_id, @@ -7575,7 +7589,7 @@ async def login(request: Request): "login_method": "username_password", "premium_user": premium_user, }, - "secret", + litellm_master_key_hash, algorithm="HS256", ) litellm_dashboard_ui += "?userID=" + user_id @@ -7694,6 +7708,12 @@ async def onboarding(invite_link: str): litellm_dashboard_ui += "/ui/onboarding" import jwt + if litellm_master_key_hash is None: + raise HTTPException( + status_code=500, + detail={"error": "No master key set, please set LITELLM_MASTER_KEY"}, + ) + jwt_token = jwt.encode( { "user_id": user_obj.user_id, @@ -7703,7 +7723,7 @@ async def onboarding(invite_link: str): "login_method": "username_password", "premium_user": premium_user, }, - "secret", + litellm_master_key_hash, algorithm="HS256", ) @@ -8114,6 +8134,12 @@ async def auth_callback(request: Request): import jwt + if litellm_master_key_hash is None: + raise HTTPException( + status_code=500, + detail={"error": "No master key set, please set LITELLM_MASTER_KEY"}, + ) + jwt_token = jwt.encode( { "user_id": user_id, @@ -8123,7 +8149,7 @@ async def auth_callback(request: Request): "login_method": "sso", "premium_user": premium_user, }, - "secret", + litellm_master_key_hash, algorithm="HS256", ) litellm_dashboard_ui += "?userID=" + user_id From 066ed01d0f1894f0d171334331568306edf7a7a4 Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Sat, 22 Jun 2024 09:05:06 -0700 Subject: [PATCH 09/22] read token from cookie --- ui/litellm-dashboard/src/app/onboarding/page.tsx | 11 ++++++++++- ui/litellm-dashboard/src/app/page.tsx | 11 ++++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/ui/litellm-dashboard/src/app/onboarding/page.tsx b/ui/litellm-dashboard/src/app/onboarding/page.tsx index 44c37610cec..a31afb0f9e5 100644 --- a/ui/litellm-dashboard/src/app/onboarding/page.tsx +++ b/ui/litellm-dashboard/src/app/onboarding/page.tsx @@ -20,10 +20,19 @@ import { } from "@/components/networking"; import { jwtDecode } from "jwt-decode"; import { Form, Button as Button2, message } from "antd"; + +function getCookie(name: string) { + console.log("COOKIES", document.cookie) + const cookieValue = document.cookie + .split('; ') + .find(row => row.startsWith(name + '=')); + return cookieValue ? cookieValue.split('=')[1] : null; +} + export default function Onboarding() { const [form] = Form.useForm(); const searchParams = useSearchParams(); - const token = searchParams.get("token"); + const token = getCookie('token'); const inviteID = searchParams.get("id"); const [accessToken, setAccessToken] = useState(null); const [defaultUserEmail, setDefaultUserEmail] = useState(""); diff --git a/ui/litellm-dashboard/src/app/page.tsx b/ui/litellm-dashboard/src/app/page.tsx index ed9c98df7c6..41f0e8529b3 100644 --- a/ui/litellm-dashboard/src/app/page.tsx +++ b/ui/litellm-dashboard/src/app/page.tsx @@ -19,6 +19,15 @@ import CacheDashboard from "@/components/cache_dashboard"; import { jwtDecode } from "jwt-decode"; import { Typography } from "antd"; +function getCookie(name: string) { + console.log("COOKIES", document.cookie) + const cookieValue = document.cookie + .split('; ') + .find(row => row.startsWith(name + '=')); + return cookieValue ? cookieValue.split('=')[1] : null; +} + + function formatUserRole(userRole: string) { if (!userRole) { return "Undefined Role"; @@ -68,7 +77,7 @@ const CreateKeyPage = () => { const searchParams = useSearchParams(); const [modelData, setModelData] = useState({ data: [] }); const userID = searchParams.get("userID"); - const token = searchParams.get("token"); + const token = getCookie('token'); const [page, setPage] = useState("api-keys"); const [accessToken, setAccessToken] = useState(null); From c4f6b903b351aadac4c18f5629a974d122d9c50e Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Sat, 22 Jun 2024 09:13:34 -0700 Subject: [PATCH 10/22] ui - new build --- litellm/proxy/_experimental/out/404.html | 2 +- .../_buildManifest.js | 0 .../_ssgManifest.js | 0 .../static/chunks/app/onboarding/page-da04a591bae84617.js | 1 - .../static/chunks/app/onboarding/page-fd30ae439831db99.js | 1 + .../out/_next/static/chunks/app/page-42b04008af7da690.js | 1 + .../out/_next/static/chunks/app/page-5b9334558218205d.js | 1 - litellm/proxy/_experimental/out/index.html | 2 +- litellm/proxy/_experimental/out/index.txt | 4 ++-- litellm/proxy/_experimental/out/model_hub.html | 2 +- litellm/proxy/_experimental/out/model_hub.txt | 2 +- litellm/proxy/_experimental/out/onboarding.html | 2 +- litellm/proxy/_experimental/out/onboarding.txt | 4 ++-- ui/litellm-dashboard/out/404.html | 2 +- .../_buildManifest.js | 0 .../_ssgManifest.js | 0 .../static/chunks/app/onboarding/page-da04a591bae84617.js | 1 - .../static/chunks/app/onboarding/page-fd30ae439831db99.js | 1 + .../out/_next/static/chunks/app/page-42b04008af7da690.js | 1 + .../out/_next/static/chunks/app/page-5b9334558218205d.js | 1 - ui/litellm-dashboard/out/index.html | 2 +- ui/litellm-dashboard/out/index.txt | 4 ++-- ui/litellm-dashboard/out/model_hub.html | 2 +- ui/litellm-dashboard/out/model_hub.txt | 2 +- ui/litellm-dashboard/out/onboarding.html | 2 +- ui/litellm-dashboard/out/onboarding.txt | 4 ++-- 26 files changed, 22 insertions(+), 22 deletions(-) rename litellm/proxy/_experimental/out/_next/static/{dDWf4yi4zCe685SxgCnWX => DahySukItzAH9ZoOiMmQB}/_buildManifest.js (100%) rename litellm/proxy/_experimental/out/_next/static/{dDWf4yi4zCe685SxgCnWX => DahySukItzAH9ZoOiMmQB}/_ssgManifest.js (100%) delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/app/onboarding/page-da04a591bae84617.js create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/app/onboarding/page-fd30ae439831db99.js create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/app/page-42b04008af7da690.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/app/page-5b9334558218205d.js rename ui/litellm-dashboard/out/_next/static/{dDWf4yi4zCe685SxgCnWX => DahySukItzAH9ZoOiMmQB}/_buildManifest.js (100%) rename ui/litellm-dashboard/out/_next/static/{dDWf4yi4zCe685SxgCnWX => DahySukItzAH9ZoOiMmQB}/_ssgManifest.js (100%) delete mode 100644 ui/litellm-dashboard/out/_next/static/chunks/app/onboarding/page-da04a591bae84617.js create mode 100644 ui/litellm-dashboard/out/_next/static/chunks/app/onboarding/page-fd30ae439831db99.js create mode 100644 ui/litellm-dashboard/out/_next/static/chunks/app/page-42b04008af7da690.js delete mode 100644 ui/litellm-dashboard/out/_next/static/chunks/app/page-5b9334558218205d.js diff --git a/litellm/proxy/_experimental/out/404.html b/litellm/proxy/_experimental/out/404.html index e27fe5bab8d..909f7154275 100644 --- a/litellm/proxy/_experimental/out/404.html +++ b/litellm/proxy/_experimental/out/404.html @@ -1 +1 @@ -404: This page could not be found.LiteLLM Dashboard

404

This page could not be found.

\ No newline at end of file +404: This page could not be found.LiteLLM Dashboard

404

This page could not be found.

\ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/dDWf4yi4zCe685SxgCnWX/_buildManifest.js b/litellm/proxy/_experimental/out/_next/static/DahySukItzAH9ZoOiMmQB/_buildManifest.js similarity index 100% rename from litellm/proxy/_experimental/out/_next/static/dDWf4yi4zCe685SxgCnWX/_buildManifest.js rename to litellm/proxy/_experimental/out/_next/static/DahySukItzAH9ZoOiMmQB/_buildManifest.js diff --git a/litellm/proxy/_experimental/out/_next/static/dDWf4yi4zCe685SxgCnWX/_ssgManifest.js b/litellm/proxy/_experimental/out/_next/static/DahySukItzAH9ZoOiMmQB/_ssgManifest.js similarity index 100% rename from litellm/proxy/_experimental/out/_next/static/dDWf4yi4zCe685SxgCnWX/_ssgManifest.js rename to litellm/proxy/_experimental/out/_next/static/DahySukItzAH9ZoOiMmQB/_ssgManifest.js diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/app/onboarding/page-da04a591bae84617.js b/litellm/proxy/_experimental/out/_next/static/chunks/app/onboarding/page-da04a591bae84617.js deleted file mode 100644 index 206e6c60271..00000000000 --- a/litellm/proxy/_experimental/out/_next/static/chunks/app/onboarding/page-da04a591bae84617.js +++ /dev/null @@ -1 +0,0 @@ -(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[461],{61994:function(e,s,l){Promise.resolve().then(l.bind(l,667))},667:function(e,s,l){"use strict";l.r(s),l.d(s,{default:function(){return _}});var t=l(3827),a=l(64090),r=l(47907),n=l(16450),i=l(18190),o=l(13810),u=l(10384),c=l(46453),d=l(71801),m=l(52273),h=l(42440),x=l(30953),j=l(777),p=l(37963),f=l(60620),g=l(1861);function _(){let[e]=f.Z.useForm(),s=(0,r.useSearchParams)();s.get("token");let l=s.get("id"),[_,Z]=(0,a.useState)(null),[w,b]=(0,a.useState)(""),[N,S]=(0,a.useState)(""),[k,y]=(0,a.useState)(null),[v,E]=(0,a.useState)(""),[F,I]=(0,a.useState)("");return(0,a.useEffect)(()=>{l&&(0,j.W_)(l).then(e=>{let s=e.login_url;console.log("login_url:",s),E(s);let l=e.token,t=(0,p.o)(l);I(l),console.log("decoded:",t),Z(t.key),console.log("decoded user email:",t.user_email),S(t.user_email),y(t.user_id)})},[l]),(0,t.jsx)("div",{className:"mx-auto max-w-md mt-10",children:(0,t.jsxs)(o.Z,{children:[(0,t.jsx)(h.Z,{className:"text-sm mb-5 text-center",children:"\uD83D\uDE85 LiteLLM"}),(0,t.jsx)(h.Z,{className:"text-xl",children:"Sign up"}),(0,t.jsx)(d.Z,{children:"Claim your user account to login to Admin UI."}),(0,t.jsx)(i.Z,{className:"mt-4",title:"SSO",icon:x.GH$,color:"sky",children:(0,t.jsxs)(c.Z,{numItems:2,className:"flex justify-between items-center",children:[(0,t.jsx)(u.Z,{children:"SSO is under the Enterprise Tirer."}),(0,t.jsx)(u.Z,{children:(0,t.jsx)(n.Z,{variant:"primary",className:"mb-2",children:(0,t.jsx)("a",{href:"https://forms.gle/W3U4PZpJGFHWtHyA9",target:"_blank",children:"Get Free Trial"})})})]})}),(0,t.jsxs)(f.Z,{className:"mt-10 mb-5 mx-auto",layout:"vertical",onFinish:e=>{console.log("in handle submit. accessToken:",_,"token:",F,"formValues:",e),_&&F&&(e.user_email=N,k&&l&&(0,j.m_)(_,l,k,e.password).then(e=>{var s;let l="/ui/";console.log("redirecting to:",l+="?userID="+((null===(s=e.data)||void 0===s?void 0:s.user_id)||e.user_id)+"&token="+F),window.location.href=l}))},children:[(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(f.Z.Item,{label:"Email Address",name:"user_email",children:(0,t.jsx)(m.Z,{type:"email",disabled:!0,value:N,defaultValue:N,className:"max-w-md"})}),(0,t.jsx)(f.Z.Item,{label:"Password",name:"password",rules:[{required:!0,message:"password required to sign up"}],help:"Create a password for your account",children:(0,t.jsx)(m.Z,{placeholder:"",type:"password",className:"max-w-md"})})]}),(0,t.jsx)("div",{className:"mt-10",children:(0,t.jsx)(g.ZP,{htmlType:"submit",children:"Sign Up"})})]})]})})}}},function(e){e.O(0,[665,294,684,777,971,69,744],function(){return e(e.s=61994)}),_N_E=e.O()}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/app/onboarding/page-fd30ae439831db99.js b/litellm/proxy/_experimental/out/_next/static/chunks/app/onboarding/page-fd30ae439831db99.js new file mode 100644 index 00000000000..ae763de169c --- /dev/null +++ b/litellm/proxy/_experimental/out/_next/static/chunks/app/onboarding/page-fd30ae439831db99.js @@ -0,0 +1 @@ +(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[461],{61994:function(e,s,t){Promise.resolve().then(t.bind(t,667))},667:function(e,s,t){"use strict";t.r(s),t.d(s,{default:function(){return _}});var l=t(3827),n=t(64090),a=t(47907),r=t(16450),i=t(18190),o=t(13810),c=t(10384),u=t(46453),d=t(71801),m=t(52273),h=t(42440),x=t(30953),p=t(777),f=t(37963),j=t(60620),g=t(1861);function _(){let[e]=j.Z.useForm(),s=(0,a.useSearchParams)();!function(e){console.log("COOKIES",document.cookie);let s=document.cookie.split("; ").find(s=>s.startsWith(e+"="));s&&s.split("=")[1]}("token");let t=s.get("id"),[_,Z]=(0,n.useState)(null),[k,w]=(0,n.useState)(""),[S,b]=(0,n.useState)(""),[N,y]=(0,n.useState)(null),[v,E]=(0,n.useState)(""),[I,O]=(0,n.useState)("");return(0,n.useEffect)(()=>{t&&(0,p.W_)(t).then(e=>{let s=e.login_url;console.log("login_url:",s),E(s);let t=e.token,l=(0,f.o)(t);O(t),console.log("decoded:",l),Z(l.key),console.log("decoded user email:",l.user_email),b(l.user_email),y(l.user_id)})},[t]),(0,l.jsx)("div",{className:"mx-auto max-w-md mt-10",children:(0,l.jsxs)(o.Z,{children:[(0,l.jsx)(h.Z,{className:"text-sm mb-5 text-center",children:"\uD83D\uDE85 LiteLLM"}),(0,l.jsx)(h.Z,{className:"text-xl",children:"Sign up"}),(0,l.jsx)(d.Z,{children:"Claim your user account to login to Admin UI."}),(0,l.jsx)(i.Z,{className:"mt-4",title:"SSO",icon:x.GH$,color:"sky",children:(0,l.jsxs)(u.Z,{numItems:2,className:"flex justify-between items-center",children:[(0,l.jsx)(c.Z,{children:"SSO is under the Enterprise Tirer."}),(0,l.jsx)(c.Z,{children:(0,l.jsx)(r.Z,{variant:"primary",className:"mb-2",children:(0,l.jsx)("a",{href:"https://forms.gle/W3U4PZpJGFHWtHyA9",target:"_blank",children:"Get Free Trial"})})})]})}),(0,l.jsxs)(j.Z,{className:"mt-10 mb-5 mx-auto",layout:"vertical",onFinish:e=>{console.log("in handle submit. accessToken:",_,"token:",I,"formValues:",e),_&&I&&(e.user_email=S,N&&t&&(0,p.m_)(_,t,N,e.password).then(e=>{var s;let t="/ui/";console.log("redirecting to:",t+="?userID="+((null===(s=e.data)||void 0===s?void 0:s.user_id)||e.user_id)+"&token="+I),window.location.href=t}))},children:[(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(j.Z.Item,{label:"Email Address",name:"user_email",children:(0,l.jsx)(m.Z,{type:"email",disabled:!0,value:S,defaultValue:S,className:"max-w-md"})}),(0,l.jsx)(j.Z.Item,{label:"Password",name:"password",rules:[{required:!0,message:"password required to sign up"}],help:"Create a password for your account",children:(0,l.jsx)(m.Z,{placeholder:"",type:"password",className:"max-w-md"})})]}),(0,l.jsx)("div",{className:"mt-10",children:(0,l.jsx)(g.ZP,{htmlType:"submit",children:"Sign Up"})})]})]})})}}},function(e){e.O(0,[665,294,684,777,971,69,744],function(){return e(e.s=61994)}),_N_E=e.O()}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/app/page-42b04008af7da690.js b/litellm/proxy/_experimental/out/_next/static/chunks/app/page-42b04008af7da690.js new file mode 100644 index 00000000000..f3bad03c2ef --- /dev/null +++ b/litellm/proxy/_experimental/out/_next/static/chunks/app/page-42b04008af7da690.js @@ -0,0 +1 @@ +(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[931],{20661:function(e,l,s){Promise.resolve().then(s.bind(s,48951))},48951:function(e,l,s){"use strict";s.r(l),s.d(l,{default:function(){return li}});var t,n,a=s(3827),r=s(64090),i=s(47907),o=s(8792),d=s(40491),c=s(65270),m=e=>{let{userID:l,userRole:s,userEmail:t,showSSOBanner:n,premiumUser:r,setProxySettings:i,proxySettings:m}=e;console.log("User ID:",l),console.log("userEmail:",t),console.log("showSSOBanner:",n),console.log("premiumUser:",r);let u="";console.log("PROXY_settings=",m),m&&m.PROXY_LOGOUT_URL&&void 0!==m.PROXY_LOGOUT_URL&&(u=m.PROXY_LOGOUT_URL),console.log("logoutUrl=",u);let h=[{key:"1",label:(0,a.jsxs)(a.Fragment,{children:[(0,a.jsxs)("p",{children:["Role: ",s]}),(0,a.jsxs)("p",{children:["ID: ",l]}),(0,a.jsxs)("p",{children:["Premium User: ",String(r)]})]})},{key:"2",label:(0,a.jsx)("a",{href:u,children:(0,a.jsx)("p",{children:"Logout"})})}];return(0,a.jsxs)("nav",{className:"left-0 right-0 top-0 flex justify-between items-center h-12 mb-4",children:[(0,a.jsx)("div",{className:"text-left my-2 absolute top-0 left-0",children:(0,a.jsx)("div",{className:"flex flex-col items-center",children:(0,a.jsx)(o.default,{href:"/",children:(0,a.jsx)("button",{className:"text-gray-800 rounded text-center",children:(0,a.jsx)("img",{src:"/get_image",width:160,height:160,alt:"LiteLLM Brand",className:"mr-2"})})})})}),(0,a.jsxs)("div",{className:"text-right mx-4 my-2 absolute top-0 right-0 flex items-center justify-end space-x-2",children:[n?(0,a.jsx)("div",{style:{padding:"6px",borderRadius:"8px"},children:(0,a.jsx)("a",{href:"https://calendly.com/d/4mp-gd3-k5k/litellm-1-1-onboarding-chat",target:"_blank",style:{fontSize:"14px",textDecoration:"underline"},children:"Get enterprise license"})}):null,(0,a.jsx)("div",{style:{border:"1px solid #391085",padding:"6px",borderRadius:"8px"},children:(0,a.jsx)(d.Z,{menu:{items:h},children:(0,a.jsx)(c.Z,{children:t})})})]})]})},u=s(777),h=s(10384),x=s(46453),p=s(16450),j=s(52273),g=s(26780),Z=s(15595),f=s(6698),_=s(71801),y=s(42440),b=s(42308),v=s(50670),S=s(60620),k=s(80588),w=s(99129),N=s(44839),A=s(88707),I=s(1861);let{Option:C}=v.default;var P=e=>{let{userID:l,team:s,userRole:t,accessToken:n,data:i,setData:o}=e,[d]=S.Z.useForm(),[c,m]=(0,r.useState)(!1),[P,T]=(0,r.useState)(null),[O,E]=(0,r.useState)(null),[R,M]=(0,r.useState)([]),[F,D]=(0,r.useState)([]),L=()=>{m(!1),d.resetFields()},U=()=>{m(!1),T(null),d.resetFields()};(0,r.useEffect)(()=>{(async()=>{try{if(null===l||null===t)return;if(null!==n){let e=(await (0,u.So)(n,l,t)).data.map(e=>e.id);console.log("available_model_names:",e),M(e)}}catch(e){console.error("Error fetching user models:",e)}})()},[n,l,t]);let V=async e=>{try{var s,t,a;let r=null!==(s=null==e?void 0:e.key_alias)&&void 0!==s?s:"",c=null!==(t=null==e?void 0:e.team_id)&&void 0!==t?t:null;if((null!==(a=null==i?void 0:i.filter(e=>e.team_id===c).map(e=>e.key_alias))&&void 0!==a?a:[]).includes(r))throw Error("Key alias ".concat(r," already exists for team with ID ").concat(c,", please provide another key alias"));k.ZP.info("Making API Call"),m(!0);let h=await (0,u.wX)(n,l,e);console.log("key create Response:",h),o(e=>e?[...e,h]:[h]),T(h.key),E(h.soft_budget),k.ZP.success("API Key Created"),d.resetFields(),localStorage.removeItem("userData"+l)}catch(e){console.error("Error creating the key:",e),k.ZP.error("Error creating the key: ".concat(e),20)}};return(0,r.useEffect)(()=>{D(s&&s.models.length>0?s.models.includes("all-proxy-models")?R:s.models:R)},[s,R]),(0,a.jsxs)("div",{children:[(0,a.jsx)(p.Z,{className:"mx-auto",onClick:()=>m(!0),children:"+ Create New Key"}),(0,a.jsx)(w.Z,{title:"Create Key",visible:c,width:800,footer:null,onOk:L,onCancel:U,children:(0,a.jsxs)(S.Z,{form:d,onFinish:V,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(S.Z.Item,{label:"Key Name",name:"key_alias",rules:[{required:!0,message:"Please input a key name"}],help:"required",children:(0,a.jsx)(j.Z,{placeholder:""})}),(0,a.jsx)(S.Z.Item,{label:"Team ID",name:"team_id",hidden:!0,initialValue:s?s.team_id:null,valuePropName:"team_id",className:"mt-8",children:(0,a.jsx)(N.Z,{value:s?s.team_alias:"",disabled:!0})}),(0,a.jsx)(S.Z.Item,{label:"Models",name:"models",rules:[{required:!0,message:"Please select a model"}],help:"required",children:(0,a.jsxs)(v.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},onChange:e=>{e.includes("all-team-models")&&d.setFieldsValue({models:["all-team-models"]})},children:[(0,a.jsx)(C,{value:"all-team-models",children:"All Team Models"},"all-team-models"),F.map(e=>(0,a.jsx)(C,{value:e,children:e},e))]})}),(0,a.jsxs)(g.Z,{className:"mt-20 mb-8",children:[(0,a.jsx)(f.Z,{children:(0,a.jsx)("b",{children:"Optional Settings"})}),(0,a.jsxs)(Z.Z,{children:[(0,a.jsx)(S.Z.Item,{className:"mt-8",label:"Max Budget (USD)",name:"max_budget",help:"Budget cannot exceed team max budget: $".concat((null==s?void 0:s.max_budget)!==null&&(null==s?void 0:s.max_budget)!==void 0?null==s?void 0:s.max_budget:"unlimited"),rules:[{validator:async(e,l)=>{if(l&&s&&null!==s.max_budget&&l>s.max_budget)throw Error("Budget cannot exceed team max budget: $".concat(s.max_budget))}}],children:(0,a.jsx)(A.Z,{step:.01,precision:2,width:200})}),(0,a.jsx)(S.Z.Item,{className:"mt-8",label:"Reset Budget",name:"budget_duration",help:"Team Reset Budget: ".concat((null==s?void 0:s.budget_duration)!==null&&(null==s?void 0:s.budget_duration)!==void 0?null==s?void 0:s.budget_duration:"None"),children:(0,a.jsxs)(v.default,{defaultValue:null,placeholder:"n/a",children:[(0,a.jsx)(v.default.Option,{value:"24h",children:"daily"}),(0,a.jsx)(v.default.Option,{value:"7d",children:"weekly"}),(0,a.jsx)(v.default.Option,{value:"30d",children:"monthly"})]})}),(0,a.jsx)(S.Z.Item,{className:"mt-8",label:"Tokens per minute Limit (TPM)",name:"tpm_limit",help:"TPM cannot exceed team TPM limit: ".concat((null==s?void 0:s.tpm_limit)!==null&&(null==s?void 0:s.tpm_limit)!==void 0?null==s?void 0:s.tpm_limit:"unlimited"),rules:[{validator:async(e,l)=>{if(l&&s&&null!==s.tpm_limit&&l>s.tpm_limit)throw Error("TPM limit cannot exceed team TPM limit: ".concat(s.tpm_limit))}}],children:(0,a.jsx)(A.Z,{step:1,width:400})}),(0,a.jsx)(S.Z.Item,{className:"mt-8",label:"Requests per minute Limit (RPM)",name:"rpm_limit",help:"RPM cannot exceed team RPM limit: ".concat((null==s?void 0:s.rpm_limit)!==null&&(null==s?void 0:s.rpm_limit)!==void 0?null==s?void 0:s.rpm_limit:"unlimited"),rules:[{validator:async(e,l)=>{if(l&&s&&null!==s.rpm_limit&&l>s.rpm_limit)throw Error("RPM limit cannot exceed team RPM limit: ".concat(s.rpm_limit))}}],children:(0,a.jsx)(A.Z,{step:1,width:400})}),(0,a.jsx)(S.Z.Item,{label:"Expire Key (eg: 30s, 30h, 30d)",name:"duration",className:"mt-8",children:(0,a.jsx)(j.Z,{placeholder:""})}),(0,a.jsx)(S.Z.Item,{label:"Metadata",name:"metadata",className:"mt-8",children:(0,a.jsx)(N.Z.TextArea,{rows:4,placeholder:"Enter metadata as JSON"})})]})]})]}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(I.ZP,{htmlType:"submit",children:"Create Key"})})]})}),P&&(0,a.jsx)(w.Z,{visible:c,onOk:L,onCancel:U,footer:null,children:(0,a.jsxs)(x.Z,{numItems:1,className:"gap-2 w-full",children:[(0,a.jsx)(y.Z,{children:"Save your Key"}),(0,a.jsx)(h.Z,{numColSpan:1,children:(0,a.jsxs)("p",{children:["Please save this secret key somewhere safe and accessible. For security reasons, ",(0,a.jsx)("b",{children:"you will not be able to view it again"})," ","through your LiteLLM account. If you lose this secret key, you will need to generate a new one."]})}),(0,a.jsx)(h.Z,{numColSpan:1,children:null!=P?(0,a.jsxs)("div",{children:[(0,a.jsx)(_.Z,{className:"mt-3",children:"API Key:"}),(0,a.jsx)("div",{style:{background:"#f8f8f8",padding:"10px",borderRadius:"5px",marginBottom:"10px"},children:(0,a.jsx)("pre",{style:{wordWrap:"break-word",whiteSpace:"normal"},children:P})}),(0,a.jsx)(b.CopyToClipboard,{text:P,onCopy:()=>{k.ZP.success("API Key copied to clipboard")},children:(0,a.jsx)(p.Z,{className:"mt-3",children:"Copy API Key"})})]}):(0,a.jsx)(_.Z,{children:"Key being created, this might take 30s"})})]})})]})},T=s(9454),O=s(98941),E=s(33393),R=s(5),M=s(13810),F=s(61244),D=s(10827),L=s(3851),U=s(2044),V=s(64167),z=s(74480),q=s(7178),B=s(95093),K=s(27166);let{Option:W}=v.default;var H=e=>{let{userID:l,userRole:s,accessToken:t,selectedTeam:n,data:i,setData:o,teams:d}=e,[c,m]=(0,r.useState)(!1),[h,x]=(0,r.useState)(!1),[j,g]=(0,r.useState)(null),[Z,f]=(0,r.useState)(null),[b,C]=(0,r.useState)(null),[P,H]=(0,r.useState)(""),[G,Y]=(0,r.useState)(!1),[J,X]=(0,r.useState)(!1),[$,Q]=(0,r.useState)(null),[ee,el]=(0,r.useState)([]),es=new Set,[et,en]=(0,r.useState)(es);(0,r.useEffect)(()=>{(async()=>{try{if(null===l)return;if(null!==t&&null!==s){let e=(await (0,u.So)(t,l,s)).data.map(e=>e.id);console.log("available_model_names:",e),el(e)}}catch(e){console.error("Error fetching user models:",e)}})()},[t,l,s]),(0,r.useEffect)(()=>{if(d){let e=new Set;d.forEach((l,s)=>{let t=l.team_id;e.add(t)}),en(e)}},[d]);let ea=e=>{console.log("handleEditClick:",e),null==e.token&&null!==e.token_id&&(e.token=e.token_id),Q(e),Y(!0)},er=async e=>{if(null==t)return;let l=e.token;e.key=l,console.log("handleEditSubmit:",e);let s=await (0,u.Nc)(t,e);console.log("handleEditSubmit: newKeyValues",s),i&&o(i.map(e=>e.token===l?s:e)),k.ZP.success("Key updated successfully"),Y(!1),Q(null)},ei=async e=>{console.log("handleDelete:",e),null==e.token&&null!==e.token_id&&(e.token=e.token_id),null!=i&&(g(e.token),localStorage.removeItem("userData"+l),x(!0))},eo=async()=>{if(null!=j&&null!=i){try{await (0,u.I1)(t,j);let e=i.filter(e=>e.token!==j);o(e)}catch(e){console.error("Error deleting the key:",e)}x(!1),g(null)}};if(null!=i)return console.log("RERENDER TRIGGERED"),(0,a.jsxs)("div",{children:[(0,a.jsxs)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh] mb-4 mt-2",children:[(0,a.jsxs)(D.Z,{className:"mt-5 max-h-[300px] min-h-[300px]",children:[(0,a.jsx)(V.Z,{children:(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(z.Z,{children:"Key Alias"}),(0,a.jsx)(z.Z,{children:"Secret Key"}),(0,a.jsx)(z.Z,{children:"Spend (USD)"}),(0,a.jsx)(z.Z,{children:"Budget (USD)"}),(0,a.jsx)(z.Z,{children:"Models"}),(0,a.jsx)(z.Z,{children:"TPM / RPM Limits"})]})}),(0,a.jsx)(L.Z,{children:i.map(e=>{if(console.log(e),"litellm-dashboard"===e.team_id)return null;if(n){if(console.log("item team id: ".concat(e.team_id,", knownTeamIDs.has(item.team_id): ").concat(et.has(e.team_id),", selectedTeam id: ").concat(n.team_id)),(null!=n.team_id||null===e.team_id||et.has(e.team_id))&&e.team_id!=n.team_id)return null;console.log("item team id: ".concat(e.team_id,", is returned"))}return(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(U.Z,{style:{maxWidth:"2px",whiteSpace:"pre-wrap",overflow:"hidden"},children:null!=e.key_alias?(0,a.jsx)(_.Z,{children:e.key_alias}):(0,a.jsx)(_.Z,{children:"Not Set"})}),(0,a.jsx)(U.Z,{children:(0,a.jsx)(_.Z,{children:e.key_name})}),(0,a.jsx)(U.Z,{children:(0,a.jsx)(_.Z,{children:(()=>{try{return parseFloat(e.spend).toFixed(4)}catch(l){return e.spend}})()})}),(0,a.jsx)(U.Z,{children:null!=e.max_budget?(0,a.jsx)(_.Z,{children:e.max_budget}):(0,a.jsx)(_.Z,{children:"Unlimited"})}),(0,a.jsx)(U.Z,{children:Array.isArray(e.models)?(0,a.jsx)("div",{style:{display:"flex",flexDirection:"column"},children:0===e.models.length?(0,a.jsx)(a.Fragment,{children:n&&n.models&&n.models.length>0?n.models.map((e,l)=>"all-proxy-models"===e?(0,a.jsx)(R.Z,{size:"xs",className:"mb-1",color:"red",children:(0,a.jsx)(_.Z,{children:"All Proxy Models"})},l):"all-team-models"===e?(0,a.jsx)(R.Z,{size:"xs",className:"mb-1",color:"red",children:(0,a.jsx)(_.Z,{children:"All Team Models"})},l):(0,a.jsx)(R.Z,{size:"xs",className:"mb-1",color:"blue",children:(0,a.jsx)(_.Z,{children:e.length>30?"".concat(e.slice(0,30),"..."):e})},l)):(0,a.jsx)(R.Z,{size:"xs",className:"mb-1",color:"blue",children:(0,a.jsx)(_.Z,{children:"all-proxy-models"})})}):e.models.map((e,l)=>"all-proxy-models"===e?(0,a.jsx)(R.Z,{size:"xs",className:"mb-1",color:"red",children:(0,a.jsx)(_.Z,{children:"All Proxy Models"})},l):"all-team-models"===e?(0,a.jsx)(R.Z,{size:"xs",className:"mb-1",color:"red",children:(0,a.jsx)(_.Z,{children:"All Team Models"})},l):(0,a.jsx)(R.Z,{size:"xs",className:"mb-1",color:"blue",children:(0,a.jsx)(_.Z,{children:e.length>30?"".concat(e.slice(0,30),"..."):e})},l))}):null}),(0,a.jsx)(U.Z,{children:(0,a.jsxs)(_.Z,{children:["TPM: ",e.tpm_limit?e.tpm_limit:"Unlimited"," ",(0,a.jsx)("br",{})," RPM:"," ",e.rpm_limit?e.rpm_limit:"Unlimited"]})}),(0,a.jsxs)(U.Z,{children:[(0,a.jsx)(F.Z,{onClick:()=>{Q(e),X(!0)},icon:T.Z,size:"sm"}),(0,a.jsx)(w.Z,{open:J,onCancel:()=>{X(!1),Q(null)},footer:null,width:800,children:$&&(0,a.jsxs)(a.Fragment,{children:[(0,a.jsxs)("div",{className:"grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3 mt-8",children:[(0,a.jsxs)(M.Z,{children:[(0,a.jsx)("p",{className:"text-tremor-default font-medium text-tremor-content dark:text-dark-tremor-content",children:"Spend"}),(0,a.jsx)("div",{className:"mt-2 flex items-baseline space-x-2.5",children:(0,a.jsx)("p",{className:"text-tremor font-semibold text-tremor-content-strong dark:text-dark-tremor-content-strong",children:(()=>{try{return parseFloat($.spend).toFixed(4)}catch(e){return $.spend}})()})})]}),(0,a.jsxs)(M.Z,{children:[(0,a.jsx)("p",{className:"text-tremor-default font-medium text-tremor-content dark:text-dark-tremor-content",children:"Budget"}),(0,a.jsx)("div",{className:"mt-2 flex items-baseline space-x-2.5",children:(0,a.jsx)("p",{className:"text-tremor font-semibold text-tremor-content-strong dark:text-dark-tremor-content-strong",children:null!=$.max_budget?(0,a.jsx)(a.Fragment,{children:$.max_budget}):(0,a.jsx)(a.Fragment,{children:"Unlimited"})})})]},e.name),(0,a.jsxs)(M.Z,{children:[(0,a.jsx)("p",{className:"text-tremor-default font-medium text-tremor-content dark:text-dark-tremor-content",children:"Expires"}),(0,a.jsx)("div",{className:"mt-2 flex items-baseline space-x-2.5",children:(0,a.jsx)("p",{className:"text-tremor-default font-small text-tremor-content-strong dark:text-dark-tremor-content-strong",children:null!=$.expires?(0,a.jsx)(a.Fragment,{children:new Date($.expires).toLocaleString(void 0,{day:"numeric",month:"long",year:"numeric",hour:"numeric",minute:"numeric",second:"numeric"})}):(0,a.jsx)(a.Fragment,{children:"Never"})})})]},e.name)]}),(0,a.jsxs)(M.Z,{className:"my-4",children:[(0,a.jsx)(y.Z,{children:"Token Name"}),(0,a.jsx)(_.Z,{className:"my-1",children:$.key_alias?$.key_alias:$.key_name}),(0,a.jsx)(y.Z,{children:"Token ID"}),(0,a.jsx)(_.Z,{className:"my-1 text-[12px]",children:$.token}),(0,a.jsx)(y.Z,{children:"Metadata"}),(0,a.jsx)(_.Z,{className:"my-1",children:(0,a.jsxs)("pre",{children:[JSON.stringify($.metadata)," "]})})]}),(0,a.jsx)(p.Z,{className:"mx-auto flex items-center",onClick:()=>{X(!1),Q(null)},children:"Close"})]})}),(0,a.jsx)(F.Z,{icon:O.Z,size:"sm",onClick:()=>ea(e)}),(0,a.jsx)(F.Z,{onClick:()=>ei(e),icon:E.Z,size:"sm"})]})]},e.token)})})]}),h&&(0,a.jsx)("div",{className:"fixed z-10 inset-0 overflow-y-auto",children:(0,a.jsxs)("div",{className:"flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0",children:[(0,a.jsx)("div",{className:"fixed inset-0 transition-opacity","aria-hidden":"true",children:(0,a.jsx)("div",{className:"absolute inset-0 bg-gray-500 opacity-75"})}),(0,a.jsx)("span",{className:"hidden sm:inline-block sm:align-middle sm:h-screen","aria-hidden":"true",children:"​"}),(0,a.jsxs)("div",{className:"inline-block align-bottom bg-white rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full",children:[(0,a.jsx)("div",{className:"bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4",children:(0,a.jsx)("div",{className:"sm:flex sm:items-start",children:(0,a.jsxs)("div",{className:"mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left",children:[(0,a.jsx)("h3",{className:"text-lg leading-6 font-medium text-gray-900",children:"Delete Key"}),(0,a.jsx)("div",{className:"mt-2",children:(0,a.jsx)("p",{className:"text-sm text-gray-500",children:"Are you sure you want to delete this key ?"})})]})})}),(0,a.jsxs)("div",{className:"bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse",children:[(0,a.jsx)(p.Z,{onClick:eo,color:"red",className:"ml-2",children:"Delete"}),(0,a.jsx)(p.Z,{onClick:()=>{x(!1),g(null)},children:"Cancel"})]})]})]})})]}),$&&(0,a.jsx)(e=>{let{visible:l,onCancel:s,token:t,onSubmit:i}=e,[o]=S.Z.useForm(),[c,m]=(0,r.useState)(n),[u,h]=(0,r.useState)([]),[x,p]=(0,r.useState)(!1);return(0,a.jsx)(w.Z,{title:"Edit Key",visible:l,width:800,footer:null,onOk:()=>{o.validateFields().then(e=>{o.resetFields()}).catch(e=>{console.error("Validation failed:",e)})},onCancel:s,children:(0,a.jsxs)(S.Z,{form:o,onFinish:er,initialValues:t,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(S.Z.Item,{label:"Key Name",name:"key_alias",rules:[{required:!0,message:"Please input a key name"}],help:"required",children:(0,a.jsx)(N.Z,{})}),(0,a.jsx)(S.Z.Item,{label:"Models",name:"models",rules:[{validator:(e,l)=>{let s=l.filter(e=>!c.models.includes(e)&&"all-team-models"!==e&&"all-proxy-models"!==e&&!c.models.includes("all-proxy-models"));return(console.log("errorModels: ".concat(s)),s.length>0)?Promise.reject("Some models are not part of the new team's models - ".concat(s,"Team models: ").concat(c.models)):Promise.resolve()}}],children:(0,a.jsxs)(v.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:[(0,a.jsx)(W,{value:"all-team-models",children:"All Team Models"},"all-team-models"),c&&c.models?c.models.includes("all-proxy-models")?ee.filter(e=>"all-proxy-models"!==e).map(e=>(0,a.jsx)(W,{value:e,children:e},e)):c.models.map(e=>(0,a.jsx)(W,{value:e,children:e},e)):ee.map(e=>(0,a.jsx)(W,{value:e,children:e},e))]})}),(0,a.jsx)(S.Z.Item,{className:"mt-8",label:"Max Budget (USD)",name:"max_budget",help:"Budget cannot exceed team max budget: ".concat((null==c?void 0:c.max_budget)!==null&&(null==c?void 0:c.max_budget)!==void 0?null==c?void 0:c.max_budget:"unlimited"),rules:[{validator:async(e,l)=>{if(l&&c&&null!==c.max_budget&&l>c.max_budget)throw console.log("keyTeam.max_budget: ".concat(c.max_budget)),Error("Budget cannot exceed team max budget: $".concat(c.max_budget))}}],children:(0,a.jsx)(A.Z,{step:.01,precision:2,width:200})}),(0,a.jsx)(S.Z.Item,{label:"token",name:"token",hidden:!0}),(0,a.jsx)(S.Z.Item,{label:"Team",name:"team_id",help:"the team this key belongs to",children:(0,a.jsx)(B.Z,{value:t.team_alias,children:null==d?void 0:d.map((e,l)=>(0,a.jsx)(K.Z,{value:e.team_id,onClick:()=>m(e),children:e.team_alias},l))})})]}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(I.ZP,{htmlType:"submit",children:"Edit Key"})})]})})},{visible:G,onCancel:()=>{Y(!1),Q(null)},token:$,onSubmit:er})]})},G=e=>{let{userID:l,userRole:s,accessToken:t,userSpend:n,selectedTeam:i}=e;console.log("userSpend: ".concat(n));let[o,d]=(0,r.useState)(null!==n?n:0),[c,m]=(0,r.useState)(0),[h,x]=(0,r.useState)([]);(0,r.useEffect)(()=>{let e=async()=>{if(t&&l&&s&&"Admin"===s&&null==n)try{let e=await (0,u.Qy)(t);e&&(e.spend?d(e.spend):d(0),e.max_budget?m(e.max_budget):m(0))}catch(e){console.error("Error fetching global spend data:",e)}};(async()=>{try{if(null===l||null===s)return;if(null!==t){let e=(await (0,u.So)(t,l,s)).data.map(e=>e.id);console.log("available_model_names:",e),x(e)}}catch(e){console.error("Error fetching user models:",e)}})(),e()},[s,t,l]),(0,r.useEffect)(()=>{null!==n&&d(n)},[n]);let p=[];i&&i.models&&(p=i.models),p&&p.includes("all-proxy-models")?(console.log("user models:",h),p=h):p&&p.includes("all-team-models")?p=i.models:p&&0===p.length&&(p=h);let j=void 0!==o?o.toFixed(4):null;return console.log("spend in view user spend: ".concat(o)),(0,a.jsx)("div",{className:"flex items-center",children:(0,a.jsxs)("div",{children:[(0,a.jsxs)("p",{className:"text-tremor-default text-tremor-content dark:text-dark-tremor-content",children:["Total Spend"," "]}),(0,a.jsxs)("p",{className:"text-2xl text-tremor-content-strong dark:text-dark-tremor-content-strong font-semibold",children:["$",j]})]})})},Y=e=>{let{userID:l,userRole:s,selectedTeam:t,accessToken:n}=e,[i,o]=(0,r.useState)([]);(0,r.useEffect)(()=>{(async()=>{try{if(null===l||null===s)return;if(null!==n){let e=(await (0,u.So)(n,l,s)).data.map(e=>e.id);console.log("available_model_names:",e),o(e)}}catch(e){console.error("Error fetching user models:",e)}})()},[n,l,s]);let d=[];return t&&t.models&&(d=t.models),d&&d.includes("all-proxy-models")&&(console.log("user models:",i),d=i),(0,a.jsx)(a.Fragment,{children:(0,a.jsx)("div",{className:"mb-5",children:(0,a.jsx)("p",{className:"text-3xl text-tremor-content-strong dark:text-dark-tremor-content-strong font-semibold",children:null==t?void 0:t.team_alias})})})},J=e=>{let l,{teams:s,setSelectedTeam:t,userRole:n}=e,i={models:[],team_id:null,team_alias:"Default Team"},[o,d]=(0,r.useState)(i);return(l="App User"===n?s:s?[...s,i]:[i],"App User"===n)?null:(0,a.jsxs)("div",{className:"mt-5 mb-5",children:[(0,a.jsx)(y.Z,{children:"Select Team"}),(0,a.jsx)(_.Z,{children:"If you belong to multiple teams, this setting controls which team is used by default when creating new API Keys."}),(0,a.jsxs)(_.Z,{className:"mt-3 mb-3",children:[(0,a.jsx)("b",{children:"Default Team:"})," If no team_id is set for a key, it will be grouped under here."]}),l&&l.length>0?(0,a.jsx)(B.Z,{defaultValue:"0",children:l.map((e,l)=>(0,a.jsx)(K.Z,{value:String(l),onClick:()=>t(e),children:e.team_alias},l))}):(0,a.jsxs)(_.Z,{children:["No team created. ",(0,a.jsx)("b",{children:"Defaulting to personal account."})]})]})},X=s(37963),$=s(97482);console.log("isLocal:",!1);var Q=e=>{let{userID:l,userRole:s,teams:t,keys:n,setUserRole:o,userEmail:d,setUserEmail:c,setTeams:m,setKeys:p,setProxySettings:j,proxySettings:g}=e,[Z,f]=(0,r.useState)(null);(0,i.useSearchParams)().get("viewSpend"),(0,i.useRouter)();let _=function(e){console.log("COOKIES",document.cookie);let l=document.cookie.split("; ").find(l=>l.startsWith(e+"="));return l?l.split("=")[1]:null}("token"),[y,b]=(0,r.useState)(null),[v,S]=(0,r.useState)(null),[k,w]=(0,r.useState)([]),N={models:[],team_alias:"Default Team",team_id:null},[A,I]=(0,r.useState)(t?t[0]:N);if(window.addEventListener("beforeunload",function(){sessionStorage.clear()}),(0,r.useEffect)(()=>{if(_){let e=(0,X.o)(_);if(e){if(console.log("Decoded token:",e),console.log("Decoded key:",e.key),b(e.key),e.user_role){let l=function(e){if(!e)return"Undefined Role";switch(console.log("Received user role: ".concat(e)),e.toLowerCase()){case"app_owner":case"demo_app_owner":return"App Owner";case"app_admin":case"proxy_admin":return"Admin";case"proxy_admin_viewer":return"Admin Viewer";case"app_user":return"App User";case"internal_user":return"Internal User";case"internal_user_viewer":return"Internal Viewer";default:return"Unknown Role"}}(e.user_role);console.log("Decoded user_role:",l),o(l)}else console.log("User role not defined");e.user_email?c(e.user_email):console.log("User Email is not set ".concat(e))}}if(l&&y&&s&&!n&&!Z){let e=sessionStorage.getItem("userModels"+l);e?w(JSON.parse(e)):(async()=>{try{let e=await (0,u.Dj)(y);j(e);let t=await (0,u.Br)(y,l,s,!1,null,null);if(console.log("received teams in user dashboard: ".concat(Object.keys(t),"; team values: ").concat(Object.entries(t.teams))),"Admin"==s){let e=await (0,u.Qy)(y);f(e),console.log("globalSpend:",e)}else f(t.user_info);p(t.keys),m(t.teams);let n=[...t.teams];n.length>0?(console.log("response['teams']: ".concat(n)),I(n[0])):I(N),sessionStorage.setItem("userData"+l,JSON.stringify(t.keys)),sessionStorage.setItem("userSpendData"+l,JSON.stringify(t.user_info));let a=(await (0,u.So)(y,l,s)).data.map(e=>e.id);console.log("available_model_names:",a),w(a),console.log("userModels:",k),sessionStorage.setItem("userModels"+l,JSON.stringify(a))}catch(e){console.error("There was an error fetching the data",e)}})()}},[l,_,y,n,s]),(0,r.useEffect)(()=>{if(null!==n&&null!=A&&null!==A.team_id){let e=0;for(let l of n)A.hasOwnProperty("team_id")&&null!==l.team_id&&l.team_id===A.team_id&&(e+=l.spend);S(e)}else if(null!==n){let e=0;for(let l of n)e+=l.spend;S(e)}},[A]),null==l||null==_){let e="/sso/key/generate";return console.log("Full URL:",e),window.location.href=e,null}if(null==y)return null;if(null==s&&o("App Owner"),s&&"Admin Viewer"==s){let{Title:e,Paragraph:l}=$.default;return(0,a.jsxs)("div",{children:[(0,a.jsx)(e,{level:1,children:"Access Denied"}),(0,a.jsx)(l,{children:"Ask your proxy admin for access to create keys"})]})}return console.log("inside user dashboard, selected team",A),(0,a.jsx)("div",{className:"w-full mx-4",children:(0,a.jsx)(x.Z,{numItems:1,className:"gap-2 p-8 h-[75vh] w-full mt-2",children:(0,a.jsxs)(h.Z,{numColSpan:1,children:[(0,a.jsx)(Y,{userID:l,userRole:s,selectedTeam:A||null,accessToken:y}),(0,a.jsx)(G,{userID:l,userRole:s,accessToken:y,userSpend:v,selectedTeam:A||null}),(0,a.jsx)(H,{userID:l,userRole:s,accessToken:y,selectedTeam:A||null,data:n,setData:p,teams:t}),(0,a.jsx)(P,{userID:l,team:A||null,userRole:s,accessToken:y,data:n,setData:p},A?A.team_id:null),(0,a.jsx)(J,{teams:t,setSelectedTeam:I,userRole:s})]})})})},ee=s(49167),el=s(35087),es=s(92836),et=s(26734),en=s(41608),ea=s(32126),er=s(23682),ei=s(47047),eo=s(76628),ed=s(25707),ec=s(44041),em=s(6180),eu=s(28683),eh=s(38302),ex=s(66242),ep=s(78578),ej=s(63954),eg=s(34658),eZ=e=>{let{modelID:l,accessToken:s}=e,[t,n]=(0,r.useState)(!1),i=async()=>{try{k.ZP.info("Making API Call"),n(!0);let e=await (0,u.Og)(s,l);console.log("model delete Response:",e),k.ZP.success("Model ".concat(l," deleted successfully")),n(!1)}catch(e){console.error("Error deleting the model:",e)}};return(0,a.jsxs)("div",{children:[(0,a.jsx)(F.Z,{onClick:()=>n(!0),icon:E.Z,size:"sm"}),(0,a.jsx)(w.Z,{open:t,onOk:i,okType:"danger",onCancel:()=>n(!1),children:(0,a.jsxs)(x.Z,{numItems:1,className:"gap-2 w-full",children:[(0,a.jsx)(y.Z,{children:"Delete Model"}),(0,a.jsx)(h.Z,{numColSpan:1,children:(0,a.jsx)("p",{children:"Are you sure you want to delete this model? This action is irreversible."})}),(0,a.jsx)(h.Z,{numColSpan:1,children:(0,a.jsxs)("p",{children:["Model ID: ",(0,a.jsx)("b",{children:l})]})})]})})]})},ef=s(97766),e_=s(46495),ey=s(18190),eb=s(91118),ev=e=>{let{modelMetrics:l,modelMetricsCategories:s,customTooltip:t,premiumUser:n}=e;return n?(0,a.jsx)(eb.Z,{title:"Time to First token (s)",className:"h-72",data:l,index:"date",showLegend:!1,categories:s,colors:["indigo","rose"],connectNulls:!0,customTooltip:t}):(0,a.jsxs)("div",{children:[(0,a.jsx)(ey.Z,{title:"✨ Enterprise Feature",color:"teal",className:"mt-2 mb-4",children:"Enterprise features are available for users with a specific license, please contact LiteLLM to unlock this limitation."}),(0,a.jsx)(p.Z,{variant:"primary",children:(0,a.jsx)("a",{href:"https://forms.gle/W3U4PZpJGFHWtHyA9",target:"_blank",children:"Get in touch"})})]})},eS=e=>{let{fields:l,selectedProvider:s}=e;return 0===l.length?null:(0,a.jsx)(a.Fragment,{children:l.map(e=>(0,a.jsx)(S.Z.Item,{rules:[{required:!0,message:"Required"}],label:e.field_name.replace(/_/g," ").replace(/\b\w/g,e=>e.toUpperCase()),name:e.field_name,tooltip:e.field_description,className:"mb-2",children:(0,a.jsx)(j.Z,{placeholder:e.field_value,type:"password"})},e.field_name))})},ek=s(67951);let{Title:ew,Link:eN}=$.default;(t=n||(n={})).OpenAI="OpenAI",t.Azure="Azure",t.Azure_AI_Studio="Azure AI Studio",t.Anthropic="Anthropic",t.Google_AI_Studio="Google AI Studio",t.Bedrock="Amazon Bedrock",t.OpenAI_Compatible="OpenAI-Compatible Endpoints (Groq, Together AI, Mistral AI, etc.)",t.Vertex_AI="Vertex AI (Anthropic, Gemini, etc.)",t.Databricks="Databricks",t.Ollama="Ollama";let eA={OpenAI:"openai",Azure:"azure",Azure_AI_Studio:"azure_ai",Anthropic:"anthropic",Google_AI_Studio:"gemini",Bedrock:"bedrock",OpenAI_Compatible:"openai",Vertex_AI:"vertex_ai",Databricks:"databricks",Ollama:"ollama"},eI={"BadRequestError (400)":"BadRequestErrorRetries","AuthenticationError (401)":"AuthenticationErrorRetries","TimeoutError (408)":"TimeoutErrorRetries","RateLimitError (429)":"RateLimitErrorRetries","ContentPolicyViolationError (400)":"ContentPolicyViolationErrorRetries","InternalServerError (500)":"InternalServerErrorRetries"},eC=async(e,l,s)=>{try{let t=Array.isArray(e.model)?e.model:[e.model];console.log("received deployments: ".concat(t)),console.log("received type of deployments: ".concat(typeof t)),t.forEach(async s=>{console.log("litellm_model: ".concat(s));let t={},n={};t.model=s;let a="";for(let[l,s]of(console.log("formValues add deployment:",e),Object.entries(e)))if(""!==s){if("model_name"==l)a+=s;else if("custom_llm_provider"==l)continue;else if("model"==l)continue;else if("base_model"===l)n[l]=s;else if("litellm_extra_params"==l){console.log("litellm_extra_params:",s);let e={};if(s&&void 0!=s){try{e=JSON.parse(s)}catch(e){throw k.ZP.error("Failed to parse LiteLLM Extra Params: "+e,10),Error("Failed to parse litellm_extra_params: "+e)}for(let[l,s]of Object.entries(e))t[l]=s}}else t[l]=s}let r={model_name:a,litellm_params:t,model_info:n},i=await (0,u.kK)(l,r);console.log("response for model create call: ".concat(i.data))}),s.resetFields()}catch(e){k.ZP.error("Failed to create model: "+e,10)}};var eP=e=>{var l,s,t;let i,{accessToken:o,token:d,userRole:c,userID:m,modelData:h={data:[]},keys:g,setModelData:Z,premiumUser:f}=e,[b,v]=(0,r.useState)([]),[N]=S.Z.useForm(),[C,P]=(0,r.useState)(null),[E,W]=(0,r.useState)(""),[H,G]=(0,r.useState)([]),Y=Object.values(n).filter(e=>isNaN(Number(e))),[J,X]=(0,r.useState)([]),[Q,ey]=(0,r.useState)("OpenAI"),[eb,eP]=(0,r.useState)(""),[eT,eO]=(0,r.useState)(!1),[eE,eR]=(0,r.useState)(!1),[eM,eF]=(0,r.useState)(null),[eD,eL]=(0,r.useState)([]),[eU,eV]=(0,r.useState)(null),[ez,eq]=(0,r.useState)([]),[eB,eK]=(0,r.useState)([]),[eW,eH]=(0,r.useState)([]),[eG,eY]=(0,r.useState)([]),[eJ,eX]=(0,r.useState)([]),[e$,eQ]=(0,r.useState)([]),[e0,e1]=(0,r.useState)([]),[e2,e4]=(0,r.useState)([]),[e5,e8]=(0,r.useState)([]),[e3,e6]=(0,r.useState)({from:new Date(Date.now()-6048e5),to:new Date}),[e9,e7]=(0,r.useState)(null),[le,ll]=(0,r.useState)(0),[ls,lt]=(0,r.useState)({}),[ln,la]=(0,r.useState)([]),[lr,li]=(0,r.useState)(!1),[lo,ld]=(0,r.useState)(null),[lc,lm]=(0,r.useState)(null),[lu,lh]=(0,r.useState)([]);(0,r.useEffect)(()=>{lb(eU,e3.from,e3.to)},[lo,lc]);let lx=e=>{eF(e),eO(!0)},lp=e=>{eF(e),eR(!0)},lj=async e=>{if(console.log("handleEditSubmit:",e),null==o)return;let l={},s=null;for(let[t,n]of Object.entries(e))"model_id"!==t?l[t]=n:s=n;let t={litellm_params:l,model_info:{id:s}};console.log("handleEditSubmit payload:",t);try{await (0,u.um)(o,t),k.ZP.success("Model updated successfully, restart server to see updates"),eO(!1),eF(null)}catch(e){console.log("Error occurred")}},lg=()=>{W(new Date().toLocaleString())},lZ=async()=>{if(!o){console.error("Access token is missing");return}console.log("new modelGroupRetryPolicy:",e9);try{await (0,u.K_)(o,{router_settings:{model_group_retry_policy:e9}}),k.ZP.success("Retry settings saved successfully")}catch(e){console.error("Failed to save retry settings:",e),k.ZP.error("Failed to save retry settings")}};if((0,r.useEffect)(()=>{if(!o||!d||!c||!m)return;let e=async()=>{try{var e,l,s,t,n,a,r,i,d,h,x,p;let j=await (0,u.hy)(o);X(j);let g=await (0,u.AZ)(o,m,c);console.log("Model data response:",g.data),Z(g);let f=new Set;for(let e=0;e0&&(y=_[_.length-1],console.log("_initial_model_group:",y),eV(y)),console.log("selectedModelGroup:",eU);let b=await (0,u.o6)(o,m,c,y,null===(e=e3.from)||void 0===e?void 0:e.toISOString(),null===(l=e3.to)||void 0===l?void 0:l.toISOString(),null==lo?void 0:lo.token,lc);console.log("Model metrics response:",b),eK(b.data),eH(b.all_api_bases);let v=await (0,u.Rg)(o,y,null===(s=e3.from)||void 0===s?void 0:s.toISOString(),null===(t=e3.to)||void 0===t?void 0:t.toISOString());eY(v.data),eX(v.all_api_bases);let S=await (0,u.N8)(o,m,c,y,null===(n=e3.from)||void 0===n?void 0:n.toISOString(),null===(a=e3.to)||void 0===a?void 0:a.toISOString(),null==lo?void 0:lo.token,lc);console.log("Model exceptions response:",S),eQ(S.data),e1(S.exception_types);let k=await (0,u.fP)(o,m,c,y,null===(r=e3.from)||void 0===r?void 0:r.toISOString(),null===(i=e3.to)||void 0===i?void 0:i.toISOString(),null==lo?void 0:lo.token,lc),w=await (0,u.n$)(o,null===(d=e3.from)||void 0===d?void 0:d.toISOString().split("T")[0],null===(h=e3.to)||void 0===h?void 0:h.toISOString().split("T")[0],y);lt(w);let N=await (0,u.v9)(o,null===(x=e3.from)||void 0===x?void 0:x.toISOString().split("T")[0],null===(p=e3.to)||void 0===p?void 0:p.toISOString().split("T")[0],y);la(N),console.log("dailyExceptions:",w),console.log("dailyExceptionsPerDeplyment:",N),console.log("slowResponses:",k),e8(k);let A=await (0,u.j2)(o);lh(null==A?void 0:A.end_users);let I=(await (0,u.BL)(o,m,c)).router_settings;console.log("routerSettingsInfo:",I);let C=I.model_group_retry_policy,P=I.num_retries;console.log("model_group_retry_policy:",C),console.log("default_retries:",P),e7(C),ll(P)}catch(e){console.error("There was an error fetching the model data",e)}};o&&d&&c&&m&&e();let l=async()=>{let e=await (0,u.qm)();console.log("received model cost map data: ".concat(Object.keys(e))),P(e)};null==C&&l(),lg()},[o,d,c,m,C,E]),!h||!o||!d||!c||!m)return(0,a.jsx)("div",{children:"Loading..."});let lf=[];for(let e=0;e(console.log("GET PROVIDER CALLED! - ".concat(C)),null!=C&&"object"==typeof C&&e in C)?C[e].litellm_provider:"openai";if(n){let e=n.split("/"),l=e[0];r=1===e.length?u(n):l}else r="openai";a&&(i=null==a?void 0:a.input_cost_per_token,o=null==a?void 0:a.output_cost_per_token,d=null==a?void 0:a.max_tokens,c=null==a?void 0:a.max_input_tokens),(null==t?void 0:t.litellm_params)&&(m=Object.fromEntries(Object.entries(null==t?void 0:t.litellm_params).filter(e=>{let[l]=e;return"model"!==l&&"api_base"!==l}))),h.data[e].provider=r,h.data[e].input_cost=i,h.data[e].output_cost=o,h.data[e].input_cost&&(h.data[e].input_cost=(1e6*Number(h.data[e].input_cost)).toFixed(2)),h.data[e].output_cost&&(h.data[e].output_cost=(1e6*Number(h.data[e].output_cost)).toFixed(2)),h.data[e].max_tokens=d,h.data[e].max_input_tokens=c,h.data[e].api_base=null==t?void 0:null===(s=t.litellm_params)||void 0===s?void 0:s.api_base,h.data[e].cleanedLitellmParams=m,lf.push(t.model_name),console.log(h.data[e])}if(c&&"Admin Viewer"==c){let{Title:e,Paragraph:l}=$.default;return(0,a.jsxs)("div",{children:[(0,a.jsx)(e,{level:1,children:"Access Denied"}),(0,a.jsx)(l,{children:"Ask your proxy admin for access to view all models"})]})}let l_=e=>{console.log("received provider string: ".concat(e));let l=Object.keys(n).find(l=>n[l]===e);if(l){let e=eA[l];console.log("mappingResult: ".concat(e));let s=[];"object"==typeof C&&Object.entries(C).forEach(l=>{let[t,n]=l;null!==n&&"object"==typeof n&&"litellm_provider"in n&&(n.litellm_provider===e||n.litellm_provider.includes(e))&&s.push(t)}),G(s),console.log("providerModels: ".concat(H))}},ly=async()=>{try{k.ZP.info("Running health check..."),eP("");let e=await (0,u.EY)(o);eP(e)}catch(e){console.error("Error running health check:",e),eP("Error running health check")}},lb=async(e,l,s)=>{if(console.log("Updating model metrics for group:",e),!o||!m||!c||!l||!s)return;console.log("inside updateModelMetrics - startTime:",l,"endTime:",s),eV(e);let t=null==lo?void 0:lo.token;void 0===t&&(t=null);let n=lc;void 0===n&&(n=null),l.setHours(0),l.setMinutes(0),l.setSeconds(0),s.setHours(23),s.setMinutes(59),s.setSeconds(59);try{let a=await (0,u.o6)(o,m,c,e,l.toISOString(),s.toISOString(),t,n);console.log("Model metrics response:",a),eK(a.data),eH(a.all_api_bases);let r=await (0,u.Rg)(o,e,l.toISOString(),s.toISOString());eY(r.data),eX(r.all_api_bases);let i=await (0,u.N8)(o,m,c,e,l.toISOString(),s.toISOString(),t,n);console.log("Model exceptions response:",i),eQ(i.data),e1(i.exception_types);let d=await (0,u.fP)(o,m,c,e,l.toISOString(),s.toISOString(),t,n);if(console.log("slowResponses:",d),e8(d),e){let t=await (0,u.n$)(o,null==l?void 0:l.toISOString().split("T")[0],null==s?void 0:s.toISOString().split("T")[0],e);lt(t);let n=await (0,u.v9)(o,null==l?void 0:l.toISOString().split("T")[0],null==s?void 0:s.toISOString().split("T")[0],e);la(n)}}catch(e){console.error("Failed to fetch model metrics",e)}},lv=(0,a.jsxs)("div",{children:[(0,a.jsx)(_.Z,{className:"mb-1",children:"Select API Key Name"}),f?(0,a.jsxs)("div",{children:[(0,a.jsxs)(B.Z,{defaultValue:"all-keys",children:[(0,a.jsx)(K.Z,{value:"all-keys",onClick:()=>{ld(null)},children:"All Keys"},"all-keys"),null==g?void 0:g.map((e,l)=>e&&null!==e.key_alias&&e.key_alias.length>0?(0,a.jsx)(K.Z,{value:String(l),onClick:()=>{ld(e)},children:e.key_alias},l):null)]}),(0,a.jsx)(_.Z,{className:"mt-1",children:"Select Customer Name"}),(0,a.jsxs)(B.Z,{defaultValue:"all-customers",children:[(0,a.jsx)(K.Z,{value:"all-customers",onClick:()=>{lm(null)},children:"All Customers"},"all-customers"),null==lu?void 0:lu.map((e,l)=>(0,a.jsx)(K.Z,{value:e,onClick:()=>{lm(e)},children:e},l))]})]}):(0,a.jsxs)("div",{children:[(0,a.jsxs)(B.Z,{defaultValue:"all-keys",children:[(0,a.jsx)(K.Z,{value:"all-keys",onClick:()=>{ld(null)},children:"All Keys"},"all-keys"),null==g?void 0:g.map((e,l)=>e&&null!==e.key_alias&&e.key_alias.length>0?(0,a.jsxs)(K.Z,{value:String(l),disabled:!0,onClick:()=>{ld(e)},children:["✨ ",e.key_alias," (Enterprise only Feature)"]},l):null)]}),(0,a.jsx)(_.Z,{className:"mt-1",children:"Select Customer Name"}),(0,a.jsxs)(B.Z,{defaultValue:"all-customers",children:[(0,a.jsx)(K.Z,{value:"all-customers",onClick:()=>{lm(null)},children:"All Customers"},"all-customers"),null==lu?void 0:lu.map((e,l)=>(0,a.jsxs)(K.Z,{value:e,disabled:!0,onClick:()=>{lm(e)},children:["✨ ",e," (Enterprise only Feature)"]},l))]})]})]}),lS=e=>{var l,s;let{payload:t,active:n}=e;if(!n||!t)return null;let r=null===(s=t[0])||void 0===s?void 0:null===(l=s.payload)||void 0===l?void 0:l.date,i=t.sort((e,l)=>l.value-e.value);if(i.length>5){let e=i.length-5;(i=i.slice(0,5)).push({dataKey:"".concat(e," other deployments"),value:t.slice(5).reduce((e,l)=>e+l.value,0),color:"gray"})}return(0,a.jsxs)("div",{className:"w-150 rounded-tremor-default border border-tremor-border bg-tremor-background p-2 text-tremor-default shadow-tremor-dropdown",children:[r&&(0,a.jsxs)("p",{className:"text-tremor-content-emphasis mb-2",children:["Date: ",r]}),i.map((e,l)=>{let s=parseFloat(e.value.toFixed(5)),t=0===s&&e.value>0?"<0.00001":s.toFixed(5);return(0,a.jsxs)("div",{className:"flex justify-between",children:[(0,a.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,a.jsx)("div",{className:"w-2 h-2 mt-1 rounded-full bg-".concat(e.color,"-500")}),(0,a.jsx)("p",{className:"text-tremor-content",children:e.dataKey})]}),(0,a.jsx)("p",{className:"font-medium text-tremor-content-emphasis text-righ ml-2",children:t})]},l)})]})};console.log("selectedProvider: ".concat(Q)),console.log("providerModels.length: ".concat(H.length));let lk=Object.keys(n).find(e=>n[e]===Q);return lk&&(i=J.find(e=>e.name===eA[lk])),(0,a.jsx)("div",{style:{width:"100%",height:"100%"},children:(0,a.jsxs)(et.Z,{className:"gap-2 p-8 h-[75vh] w-full mt-2",children:[(0,a.jsxs)(en.Z,{className:"flex justify-between mt-2 w-full items-center",children:[(0,a.jsxs)("div",{className:"flex",children:[(0,a.jsx)(es.Z,{children:"All Models"}),(0,a.jsx)(es.Z,{children:"Add Model"}),(0,a.jsx)(es.Z,{children:(0,a.jsx)("pre",{children:"/health Models"})}),(0,a.jsx)(es.Z,{children:"Model Analytics"}),(0,a.jsx)(es.Z,{children:"Model Retry Settings"})]}),(0,a.jsxs)("div",{className:"flex items-center space-x-2",children:[E&&(0,a.jsxs)(_.Z,{children:["Last Refreshed: ",E]}),(0,a.jsx)(F.Z,{icon:ej.Z,variant:"shadow",size:"xs",className:"self-center",onClick:lg})]})]}),(0,a.jsxs)(er.Z,{children:[(0,a.jsxs)(ea.Z,{children:[(0,a.jsxs)(x.Z,{children:[(0,a.jsxs)("div",{className:"flex items-center",children:[(0,a.jsx)(_.Z,{children:"Filter by Public Model Name"}),(0,a.jsxs)(B.Z,{className:"mb-4 mt-2 ml-2 w-50",defaultValue:eU||eD[0],onValueChange:e=>eV("all"===e?"all":e),value:eU||eD[0],children:[(0,a.jsx)(K.Z,{value:"all",children:"All Models"}),eD.map((e,l)=>(0,a.jsx)(K.Z,{value:e,onClick:()=>eV(e),children:e},l))]})]}),(0,a.jsx)(M.Z,{children:(0,a.jsxs)(D.Z,{style:{maxWidth:"1500px",width:"100%"},children:[(0,a.jsx)(V.Z,{children:(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(z.Z,{style:{maxWidth:"150px",whiteSpace:"normal",wordBreak:"break-word",fontSize:"11px"},children:"Public Model Name"}),(0,a.jsx)(z.Z,{style:{maxWidth:"100px",whiteSpace:"normal",wordBreak:"break-word",fontSize:"11px"},children:"Provider"}),"Admin"===c&&(0,a.jsx)(z.Z,{style:{maxWidth:"150px",whiteSpace:"normal",wordBreak:"break-word",fontSize:"11px"},children:"API Base"}),(0,a.jsxs)(z.Z,{style:{maxWidth:"85px",whiteSpace:"normal",wordBreak:"break-word",fontSize:"11px"},children:["Input Price"," ",(0,a.jsx)("p",{style:{fontSize:"10px",color:"gray"},children:"/1M Tokens ($)"})]}),(0,a.jsxs)(z.Z,{style:{maxWidth:"85px",whiteSpace:"normal",wordBreak:"break-word",fontSize:"11px"},children:["Output Price"," ",(0,a.jsx)("p",{style:{fontSize:"10px",color:"gray"},children:"/1M Tokens ($)"})]}),(0,a.jsx)(z.Z,{style:{maxWidth:"100px",whiteSpace:"normal",wordBreak:"break-word",fontSize:"11px"},children:f?"Created At":(0,a.jsxs)("a",{href:"https://forms.gle/W3U4PZpJGFHWtHyA9",target:"_blank",style:{color:"#72bcd4"},children:[" ","✨ Created At"]})}),(0,a.jsx)(z.Z,{style:{maxWidth:"100px",whiteSpace:"normal",wordBreak:"break-word",fontSize:"11px"},children:f?"Created By":(0,a.jsxs)("a",{href:"https://forms.gle/W3U4PZpJGFHWtHyA9",target:"_blank",style:{color:"#72bcd4"},children:[" ","✨ Created By"]})}),(0,a.jsx)(z.Z,{style:{maxWidth:"50px",whiteSpace:"normal",wordBreak:"break-word",fontSize:"11px"},children:"Status"}),(0,a.jsx)(z.Z,{})]})}),(0,a.jsx)(L.Z,{children:h.data.filter(e=>"all"===eU||e.model_name===eU||null==eU||""===eU).map((e,l)=>{var s;return(0,a.jsxs)(q.Z,{style:{maxHeight:"1px",minHeight:"1px"},children:[(0,a.jsx)(U.Z,{style:{maxWidth:"100px",whiteSpace:"normal",wordBreak:"break-word"},children:(0,a.jsx)("p",{className:"text-xs",children:e.model_name||"-"})}),(0,a.jsx)(U.Z,{style:{maxWidth:"100px",whiteSpace:"normal",wordBreak:"break-word"},children:(0,a.jsx)("p",{className:"text-xs",children:e.provider||"-"})}),"Admin"===c&&(0,a.jsx)(U.Z,{style:{maxWidth:"150px",whiteSpace:"normal",wordBreak:"break-word"},children:(0,a.jsx)(em.Z,{title:e&&e.api_base,children:(0,a.jsx)("pre",{style:{maxWidth:"150px",whiteSpace:"normal",wordBreak:"break-word"},className:"text-xs",title:e&&e.api_base?e.api_base:"",children:e&&e.api_base?e.api_base.slice(0,20):"-"})})}),(0,a.jsx)(U.Z,{style:{maxWidth:"80px",whiteSpace:"normal",wordBreak:"break-word"},children:(0,a.jsx)("pre",{className:"text-xs",children:e.input_cost?e.input_cost:null!=e.litellm_params.input_cost_per_token&&void 0!=e.litellm_params.input_cost_per_token?(1e6*Number(e.litellm_params.input_cost_per_token)).toFixed(2):null})}),(0,a.jsx)(U.Z,{style:{maxWidth:"80px",whiteSpace:"normal",wordBreak:"break-word"},children:(0,a.jsx)("pre",{className:"text-xs",children:e.output_cost?e.output_cost:e.litellm_params.output_cost_per_token?(1e6*Number(e.litellm_params.output_cost_per_token)).toFixed(2):null})}),(0,a.jsx)(U.Z,{children:(0,a.jsx)("p",{className:"text-xs",children:f&&((s=e.model_info.created_at)?new Date(s).toLocaleDateString("en-US"):null)||"-"})}),(0,a.jsx)(U.Z,{children:(0,a.jsx)("p",{className:"text-xs",children:f&&e.model_info.created_by||"-"})}),(0,a.jsx)(U.Z,{style:{maxWidth:"100px",whiteSpace:"normal",wordBreak:"break-word"},children:e.model_info.db_model?(0,a.jsx)(R.Z,{size:"xs",className:"text-white",children:(0,a.jsx)("p",{className:"text-xs",children:"DB Model"})}):(0,a.jsx)(R.Z,{size:"xs",className:"text-black",children:(0,a.jsx)("p",{className:"text-xs",children:"Config Model"})})}),(0,a.jsx)(U.Z,{style:{maxWidth:"150px",whiteSpace:"normal",wordBreak:"break-word"},children:(0,a.jsxs)(x.Z,{numItems:3,children:[(0,a.jsx)(eu.Z,{children:(0,a.jsx)(F.Z,{icon:T.Z,size:"sm",onClick:()=>lp(e)})}),(0,a.jsx)(eu.Z,{children:(0,a.jsx)(F.Z,{icon:O.Z,size:"sm",onClick:()=>lx(e)})}),(0,a.jsx)(eu.Z,{children:(0,a.jsx)(eZ,{modelID:e.model_info.id,accessToken:o})})]})})]},l)})})]})})]}),(0,a.jsx)(e=>{let{visible:l,onCancel:s,model:t,onSubmit:n}=e,[r]=S.Z.useForm(),i={},o="",d="";if(t){i=t.litellm_params,o=t.model_name;let e=t.model_info;e&&(d=e.id,console.log("model_id: ".concat(d)),i.model_id=d)}return(0,a.jsx)(w.Z,{title:"Edit Model "+o,visible:l,width:800,footer:null,onOk:()=>{r.validateFields().then(e=>{n(e),r.resetFields()}).catch(e=>{console.error("Validation failed:",e)})},onCancel:s,children:(0,a.jsxs)(S.Z,{form:r,onFinish:lj,initialValues:i,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(S.Z.Item,{className:"mt-8",label:"api_base",name:"api_base",children:(0,a.jsx)(j.Z,{})}),(0,a.jsx)(S.Z.Item,{label:"tpm",name:"tpm",tooltip:"int (optional) - Tokens limit for this deployment: in tokens per minute (tpm). Find this information on your model/providers website",children:(0,a.jsx)(A.Z,{min:0,step:1})}),(0,a.jsx)(S.Z.Item,{label:"rpm",name:"rpm",tooltip:"int (optional) - Rate limit for this deployment: in requests per minute (rpm). Find this information on your model/providers website",children:(0,a.jsx)(A.Z,{min:0,step:1})}),(0,a.jsx)(S.Z.Item,{label:"max_retries",name:"max_retries",children:(0,a.jsx)(A.Z,{min:0,step:1})}),(0,a.jsx)(S.Z.Item,{label:"timeout",name:"timeout",tooltip:"int (optional) - Timeout in seconds for LLM requests (Defaults to 600 seconds)",children:(0,a.jsx)(A.Z,{min:0,step:1})}),(0,a.jsx)(S.Z.Item,{label:"stream_timeout",name:"stream_timeout",tooltip:"int (optional) - Timeout for stream requests (seconds)",children:(0,a.jsx)(A.Z,{min:0,step:1})}),(0,a.jsx)(S.Z.Item,{label:"input_cost_per_token",name:"input_cost_per_token",tooltip:"float (optional) - Input cost per token",children:(0,a.jsx)(A.Z,{min:0,step:1e-4})}),(0,a.jsx)(S.Z.Item,{label:"output_cost_per_token",name:"output_cost_per_token",tooltip:"float (optional) - Output cost per token",children:(0,a.jsx)(A.Z,{min:0,step:1e-4})}),(0,a.jsx)(S.Z.Item,{label:"model_id",name:"model_id",hidden:!0})]}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(I.ZP,{htmlType:"submit",children:"Save"})})]})})},{visible:eT,onCancel:()=>{eO(!1),eF(null)},model:eM,onSubmit:lj}),(0,a.jsxs)(w.Z,{title:eM&&eM.model_name,visible:eE,width:800,footer:null,onCancel:()=>{eR(!1),eF(null)},children:[(0,a.jsx)(y.Z,{children:"Model Info"}),(0,a.jsx)(ek.Z,{language:"json",children:eM&&JSON.stringify(eM,null,2)})]})]}),(0,a.jsxs)(ea.Z,{className:"h-full",children:[(0,a.jsx)(ew,{level:2,children:"Add new model"}),(0,a.jsx)(M.Z,{children:(0,a.jsxs)(S.Z,{form:N,onFinish:()=>{N.validateFields().then(e=>{eC(e,o,N)}).catch(e=>{console.error("Validation failed:",e)})},labelCol:{span:10},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(S.Z.Item,{rules:[{required:!0,message:"Required"}],label:"Provider:",name:"custom_llm_provider",tooltip:"E.g. OpenAI, Azure OpenAI, Anthropic, Bedrock, etc.",labelCol:{span:10},labelAlign:"left",children:(0,a.jsx)(B.Z,{value:Q.toString(),children:Y.map((e,l)=>(0,a.jsx)(K.Z,{value:e,onClick:()=>{l_(e),ey(e)},children:e},l))})}),(0,a.jsx)(S.Z.Item,{rules:[{required:!0,message:"Required"}],label:"Public Model Name",name:"model_name",tooltip:"Model name your users will pass in. Also used for load-balancing, LiteLLM will load balance between all models with this public name.",className:"mb-0",children:(0,a.jsx)(j.Z,{placeholder:"Vertex AI (Anthropic, Gemini, etc.)"===(t=Q.toString())?"gemini-pro":"Anthropic"==t||"Amazon Bedrock"==t?"claude-3-opus":"Google AI Studio"==t?"gemini-pro":"Azure AI Studio"==t?"azure_ai/command-r-plus":"Azure"==t?"azure/my-deployment":"gpt-3.5-turbo"})}),(0,a.jsxs)(eh.Z,{children:[(0,a.jsx)(eu.Z,{span:10}),(0,a.jsx)(eu.Z,{span:10,children:(0,a.jsx)(_.Z,{className:"mb-3 mt-1",children:"Model name your users will pass in."})})]}),(0,a.jsx)(S.Z.Item,{rules:[{required:!0,message:"Required"}],label:"LiteLLM Model Name(s)",name:"model",tooltip:"Actual model name used for making litellm.completion() call.",className:"mb-0",children:"Azure"===Q?(0,a.jsx)(j.Z,{placeholder:"Enter model name"}):H.length>0?(0,a.jsx)(ei.Z,{value:H,children:H.map((e,l)=>(0,a.jsx)(eo.Z,{value:e,children:e},l))}):(0,a.jsx)(j.Z,{placeholder:"gpt-3.5-turbo-0125"})}),(0,a.jsxs)(eh.Z,{children:[(0,a.jsx)(eu.Z,{span:10}),(0,a.jsx)(eu.Z,{span:10,children:(0,a.jsxs)(_.Z,{className:"mb-3 mt-1",children:["Actual model name used for making"," ",(0,a.jsx)(eN,{href:"https://docs.litellm.ai/docs/providers",target:"_blank",children:"litellm.completion() call"}),". We'll"," ",(0,a.jsx)(eN,{href:"https://docs.litellm.ai/docs/proxy/reliability#step-1---set-deployments-on-config",target:"_blank",children:"loadbalance"})," ","models with the same 'public name'"]})})]}),void 0!==i&&i.fields.length>0&&(0,a.jsx)(eS,{fields:i.fields,selectedProvider:i.name}),"Amazon Bedrock"!=Q&&"Vertex AI (Anthropic, Gemini, etc.)"!=Q&&"Ollama"!=Q&&(void 0===i||0==i.fields.length)&&(0,a.jsx)(S.Z.Item,{rules:[{required:!0,message:"Required"}],label:"API Key",name:"api_key",children:(0,a.jsx)(j.Z,{placeholder:"sk-",type:"password"})}),"OpenAI"==Q&&(0,a.jsx)(S.Z.Item,{label:"Organization ID",name:"organization_id",children:(0,a.jsx)(j.Z,{placeholder:"[OPTIONAL] my-unique-org"})}),"Vertex AI (Anthropic, Gemini, etc.)"==Q&&(0,a.jsx)(S.Z.Item,{rules:[{required:!0,message:"Required"}],label:"Vertex Project",name:"vertex_project",children:(0,a.jsx)(j.Z,{placeholder:"adroit-cadet-1234.."})}),"Vertex AI (Anthropic, Gemini, etc.)"==Q&&(0,a.jsx)(S.Z.Item,{rules:[{required:!0,message:"Required"}],label:"Vertex Location",name:"vertex_location",children:(0,a.jsx)(j.Z,{placeholder:"us-east-1"})}),"Vertex AI (Anthropic, Gemini, etc.)"==Q&&(0,a.jsx)(S.Z.Item,{rules:[{required:!0,message:"Required"}],label:"Vertex Credentials",name:"vertex_credentials",className:"mb-0",children:(0,a.jsx)(e_.Z,{name:"file",accept:".json",beforeUpload:e=>{if("application/json"===e.type){let l=new FileReader;l.onload=e=>{if(e.target){let l=e.target.result;N.setFieldsValue({vertex_credentials:l})}},l.readAsText(e)}return!1},onChange(e){"uploading"!==e.file.status&&console.log(e.file,e.fileList),"done"===e.file.status?k.ZP.success("".concat(e.file.name," file uploaded successfully")):"error"===e.file.status&&k.ZP.error("".concat(e.file.name," file upload failed."))},children:(0,a.jsx)(I.ZP,{icon:(0,a.jsx)(ef.Z,{}),children:"Click to Upload"})})}),"Vertex AI (Anthropic, Gemini, etc.)"==Q&&(0,a.jsxs)(eh.Z,{children:[(0,a.jsx)(eu.Z,{span:10}),(0,a.jsx)(eu.Z,{span:10,children:(0,a.jsx)(_.Z,{className:"mb-3 mt-1",children:"Give litellm a gcp service account(.json file), so it can make the relevant calls"})})]}),("Azure"==Q||"OpenAI-Compatible Endpoints (Groq, Together AI, Mistral AI, etc.)"==Q)&&(0,a.jsx)(S.Z.Item,{rules:[{required:!0,message:"Required"}],label:"API Base",name:"api_base",children:(0,a.jsx)(j.Z,{placeholder:"https://..."})}),"Azure"==Q&&(0,a.jsx)(S.Z.Item,{rules:[{required:!0,message:"Required"}],label:"API Version",name:"api_version",children:(0,a.jsx)(j.Z,{placeholder:"2023-07-01-preview"})}),"Azure"==Q&&(0,a.jsxs)("div",{children:[(0,a.jsx)(S.Z.Item,{label:"Base Model",name:"base_model",className:"mb-0",children:(0,a.jsx)(j.Z,{placeholder:"azure/gpt-3.5-turbo"})}),(0,a.jsxs)(eh.Z,{children:[(0,a.jsx)(eu.Z,{span:10}),(0,a.jsx)(eu.Z,{span:10,children:(0,a.jsxs)(_.Z,{className:"mb-2",children:["The actual model your azure deployment uses. Used for accurate cost tracking. Select name from"," ",(0,a.jsx)(eN,{href:"https://github.com/BerriAI/litellm/blob/main/model_prices_and_context_window.json",target:"_blank",children:"here"})]})})]})]}),"Amazon Bedrock"==Q&&(0,a.jsx)(S.Z.Item,{rules:[{required:!0,message:"Required"}],label:"AWS Access Key ID",name:"aws_access_key_id",tooltip:"You can provide the raw key or the environment variable (e.g. `os.environ/MY_SECRET_KEY`).",children:(0,a.jsx)(j.Z,{placeholder:""})}),"Amazon Bedrock"==Q&&(0,a.jsx)(S.Z.Item,{rules:[{required:!0,message:"Required"}],label:"AWS Secret Access Key",name:"aws_secret_access_key",tooltip:"You can provide the raw key or the environment variable (e.g. `os.environ/MY_SECRET_KEY`).",children:(0,a.jsx)(j.Z,{placeholder:""})}),"Amazon Bedrock"==Q&&(0,a.jsx)(S.Z.Item,{rules:[{required:!0,message:"Required"}],label:"AWS Region Name",name:"aws_region_name",tooltip:"You can provide the raw key or the environment variable (e.g. `os.environ/MY_SECRET_KEY`).",children:(0,a.jsx)(j.Z,{placeholder:"us-east-1"})}),(0,a.jsx)(S.Z.Item,{label:"LiteLLM Params",name:"litellm_extra_params",tooltip:"Optional litellm params used for making a litellm.completion() call.",className:"mb-0",children:(0,a.jsx)(ep.Z,{rows:4,placeholder:'{ "rpm": 100, "timeout": 0, "stream_timeout": 0 }'})}),(0,a.jsxs)(eh.Z,{children:[(0,a.jsx)(eu.Z,{span:10}),(0,a.jsx)(eu.Z,{span:10,children:(0,a.jsxs)(_.Z,{className:"mb-3 mt-1",children:["Pass JSON of litellm supported params"," ",(0,a.jsx)(eN,{href:"https://docs.litellm.ai/docs/completion/input",target:"_blank",children:"litellm.completion() call"})]})})]})]}),(0,a.jsx)("div",{style:{textAlign:"center",marginTop:"10px"},children:(0,a.jsx)(I.ZP,{htmlType:"submit",children:"Add Model"})}),(0,a.jsx)(em.Z,{title:"Get help on our github",children:(0,a.jsx)($.default.Link,{href:"https://github.com/BerriAI/litellm/issues",children:"Need Help?"})})]})})]}),(0,a.jsx)(ea.Z,{children:(0,a.jsxs)(M.Z,{children:[(0,a.jsx)(_.Z,{children:"`/health` will run a very small request through your models configured on litellm"}),(0,a.jsx)(p.Z,{onClick:ly,children:"Run `/health`"}),eb&&(0,a.jsx)("pre",{children:JSON.stringify(eb,null,2)})]})}),(0,a.jsxs)(ea.Z,{children:[(0,a.jsxs)(x.Z,{numItems:4,className:"mt-2 mb-2",children:[(0,a.jsxs)(eu.Z,{children:[(0,a.jsx)(_.Z,{children:"Select Time Range"}),(0,a.jsx)(el.Z,{enableSelect:!0,value:e3,className:"mr-2",onValueChange:e=>{e6(e),lb(eU,e.from,e.to)}})]}),(0,a.jsxs)(eu.Z,{className:"ml-2",children:[(0,a.jsx)(_.Z,{children:"Select Model Group"}),(0,a.jsx)(B.Z,{defaultValue:eU||eD[0],value:eU||eD[0],children:eD.map((e,l)=>(0,a.jsx)(K.Z,{value:e,onClick:()=>lb(e,e3.from,e3.to),children:e},l))})]}),(0,a.jsx)(eu.Z,{children:(0,a.jsx)(ex.Z,{trigger:"click",content:lv,overlayStyle:{width:"20vw"},children:(0,a.jsx)(p.Z,{icon:eg.Z,size:"md",variant:"secondary",className:"mt-4 ml-2",style:{border:"none"},onClick:()=>li(!0)})})})]}),(0,a.jsxs)(x.Z,{numItems:2,children:[(0,a.jsx)(eu.Z,{children:(0,a.jsx)(M.Z,{className:"mr-2 max-h-[400px] min-h-[400px]",children:(0,a.jsxs)(et.Z,{children:[(0,a.jsxs)(en.Z,{variant:"line",defaultValue:"1",children:[(0,a.jsx)(es.Z,{value:"1",children:"Avg. Latency per Token"}),(0,a.jsx)(es.Z,{value:"2",children:"✨ Time to first token"})]}),(0,a.jsxs)(er.Z,{children:[(0,a.jsxs)(ea.Z,{children:[(0,a.jsx)("p",{className:"text-gray-500 italic",children:" (seconds/token)"}),(0,a.jsx)(_.Z,{className:"text-gray-500 italic mt-1 mb-1",children:"average Latency for successfull requests divided by the total tokens"}),eB&&eW&&(0,a.jsx)(ed.Z,{title:"Model Latency",className:"h-72",data:eB,showLegend:!1,index:"date",categories:eW,connectNulls:!0,customTooltip:lS})]}),(0,a.jsx)(ea.Z,{children:(0,a.jsx)(ev,{modelMetrics:eG,modelMetricsCategories:eJ,customTooltip:lS,premiumUser:f})})]})]})})}),(0,a.jsx)(eu.Z,{children:(0,a.jsx)(M.Z,{className:"ml-2 max-h-[400px] min-h-[400px] overflow-y-auto",children:(0,a.jsxs)(D.Z,{children:[(0,a.jsx)(V.Z,{children:(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(z.Z,{children:"Deployment"}),(0,a.jsx)(z.Z,{children:"Success Responses"}),(0,a.jsxs)(z.Z,{children:["Slow Responses ",(0,a.jsx)("p",{children:"Success Responses taking 600+s"})]})]})}),(0,a.jsx)(L.Z,{children:e5.map((e,l)=>(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(U.Z,{children:e.api_base}),(0,a.jsx)(U.Z,{children:e.total_count}),(0,a.jsx)(U.Z,{children:e.slow_count})]},l))})]})})})]}),(0,a.jsx)(x.Z,{numItems:1,className:"gap-2 w-full mt-2",children:(0,a.jsxs)(M.Z,{children:[(0,a.jsxs)(y.Z,{children:["All Exceptions for ",eU]}),(0,a.jsx)(ec.Z,{className:"h-60",data:e$,index:"model",categories:e0,stack:!0,yAxisWidth:30})]})}),(0,a.jsxs)(x.Z,{numItems:1,className:"gap-2 w-full mt-2",children:[(0,a.jsxs)(M.Z,{children:[(0,a.jsxs)(y.Z,{children:["All Up Rate Limit Errors (429) for ",eU]}),(0,a.jsxs)(x.Z,{numItems:1,children:[(0,a.jsxs)(eu.Z,{children:[(0,a.jsxs)(ee.Z,{style:{fontSize:"15px",fontWeight:"normal",color:"#535452"},children:["Num Rate Limit Errors ",ls.sum_num_rate_limit_exceptions]}),(0,a.jsx)(ec.Z,{className:"h-40",data:ls.daily_data,index:"date",colors:["rose"],categories:["num_rate_limit_exceptions"],onValueChange:e=>console.log(e)})]}),(0,a.jsx)(eu.Z,{})]})]}),f?(0,a.jsx)(a.Fragment,{children:ln.map((e,l)=>(0,a.jsxs)(M.Z,{children:[(0,a.jsx)(y.Z,{children:e.api_base?e.api_base:"Unknown API Base"}),(0,a.jsx)(x.Z,{numItems:1,children:(0,a.jsxs)(eu.Z,{children:[(0,a.jsxs)(ee.Z,{style:{fontSize:"15px",fontWeight:"normal",color:"#535452"},children:["Num Rate Limit Errors (429) ",e.sum_num_rate_limit_exceptions]}),(0,a.jsx)(ec.Z,{className:"h-40",data:e.daily_data,index:"date",colors:["rose"],categories:["num_rate_limit_exceptions"],onValueChange:e=>console.log(e)})]})})]},l))}):(0,a.jsx)(a.Fragment,{children:ln&&ln.length>0&&ln.slice(0,1).map((e,l)=>(0,a.jsxs)(M.Z,{children:[(0,a.jsx)(y.Z,{children:"✨ Rate Limit Errors by Deployment"}),(0,a.jsx)("p",{className:"mb-2 text-gray-500 italic text-[12px]",children:"Upgrade to see exceptions for all deployments"}),(0,a.jsx)(p.Z,{variant:"primary",className:"mb-2",children:(0,a.jsx)("a",{href:"https://forms.gle/W3U4PZpJGFHWtHyA9",target:"_blank",children:"Get Free Trial"})}),(0,a.jsxs)(M.Z,{children:[(0,a.jsx)(y.Z,{children:e.api_base}),(0,a.jsx)(x.Z,{numItems:1,children:(0,a.jsxs)(eu.Z,{children:[(0,a.jsxs)(ee.Z,{style:{fontSize:"15px",fontWeight:"normal",color:"#535452"},children:["Num Rate Limit Errors ",e.sum_num_rate_limit_exceptions]}),(0,a.jsx)(ec.Z,{className:"h-40",data:e.daily_data,index:"date",colors:["rose"],categories:["num_rate_limit_exceptions"],onValueChange:e=>console.log(e)})]})})]})]},l))})]})]}),(0,a.jsxs)(ea.Z,{children:[(0,a.jsxs)("div",{className:"flex items-center",children:[(0,a.jsx)(_.Z,{children:"Filter by Public Model Name"}),(0,a.jsx)(B.Z,{className:"mb-4 mt-2 ml-2 w-50",defaultValue:eU||eD[0],value:eU||eD[0],onValueChange:e=>eV(e),children:eD.map((e,l)=>(0,a.jsx)(K.Z,{value:e,onClick:()=>eV(e),children:e},l))})]}),(0,a.jsxs)(y.Z,{children:["Retry Policy for ",eU]}),(0,a.jsx)(_.Z,{className:"mb-6",children:"How many retries should be attempted based on the Exception"}),eI&&(0,a.jsx)("table",{children:(0,a.jsx)("tbody",{children:Object.entries(eI).map((e,l)=>{var s;let[t,n]=e,r=null==e9?void 0:null===(s=e9[eU])||void 0===s?void 0:s[n];return null==r&&(r=le),(0,a.jsxs)("tr",{className:"flex justify-between items-center mt-2",children:[(0,a.jsx)("td",{children:(0,a.jsx)(_.Z,{children:t})}),(0,a.jsx)("td",{children:(0,a.jsx)(A.Z,{className:"ml-5",value:r,min:0,step:1,onChange:e=>{e7(l=>{var s;let t=null!==(s=null==l?void 0:l[eU])&&void 0!==s?s:{};return{...null!=l?l:{},[eU]:{...t,[n]:e}}})}})})]},l)})})}),(0,a.jsx)(p.Z,{className:"mt-6 mr-8",onClick:lZ,children:"Save"})]})]})]})})},eT=e=>{let{isInvitationLinkModalVisible:l,setIsInvitationLinkModalVisible:s,baseUrl:t,invitationLinkData:n}=e,{Title:r,Paragraph:i}=$.default;return(0,a.jsxs)(w.Z,{title:"Invitation Link",visible:l,width:800,footer:null,onOk:()=>{s(!1)},onCancel:()=>{s(!1)},children:[(0,a.jsx)(i,{children:"Copy and send the generated link to onboard this user to the proxy."}),(0,a.jsxs)("div",{className:"flex justify-between pt-5 pb-2",children:[(0,a.jsx)(_.Z,{className:"text-base",children:"User ID"}),(0,a.jsx)(_.Z,{children:null==n?void 0:n.user_id})]}),(0,a.jsxs)("div",{className:"flex justify-between pt-5 pb-2",children:[(0,a.jsx)(_.Z,{children:"Invitation Link"}),(0,a.jsxs)(_.Z,{children:[t,"/ui/onboarding?id=",null==n?void 0:n.id]})]}),(0,a.jsxs)("div",{className:"flex justify-end mt-5",children:[(0,a.jsx)("div",{}),(0,a.jsx)(b.CopyToClipboard,{text:"".concat(t,"/ui/onboarding?id=").concat(null==n?void 0:n.id),onCopy:()=>k.ZP.success("Copied!"),children:(0,a.jsx)(p.Z,{variant:"primary",children:"Copy invitation link"})})]})]})};let{Option:eO}=v.default;var eE=e=>{let{userID:l,accessToken:s,teams:t,possibleUIRoles:n}=e,[o]=S.Z.useForm(),[d,c]=(0,r.useState)(!1),[m,h]=(0,r.useState)(null),[x,g]=(0,r.useState)([]),[Z,f]=(0,r.useState)(!1),[y,b]=(0,r.useState)(null),A=(0,i.useRouter)(),[C,P]=(0,r.useState)("");(0,r.useEffect)(()=>{(async()=>{try{let e=await (0,u.So)(s,l,"any"),t=[];for(let l=0;l{if(A){let{protocol:e,host:l}=window.location;P("".concat(e,"/").concat(l))}},[A]);let T=async e=>{try{var t;k.ZP.info("Making API Call"),c(!0),console.log("formValues in create user:",e);let n=await (0,u.Ov)(s,null,e);console.log("user create Response:",n),h(n.key);let a=(null===(t=n.data)||void 0===t?void 0:t.user_id)||n.user_id;(0,u.XO)(s,a).then(e=>{b(e),f(!0)}),k.ZP.success("API user Created"),o.resetFields(),localStorage.removeItem("userData"+l)}catch(e){console.error("Error creating the user:",e)}};return(0,a.jsxs)("div",{children:[(0,a.jsx)(p.Z,{className:"mx-auto mb-0",onClick:()=>c(!0),children:"+ Invite User"}),(0,a.jsxs)(w.Z,{title:"Invite User",visible:d,width:800,footer:null,onOk:()=>{c(!1),o.resetFields()},onCancel:()=>{c(!1),h(null),o.resetFields()},children:[(0,a.jsx)(_.Z,{className:"mb-1",children:"Create a User who can own keys"}),(0,a.jsxs)(S.Z,{form:o,onFinish:T,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsx)(S.Z.Item,{label:"User Email",name:"user_email",children:(0,a.jsx)(j.Z,{placeholder:""})}),(0,a.jsx)(S.Z.Item,{label:"User Role",name:"user_role",children:(0,a.jsx)(v.default,{children:n&&Object.entries(n).map(e=>{let[l,{ui_label:s,description:t}]=e;return(0,a.jsx)(K.Z,{value:l,title:s,children:(0,a.jsxs)("div",{className:"flex",children:[s," ",(0,a.jsx)("p",{className:"ml-2",style:{color:"gray",fontSize:"12px"},children:t})]})},l)})})}),(0,a.jsx)(S.Z.Item,{label:"Team ID",name:"team_id",children:(0,a.jsx)(v.default,{placeholder:"Select Team ID",style:{width:"100%"},children:t?t.map(e=>(0,a.jsx)(eO,{value:e.team_id,children:e.team_alias},e.team_id)):(0,a.jsx)(eO,{value:null,children:"Default Team"},"default")})}),(0,a.jsx)(S.Z.Item,{label:"Metadata",name:"metadata",children:(0,a.jsx)(N.Z.TextArea,{rows:4,placeholder:"Enter metadata as JSON"})}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(I.ZP,{htmlType:"submit",children:"Create User"})})]})]}),m&&(0,a.jsx)(eT,{isInvitationLinkModalVisible:Z,setIsInvitationLinkModalVisible:f,baseUrl:C,invitationLinkData:y})]})},eR=e=>{let{visible:l,possibleUIRoles:s,onCancel:t,user:n,onSubmit:i}=e,[o,d]=(0,r.useState)(n),[c]=S.Z.useForm();(0,r.useEffect)(()=>{c.resetFields()},[n]);let m=async()=>{c.resetFields(),t()},u=async e=>{i(e),c.resetFields(),t()};return n?(0,a.jsx)(w.Z,{visible:l,onCancel:m,footer:null,title:"Edit User "+n.user_id,width:1e3,children:(0,a.jsx)(S.Z,{form:c,onFinish:u,initialValues:n,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(S.Z.Item,{className:"mt-8",label:"User Email",tooltip:"Email of the User",name:"user_email",children:(0,a.jsx)(j.Z,{})}),(0,a.jsx)(S.Z.Item,{label:"user_id",name:"user_id",hidden:!0,children:(0,a.jsx)(j.Z,{})}),(0,a.jsx)(S.Z.Item,{label:"User Role",name:"user_role",children:(0,a.jsx)(v.default,{children:s&&Object.entries(s).map(e=>{let[l,{ui_label:s,description:t}]=e;return(0,a.jsx)(K.Z,{value:l,title:s,children:(0,a.jsxs)("div",{className:"flex",children:[s," ",(0,a.jsx)("p",{className:"ml-2",style:{color:"gray",fontSize:"12px"},children:t})]})},l)})})}),(0,a.jsx)(S.Z.Item,{label:"Spend (USD)",name:"spend",tooltip:"(float) - Spend of all LLM calls completed by this user",children:(0,a.jsx)(A.Z,{min:0,step:1})}),(0,a.jsx)(S.Z.Item,{label:"User Budget (USD)",name:"max_budget",tooltip:"(float) - Maximum budget of this user",children:(0,a.jsx)(A.Z,{min:0,step:1})}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(I.ZP,{htmlType:"submit",children:"Save"})})]})})}):null},eM=e=>{let{accessToken:l,token:s,keys:t,userRole:n,userID:i,teams:o,setKeys:d}=e,[c,m]=(0,r.useState)(null),[h,p]=(0,r.useState)(null),[j,g]=(0,r.useState)(0),[Z,f]=r.useState(null),[_,y]=(0,r.useState)(null),[b,v]=(0,r.useState)(!1),[S,w]=(0,r.useState)(null),[N,A]=(0,r.useState)({}),I=async()=>{w(null),v(!1)},C=async e=>{if(console.log("inside handleEditSubmit:",e),l&&s&&n&&i){try{await (0,u.pf)(l,e,null),k.ZP.success("User ".concat(e.user_id," updated successfully"))}catch(e){console.error("There was an error updating the user",e)}c&&m(c.map(l=>l.user_id===e.user_id?e:l)),w(null),v(!1)}};return((0,r.useEffect)(()=>{if(!l||!s||!n||!i)return;let e=async()=>{try{let e=await (0,u.Br)(l,null,n,!0,j,25);console.log("user data response:",e),m(e);let s=await (0,u.lg)(l);A(s)}catch(e){console.error("There was an error fetching the model data",e)}};l&&s&&n&&i&&e()},[l,s,n,i,j]),c&&l&&s&&n&&i)?(0,a.jsx)("div",{style:{width:"100%"},children:(0,a.jsxs)(x.Z,{className:"gap-2 p-2 h-[90vh] w-full mt-8",children:[(0,a.jsx)(eE,{userID:i,accessToken:l,teams:o,possibleUIRoles:N}),(0,a.jsxs)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[90vh] mb-4",children:[(0,a.jsx)("div",{className:"mb-4 mt-1"}),(0,a.jsx)(et.Z,{children:(0,a.jsxs)(er.Z,{children:[(0,a.jsx)(ea.Z,{children:(0,a.jsxs)(D.Z,{className:"mt-5",children:[(0,a.jsx)(V.Z,{children:(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(z.Z,{children:"User ID"}),(0,a.jsx)(z.Z,{children:"User Email"}),(0,a.jsx)(z.Z,{children:"Role"}),(0,a.jsx)(z.Z,{children:"User Spend ($ USD)"}),(0,a.jsx)(z.Z,{children:"User Max Budget ($ USD)"}),(0,a.jsx)(z.Z,{children:"API Keys"}),(0,a.jsx)(z.Z,{})]})}),(0,a.jsx)(L.Z,{children:c.map(e=>{var l,s;return(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(U.Z,{children:e.user_id||"-"}),(0,a.jsx)(U.Z,{children:e.user_email||"-"}),(0,a.jsx)(U.Z,{children:(null==N?void 0:null===(l=N[null==e?void 0:e.user_role])||void 0===l?void 0:l.ui_label)||"-"}),(0,a.jsx)(U.Z,{children:e.spend?null===(s=e.spend)||void 0===s?void 0:s.toFixed(2):"-"}),(0,a.jsx)(U.Z,{children:e.max_budget?e.max_budget:"Unlimited"}),(0,a.jsx)(U.Z,{children:(0,a.jsx)(x.Z,{numItems:2,children:e&&e.key_aliases&&e.key_aliases.filter(e=>null!==e).length>0?(0,a.jsxs)(R.Z,{size:"xs",color:"indigo",children:[e.key_aliases.filter(e=>null!==e).length,"\xa0Keys"]}):(0,a.jsx)(R.Z,{size:"xs",color:"gray",children:"No Keys"})})}),(0,a.jsx)(U.Z,{children:(0,a.jsx)(F.Z,{icon:O.Z,onClick:()=>{w(e),v(!0)},children:"View Keys"})})]},e.user_id)})})]})}),(0,a.jsx)(ea.Z,{children:(0,a.jsxs)("div",{className:"flex items-center",children:[(0,a.jsx)("div",{className:"flex-1"}),(0,a.jsx)("div",{className:"flex-1 flex justify-between items-center"})]})})]})}),(0,a.jsx)(eR,{visible:b,possibleUIRoles:N,onCancel:I,user:S,onSubmit:C})]}),function(){if(!c)return null;let e=Math.ceil(c.length/25);return(0,a.jsxs)("div",{className:"flex justify-between items-center",children:[(0,a.jsxs)("div",{children:["Showing Page ",j+1," of ",e]}),(0,a.jsxs)("div",{className:"flex",children:[(0,a.jsx)("button",{className:"bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-l focus:outline-none",disabled:0===j,onClick:()=>g(j-1),children:"← Prev"}),(0,a.jsx)("button",{className:"bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-r focus:outline-none",onClick:()=>{g(j+1)},children:"Next →"})]})]})}()]})}):(0,a.jsx)("div",{children:"Loading..."})},eF=e=>{let{teams:l,searchParams:s,accessToken:t,setTeams:n,userID:i,userRole:o}=e,[d]=S.Z.useForm(),[c]=S.Z.useForm(),{Title:m,Paragraph:g}=$.default,[Z,f]=(0,r.useState)(""),[y,b]=(0,r.useState)(!1),[C,P]=(0,r.useState)(l?l[0]:null),[T,W]=(0,r.useState)(!1),[H,G]=(0,r.useState)(!1),[Y,J]=(0,r.useState)([]),[X,Q]=(0,r.useState)(!1),[ee,el]=(0,r.useState)(null),[es,et]=(0,r.useState)({}),en=e=>{P(e),b(!0)},ea=async e=>{let s=e.team_id;if(console.log("handleEditSubmit:",e),null==t)return;let a=await (0,u.Gh)(t,e);l&&n(l.map(e=>e.team_id===s?a.data:e)),k.ZP.success("Team updated successfully"),b(!1),P(null)},er=async e=>{el(e),Q(!0)},ei=async()=>{if(null!=ee&&null!=l&&null!=t){try{await (0,u.rs)(t,ee);let e=l.filter(e=>e.team_id!==ee);n(e)}catch(e){console.error("Error deleting the team:",e)}Q(!1),el(null)}};(0,r.useEffect)(()=>{let e=async()=>{try{if(null===i||null===o||null===t||null===l)return;console.log("fetching team info:");let e={};for(let s=0;s<(null==l?void 0:l.length);s++){let n=l[s].team_id,a=await (0,u.Xm)(t,n);console.log("teamInfo response:",a),null!==a&&(e={...e,[n]:a})}et(e)}catch(e){console.error("Error fetching team info:",e)}};(async()=>{try{if(null===i||null===o)return;if(null!==t){let e=(await (0,u.So)(t,i,o)).data.map(e=>e.id);console.log("available_model_names:",e),J(e)}}catch(e){console.error("Error fetching user models:",e)}})(),e()},[t,i,o,l]);let eo=async e=>{try{if(null!=t){var s;let a=null==e?void 0:e.team_alias;if((null!==(s=null==l?void 0:l.map(e=>e.team_alias))&&void 0!==s?s:[]).includes(a))throw Error("Team alias ".concat(a," already exists, please pick another alias"));k.ZP.info("Creating Team");let r=await (0,u.hT)(t,e);null!==l?n([...l,r]):n([r]),console.log("response for team create call: ".concat(r)),k.ZP.success("Team created"),W(!1)}}catch(e){console.error("Error creating the team:",e),k.ZP.error("Error creating the team: "+e,20)}},ed=async e=>{try{if(null!=t&&null!=l){k.ZP.info("Adding Member");let s={role:"user",user_email:e.user_email,user_id:e.user_id},a=await (0,u.cu)(t,C.team_id,s);console.log("response for team create call: ".concat(a.data));let r=l.findIndex(e=>(console.log("team.team_id=".concat(e.team_id,"; response.data.team_id=").concat(a.data.team_id)),e.team_id===a.data.team_id));if(console.log("foundIndex: ".concat(r)),-1!==r){let e=[...l];e[r]=a.data,n(e),P(a.data)}G(!1)}}catch(e){console.error("Error creating the team:",e)}};return console.log("received teams ".concat(JSON.stringify(l))),(0,a.jsx)("div",{className:"w-full mx-4",children:(0,a.jsxs)(x.Z,{numItems:1,className:"gap-2 p-8 h-[75vh] w-full mt-2",children:[(0,a.jsxs)(h.Z,{numColSpan:1,children:[(0,a.jsx)(m,{level:4,children:"All Teams"}),(0,a.jsxs)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:[(0,a.jsxs)(D.Z,{children:[(0,a.jsx)(V.Z,{children:(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(z.Z,{children:"Team Name"}),(0,a.jsx)(z.Z,{children:"Spend (USD)"}),(0,a.jsx)(z.Z,{children:"Budget (USD)"}),(0,a.jsx)(z.Z,{children:"Models"}),(0,a.jsx)(z.Z,{children:"TPM / RPM Limits"}),(0,a.jsx)(z.Z,{children:"Info"})]})}),(0,a.jsx)(L.Z,{children:l&&l.length>0?l.map(e=>(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(U.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:e.team_alias}),(0,a.jsx)(U.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:e.spend}),(0,a.jsx)(U.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:null!==e.max_budget&&void 0!==e.max_budget?e.max_budget:"No limit"}),(0,a.jsx)(U.Z,{style:{maxWidth:"8-x",whiteSpace:"pre-wrap",overflow:"hidden"},children:Array.isArray(e.models)?(0,a.jsx)("div",{style:{display:"flex",flexDirection:"column"},children:0===e.models.length?(0,a.jsx)(R.Z,{size:"xs",className:"mb-1",color:"red",children:(0,a.jsx)(_.Z,{children:"All Proxy Models"})}):e.models.map((e,l)=>"all-proxy-models"===e?(0,a.jsx)(R.Z,{size:"xs",className:"mb-1",color:"red",children:(0,a.jsx)(_.Z,{children:"All Proxy Models"})},l):(0,a.jsx)(R.Z,{size:"xs",className:"mb-1",color:"blue",children:(0,a.jsx)(_.Z,{children:e.length>30?"".concat(e.slice(0,30),"..."):e})},l))}):null}),(0,a.jsx)(U.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,a.jsxs)(_.Z,{children:["TPM: ",e.tpm_limit?e.tpm_limit:"Unlimited"," ",(0,a.jsx)("br",{}),"RPM:"," ",e.rpm_limit?e.rpm_limit:"Unlimited"]})}),(0,a.jsxs)(U.Z,{children:[(0,a.jsxs)(_.Z,{children:[es&&e.team_id&&es[e.team_id]&&es[e.team_id].keys&&es[e.team_id].keys.length," ","Keys"]}),(0,a.jsxs)(_.Z,{children:[es&&e.team_id&&es[e.team_id]&&es[e.team_id].team_info&&es[e.team_id].team_info.members_with_roles&&es[e.team_id].team_info.members_with_roles.length," ","Members"]})]}),(0,a.jsxs)(U.Z,{children:[(0,a.jsx)(F.Z,{icon:O.Z,size:"sm",onClick:()=>en(e)}),(0,a.jsx)(F.Z,{onClick:()=>er(e.team_id),icon:E.Z,size:"sm"})]})]},e.team_id)):null})]}),X&&(0,a.jsx)("div",{className:"fixed z-10 inset-0 overflow-y-auto",children:(0,a.jsxs)("div",{className:"flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0",children:[(0,a.jsx)("div",{className:"fixed inset-0 transition-opacity","aria-hidden":"true",children:(0,a.jsx)("div",{className:"absolute inset-0 bg-gray-500 opacity-75"})}),(0,a.jsx)("span",{className:"hidden sm:inline-block sm:align-middle sm:h-screen","aria-hidden":"true",children:"​"}),(0,a.jsxs)("div",{className:"inline-block align-bottom bg-white rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full",children:[(0,a.jsx)("div",{className:"bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4",children:(0,a.jsx)("div",{className:"sm:flex sm:items-start",children:(0,a.jsxs)("div",{className:"mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left",children:[(0,a.jsx)("h3",{className:"text-lg leading-6 font-medium text-gray-900",children:"Delete Team"}),(0,a.jsx)("div",{className:"mt-2",children:(0,a.jsx)("p",{className:"text-sm text-gray-500",children:"Are you sure you want to delete this team ?"})})]})})}),(0,a.jsxs)("div",{className:"bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse",children:[(0,a.jsx)(p.Z,{onClick:ei,color:"red",className:"ml-2",children:"Delete"}),(0,a.jsx)(p.Z,{onClick:()=>{Q(!1),el(null)},children:"Cancel"})]})]})]})})]})]}),(0,a.jsxs)(h.Z,{numColSpan:1,children:[(0,a.jsx)(p.Z,{className:"mx-auto",onClick:()=>W(!0),children:"+ Create New Team"}),(0,a.jsx)(w.Z,{title:"Create Team",visible:T,width:800,footer:null,onOk:()=>{W(!1),d.resetFields()},onCancel:()=>{W(!1),d.resetFields()},children:(0,a.jsxs)(S.Z,{form:d,onFinish:eo,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(S.Z.Item,{label:"Team Name",name:"team_alias",rules:[{required:!0,message:"Please input a team name"}],children:(0,a.jsx)(j.Z,{placeholder:""})}),(0,a.jsx)(S.Z.Item,{label:"Models",name:"models",children:(0,a.jsxs)(v.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:[(0,a.jsx)(v.default.Option,{value:"all-proxy-models",children:"All Proxy Models"},"all-proxy-models"),Y.map(e=>(0,a.jsx)(v.default.Option,{value:e,children:e},e))]})}),(0,a.jsx)(S.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,a.jsx)(A.Z,{step:.01,precision:2,width:200})}),(0,a.jsx)(S.Z.Item,{className:"mt-8",label:"Reset Budget",name:"budget_duration",children:(0,a.jsxs)(v.default,{defaultValue:null,placeholder:"n/a",children:[(0,a.jsx)(v.default.Option,{value:"24h",children:"daily"}),(0,a.jsx)(v.default.Option,{value:"7d",children:"weekly"}),(0,a.jsx)(v.default.Option,{value:"30d",children:"monthly"})]})}),(0,a.jsx)(S.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,a.jsx)(A.Z,{step:1,width:400})}),(0,a.jsx)(S.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,a.jsx)(A.Z,{step:1,width:400})})]}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(I.ZP,{htmlType:"submit",children:"Create Team"})})]})})]}),(0,a.jsxs)(h.Z,{numColSpan:1,children:[(0,a.jsx)(m,{level:4,children:"Team Members"}),(0,a.jsx)(g,{children:"If you belong to multiple teams, this setting controls which teams members you see."}),l&&l.length>0?(0,a.jsx)(B.Z,{defaultValue:"0",children:l.map((e,l)=>(0,a.jsx)(K.Z,{value:String(l),onClick:()=>{P(e)},children:e.team_alias},l))}):(0,a.jsxs)(g,{children:["No team created. ",(0,a.jsx)("b",{children:"Defaulting to personal account."})]})]}),(0,a.jsxs)(h.Z,{numColSpan:1,children:[(0,a.jsx)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,a.jsxs)(D.Z,{children:[(0,a.jsx)(V.Z,{children:(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(z.Z,{children:"Member Name"}),(0,a.jsx)(z.Z,{children:"Role"})]})}),(0,a.jsx)(L.Z,{children:C?C.members_with_roles.map((e,l)=>(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(U.Z,{children:e.user_email?e.user_email:e.user_id?e.user_id:null}),(0,a.jsx)(U.Z,{children:e.role})]},l)):null})]})}),C&&(0,a.jsx)(e=>{let{visible:l,onCancel:s,team:t,onSubmit:n}=e,[r]=S.Z.useForm();return(0,a.jsx)(w.Z,{title:"Edit Team",visible:l,width:800,footer:null,onOk:()=>{r.validateFields().then(e=>{n({...e,team_id:t.team_id}),r.resetFields()}).catch(e=>{console.error("Validation failed:",e)})},onCancel:s,children:(0,a.jsxs)(S.Z,{form:r,onFinish:ea,initialValues:t,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(S.Z.Item,{label:"Team Name",name:"team_alias",rules:[{required:!0,message:"Please input a team name"}],children:(0,a.jsx)(j.Z,{})}),(0,a.jsx)(S.Z.Item,{label:"Models",name:"models",children:(0,a.jsxs)(v.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:[(0,a.jsx)(v.default.Option,{value:"all-proxy-models",children:"All Proxy Models"},"all-proxy-models"),Y&&Y.map(e=>(0,a.jsx)(v.default.Option,{value:e,children:e},e))]})}),(0,a.jsx)(S.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,a.jsx)(A.Z,{step:.01,precision:2,width:200})}),(0,a.jsx)(S.Z.Item,{className:"mt-8",label:"Reset Budget",name:"budget_duration",children:(0,a.jsxs)(v.default,{defaultValue:null,placeholder:"n/a",children:[(0,a.jsx)(v.default.Option,{value:"24h",children:"daily"}),(0,a.jsx)(v.default.Option,{value:"7d",children:"weekly"}),(0,a.jsx)(v.default.Option,{value:"30d",children:"monthly"})]})}),(0,a.jsx)(S.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,a.jsx)(A.Z,{step:1,width:400})}),(0,a.jsx)(S.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,a.jsx)(A.Z,{step:1,width:400})}),(0,a.jsx)(S.Z.Item,{label:"Requests per minute Limit (RPM)",name:"team_id",hidden:!0})]}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(I.ZP,{htmlType:"submit",children:"Edit Team"})})]})})},{visible:y,onCancel:()=>{b(!1),P(null)},team:C,onSubmit:ea})]}),(0,a.jsxs)(h.Z,{numColSpan:1,children:[(0,a.jsx)(p.Z,{className:"mx-auto mb-5",onClick:()=>G(!0),children:"+ Add member"}),(0,a.jsx)(w.Z,{title:"Add member",visible:H,width:800,footer:null,onOk:()=>{G(!1),c.resetFields()},onCancel:()=>{G(!1),c.resetFields()},children:(0,a.jsxs)(S.Z,{form:d,onFinish:ed,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(S.Z.Item,{label:"Email",name:"user_email",className:"mb-4",children:(0,a.jsx)(N.Z,{name:"user_email",className:"px-3 py-2 border rounded-md w-full"})}),(0,a.jsx)("div",{className:"text-center mb-4",children:"OR"}),(0,a.jsx)(S.Z.Item,{label:"User ID",name:"user_id",className:"mb-4",children:(0,a.jsx)(N.Z,{name:"user_id",className:"px-3 py-2 border rounded-md w-full"})})]}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(I.ZP,{htmlType:"submit",children:"Add member"})})]})})]})]})})},eD=e=>{let l,{searchParams:s,accessToken:t,showSSOBanner:n}=e,[o]=S.Z.useForm(),[d]=S.Z.useForm(),{Title:c,Paragraph:m}=$.default,[j,g]=(0,r.useState)(""),[Z,f]=(0,r.useState)(null),[y,b]=(0,r.useState)(null),[v,A]=(0,r.useState)(!1),[C,P]=(0,r.useState)(!1),[T,E]=(0,r.useState)(!1),[R,W]=(0,r.useState)(!1),[H,G]=(0,r.useState)(!1),[Y,J]=(0,r.useState)(!1),X=(0,i.useRouter)(),[Q,ee]=(0,r.useState)(null),[el,es]=(0,r.useState)("");try{l=window.location.origin}catch(e){l=""}l+="/fallback/login";let et=()=>{J(!1)},en=["proxy_admin","proxy_admin_viewer"];(0,r.useEffect)(()=>{if(X){let{protocol:e,host:l}=window.location;es("".concat(e,"//").concat(l))}},[X]),(0,r.useEffect)(()=>{(async()=>{if(null!=t){let e=[],l=await (0,u.Xd)(t,"proxy_admin_viewer");l.forEach(l=>{e.push({user_role:l.user_role,user_id:l.user_id,user_email:l.user_email})}),console.log("proxy viewers: ".concat(l));let s=await (0,u.Xd)(t,"proxy_admin");s.forEach(l=>{e.push({user_role:l.user_role,user_id:l.user_id,user_email:l.user_email})}),console.log("proxy admins: ".concat(s)),console.log("combinedList: ".concat(e)),f(e),ee(await (0,u.lg)(t))}})()},[t]);let ea=()=>{W(!1),d.resetFields(),o.resetFields()},er=()=>{W(!1),d.resetFields(),o.resetFields()},ei=e=>(0,a.jsxs)(S.Z,{form:o,onFinish:e,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsx)(a.Fragment,{children:(0,a.jsx)(S.Z.Item,{label:"Email",name:"user_email",className:"mb-8 mt-4",children:(0,a.jsx)(N.Z,{name:"user_email",className:"px-3 py-2 border rounded-md w-full"})})}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},className:"mt-4",children:(0,a.jsx)(I.ZP,{htmlType:"submit",children:"Add member"})})]}),eo=(e,l,s)=>(0,a.jsxs)(S.Z,{form:o,onFinish:e,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(S.Z.Item,{rules:[{required:!0,message:"Required"}],label:"User Role",name:"user_role",labelCol:{span:10},labelAlign:"left",children:(0,a.jsx)(B.Z,{value:l,children:en.map((e,l)=>(0,a.jsx)(K.Z,{value:e,children:e},l))})}),(0,a.jsx)(S.Z.Item,{label:"Team ID",name:"user_id",hidden:!0,initialValue:s,valuePropName:"user_id",className:"mt-8",children:(0,a.jsx)(N.Z,{value:s,disabled:!0})})]}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(I.ZP,{htmlType:"submit",children:"Update role"})})]}),ed=async e=>{try{if(null!=t&&null!=Z){k.ZP.info("Making API Call");let l=await (0,u.pf)(t,e,null);console.log("response for team create call: ".concat(l));let s=Z.findIndex(e=>(console.log("user.user_id=".concat(e.user_id,"; response.user_id=").concat(l.user_id)),e.user_id===l.user_id));console.log("foundIndex: ".concat(s)),-1==s&&(console.log("updates admin with new user"),Z.push(l),f(Z)),k.ZP.success("Refresh tab to see updated user role"),W(!1)}}catch(e){console.error("Error creating the key:",e)}},ec=async e=>{try{if(null!=t&&null!=Z){var l;k.ZP.info("Making API Call");let s=await (0,u.pf)(t,e,"proxy_admin_viewer");console.log("response for team create call: ".concat(s));let n=(null===(l=s.data)||void 0===l?void 0:l.user_id)||s.user_id;(0,u.XO)(t,n).then(e=>{b(e),A(!0)});let a=Z.findIndex(e=>(console.log("user.user_id=".concat(e.user_id,"; response.user_id=").concat(s.user_id)),e.user_id===s.user_id));console.log("foundIndex: ".concat(a)),-1==a&&(console.log("updates admin with new user"),Z.push(s),f(Z)),o.resetFields(),P(!1)}}catch(e){console.error("Error creating the key:",e)}},em=async e=>{try{if(null!=t&&null!=Z){var l;k.ZP.info("Making API Call"),e.user_email,e.user_id;let s=await (0,u.pf)(t,e,"proxy_admin"),n=(null===(l=s.data)||void 0===l?void 0:l.user_id)||s.user_id;(0,u.XO)(t,n).then(e=>{b(e),A(!0)}),console.log("response for team create call: ".concat(s));let a=Z.findIndex(e=>(console.log("user.user_id=".concat(e.user_id,"; response.user_id=").concat(n)),e.user_id===s.user_id));console.log("foundIndex: ".concat(a)),-1==a&&(console.log("updates admin with new user"),Z.push(s),f(Z)),o.resetFields(),E(!1)}}catch(e){console.error("Error creating the key:",e)}},eu=async e=>{if(null==t)return;let l={environment_variables:{PROXY_BASE_URL:e.proxy_base_url,GOOGLE_CLIENT_ID:e.google_client_id,GOOGLE_CLIENT_SECRET:e.google_client_secret}};(0,u.K_)(t,l)};return console.log("admins: ".concat(null==Z?void 0:Z.length)),(0,a.jsxs)("div",{className:"w-full m-2 mt-2 p-8",children:[(0,a.jsx)(c,{level:4,children:"Admin Access "}),(0,a.jsxs)(m,{children:[n&&(0,a.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/ui#restrict-ui-access",children:"Requires SSO Setup"}),(0,a.jsx)("br",{}),(0,a.jsx)("b",{children:"Proxy Admin: "})," Can create keys, teams, users, add models, etc."," ",(0,a.jsx)("br",{}),(0,a.jsx)("b",{children:"Proxy Admin Viewer: "}),"Can just view spend. They cannot create keys, teams or grant users access to new models."," "]}),(0,a.jsxs)(x.Z,{numItems:1,className:"gap-2 p-2 w-full",children:[(0,a.jsx)(h.Z,{numColSpan:1,children:(0,a.jsx)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,a.jsxs)(D.Z,{children:[(0,a.jsx)(V.Z,{children:(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(z.Z,{children:"Member Name"}),(0,a.jsx)(z.Z,{children:"Role"})]})}),(0,a.jsx)(L.Z,{children:Z?Z.map((e,l)=>{var s;return(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(U.Z,{children:e.user_email?e.user_email:e.user_id?e.user_id:null}),(0,a.jsxs)(U.Z,{children:[" ",(null==Q?void 0:null===(s=Q[null==e?void 0:e.user_role])||void 0===s?void 0:s.ui_label)||"-"]}),(0,a.jsxs)(U.Z,{children:[(0,a.jsx)(F.Z,{icon:O.Z,size:"sm",onClick:()=>W(!0)}),(0,a.jsx)(w.Z,{title:"Update role",visible:R,width:800,footer:null,onOk:ea,onCancel:er,children:eo(ed,e.user_role,e.user_id)})]})]},l)}):null})]})})}),(0,a.jsx)(h.Z,{numColSpan:1,children:(0,a.jsxs)("div",{className:"flex justify-start",children:[(0,a.jsx)(p.Z,{className:"mr-4 mb-5",onClick:()=>E(!0),children:"+ Add admin"}),(0,a.jsx)(w.Z,{title:"Add admin",visible:T,width:800,footer:null,onOk:()=>{E(!1),d.resetFields(),o.resetFields()},onCancel:()=>{E(!1),A(!1),d.resetFields(),o.resetFields()},children:ei(em)}),(0,a.jsx)(eT,{isInvitationLinkModalVisible:v,setIsInvitationLinkModalVisible:A,baseUrl:el,invitationLinkData:y}),(0,a.jsx)(p.Z,{className:"mb-5",onClick:()=>P(!0),children:"+ Add viewer"}),(0,a.jsx)(w.Z,{title:"Add viewer",visible:C,width:800,footer:null,onOk:()=>{P(!1),d.resetFields(),o.resetFields()},onCancel:()=>{P(!1),d.resetFields(),o.resetFields()},children:ei(ec)})]})})]}),(0,a.jsxs)(x.Z,{children:[(0,a.jsx)(c,{level:4,children:"Add SSO"}),(0,a.jsxs)("div",{className:"flex justify-start mb-4",children:[(0,a.jsx)(p.Z,{onClick:()=>G(!0),children:"Add SSO"}),(0,a.jsx)(w.Z,{title:"Add SSO",visible:H,width:800,footer:null,onOk:()=>{G(!1),o.resetFields()},onCancel:()=>{G(!1),o.resetFields()},children:(0,a.jsxs)(S.Z,{form:o,onFinish:e=>{em(e),eu(e),G(!1),J(!0)},labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(S.Z.Item,{label:"Admin Email",name:"user_email",rules:[{required:!0,message:"Please enter the email of the proxy admin"}],children:(0,a.jsx)(N.Z,{})}),(0,a.jsx)(S.Z.Item,{label:"PROXY BASE URL",name:"proxy_base_url",rules:[{required:!0,message:"Please enter the proxy base url"}],children:(0,a.jsx)(N.Z,{})}),(0,a.jsx)(S.Z.Item,{label:"GOOGLE CLIENT ID",name:"google_client_id",rules:[{required:!0,message:"Please enter the google client id"}],children:(0,a.jsx)(N.Z.Password,{})}),(0,a.jsx)(S.Z.Item,{label:"GOOGLE CLIENT SECRET",name:"google_client_secret",rules:[{required:!0,message:"Please enter the google client secret"}],children:(0,a.jsx)(N.Z.Password,{})})]}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(I.ZP,{htmlType:"submit",children:"Save"})})]})}),(0,a.jsxs)(w.Z,{title:"SSO Setup Instructions",visible:Y,width:800,footer:null,onOk:et,onCancel:()=>{J(!1)},children:[(0,a.jsx)("p",{children:"Follow these steps to complete the SSO setup:"}),(0,a.jsx)(_.Z,{className:"mt-2",children:"1. DO NOT Exit this TAB"}),(0,a.jsx)(_.Z,{className:"mt-2",children:"2. Open a new tab, visit your proxy base url"}),(0,a.jsx)(_.Z,{className:"mt-2",children:"3. Confirm your SSO is configured correctly and you can login on the new Tab"}),(0,a.jsx)(_.Z,{className:"mt-2",children:"4. If Step 3 is successful, you can close this tab"}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(I.ZP,{onClick:et,children:"Done"})})]})]}),(0,a.jsxs)(ey.Z,{title:"Login without SSO",color:"teal",children:["If you need to login without sso, you can access"," ",(0,a.jsxs)("a",{href:l,target:"_blank",children:[(0,a.jsx)("b",{children:l})," "]})]})]})]})},eL=s(42556),eU=s(90252),eV=e=>{let{alertingSettings:l,handleInputChange:s,handleResetField:t,handleSubmit:n,premiumUser:r}=e,[i]=S.Z.useForm();return(0,a.jsxs)(S.Z,{form:i,onFinish:()=>{let e=i.getFieldsValue();Object.values(e).some(e=>""===e||null==e)?console.log("Some form fields are empty."):n(e)},labelAlign:"left",children:[l.map((e,l)=>(0,a.jsxs)(q.Z,{children:[(0,a.jsxs)(U.Z,{align:"center",children:[(0,a.jsx)(_.Z,{children:e.field_name}),(0,a.jsx)("p",{style:{fontSize:"0.65rem",color:"#808080",fontStyle:"italic"},className:"mt-1",children:e.field_description})]}),e.premium_field?r?(0,a.jsx)(S.Z.Item,{name:e.field_name,children:(0,a.jsx)(U.Z,{children:"Integer"===e.field_type?(0,a.jsx)(A.Z,{step:1,value:e.field_value,onChange:l=>s(e.field_name,l)}):(0,a.jsx)(N.Z,{value:e.field_value,onChange:l=>s(e.field_name,l)})})}):(0,a.jsx)(U.Z,{children:(0,a.jsx)(p.Z,{className:"flex items-center justify-center",children:(0,a.jsx)("a",{href:"https://forms.gle/W3U4PZpJGFHWtHyA9",target:"_blank",children:"✨ Enterprise Feature"})})}):(0,a.jsx)(S.Z.Item,{name:e.field_name,className:"mb-0",children:(0,a.jsx)(U.Z,{children:"Integer"===e.field_type?(0,a.jsx)(A.Z,{step:1,value:e.field_value,onChange:l=>s(e.field_name,l),className:"p-0"}):(0,a.jsx)(N.Z,{value:e.field_value,onChange:l=>s(e.field_name,l)})})}),(0,a.jsx)(U.Z,{children:!0==e.stored_in_db?(0,a.jsx)(R.Z,{icon:eU.Z,className:"text-white",children:"In DB"}):!1==e.stored_in_db?(0,a.jsx)(R.Z,{className:"text-gray bg-white outline",children:"In Config"}):(0,a.jsx)(R.Z,{className:"text-gray bg-white outline",children:"Not Set"})}),(0,a.jsx)(U.Z,{children:(0,a.jsx)(F.Z,{icon:E.Z,color:"red",onClick:()=>t(e.field_name,l),children:"Reset"})})]},l)),(0,a.jsx)("div",{children:(0,a.jsx)(I.ZP,{htmlType:"submit",children:"Update Settings"})})]})},ez=e=>{let{accessToken:l,premiumUser:s}=e,[t,n]=(0,r.useState)([]);return console.log("INSIDE ALERTING SETTINGS"),(0,r.useEffect)(()=>{l&&(0,u.RQ)(l).then(e=>{n(e)})},[l]),(0,a.jsx)(eV,{alertingSettings:t,handleInputChange:(e,l)=>{n(t.map(s=>s.field_name===e?{...s,field_value:l}:s))},handleResetField:(e,s)=>{if(l)try{let l=t.map(l=>l.field_name===e?{...l,stored_in_db:null,field_value:l.field_default_value}:l);console.log("INSIDE HANDLE RESET FIELD"),n(l)}catch(e){console.log("ERROR OCCURRED!")}},handleSubmit:e=>{if(!l||null==e||void 0==e)return;let s={};t.forEach(e=>{s[e.field_name]=e.field_value});let n={...e,...s};try{(0,u.jA)(l,"alerting_args",n),k.ZP.success("Wait 10s for proxy to update.")}catch(e){}},premiumUser:s})},eq=s(84406);let{Title:eB,Paragraph:eK}=$.default;var eW=e=>{let{accessToken:l,userRole:s,userID:t,premiumUser:n}=e,[i,o]=(0,r.useState)([]),[d,c]=(0,r.useState)([]),[m,h]=(0,r.useState)(!1),[g]=S.Z.useForm(),[Z,f]=(0,r.useState)(null),[y,b]=(0,r.useState)([]),[N,A]=(0,r.useState)(""),[C,P]=(0,r.useState)({}),[T,E]=(0,r.useState)([]),[R,B]=(0,r.useState)(!1),[W,H]=(0,r.useState)([]),[G,Y]=(0,r.useState)(null),[J,X]=(0,r.useState)([]),[$,Q]=(0,r.useState)(!1),[ee,el]=(0,r.useState)(null),ei=e=>{T.includes(e)?E(T.filter(l=>l!==e)):E([...T,e])},eo={llm_exceptions:"LLM Exceptions",llm_too_slow:"LLM Responses Too Slow",llm_requests_hanging:"LLM Requests Hanging",budget_alerts:"Budget Alerts (API Keys, Users)",db_exceptions:"Database Exceptions (Read/Write)",daily_reports:"Weekly/Monthly Spend Reports",outage_alerts:"Outage Alerts",region_outage_alerts:"Region Outage Alerts"};(0,r.useEffect)(()=>{l&&s&&t&&(0,u.BL)(l,t,s).then(e=>{console.log("callbacks",e),o(e.callbacks),H(e.available_callbacks);let l=e.alerts;if(console.log("alerts_data",l),l&&l.length>0){let e=l[0];console.log("_alert_info",e);let s=e.variables.SLACK_WEBHOOK_URL;console.log("catch_all_webhook",s),E(e.active_alerts),A(s),P(e.alerts_to_webhook)}c(l)})},[l,s,t]);let ed=e=>T&&T.includes(e),ec=()=>{if(!l)return;let e={};d.filter(e=>"email"===e.name).forEach(l=>{var s;Object.entries(null!==(s=l.variables)&&void 0!==s?s:{}).forEach(l=>{let[s,t]=l,n=document.querySelector('input[name="'.concat(s,'"]'));n&&n.value&&(e[s]=null==n?void 0:n.value)})}),console.log("updatedVariables",e);try{(0,u.K_)(l,{general_settings:{alerting:["email"]},environment_variables:e})}catch(e){k.ZP.error("Failed to update alerts: "+e,20)}k.ZP.success("Email settings updated successfully")},em=async e=>{if(!l)return;let s={};Object.entries(e).forEach(e=>{let[l,t]=e;"callback"!==l&&(s[l]=t)});try{await (0,u.K_)(l,{environment_variables:s}),k.ZP.success("Callback added successfully"),h(!1),g.resetFields(),f(null)}catch(e){k.ZP.error("Failed to add callback: "+e,20)}},eu=async e=>{if(!l)return;let s=null==e?void 0:e.callback,t={};Object.entries(e).forEach(e=>{let[l,s]=e;"callback"!==l&&(t[l]=s)});try{await (0,u.K_)(l,{environment_variables:t,litellm_settings:{success_callback:[s]}}),k.ZP.success("Callback ".concat(s," added successfully")),h(!1),g.resetFields(),f(null)}catch(e){k.ZP.error("Failed to add callback: "+e,20)}},eh=e=>{console.log("inside handleSelectedCallbackChange",e),f(e.litellm_callback_name),console.log("all callbacks",W),e&&e.litellm_callback_params?(X(e.litellm_callback_params),console.log("selectedCallbackParams",J)):X([])};return l?(console.log("callbacks: ".concat(i)),(0,a.jsxs)("div",{className:"w-full mx-4",children:[(0,a.jsx)(x.Z,{numItems:1,className:"gap-2 p-8 w-full mt-2",children:(0,a.jsxs)(et.Z,{children:[(0,a.jsxs)(en.Z,{variant:"line",defaultValue:"1",children:[(0,a.jsx)(es.Z,{value:"1",children:"Logging Callbacks"}),(0,a.jsx)(es.Z,{value:"2",children:"Alerting Types"}),(0,a.jsx)(es.Z,{value:"3",children:"Alerting Settings"}),(0,a.jsx)(es.Z,{value:"4",children:"Email Alerts"})]}),(0,a.jsxs)(er.Z,{children:[(0,a.jsxs)(ea.Z,{children:[(0,a.jsx)(eB,{level:4,children:"Active Logging Callbacks"}),(0,a.jsx)(x.Z,{numItems:2,children:(0,a.jsx)(M.Z,{className:"max-h-[50vh]",children:(0,a.jsxs)(D.Z,{children:[(0,a.jsx)(V.Z,{children:(0,a.jsx)(q.Z,{children:(0,a.jsx)(z.Z,{children:"Callback Name"})})}),(0,a.jsx)(L.Z,{children:i.map((e,s)=>(0,a.jsxs)(q.Z,{className:"flex justify-between",children:[(0,a.jsx)(U.Z,{children:(0,a.jsx)(_.Z,{children:e.name})}),(0,a.jsx)(U.Z,{children:(0,a.jsxs)(x.Z,{numItems:2,className:"flex justify-between",children:[(0,a.jsx)(F.Z,{icon:O.Z,size:"sm",onClick:()=>{el(e),Q(!0)}}),(0,a.jsx)(p.Z,{onClick:()=>(0,u.jE)(l,e.name),className:"ml-2",variant:"secondary",children:"Test Callback"})]})})]},s))})]})})}),(0,a.jsx)(p.Z,{className:"mt-2",onClick:()=>B(!0),children:"Add Callback"})]}),(0,a.jsx)(ea.Z,{children:(0,a.jsxs)(M.Z,{children:[(0,a.jsxs)(_.Z,{className:"my-2",children:["Alerts are only supported for Slack Webhook URLs. Get your webhook urls from"," ",(0,a.jsx)("a",{href:"https://api.slack.com/messaging/webhooks",target:"_blank",style:{color:"blue"},children:"here"})]}),(0,a.jsxs)(D.Z,{children:[(0,a.jsx)(V.Z,{children:(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(z.Z,{}),(0,a.jsx)(z.Z,{}),(0,a.jsx)(z.Z,{children:"Slack Webhook URL"})]})}),(0,a.jsx)(L.Z,{children:Object.entries(eo).map((e,l)=>{let[s,t]=e;return(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(U.Z,{children:"region_outage_alerts"==s?n?(0,a.jsx)(eL.Z,{id:"switch",name:"switch",checked:ed(s),onChange:()=>ei(s)}):(0,a.jsx)(p.Z,{className:"flex items-center justify-center",children:(0,a.jsx)("a",{href:"https://forms.gle/W3U4PZpJGFHWtHyA9",target:"_blank",children:"✨ Enterprise Feature"})}):(0,a.jsx)(eL.Z,{id:"switch",name:"switch",checked:ed(s),onChange:()=>ei(s)})}),(0,a.jsx)(U.Z,{children:(0,a.jsx)(_.Z,{children:t})}),(0,a.jsx)(U.Z,{children:(0,a.jsx)(j.Z,{name:s,type:"password",defaultValue:C&&C[s]?C[s]:N})})]},l)})})]}),(0,a.jsx)(p.Z,{size:"xs",className:"mt-2",onClick:()=>{if(!l)return;let e={};Object.entries(eo).forEach(l=>{let[s,t]=l,n=document.querySelector('input[name="'.concat(s,'"]'));console.log("key",s),console.log("webhookInput",n);let a=(null==n?void 0:n.value)||"";console.log("newWebhookValue",a),e[s]=a}),console.log("updatedAlertToWebhooks",e);let s={general_settings:{alert_to_webhook_url:e,alert_types:T}};console.log("payload",s);try{(0,u.K_)(l,s)}catch(e){k.ZP.error("Failed to update alerts: "+e,20)}k.ZP.success("Alerts updated successfully")},children:"Save Changes"}),(0,a.jsx)(p.Z,{onClick:()=>(0,u.jE)(l,"slack"),className:"mx-2",children:"Test Alerts"})]})}),(0,a.jsx)(ea.Z,{children:(0,a.jsx)(ez,{accessToken:l,premiumUser:n})}),(0,a.jsx)(ea.Z,{children:(0,a.jsxs)(M.Z,{children:[(0,a.jsx)(eB,{level:4,children:"Email Settings"}),(0,a.jsxs)(_.Z,{children:[(0,a.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/email",target:"_blank",style:{color:"blue"},children:" LiteLLM Docs: email alerts"})," ",(0,a.jsx)("br",{})]}),(0,a.jsx)("div",{className:"flex w-full",children:d.filter(e=>"email"===e.name).map((e,l)=>{var s;return(0,a.jsx)(U.Z,{children:(0,a.jsx)("ul",{children:(0,a.jsx)(x.Z,{numItems:2,children:Object.entries(null!==(s=e.variables)&&void 0!==s?s:{}).map(e=>{let[l,s]=e;return(0,a.jsxs)("li",{className:"mx-2 my-2",children:[!0!=n&&("EMAIL_LOGO_URL"===l||"EMAIL_SUPPORT_CONTACT"===l)?(0,a.jsxs)("div",{children:[(0,a.jsx)("a",{href:"https://forms.gle/W3U4PZpJGFHWtHyA9",target:"_blank",children:(0,a.jsxs)(_.Z,{className:"mt-2",children:[" ","✨ ",l]})}),(0,a.jsx)(j.Z,{name:l,defaultValue:s,type:"password",disabled:!0,style:{width:"400px"}})]}):(0,a.jsxs)("div",{children:[(0,a.jsx)(_.Z,{className:"mt-2",children:l}),(0,a.jsx)(j.Z,{name:l,defaultValue:s,type:"password",style:{width:"400px"}})]}),(0,a.jsxs)("p",{style:{fontSize:"small",fontStyle:"italic"},children:["SMTP_HOST"===l&&(0,a.jsxs)("div",{style:{color:"gray"},children:["Enter the SMTP host address, e.g. `smtp.resend.com`",(0,a.jsx)("span",{style:{color:"red"},children:" Required * "})]}),"SMTP_PORT"===l&&(0,a.jsxs)("div",{style:{color:"gray"},children:["Enter the SMTP port number, e.g. `587`",(0,a.jsx)("span",{style:{color:"red"},children:" Required * "})]}),"SMTP_USERNAME"===l&&(0,a.jsxs)("div",{style:{color:"gray"},children:["Enter the SMTP username, e.g. `username`",(0,a.jsx)("span",{style:{color:"red"},children:" Required * "})]}),"SMTP_PASSWORD"===l&&(0,a.jsx)("span",{style:{color:"red"},children:" Required * "}),"SMTP_SENDER_EMAIL"===l&&(0,a.jsxs)("div",{style:{color:"gray"},children:["Enter the sender email address, e.g. `sender@berri.ai`",(0,a.jsx)("span",{style:{color:"red"},children:" Required * "})]}),"TEST_EMAIL_ADDRESS"===l&&(0,a.jsxs)("div",{style:{color:"gray"},children:["Email Address to send `Test Email Alert` to. example: `info@berri.ai`",(0,a.jsx)("span",{style:{color:"red"},children:" Required * "})]}),"EMAIL_LOGO_URL"===l&&(0,a.jsx)("div",{style:{color:"gray"},children:"(Optional) Customize the Logo that appears in the email, pass a url to your logo"}),"EMAIL_SUPPORT_CONTACT"===l&&(0,a.jsx)("div",{style:{color:"gray"},children:"(Optional) Customize the support email address that appears in the email. Default is support@berri.ai"})]})]},l)})})})},l)})}),(0,a.jsx)(p.Z,{className:"mt-2",onClick:()=>ec(),children:"Save Changes"}),(0,a.jsx)(p.Z,{onClick:()=>(0,u.jE)(l,"email"),className:"mx-2",children:"Test Email Alerts"})]})})]})]})}),(0,a.jsxs)(w.Z,{title:"Add Logging Callback",visible:R,width:800,onCancel:()=>B(!1),footer:null,children:[(0,a.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/logging",className:"mb-8 mt-4",target:"_blank",style:{color:"blue"},children:" LiteLLM Docs: Logging"}),(0,a.jsx)(S.Z,{form:g,onFinish:eu,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(eq.Z,{label:"Callback",name:"callback",rules:[{required:!0,message:"Please select a callback"}],children:(0,a.jsx)(v.default,{onChange:e=>{let l=W[e];l&&(console.log(l.ui_callback_name),eh(l))},children:W&&Object.values(W).map(e=>(0,a.jsx)(K.Z,{value:e.litellm_callback_name,children:e.ui_callback_name},e.litellm_callback_name))})}),J&&J.map(e=>(0,a.jsx)(eq.Z,{label:e,name:e,rules:[{required:!0,message:"Please enter the value for "+e}],children:(0,a.jsx)(j.Z,{type:"password"})},e)),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(I.ZP,{htmlType:"submit",children:"Save"})})]})})]}),(0,a.jsx)(w.Z,{visible:$,width:800,title:"Edit ".concat(null==ee?void 0:ee.name," Settings"),onCancel:()=>Q(!1),footer:null,children:(0,a.jsxs)(S.Z,{form:g,onFinish:em,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsx)(a.Fragment,{children:ee&&ee.variables&&Object.entries(ee.variables).map(e=>{let[l,s]=e;return(0,a.jsx)(eq.Z,{label:l,name:l,children:(0,a.jsx)(j.Z,{type:"password",defaultValue:s})},l)})}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(I.ZP,{htmlType:"submit",children:"Save"})})]})})]})):null};let{Option:eH}=v.default;var eG=e=>{let{models:l,accessToken:s,routerSettings:t,setRouterSettings:n}=e,[i]=S.Z.useForm(),[o,d]=(0,r.useState)(!1),[c,m]=(0,r.useState)("");return(0,a.jsxs)("div",{children:[(0,a.jsx)(p.Z,{className:"mx-auto",onClick:()=>d(!0),children:"+ Add Fallbacks"}),(0,a.jsx)(w.Z,{title:"Add Fallbacks",visible:o,width:800,footer:null,onOk:()=>{d(!1),i.resetFields()},onCancel:()=>{d(!1),i.resetFields()},children:(0,a.jsxs)(S.Z,{form:i,onFinish:e=>{console.log(e);let{model_name:l,models:a}=e,r=[...t.fallbacks||[],{[l]:a}],o={...t,fallbacks:r};console.log(o);try{(0,u.K_)(s,{router_settings:o}),n(o)}catch(e){k.ZP.error("Failed to update router settings: "+e,20)}k.ZP.success("router settings updated successfully"),d(!1),i.resetFields()},labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(S.Z.Item,{label:"Public Model Name",name:"model_name",rules:[{required:!0,message:"Set the model to fallback for"}],help:"required",children:(0,a.jsx)(B.Z,{defaultValue:c,children:l&&l.map((e,l)=>(0,a.jsx)(K.Z,{value:e,onClick:()=>m(e),children:e},l))})}),(0,a.jsx)(S.Z.Item,{label:"Fallback Models",name:"models",rules:[{required:!0,message:"Please select a model"}],help:"required",children:(0,a.jsx)(ei.Z,{value:l,children:l&&l.filter(e=>e!=c).map(e=>(0,a.jsx)(eo.Z,{value:e,children:e},e))})})]}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(I.ZP,{htmlType:"submit",children:"Add Fallbacks"})})]})})]})},eY=s(12968);async function eJ(e,l){console.log("isLocal:",!1);let s=window.location.origin,t=new eY.ZP.OpenAI({apiKey:l,baseURL:s,dangerouslyAllowBrowser:!0});try{let l=await t.chat.completions.create({model:e,messages:[{role:"user",content:"Hi, this is a test message"}],mock_testing_fallbacks:!0});k.ZP.success((0,a.jsxs)("span",{children:["Test model=",(0,a.jsx)("strong",{children:e}),", received model=",(0,a.jsx)("strong",{children:l.model}),". See"," ",(0,a.jsx)("a",{href:"#",onClick:()=>window.open("https://docs.litellm.ai/docs/proxy/reliability","_blank"),style:{textDecoration:"underline",color:"blue"},children:"curl"})]}))}catch(e){k.ZP.error("Error occurred while generating model response. Please try again. Error: ".concat(e),20)}}let eX={ttl:3600,lowest_latency_buffer:0},e$=e=>{let{selectedStrategy:l,strategyArgs:s,paramExplanation:t}=e;return(0,a.jsxs)(g.Z,{children:[(0,a.jsx)(f.Z,{className:"text-sm font-medium text-tremor-content-strong dark:text-dark-tremor-content-strong",children:"Routing Strategy Specific Args"}),(0,a.jsx)(Z.Z,{children:"latency-based-routing"==l?(0,a.jsx)(M.Z,{children:(0,a.jsxs)(D.Z,{children:[(0,a.jsx)(V.Z,{children:(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(z.Z,{children:"Setting"}),(0,a.jsx)(z.Z,{children:"Value"})]})}),(0,a.jsx)(L.Z,{children:Object.entries(s).map(e=>{let[l,s]=e;return(0,a.jsxs)(q.Z,{children:[(0,a.jsxs)(U.Z,{children:[(0,a.jsx)(_.Z,{children:l}),(0,a.jsx)("p",{style:{fontSize:"0.65rem",color:"#808080",fontStyle:"italic"},className:"mt-1",children:t[l]})]}),(0,a.jsx)(U.Z,{children:(0,a.jsx)(j.Z,{name:l,defaultValue:"object"==typeof s?JSON.stringify(s,null,2):s.toString()})})]},l)})})]})}):(0,a.jsx)(_.Z,{children:"No specific settings"})})]})};var eQ=e=>{let{accessToken:l,userRole:s,userID:t,modelData:n}=e,[i,o]=(0,r.useState)({}),[d,c]=(0,r.useState)({}),[m,g]=(0,r.useState)([]),[Z,f]=(0,r.useState)(!1),[b]=S.Z.useForm(),[v,w]=(0,r.useState)(null),[N,I]=(0,r.useState)(null),[C,P]=(0,r.useState)(null),T={routing_strategy_args:"(dict) Arguments to pass to the routing strategy",routing_strategy:"(string) Routing strategy to use",allowed_fails:"(int) Number of times a deployment can fail before being added to cooldown",cooldown_time:"(int) time in seconds to cooldown a deployment after failure",num_retries:"(int) Number of retries for failed requests. Defaults to 0.",timeout:"(float) Timeout for requests. Defaults to None.",retry_after:"(int) Minimum time to wait before retrying a failed request",ttl:"(int) Sliding window to look back over when calculating the average latency of a deployment. Default - 1 hour (in seconds).",lowest_latency_buffer:"(float) Shuffle between deployments within this % of the lowest latency. Default - 0 (i.e. always pick lowest latency)."};(0,r.useEffect)(()=>{l&&s&&t&&((0,u.BL)(l,t,s).then(e=>{console.log("callbacks",e),o(e.router_settings)}),(0,u.YU)(l).then(e=>{g(e)}))},[l,s,t]);let O=async e=>{if(l){console.log("received key: ".concat(e)),console.log("routerSettings['fallbacks']: ".concat(i.fallbacks)),i.fallbacks.map(l=>(e in l&&delete l[e],l));try{await (0,u.K_)(l,{router_settings:i}),o({...i}),I(i.routing_strategy),k.ZP.success("Router settings updated successfully")}catch(e){k.ZP.error("Failed to update router settings: "+e,20)}}},W=(e,l)=>{g(m.map(s=>s.field_name===e?{...s,field_value:l}:s))},H=(e,s)=>{if(!l)return;let t=m[s].field_value;if(null!=t&&void 0!=t)try{(0,u.jA)(l,e,t);let s=m.map(l=>l.field_name===e?{...l,stored_in_db:!0}:l);g(s)}catch(e){}},G=(e,s)=>{if(l)try{(0,u.ao)(l,e);let s=m.map(l=>l.field_name===e?{...l,stored_in_db:null,field_value:null}:l);g(s)}catch(e){}},Y=e=>{if(!l)return;console.log("router_settings",e);let s=Object.fromEntries(Object.entries(e).map(e=>{let[l,s]=e;if("routing_strategy_args"!==l&&"routing_strategy"!==l){var t;return[l,(null===(t=document.querySelector('input[name="'.concat(l,'"]')))||void 0===t?void 0:t.value)||s]}if("routing_strategy"==l)return[l,N];if("routing_strategy_args"==l&&"latency-based-routing"==N){let e={},l=document.querySelector('input[name="lowest_latency_buffer"]'),s=document.querySelector('input[name="ttl"]');return(null==l?void 0:l.value)&&(e.lowest_latency_buffer=Number(l.value)),(null==s?void 0:s.value)&&(e.ttl=Number(s.value)),console.log("setRoutingStrategyArgs: ".concat(e)),["routing_strategy_args",e]}return null}).filter(e=>null!=e));console.log("updatedVariables",s);try{(0,u.K_)(l,{router_settings:s})}catch(e){k.ZP.error("Failed to update router settings: "+e,20)}k.ZP.success("router settings updated successfully")};return l?(0,a.jsx)("div",{className:"w-full mx-4",children:(0,a.jsxs)(et.Z,{className:"gap-2 p-8 h-[75vh] w-full mt-2",children:[(0,a.jsxs)(en.Z,{variant:"line",defaultValue:"1",children:[(0,a.jsx)(es.Z,{value:"1",children:"Loadbalancing"}),(0,a.jsx)(es.Z,{value:"2",children:"Fallbacks"}),(0,a.jsx)(es.Z,{value:"3",children:"General"})]}),(0,a.jsxs)(er.Z,{children:[(0,a.jsx)(ea.Z,{children:(0,a.jsxs)(x.Z,{numItems:1,className:"gap-2 p-8 w-full mt-2",children:[(0,a.jsx)(y.Z,{children:"Router Settings"}),(0,a.jsxs)(M.Z,{children:[(0,a.jsxs)(D.Z,{children:[(0,a.jsx)(V.Z,{children:(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(z.Z,{children:"Setting"}),(0,a.jsx)(z.Z,{children:"Value"})]})}),(0,a.jsx)(L.Z,{children:Object.entries(i).filter(e=>{let[l,s]=e;return"fallbacks"!=l&&"context_window_fallbacks"!=l&&"routing_strategy_args"!=l}).map(e=>{let[l,s]=e;return(0,a.jsxs)(q.Z,{children:[(0,a.jsxs)(U.Z,{children:[(0,a.jsx)(_.Z,{children:l}),(0,a.jsx)("p",{style:{fontSize:"0.65rem",color:"#808080",fontStyle:"italic"},className:"mt-1",children:T[l]})]}),(0,a.jsx)(U.Z,{children:"routing_strategy"==l?(0,a.jsxs)(B.Z,{defaultValue:s,className:"w-full max-w-md",onValueChange:I,children:[(0,a.jsx)(K.Z,{value:"usage-based-routing",children:"usage-based-routing"}),(0,a.jsx)(K.Z,{value:"latency-based-routing",children:"latency-based-routing"}),(0,a.jsx)(K.Z,{value:"simple-shuffle",children:"simple-shuffle"})]}):(0,a.jsx)(j.Z,{name:l,defaultValue:"object"==typeof s?JSON.stringify(s,null,2):s.toString()})})]},l)})})]}),(0,a.jsx)(e$,{selectedStrategy:N,strategyArgs:i&&i.routing_strategy_args&&Object.keys(i.routing_strategy_args).length>0?i.routing_strategy_args:eX,paramExplanation:T})]}),(0,a.jsx)(h.Z,{children:(0,a.jsx)(p.Z,{className:"mt-2",onClick:()=>Y(i),children:"Save Changes"})})]})}),(0,a.jsxs)(ea.Z,{children:[(0,a.jsxs)(D.Z,{children:[(0,a.jsx)(V.Z,{children:(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(z.Z,{children:"Model Name"}),(0,a.jsx)(z.Z,{children:"Fallbacks"})]})}),(0,a.jsx)(L.Z,{children:i.fallbacks&&i.fallbacks.map((e,s)=>Object.entries(e).map(e=>{let[t,n]=e;return(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(U.Z,{children:t}),(0,a.jsx)(U.Z,{children:Array.isArray(n)?n.join(", "):n}),(0,a.jsx)(U.Z,{children:(0,a.jsx)(p.Z,{onClick:()=>eJ(t,l),children:"Test Fallback"})}),(0,a.jsx)(U.Z,{children:(0,a.jsx)(F.Z,{icon:E.Z,size:"sm",onClick:()=>O(t)})})]},s.toString()+t)}))})]}),(0,a.jsx)(eG,{models:(null==n?void 0:n.data)?n.data.map(e=>e.model_name):[],accessToken:l,routerSettings:i,setRouterSettings:o})]}),(0,a.jsx)(ea.Z,{children:(0,a.jsx)(M.Z,{children:(0,a.jsxs)(D.Z,{children:[(0,a.jsx)(V.Z,{children:(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(z.Z,{children:"Setting"}),(0,a.jsx)(z.Z,{children:"Value"}),(0,a.jsx)(z.Z,{children:"Status"}),(0,a.jsx)(z.Z,{children:"Action"})]})}),(0,a.jsx)(L.Z,{children:m.map((e,l)=>(0,a.jsxs)(q.Z,{children:[(0,a.jsxs)(U.Z,{children:[(0,a.jsx)(_.Z,{children:e.field_name}),(0,a.jsx)("p",{style:{fontSize:"0.65rem",color:"#808080",fontStyle:"italic"},className:"mt-1",children:e.field_description})]}),(0,a.jsx)(U.Z,{children:"Integer"==e.field_type?(0,a.jsx)(A.Z,{step:1,value:e.field_value,onChange:l=>W(e.field_name,l)}):null}),(0,a.jsx)(U.Z,{children:!0==e.stored_in_db?(0,a.jsx)(R.Z,{icon:eU.Z,className:"text-white",children:"In DB"}):!1==e.stored_in_db?(0,a.jsx)(R.Z,{className:"text-gray bg-white outline",children:"In Config"}):(0,a.jsx)(R.Z,{className:"text-gray bg-white outline",children:"Not Set"})}),(0,a.jsxs)(U.Z,{children:[(0,a.jsx)(p.Z,{onClick:()=>H(e.field_name,l),children:"Update"}),(0,a.jsx)(F.Z,{icon:E.Z,color:"red",onClick:()=>G(e.field_name,l),children:"Reset"})]})]},l))})]})})})]})]})}):null},e0=e=>{let{isModalVisible:l,accessToken:s,setIsModalVisible:t,setBudgetList:n}=e,[r]=S.Z.useForm(),i=async e=>{if(null!=s&&void 0!=s)try{k.ZP.info("Making API Call");let l=await (0,u.Zr)(s,e);console.log("key create Response:",l),n(e=>e?[...e,l]:[l]),k.ZP.success("API Key Created"),r.resetFields()}catch(e){console.error("Error creating the key:",e),k.ZP.error("Error creating the key: ".concat(e),20)}};return(0,a.jsx)(w.Z,{title:"Create Budget",visible:l,width:800,footer:null,onOk:()=>{t(!1),r.resetFields()},onCancel:()=>{t(!1),r.resetFields()},children:(0,a.jsxs)(S.Z,{form:r,onFinish:i,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(S.Z.Item,{label:"Budget ID",name:"budget_id",rules:[{required:!0,message:"Please input a human-friendly name for the budget"}],help:"A human-friendly name for the budget",children:(0,a.jsx)(j.Z,{placeholder:""})}),(0,a.jsx)(S.Z.Item,{label:"Max Tokens per minute",name:"tpm_limit",help:"Default is model limit.",children:(0,a.jsx)(A.Z,{step:1,precision:2,width:200})}),(0,a.jsx)(S.Z.Item,{label:"Max Requests per minute",name:"rpm_limit",help:"Default is model limit.",children:(0,a.jsx)(A.Z,{step:1,precision:2,width:200})}),(0,a.jsxs)(g.Z,{className:"mt-20 mb-8",children:[(0,a.jsx)(f.Z,{children:(0,a.jsx)("b",{children:"Optional Settings"})}),(0,a.jsxs)(Z.Z,{children:[(0,a.jsx)(S.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,a.jsx)(A.Z,{step:.01,precision:2,width:200})}),(0,a.jsx)(S.Z.Item,{className:"mt-8",label:"Reset Budget",name:"budget_duration",children:(0,a.jsxs)(v.default,{defaultValue:null,placeholder:"n/a",children:[(0,a.jsx)(v.default.Option,{value:"24h",children:"daily"}),(0,a.jsx)(v.default.Option,{value:"7d",children:"weekly"}),(0,a.jsx)(v.default.Option,{value:"30d",children:"monthly"})]})})]})]})]}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(I.ZP,{htmlType:"submit",children:"Create Budget"})})]})})},e1=e=>{let{isModalVisible:l,accessToken:s,setIsModalVisible:t,setBudgetList:n,existingBudget:r}=e,[i]=S.Z.useForm(),o=async e=>{if(null!=s&&void 0!=s)try{k.ZP.info("Making API Call");let l=await (0,u.Zr)(s,e);console.log("key create Response:",l),n(e=>e?[...e,l]:[l]),k.ZP.success("API Key Created"),i.resetFields()}catch(e){console.error("Error creating the key:",e),k.ZP.error("Error creating the key: ".concat(e),20)}};return(0,a.jsx)(w.Z,{title:"Edit Budget",visible:l,width:800,footer:null,onOk:()=>{t(!1),i.resetFields()},onCancel:()=>{t(!1),i.resetFields()},children:(0,a.jsxs)(S.Z,{form:i,onFinish:o,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",initialValues:r,children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(S.Z.Item,{label:"Budget ID",name:"budget_id",rules:[{required:!0,message:"Please input a human-friendly name for the budget"}],help:"A human-friendly name for the budget",children:(0,a.jsx)(j.Z,{placeholder:""})}),(0,a.jsx)(S.Z.Item,{label:"Max Tokens per minute",name:"tpm_limit",help:"Default is model limit.",children:(0,a.jsx)(A.Z,{step:1,precision:2,width:200})}),(0,a.jsx)(S.Z.Item,{label:"Max Requests per minute",name:"rpm_limit",help:"Default is model limit.",children:(0,a.jsx)(A.Z,{step:1,precision:2,width:200})}),(0,a.jsxs)(g.Z,{className:"mt-20 mb-8",children:[(0,a.jsx)(f.Z,{children:(0,a.jsx)("b",{children:"Optional Settings"})}),(0,a.jsxs)(Z.Z,{children:[(0,a.jsx)(S.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,a.jsx)(A.Z,{step:.01,precision:2,width:200})}),(0,a.jsx)(S.Z.Item,{className:"mt-8",label:"Reset Budget",name:"budget_duration",children:(0,a.jsxs)(v.default,{defaultValue:null,placeholder:"n/a",children:[(0,a.jsx)(v.default.Option,{value:"24h",children:"daily"}),(0,a.jsx)(v.default.Option,{value:"7d",children:"weekly"}),(0,a.jsx)(v.default.Option,{value:"30d",children:"monthly"})]})})]})]})]}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(I.ZP,{htmlType:"submit",children:"Edit Budget"})})]})})},e2=e=>{let{accessToken:l}=e,[s,t]=(0,r.useState)(!1),[n,i]=(0,r.useState)(!1),[o,d]=(0,r.useState)(null),[c,m]=(0,r.useState)([]);(0,r.useEffect)(()=>{l&&(0,u.O3)(l).then(e=>{m(e)})},[l]);let h=async(e,s)=>{null!=l&&(d(c[s]),i(!0))},x=async(e,s)=>{if(null==l)return;k.ZP.info("Request made"),await (0,u.NV)(l,e);let t=[...c];t.splice(s,1),m(t),k.ZP.success("Budget Deleted.")};return(0,a.jsxs)("div",{className:"w-full mx-auto flex-auto overflow-y-auto m-8 p-2",children:[(0,a.jsx)(p.Z,{size:"sm",variant:"primary",className:"mb-2",onClick:()=>t(!0),children:"+ Create Budget"}),(0,a.jsx)(e0,{accessToken:l,isModalVisible:s,setIsModalVisible:t,setBudgetList:m}),o&&(0,a.jsx)(e1,{accessToken:l,isModalVisible:n,setIsModalVisible:i,setBudgetList:m,existingBudget:o}),(0,a.jsxs)(M.Z,{children:[(0,a.jsx)(_.Z,{children:"Create a budget to assign to customers."}),(0,a.jsxs)(D.Z,{children:[(0,a.jsx)(V.Z,{children:(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(z.Z,{children:"Budget ID"}),(0,a.jsx)(z.Z,{children:"Max Budget"}),(0,a.jsx)(z.Z,{children:"TPM"}),(0,a.jsx)(z.Z,{children:"RPM"})]})}),(0,a.jsx)(L.Z,{children:c.map((e,l)=>(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(U.Z,{children:e.budget_id}),(0,a.jsx)(U.Z,{children:e.max_budget?e.max_budget:"n/a"}),(0,a.jsx)(U.Z,{children:e.tpm_limit?e.tpm_limit:"n/a"}),(0,a.jsx)(U.Z,{children:e.rpm_limit?e.rpm_limit:"n/a"}),(0,a.jsx)(F.Z,{icon:O.Z,size:"sm",onClick:()=>h(e.budget_id,l)}),(0,a.jsx)(F.Z,{icon:E.Z,size:"sm",onClick:()=>x(e.budget_id,l)})]},l))})]})]}),(0,a.jsxs)("div",{className:"mt-5",children:[(0,a.jsx)(_.Z,{className:"text-base",children:"How to use budget id"}),(0,a.jsxs)(et.Z,{children:[(0,a.jsxs)(en.Z,{children:[(0,a.jsx)(es.Z,{children:"Assign Budget to Customer"}),(0,a.jsx)(es.Z,{children:"Test it (Curl)"}),(0,a.jsx)(es.Z,{children:"Test it (OpenAI SDK)"})]}),(0,a.jsxs)(er.Z,{children:[(0,a.jsx)(ea.Z,{children:(0,a.jsx)(ek.Z,{language:"bash",children:"\ncurl -X POST --location '/end_user/new' \n-H 'Authorization: Bearer ' \n-H 'Content-Type: application/json' \n-d '{\"user_id\": \"my-customer-id', \"budget_id\": \"\"}' # \uD83D\uDC48 KEY CHANGE\n\n "})}),(0,a.jsx)(ea.Z,{children:(0,a.jsx)(ek.Z,{language:"bash",children:'\ncurl -X POST --location \'/chat/completions\' \n-H \'Authorization: Bearer \' \n-H \'Content-Type: application/json\' \n-d \'{\n "model": "gpt-3.5-turbo\', \n "messages":[{"role": "user", "content": "Hey, how\'s it going?"}],\n "user": "my-customer-id"\n}\' # \uD83D\uDC48 KEY CHANGE\n\n '})}),(0,a.jsx)(ea.Z,{children:(0,a.jsx)(ek.Z,{language:"python",children:'from openai import OpenAI\nclient = OpenAI(\n base_url="{let{proxySettings:l}=e,s="http://localhost:4000";return l&&l.PROXY_BASE_URL&&void 0!==l.PROXY_BASE_URL&&(s=l.PROXY_BASE_URL),(0,a.jsx)(a.Fragment,{children:(0,a.jsx)(x.Z,{className:"gap-2 p-8 h-[80vh] w-full mt-2",children:(0,a.jsxs)("div",{className:"mb-5",children:[(0,a.jsx)("p",{className:"text-2xl text-tremor-content-strong dark:text-dark-tremor-content-strong font-semibold",children:"OpenAI Compatible Proxy: API Reference"}),(0,a.jsx)(_.Z,{className:"mt-2 mb-2",children:"LiteLLM is OpenAI Compatible. This means your API Key works with the OpenAI SDK. Just replace the base_url to point to your litellm proxy. Example Below "}),(0,a.jsxs)(et.Z,{children:[(0,a.jsxs)(en.Z,{children:[(0,a.jsx)(es.Z,{children:"OpenAI Python SDK"}),(0,a.jsx)(es.Z,{children:"LlamaIndex"}),(0,a.jsx)(es.Z,{children:"Langchain Py"})]}),(0,a.jsxs)(er.Z,{children:[(0,a.jsx)(ea.Z,{children:(0,a.jsx)(ek.Z,{language:"python",children:'\nimport openai\nclient = openai.OpenAI(\n api_key="your_api_key",\n base_url="'.concat(s,'" # LiteLLM Proxy is OpenAI compatible, Read More: https://docs.litellm.ai/docs/proxy/user_keys\n)\n\nresponse = client.chat.completions.create(\n model="gpt-3.5-turbo", # model to send to the proxy\n messages = [\n {\n "role": "user",\n "content": "this is a test request, write a short poem"\n }\n ]\n)\n\nprint(response)\n ')})}),(0,a.jsx)(ea.Z,{children:(0,a.jsx)(ek.Z,{language:"python",children:'\nimport os, dotenv\n\nfrom llama_index.llms import AzureOpenAI\nfrom llama_index.embeddings import AzureOpenAIEmbedding\nfrom llama_index import VectorStoreIndex, SimpleDirectoryReader, ServiceContext\n\nllm = AzureOpenAI(\n engine="azure-gpt-3.5", # model_name on litellm proxy\n temperature=0.0,\n azure_endpoint="'.concat(s,'", # litellm proxy endpoint\n api_key="sk-1234", # litellm proxy API Key\n api_version="2023-07-01-preview",\n)\n\nembed_model = AzureOpenAIEmbedding(\n deployment_name="azure-embedding-model",\n azure_endpoint="').concat(s,'",\n api_key="sk-1234",\n api_version="2023-07-01-preview",\n)\n\n\ndocuments = SimpleDirectoryReader("llama_index_data").load_data()\nservice_context = ServiceContext.from_defaults(llm=llm, embed_model=embed_model)\nindex = VectorStoreIndex.from_documents(documents, service_context=service_context)\n\nquery_engine = index.as_query_engine()\nresponse = query_engine.query("What did the author do growing up?")\nprint(response)\n\n ')})}),(0,a.jsx)(ea.Z,{children:(0,a.jsx)(ek.Z,{language:"python",children:'\nfrom langchain.chat_models import ChatOpenAI\nfrom langchain.prompts.chat import (\n ChatPromptTemplate,\n HumanMessagePromptTemplate,\n SystemMessagePromptTemplate,\n)\nfrom langchain.schema import HumanMessage, SystemMessage\n\nchat = ChatOpenAI(\n openai_api_base="'.concat(s,'",\n model = "gpt-3.5-turbo",\n temperature=0.1\n)\n\nmessages = [\n SystemMessage(\n content="You are a helpful assistant that im using to make a test request to."\n ),\n HumanMessage(\n content="test from litellm. tell me why it\'s amazing in 1 sentence"\n ),\n]\nresponse = chat(messages)\n\nprint(response)\n\n ')})})]})]})]})})})};async function e8(e,l,s,t){console.log("isLocal:",!1);let n=window.location.origin,a=new eY.ZP.OpenAI({apiKey:t,baseURL:n,dangerouslyAllowBrowser:!0});try{for await(let t of(await a.chat.completions.create({model:s,stream:!0,messages:[{role:"user",content:e}]})))console.log(t),t.choices[0].delta.content&&l(t.choices[0].delta.content)}catch(e){k.ZP.error("Error occurred while generating model response. Please try again. Error: ".concat(e),20)}}var e3=e=>{let{accessToken:l,token:s,userRole:t,userID:n}=e,[i,o]=(0,r.useState)(""),[d,c]=(0,r.useState)(""),[m,g]=(0,r.useState)([]),[Z,f]=(0,r.useState)(void 0),[y,b]=(0,r.useState)([]);(0,r.useEffect)(()=>{l&&s&&t&&n&&(async()=>{try{let e=await (0,u.So)(l,n,t);if(console.log("model_info:",e),(null==e?void 0:e.data.length)>0){let l=e.data.map(e=>({value:e.id,label:e.id}));if(console.log(l),l.length>0){let e=Array.from(new Set(l));console.log("Unique models:",e),e.sort((e,l)=>e.label.localeCompare(l.label)),console.log("Model info:",y),b(e)}f(e.data[0].id)}}catch(e){console.error("Error fetching model info:",e)}})()},[l,n,t]);let S=(e,l)=>{g(s=>{let t=s[s.length-1];return t&&t.role===e?[...s.slice(0,s.length-1),{role:e,content:t.content+l}]:[...s,{role:e,content:l}]})},k=async()=>{if(""!==d.trim()&&i&&s&&t&&n){g(e=>[...e,{role:"user",content:d}]);try{Z&&await e8(d,e=>S("assistant",e),Z,i)}catch(e){console.error("Error fetching model response",e),S("assistant","Error fetching model response")}c("")}};if(t&&"Admin Viewer"==t){let{Title:e,Paragraph:l}=$.default;return(0,a.jsxs)("div",{children:[(0,a.jsx)(e,{level:1,children:"Access Denied"}),(0,a.jsx)(l,{children:"Ask your proxy admin for access to test models"})]})}return(0,a.jsx)("div",{style:{width:"100%",position:"relative"},children:(0,a.jsx)(x.Z,{className:"gap-2 p-8 h-[80vh] w-full mt-2",children:(0,a.jsx)(M.Z,{children:(0,a.jsxs)(et.Z,{children:[(0,a.jsx)(en.Z,{children:(0,a.jsx)(es.Z,{children:"Chat"})}),(0,a.jsx)(er.Z,{children:(0,a.jsxs)(ea.Z,{children:[(0,a.jsx)("div",{className:"sm:max-w-2xl",children:(0,a.jsxs)(x.Z,{numItems:2,children:[(0,a.jsxs)(h.Z,{children:[(0,a.jsx)(_.Z,{children:"API Key"}),(0,a.jsx)(j.Z,{placeholder:"Type API Key here",type:"password",onValueChange:o,value:i})]}),(0,a.jsxs)(h.Z,{className:"mx-2",children:[(0,a.jsx)(_.Z,{children:"Select Model:"}),(0,a.jsx)(v.default,{placeholder:"Select a Model",onChange:e=>{console.log("selected ".concat(e)),f(e)},options:y,style:{width:"200px"}})]})]})}),(0,a.jsxs)(D.Z,{className:"mt-5",style:{display:"block",maxHeight:"60vh",overflowY:"auto"},children:[(0,a.jsx)(V.Z,{children:(0,a.jsx)(q.Z,{children:(0,a.jsx)(U.Z,{})})}),(0,a.jsx)(L.Z,{children:m.map((e,l)=>(0,a.jsx)(q.Z,{children:(0,a.jsx)(U.Z,{children:"".concat(e.role,": ").concat(e.content)})},l))})]}),(0,a.jsx)("div",{className:"mt-3",style:{position:"absolute",bottom:5,width:"95%"},children:(0,a.jsxs)("div",{className:"flex",children:[(0,a.jsx)(j.Z,{type:"text",value:d,onChange:e=>c(e.target.value),onKeyDown:e=>{"Enter"===e.key&&k()},placeholder:"Type your message..."}),(0,a.jsx)(p.Z,{onClick:k,className:"ml-2",children:"Send"})]})})]})})]})})})})},e6=s(33509),e9=s(95781);let{Sider:e7}=e6.default;var le=e=>{let{setPage:l,userRole:s,defaultSelectedKey:t}=e;return"Admin Viewer"==s?(0,a.jsx)(e6.default,{style:{minHeight:"100vh",maxWidth:"120px"},children:(0,a.jsx)(e7,{width:120,children:(0,a.jsx)(e9.Z,{mode:"inline",defaultSelectedKeys:t||["4"],style:{height:"100%",borderRight:0},children:(0,a.jsx)(e9.Z.Item,{onClick:()=>l("usage"),children:"Usage"},"1")})})}):(0,a.jsx)(e6.default,{style:{minHeight:"100vh",maxWidth:"145px"},children:(0,a.jsx)(e7,{width:145,children:(0,a.jsxs)(e9.Z,{mode:"inline",defaultSelectedKeys:t||["1"],style:{height:"100%",borderRight:0},children:[(0,a.jsx)(e9.Z.Item,{onClick:()=>l("api-keys"),children:(0,a.jsx)(_.Z,{children:"API Keys"})},"1"),(0,a.jsx)(e9.Z.Item,{onClick:()=>l("llm-playground"),children:(0,a.jsx)(_.Z,{children:"Test Key"})},"3"),"Admin"==s?(0,a.jsx)(e9.Z.Item,{onClick:()=>l("models"),children:(0,a.jsx)(_.Z,{children:"Models"})},"2"):null,"Admin"==s?(0,a.jsx)(e9.Z.Item,{onClick:()=>l("usage"),children:(0,a.jsx)(_.Z,{children:"Usage"})},"4"):null,"Admin"==s?(0,a.jsx)(e9.Z.Item,{onClick:()=>l("teams"),children:(0,a.jsx)(_.Z,{children:"Teams"})},"6"):null,"Admin"==s?(0,a.jsx)(e9.Z.Item,{onClick:()=>l("users"),children:(0,a.jsx)(_.Z,{children:"Internal Users"})},"5"):null,"Admin"==s?(0,a.jsx)(e9.Z.Item,{onClick:()=>l("settings"),children:(0,a.jsx)(_.Z,{children:"Logging & Alerts"})},"8"):null,"Admin"==s?(0,a.jsx)(e9.Z.Item,{onClick:()=>l("caching"),children:(0,a.jsx)(_.Z,{children:"Caching"})},"9"):null,"Admin"==s?(0,a.jsx)(e9.Z.Item,{onClick:()=>l("budgets"),children:(0,a.jsx)(_.Z,{children:"Budgets"})},"10"):null,"Admin"==s?(0,a.jsx)(e9.Z.Item,{onClick:()=>l("general-settings"),children:(0,a.jsx)(_.Z,{children:"Router Settings"})},"11"):null,"Admin"==s?(0,a.jsx)(e9.Z.Item,{onClick:()=>l("admin-panel"),children:(0,a.jsx)(_.Z,{children:"Admin"})},"12"):null,(0,a.jsx)(e9.Z.Item,{onClick:()=>l("api_ref"),children:(0,a.jsx)(_.Z,{children:"API Reference"})},"13"),(0,a.jsx)(e9.Z.Item,{onClick:()=>l("model-hub"),children:(0,a.jsx)(_.Z,{children:"Model Hub"})},"15")]})})})},ll=s(67989),ls=s(52703),lt=e=>{let{accessToken:l,token:s,userRole:t,userID:n,keys:i,premiumUser:o}=e,d=new Date,[c,m]=(0,r.useState)([]),[j,g]=(0,r.useState)([]),[Z,f]=(0,r.useState)([]),[b,v]=(0,r.useState)([]),[S,k]=(0,r.useState)([]),[w,N]=(0,r.useState)([]),[A,I]=(0,r.useState)([]),[C,P]=(0,r.useState)([]),[T,O]=(0,r.useState)([]),[E,R]=(0,r.useState)([]),[F,W]=(0,r.useState)({}),[H,Y]=(0,r.useState)([]),[J,X]=(0,r.useState)(""),[$,Q]=(0,r.useState)(["all-tags"]),[em,eu]=(0,r.useState)({from:new Date(Date.now()-6048e5),to:new Date}),eh=new Date(d.getFullYear(),d.getMonth(),1),ex=new Date(d.getFullYear(),d.getMonth()+1,0),ep=e_(eh),ej=e_(ex);function eg(e){return new Intl.NumberFormat("en-US",{maximumFractionDigits:0,notation:"compact",compactDisplay:"short"}).format(e)}console.log("keys in usage",i),console.log("premium user in usage",o),(0,r.useEffect)(()=>{ef(em.from,em.to)},[em,$]);let eZ=async(e,s,t)=>{if(!e||!s||!l)return;s.setHours(23,59,59,999),e.setHours(0,0,0,0),console.log("uiSelectedKey",t);let n=await (0,u.b1)(l,t,e.toISOString(),s.toISOString());console.log("End user data updated successfully",n),v(n)},ef=async(e,s)=>{e&&s&&l&&(s.setHours(23,59,59,999),e.setHours(0,0,0,0),N((await (0,u.J$)(l,e.toISOString(),s.toISOString(),0===$.length?void 0:$)).spend_per_tag),console.log("Tag spend data updated successfully"))};function e_(e){let l=e.getFullYear(),s=e.getMonth()+1,t=e.getDate();return"".concat(l,"-").concat(s<10?"0"+s:s,"-").concat(t<10?"0"+t:t)}return console.log("Start date is ".concat(ep)),console.log("End date is ".concat(ej)),(0,r.useEffect)(()=>{l&&s&&t&&n&&(async()=>{try{if(console.log("user role: ".concat(t)),"Admin"==t||"Admin Viewer"==t){var e,a;let t=await (0,u.FC)(l);m(t);let n=await (0,u.OU)(l,s,ep,ej);console.log("provider_spend",n),R(n);let r=(await (0,u.tN)(l)).map(e=>({key:(e.key_alias||e.key_name||e.api_key).substring(0,10),spend:e.total_spend}));g(r);let i=(await (0,u.Au)(l)).map(e=>({key:e.model,spend:e.total_spend}));f(i);let o=await (0,u.mR)(l);console.log("teamSpend",o),k(o.daily_spend),P(o.teams);let d=o.total_spend_per_team;d=d.map(e=>(e.name=e.team_id||"",e.value=e.total_spend||0,e.value=e.value.toFixed(2),e)),O(d);let c=await (0,u.X)(l);I(c.tag_names);let h=await (0,u.J$)(l,null===(e=em.from)||void 0===e?void 0:e.toISOString(),null===(a=em.to)||void 0===a?void 0:a.toISOString(),void 0);N(h.spend_per_tag);let x=await (0,u.b1)(l,null,void 0,void 0);v(x),console.log("spend/user result",x);let p=await (0,u.wd)(l,ep,ej);W(p);let j=await (0,u.xA)(l,ep,ej);console.log("global activity per model",j),Y(j)}else"App Owner"==t&&await (0,u.HK)(l,s,t,n,ep,ej).then(async e=>{if(console.log("result from spend logs call",e),"daily_spend"in e){let l=e.daily_spend;console.log("daily spend",l),m(l);let s=e.top_api_keys;g(s)}else{let s=(await (0,u.e2)(l,function(e){let l=[];e.forEach(e=>{Object.entries(e).forEach(e=>{let[s,t]=e;"spend"!==s&&"startTime"!==s&&"models"!==s&&"users"!==s&&l.push({key:s,spend:t})})}),l.sort((e,l)=>Number(l.spend)-Number(e.spend));let s=l.slice(0,5).map(e=>e.key);return console.log("topKeys: ".concat(Object.keys(s[0]))),s}(e))).info.map(e=>({key:(e.key_name||e.key_alias).substring(0,10),spend:e.spend}));g(s),m(e)}})}catch(e){console.error("There was an error fetching the data",e)}})()},[l,s,t,n,ep,ej]),(0,a.jsx)("div",{style:{width:"100%"},className:"p-8",children:(0,a.jsxs)(et.Z,{children:[(0,a.jsxs)(en.Z,{className:"mt-2",children:[(0,a.jsx)(es.Z,{children:"All Up"}),(0,a.jsx)(es.Z,{children:"Team Based Usage"}),(0,a.jsx)(es.Z,{children:"Customer Usage"}),(0,a.jsx)(es.Z,{children:"Tag Based Usage"})]}),(0,a.jsxs)(er.Z,{children:[(0,a.jsx)(ea.Z,{children:(0,a.jsxs)(et.Z,{children:[(0,a.jsxs)(en.Z,{variant:"solid",className:"mt-1",children:[(0,a.jsx)(es.Z,{children:"Cost"}),(0,a.jsx)(es.Z,{children:"Activity"})]}),(0,a.jsxs)(er.Z,{children:[(0,a.jsx)(ea.Z,{children:(0,a.jsxs)(x.Z,{numItems:2,className:"gap-2 h-[100vh] w-full",children:[(0,a.jsx)(G,{userID:n,userRole:t,accessToken:l,userSpend:null,selectedTeam:null}),(0,a.jsx)(h.Z,{numColSpan:2,children:(0,a.jsxs)(M.Z,{children:[(0,a.jsx)(y.Z,{children:"Monthly Spend"}),(0,a.jsx)(ec.Z,{data:c,index:"date",categories:["spend"],colors:["blue"],valueFormatter:e=>"$ ".concat(new Intl.NumberFormat("us").format(e).toString()),yAxisWidth:100,tickGap:5})]})}),(0,a.jsx)(h.Z,{numColSpan:1,children:(0,a.jsxs)(M.Z,{children:[(0,a.jsx)(y.Z,{children:"Top API Keys"}),(0,a.jsx)(ec.Z,{className:"mt-4 h-40",data:j,index:"key",categories:["spend"],colors:["blue"],yAxisWidth:80,tickGap:5,layout:"vertical",showXAxis:!1,showLegend:!1})]})}),(0,a.jsx)(h.Z,{numColSpan:1,children:(0,a.jsxs)(M.Z,{children:[(0,a.jsx)(y.Z,{children:"Top Models"}),(0,a.jsx)(ec.Z,{className:"mt-4 h-40",data:Z,index:"key",categories:["spend"],colors:["blue"],yAxisWidth:200,layout:"vertical",showXAxis:!1,showLegend:!1})]})}),(0,a.jsx)(h.Z,{numColSpan:1}),(0,a.jsx)(h.Z,{numColSpan:2,children:(0,a.jsxs)(M.Z,{className:"mb-2",children:[(0,a.jsx)(y.Z,{children:"✨ Spend by Provider"}),o?(0,a.jsx)(a.Fragment,{children:(0,a.jsxs)(x.Z,{numItems:2,children:[(0,a.jsx)(h.Z,{numColSpan:1,children:(0,a.jsx)(ls.Z,{className:"mt-4 h-40",variant:"pie",data:E,index:"provider",category:"spend"})}),(0,a.jsx)(h.Z,{numColSpan:1,children:(0,a.jsxs)(D.Z,{children:[(0,a.jsx)(V.Z,{children:(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(z.Z,{children:"Provider"}),(0,a.jsx)(z.Z,{children:"Spend"})]})}),(0,a.jsx)(L.Z,{children:E.map(e=>(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(U.Z,{children:e.provider}),(0,a.jsx)(U.Z,{children:1e-5>parseFloat(e.spend.toFixed(2))?"less than 0.00":e.spend.toFixed(2)})]},e.provider))})]})})]})}):(0,a.jsxs)("div",{children:[(0,a.jsx)("p",{className:"mb-2 text-gray-500 italic text-[12px]",children:"Upgrade to use this feature"}),(0,a.jsx)(p.Z,{variant:"primary",className:"mb-2",children:(0,a.jsx)("a",{href:"https://forms.gle/W3U4PZpJGFHWtHyA9",target:"_blank",children:"Get Free Trial"})})]})]})})]})}),(0,a.jsx)(ea.Z,{children:(0,a.jsxs)(x.Z,{numItems:1,className:"gap-2 h-[75vh] w-full",children:[(0,a.jsxs)(M.Z,{children:[(0,a.jsx)(y.Z,{children:"All Up"}),(0,a.jsxs)(x.Z,{numItems:2,children:[(0,a.jsxs)(h.Z,{children:[(0,a.jsxs)(ee.Z,{style:{fontSize:"15px",fontWeight:"normal",color:"#535452"},children:["API Requests ",eg(F.sum_api_requests)]}),(0,a.jsx)(ed.Z,{className:"h-40",data:F.daily_data,valueFormatter:eg,index:"date",colors:["cyan"],categories:["api_requests"],onValueChange:e=>console.log(e)})]}),(0,a.jsxs)(h.Z,{children:[(0,a.jsxs)(ee.Z,{style:{fontSize:"15px",fontWeight:"normal",color:"#535452"},children:["Tokens ",eg(F.sum_total_tokens)]}),(0,a.jsx)(ec.Z,{className:"h-40",data:F.daily_data,valueFormatter:eg,index:"date",colors:["cyan"],categories:["total_tokens"],onValueChange:e=>console.log(e)})]})]})]}),o?(0,a.jsx)(a.Fragment,{children:H.map((e,l)=>(0,a.jsxs)(M.Z,{children:[(0,a.jsx)(y.Z,{children:e.model}),(0,a.jsxs)(x.Z,{numItems:2,children:[(0,a.jsxs)(h.Z,{children:[(0,a.jsxs)(ee.Z,{style:{fontSize:"15px",fontWeight:"normal",color:"#535452"},children:["API Requests ",eg(e.sum_api_requests)]}),(0,a.jsx)(ed.Z,{className:"h-40",data:e.daily_data,index:"date",colors:["cyan"],categories:["api_requests"],valueFormatter:eg,onValueChange:e=>console.log(e)})]}),(0,a.jsxs)(h.Z,{children:[(0,a.jsxs)(ee.Z,{style:{fontSize:"15px",fontWeight:"normal",color:"#535452"},children:["Tokens ",eg(e.sum_total_tokens)]}),(0,a.jsx)(ec.Z,{className:"h-40",data:e.daily_data,index:"date",colors:["cyan"],categories:["total_tokens"],valueFormatter:eg,onValueChange:e=>console.log(e)})]})]})]},l))}):(0,a.jsx)(a.Fragment,{children:H&&H.length>0&&H.slice(0,1).map((e,l)=>(0,a.jsxs)(M.Z,{children:[(0,a.jsx)(y.Z,{children:"✨ Activity by Model"}),(0,a.jsx)("p",{className:"mb-2 text-gray-500 italic text-[12px]",children:"Upgrade to see analytics for all models"}),(0,a.jsx)(p.Z,{variant:"primary",className:"mb-2",children:(0,a.jsx)("a",{href:"https://forms.gle/W3U4PZpJGFHWtHyA9",target:"_blank",children:"Get Free Trial"})}),(0,a.jsxs)(M.Z,{children:[(0,a.jsx)(y.Z,{children:e.model}),(0,a.jsxs)(x.Z,{numItems:2,children:[(0,a.jsxs)(h.Z,{children:[(0,a.jsxs)(ee.Z,{style:{fontSize:"15px",fontWeight:"normal",color:"#535452"},children:["API Requests ",eg(e.sum_api_requests)]}),(0,a.jsx)(ed.Z,{className:"h-40",data:e.daily_data,index:"date",colors:["cyan"],categories:["api_requests"],valueFormatter:eg,onValueChange:e=>console.log(e)})]}),(0,a.jsxs)(h.Z,{children:[(0,a.jsxs)(ee.Z,{style:{fontSize:"15px",fontWeight:"normal",color:"#535452"},children:["Tokens ",eg(e.sum_total_tokens)]}),(0,a.jsx)(ec.Z,{className:"h-40",data:e.daily_data,index:"date",colors:["cyan"],valueFormatter:eg,categories:["total_tokens"],onValueChange:e=>console.log(e)})]})]})]})]},l))})]})})]})]})}),(0,a.jsx)(ea.Z,{children:(0,a.jsxs)(x.Z,{numItems:2,className:"gap-2 h-[75vh] w-full",children:[(0,a.jsxs)(h.Z,{numColSpan:2,children:[(0,a.jsxs)(M.Z,{className:"mb-2",children:[(0,a.jsx)(y.Z,{children:"Total Spend Per Team"}),(0,a.jsx)(ll.Z,{data:T})]}),(0,a.jsxs)(M.Z,{children:[(0,a.jsx)(y.Z,{children:"Daily Spend Per Team"}),(0,a.jsx)(ec.Z,{className:"h-72",data:S,showLegend:!0,index:"date",categories:C,yAxisWidth:80,stack:!0})]})]}),(0,a.jsx)(h.Z,{numColSpan:2})]})}),(0,a.jsxs)(ea.Z,{children:[(0,a.jsxs)("p",{className:"mb-2 text-gray-500 italic text-[12px]",children:["Customers of your LLM API calls. Tracked when a `user` param is passed in your LLM calls ",(0,a.jsx)("a",{className:"text-blue-500",href:"https://docs.litellm.ai/docs/proxy/users",target:"_blank",children:"docs here"})]}),(0,a.jsxs)(x.Z,{numItems:2,children:[(0,a.jsxs)(h.Z,{children:[(0,a.jsx)(_.Z,{children:"Select Time Range"}),(0,a.jsx)(el.Z,{enableSelect:!0,value:em,onValueChange:e=>{eu(e),eZ(e.from,e.to,null)}})]}),(0,a.jsxs)(h.Z,{children:[(0,a.jsx)(_.Z,{children:"Select Key"}),(0,a.jsxs)(B.Z,{defaultValue:"all-keys",children:[(0,a.jsx)(K.Z,{value:"all-keys",onClick:()=>{eZ(em.from,em.to,null)},children:"All Keys"},"all-keys"),null==i?void 0:i.map((e,l)=>e&&null!==e.key_alias&&e.key_alias.length>0?(0,a.jsx)(K.Z,{value:String(l),onClick:()=>{eZ(em.from,em.to,e.token)},children:e.key_alias},l):null)]})]})]}),(0,a.jsx)(M.Z,{className:"mt-4",children:(0,a.jsxs)(D.Z,{className:"max-h-[70vh] min-h-[500px]",children:[(0,a.jsx)(V.Z,{children:(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(z.Z,{children:"Customer"}),(0,a.jsx)(z.Z,{children:"Spend"}),(0,a.jsx)(z.Z,{children:"Total Events"})]})}),(0,a.jsx)(L.Z,{children:null==b?void 0:b.map((e,l)=>{var s;return(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(U.Z,{children:e.end_user}),(0,a.jsx)(U.Z,{children:null===(s=e.total_spend)||void 0===s?void 0:s.toFixed(4)}),(0,a.jsx)(U.Z,{children:e.total_count})]},l)})})]})})]}),(0,a.jsxs)(ea.Z,{children:[(0,a.jsxs)(x.Z,{numItems:2,children:[(0,a.jsx)(h.Z,{numColSpan:1,children:(0,a.jsx)(el.Z,{className:"mb-4",enableSelect:!0,value:em,onValueChange:e=>{eu(e),ef(e.from,e.to)}})}),(0,a.jsx)(h.Z,{children:o?(0,a.jsx)("div",{children:(0,a.jsxs)(ei.Z,{value:$,onValueChange:e=>Q(e),children:[(0,a.jsx)(eo.Z,{value:"all-tags",onClick:()=>Q(["all-tags"]),children:"All Tags"},"all-tags"),A&&A.filter(e=>"all-tags"!==e).map((e,l)=>(0,a.jsx)(eo.Z,{value:String(e),children:e},e))]})}):(0,a.jsx)("div",{children:(0,a.jsxs)(ei.Z,{value:$,onValueChange:e=>Q(e),children:[(0,a.jsx)(eo.Z,{value:"all-tags",onClick:()=>Q(["all-tags"]),children:"All Tags"},"all-tags"),A&&A.filter(e=>"all-tags"!==e).map((e,l)=>(0,a.jsxs)(K.Z,{value:String(e),disabled:!0,children:["✨ ",e," (Enterprise only Feature)"]},e))]})})})]}),(0,a.jsxs)(x.Z,{numItems:2,className:"gap-2 h-[75vh] w-full mb-4",children:[(0,a.jsx)(h.Z,{numColSpan:2,children:(0,a.jsxs)(M.Z,{children:[(0,a.jsx)(y.Z,{children:"Spend Per Tag"}),(0,a.jsxs)(_.Z,{children:["Get Started Tracking cost per tag ",(0,a.jsx)("a",{className:"text-blue-500",href:"https://docs.litellm.ai/docs/proxy/cost_tracking",target:"_blank",children:"here"})]}),(0,a.jsx)(ec.Z,{className:"h-72",data:w,index:"name",categories:["spend"],colors:["blue"]})]})}),(0,a.jsx)(h.Z,{numColSpan:2})]})]})]})]})})};let ln=e=>{if(e)return e.toISOString().split("T")[0]};function la(e){return new Intl.NumberFormat("en-US",{maximumFractionDigits:0,notation:"compact",compactDisplay:"short"}).format(e)}var lr=e=>{let{accessToken:l,token:s,userRole:t,userID:n,premiumUser:i}=e,[o,d]=(0,r.useState)([]),[c,m]=(0,r.useState)([]),[p,j]=(0,r.useState)([]),[g,Z]=(0,r.useState)([]),[f,_]=(0,r.useState)("0"),[y,b]=(0,r.useState)("0"),[v,S]=(0,r.useState)("0"),[k,w]=(0,r.useState)({from:new Date(Date.now()-6048e5),to:new Date});(0,r.useEffect)(()=>{l&&k&&(async()=>{Z(await (0,u.zg)(l,ln(k.from),ln(k.to)))})()},[l]);let N=Array.from(new Set(g.map(e=>{var l;return null!==(l=null==e?void 0:e.api_key)&&void 0!==l?l:""}))),A=Array.from(new Set(g.map(e=>{var l;return null!==(l=null==e?void 0:e.model)&&void 0!==l?l:""})));Array.from(new Set(g.map(e=>{var l;return null!==(l=null==e?void 0:e.call_type)&&void 0!==l?l:""})));let I=async(e,s)=>{e&&s&&l&&(s.setHours(23,59,59,999),e.setHours(0,0,0,0),Z(await (0,u.zg)(l,ln(e),ln(s))))};return(0,r.useEffect)(()=>{console.log("DATA IN CACHE DASHBOARD",g);let e=g;c.length>0&&(e=e.filter(e=>c.includes(e.api_key))),p.length>0&&(e=e.filter(e=>p.includes(e.model))),console.log("before processed data in cache dashboard",e);let l=0,s=0,t=0,n=e.reduce((e,n)=>{console.log("Processing item:",n),n.call_type||(console.log("Item has no call_type:",n),n.call_type="Unknown"),l+=(n.total_rows||0)-(n.cache_hit_true_rows||0),s+=n.cache_hit_true_rows||0,t+=n.cached_completion_tokens||0;let a=e.find(e=>e.name===n.call_type);return a?(a["LLM API requests"]+=(n.total_rows||0)-(n.cache_hit_true_rows||0),a["Cache hit"]+=n.cache_hit_true_rows||0,a["Cached Completion Tokens"]+=n.cached_completion_tokens||0,a["Generated Completion Tokens"]+=n.generated_completion_tokens||0):e.push({name:n.call_type,"LLM API requests":(n.total_rows||0)-(n.cache_hit_true_rows||0),"Cache hit":n.cache_hit_true_rows||0,"Cached Completion Tokens":n.cached_completion_tokens||0,"Generated Completion Tokens":n.generated_completion_tokens||0}),e},[]);_(la(s)),b(la(t)),l>0?S((s/l*100).toFixed(2)):S("0"),d(n),console.log("PROCESSED DATA IN CACHE DASHBOARD",n)},[c,p,k,g]),(0,a.jsxs)(M.Z,{children:[(0,a.jsxs)(x.Z,{numItems:3,className:"gap-4 mt-4",children:[(0,a.jsx)(h.Z,{children:(0,a.jsx)(ei.Z,{placeholder:"Select API Keys",value:c,onValueChange:m,children:N.map(e=>(0,a.jsx)(eo.Z,{value:e,children:e},e))})}),(0,a.jsx)(h.Z,{children:(0,a.jsx)(ei.Z,{placeholder:"Select Models",value:p,onValueChange:j,children:A.map(e=>(0,a.jsx)(eo.Z,{value:e,children:e},e))})}),(0,a.jsx)(h.Z,{children:(0,a.jsx)(el.Z,{enableSelect:!0,value:k,onValueChange:e=>{w(e),I(e.from,e.to)},selectPlaceholder:"Select date range"})})]}),(0,a.jsxs)("div",{className:"grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3 mt-4",children:[(0,a.jsxs)(M.Z,{children:[(0,a.jsx)("p",{className:"text-tremor-default font-medium text-tremor-content dark:text-dark-tremor-content",children:"Cache Hit Ratio"}),(0,a.jsx)("div",{className:"mt-2 flex items-baseline space-x-2.5",children:(0,a.jsxs)("p",{className:"text-tremor-metric font-semibold text-tremor-content-strong dark:text-dark-tremor-content-strong",children:[v,"%"]})})]}),(0,a.jsxs)(M.Z,{children:[(0,a.jsx)("p",{className:"text-tremor-default font-medium text-tremor-content dark:text-dark-tremor-content",children:"Cache Hits"}),(0,a.jsx)("div",{className:"mt-2 flex items-baseline space-x-2.5",children:(0,a.jsx)("p",{className:"text-tremor-metric font-semibold text-tremor-content-strong dark:text-dark-tremor-content-strong",children:f})})]}),(0,a.jsxs)(M.Z,{children:[(0,a.jsx)("p",{className:"text-tremor-default font-medium text-tremor-content dark:text-dark-tremor-content",children:"Cached Tokens"}),(0,a.jsx)("div",{className:"mt-2 flex items-baseline space-x-2.5",children:(0,a.jsx)("p",{className:"text-tremor-metric font-semibold text-tremor-content-strong dark:text-dark-tremor-content-strong",children:y})})]})]}),(0,a.jsx)(ee.Z,{className:"mt-4",children:"Cache Hits vs API Requests"}),(0,a.jsx)(ec.Z,{title:"Cache Hits vs API Requests",data:o,index:"name",valueFormatter:la,categories:["LLM API requests","Cache hit"],colors:["sky","teal"],yAxisWidth:48}),(0,a.jsx)(ee.Z,{className:"mt-4",children:"Cached Completion Tokens vs Generated Completion Tokens"}),(0,a.jsx)(ec.Z,{className:"mt-6",data:o,index:"name",valueFormatter:la,categories:["Generated Completion Tokens","Cached Completion Tokens"],colors:["sky","teal"],yAxisWidth:48})]})},li=()=>{let{Title:e,Paragraph:l}=$.default,[s,t]=(0,r.useState)(""),[n,o]=(0,r.useState)(!1),[d,c]=(0,r.useState)(null),[u,h]=(0,r.useState)(null),[x,p]=(0,r.useState)(null),[j,g]=(0,r.useState)({PROXY_BASE_URL:"",PROXY_LOGOUT_URL:""}),[Z,f]=(0,r.useState)(!0),_=(0,i.useSearchParams)(),[y,b]=(0,r.useState)({data:[]}),v=_.get("userID"),S=function(e){console.log("COOKIES",document.cookie);let l=document.cookie.split("; ").find(l=>l.startsWith(e+"="));return l?l.split("=")[1]:null}("token"),[k,w]=(0,r.useState)("api-keys"),[N,A]=(0,r.useState)(null);return(0,r.useEffect)(()=>{if(S){let e=(0,X.o)(S);if(e){if(console.log("Decoded token:",e),console.log("Decoded key:",e.key),A(e.key),e.user_role){let l=function(e){if(!e)return"Undefined Role";switch(console.log("Received user role: ".concat(e.toLowerCase())),console.log("Received user role length: ".concat(e.toLowerCase().length)),e.toLowerCase()){case"app_owner":case"demo_app_owner":return"App Owner";case"app_admin":case"proxy_admin":return"Admin";case"proxy_admin_viewer":return"Admin Viewer";case"internal_user":return"Internal User";case"internal_viewer":return"Internal Viewer";case"app_user":return"App User";default:return"Unknown Role"}}(e.user_role);console.log("Decoded user_role:",l),t(l),"Admin Viewer"==l&&w("usage")}else console.log("User role not defined");e.user_email?c(e.user_email):console.log("User Email is not set ".concat(e)),e.login_method?f("username_password"==e.login_method):console.log("User Email is not set ".concat(e)),e.premium_user&&o(e.premium_user)}}},[S]),(0,a.jsx)(r.Suspense,{fallback:(0,a.jsx)("div",{children:"Loading..."}),children:(0,a.jsxs)("div",{className:"flex flex-col min-h-screen",children:[(0,a.jsx)(m,{userID:v,userRole:s,userEmail:d,showSSOBanner:Z,premiumUser:n,setProxySettings:g,proxySettings:j}),(0,a.jsxs)("div",{className:"flex flex-1 overflow-auto",children:[(0,a.jsx)("div",{className:"mt-8",children:(0,a.jsx)(le,{setPage:w,userRole:s,defaultSelectedKey:null})}),"api-keys"==k?(0,a.jsx)(Q,{userID:v,userRole:s,teams:u,keys:x,setUserRole:t,userEmail:d,setUserEmail:c,setTeams:h,setKeys:p,setProxySettings:g,proxySettings:j}):"models"==k?(0,a.jsx)(eP,{userID:v,userRole:s,token:S,keys:x,accessToken:N,modelData:y,setModelData:b,premiumUser:n}):"llm-playground"==k?(0,a.jsx)(e3,{userID:v,userRole:s,token:S,accessToken:N}):"users"==k?(0,a.jsx)(eM,{userID:v,userRole:s,token:S,keys:x,teams:u,accessToken:N,setKeys:p}):"teams"==k?(0,a.jsx)(eF,{teams:u,setTeams:h,searchParams:_,accessToken:N,userID:v,userRole:s}):"admin-panel"==k?(0,a.jsx)(eD,{setTeams:h,searchParams:_,accessToken:N,showSSOBanner:Z}):"api_ref"==k?(0,a.jsx)(e5,{proxySettings:j}):"settings"==k?(0,a.jsx)(eW,{userID:v,userRole:s,accessToken:N,premiumUser:n}):"budgets"==k?(0,a.jsx)(e2,{accessToken:N}):"general-settings"==k?(0,a.jsx)(eQ,{userID:v,userRole:s,accessToken:N,modelData:y}):"model-hub"==k?(0,a.jsx)(e4.Z,{accessToken:N,publicPage:!1,premiumUser:n}):"caching"==k?(0,a.jsx)(lr,{userID:v,userRole:s,token:S,accessToken:N,premiumUser:n}):(0,a.jsx)(lt,{userID:v,userRole:s,token:S,accessToken:N,keys:x,premiumUser:n})]})]})})}},41134:function(e,l,s){"use strict";s.d(l,{Z:function(){return y}});var t=s(3827),n=s(64090),a=s(47907),r=s(777),i=s(16450),o=s(13810),d=s(92836),c=s(26734),m=s(41608),u=s(32126),h=s(23682),x=s(71801),p=s(42440),j=s(84174),g=s(50459),Z=s(6180),f=s(99129),_=s(67951),y=e=>{var l;let{accessToken:s,publicPage:y,premiumUser:b}=e,[v,S]=(0,n.useState)(!1),[k,w]=(0,n.useState)(null),[N,A]=(0,n.useState)(!1),[I,C]=(0,n.useState)(!1),[P,T]=(0,n.useState)(null),O=(0,a.useRouter)();(0,n.useEffect)(()=>{s&&(async()=>{try{let e=await (0,r.kn)(s);console.log("ModelHubData:",e),w(e.data),(0,r.E9)(s,"enable_public_model_hub").then(e=>{console.log("data: ".concat(JSON.stringify(e))),!0==e.field_value&&S(!0)}).catch(e=>{})}catch(e){console.error("There was an error fetching the model data",e)}})()},[s,y]);let E=e=>{T(e),A(!0)},R=async()=>{s&&(0,r.jA)(s,"enable_public_model_hub",!0).then(e=>{C(!0)})},M=()=>{A(!1),C(!1),T(null)},F=()=>{A(!1),C(!1),T(null)},D=e=>{navigator.clipboard.writeText(e)};return(0,t.jsxs)("div",{children:[y&&v||!1==y?(0,t.jsxs)("div",{className:"w-full m-2 mt-2 p-8",children:[(0,t.jsx)("div",{className:"relative w-full"}),(0,t.jsxs)("div",{className:"flex ".concat(y?"justify-between":"items-center"),children:[(0,t.jsx)(p.Z,{className:"ml-8 text-center ",children:"Model Hub"}),!1==y?b?(0,t.jsx)(i.Z,{className:"ml-4",onClick:()=>R(),children:"✨ Make Public"}):(0,t.jsx)(i.Z,{className:"ml-4",children:(0,t.jsx)("a",{href:"https://forms.gle/W3U4PZpJGFHWtHyA9",target:"_blank",children:"✨ Make Public"})}):(0,t.jsxs)("div",{className:"flex justify-between items-center",children:[(0,t.jsx)("p",{children:"Filter by key:"}),(0,t.jsx)(x.Z,{className:"bg-gray-200 pr-2 pl-2 pt-1 pb-1 text-center",children:"/ui/model_hub?key="})]})]}),(0,t.jsx)("div",{className:"grid grid-cols-2 gap-6 sm:grid-cols-3 lg:grid-cols-4 pr-8",children:k&&k.map(e=>(0,t.jsxs)(o.Z,{className:"mt-5 mx-8",children:[(0,t.jsxs)("pre",{className:"flex justify-between",children:[(0,t.jsx)(p.Z,{children:e.model_group}),(0,t.jsx)(Z.Z,{title:e.model_group,children:(0,t.jsx)(j.Z,{onClick:()=>D(e.model_group),style:{cursor:"pointer",marginRight:"10px"}})})]}),(0,t.jsxs)("div",{className:"my-5",children:[(0,t.jsxs)(x.Z,{children:["Mode: ",e.mode]}),(0,t.jsxs)(x.Z,{children:["Supports Function Calling:"," ",(null==e?void 0:e.supports_function_calling)==!0?"Yes":"No"]}),(0,t.jsxs)(x.Z,{children:["Supports Vision:"," ",(null==e?void 0:e.supports_vision)==!0?"Yes":"No"]}),(0,t.jsxs)(x.Z,{children:["Max Input Tokens:"," ",(null==e?void 0:e.max_input_tokens)?null==e?void 0:e.max_input_tokens:"N/A"]}),(0,t.jsxs)(x.Z,{children:["Max Output Tokens:"," ",(null==e?void 0:e.max_output_tokens)?null==e?void 0:e.max_output_tokens:"N/A"]})]}),(0,t.jsx)("div",{style:{marginTop:"auto",textAlign:"right"},children:(0,t.jsxs)("a",{href:"#",onClick:()=>E(e),style:{color:"#1890ff",fontSize:"smaller"},children:["View more ",(0,t.jsx)(g.Z,{})]})})]},e.model_group))})]}):(0,t.jsxs)(o.Z,{className:"mx-auto max-w-xl mt-10",children:[(0,t.jsx)(x.Z,{className:"text-xl text-center mb-2 text-black",children:"Public Model Hub not enabled."}),(0,t.jsx)("p",{className:"text-base text-center text-slate-800",children:"Ask your proxy admin to enable this on their Admin UI."})]}),(0,t.jsx)(f.Z,{title:"Public Model Hub",width:600,visible:I,footer:null,onOk:M,onCancel:F,children:(0,t.jsxs)("div",{className:"pt-5 pb-5",children:[(0,t.jsxs)("div",{className:"flex justify-between mb-4",children:[(0,t.jsx)(x.Z,{className:"text-base mr-2",children:"Shareable Link:"}),(0,t.jsx)(x.Z,{className:"max-w-sm ml-2 bg-gray-200 pr-2 pl-2 pt-1 pb-1 text-center rounded",children:"/ui/model_hub?key="})]}),(0,t.jsx)("div",{className:"flex justify-end",children:(0,t.jsx)(i.Z,{onClick:()=>{O.replace("/model_hub?key=".concat(s))},children:"See Page"})})]})}),(0,t.jsx)(f.Z,{title:P&&P.model_group?P.model_group:"Unknown Model",width:800,visible:N,footer:null,onOk:M,onCancel:F,children:P&&(0,t.jsxs)("div",{children:[(0,t.jsx)("p",{className:"mb-4",children:(0,t.jsx)("strong",{children:"Model Information & Usage"})}),(0,t.jsxs)(c.Z,{children:[(0,t.jsxs)(m.Z,{children:[(0,t.jsx)(d.Z,{children:"OpenAI Python SDK"}),(0,t.jsx)(d.Z,{children:"Supported OpenAI Params"}),(0,t.jsx)(d.Z,{children:"LlamaIndex"}),(0,t.jsx)(d.Z,{children:"Langchain Py"})]}),(0,t.jsxs)(h.Z,{children:[(0,t.jsx)(u.Z,{children:(0,t.jsx)(_.Z,{language:"python",children:'\nimport openai\nclient = openai.OpenAI(\n api_key="your_api_key",\n base_url="http://0.0.0.0:4000" # LiteLLM Proxy is OpenAI compatible, Read More: https://docs.litellm.ai/docs/proxy/user_keys\n)\n\nresponse = client.chat.completions.create(\n model="'.concat(P.model_group,'", # model to send to the proxy\n messages = [\n {\n "role": "user",\n "content": "this is a test request, write a short poem"\n }\n ]\n)\n\nprint(response)\n ')})}),(0,t.jsx)(u.Z,{children:(0,t.jsx)(_.Z,{language:"python",children:"".concat(null===(l=P.supported_openai_params)||void 0===l?void 0:l.map(e=>"".concat(e,"\n")).join(""))})}),(0,t.jsx)(u.Z,{children:(0,t.jsx)(_.Z,{language:"python",children:'\nimport os, dotenv\n\nfrom llama_index.llms import AzureOpenAI\nfrom llama_index.embeddings import AzureOpenAIEmbedding\nfrom llama_index import VectorStoreIndex, SimpleDirectoryReader, ServiceContext\n\nllm = AzureOpenAI(\n engine="'.concat(P.model_group,'", # model_name on litellm proxy\n temperature=0.0,\n azure_endpoint="http://0.0.0.0:4000", # litellm proxy endpoint\n api_key="sk-1234", # litellm proxy API Key\n api_version="2023-07-01-preview",\n)\n\nembed_model = AzureOpenAIEmbedding(\n deployment_name="azure-embedding-model",\n azure_endpoint="http://0.0.0.0:4000",\n api_key="sk-1234",\n api_version="2023-07-01-preview",\n)\n\n\ndocuments = SimpleDirectoryReader("llama_index_data").load_data()\nservice_context = ServiceContext.from_defaults(llm=llm, embed_model=embed_model)\nindex = VectorStoreIndex.from_documents(documents, service_context=service_context)\n\nquery_engine = index.as_query_engine()\nresponse = query_engine.query("What did the author do growing up?")\nprint(response)\n\n ')})}),(0,t.jsx)(u.Z,{children:(0,t.jsx)(_.Z,{language:"python",children:'\nfrom langchain.chat_models import ChatOpenAI\nfrom langchain.prompts.chat import (\n ChatPromptTemplate,\n HumanMessagePromptTemplate,\n SystemMessagePromptTemplate,\n)\nfrom langchain.schema import HumanMessage, SystemMessage\n\nchat = ChatOpenAI(\n openai_api_base="http://0.0.0.0:4000",\n model = "'.concat(P.model_group,'",\n temperature=0.1\n)\n\nmessages = [\n SystemMessage(\n content="You are a helpful assistant that im using to make a test request to."\n ),\n HumanMessage(\n content="test from litellm. tell me why it\'s amazing in 1 sentence"\n ),\n]\nresponse = chat(messages)\n\nprint(response)\n\n ')})})]})]})]})})]})}}},function(e){e.O(0,[936,294,131,684,759,777,971,69,744],function(){return e(e.s=20661)}),_N_E=e.O()}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/app/page-5b9334558218205d.js b/litellm/proxy/_experimental/out/_next/static/chunks/app/page-5b9334558218205d.js deleted file mode 100644 index b68b1963c55..00000000000 --- a/litellm/proxy/_experimental/out/_next/static/chunks/app/page-5b9334558218205d.js +++ /dev/null @@ -1 +0,0 @@ -(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[931],{20661:function(e,l,s){Promise.resolve().then(s.bind(s,48951))},48951:function(e,l,s){"use strict";s.r(l),s.d(l,{default:function(){return li}});var t,n,a=s(3827),r=s(64090),i=s(47907),o=s(8792),d=s(40491),c=s(65270),m=e=>{let{userID:l,userRole:s,userEmail:t,showSSOBanner:n,premiumUser:r,setProxySettings:i,proxySettings:m}=e;console.log("User ID:",l),console.log("userEmail:",t),console.log("showSSOBanner:",n),console.log("premiumUser:",r);let u="";console.log("PROXY_settings=",m),m&&m.PROXY_LOGOUT_URL&&void 0!==m.PROXY_LOGOUT_URL&&(u=m.PROXY_LOGOUT_URL),console.log("logoutUrl=",u);let h=[{key:"1",label:(0,a.jsxs)(a.Fragment,{children:[(0,a.jsxs)("p",{children:["Role: ",s]}),(0,a.jsxs)("p",{children:["ID: ",l]}),(0,a.jsxs)("p",{children:["Premium User: ",String(r)]})]})},{key:"2",label:(0,a.jsx)("a",{href:u,children:(0,a.jsx)("p",{children:"Logout"})})}];return(0,a.jsxs)("nav",{className:"left-0 right-0 top-0 flex justify-between items-center h-12 mb-4",children:[(0,a.jsx)("div",{className:"text-left my-2 absolute top-0 left-0",children:(0,a.jsx)("div",{className:"flex flex-col items-center",children:(0,a.jsx)(o.default,{href:"/",children:(0,a.jsx)("button",{className:"text-gray-800 rounded text-center",children:(0,a.jsx)("img",{src:"/get_image",width:160,height:160,alt:"LiteLLM Brand",className:"mr-2"})})})})}),(0,a.jsxs)("div",{className:"text-right mx-4 my-2 absolute top-0 right-0 flex items-center justify-end space-x-2",children:[n?(0,a.jsx)("div",{style:{padding:"6px",borderRadius:"8px"},children:(0,a.jsx)("a",{href:"https://calendly.com/d/4mp-gd3-k5k/litellm-1-1-onboarding-chat",target:"_blank",style:{fontSize:"14px",textDecoration:"underline"},children:"Get enterprise license"})}):null,(0,a.jsx)("div",{style:{border:"1px solid #391085",padding:"6px",borderRadius:"8px"},children:(0,a.jsx)(d.Z,{menu:{items:h},children:(0,a.jsx)(c.Z,{children:t})})})]})]})},u=s(777),h=s(10384),x=s(46453),p=s(16450),j=s(52273),g=s(26780),Z=s(15595),f=s(6698),_=s(71801),y=s(42440),b=s(42308),v=s(50670),S=s(60620),k=s(80588),w=s(99129),N=s(44839),A=s(88707),I=s(1861);let{Option:C}=v.default;var P=e=>{let{userID:l,team:s,userRole:t,accessToken:n,data:i,setData:o}=e,[d]=S.Z.useForm(),[c,m]=(0,r.useState)(!1),[P,T]=(0,r.useState)(null),[O,E]=(0,r.useState)(null),[R,M]=(0,r.useState)([]),[F,D]=(0,r.useState)([]),L=()=>{m(!1),d.resetFields()},U=()=>{m(!1),T(null),d.resetFields()};(0,r.useEffect)(()=>{(async()=>{try{if(null===l||null===t)return;if(null!==n){let e=(await (0,u.So)(n,l,t)).data.map(e=>e.id);console.log("available_model_names:",e),M(e)}}catch(e){console.error("Error fetching user models:",e)}})()},[n,l,t]);let V=async e=>{try{var s,t,a;let r=null!==(s=null==e?void 0:e.key_alias)&&void 0!==s?s:"",c=null!==(t=null==e?void 0:e.team_id)&&void 0!==t?t:null;if((null!==(a=null==i?void 0:i.filter(e=>e.team_id===c).map(e=>e.key_alias))&&void 0!==a?a:[]).includes(r))throw Error("Key alias ".concat(r," already exists for team with ID ").concat(c,", please provide another key alias"));k.ZP.info("Making API Call"),m(!0);let h=await (0,u.wX)(n,l,e);console.log("key create Response:",h),o(e=>e?[...e,h]:[h]),T(h.key),E(h.soft_budget),k.ZP.success("API Key Created"),d.resetFields(),localStorage.removeItem("userData"+l)}catch(e){console.error("Error creating the key:",e),k.ZP.error("Error creating the key: ".concat(e),20)}};return(0,r.useEffect)(()=>{D(s&&s.models.length>0?s.models.includes("all-proxy-models")?R:s.models:R)},[s,R]),(0,a.jsxs)("div",{children:[(0,a.jsx)(p.Z,{className:"mx-auto",onClick:()=>m(!0),children:"+ Create New Key"}),(0,a.jsx)(w.Z,{title:"Create Key",visible:c,width:800,footer:null,onOk:L,onCancel:U,children:(0,a.jsxs)(S.Z,{form:d,onFinish:V,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(S.Z.Item,{label:"Key Name",name:"key_alias",rules:[{required:!0,message:"Please input a key name"}],help:"required",children:(0,a.jsx)(j.Z,{placeholder:""})}),(0,a.jsx)(S.Z.Item,{label:"Team ID",name:"team_id",hidden:!0,initialValue:s?s.team_id:null,valuePropName:"team_id",className:"mt-8",children:(0,a.jsx)(N.Z,{value:s?s.team_alias:"",disabled:!0})}),(0,a.jsx)(S.Z.Item,{label:"Models",name:"models",rules:[{required:!0,message:"Please select a model"}],help:"required",children:(0,a.jsxs)(v.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},onChange:e=>{e.includes("all-team-models")&&d.setFieldsValue({models:["all-team-models"]})},children:[(0,a.jsx)(C,{value:"all-team-models",children:"All Team Models"},"all-team-models"),F.map(e=>(0,a.jsx)(C,{value:e,children:e},e))]})}),(0,a.jsxs)(g.Z,{className:"mt-20 mb-8",children:[(0,a.jsx)(f.Z,{children:(0,a.jsx)("b",{children:"Optional Settings"})}),(0,a.jsxs)(Z.Z,{children:[(0,a.jsx)(S.Z.Item,{className:"mt-8",label:"Max Budget (USD)",name:"max_budget",help:"Budget cannot exceed team max budget: $".concat((null==s?void 0:s.max_budget)!==null&&(null==s?void 0:s.max_budget)!==void 0?null==s?void 0:s.max_budget:"unlimited"),rules:[{validator:async(e,l)=>{if(l&&s&&null!==s.max_budget&&l>s.max_budget)throw Error("Budget cannot exceed team max budget: $".concat(s.max_budget))}}],children:(0,a.jsx)(A.Z,{step:.01,precision:2,width:200})}),(0,a.jsx)(S.Z.Item,{className:"mt-8",label:"Reset Budget",name:"budget_duration",help:"Team Reset Budget: ".concat((null==s?void 0:s.budget_duration)!==null&&(null==s?void 0:s.budget_duration)!==void 0?null==s?void 0:s.budget_duration:"None"),children:(0,a.jsxs)(v.default,{defaultValue:null,placeholder:"n/a",children:[(0,a.jsx)(v.default.Option,{value:"24h",children:"daily"}),(0,a.jsx)(v.default.Option,{value:"7d",children:"weekly"}),(0,a.jsx)(v.default.Option,{value:"30d",children:"monthly"})]})}),(0,a.jsx)(S.Z.Item,{className:"mt-8",label:"Tokens per minute Limit (TPM)",name:"tpm_limit",help:"TPM cannot exceed team TPM limit: ".concat((null==s?void 0:s.tpm_limit)!==null&&(null==s?void 0:s.tpm_limit)!==void 0?null==s?void 0:s.tpm_limit:"unlimited"),rules:[{validator:async(e,l)=>{if(l&&s&&null!==s.tpm_limit&&l>s.tpm_limit)throw Error("TPM limit cannot exceed team TPM limit: ".concat(s.tpm_limit))}}],children:(0,a.jsx)(A.Z,{step:1,width:400})}),(0,a.jsx)(S.Z.Item,{className:"mt-8",label:"Requests per minute Limit (RPM)",name:"rpm_limit",help:"RPM cannot exceed team RPM limit: ".concat((null==s?void 0:s.rpm_limit)!==null&&(null==s?void 0:s.rpm_limit)!==void 0?null==s?void 0:s.rpm_limit:"unlimited"),rules:[{validator:async(e,l)=>{if(l&&s&&null!==s.rpm_limit&&l>s.rpm_limit)throw Error("RPM limit cannot exceed team RPM limit: ".concat(s.rpm_limit))}}],children:(0,a.jsx)(A.Z,{step:1,width:400})}),(0,a.jsx)(S.Z.Item,{label:"Expire Key (eg: 30s, 30h, 30d)",name:"duration",className:"mt-8",children:(0,a.jsx)(j.Z,{placeholder:""})}),(0,a.jsx)(S.Z.Item,{label:"Metadata",name:"metadata",className:"mt-8",children:(0,a.jsx)(N.Z.TextArea,{rows:4,placeholder:"Enter metadata as JSON"})})]})]})]}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(I.ZP,{htmlType:"submit",children:"Create Key"})})]})}),P&&(0,a.jsx)(w.Z,{visible:c,onOk:L,onCancel:U,footer:null,children:(0,a.jsxs)(x.Z,{numItems:1,className:"gap-2 w-full",children:[(0,a.jsx)(y.Z,{children:"Save your Key"}),(0,a.jsx)(h.Z,{numColSpan:1,children:(0,a.jsxs)("p",{children:["Please save this secret key somewhere safe and accessible. For security reasons, ",(0,a.jsx)("b",{children:"you will not be able to view it again"})," ","through your LiteLLM account. If you lose this secret key, you will need to generate a new one."]})}),(0,a.jsx)(h.Z,{numColSpan:1,children:null!=P?(0,a.jsxs)("div",{children:[(0,a.jsx)(_.Z,{className:"mt-3",children:"API Key:"}),(0,a.jsx)("div",{style:{background:"#f8f8f8",padding:"10px",borderRadius:"5px",marginBottom:"10px"},children:(0,a.jsx)("pre",{style:{wordWrap:"break-word",whiteSpace:"normal"},children:P})}),(0,a.jsx)(b.CopyToClipboard,{text:P,onCopy:()=>{k.ZP.success("API Key copied to clipboard")},children:(0,a.jsx)(p.Z,{className:"mt-3",children:"Copy API Key"})})]}):(0,a.jsx)(_.Z,{children:"Key being created, this might take 30s"})})]})})]})},T=s(9454),O=s(98941),E=s(33393),R=s(5),M=s(13810),F=s(61244),D=s(10827),L=s(3851),U=s(2044),V=s(64167),z=s(74480),q=s(7178),B=s(95093),K=s(27166);let{Option:W}=v.default;var H=e=>{let{userID:l,userRole:s,accessToken:t,selectedTeam:n,data:i,setData:o,teams:d}=e,[c,m]=(0,r.useState)(!1),[h,x]=(0,r.useState)(!1),[j,g]=(0,r.useState)(null),[Z,f]=(0,r.useState)(null),[b,C]=(0,r.useState)(null),[P,H]=(0,r.useState)(""),[G,Y]=(0,r.useState)(!1),[J,X]=(0,r.useState)(!1),[$,Q]=(0,r.useState)(null),[ee,el]=(0,r.useState)([]),es=new Set,[et,en]=(0,r.useState)(es);(0,r.useEffect)(()=>{(async()=>{try{if(null===l)return;if(null!==t&&null!==s){let e=(await (0,u.So)(t,l,s)).data.map(e=>e.id);console.log("available_model_names:",e),el(e)}}catch(e){console.error("Error fetching user models:",e)}})()},[t,l,s]),(0,r.useEffect)(()=>{if(d){let e=new Set;d.forEach((l,s)=>{let t=l.team_id;e.add(t)}),en(e)}},[d]);let ea=e=>{console.log("handleEditClick:",e),null==e.token&&null!==e.token_id&&(e.token=e.token_id),Q(e),Y(!0)},er=async e=>{if(null==t)return;let l=e.token;e.key=l,console.log("handleEditSubmit:",e);let s=await (0,u.Nc)(t,e);console.log("handleEditSubmit: newKeyValues",s),i&&o(i.map(e=>e.token===l?s:e)),k.ZP.success("Key updated successfully"),Y(!1),Q(null)},ei=async e=>{console.log("handleDelete:",e),null==e.token&&null!==e.token_id&&(e.token=e.token_id),null!=i&&(g(e.token),localStorage.removeItem("userData"+l),x(!0))},eo=async()=>{if(null!=j&&null!=i){try{await (0,u.I1)(t,j);let e=i.filter(e=>e.token!==j);o(e)}catch(e){console.error("Error deleting the key:",e)}x(!1),g(null)}};if(null!=i)return console.log("RERENDER TRIGGERED"),(0,a.jsxs)("div",{children:[(0,a.jsxs)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh] mb-4 mt-2",children:[(0,a.jsxs)(D.Z,{className:"mt-5 max-h-[300px] min-h-[300px]",children:[(0,a.jsx)(V.Z,{children:(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(z.Z,{children:"Key Alias"}),(0,a.jsx)(z.Z,{children:"Secret Key"}),(0,a.jsx)(z.Z,{children:"Spend (USD)"}),(0,a.jsx)(z.Z,{children:"Budget (USD)"}),(0,a.jsx)(z.Z,{children:"Models"}),(0,a.jsx)(z.Z,{children:"TPM / RPM Limits"})]})}),(0,a.jsx)(L.Z,{children:i.map(e=>{if(console.log(e),"litellm-dashboard"===e.team_id)return null;if(n){if(console.log("item team id: ".concat(e.team_id,", knownTeamIDs.has(item.team_id): ").concat(et.has(e.team_id),", selectedTeam id: ").concat(n.team_id)),(null!=n.team_id||null===e.team_id||et.has(e.team_id))&&e.team_id!=n.team_id)return null;console.log("item team id: ".concat(e.team_id,", is returned"))}return(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(U.Z,{style:{maxWidth:"2px",whiteSpace:"pre-wrap",overflow:"hidden"},children:null!=e.key_alias?(0,a.jsx)(_.Z,{children:e.key_alias}):(0,a.jsx)(_.Z,{children:"Not Set"})}),(0,a.jsx)(U.Z,{children:(0,a.jsx)(_.Z,{children:e.key_name})}),(0,a.jsx)(U.Z,{children:(0,a.jsx)(_.Z,{children:(()=>{try{return parseFloat(e.spend).toFixed(4)}catch(l){return e.spend}})()})}),(0,a.jsx)(U.Z,{children:null!=e.max_budget?(0,a.jsx)(_.Z,{children:e.max_budget}):(0,a.jsx)(_.Z,{children:"Unlimited"})}),(0,a.jsx)(U.Z,{children:Array.isArray(e.models)?(0,a.jsx)("div",{style:{display:"flex",flexDirection:"column"},children:0===e.models.length?(0,a.jsx)(a.Fragment,{children:n&&n.models&&n.models.length>0?n.models.map((e,l)=>"all-proxy-models"===e?(0,a.jsx)(R.Z,{size:"xs",className:"mb-1",color:"red",children:(0,a.jsx)(_.Z,{children:"All Proxy Models"})},l):"all-team-models"===e?(0,a.jsx)(R.Z,{size:"xs",className:"mb-1",color:"red",children:(0,a.jsx)(_.Z,{children:"All Team Models"})},l):(0,a.jsx)(R.Z,{size:"xs",className:"mb-1",color:"blue",children:(0,a.jsx)(_.Z,{children:e.length>30?"".concat(e.slice(0,30),"..."):e})},l)):(0,a.jsx)(R.Z,{size:"xs",className:"mb-1",color:"blue",children:(0,a.jsx)(_.Z,{children:"all-proxy-models"})})}):e.models.map((e,l)=>"all-proxy-models"===e?(0,a.jsx)(R.Z,{size:"xs",className:"mb-1",color:"red",children:(0,a.jsx)(_.Z,{children:"All Proxy Models"})},l):"all-team-models"===e?(0,a.jsx)(R.Z,{size:"xs",className:"mb-1",color:"red",children:(0,a.jsx)(_.Z,{children:"All Team Models"})},l):(0,a.jsx)(R.Z,{size:"xs",className:"mb-1",color:"blue",children:(0,a.jsx)(_.Z,{children:e.length>30?"".concat(e.slice(0,30),"..."):e})},l))}):null}),(0,a.jsx)(U.Z,{children:(0,a.jsxs)(_.Z,{children:["TPM: ",e.tpm_limit?e.tpm_limit:"Unlimited"," ",(0,a.jsx)("br",{})," RPM:"," ",e.rpm_limit?e.rpm_limit:"Unlimited"]})}),(0,a.jsxs)(U.Z,{children:[(0,a.jsx)(F.Z,{onClick:()=>{Q(e),X(!0)},icon:T.Z,size:"sm"}),(0,a.jsx)(w.Z,{open:J,onCancel:()=>{X(!1),Q(null)},footer:null,width:800,children:$&&(0,a.jsxs)(a.Fragment,{children:[(0,a.jsxs)("div",{className:"grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3 mt-8",children:[(0,a.jsxs)(M.Z,{children:[(0,a.jsx)("p",{className:"text-tremor-default font-medium text-tremor-content dark:text-dark-tremor-content",children:"Spend"}),(0,a.jsx)("div",{className:"mt-2 flex items-baseline space-x-2.5",children:(0,a.jsx)("p",{className:"text-tremor font-semibold text-tremor-content-strong dark:text-dark-tremor-content-strong",children:(()=>{try{return parseFloat($.spend).toFixed(4)}catch(e){return $.spend}})()})})]}),(0,a.jsxs)(M.Z,{children:[(0,a.jsx)("p",{className:"text-tremor-default font-medium text-tremor-content dark:text-dark-tremor-content",children:"Budget"}),(0,a.jsx)("div",{className:"mt-2 flex items-baseline space-x-2.5",children:(0,a.jsx)("p",{className:"text-tremor font-semibold text-tremor-content-strong dark:text-dark-tremor-content-strong",children:null!=$.max_budget?(0,a.jsx)(a.Fragment,{children:$.max_budget}):(0,a.jsx)(a.Fragment,{children:"Unlimited"})})})]},e.name),(0,a.jsxs)(M.Z,{children:[(0,a.jsx)("p",{className:"text-tremor-default font-medium text-tremor-content dark:text-dark-tremor-content",children:"Expires"}),(0,a.jsx)("div",{className:"mt-2 flex items-baseline space-x-2.5",children:(0,a.jsx)("p",{className:"text-tremor-default font-small text-tremor-content-strong dark:text-dark-tremor-content-strong",children:null!=$.expires?(0,a.jsx)(a.Fragment,{children:new Date($.expires).toLocaleString(void 0,{day:"numeric",month:"long",year:"numeric",hour:"numeric",minute:"numeric",second:"numeric"})}):(0,a.jsx)(a.Fragment,{children:"Never"})})})]},e.name)]}),(0,a.jsxs)(M.Z,{className:"my-4",children:[(0,a.jsx)(y.Z,{children:"Token Name"}),(0,a.jsx)(_.Z,{className:"my-1",children:$.key_alias?$.key_alias:$.key_name}),(0,a.jsx)(y.Z,{children:"Token ID"}),(0,a.jsx)(_.Z,{className:"my-1 text-[12px]",children:$.token}),(0,a.jsx)(y.Z,{children:"Metadata"}),(0,a.jsx)(_.Z,{className:"my-1",children:(0,a.jsxs)("pre",{children:[JSON.stringify($.metadata)," "]})})]}),(0,a.jsx)(p.Z,{className:"mx-auto flex items-center",onClick:()=>{X(!1),Q(null)},children:"Close"})]})}),(0,a.jsx)(F.Z,{icon:O.Z,size:"sm",onClick:()=>ea(e)}),(0,a.jsx)(F.Z,{onClick:()=>ei(e),icon:E.Z,size:"sm"})]})]},e.token)})})]}),h&&(0,a.jsx)("div",{className:"fixed z-10 inset-0 overflow-y-auto",children:(0,a.jsxs)("div",{className:"flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0",children:[(0,a.jsx)("div",{className:"fixed inset-0 transition-opacity","aria-hidden":"true",children:(0,a.jsx)("div",{className:"absolute inset-0 bg-gray-500 opacity-75"})}),(0,a.jsx)("span",{className:"hidden sm:inline-block sm:align-middle sm:h-screen","aria-hidden":"true",children:"​"}),(0,a.jsxs)("div",{className:"inline-block align-bottom bg-white rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full",children:[(0,a.jsx)("div",{className:"bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4",children:(0,a.jsx)("div",{className:"sm:flex sm:items-start",children:(0,a.jsxs)("div",{className:"mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left",children:[(0,a.jsx)("h3",{className:"text-lg leading-6 font-medium text-gray-900",children:"Delete Key"}),(0,a.jsx)("div",{className:"mt-2",children:(0,a.jsx)("p",{className:"text-sm text-gray-500",children:"Are you sure you want to delete this key ?"})})]})})}),(0,a.jsxs)("div",{className:"bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse",children:[(0,a.jsx)(p.Z,{onClick:eo,color:"red",className:"ml-2",children:"Delete"}),(0,a.jsx)(p.Z,{onClick:()=>{x(!1),g(null)},children:"Cancel"})]})]})]})})]}),$&&(0,a.jsx)(e=>{let{visible:l,onCancel:s,token:t,onSubmit:i}=e,[o]=S.Z.useForm(),[c,m]=(0,r.useState)(n),[u,h]=(0,r.useState)([]),[x,p]=(0,r.useState)(!1);return(0,a.jsx)(w.Z,{title:"Edit Key",visible:l,width:800,footer:null,onOk:()=>{o.validateFields().then(e=>{o.resetFields()}).catch(e=>{console.error("Validation failed:",e)})},onCancel:s,children:(0,a.jsxs)(S.Z,{form:o,onFinish:er,initialValues:t,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(S.Z.Item,{label:"Key Name",name:"key_alias",rules:[{required:!0,message:"Please input a key name"}],help:"required",children:(0,a.jsx)(N.Z,{})}),(0,a.jsx)(S.Z.Item,{label:"Models",name:"models",rules:[{validator:(e,l)=>{let s=l.filter(e=>!c.models.includes(e)&&"all-team-models"!==e&&"all-proxy-models"!==e&&!c.models.includes("all-proxy-models"));return(console.log("errorModels: ".concat(s)),s.length>0)?Promise.reject("Some models are not part of the new team's models - ".concat(s,"Team models: ").concat(c.models)):Promise.resolve()}}],children:(0,a.jsxs)(v.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:[(0,a.jsx)(W,{value:"all-team-models",children:"All Team Models"},"all-team-models"),c&&c.models?c.models.includes("all-proxy-models")?ee.filter(e=>"all-proxy-models"!==e).map(e=>(0,a.jsx)(W,{value:e,children:e},e)):c.models.map(e=>(0,a.jsx)(W,{value:e,children:e},e)):ee.map(e=>(0,a.jsx)(W,{value:e,children:e},e))]})}),(0,a.jsx)(S.Z.Item,{className:"mt-8",label:"Max Budget (USD)",name:"max_budget",help:"Budget cannot exceed team max budget: ".concat((null==c?void 0:c.max_budget)!==null&&(null==c?void 0:c.max_budget)!==void 0?null==c?void 0:c.max_budget:"unlimited"),rules:[{validator:async(e,l)=>{if(l&&c&&null!==c.max_budget&&l>c.max_budget)throw console.log("keyTeam.max_budget: ".concat(c.max_budget)),Error("Budget cannot exceed team max budget: $".concat(c.max_budget))}}],children:(0,a.jsx)(A.Z,{step:.01,precision:2,width:200})}),(0,a.jsx)(S.Z.Item,{label:"token",name:"token",hidden:!0}),(0,a.jsx)(S.Z.Item,{label:"Team",name:"team_id",help:"the team this key belongs to",children:(0,a.jsx)(B.Z,{value:t.team_alias,children:null==d?void 0:d.map((e,l)=>(0,a.jsx)(K.Z,{value:e.team_id,onClick:()=>m(e),children:e.team_alias},l))})})]}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(I.ZP,{htmlType:"submit",children:"Edit Key"})})]})})},{visible:G,onCancel:()=>{Y(!1),Q(null)},token:$,onSubmit:er})]})},G=e=>{let{userID:l,userRole:s,accessToken:t,userSpend:n,selectedTeam:i}=e;console.log("userSpend: ".concat(n));let[o,d]=(0,r.useState)(null!==n?n:0),[c,m]=(0,r.useState)(0),[h,x]=(0,r.useState)([]);(0,r.useEffect)(()=>{let e=async()=>{if(t&&l&&s&&"Admin"===s&&null==n)try{let e=await (0,u.Qy)(t);e&&(e.spend?d(e.spend):d(0),e.max_budget?m(e.max_budget):m(0))}catch(e){console.error("Error fetching global spend data:",e)}};(async()=>{try{if(null===l||null===s)return;if(null!==t){let e=(await (0,u.So)(t,l,s)).data.map(e=>e.id);console.log("available_model_names:",e),x(e)}}catch(e){console.error("Error fetching user models:",e)}})(),e()},[s,t,l]),(0,r.useEffect)(()=>{null!==n&&d(n)},[n]);let p=[];i&&i.models&&(p=i.models),p&&p.includes("all-proxy-models")?(console.log("user models:",h),p=h):p&&p.includes("all-team-models")?p=i.models:p&&0===p.length&&(p=h);let j=void 0!==o?o.toFixed(4):null;return console.log("spend in view user spend: ".concat(o)),(0,a.jsx)("div",{className:"flex items-center",children:(0,a.jsxs)("div",{children:[(0,a.jsxs)("p",{className:"text-tremor-default text-tremor-content dark:text-dark-tremor-content",children:["Total Spend"," "]}),(0,a.jsxs)("p",{className:"text-2xl text-tremor-content-strong dark:text-dark-tremor-content-strong font-semibold",children:["$",j]})]})})},Y=e=>{let{userID:l,userRole:s,selectedTeam:t,accessToken:n}=e,[i,o]=(0,r.useState)([]);(0,r.useEffect)(()=>{(async()=>{try{if(null===l||null===s)return;if(null!==n){let e=(await (0,u.So)(n,l,s)).data.map(e=>e.id);console.log("available_model_names:",e),o(e)}}catch(e){console.error("Error fetching user models:",e)}})()},[n,l,s]);let d=[];return t&&t.models&&(d=t.models),d&&d.includes("all-proxy-models")&&(console.log("user models:",i),d=i),(0,a.jsx)(a.Fragment,{children:(0,a.jsx)("div",{className:"mb-5",children:(0,a.jsx)("p",{className:"text-3xl text-tremor-content-strong dark:text-dark-tremor-content-strong font-semibold",children:null==t?void 0:t.team_alias})})})},J=e=>{let l,{teams:s,setSelectedTeam:t,userRole:n}=e,i={models:[],team_id:null,team_alias:"Default Team"},[o,d]=(0,r.useState)(i);return(l="App User"===n?s:s?[...s,i]:[i],"App User"===n)?null:(0,a.jsxs)("div",{className:"mt-5 mb-5",children:[(0,a.jsx)(y.Z,{children:"Select Team"}),(0,a.jsx)(_.Z,{children:"If you belong to multiple teams, this setting controls which team is used by default when creating new API Keys."}),(0,a.jsxs)(_.Z,{className:"mt-3 mb-3",children:[(0,a.jsx)("b",{children:"Default Team:"})," If no team_id is set for a key, it will be grouped under here."]}),l&&l.length>0?(0,a.jsx)(B.Z,{defaultValue:"0",children:l.map((e,l)=>(0,a.jsx)(K.Z,{value:String(l),onClick:()=>t(e),children:e.team_alias},l))}):(0,a.jsxs)(_.Z,{children:["No team created. ",(0,a.jsx)("b",{children:"Defaulting to personal account."})]})]})},X=s(37963),$=s(97482);console.log("isLocal:",!1);var Q=e=>{let{userID:l,userRole:s,teams:t,keys:n,setUserRole:o,userEmail:d,setUserEmail:c,setTeams:m,setKeys:p,setProxySettings:j,proxySettings:g}=e,[Z,f]=(0,r.useState)(null),_=(0,i.useSearchParams)();_.get("viewSpend"),(0,i.useRouter)();let y=_.get("token"),[b,v]=(0,r.useState)(null),[S,k]=(0,r.useState)(null),[w,N]=(0,r.useState)([]),A={models:[],team_alias:"Default Team",team_id:null},[I,C]=(0,r.useState)(t?t[0]:A);if(window.addEventListener("beforeunload",function(){sessionStorage.clear()}),(0,r.useEffect)(()=>{if(y){let e=(0,X.o)(y);if(e){if(console.log("Decoded token:",e),console.log("Decoded key:",e.key),v(e.key),e.user_role){let l=function(e){if(!e)return"Undefined Role";switch(console.log("Received user role: ".concat(e)),e.toLowerCase()){case"app_owner":case"demo_app_owner":return"App Owner";case"app_admin":case"proxy_admin":return"Admin";case"proxy_admin_viewer":return"Admin Viewer";case"app_user":return"App User";case"internal_user":return"Internal User";case"internal_user_viewer":return"Internal Viewer";default:return"Unknown Role"}}(e.user_role);console.log("Decoded user_role:",l),o(l)}else console.log("User role not defined");e.user_email?c(e.user_email):console.log("User Email is not set ".concat(e))}}if(l&&b&&s&&!n&&!Z){let e=sessionStorage.getItem("userModels"+l);e?N(JSON.parse(e)):(async()=>{try{let e=await (0,u.Dj)(b);j(e);let t=await (0,u.Br)(b,l,s,!1,null,null);if(console.log("received teams in user dashboard: ".concat(Object.keys(t),"; team values: ").concat(Object.entries(t.teams))),"Admin"==s){let e=await (0,u.Qy)(b);f(e),console.log("globalSpend:",e)}else f(t.user_info);p(t.keys),m(t.teams);let n=[...t.teams];n.length>0?(console.log("response['teams']: ".concat(n)),C(n[0])):C(A),sessionStorage.setItem("userData"+l,JSON.stringify(t.keys)),sessionStorage.setItem("userSpendData"+l,JSON.stringify(t.user_info));let a=(await (0,u.So)(b,l,s)).data.map(e=>e.id);console.log("available_model_names:",a),N(a),console.log("userModels:",w),sessionStorage.setItem("userModels"+l,JSON.stringify(a))}catch(e){console.error("There was an error fetching the data",e)}})()}},[l,y,b,n,s]),(0,r.useEffect)(()=>{if(null!==n&&null!=I&&null!==I.team_id){let e=0;for(let l of n)I.hasOwnProperty("team_id")&&null!==l.team_id&&l.team_id===I.team_id&&(e+=l.spend);k(e)}else if(null!==n){let e=0;for(let l of n)e+=l.spend;k(e)}},[I]),null==l||null==y){let e="/sso/key/generate";return console.log("Full URL:",e),window.location.href=e,null}if(null==b)return null;if(null==s&&o("App Owner"),s&&"Admin Viewer"==s){let{Title:e,Paragraph:l}=$.default;return(0,a.jsxs)("div",{children:[(0,a.jsx)(e,{level:1,children:"Access Denied"}),(0,a.jsx)(l,{children:"Ask your proxy admin for access to create keys"})]})}return console.log("inside user dashboard, selected team",I),(0,a.jsx)("div",{className:"w-full mx-4",children:(0,a.jsx)(x.Z,{numItems:1,className:"gap-2 p-8 h-[75vh] w-full mt-2",children:(0,a.jsxs)(h.Z,{numColSpan:1,children:[(0,a.jsx)(Y,{userID:l,userRole:s,selectedTeam:I||null,accessToken:b}),(0,a.jsx)(G,{userID:l,userRole:s,accessToken:b,userSpend:S,selectedTeam:I||null}),(0,a.jsx)(H,{userID:l,userRole:s,accessToken:b,selectedTeam:I||null,data:n,setData:p,teams:t}),(0,a.jsx)(P,{userID:l,team:I||null,userRole:s,accessToken:b,data:n,setData:p},I?I.team_id:null),(0,a.jsx)(J,{teams:t,setSelectedTeam:C,userRole:s})]})})})},ee=s(49167),el=s(35087),es=s(92836),et=s(26734),en=s(41608),ea=s(32126),er=s(23682),ei=s(47047),eo=s(76628),ed=s(25707),ec=s(44041),em=s(6180),eu=s(28683),eh=s(38302),ex=s(66242),ep=s(78578),ej=s(63954),eg=s(34658),eZ=e=>{let{modelID:l,accessToken:s}=e,[t,n]=(0,r.useState)(!1),i=async()=>{try{k.ZP.info("Making API Call"),n(!0);let e=await (0,u.Og)(s,l);console.log("model delete Response:",e),k.ZP.success("Model ".concat(l," deleted successfully")),n(!1)}catch(e){console.error("Error deleting the model:",e)}};return(0,a.jsxs)("div",{children:[(0,a.jsx)(F.Z,{onClick:()=>n(!0),icon:E.Z,size:"sm"}),(0,a.jsx)(w.Z,{open:t,onOk:i,okType:"danger",onCancel:()=>n(!1),children:(0,a.jsxs)(x.Z,{numItems:1,className:"gap-2 w-full",children:[(0,a.jsx)(y.Z,{children:"Delete Model"}),(0,a.jsx)(h.Z,{numColSpan:1,children:(0,a.jsx)("p",{children:"Are you sure you want to delete this model? This action is irreversible."})}),(0,a.jsx)(h.Z,{numColSpan:1,children:(0,a.jsxs)("p",{children:["Model ID: ",(0,a.jsx)("b",{children:l})]})})]})})]})},ef=s(97766),e_=s(46495),ey=s(18190),eb=s(91118),ev=e=>{let{modelMetrics:l,modelMetricsCategories:s,customTooltip:t,premiumUser:n}=e;return n?(0,a.jsx)(eb.Z,{title:"Time to First token (s)",className:"h-72",data:l,index:"date",showLegend:!1,categories:s,colors:["indigo","rose"],connectNulls:!0,customTooltip:t}):(0,a.jsxs)("div",{children:[(0,a.jsx)(ey.Z,{title:"✨ Enterprise Feature",color:"teal",className:"mt-2 mb-4",children:"Enterprise features are available for users with a specific license, please contact LiteLLM to unlock this limitation."}),(0,a.jsx)(p.Z,{variant:"primary",children:(0,a.jsx)("a",{href:"https://forms.gle/W3U4PZpJGFHWtHyA9",target:"_blank",children:"Get in touch"})})]})},eS=e=>{let{fields:l,selectedProvider:s}=e;return 0===l.length?null:(0,a.jsx)(a.Fragment,{children:l.map(e=>(0,a.jsx)(S.Z.Item,{rules:[{required:!0,message:"Required"}],label:e.field_name.replace(/_/g," ").replace(/\b\w/g,e=>e.toUpperCase()),name:e.field_name,tooltip:e.field_description,className:"mb-2",children:(0,a.jsx)(j.Z,{placeholder:e.field_value,type:"password"})},e.field_name))})},ek=s(67951);let{Title:ew,Link:eN}=$.default;(t=n||(n={})).OpenAI="OpenAI",t.Azure="Azure",t.Azure_AI_Studio="Azure AI Studio",t.Anthropic="Anthropic",t.Google_AI_Studio="Google AI Studio",t.Bedrock="Amazon Bedrock",t.OpenAI_Compatible="OpenAI-Compatible Endpoints (Groq, Together AI, Mistral AI, etc.)",t.Vertex_AI="Vertex AI (Anthropic, Gemini, etc.)",t.Databricks="Databricks",t.Ollama="Ollama";let eA={OpenAI:"openai",Azure:"azure",Azure_AI_Studio:"azure_ai",Anthropic:"anthropic",Google_AI_Studio:"gemini",Bedrock:"bedrock",OpenAI_Compatible:"openai",Vertex_AI:"vertex_ai",Databricks:"databricks",Ollama:"ollama"},eI={"BadRequestError (400)":"BadRequestErrorRetries","AuthenticationError (401)":"AuthenticationErrorRetries","TimeoutError (408)":"TimeoutErrorRetries","RateLimitError (429)":"RateLimitErrorRetries","ContentPolicyViolationError (400)":"ContentPolicyViolationErrorRetries","InternalServerError (500)":"InternalServerErrorRetries"},eC=async(e,l,s)=>{try{let t=Array.isArray(e.model)?e.model:[e.model];console.log("received deployments: ".concat(t)),console.log("received type of deployments: ".concat(typeof t)),t.forEach(async s=>{console.log("litellm_model: ".concat(s));let t={},n={};t.model=s;let a="";for(let[l,s]of(console.log("formValues add deployment:",e),Object.entries(e)))if(""!==s){if("model_name"==l)a+=s;else if("custom_llm_provider"==l)continue;else if("model"==l)continue;else if("base_model"===l)n[l]=s;else if("litellm_extra_params"==l){console.log("litellm_extra_params:",s);let e={};if(s&&void 0!=s){try{e=JSON.parse(s)}catch(e){throw k.ZP.error("Failed to parse LiteLLM Extra Params: "+e,10),Error("Failed to parse litellm_extra_params: "+e)}for(let[l,s]of Object.entries(e))t[l]=s}}else t[l]=s}let r={model_name:a,litellm_params:t,model_info:n},i=await (0,u.kK)(l,r);console.log("response for model create call: ".concat(i.data))}),s.resetFields()}catch(e){k.ZP.error("Failed to create model: "+e,10)}};var eP=e=>{var l,s,t;let i,{accessToken:o,token:d,userRole:c,userID:m,modelData:h={data:[]},keys:g,setModelData:Z,premiumUser:f}=e,[b,v]=(0,r.useState)([]),[N]=S.Z.useForm(),[C,P]=(0,r.useState)(null),[E,W]=(0,r.useState)(""),[H,G]=(0,r.useState)([]),Y=Object.values(n).filter(e=>isNaN(Number(e))),[J,X]=(0,r.useState)([]),[Q,ey]=(0,r.useState)("OpenAI"),[eb,eP]=(0,r.useState)(""),[eT,eO]=(0,r.useState)(!1),[eE,eR]=(0,r.useState)(!1),[eM,eF]=(0,r.useState)(null),[eD,eL]=(0,r.useState)([]),[eU,eV]=(0,r.useState)(null),[ez,eq]=(0,r.useState)([]),[eB,eK]=(0,r.useState)([]),[eW,eH]=(0,r.useState)([]),[eG,eY]=(0,r.useState)([]),[eJ,eX]=(0,r.useState)([]),[e$,eQ]=(0,r.useState)([]),[e0,e1]=(0,r.useState)([]),[e2,e4]=(0,r.useState)([]),[e5,e8]=(0,r.useState)([]),[e3,e6]=(0,r.useState)({from:new Date(Date.now()-6048e5),to:new Date}),[e9,e7]=(0,r.useState)(null),[le,ll]=(0,r.useState)(0),[ls,lt]=(0,r.useState)({}),[ln,la]=(0,r.useState)([]),[lr,li]=(0,r.useState)(!1),[lo,ld]=(0,r.useState)(null),[lc,lm]=(0,r.useState)(null),[lu,lh]=(0,r.useState)([]);(0,r.useEffect)(()=>{lb(eU,e3.from,e3.to)},[lo,lc]);let lx=e=>{eF(e),eO(!0)},lp=e=>{eF(e),eR(!0)},lj=async e=>{if(console.log("handleEditSubmit:",e),null==o)return;let l={},s=null;for(let[t,n]of Object.entries(e))"model_id"!==t?l[t]=n:s=n;let t={litellm_params:l,model_info:{id:s}};console.log("handleEditSubmit payload:",t);try{await (0,u.um)(o,t),k.ZP.success("Model updated successfully, restart server to see updates"),eO(!1),eF(null)}catch(e){console.log("Error occurred")}},lg=()=>{W(new Date().toLocaleString())},lZ=async()=>{if(!o){console.error("Access token is missing");return}console.log("new modelGroupRetryPolicy:",e9);try{await (0,u.K_)(o,{router_settings:{model_group_retry_policy:e9}}),k.ZP.success("Retry settings saved successfully")}catch(e){console.error("Failed to save retry settings:",e),k.ZP.error("Failed to save retry settings")}};if((0,r.useEffect)(()=>{if(!o||!d||!c||!m)return;let e=async()=>{try{var e,l,s,t,n,a,r,i,d,h,x,p;let j=await (0,u.hy)(o);X(j);let g=await (0,u.AZ)(o,m,c);console.log("Model data response:",g.data),Z(g);let f=new Set;for(let e=0;e0&&(y=_[_.length-1],console.log("_initial_model_group:",y),eV(y)),console.log("selectedModelGroup:",eU);let b=await (0,u.o6)(o,m,c,y,null===(e=e3.from)||void 0===e?void 0:e.toISOString(),null===(l=e3.to)||void 0===l?void 0:l.toISOString(),null==lo?void 0:lo.token,lc);console.log("Model metrics response:",b),eK(b.data),eH(b.all_api_bases);let v=await (0,u.Rg)(o,y,null===(s=e3.from)||void 0===s?void 0:s.toISOString(),null===(t=e3.to)||void 0===t?void 0:t.toISOString());eY(v.data),eX(v.all_api_bases);let S=await (0,u.N8)(o,m,c,y,null===(n=e3.from)||void 0===n?void 0:n.toISOString(),null===(a=e3.to)||void 0===a?void 0:a.toISOString(),null==lo?void 0:lo.token,lc);console.log("Model exceptions response:",S),eQ(S.data),e1(S.exception_types);let k=await (0,u.fP)(o,m,c,y,null===(r=e3.from)||void 0===r?void 0:r.toISOString(),null===(i=e3.to)||void 0===i?void 0:i.toISOString(),null==lo?void 0:lo.token,lc),w=await (0,u.n$)(o,null===(d=e3.from)||void 0===d?void 0:d.toISOString().split("T")[0],null===(h=e3.to)||void 0===h?void 0:h.toISOString().split("T")[0],y);lt(w);let N=await (0,u.v9)(o,null===(x=e3.from)||void 0===x?void 0:x.toISOString().split("T")[0],null===(p=e3.to)||void 0===p?void 0:p.toISOString().split("T")[0],y);la(N),console.log("dailyExceptions:",w),console.log("dailyExceptionsPerDeplyment:",N),console.log("slowResponses:",k),e8(k);let A=await (0,u.j2)(o);lh(null==A?void 0:A.end_users);let I=(await (0,u.BL)(o,m,c)).router_settings;console.log("routerSettingsInfo:",I);let C=I.model_group_retry_policy,P=I.num_retries;console.log("model_group_retry_policy:",C),console.log("default_retries:",P),e7(C),ll(P)}catch(e){console.error("There was an error fetching the model data",e)}};o&&d&&c&&m&&e();let l=async()=>{let e=await (0,u.qm)();console.log("received model cost map data: ".concat(Object.keys(e))),P(e)};null==C&&l(),lg()},[o,d,c,m,C,E]),!h||!o||!d||!c||!m)return(0,a.jsx)("div",{children:"Loading..."});let lf=[];for(let e=0;e(console.log("GET PROVIDER CALLED! - ".concat(C)),null!=C&&"object"==typeof C&&e in C)?C[e].litellm_provider:"openai";if(n){let e=n.split("/"),l=e[0];r=1===e.length?u(n):l}else r="openai";a&&(i=null==a?void 0:a.input_cost_per_token,o=null==a?void 0:a.output_cost_per_token,d=null==a?void 0:a.max_tokens,c=null==a?void 0:a.max_input_tokens),(null==t?void 0:t.litellm_params)&&(m=Object.fromEntries(Object.entries(null==t?void 0:t.litellm_params).filter(e=>{let[l]=e;return"model"!==l&&"api_base"!==l}))),h.data[e].provider=r,h.data[e].input_cost=i,h.data[e].output_cost=o,h.data[e].input_cost&&(h.data[e].input_cost=(1e6*Number(h.data[e].input_cost)).toFixed(2)),h.data[e].output_cost&&(h.data[e].output_cost=(1e6*Number(h.data[e].output_cost)).toFixed(2)),h.data[e].max_tokens=d,h.data[e].max_input_tokens=c,h.data[e].api_base=null==t?void 0:null===(s=t.litellm_params)||void 0===s?void 0:s.api_base,h.data[e].cleanedLitellmParams=m,lf.push(t.model_name),console.log(h.data[e])}if(c&&"Admin Viewer"==c){let{Title:e,Paragraph:l}=$.default;return(0,a.jsxs)("div",{children:[(0,a.jsx)(e,{level:1,children:"Access Denied"}),(0,a.jsx)(l,{children:"Ask your proxy admin for access to view all models"})]})}let l_=e=>{console.log("received provider string: ".concat(e));let l=Object.keys(n).find(l=>n[l]===e);if(l){let e=eA[l];console.log("mappingResult: ".concat(e));let s=[];"object"==typeof C&&Object.entries(C).forEach(l=>{let[t,n]=l;null!==n&&"object"==typeof n&&"litellm_provider"in n&&(n.litellm_provider===e||n.litellm_provider.includes(e))&&s.push(t)}),G(s),console.log("providerModels: ".concat(H))}},ly=async()=>{try{k.ZP.info("Running health check..."),eP("");let e=await (0,u.EY)(o);eP(e)}catch(e){console.error("Error running health check:",e),eP("Error running health check")}},lb=async(e,l,s)=>{if(console.log("Updating model metrics for group:",e),!o||!m||!c||!l||!s)return;console.log("inside updateModelMetrics - startTime:",l,"endTime:",s),eV(e);let t=null==lo?void 0:lo.token;void 0===t&&(t=null);let n=lc;void 0===n&&(n=null),l.setHours(0),l.setMinutes(0),l.setSeconds(0),s.setHours(23),s.setMinutes(59),s.setSeconds(59);try{let a=await (0,u.o6)(o,m,c,e,l.toISOString(),s.toISOString(),t,n);console.log("Model metrics response:",a),eK(a.data),eH(a.all_api_bases);let r=await (0,u.Rg)(o,e,l.toISOString(),s.toISOString());eY(r.data),eX(r.all_api_bases);let i=await (0,u.N8)(o,m,c,e,l.toISOString(),s.toISOString(),t,n);console.log("Model exceptions response:",i),eQ(i.data),e1(i.exception_types);let d=await (0,u.fP)(o,m,c,e,l.toISOString(),s.toISOString(),t,n);if(console.log("slowResponses:",d),e8(d),e){let t=await (0,u.n$)(o,null==l?void 0:l.toISOString().split("T")[0],null==s?void 0:s.toISOString().split("T")[0],e);lt(t);let n=await (0,u.v9)(o,null==l?void 0:l.toISOString().split("T")[0],null==s?void 0:s.toISOString().split("T")[0],e);la(n)}}catch(e){console.error("Failed to fetch model metrics",e)}},lv=(0,a.jsxs)("div",{children:[(0,a.jsx)(_.Z,{className:"mb-1",children:"Select API Key Name"}),f?(0,a.jsxs)("div",{children:[(0,a.jsxs)(B.Z,{defaultValue:"all-keys",children:[(0,a.jsx)(K.Z,{value:"all-keys",onClick:()=>{ld(null)},children:"All Keys"},"all-keys"),null==g?void 0:g.map((e,l)=>e&&null!==e.key_alias&&e.key_alias.length>0?(0,a.jsx)(K.Z,{value:String(l),onClick:()=>{ld(e)},children:e.key_alias},l):null)]}),(0,a.jsx)(_.Z,{className:"mt-1",children:"Select Customer Name"}),(0,a.jsxs)(B.Z,{defaultValue:"all-customers",children:[(0,a.jsx)(K.Z,{value:"all-customers",onClick:()=>{lm(null)},children:"All Customers"},"all-customers"),null==lu?void 0:lu.map((e,l)=>(0,a.jsx)(K.Z,{value:e,onClick:()=>{lm(e)},children:e},l))]})]}):(0,a.jsxs)("div",{children:[(0,a.jsxs)(B.Z,{defaultValue:"all-keys",children:[(0,a.jsx)(K.Z,{value:"all-keys",onClick:()=>{ld(null)},children:"All Keys"},"all-keys"),null==g?void 0:g.map((e,l)=>e&&null!==e.key_alias&&e.key_alias.length>0?(0,a.jsxs)(K.Z,{value:String(l),disabled:!0,onClick:()=>{ld(e)},children:["✨ ",e.key_alias," (Enterprise only Feature)"]},l):null)]}),(0,a.jsx)(_.Z,{className:"mt-1",children:"Select Customer Name"}),(0,a.jsxs)(B.Z,{defaultValue:"all-customers",children:[(0,a.jsx)(K.Z,{value:"all-customers",onClick:()=>{lm(null)},children:"All Customers"},"all-customers"),null==lu?void 0:lu.map((e,l)=>(0,a.jsxs)(K.Z,{value:e,disabled:!0,onClick:()=>{lm(e)},children:["✨ ",e," (Enterprise only Feature)"]},l))]})]})]}),lS=e=>{var l,s;let{payload:t,active:n}=e;if(!n||!t)return null;let r=null===(s=t[0])||void 0===s?void 0:null===(l=s.payload)||void 0===l?void 0:l.date,i=t.sort((e,l)=>l.value-e.value);if(i.length>5){let e=i.length-5;(i=i.slice(0,5)).push({dataKey:"".concat(e," other deployments"),value:t.slice(5).reduce((e,l)=>e+l.value,0),color:"gray"})}return(0,a.jsxs)("div",{className:"w-150 rounded-tremor-default border border-tremor-border bg-tremor-background p-2 text-tremor-default shadow-tremor-dropdown",children:[r&&(0,a.jsxs)("p",{className:"text-tremor-content-emphasis mb-2",children:["Date: ",r]}),i.map((e,l)=>{let s=parseFloat(e.value.toFixed(5)),t=0===s&&e.value>0?"<0.00001":s.toFixed(5);return(0,a.jsxs)("div",{className:"flex justify-between",children:[(0,a.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,a.jsx)("div",{className:"w-2 h-2 mt-1 rounded-full bg-".concat(e.color,"-500")}),(0,a.jsx)("p",{className:"text-tremor-content",children:e.dataKey})]}),(0,a.jsx)("p",{className:"font-medium text-tremor-content-emphasis text-righ ml-2",children:t})]},l)})]})};console.log("selectedProvider: ".concat(Q)),console.log("providerModels.length: ".concat(H.length));let lk=Object.keys(n).find(e=>n[e]===Q);return lk&&(i=J.find(e=>e.name===eA[lk])),(0,a.jsx)("div",{style:{width:"100%",height:"100%"},children:(0,a.jsxs)(et.Z,{className:"gap-2 p-8 h-[75vh] w-full mt-2",children:[(0,a.jsxs)(en.Z,{className:"flex justify-between mt-2 w-full items-center",children:[(0,a.jsxs)("div",{className:"flex",children:[(0,a.jsx)(es.Z,{children:"All Models"}),(0,a.jsx)(es.Z,{children:"Add Model"}),(0,a.jsx)(es.Z,{children:(0,a.jsx)("pre",{children:"/health Models"})}),(0,a.jsx)(es.Z,{children:"Model Analytics"}),(0,a.jsx)(es.Z,{children:"Model Retry Settings"})]}),(0,a.jsxs)("div",{className:"flex items-center space-x-2",children:[E&&(0,a.jsxs)(_.Z,{children:["Last Refreshed: ",E]}),(0,a.jsx)(F.Z,{icon:ej.Z,variant:"shadow",size:"xs",className:"self-center",onClick:lg})]})]}),(0,a.jsxs)(er.Z,{children:[(0,a.jsxs)(ea.Z,{children:[(0,a.jsxs)(x.Z,{children:[(0,a.jsxs)("div",{className:"flex items-center",children:[(0,a.jsx)(_.Z,{children:"Filter by Public Model Name"}),(0,a.jsxs)(B.Z,{className:"mb-4 mt-2 ml-2 w-50",defaultValue:eU||eD[0],onValueChange:e=>eV("all"===e?"all":e),value:eU||eD[0],children:[(0,a.jsx)(K.Z,{value:"all",children:"All Models"}),eD.map((e,l)=>(0,a.jsx)(K.Z,{value:e,onClick:()=>eV(e),children:e},l))]})]}),(0,a.jsx)(M.Z,{children:(0,a.jsxs)(D.Z,{style:{maxWidth:"1500px",width:"100%"},children:[(0,a.jsx)(V.Z,{children:(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(z.Z,{style:{maxWidth:"150px",whiteSpace:"normal",wordBreak:"break-word",fontSize:"11px"},children:"Public Model Name"}),(0,a.jsx)(z.Z,{style:{maxWidth:"100px",whiteSpace:"normal",wordBreak:"break-word",fontSize:"11px"},children:"Provider"}),"Admin"===c&&(0,a.jsx)(z.Z,{style:{maxWidth:"150px",whiteSpace:"normal",wordBreak:"break-word",fontSize:"11px"},children:"API Base"}),(0,a.jsxs)(z.Z,{style:{maxWidth:"85px",whiteSpace:"normal",wordBreak:"break-word",fontSize:"11px"},children:["Input Price"," ",(0,a.jsx)("p",{style:{fontSize:"10px",color:"gray"},children:"/1M Tokens ($)"})]}),(0,a.jsxs)(z.Z,{style:{maxWidth:"85px",whiteSpace:"normal",wordBreak:"break-word",fontSize:"11px"},children:["Output Price"," ",(0,a.jsx)("p",{style:{fontSize:"10px",color:"gray"},children:"/1M Tokens ($)"})]}),(0,a.jsx)(z.Z,{style:{maxWidth:"100px",whiteSpace:"normal",wordBreak:"break-word",fontSize:"11px"},children:f?"Created At":(0,a.jsxs)("a",{href:"https://forms.gle/W3U4PZpJGFHWtHyA9",target:"_blank",style:{color:"#72bcd4"},children:[" ","✨ Created At"]})}),(0,a.jsx)(z.Z,{style:{maxWidth:"100px",whiteSpace:"normal",wordBreak:"break-word",fontSize:"11px"},children:f?"Created By":(0,a.jsxs)("a",{href:"https://forms.gle/W3U4PZpJGFHWtHyA9",target:"_blank",style:{color:"#72bcd4"},children:[" ","✨ Created By"]})}),(0,a.jsx)(z.Z,{style:{maxWidth:"50px",whiteSpace:"normal",wordBreak:"break-word",fontSize:"11px"},children:"Status"}),(0,a.jsx)(z.Z,{})]})}),(0,a.jsx)(L.Z,{children:h.data.filter(e=>"all"===eU||e.model_name===eU||null==eU||""===eU).map((e,l)=>{var s;return(0,a.jsxs)(q.Z,{style:{maxHeight:"1px",minHeight:"1px"},children:[(0,a.jsx)(U.Z,{style:{maxWidth:"100px",whiteSpace:"normal",wordBreak:"break-word"},children:(0,a.jsx)("p",{className:"text-xs",children:e.model_name||"-"})}),(0,a.jsx)(U.Z,{style:{maxWidth:"100px",whiteSpace:"normal",wordBreak:"break-word"},children:(0,a.jsx)("p",{className:"text-xs",children:e.provider||"-"})}),"Admin"===c&&(0,a.jsx)(U.Z,{style:{maxWidth:"150px",whiteSpace:"normal",wordBreak:"break-word"},children:(0,a.jsx)(em.Z,{title:e&&e.api_base,children:(0,a.jsx)("pre",{style:{maxWidth:"150px",whiteSpace:"normal",wordBreak:"break-word"},className:"text-xs",title:e&&e.api_base?e.api_base:"",children:e&&e.api_base?e.api_base.slice(0,20):"-"})})}),(0,a.jsx)(U.Z,{style:{maxWidth:"80px",whiteSpace:"normal",wordBreak:"break-word"},children:(0,a.jsx)("pre",{className:"text-xs",children:e.input_cost?e.input_cost:null!=e.litellm_params.input_cost_per_token&&void 0!=e.litellm_params.input_cost_per_token?(1e6*Number(e.litellm_params.input_cost_per_token)).toFixed(2):null})}),(0,a.jsx)(U.Z,{style:{maxWidth:"80px",whiteSpace:"normal",wordBreak:"break-word"},children:(0,a.jsx)("pre",{className:"text-xs",children:e.output_cost?e.output_cost:e.litellm_params.output_cost_per_token?(1e6*Number(e.litellm_params.output_cost_per_token)).toFixed(2):null})}),(0,a.jsx)(U.Z,{children:(0,a.jsx)("p",{className:"text-xs",children:f&&((s=e.model_info.created_at)?new Date(s).toLocaleDateString("en-US"):null)||"-"})}),(0,a.jsx)(U.Z,{children:(0,a.jsx)("p",{className:"text-xs",children:f&&e.model_info.created_by||"-"})}),(0,a.jsx)(U.Z,{style:{maxWidth:"100px",whiteSpace:"normal",wordBreak:"break-word"},children:e.model_info.db_model?(0,a.jsx)(R.Z,{size:"xs",className:"text-white",children:(0,a.jsx)("p",{className:"text-xs",children:"DB Model"})}):(0,a.jsx)(R.Z,{size:"xs",className:"text-black",children:(0,a.jsx)("p",{className:"text-xs",children:"Config Model"})})}),(0,a.jsx)(U.Z,{style:{maxWidth:"150px",whiteSpace:"normal",wordBreak:"break-word"},children:(0,a.jsxs)(x.Z,{numItems:3,children:[(0,a.jsx)(eu.Z,{children:(0,a.jsx)(F.Z,{icon:T.Z,size:"sm",onClick:()=>lp(e)})}),(0,a.jsx)(eu.Z,{children:(0,a.jsx)(F.Z,{icon:O.Z,size:"sm",onClick:()=>lx(e)})}),(0,a.jsx)(eu.Z,{children:(0,a.jsx)(eZ,{modelID:e.model_info.id,accessToken:o})})]})})]},l)})})]})})]}),(0,a.jsx)(e=>{let{visible:l,onCancel:s,model:t,onSubmit:n}=e,[r]=S.Z.useForm(),i={},o="",d="";if(t){i=t.litellm_params,o=t.model_name;let e=t.model_info;e&&(d=e.id,console.log("model_id: ".concat(d)),i.model_id=d)}return(0,a.jsx)(w.Z,{title:"Edit Model "+o,visible:l,width:800,footer:null,onOk:()=>{r.validateFields().then(e=>{n(e),r.resetFields()}).catch(e=>{console.error("Validation failed:",e)})},onCancel:s,children:(0,a.jsxs)(S.Z,{form:r,onFinish:lj,initialValues:i,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(S.Z.Item,{className:"mt-8",label:"api_base",name:"api_base",children:(0,a.jsx)(j.Z,{})}),(0,a.jsx)(S.Z.Item,{label:"tpm",name:"tpm",tooltip:"int (optional) - Tokens limit for this deployment: in tokens per minute (tpm). Find this information on your model/providers website",children:(0,a.jsx)(A.Z,{min:0,step:1})}),(0,a.jsx)(S.Z.Item,{label:"rpm",name:"rpm",tooltip:"int (optional) - Rate limit for this deployment: in requests per minute (rpm). Find this information on your model/providers website",children:(0,a.jsx)(A.Z,{min:0,step:1})}),(0,a.jsx)(S.Z.Item,{label:"max_retries",name:"max_retries",children:(0,a.jsx)(A.Z,{min:0,step:1})}),(0,a.jsx)(S.Z.Item,{label:"timeout",name:"timeout",tooltip:"int (optional) - Timeout in seconds for LLM requests (Defaults to 600 seconds)",children:(0,a.jsx)(A.Z,{min:0,step:1})}),(0,a.jsx)(S.Z.Item,{label:"stream_timeout",name:"stream_timeout",tooltip:"int (optional) - Timeout for stream requests (seconds)",children:(0,a.jsx)(A.Z,{min:0,step:1})}),(0,a.jsx)(S.Z.Item,{label:"input_cost_per_token",name:"input_cost_per_token",tooltip:"float (optional) - Input cost per token",children:(0,a.jsx)(A.Z,{min:0,step:1e-4})}),(0,a.jsx)(S.Z.Item,{label:"output_cost_per_token",name:"output_cost_per_token",tooltip:"float (optional) - Output cost per token",children:(0,a.jsx)(A.Z,{min:0,step:1e-4})}),(0,a.jsx)(S.Z.Item,{label:"model_id",name:"model_id",hidden:!0})]}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(I.ZP,{htmlType:"submit",children:"Save"})})]})})},{visible:eT,onCancel:()=>{eO(!1),eF(null)},model:eM,onSubmit:lj}),(0,a.jsxs)(w.Z,{title:eM&&eM.model_name,visible:eE,width:800,footer:null,onCancel:()=>{eR(!1),eF(null)},children:[(0,a.jsx)(y.Z,{children:"Model Info"}),(0,a.jsx)(ek.Z,{language:"json",children:eM&&JSON.stringify(eM,null,2)})]})]}),(0,a.jsxs)(ea.Z,{className:"h-full",children:[(0,a.jsx)(ew,{level:2,children:"Add new model"}),(0,a.jsx)(M.Z,{children:(0,a.jsxs)(S.Z,{form:N,onFinish:()=>{N.validateFields().then(e=>{eC(e,o,N)}).catch(e=>{console.error("Validation failed:",e)})},labelCol:{span:10},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(S.Z.Item,{rules:[{required:!0,message:"Required"}],label:"Provider:",name:"custom_llm_provider",tooltip:"E.g. OpenAI, Azure OpenAI, Anthropic, Bedrock, etc.",labelCol:{span:10},labelAlign:"left",children:(0,a.jsx)(B.Z,{value:Q.toString(),children:Y.map((e,l)=>(0,a.jsx)(K.Z,{value:e,onClick:()=>{l_(e),ey(e)},children:e},l))})}),(0,a.jsx)(S.Z.Item,{rules:[{required:!0,message:"Required"}],label:"Public Model Name",name:"model_name",tooltip:"Model name your users will pass in. Also used for load-balancing, LiteLLM will load balance between all models with this public name.",className:"mb-0",children:(0,a.jsx)(j.Z,{placeholder:"Vertex AI (Anthropic, Gemini, etc.)"===(t=Q.toString())?"gemini-pro":"Anthropic"==t||"Amazon Bedrock"==t?"claude-3-opus":"Google AI Studio"==t?"gemini-pro":"Azure AI Studio"==t?"azure_ai/command-r-plus":"Azure"==t?"azure/my-deployment":"gpt-3.5-turbo"})}),(0,a.jsxs)(eh.Z,{children:[(0,a.jsx)(eu.Z,{span:10}),(0,a.jsx)(eu.Z,{span:10,children:(0,a.jsx)(_.Z,{className:"mb-3 mt-1",children:"Model name your users will pass in."})})]}),(0,a.jsx)(S.Z.Item,{rules:[{required:!0,message:"Required"}],label:"LiteLLM Model Name(s)",name:"model",tooltip:"Actual model name used for making litellm.completion() call.",className:"mb-0",children:"Azure"===Q?(0,a.jsx)(j.Z,{placeholder:"Enter model name"}):H.length>0?(0,a.jsx)(ei.Z,{value:H,children:H.map((e,l)=>(0,a.jsx)(eo.Z,{value:e,children:e},l))}):(0,a.jsx)(j.Z,{placeholder:"gpt-3.5-turbo-0125"})}),(0,a.jsxs)(eh.Z,{children:[(0,a.jsx)(eu.Z,{span:10}),(0,a.jsx)(eu.Z,{span:10,children:(0,a.jsxs)(_.Z,{className:"mb-3 mt-1",children:["Actual model name used for making"," ",(0,a.jsx)(eN,{href:"https://docs.litellm.ai/docs/providers",target:"_blank",children:"litellm.completion() call"}),". We'll"," ",(0,a.jsx)(eN,{href:"https://docs.litellm.ai/docs/proxy/reliability#step-1---set-deployments-on-config",target:"_blank",children:"loadbalance"})," ","models with the same 'public name'"]})})]}),void 0!==i&&i.fields.length>0&&(0,a.jsx)(eS,{fields:i.fields,selectedProvider:i.name}),"Amazon Bedrock"!=Q&&"Vertex AI (Anthropic, Gemini, etc.)"!=Q&&"Ollama"!=Q&&(void 0===i||0==i.fields.length)&&(0,a.jsx)(S.Z.Item,{rules:[{required:!0,message:"Required"}],label:"API Key",name:"api_key",children:(0,a.jsx)(j.Z,{placeholder:"sk-",type:"password"})}),"OpenAI"==Q&&(0,a.jsx)(S.Z.Item,{label:"Organization ID",name:"organization_id",children:(0,a.jsx)(j.Z,{placeholder:"[OPTIONAL] my-unique-org"})}),"Vertex AI (Anthropic, Gemini, etc.)"==Q&&(0,a.jsx)(S.Z.Item,{rules:[{required:!0,message:"Required"}],label:"Vertex Project",name:"vertex_project",children:(0,a.jsx)(j.Z,{placeholder:"adroit-cadet-1234.."})}),"Vertex AI (Anthropic, Gemini, etc.)"==Q&&(0,a.jsx)(S.Z.Item,{rules:[{required:!0,message:"Required"}],label:"Vertex Location",name:"vertex_location",children:(0,a.jsx)(j.Z,{placeholder:"us-east-1"})}),"Vertex AI (Anthropic, Gemini, etc.)"==Q&&(0,a.jsx)(S.Z.Item,{rules:[{required:!0,message:"Required"}],label:"Vertex Credentials",name:"vertex_credentials",className:"mb-0",children:(0,a.jsx)(e_.Z,{name:"file",accept:".json",beforeUpload:e=>{if("application/json"===e.type){let l=new FileReader;l.onload=e=>{if(e.target){let l=e.target.result;N.setFieldsValue({vertex_credentials:l})}},l.readAsText(e)}return!1},onChange(e){"uploading"!==e.file.status&&console.log(e.file,e.fileList),"done"===e.file.status?k.ZP.success("".concat(e.file.name," file uploaded successfully")):"error"===e.file.status&&k.ZP.error("".concat(e.file.name," file upload failed."))},children:(0,a.jsx)(I.ZP,{icon:(0,a.jsx)(ef.Z,{}),children:"Click to Upload"})})}),"Vertex AI (Anthropic, Gemini, etc.)"==Q&&(0,a.jsxs)(eh.Z,{children:[(0,a.jsx)(eu.Z,{span:10}),(0,a.jsx)(eu.Z,{span:10,children:(0,a.jsx)(_.Z,{className:"mb-3 mt-1",children:"Give litellm a gcp service account(.json file), so it can make the relevant calls"})})]}),("Azure"==Q||"OpenAI-Compatible Endpoints (Groq, Together AI, Mistral AI, etc.)"==Q)&&(0,a.jsx)(S.Z.Item,{rules:[{required:!0,message:"Required"}],label:"API Base",name:"api_base",children:(0,a.jsx)(j.Z,{placeholder:"https://..."})}),"Azure"==Q&&(0,a.jsx)(S.Z.Item,{rules:[{required:!0,message:"Required"}],label:"API Version",name:"api_version",children:(0,a.jsx)(j.Z,{placeholder:"2023-07-01-preview"})}),"Azure"==Q&&(0,a.jsxs)("div",{children:[(0,a.jsx)(S.Z.Item,{label:"Base Model",name:"base_model",className:"mb-0",children:(0,a.jsx)(j.Z,{placeholder:"azure/gpt-3.5-turbo"})}),(0,a.jsxs)(eh.Z,{children:[(0,a.jsx)(eu.Z,{span:10}),(0,a.jsx)(eu.Z,{span:10,children:(0,a.jsxs)(_.Z,{className:"mb-2",children:["The actual model your azure deployment uses. Used for accurate cost tracking. Select name from"," ",(0,a.jsx)(eN,{href:"https://github.com/BerriAI/litellm/blob/main/model_prices_and_context_window.json",target:"_blank",children:"here"})]})})]})]}),"Amazon Bedrock"==Q&&(0,a.jsx)(S.Z.Item,{rules:[{required:!0,message:"Required"}],label:"AWS Access Key ID",name:"aws_access_key_id",tooltip:"You can provide the raw key or the environment variable (e.g. `os.environ/MY_SECRET_KEY`).",children:(0,a.jsx)(j.Z,{placeholder:""})}),"Amazon Bedrock"==Q&&(0,a.jsx)(S.Z.Item,{rules:[{required:!0,message:"Required"}],label:"AWS Secret Access Key",name:"aws_secret_access_key",tooltip:"You can provide the raw key or the environment variable (e.g. `os.environ/MY_SECRET_KEY`).",children:(0,a.jsx)(j.Z,{placeholder:""})}),"Amazon Bedrock"==Q&&(0,a.jsx)(S.Z.Item,{rules:[{required:!0,message:"Required"}],label:"AWS Region Name",name:"aws_region_name",tooltip:"You can provide the raw key or the environment variable (e.g. `os.environ/MY_SECRET_KEY`).",children:(0,a.jsx)(j.Z,{placeholder:"us-east-1"})}),(0,a.jsx)(S.Z.Item,{label:"LiteLLM Params",name:"litellm_extra_params",tooltip:"Optional litellm params used for making a litellm.completion() call.",className:"mb-0",children:(0,a.jsx)(ep.Z,{rows:4,placeholder:'{ "rpm": 100, "timeout": 0, "stream_timeout": 0 }'})}),(0,a.jsxs)(eh.Z,{children:[(0,a.jsx)(eu.Z,{span:10}),(0,a.jsx)(eu.Z,{span:10,children:(0,a.jsxs)(_.Z,{className:"mb-3 mt-1",children:["Pass JSON of litellm supported params"," ",(0,a.jsx)(eN,{href:"https://docs.litellm.ai/docs/completion/input",target:"_blank",children:"litellm.completion() call"})]})})]})]}),(0,a.jsx)("div",{style:{textAlign:"center",marginTop:"10px"},children:(0,a.jsx)(I.ZP,{htmlType:"submit",children:"Add Model"})}),(0,a.jsx)(em.Z,{title:"Get help on our github",children:(0,a.jsx)($.default.Link,{href:"https://github.com/BerriAI/litellm/issues",children:"Need Help?"})})]})})]}),(0,a.jsx)(ea.Z,{children:(0,a.jsxs)(M.Z,{children:[(0,a.jsx)(_.Z,{children:"`/health` will run a very small request through your models configured on litellm"}),(0,a.jsx)(p.Z,{onClick:ly,children:"Run `/health`"}),eb&&(0,a.jsx)("pre",{children:JSON.stringify(eb,null,2)})]})}),(0,a.jsxs)(ea.Z,{children:[(0,a.jsxs)(x.Z,{numItems:4,className:"mt-2 mb-2",children:[(0,a.jsxs)(eu.Z,{children:[(0,a.jsx)(_.Z,{children:"Select Time Range"}),(0,a.jsx)(el.Z,{enableSelect:!0,value:e3,className:"mr-2",onValueChange:e=>{e6(e),lb(eU,e.from,e.to)}})]}),(0,a.jsxs)(eu.Z,{className:"ml-2",children:[(0,a.jsx)(_.Z,{children:"Select Model Group"}),(0,a.jsx)(B.Z,{defaultValue:eU||eD[0],value:eU||eD[0],children:eD.map((e,l)=>(0,a.jsx)(K.Z,{value:e,onClick:()=>lb(e,e3.from,e3.to),children:e},l))})]}),(0,a.jsx)(eu.Z,{children:(0,a.jsx)(ex.Z,{trigger:"click",content:lv,overlayStyle:{width:"20vw"},children:(0,a.jsx)(p.Z,{icon:eg.Z,size:"md",variant:"secondary",className:"mt-4 ml-2",style:{border:"none"},onClick:()=>li(!0)})})})]}),(0,a.jsxs)(x.Z,{numItems:2,children:[(0,a.jsx)(eu.Z,{children:(0,a.jsx)(M.Z,{className:"mr-2 max-h-[400px] min-h-[400px]",children:(0,a.jsxs)(et.Z,{children:[(0,a.jsxs)(en.Z,{variant:"line",defaultValue:"1",children:[(0,a.jsx)(es.Z,{value:"1",children:"Avg. Latency per Token"}),(0,a.jsx)(es.Z,{value:"2",children:"✨ Time to first token"})]}),(0,a.jsxs)(er.Z,{children:[(0,a.jsxs)(ea.Z,{children:[(0,a.jsx)("p",{className:"text-gray-500 italic",children:" (seconds/token)"}),(0,a.jsx)(_.Z,{className:"text-gray-500 italic mt-1 mb-1",children:"average Latency for successfull requests divided by the total tokens"}),eB&&eW&&(0,a.jsx)(ed.Z,{title:"Model Latency",className:"h-72",data:eB,showLegend:!1,index:"date",categories:eW,connectNulls:!0,customTooltip:lS})]}),(0,a.jsx)(ea.Z,{children:(0,a.jsx)(ev,{modelMetrics:eG,modelMetricsCategories:eJ,customTooltip:lS,premiumUser:f})})]})]})})}),(0,a.jsx)(eu.Z,{children:(0,a.jsx)(M.Z,{className:"ml-2 max-h-[400px] min-h-[400px] overflow-y-auto",children:(0,a.jsxs)(D.Z,{children:[(0,a.jsx)(V.Z,{children:(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(z.Z,{children:"Deployment"}),(0,a.jsx)(z.Z,{children:"Success Responses"}),(0,a.jsxs)(z.Z,{children:["Slow Responses ",(0,a.jsx)("p",{children:"Success Responses taking 600+s"})]})]})}),(0,a.jsx)(L.Z,{children:e5.map((e,l)=>(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(U.Z,{children:e.api_base}),(0,a.jsx)(U.Z,{children:e.total_count}),(0,a.jsx)(U.Z,{children:e.slow_count})]},l))})]})})})]}),(0,a.jsx)(x.Z,{numItems:1,className:"gap-2 w-full mt-2",children:(0,a.jsxs)(M.Z,{children:[(0,a.jsxs)(y.Z,{children:["All Exceptions for ",eU]}),(0,a.jsx)(ec.Z,{className:"h-60",data:e$,index:"model",categories:e0,stack:!0,yAxisWidth:30})]})}),(0,a.jsxs)(x.Z,{numItems:1,className:"gap-2 w-full mt-2",children:[(0,a.jsxs)(M.Z,{children:[(0,a.jsxs)(y.Z,{children:["All Up Rate Limit Errors (429) for ",eU]}),(0,a.jsxs)(x.Z,{numItems:1,children:[(0,a.jsxs)(eu.Z,{children:[(0,a.jsxs)(ee.Z,{style:{fontSize:"15px",fontWeight:"normal",color:"#535452"},children:["Num Rate Limit Errors ",ls.sum_num_rate_limit_exceptions]}),(0,a.jsx)(ec.Z,{className:"h-40",data:ls.daily_data,index:"date",colors:["rose"],categories:["num_rate_limit_exceptions"],onValueChange:e=>console.log(e)})]}),(0,a.jsx)(eu.Z,{})]})]}),f?(0,a.jsx)(a.Fragment,{children:ln.map((e,l)=>(0,a.jsxs)(M.Z,{children:[(0,a.jsx)(y.Z,{children:e.api_base?e.api_base:"Unknown API Base"}),(0,a.jsx)(x.Z,{numItems:1,children:(0,a.jsxs)(eu.Z,{children:[(0,a.jsxs)(ee.Z,{style:{fontSize:"15px",fontWeight:"normal",color:"#535452"},children:["Num Rate Limit Errors (429) ",e.sum_num_rate_limit_exceptions]}),(0,a.jsx)(ec.Z,{className:"h-40",data:e.daily_data,index:"date",colors:["rose"],categories:["num_rate_limit_exceptions"],onValueChange:e=>console.log(e)})]})})]},l))}):(0,a.jsx)(a.Fragment,{children:ln&&ln.length>0&&ln.slice(0,1).map((e,l)=>(0,a.jsxs)(M.Z,{children:[(0,a.jsx)(y.Z,{children:"✨ Rate Limit Errors by Deployment"}),(0,a.jsx)("p",{className:"mb-2 text-gray-500 italic text-[12px]",children:"Upgrade to see exceptions for all deployments"}),(0,a.jsx)(p.Z,{variant:"primary",className:"mb-2",children:(0,a.jsx)("a",{href:"https://forms.gle/W3U4PZpJGFHWtHyA9",target:"_blank",children:"Get Free Trial"})}),(0,a.jsxs)(M.Z,{children:[(0,a.jsx)(y.Z,{children:e.api_base}),(0,a.jsx)(x.Z,{numItems:1,children:(0,a.jsxs)(eu.Z,{children:[(0,a.jsxs)(ee.Z,{style:{fontSize:"15px",fontWeight:"normal",color:"#535452"},children:["Num Rate Limit Errors ",e.sum_num_rate_limit_exceptions]}),(0,a.jsx)(ec.Z,{className:"h-40",data:e.daily_data,index:"date",colors:["rose"],categories:["num_rate_limit_exceptions"],onValueChange:e=>console.log(e)})]})})]})]},l))})]})]}),(0,a.jsxs)(ea.Z,{children:[(0,a.jsxs)("div",{className:"flex items-center",children:[(0,a.jsx)(_.Z,{children:"Filter by Public Model Name"}),(0,a.jsx)(B.Z,{className:"mb-4 mt-2 ml-2 w-50",defaultValue:eU||eD[0],value:eU||eD[0],onValueChange:e=>eV(e),children:eD.map((e,l)=>(0,a.jsx)(K.Z,{value:e,onClick:()=>eV(e),children:e},l))})]}),(0,a.jsxs)(y.Z,{children:["Retry Policy for ",eU]}),(0,a.jsx)(_.Z,{className:"mb-6",children:"How many retries should be attempted based on the Exception"}),eI&&(0,a.jsx)("table",{children:(0,a.jsx)("tbody",{children:Object.entries(eI).map((e,l)=>{var s;let[t,n]=e,r=null==e9?void 0:null===(s=e9[eU])||void 0===s?void 0:s[n];return null==r&&(r=le),(0,a.jsxs)("tr",{className:"flex justify-between items-center mt-2",children:[(0,a.jsx)("td",{children:(0,a.jsx)(_.Z,{children:t})}),(0,a.jsx)("td",{children:(0,a.jsx)(A.Z,{className:"ml-5",value:r,min:0,step:1,onChange:e=>{e7(l=>{var s;let t=null!==(s=null==l?void 0:l[eU])&&void 0!==s?s:{};return{...null!=l?l:{},[eU]:{...t,[n]:e}}})}})})]},l)})})}),(0,a.jsx)(p.Z,{className:"mt-6 mr-8",onClick:lZ,children:"Save"})]})]})]})})},eT=e=>{let{isInvitationLinkModalVisible:l,setIsInvitationLinkModalVisible:s,baseUrl:t,invitationLinkData:n}=e,{Title:r,Paragraph:i}=$.default;return(0,a.jsxs)(w.Z,{title:"Invitation Link",visible:l,width:800,footer:null,onOk:()=>{s(!1)},onCancel:()=>{s(!1)},children:[(0,a.jsx)(i,{children:"Copy and send the generated link to onboard this user to the proxy."}),(0,a.jsxs)("div",{className:"flex justify-between pt-5 pb-2",children:[(0,a.jsx)(_.Z,{className:"text-base",children:"User ID"}),(0,a.jsx)(_.Z,{children:null==n?void 0:n.user_id})]}),(0,a.jsxs)("div",{className:"flex justify-between pt-5 pb-2",children:[(0,a.jsx)(_.Z,{children:"Invitation Link"}),(0,a.jsxs)(_.Z,{children:[t,"/ui/onboarding?id=",null==n?void 0:n.id]})]}),(0,a.jsxs)("div",{className:"flex justify-end mt-5",children:[(0,a.jsx)("div",{}),(0,a.jsx)(b.CopyToClipboard,{text:"".concat(t,"/ui/onboarding?id=").concat(null==n?void 0:n.id),onCopy:()=>k.ZP.success("Copied!"),children:(0,a.jsx)(p.Z,{variant:"primary",children:"Copy invitation link"})})]})]})};let{Option:eO}=v.default;var eE=e=>{let{userID:l,accessToken:s,teams:t,possibleUIRoles:n}=e,[o]=S.Z.useForm(),[d,c]=(0,r.useState)(!1),[m,h]=(0,r.useState)(null),[x,g]=(0,r.useState)([]),[Z,f]=(0,r.useState)(!1),[y,b]=(0,r.useState)(null),A=(0,i.useRouter)(),[C,P]=(0,r.useState)("");(0,r.useEffect)(()=>{(async()=>{try{let e=await (0,u.So)(s,l,"any"),t=[];for(let l=0;l{if(A){let{protocol:e,host:l}=window.location;P("".concat(e,"/").concat(l))}},[A]);let T=async e=>{try{var t;k.ZP.info("Making API Call"),c(!0),console.log("formValues in create user:",e);let n=await (0,u.Ov)(s,null,e);console.log("user create Response:",n),h(n.key);let a=(null===(t=n.data)||void 0===t?void 0:t.user_id)||n.user_id;(0,u.XO)(s,a).then(e=>{b(e),f(!0)}),k.ZP.success("API user Created"),o.resetFields(),localStorage.removeItem("userData"+l)}catch(e){console.error("Error creating the user:",e)}};return(0,a.jsxs)("div",{children:[(0,a.jsx)(p.Z,{className:"mx-auto mb-0",onClick:()=>c(!0),children:"+ Invite User"}),(0,a.jsxs)(w.Z,{title:"Invite User",visible:d,width:800,footer:null,onOk:()=>{c(!1),o.resetFields()},onCancel:()=>{c(!1),h(null),o.resetFields()},children:[(0,a.jsx)(_.Z,{className:"mb-1",children:"Create a User who can own keys"}),(0,a.jsxs)(S.Z,{form:o,onFinish:T,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsx)(S.Z.Item,{label:"User Email",name:"user_email",children:(0,a.jsx)(j.Z,{placeholder:""})}),(0,a.jsx)(S.Z.Item,{label:"User Role",name:"user_role",children:(0,a.jsx)(v.default,{children:n&&Object.entries(n).map(e=>{let[l,{ui_label:s,description:t}]=e;return(0,a.jsx)(K.Z,{value:l,title:s,children:(0,a.jsxs)("div",{className:"flex",children:[s," ",(0,a.jsx)("p",{className:"ml-2",style:{color:"gray",fontSize:"12px"},children:t})]})},l)})})}),(0,a.jsx)(S.Z.Item,{label:"Team ID",name:"team_id",children:(0,a.jsx)(v.default,{placeholder:"Select Team ID",style:{width:"100%"},children:t?t.map(e=>(0,a.jsx)(eO,{value:e.team_id,children:e.team_alias},e.team_id)):(0,a.jsx)(eO,{value:null,children:"Default Team"},"default")})}),(0,a.jsx)(S.Z.Item,{label:"Metadata",name:"metadata",children:(0,a.jsx)(N.Z.TextArea,{rows:4,placeholder:"Enter metadata as JSON"})}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(I.ZP,{htmlType:"submit",children:"Create User"})})]})]}),m&&(0,a.jsx)(eT,{isInvitationLinkModalVisible:Z,setIsInvitationLinkModalVisible:f,baseUrl:C,invitationLinkData:y})]})},eR=e=>{let{visible:l,possibleUIRoles:s,onCancel:t,user:n,onSubmit:i}=e,[o,d]=(0,r.useState)(n),[c]=S.Z.useForm();(0,r.useEffect)(()=>{c.resetFields()},[n]);let m=async()=>{c.resetFields(),t()},u=async e=>{i(e),c.resetFields(),t()};return n?(0,a.jsx)(w.Z,{visible:l,onCancel:m,footer:null,title:"Edit User "+n.user_id,width:1e3,children:(0,a.jsx)(S.Z,{form:c,onFinish:u,initialValues:n,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(S.Z.Item,{className:"mt-8",label:"User Email",tooltip:"Email of the User",name:"user_email",children:(0,a.jsx)(j.Z,{})}),(0,a.jsx)(S.Z.Item,{label:"user_id",name:"user_id",hidden:!0,children:(0,a.jsx)(j.Z,{})}),(0,a.jsx)(S.Z.Item,{label:"User Role",name:"user_role",children:(0,a.jsx)(v.default,{children:s&&Object.entries(s).map(e=>{let[l,{ui_label:s,description:t}]=e;return(0,a.jsx)(K.Z,{value:l,title:s,children:(0,a.jsxs)("div",{className:"flex",children:[s," ",(0,a.jsx)("p",{className:"ml-2",style:{color:"gray",fontSize:"12px"},children:t})]})},l)})})}),(0,a.jsx)(S.Z.Item,{label:"Spend (USD)",name:"spend",tooltip:"(float) - Spend of all LLM calls completed by this user",children:(0,a.jsx)(A.Z,{min:0,step:1})}),(0,a.jsx)(S.Z.Item,{label:"User Budget (USD)",name:"max_budget",tooltip:"(float) - Maximum budget of this user",children:(0,a.jsx)(A.Z,{min:0,step:1})}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(I.ZP,{htmlType:"submit",children:"Save"})})]})})}):null},eM=e=>{let{accessToken:l,token:s,keys:t,userRole:n,userID:i,teams:o,setKeys:d}=e,[c,m]=(0,r.useState)(null),[h,p]=(0,r.useState)(null),[j,g]=(0,r.useState)(0),[Z,f]=r.useState(null),[_,y]=(0,r.useState)(null),[b,v]=(0,r.useState)(!1),[S,w]=(0,r.useState)(null),[N,A]=(0,r.useState)({}),I=async()=>{w(null),v(!1)},C=async e=>{if(console.log("inside handleEditSubmit:",e),l&&s&&n&&i){try{await (0,u.pf)(l,e,null),k.ZP.success("User ".concat(e.user_id," updated successfully"))}catch(e){console.error("There was an error updating the user",e)}c&&m(c.map(l=>l.user_id===e.user_id?e:l)),w(null),v(!1)}};return((0,r.useEffect)(()=>{if(!l||!s||!n||!i)return;let e=async()=>{try{let e=await (0,u.Br)(l,null,n,!0,j,25);console.log("user data response:",e),m(e);let s=await (0,u.lg)(l);A(s)}catch(e){console.error("There was an error fetching the model data",e)}};l&&s&&n&&i&&e()},[l,s,n,i,j]),c&&l&&s&&n&&i)?(0,a.jsx)("div",{style:{width:"100%"},children:(0,a.jsxs)(x.Z,{className:"gap-2 p-2 h-[90vh] w-full mt-8",children:[(0,a.jsx)(eE,{userID:i,accessToken:l,teams:o,possibleUIRoles:N}),(0,a.jsxs)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[90vh] mb-4",children:[(0,a.jsx)("div",{className:"mb-4 mt-1"}),(0,a.jsx)(et.Z,{children:(0,a.jsxs)(er.Z,{children:[(0,a.jsx)(ea.Z,{children:(0,a.jsxs)(D.Z,{className:"mt-5",children:[(0,a.jsx)(V.Z,{children:(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(z.Z,{children:"User ID"}),(0,a.jsx)(z.Z,{children:"User Email"}),(0,a.jsx)(z.Z,{children:"Role"}),(0,a.jsx)(z.Z,{children:"User Spend ($ USD)"}),(0,a.jsx)(z.Z,{children:"User Max Budget ($ USD)"}),(0,a.jsx)(z.Z,{children:"API Keys"}),(0,a.jsx)(z.Z,{})]})}),(0,a.jsx)(L.Z,{children:c.map(e=>{var l,s;return(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(U.Z,{children:e.user_id||"-"}),(0,a.jsx)(U.Z,{children:e.user_email||"-"}),(0,a.jsx)(U.Z,{children:(null==N?void 0:null===(l=N[null==e?void 0:e.user_role])||void 0===l?void 0:l.ui_label)||"-"}),(0,a.jsx)(U.Z,{children:e.spend?null===(s=e.spend)||void 0===s?void 0:s.toFixed(2):"-"}),(0,a.jsx)(U.Z,{children:e.max_budget?e.max_budget:"Unlimited"}),(0,a.jsx)(U.Z,{children:(0,a.jsx)(x.Z,{numItems:2,children:e&&e.key_aliases&&e.key_aliases.filter(e=>null!==e).length>0?(0,a.jsxs)(R.Z,{size:"xs",color:"indigo",children:[e.key_aliases.filter(e=>null!==e).length,"\xa0Keys"]}):(0,a.jsx)(R.Z,{size:"xs",color:"gray",children:"No Keys"})})}),(0,a.jsx)(U.Z,{children:(0,a.jsx)(F.Z,{icon:O.Z,onClick:()=>{w(e),v(!0)},children:"View Keys"})})]},e.user_id)})})]})}),(0,a.jsx)(ea.Z,{children:(0,a.jsxs)("div",{className:"flex items-center",children:[(0,a.jsx)("div",{className:"flex-1"}),(0,a.jsx)("div",{className:"flex-1 flex justify-between items-center"})]})})]})}),(0,a.jsx)(eR,{visible:b,possibleUIRoles:N,onCancel:I,user:S,onSubmit:C})]}),function(){if(!c)return null;let e=Math.ceil(c.length/25);return(0,a.jsxs)("div",{className:"flex justify-between items-center",children:[(0,a.jsxs)("div",{children:["Showing Page ",j+1," of ",e]}),(0,a.jsxs)("div",{className:"flex",children:[(0,a.jsx)("button",{className:"bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-l focus:outline-none",disabled:0===j,onClick:()=>g(j-1),children:"← Prev"}),(0,a.jsx)("button",{className:"bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-r focus:outline-none",onClick:()=>{g(j+1)},children:"Next →"})]})]})}()]})}):(0,a.jsx)("div",{children:"Loading..."})},eF=e=>{let{teams:l,searchParams:s,accessToken:t,setTeams:n,userID:i,userRole:o}=e,[d]=S.Z.useForm(),[c]=S.Z.useForm(),{Title:m,Paragraph:g}=$.default,[Z,f]=(0,r.useState)(""),[y,b]=(0,r.useState)(!1),[C,P]=(0,r.useState)(l?l[0]:null),[T,W]=(0,r.useState)(!1),[H,G]=(0,r.useState)(!1),[Y,J]=(0,r.useState)([]),[X,Q]=(0,r.useState)(!1),[ee,el]=(0,r.useState)(null),[es,et]=(0,r.useState)({}),en=e=>{P(e),b(!0)},ea=async e=>{let s=e.team_id;if(console.log("handleEditSubmit:",e),null==t)return;let a=await (0,u.Gh)(t,e);l&&n(l.map(e=>e.team_id===s?a.data:e)),k.ZP.success("Team updated successfully"),b(!1),P(null)},er=async e=>{el(e),Q(!0)},ei=async()=>{if(null!=ee&&null!=l&&null!=t){try{await (0,u.rs)(t,ee);let e=l.filter(e=>e.team_id!==ee);n(e)}catch(e){console.error("Error deleting the team:",e)}Q(!1),el(null)}};(0,r.useEffect)(()=>{let e=async()=>{try{if(null===i||null===o||null===t||null===l)return;console.log("fetching team info:");let e={};for(let s=0;s<(null==l?void 0:l.length);s++){let n=l[s].team_id,a=await (0,u.Xm)(t,n);console.log("teamInfo response:",a),null!==a&&(e={...e,[n]:a})}et(e)}catch(e){console.error("Error fetching team info:",e)}};(async()=>{try{if(null===i||null===o)return;if(null!==t){let e=(await (0,u.So)(t,i,o)).data.map(e=>e.id);console.log("available_model_names:",e),J(e)}}catch(e){console.error("Error fetching user models:",e)}})(),e()},[t,i,o,l]);let eo=async e=>{try{if(null!=t){var s;let a=null==e?void 0:e.team_alias;if((null!==(s=null==l?void 0:l.map(e=>e.team_alias))&&void 0!==s?s:[]).includes(a))throw Error("Team alias ".concat(a," already exists, please pick another alias"));k.ZP.info("Creating Team");let r=await (0,u.hT)(t,e);null!==l?n([...l,r]):n([r]),console.log("response for team create call: ".concat(r)),k.ZP.success("Team created"),W(!1)}}catch(e){console.error("Error creating the team:",e),k.ZP.error("Error creating the team: "+e,20)}},ed=async e=>{try{if(null!=t&&null!=l){k.ZP.info("Adding Member");let s={role:"user",user_email:e.user_email,user_id:e.user_id},a=await (0,u.cu)(t,C.team_id,s);console.log("response for team create call: ".concat(a.data));let r=l.findIndex(e=>(console.log("team.team_id=".concat(e.team_id,"; response.data.team_id=").concat(a.data.team_id)),e.team_id===a.data.team_id));if(console.log("foundIndex: ".concat(r)),-1!==r){let e=[...l];e[r]=a.data,n(e),P(a.data)}G(!1)}}catch(e){console.error("Error creating the team:",e)}};return console.log("received teams ".concat(JSON.stringify(l))),(0,a.jsx)("div",{className:"w-full mx-4",children:(0,a.jsxs)(x.Z,{numItems:1,className:"gap-2 p-8 h-[75vh] w-full mt-2",children:[(0,a.jsxs)(h.Z,{numColSpan:1,children:[(0,a.jsx)(m,{level:4,children:"All Teams"}),(0,a.jsxs)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:[(0,a.jsxs)(D.Z,{children:[(0,a.jsx)(V.Z,{children:(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(z.Z,{children:"Team Name"}),(0,a.jsx)(z.Z,{children:"Spend (USD)"}),(0,a.jsx)(z.Z,{children:"Budget (USD)"}),(0,a.jsx)(z.Z,{children:"Models"}),(0,a.jsx)(z.Z,{children:"TPM / RPM Limits"}),(0,a.jsx)(z.Z,{children:"Info"})]})}),(0,a.jsx)(L.Z,{children:l&&l.length>0?l.map(e=>(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(U.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:e.team_alias}),(0,a.jsx)(U.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:e.spend}),(0,a.jsx)(U.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:null!==e.max_budget&&void 0!==e.max_budget?e.max_budget:"No limit"}),(0,a.jsx)(U.Z,{style:{maxWidth:"8-x",whiteSpace:"pre-wrap",overflow:"hidden"},children:Array.isArray(e.models)?(0,a.jsx)("div",{style:{display:"flex",flexDirection:"column"},children:0===e.models.length?(0,a.jsx)(R.Z,{size:"xs",className:"mb-1",color:"red",children:(0,a.jsx)(_.Z,{children:"All Proxy Models"})}):e.models.map((e,l)=>"all-proxy-models"===e?(0,a.jsx)(R.Z,{size:"xs",className:"mb-1",color:"red",children:(0,a.jsx)(_.Z,{children:"All Proxy Models"})},l):(0,a.jsx)(R.Z,{size:"xs",className:"mb-1",color:"blue",children:(0,a.jsx)(_.Z,{children:e.length>30?"".concat(e.slice(0,30),"..."):e})},l))}):null}),(0,a.jsx)(U.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,a.jsxs)(_.Z,{children:["TPM: ",e.tpm_limit?e.tpm_limit:"Unlimited"," ",(0,a.jsx)("br",{}),"RPM:"," ",e.rpm_limit?e.rpm_limit:"Unlimited"]})}),(0,a.jsxs)(U.Z,{children:[(0,a.jsxs)(_.Z,{children:[es&&e.team_id&&es[e.team_id]&&es[e.team_id].keys&&es[e.team_id].keys.length," ","Keys"]}),(0,a.jsxs)(_.Z,{children:[es&&e.team_id&&es[e.team_id]&&es[e.team_id].team_info&&es[e.team_id].team_info.members_with_roles&&es[e.team_id].team_info.members_with_roles.length," ","Members"]})]}),(0,a.jsxs)(U.Z,{children:[(0,a.jsx)(F.Z,{icon:O.Z,size:"sm",onClick:()=>en(e)}),(0,a.jsx)(F.Z,{onClick:()=>er(e.team_id),icon:E.Z,size:"sm"})]})]},e.team_id)):null})]}),X&&(0,a.jsx)("div",{className:"fixed z-10 inset-0 overflow-y-auto",children:(0,a.jsxs)("div",{className:"flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0",children:[(0,a.jsx)("div",{className:"fixed inset-0 transition-opacity","aria-hidden":"true",children:(0,a.jsx)("div",{className:"absolute inset-0 bg-gray-500 opacity-75"})}),(0,a.jsx)("span",{className:"hidden sm:inline-block sm:align-middle sm:h-screen","aria-hidden":"true",children:"​"}),(0,a.jsxs)("div",{className:"inline-block align-bottom bg-white rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full",children:[(0,a.jsx)("div",{className:"bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4",children:(0,a.jsx)("div",{className:"sm:flex sm:items-start",children:(0,a.jsxs)("div",{className:"mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left",children:[(0,a.jsx)("h3",{className:"text-lg leading-6 font-medium text-gray-900",children:"Delete Team"}),(0,a.jsx)("div",{className:"mt-2",children:(0,a.jsx)("p",{className:"text-sm text-gray-500",children:"Are you sure you want to delete this team ?"})})]})})}),(0,a.jsxs)("div",{className:"bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse",children:[(0,a.jsx)(p.Z,{onClick:ei,color:"red",className:"ml-2",children:"Delete"}),(0,a.jsx)(p.Z,{onClick:()=>{Q(!1),el(null)},children:"Cancel"})]})]})]})})]})]}),(0,a.jsxs)(h.Z,{numColSpan:1,children:[(0,a.jsx)(p.Z,{className:"mx-auto",onClick:()=>W(!0),children:"+ Create New Team"}),(0,a.jsx)(w.Z,{title:"Create Team",visible:T,width:800,footer:null,onOk:()=>{W(!1),d.resetFields()},onCancel:()=>{W(!1),d.resetFields()},children:(0,a.jsxs)(S.Z,{form:d,onFinish:eo,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(S.Z.Item,{label:"Team Name",name:"team_alias",rules:[{required:!0,message:"Please input a team name"}],children:(0,a.jsx)(j.Z,{placeholder:""})}),(0,a.jsx)(S.Z.Item,{label:"Models",name:"models",children:(0,a.jsxs)(v.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:[(0,a.jsx)(v.default.Option,{value:"all-proxy-models",children:"All Proxy Models"},"all-proxy-models"),Y.map(e=>(0,a.jsx)(v.default.Option,{value:e,children:e},e))]})}),(0,a.jsx)(S.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,a.jsx)(A.Z,{step:.01,precision:2,width:200})}),(0,a.jsx)(S.Z.Item,{className:"mt-8",label:"Reset Budget",name:"budget_duration",children:(0,a.jsxs)(v.default,{defaultValue:null,placeholder:"n/a",children:[(0,a.jsx)(v.default.Option,{value:"24h",children:"daily"}),(0,a.jsx)(v.default.Option,{value:"7d",children:"weekly"}),(0,a.jsx)(v.default.Option,{value:"30d",children:"monthly"})]})}),(0,a.jsx)(S.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,a.jsx)(A.Z,{step:1,width:400})}),(0,a.jsx)(S.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,a.jsx)(A.Z,{step:1,width:400})})]}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(I.ZP,{htmlType:"submit",children:"Create Team"})})]})})]}),(0,a.jsxs)(h.Z,{numColSpan:1,children:[(0,a.jsx)(m,{level:4,children:"Team Members"}),(0,a.jsx)(g,{children:"If you belong to multiple teams, this setting controls which teams members you see."}),l&&l.length>0?(0,a.jsx)(B.Z,{defaultValue:"0",children:l.map((e,l)=>(0,a.jsx)(K.Z,{value:String(l),onClick:()=>{P(e)},children:e.team_alias},l))}):(0,a.jsxs)(g,{children:["No team created. ",(0,a.jsx)("b",{children:"Defaulting to personal account."})]})]}),(0,a.jsxs)(h.Z,{numColSpan:1,children:[(0,a.jsx)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,a.jsxs)(D.Z,{children:[(0,a.jsx)(V.Z,{children:(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(z.Z,{children:"Member Name"}),(0,a.jsx)(z.Z,{children:"Role"})]})}),(0,a.jsx)(L.Z,{children:C?C.members_with_roles.map((e,l)=>(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(U.Z,{children:e.user_email?e.user_email:e.user_id?e.user_id:null}),(0,a.jsx)(U.Z,{children:e.role})]},l)):null})]})}),C&&(0,a.jsx)(e=>{let{visible:l,onCancel:s,team:t,onSubmit:n}=e,[r]=S.Z.useForm();return(0,a.jsx)(w.Z,{title:"Edit Team",visible:l,width:800,footer:null,onOk:()=>{r.validateFields().then(e=>{n({...e,team_id:t.team_id}),r.resetFields()}).catch(e=>{console.error("Validation failed:",e)})},onCancel:s,children:(0,a.jsxs)(S.Z,{form:r,onFinish:ea,initialValues:t,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(S.Z.Item,{label:"Team Name",name:"team_alias",rules:[{required:!0,message:"Please input a team name"}],children:(0,a.jsx)(j.Z,{})}),(0,a.jsx)(S.Z.Item,{label:"Models",name:"models",children:(0,a.jsxs)(v.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:[(0,a.jsx)(v.default.Option,{value:"all-proxy-models",children:"All Proxy Models"},"all-proxy-models"),Y&&Y.map(e=>(0,a.jsx)(v.default.Option,{value:e,children:e},e))]})}),(0,a.jsx)(S.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,a.jsx)(A.Z,{step:.01,precision:2,width:200})}),(0,a.jsx)(S.Z.Item,{className:"mt-8",label:"Reset Budget",name:"budget_duration",children:(0,a.jsxs)(v.default,{defaultValue:null,placeholder:"n/a",children:[(0,a.jsx)(v.default.Option,{value:"24h",children:"daily"}),(0,a.jsx)(v.default.Option,{value:"7d",children:"weekly"}),(0,a.jsx)(v.default.Option,{value:"30d",children:"monthly"})]})}),(0,a.jsx)(S.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,a.jsx)(A.Z,{step:1,width:400})}),(0,a.jsx)(S.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,a.jsx)(A.Z,{step:1,width:400})}),(0,a.jsx)(S.Z.Item,{label:"Requests per minute Limit (RPM)",name:"team_id",hidden:!0})]}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(I.ZP,{htmlType:"submit",children:"Edit Team"})})]})})},{visible:y,onCancel:()=>{b(!1),P(null)},team:C,onSubmit:ea})]}),(0,a.jsxs)(h.Z,{numColSpan:1,children:[(0,a.jsx)(p.Z,{className:"mx-auto mb-5",onClick:()=>G(!0),children:"+ Add member"}),(0,a.jsx)(w.Z,{title:"Add member",visible:H,width:800,footer:null,onOk:()=>{G(!1),c.resetFields()},onCancel:()=>{G(!1),c.resetFields()},children:(0,a.jsxs)(S.Z,{form:d,onFinish:ed,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(S.Z.Item,{label:"Email",name:"user_email",className:"mb-4",children:(0,a.jsx)(N.Z,{name:"user_email",className:"px-3 py-2 border rounded-md w-full"})}),(0,a.jsx)("div",{className:"text-center mb-4",children:"OR"}),(0,a.jsx)(S.Z.Item,{label:"User ID",name:"user_id",className:"mb-4",children:(0,a.jsx)(N.Z,{name:"user_id",className:"px-3 py-2 border rounded-md w-full"})})]}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(I.ZP,{htmlType:"submit",children:"Add member"})})]})})]})]})})},eD=e=>{let l,{searchParams:s,accessToken:t,showSSOBanner:n}=e,[o]=S.Z.useForm(),[d]=S.Z.useForm(),{Title:c,Paragraph:m}=$.default,[j,g]=(0,r.useState)(""),[Z,f]=(0,r.useState)(null),[y,b]=(0,r.useState)(null),[v,A]=(0,r.useState)(!1),[C,P]=(0,r.useState)(!1),[T,E]=(0,r.useState)(!1),[R,W]=(0,r.useState)(!1),[H,G]=(0,r.useState)(!1),[Y,J]=(0,r.useState)(!1),X=(0,i.useRouter)(),[Q,ee]=(0,r.useState)(null),[el,es]=(0,r.useState)("");try{l=window.location.origin}catch(e){l=""}l+="/fallback/login";let et=()=>{J(!1)},en=["proxy_admin","proxy_admin_viewer"];(0,r.useEffect)(()=>{if(X){let{protocol:e,host:l}=window.location;es("".concat(e,"//").concat(l))}},[X]),(0,r.useEffect)(()=>{(async()=>{if(null!=t){let e=[],l=await (0,u.Xd)(t,"proxy_admin_viewer");l.forEach(l=>{e.push({user_role:l.user_role,user_id:l.user_id,user_email:l.user_email})}),console.log("proxy viewers: ".concat(l));let s=await (0,u.Xd)(t,"proxy_admin");s.forEach(l=>{e.push({user_role:l.user_role,user_id:l.user_id,user_email:l.user_email})}),console.log("proxy admins: ".concat(s)),console.log("combinedList: ".concat(e)),f(e),ee(await (0,u.lg)(t))}})()},[t]);let ea=()=>{W(!1),d.resetFields(),o.resetFields()},er=()=>{W(!1),d.resetFields(),o.resetFields()},ei=e=>(0,a.jsxs)(S.Z,{form:o,onFinish:e,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsx)(a.Fragment,{children:(0,a.jsx)(S.Z.Item,{label:"Email",name:"user_email",className:"mb-8 mt-4",children:(0,a.jsx)(N.Z,{name:"user_email",className:"px-3 py-2 border rounded-md w-full"})})}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},className:"mt-4",children:(0,a.jsx)(I.ZP,{htmlType:"submit",children:"Add member"})})]}),eo=(e,l,s)=>(0,a.jsxs)(S.Z,{form:o,onFinish:e,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(S.Z.Item,{rules:[{required:!0,message:"Required"}],label:"User Role",name:"user_role",labelCol:{span:10},labelAlign:"left",children:(0,a.jsx)(B.Z,{value:l,children:en.map((e,l)=>(0,a.jsx)(K.Z,{value:e,children:e},l))})}),(0,a.jsx)(S.Z.Item,{label:"Team ID",name:"user_id",hidden:!0,initialValue:s,valuePropName:"user_id",className:"mt-8",children:(0,a.jsx)(N.Z,{value:s,disabled:!0})})]}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(I.ZP,{htmlType:"submit",children:"Update role"})})]}),ed=async e=>{try{if(null!=t&&null!=Z){k.ZP.info("Making API Call");let l=await (0,u.pf)(t,e,null);console.log("response for team create call: ".concat(l));let s=Z.findIndex(e=>(console.log("user.user_id=".concat(e.user_id,"; response.user_id=").concat(l.user_id)),e.user_id===l.user_id));console.log("foundIndex: ".concat(s)),-1==s&&(console.log("updates admin with new user"),Z.push(l),f(Z)),k.ZP.success("Refresh tab to see updated user role"),W(!1)}}catch(e){console.error("Error creating the key:",e)}},ec=async e=>{try{if(null!=t&&null!=Z){var l;k.ZP.info("Making API Call");let s=await (0,u.pf)(t,e,"proxy_admin_viewer");console.log("response for team create call: ".concat(s));let n=(null===(l=s.data)||void 0===l?void 0:l.user_id)||s.user_id;(0,u.XO)(t,n).then(e=>{b(e),A(!0)});let a=Z.findIndex(e=>(console.log("user.user_id=".concat(e.user_id,"; response.user_id=").concat(s.user_id)),e.user_id===s.user_id));console.log("foundIndex: ".concat(a)),-1==a&&(console.log("updates admin with new user"),Z.push(s),f(Z)),o.resetFields(),P(!1)}}catch(e){console.error("Error creating the key:",e)}},em=async e=>{try{if(null!=t&&null!=Z){var l;k.ZP.info("Making API Call"),e.user_email,e.user_id;let s=await (0,u.pf)(t,e,"proxy_admin"),n=(null===(l=s.data)||void 0===l?void 0:l.user_id)||s.user_id;(0,u.XO)(t,n).then(e=>{b(e),A(!0)}),console.log("response for team create call: ".concat(s));let a=Z.findIndex(e=>(console.log("user.user_id=".concat(e.user_id,"; response.user_id=").concat(n)),e.user_id===s.user_id));console.log("foundIndex: ".concat(a)),-1==a&&(console.log("updates admin with new user"),Z.push(s),f(Z)),o.resetFields(),E(!1)}}catch(e){console.error("Error creating the key:",e)}},eu=async e=>{if(null==t)return;let l={environment_variables:{PROXY_BASE_URL:e.proxy_base_url,GOOGLE_CLIENT_ID:e.google_client_id,GOOGLE_CLIENT_SECRET:e.google_client_secret}};(0,u.K_)(t,l)};return console.log("admins: ".concat(null==Z?void 0:Z.length)),(0,a.jsxs)("div",{className:"w-full m-2 mt-2 p-8",children:[(0,a.jsx)(c,{level:4,children:"Admin Access "}),(0,a.jsxs)(m,{children:[n&&(0,a.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/ui#restrict-ui-access",children:"Requires SSO Setup"}),(0,a.jsx)("br",{}),(0,a.jsx)("b",{children:"Proxy Admin: "})," Can create keys, teams, users, add models, etc."," ",(0,a.jsx)("br",{}),(0,a.jsx)("b",{children:"Proxy Admin Viewer: "}),"Can just view spend. They cannot create keys, teams or grant users access to new models."," "]}),(0,a.jsxs)(x.Z,{numItems:1,className:"gap-2 p-2 w-full",children:[(0,a.jsx)(h.Z,{numColSpan:1,children:(0,a.jsx)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,a.jsxs)(D.Z,{children:[(0,a.jsx)(V.Z,{children:(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(z.Z,{children:"Member Name"}),(0,a.jsx)(z.Z,{children:"Role"})]})}),(0,a.jsx)(L.Z,{children:Z?Z.map((e,l)=>{var s;return(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(U.Z,{children:e.user_email?e.user_email:e.user_id?e.user_id:null}),(0,a.jsxs)(U.Z,{children:[" ",(null==Q?void 0:null===(s=Q[null==e?void 0:e.user_role])||void 0===s?void 0:s.ui_label)||"-"]}),(0,a.jsxs)(U.Z,{children:[(0,a.jsx)(F.Z,{icon:O.Z,size:"sm",onClick:()=>W(!0)}),(0,a.jsx)(w.Z,{title:"Update role",visible:R,width:800,footer:null,onOk:ea,onCancel:er,children:eo(ed,e.user_role,e.user_id)})]})]},l)}):null})]})})}),(0,a.jsx)(h.Z,{numColSpan:1,children:(0,a.jsxs)("div",{className:"flex justify-start",children:[(0,a.jsx)(p.Z,{className:"mr-4 mb-5",onClick:()=>E(!0),children:"+ Add admin"}),(0,a.jsx)(w.Z,{title:"Add admin",visible:T,width:800,footer:null,onOk:()=>{E(!1),d.resetFields(),o.resetFields()},onCancel:()=>{E(!1),A(!1),d.resetFields(),o.resetFields()},children:ei(em)}),(0,a.jsx)(eT,{isInvitationLinkModalVisible:v,setIsInvitationLinkModalVisible:A,baseUrl:el,invitationLinkData:y}),(0,a.jsx)(p.Z,{className:"mb-5",onClick:()=>P(!0),children:"+ Add viewer"}),(0,a.jsx)(w.Z,{title:"Add viewer",visible:C,width:800,footer:null,onOk:()=>{P(!1),d.resetFields(),o.resetFields()},onCancel:()=>{P(!1),d.resetFields(),o.resetFields()},children:ei(ec)})]})})]}),(0,a.jsxs)(x.Z,{children:[(0,a.jsx)(c,{level:4,children:"Add SSO"}),(0,a.jsxs)("div",{className:"flex justify-start mb-4",children:[(0,a.jsx)(p.Z,{onClick:()=>G(!0),children:"Add SSO"}),(0,a.jsx)(w.Z,{title:"Add SSO",visible:H,width:800,footer:null,onOk:()=>{G(!1),o.resetFields()},onCancel:()=>{G(!1),o.resetFields()},children:(0,a.jsxs)(S.Z,{form:o,onFinish:e=>{em(e),eu(e),G(!1),J(!0)},labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(S.Z.Item,{label:"Admin Email",name:"user_email",rules:[{required:!0,message:"Please enter the email of the proxy admin"}],children:(0,a.jsx)(N.Z,{})}),(0,a.jsx)(S.Z.Item,{label:"PROXY BASE URL",name:"proxy_base_url",rules:[{required:!0,message:"Please enter the proxy base url"}],children:(0,a.jsx)(N.Z,{})}),(0,a.jsx)(S.Z.Item,{label:"GOOGLE CLIENT ID",name:"google_client_id",rules:[{required:!0,message:"Please enter the google client id"}],children:(0,a.jsx)(N.Z.Password,{})}),(0,a.jsx)(S.Z.Item,{label:"GOOGLE CLIENT SECRET",name:"google_client_secret",rules:[{required:!0,message:"Please enter the google client secret"}],children:(0,a.jsx)(N.Z.Password,{})})]}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(I.ZP,{htmlType:"submit",children:"Save"})})]})}),(0,a.jsxs)(w.Z,{title:"SSO Setup Instructions",visible:Y,width:800,footer:null,onOk:et,onCancel:()=>{J(!1)},children:[(0,a.jsx)("p",{children:"Follow these steps to complete the SSO setup:"}),(0,a.jsx)(_.Z,{className:"mt-2",children:"1. DO NOT Exit this TAB"}),(0,a.jsx)(_.Z,{className:"mt-2",children:"2. Open a new tab, visit your proxy base url"}),(0,a.jsx)(_.Z,{className:"mt-2",children:"3. Confirm your SSO is configured correctly and you can login on the new Tab"}),(0,a.jsx)(_.Z,{className:"mt-2",children:"4. If Step 3 is successful, you can close this tab"}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(I.ZP,{onClick:et,children:"Done"})})]})]}),(0,a.jsxs)(ey.Z,{title:"Login without SSO",color:"teal",children:["If you need to login without sso, you can access"," ",(0,a.jsxs)("a",{href:l,target:"_blank",children:[(0,a.jsx)("b",{children:l})," "]})]})]})]})},eL=s(42556),eU=s(90252),eV=e=>{let{alertingSettings:l,handleInputChange:s,handleResetField:t,handleSubmit:n,premiumUser:r}=e,[i]=S.Z.useForm();return(0,a.jsxs)(S.Z,{form:i,onFinish:()=>{let e=i.getFieldsValue();Object.values(e).some(e=>""===e||null==e)?console.log("Some form fields are empty."):n(e)},labelAlign:"left",children:[l.map((e,l)=>(0,a.jsxs)(q.Z,{children:[(0,a.jsxs)(U.Z,{align:"center",children:[(0,a.jsx)(_.Z,{children:e.field_name}),(0,a.jsx)("p",{style:{fontSize:"0.65rem",color:"#808080",fontStyle:"italic"},className:"mt-1",children:e.field_description})]}),e.premium_field?r?(0,a.jsx)(S.Z.Item,{name:e.field_name,children:(0,a.jsx)(U.Z,{children:"Integer"===e.field_type?(0,a.jsx)(A.Z,{step:1,value:e.field_value,onChange:l=>s(e.field_name,l)}):(0,a.jsx)(N.Z,{value:e.field_value,onChange:l=>s(e.field_name,l)})})}):(0,a.jsx)(U.Z,{children:(0,a.jsx)(p.Z,{className:"flex items-center justify-center",children:(0,a.jsx)("a",{href:"https://forms.gle/W3U4PZpJGFHWtHyA9",target:"_blank",children:"✨ Enterprise Feature"})})}):(0,a.jsx)(S.Z.Item,{name:e.field_name,className:"mb-0",children:(0,a.jsx)(U.Z,{children:"Integer"===e.field_type?(0,a.jsx)(A.Z,{step:1,value:e.field_value,onChange:l=>s(e.field_name,l),className:"p-0"}):(0,a.jsx)(N.Z,{value:e.field_value,onChange:l=>s(e.field_name,l)})})}),(0,a.jsx)(U.Z,{children:!0==e.stored_in_db?(0,a.jsx)(R.Z,{icon:eU.Z,className:"text-white",children:"In DB"}):!1==e.stored_in_db?(0,a.jsx)(R.Z,{className:"text-gray bg-white outline",children:"In Config"}):(0,a.jsx)(R.Z,{className:"text-gray bg-white outline",children:"Not Set"})}),(0,a.jsx)(U.Z,{children:(0,a.jsx)(F.Z,{icon:E.Z,color:"red",onClick:()=>t(e.field_name,l),children:"Reset"})})]},l)),(0,a.jsx)("div",{children:(0,a.jsx)(I.ZP,{htmlType:"submit",children:"Update Settings"})})]})},ez=e=>{let{accessToken:l,premiumUser:s}=e,[t,n]=(0,r.useState)([]);return console.log("INSIDE ALERTING SETTINGS"),(0,r.useEffect)(()=>{l&&(0,u.RQ)(l).then(e=>{n(e)})},[l]),(0,a.jsx)(eV,{alertingSettings:t,handleInputChange:(e,l)=>{n(t.map(s=>s.field_name===e?{...s,field_value:l}:s))},handleResetField:(e,s)=>{if(l)try{let l=t.map(l=>l.field_name===e?{...l,stored_in_db:null,field_value:l.field_default_value}:l);console.log("INSIDE HANDLE RESET FIELD"),n(l)}catch(e){console.log("ERROR OCCURRED!")}},handleSubmit:e=>{if(!l||null==e||void 0==e)return;let s={};t.forEach(e=>{s[e.field_name]=e.field_value});let n={...e,...s};try{(0,u.jA)(l,"alerting_args",n),k.ZP.success("Wait 10s for proxy to update.")}catch(e){}},premiumUser:s})},eq=s(84406);let{Title:eB,Paragraph:eK}=$.default;var eW=e=>{let{accessToken:l,userRole:s,userID:t,premiumUser:n}=e,[i,o]=(0,r.useState)([]),[d,c]=(0,r.useState)([]),[m,h]=(0,r.useState)(!1),[g]=S.Z.useForm(),[Z,f]=(0,r.useState)(null),[y,b]=(0,r.useState)([]),[N,A]=(0,r.useState)(""),[C,P]=(0,r.useState)({}),[T,E]=(0,r.useState)([]),[R,B]=(0,r.useState)(!1),[W,H]=(0,r.useState)([]),[G,Y]=(0,r.useState)(null),[J,X]=(0,r.useState)([]),[$,Q]=(0,r.useState)(!1),[ee,el]=(0,r.useState)(null),ei=e=>{T.includes(e)?E(T.filter(l=>l!==e)):E([...T,e])},eo={llm_exceptions:"LLM Exceptions",llm_too_slow:"LLM Responses Too Slow",llm_requests_hanging:"LLM Requests Hanging",budget_alerts:"Budget Alerts (API Keys, Users)",db_exceptions:"Database Exceptions (Read/Write)",daily_reports:"Weekly/Monthly Spend Reports",outage_alerts:"Outage Alerts",region_outage_alerts:"Region Outage Alerts"};(0,r.useEffect)(()=>{l&&s&&t&&(0,u.BL)(l,t,s).then(e=>{console.log("callbacks",e),o(e.callbacks),H(e.available_callbacks);let l=e.alerts;if(console.log("alerts_data",l),l&&l.length>0){let e=l[0];console.log("_alert_info",e);let s=e.variables.SLACK_WEBHOOK_URL;console.log("catch_all_webhook",s),E(e.active_alerts),A(s),P(e.alerts_to_webhook)}c(l)})},[l,s,t]);let ed=e=>T&&T.includes(e),ec=()=>{if(!l)return;let e={};d.filter(e=>"email"===e.name).forEach(l=>{var s;Object.entries(null!==(s=l.variables)&&void 0!==s?s:{}).forEach(l=>{let[s,t]=l,n=document.querySelector('input[name="'.concat(s,'"]'));n&&n.value&&(e[s]=null==n?void 0:n.value)})}),console.log("updatedVariables",e);try{(0,u.K_)(l,{general_settings:{alerting:["email"]},environment_variables:e})}catch(e){k.ZP.error("Failed to update alerts: "+e,20)}k.ZP.success("Email settings updated successfully")},em=async e=>{if(!l)return;let s={};Object.entries(e).forEach(e=>{let[l,t]=e;"callback"!==l&&(s[l]=t)});try{await (0,u.K_)(l,{environment_variables:s}),k.ZP.success("Callback added successfully"),h(!1),g.resetFields(),f(null)}catch(e){k.ZP.error("Failed to add callback: "+e,20)}},eu=async e=>{if(!l)return;let s=null==e?void 0:e.callback,t={};Object.entries(e).forEach(e=>{let[l,s]=e;"callback"!==l&&(t[l]=s)});try{await (0,u.K_)(l,{environment_variables:t,litellm_settings:{success_callback:[s]}}),k.ZP.success("Callback ".concat(s," added successfully")),h(!1),g.resetFields(),f(null)}catch(e){k.ZP.error("Failed to add callback: "+e,20)}},eh=e=>{console.log("inside handleSelectedCallbackChange",e),f(e.litellm_callback_name),console.log("all callbacks",W),e&&e.litellm_callback_params?(X(e.litellm_callback_params),console.log("selectedCallbackParams",J)):X([])};return l?(console.log("callbacks: ".concat(i)),(0,a.jsxs)("div",{className:"w-full mx-4",children:[(0,a.jsx)(x.Z,{numItems:1,className:"gap-2 p-8 w-full mt-2",children:(0,a.jsxs)(et.Z,{children:[(0,a.jsxs)(en.Z,{variant:"line",defaultValue:"1",children:[(0,a.jsx)(es.Z,{value:"1",children:"Logging Callbacks"}),(0,a.jsx)(es.Z,{value:"2",children:"Alerting Types"}),(0,a.jsx)(es.Z,{value:"3",children:"Alerting Settings"}),(0,a.jsx)(es.Z,{value:"4",children:"Email Alerts"})]}),(0,a.jsxs)(er.Z,{children:[(0,a.jsxs)(ea.Z,{children:[(0,a.jsx)(eB,{level:4,children:"Active Logging Callbacks"}),(0,a.jsx)(x.Z,{numItems:2,children:(0,a.jsx)(M.Z,{className:"max-h-[50vh]",children:(0,a.jsxs)(D.Z,{children:[(0,a.jsx)(V.Z,{children:(0,a.jsx)(q.Z,{children:(0,a.jsx)(z.Z,{children:"Callback Name"})})}),(0,a.jsx)(L.Z,{children:i.map((e,s)=>(0,a.jsxs)(q.Z,{className:"flex justify-between",children:[(0,a.jsx)(U.Z,{children:(0,a.jsx)(_.Z,{children:e.name})}),(0,a.jsx)(U.Z,{children:(0,a.jsxs)(x.Z,{numItems:2,className:"flex justify-between",children:[(0,a.jsx)(F.Z,{icon:O.Z,size:"sm",onClick:()=>{el(e),Q(!0)}}),(0,a.jsx)(p.Z,{onClick:()=>(0,u.jE)(l,e.name),className:"ml-2",variant:"secondary",children:"Test Callback"})]})})]},s))})]})})}),(0,a.jsx)(p.Z,{className:"mt-2",onClick:()=>B(!0),children:"Add Callback"})]}),(0,a.jsx)(ea.Z,{children:(0,a.jsxs)(M.Z,{children:[(0,a.jsxs)(_.Z,{className:"my-2",children:["Alerts are only supported for Slack Webhook URLs. Get your webhook urls from"," ",(0,a.jsx)("a",{href:"https://api.slack.com/messaging/webhooks",target:"_blank",style:{color:"blue"},children:"here"})]}),(0,a.jsxs)(D.Z,{children:[(0,a.jsx)(V.Z,{children:(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(z.Z,{}),(0,a.jsx)(z.Z,{}),(0,a.jsx)(z.Z,{children:"Slack Webhook URL"})]})}),(0,a.jsx)(L.Z,{children:Object.entries(eo).map((e,l)=>{let[s,t]=e;return(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(U.Z,{children:"region_outage_alerts"==s?n?(0,a.jsx)(eL.Z,{id:"switch",name:"switch",checked:ed(s),onChange:()=>ei(s)}):(0,a.jsx)(p.Z,{className:"flex items-center justify-center",children:(0,a.jsx)("a",{href:"https://forms.gle/W3U4PZpJGFHWtHyA9",target:"_blank",children:"✨ Enterprise Feature"})}):(0,a.jsx)(eL.Z,{id:"switch",name:"switch",checked:ed(s),onChange:()=>ei(s)})}),(0,a.jsx)(U.Z,{children:(0,a.jsx)(_.Z,{children:t})}),(0,a.jsx)(U.Z,{children:(0,a.jsx)(j.Z,{name:s,type:"password",defaultValue:C&&C[s]?C[s]:N})})]},l)})})]}),(0,a.jsx)(p.Z,{size:"xs",className:"mt-2",onClick:()=>{if(!l)return;let e={};Object.entries(eo).forEach(l=>{let[s,t]=l,n=document.querySelector('input[name="'.concat(s,'"]'));console.log("key",s),console.log("webhookInput",n);let a=(null==n?void 0:n.value)||"";console.log("newWebhookValue",a),e[s]=a}),console.log("updatedAlertToWebhooks",e);let s={general_settings:{alert_to_webhook_url:e,alert_types:T}};console.log("payload",s);try{(0,u.K_)(l,s)}catch(e){k.ZP.error("Failed to update alerts: "+e,20)}k.ZP.success("Alerts updated successfully")},children:"Save Changes"}),(0,a.jsx)(p.Z,{onClick:()=>(0,u.jE)(l,"slack"),className:"mx-2",children:"Test Alerts"})]})}),(0,a.jsx)(ea.Z,{children:(0,a.jsx)(ez,{accessToken:l,premiumUser:n})}),(0,a.jsx)(ea.Z,{children:(0,a.jsxs)(M.Z,{children:[(0,a.jsx)(eB,{level:4,children:"Email Settings"}),(0,a.jsxs)(_.Z,{children:[(0,a.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/email",target:"_blank",style:{color:"blue"},children:" LiteLLM Docs: email alerts"})," ",(0,a.jsx)("br",{})]}),(0,a.jsx)("div",{className:"flex w-full",children:d.filter(e=>"email"===e.name).map((e,l)=>{var s;return(0,a.jsx)(U.Z,{children:(0,a.jsx)("ul",{children:(0,a.jsx)(x.Z,{numItems:2,children:Object.entries(null!==(s=e.variables)&&void 0!==s?s:{}).map(e=>{let[l,s]=e;return(0,a.jsxs)("li",{className:"mx-2 my-2",children:[!0!=n&&("EMAIL_LOGO_URL"===l||"EMAIL_SUPPORT_CONTACT"===l)?(0,a.jsxs)("div",{children:[(0,a.jsx)("a",{href:"https://forms.gle/W3U4PZpJGFHWtHyA9",target:"_blank",children:(0,a.jsxs)(_.Z,{className:"mt-2",children:[" ","✨ ",l]})}),(0,a.jsx)(j.Z,{name:l,defaultValue:s,type:"password",disabled:!0,style:{width:"400px"}})]}):(0,a.jsxs)("div",{children:[(0,a.jsx)(_.Z,{className:"mt-2",children:l}),(0,a.jsx)(j.Z,{name:l,defaultValue:s,type:"password",style:{width:"400px"}})]}),(0,a.jsxs)("p",{style:{fontSize:"small",fontStyle:"italic"},children:["SMTP_HOST"===l&&(0,a.jsxs)("div",{style:{color:"gray"},children:["Enter the SMTP host address, e.g. `smtp.resend.com`",(0,a.jsx)("span",{style:{color:"red"},children:" Required * "})]}),"SMTP_PORT"===l&&(0,a.jsxs)("div",{style:{color:"gray"},children:["Enter the SMTP port number, e.g. `587`",(0,a.jsx)("span",{style:{color:"red"},children:" Required * "})]}),"SMTP_USERNAME"===l&&(0,a.jsxs)("div",{style:{color:"gray"},children:["Enter the SMTP username, e.g. `username`",(0,a.jsx)("span",{style:{color:"red"},children:" Required * "})]}),"SMTP_PASSWORD"===l&&(0,a.jsx)("span",{style:{color:"red"},children:" Required * "}),"SMTP_SENDER_EMAIL"===l&&(0,a.jsxs)("div",{style:{color:"gray"},children:["Enter the sender email address, e.g. `sender@berri.ai`",(0,a.jsx)("span",{style:{color:"red"},children:" Required * "})]}),"TEST_EMAIL_ADDRESS"===l&&(0,a.jsxs)("div",{style:{color:"gray"},children:["Email Address to send `Test Email Alert` to. example: `info@berri.ai`",(0,a.jsx)("span",{style:{color:"red"},children:" Required * "})]}),"EMAIL_LOGO_URL"===l&&(0,a.jsx)("div",{style:{color:"gray"},children:"(Optional) Customize the Logo that appears in the email, pass a url to your logo"}),"EMAIL_SUPPORT_CONTACT"===l&&(0,a.jsx)("div",{style:{color:"gray"},children:"(Optional) Customize the support email address that appears in the email. Default is support@berri.ai"})]})]},l)})})})},l)})}),(0,a.jsx)(p.Z,{className:"mt-2",onClick:()=>ec(),children:"Save Changes"}),(0,a.jsx)(p.Z,{onClick:()=>(0,u.jE)(l,"email"),className:"mx-2",children:"Test Email Alerts"})]})})]})]})}),(0,a.jsxs)(w.Z,{title:"Add Logging Callback",visible:R,width:800,onCancel:()=>B(!1),footer:null,children:[(0,a.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/logging",className:"mb-8 mt-4",target:"_blank",style:{color:"blue"},children:" LiteLLM Docs: Logging"}),(0,a.jsx)(S.Z,{form:g,onFinish:eu,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(eq.Z,{label:"Callback",name:"callback",rules:[{required:!0,message:"Please select a callback"}],children:(0,a.jsx)(v.default,{onChange:e=>{let l=W[e];l&&(console.log(l.ui_callback_name),eh(l))},children:W&&Object.values(W).map(e=>(0,a.jsx)(K.Z,{value:e.litellm_callback_name,children:e.ui_callback_name},e.litellm_callback_name))})}),J&&J.map(e=>(0,a.jsx)(eq.Z,{label:e,name:e,rules:[{required:!0,message:"Please enter the value for "+e}],children:(0,a.jsx)(j.Z,{type:"password"})},e)),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(I.ZP,{htmlType:"submit",children:"Save"})})]})})]}),(0,a.jsx)(w.Z,{visible:$,width:800,title:"Edit ".concat(null==ee?void 0:ee.name," Settings"),onCancel:()=>Q(!1),footer:null,children:(0,a.jsxs)(S.Z,{form:g,onFinish:em,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsx)(a.Fragment,{children:ee&&ee.variables&&Object.entries(ee.variables).map(e=>{let[l,s]=e;return(0,a.jsx)(eq.Z,{label:l,name:l,children:(0,a.jsx)(j.Z,{type:"password",defaultValue:s})},l)})}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(I.ZP,{htmlType:"submit",children:"Save"})})]})})]})):null};let{Option:eH}=v.default;var eG=e=>{let{models:l,accessToken:s,routerSettings:t,setRouterSettings:n}=e,[i]=S.Z.useForm(),[o,d]=(0,r.useState)(!1),[c,m]=(0,r.useState)("");return(0,a.jsxs)("div",{children:[(0,a.jsx)(p.Z,{className:"mx-auto",onClick:()=>d(!0),children:"+ Add Fallbacks"}),(0,a.jsx)(w.Z,{title:"Add Fallbacks",visible:o,width:800,footer:null,onOk:()=>{d(!1),i.resetFields()},onCancel:()=>{d(!1),i.resetFields()},children:(0,a.jsxs)(S.Z,{form:i,onFinish:e=>{console.log(e);let{model_name:l,models:a}=e,r=[...t.fallbacks||[],{[l]:a}],o={...t,fallbacks:r};console.log(o);try{(0,u.K_)(s,{router_settings:o}),n(o)}catch(e){k.ZP.error("Failed to update router settings: "+e,20)}k.ZP.success("router settings updated successfully"),d(!1),i.resetFields()},labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(S.Z.Item,{label:"Public Model Name",name:"model_name",rules:[{required:!0,message:"Set the model to fallback for"}],help:"required",children:(0,a.jsx)(B.Z,{defaultValue:c,children:l&&l.map((e,l)=>(0,a.jsx)(K.Z,{value:e,onClick:()=>m(e),children:e},l))})}),(0,a.jsx)(S.Z.Item,{label:"Fallback Models",name:"models",rules:[{required:!0,message:"Please select a model"}],help:"required",children:(0,a.jsx)(ei.Z,{value:l,children:l&&l.filter(e=>e!=c).map(e=>(0,a.jsx)(eo.Z,{value:e,children:e},e))})})]}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(I.ZP,{htmlType:"submit",children:"Add Fallbacks"})})]})})]})},eY=s(12968);async function eJ(e,l){console.log("isLocal:",!1);let s=window.location.origin,t=new eY.ZP.OpenAI({apiKey:l,baseURL:s,dangerouslyAllowBrowser:!0});try{let l=await t.chat.completions.create({model:e,messages:[{role:"user",content:"Hi, this is a test message"}],mock_testing_fallbacks:!0});k.ZP.success((0,a.jsxs)("span",{children:["Test model=",(0,a.jsx)("strong",{children:e}),", received model=",(0,a.jsx)("strong",{children:l.model}),". See"," ",(0,a.jsx)("a",{href:"#",onClick:()=>window.open("https://docs.litellm.ai/docs/proxy/reliability","_blank"),style:{textDecoration:"underline",color:"blue"},children:"curl"})]}))}catch(e){k.ZP.error("Error occurred while generating model response. Please try again. Error: ".concat(e),20)}}let eX={ttl:3600,lowest_latency_buffer:0},e$=e=>{let{selectedStrategy:l,strategyArgs:s,paramExplanation:t}=e;return(0,a.jsxs)(g.Z,{children:[(0,a.jsx)(f.Z,{className:"text-sm font-medium text-tremor-content-strong dark:text-dark-tremor-content-strong",children:"Routing Strategy Specific Args"}),(0,a.jsx)(Z.Z,{children:"latency-based-routing"==l?(0,a.jsx)(M.Z,{children:(0,a.jsxs)(D.Z,{children:[(0,a.jsx)(V.Z,{children:(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(z.Z,{children:"Setting"}),(0,a.jsx)(z.Z,{children:"Value"})]})}),(0,a.jsx)(L.Z,{children:Object.entries(s).map(e=>{let[l,s]=e;return(0,a.jsxs)(q.Z,{children:[(0,a.jsxs)(U.Z,{children:[(0,a.jsx)(_.Z,{children:l}),(0,a.jsx)("p",{style:{fontSize:"0.65rem",color:"#808080",fontStyle:"italic"},className:"mt-1",children:t[l]})]}),(0,a.jsx)(U.Z,{children:(0,a.jsx)(j.Z,{name:l,defaultValue:"object"==typeof s?JSON.stringify(s,null,2):s.toString()})})]},l)})})]})}):(0,a.jsx)(_.Z,{children:"No specific settings"})})]})};var eQ=e=>{let{accessToken:l,userRole:s,userID:t,modelData:n}=e,[i,o]=(0,r.useState)({}),[d,c]=(0,r.useState)({}),[m,g]=(0,r.useState)([]),[Z,f]=(0,r.useState)(!1),[b]=S.Z.useForm(),[v,w]=(0,r.useState)(null),[N,I]=(0,r.useState)(null),[C,P]=(0,r.useState)(null),T={routing_strategy_args:"(dict) Arguments to pass to the routing strategy",routing_strategy:"(string) Routing strategy to use",allowed_fails:"(int) Number of times a deployment can fail before being added to cooldown",cooldown_time:"(int) time in seconds to cooldown a deployment after failure",num_retries:"(int) Number of retries for failed requests. Defaults to 0.",timeout:"(float) Timeout for requests. Defaults to None.",retry_after:"(int) Minimum time to wait before retrying a failed request",ttl:"(int) Sliding window to look back over when calculating the average latency of a deployment. Default - 1 hour (in seconds).",lowest_latency_buffer:"(float) Shuffle between deployments within this % of the lowest latency. Default - 0 (i.e. always pick lowest latency)."};(0,r.useEffect)(()=>{l&&s&&t&&((0,u.BL)(l,t,s).then(e=>{console.log("callbacks",e),o(e.router_settings)}),(0,u.YU)(l).then(e=>{g(e)}))},[l,s,t]);let O=async e=>{if(l){console.log("received key: ".concat(e)),console.log("routerSettings['fallbacks']: ".concat(i.fallbacks)),i.fallbacks.map(l=>(e in l&&delete l[e],l));try{await (0,u.K_)(l,{router_settings:i}),o({...i}),I(i.routing_strategy),k.ZP.success("Router settings updated successfully")}catch(e){k.ZP.error("Failed to update router settings: "+e,20)}}},W=(e,l)=>{g(m.map(s=>s.field_name===e?{...s,field_value:l}:s))},H=(e,s)=>{if(!l)return;let t=m[s].field_value;if(null!=t&&void 0!=t)try{(0,u.jA)(l,e,t);let s=m.map(l=>l.field_name===e?{...l,stored_in_db:!0}:l);g(s)}catch(e){}},G=(e,s)=>{if(l)try{(0,u.ao)(l,e);let s=m.map(l=>l.field_name===e?{...l,stored_in_db:null,field_value:null}:l);g(s)}catch(e){}},Y=e=>{if(!l)return;console.log("router_settings",e);let s=Object.fromEntries(Object.entries(e).map(e=>{let[l,s]=e;if("routing_strategy_args"!==l&&"routing_strategy"!==l){var t;return[l,(null===(t=document.querySelector('input[name="'.concat(l,'"]')))||void 0===t?void 0:t.value)||s]}if("routing_strategy"==l)return[l,N];if("routing_strategy_args"==l&&"latency-based-routing"==N){let e={},l=document.querySelector('input[name="lowest_latency_buffer"]'),s=document.querySelector('input[name="ttl"]');return(null==l?void 0:l.value)&&(e.lowest_latency_buffer=Number(l.value)),(null==s?void 0:s.value)&&(e.ttl=Number(s.value)),console.log("setRoutingStrategyArgs: ".concat(e)),["routing_strategy_args",e]}return null}).filter(e=>null!=e));console.log("updatedVariables",s);try{(0,u.K_)(l,{router_settings:s})}catch(e){k.ZP.error("Failed to update router settings: "+e,20)}k.ZP.success("router settings updated successfully")};return l?(0,a.jsx)("div",{className:"w-full mx-4",children:(0,a.jsxs)(et.Z,{className:"gap-2 p-8 h-[75vh] w-full mt-2",children:[(0,a.jsxs)(en.Z,{variant:"line",defaultValue:"1",children:[(0,a.jsx)(es.Z,{value:"1",children:"Loadbalancing"}),(0,a.jsx)(es.Z,{value:"2",children:"Fallbacks"}),(0,a.jsx)(es.Z,{value:"3",children:"General"})]}),(0,a.jsxs)(er.Z,{children:[(0,a.jsx)(ea.Z,{children:(0,a.jsxs)(x.Z,{numItems:1,className:"gap-2 p-8 w-full mt-2",children:[(0,a.jsx)(y.Z,{children:"Router Settings"}),(0,a.jsxs)(M.Z,{children:[(0,a.jsxs)(D.Z,{children:[(0,a.jsx)(V.Z,{children:(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(z.Z,{children:"Setting"}),(0,a.jsx)(z.Z,{children:"Value"})]})}),(0,a.jsx)(L.Z,{children:Object.entries(i).filter(e=>{let[l,s]=e;return"fallbacks"!=l&&"context_window_fallbacks"!=l&&"routing_strategy_args"!=l}).map(e=>{let[l,s]=e;return(0,a.jsxs)(q.Z,{children:[(0,a.jsxs)(U.Z,{children:[(0,a.jsx)(_.Z,{children:l}),(0,a.jsx)("p",{style:{fontSize:"0.65rem",color:"#808080",fontStyle:"italic"},className:"mt-1",children:T[l]})]}),(0,a.jsx)(U.Z,{children:"routing_strategy"==l?(0,a.jsxs)(B.Z,{defaultValue:s,className:"w-full max-w-md",onValueChange:I,children:[(0,a.jsx)(K.Z,{value:"usage-based-routing",children:"usage-based-routing"}),(0,a.jsx)(K.Z,{value:"latency-based-routing",children:"latency-based-routing"}),(0,a.jsx)(K.Z,{value:"simple-shuffle",children:"simple-shuffle"})]}):(0,a.jsx)(j.Z,{name:l,defaultValue:"object"==typeof s?JSON.stringify(s,null,2):s.toString()})})]},l)})})]}),(0,a.jsx)(e$,{selectedStrategy:N,strategyArgs:i&&i.routing_strategy_args&&Object.keys(i.routing_strategy_args).length>0?i.routing_strategy_args:eX,paramExplanation:T})]}),(0,a.jsx)(h.Z,{children:(0,a.jsx)(p.Z,{className:"mt-2",onClick:()=>Y(i),children:"Save Changes"})})]})}),(0,a.jsxs)(ea.Z,{children:[(0,a.jsxs)(D.Z,{children:[(0,a.jsx)(V.Z,{children:(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(z.Z,{children:"Model Name"}),(0,a.jsx)(z.Z,{children:"Fallbacks"})]})}),(0,a.jsx)(L.Z,{children:i.fallbacks&&i.fallbacks.map((e,s)=>Object.entries(e).map(e=>{let[t,n]=e;return(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(U.Z,{children:t}),(0,a.jsx)(U.Z,{children:Array.isArray(n)?n.join(", "):n}),(0,a.jsx)(U.Z,{children:(0,a.jsx)(p.Z,{onClick:()=>eJ(t,l),children:"Test Fallback"})}),(0,a.jsx)(U.Z,{children:(0,a.jsx)(F.Z,{icon:E.Z,size:"sm",onClick:()=>O(t)})})]},s.toString()+t)}))})]}),(0,a.jsx)(eG,{models:(null==n?void 0:n.data)?n.data.map(e=>e.model_name):[],accessToken:l,routerSettings:i,setRouterSettings:o})]}),(0,a.jsx)(ea.Z,{children:(0,a.jsx)(M.Z,{children:(0,a.jsxs)(D.Z,{children:[(0,a.jsx)(V.Z,{children:(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(z.Z,{children:"Setting"}),(0,a.jsx)(z.Z,{children:"Value"}),(0,a.jsx)(z.Z,{children:"Status"}),(0,a.jsx)(z.Z,{children:"Action"})]})}),(0,a.jsx)(L.Z,{children:m.map((e,l)=>(0,a.jsxs)(q.Z,{children:[(0,a.jsxs)(U.Z,{children:[(0,a.jsx)(_.Z,{children:e.field_name}),(0,a.jsx)("p",{style:{fontSize:"0.65rem",color:"#808080",fontStyle:"italic"},className:"mt-1",children:e.field_description})]}),(0,a.jsx)(U.Z,{children:"Integer"==e.field_type?(0,a.jsx)(A.Z,{step:1,value:e.field_value,onChange:l=>W(e.field_name,l)}):null}),(0,a.jsx)(U.Z,{children:!0==e.stored_in_db?(0,a.jsx)(R.Z,{icon:eU.Z,className:"text-white",children:"In DB"}):!1==e.stored_in_db?(0,a.jsx)(R.Z,{className:"text-gray bg-white outline",children:"In Config"}):(0,a.jsx)(R.Z,{className:"text-gray bg-white outline",children:"Not Set"})}),(0,a.jsxs)(U.Z,{children:[(0,a.jsx)(p.Z,{onClick:()=>H(e.field_name,l),children:"Update"}),(0,a.jsx)(F.Z,{icon:E.Z,color:"red",onClick:()=>G(e.field_name,l),children:"Reset"})]})]},l))})]})})})]})]})}):null},e0=e=>{let{isModalVisible:l,accessToken:s,setIsModalVisible:t,setBudgetList:n}=e,[r]=S.Z.useForm(),i=async e=>{if(null!=s&&void 0!=s)try{k.ZP.info("Making API Call");let l=await (0,u.Zr)(s,e);console.log("key create Response:",l),n(e=>e?[...e,l]:[l]),k.ZP.success("API Key Created"),r.resetFields()}catch(e){console.error("Error creating the key:",e),k.ZP.error("Error creating the key: ".concat(e),20)}};return(0,a.jsx)(w.Z,{title:"Create Budget",visible:l,width:800,footer:null,onOk:()=>{t(!1),r.resetFields()},onCancel:()=>{t(!1),r.resetFields()},children:(0,a.jsxs)(S.Z,{form:r,onFinish:i,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(S.Z.Item,{label:"Budget ID",name:"budget_id",rules:[{required:!0,message:"Please input a human-friendly name for the budget"}],help:"A human-friendly name for the budget",children:(0,a.jsx)(j.Z,{placeholder:""})}),(0,a.jsx)(S.Z.Item,{label:"Max Tokens per minute",name:"tpm_limit",help:"Default is model limit.",children:(0,a.jsx)(A.Z,{step:1,precision:2,width:200})}),(0,a.jsx)(S.Z.Item,{label:"Max Requests per minute",name:"rpm_limit",help:"Default is model limit.",children:(0,a.jsx)(A.Z,{step:1,precision:2,width:200})}),(0,a.jsxs)(g.Z,{className:"mt-20 mb-8",children:[(0,a.jsx)(f.Z,{children:(0,a.jsx)("b",{children:"Optional Settings"})}),(0,a.jsxs)(Z.Z,{children:[(0,a.jsx)(S.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,a.jsx)(A.Z,{step:.01,precision:2,width:200})}),(0,a.jsx)(S.Z.Item,{className:"mt-8",label:"Reset Budget",name:"budget_duration",children:(0,a.jsxs)(v.default,{defaultValue:null,placeholder:"n/a",children:[(0,a.jsx)(v.default.Option,{value:"24h",children:"daily"}),(0,a.jsx)(v.default.Option,{value:"7d",children:"weekly"}),(0,a.jsx)(v.default.Option,{value:"30d",children:"monthly"})]})})]})]})]}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(I.ZP,{htmlType:"submit",children:"Create Budget"})})]})})},e1=e=>{let{isModalVisible:l,accessToken:s,setIsModalVisible:t,setBudgetList:n,existingBudget:r}=e,[i]=S.Z.useForm(),o=async e=>{if(null!=s&&void 0!=s)try{k.ZP.info("Making API Call");let l=await (0,u.Zr)(s,e);console.log("key create Response:",l),n(e=>e?[...e,l]:[l]),k.ZP.success("API Key Created"),i.resetFields()}catch(e){console.error("Error creating the key:",e),k.ZP.error("Error creating the key: ".concat(e),20)}};return(0,a.jsx)(w.Z,{title:"Edit Budget",visible:l,width:800,footer:null,onOk:()=>{t(!1),i.resetFields()},onCancel:()=>{t(!1),i.resetFields()},children:(0,a.jsxs)(S.Z,{form:i,onFinish:o,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",initialValues:r,children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(S.Z.Item,{label:"Budget ID",name:"budget_id",rules:[{required:!0,message:"Please input a human-friendly name for the budget"}],help:"A human-friendly name for the budget",children:(0,a.jsx)(j.Z,{placeholder:""})}),(0,a.jsx)(S.Z.Item,{label:"Max Tokens per minute",name:"tpm_limit",help:"Default is model limit.",children:(0,a.jsx)(A.Z,{step:1,precision:2,width:200})}),(0,a.jsx)(S.Z.Item,{label:"Max Requests per minute",name:"rpm_limit",help:"Default is model limit.",children:(0,a.jsx)(A.Z,{step:1,precision:2,width:200})}),(0,a.jsxs)(g.Z,{className:"mt-20 mb-8",children:[(0,a.jsx)(f.Z,{children:(0,a.jsx)("b",{children:"Optional Settings"})}),(0,a.jsxs)(Z.Z,{children:[(0,a.jsx)(S.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,a.jsx)(A.Z,{step:.01,precision:2,width:200})}),(0,a.jsx)(S.Z.Item,{className:"mt-8",label:"Reset Budget",name:"budget_duration",children:(0,a.jsxs)(v.default,{defaultValue:null,placeholder:"n/a",children:[(0,a.jsx)(v.default.Option,{value:"24h",children:"daily"}),(0,a.jsx)(v.default.Option,{value:"7d",children:"weekly"}),(0,a.jsx)(v.default.Option,{value:"30d",children:"monthly"})]})})]})]})]}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(I.ZP,{htmlType:"submit",children:"Edit Budget"})})]})})},e2=e=>{let{accessToken:l}=e,[s,t]=(0,r.useState)(!1),[n,i]=(0,r.useState)(!1),[o,d]=(0,r.useState)(null),[c,m]=(0,r.useState)([]);(0,r.useEffect)(()=>{l&&(0,u.O3)(l).then(e=>{m(e)})},[l]);let h=async(e,s)=>{null!=l&&(d(c[s]),i(!0))},x=async(e,s)=>{if(null==l)return;k.ZP.info("Request made"),await (0,u.NV)(l,e);let t=[...c];t.splice(s,1),m(t),k.ZP.success("Budget Deleted.")};return(0,a.jsxs)("div",{className:"w-full mx-auto flex-auto overflow-y-auto m-8 p-2",children:[(0,a.jsx)(p.Z,{size:"sm",variant:"primary",className:"mb-2",onClick:()=>t(!0),children:"+ Create Budget"}),(0,a.jsx)(e0,{accessToken:l,isModalVisible:s,setIsModalVisible:t,setBudgetList:m}),o&&(0,a.jsx)(e1,{accessToken:l,isModalVisible:n,setIsModalVisible:i,setBudgetList:m,existingBudget:o}),(0,a.jsxs)(M.Z,{children:[(0,a.jsx)(_.Z,{children:"Create a budget to assign to customers."}),(0,a.jsxs)(D.Z,{children:[(0,a.jsx)(V.Z,{children:(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(z.Z,{children:"Budget ID"}),(0,a.jsx)(z.Z,{children:"Max Budget"}),(0,a.jsx)(z.Z,{children:"TPM"}),(0,a.jsx)(z.Z,{children:"RPM"})]})}),(0,a.jsx)(L.Z,{children:c.map((e,l)=>(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(U.Z,{children:e.budget_id}),(0,a.jsx)(U.Z,{children:e.max_budget?e.max_budget:"n/a"}),(0,a.jsx)(U.Z,{children:e.tpm_limit?e.tpm_limit:"n/a"}),(0,a.jsx)(U.Z,{children:e.rpm_limit?e.rpm_limit:"n/a"}),(0,a.jsx)(F.Z,{icon:O.Z,size:"sm",onClick:()=>h(e.budget_id,l)}),(0,a.jsx)(F.Z,{icon:E.Z,size:"sm",onClick:()=>x(e.budget_id,l)})]},l))})]})]}),(0,a.jsxs)("div",{className:"mt-5",children:[(0,a.jsx)(_.Z,{className:"text-base",children:"How to use budget id"}),(0,a.jsxs)(et.Z,{children:[(0,a.jsxs)(en.Z,{children:[(0,a.jsx)(es.Z,{children:"Assign Budget to Customer"}),(0,a.jsx)(es.Z,{children:"Test it (Curl)"}),(0,a.jsx)(es.Z,{children:"Test it (OpenAI SDK)"})]}),(0,a.jsxs)(er.Z,{children:[(0,a.jsx)(ea.Z,{children:(0,a.jsx)(ek.Z,{language:"bash",children:"\ncurl -X POST --location '/end_user/new' \n-H 'Authorization: Bearer ' \n-H 'Content-Type: application/json' \n-d '{\"user_id\": \"my-customer-id', \"budget_id\": \"\"}' # \uD83D\uDC48 KEY CHANGE\n\n "})}),(0,a.jsx)(ea.Z,{children:(0,a.jsx)(ek.Z,{language:"bash",children:'\ncurl -X POST --location \'/chat/completions\' \n-H \'Authorization: Bearer \' \n-H \'Content-Type: application/json\' \n-d \'{\n "model": "gpt-3.5-turbo\', \n "messages":[{"role": "user", "content": "Hey, how\'s it going?"}],\n "user": "my-customer-id"\n}\' # \uD83D\uDC48 KEY CHANGE\n\n '})}),(0,a.jsx)(ea.Z,{children:(0,a.jsx)(ek.Z,{language:"python",children:'from openai import OpenAI\nclient = OpenAI(\n base_url="{let{proxySettings:l}=e,s="http://localhost:4000";return l&&l.PROXY_BASE_URL&&void 0!==l.PROXY_BASE_URL&&(s=l.PROXY_BASE_URL),(0,a.jsx)(a.Fragment,{children:(0,a.jsx)(x.Z,{className:"gap-2 p-8 h-[80vh] w-full mt-2",children:(0,a.jsxs)("div",{className:"mb-5",children:[(0,a.jsx)("p",{className:"text-2xl text-tremor-content-strong dark:text-dark-tremor-content-strong font-semibold",children:"OpenAI Compatible Proxy: API Reference"}),(0,a.jsx)(_.Z,{className:"mt-2 mb-2",children:"LiteLLM is OpenAI Compatible. This means your API Key works with the OpenAI SDK. Just replace the base_url to point to your litellm proxy. Example Below "}),(0,a.jsxs)(et.Z,{children:[(0,a.jsxs)(en.Z,{children:[(0,a.jsx)(es.Z,{children:"OpenAI Python SDK"}),(0,a.jsx)(es.Z,{children:"LlamaIndex"}),(0,a.jsx)(es.Z,{children:"Langchain Py"})]}),(0,a.jsxs)(er.Z,{children:[(0,a.jsx)(ea.Z,{children:(0,a.jsx)(ek.Z,{language:"python",children:'\nimport openai\nclient = openai.OpenAI(\n api_key="your_api_key",\n base_url="'.concat(s,'" # LiteLLM Proxy is OpenAI compatible, Read More: https://docs.litellm.ai/docs/proxy/user_keys\n)\n\nresponse = client.chat.completions.create(\n model="gpt-3.5-turbo", # model to send to the proxy\n messages = [\n {\n "role": "user",\n "content": "this is a test request, write a short poem"\n }\n ]\n)\n\nprint(response)\n ')})}),(0,a.jsx)(ea.Z,{children:(0,a.jsx)(ek.Z,{language:"python",children:'\nimport os, dotenv\n\nfrom llama_index.llms import AzureOpenAI\nfrom llama_index.embeddings import AzureOpenAIEmbedding\nfrom llama_index import VectorStoreIndex, SimpleDirectoryReader, ServiceContext\n\nllm = AzureOpenAI(\n engine="azure-gpt-3.5", # model_name on litellm proxy\n temperature=0.0,\n azure_endpoint="'.concat(s,'", # litellm proxy endpoint\n api_key="sk-1234", # litellm proxy API Key\n api_version="2023-07-01-preview",\n)\n\nembed_model = AzureOpenAIEmbedding(\n deployment_name="azure-embedding-model",\n azure_endpoint="').concat(s,'",\n api_key="sk-1234",\n api_version="2023-07-01-preview",\n)\n\n\ndocuments = SimpleDirectoryReader("llama_index_data").load_data()\nservice_context = ServiceContext.from_defaults(llm=llm, embed_model=embed_model)\nindex = VectorStoreIndex.from_documents(documents, service_context=service_context)\n\nquery_engine = index.as_query_engine()\nresponse = query_engine.query("What did the author do growing up?")\nprint(response)\n\n ')})}),(0,a.jsx)(ea.Z,{children:(0,a.jsx)(ek.Z,{language:"python",children:'\nfrom langchain.chat_models import ChatOpenAI\nfrom langchain.prompts.chat import (\n ChatPromptTemplate,\n HumanMessagePromptTemplate,\n SystemMessagePromptTemplate,\n)\nfrom langchain.schema import HumanMessage, SystemMessage\n\nchat = ChatOpenAI(\n openai_api_base="'.concat(s,'",\n model = "gpt-3.5-turbo",\n temperature=0.1\n)\n\nmessages = [\n SystemMessage(\n content="You are a helpful assistant that im using to make a test request to."\n ),\n HumanMessage(\n content="test from litellm. tell me why it\'s amazing in 1 sentence"\n ),\n]\nresponse = chat(messages)\n\nprint(response)\n\n ')})})]})]})]})})})};async function e8(e,l,s,t){console.log("isLocal:",!1);let n=window.location.origin,a=new eY.ZP.OpenAI({apiKey:t,baseURL:n,dangerouslyAllowBrowser:!0});try{for await(let t of(await a.chat.completions.create({model:s,stream:!0,messages:[{role:"user",content:e}]})))console.log(t),t.choices[0].delta.content&&l(t.choices[0].delta.content)}catch(e){k.ZP.error("Error occurred while generating model response. Please try again. Error: ".concat(e),20)}}var e3=e=>{let{accessToken:l,token:s,userRole:t,userID:n}=e,[i,o]=(0,r.useState)(""),[d,c]=(0,r.useState)(""),[m,g]=(0,r.useState)([]),[Z,f]=(0,r.useState)(void 0),[y,b]=(0,r.useState)([]);(0,r.useEffect)(()=>{l&&s&&t&&n&&(async()=>{try{let e=await (0,u.So)(l,n,t);if(console.log("model_info:",e),(null==e?void 0:e.data.length)>0){let l=e.data.map(e=>({value:e.id,label:e.id}));if(console.log(l),l.length>0){let e=Array.from(new Set(l));console.log("Unique models:",e),e.sort((e,l)=>e.label.localeCompare(l.label)),console.log("Model info:",y),b(e)}f(e.data[0].id)}}catch(e){console.error("Error fetching model info:",e)}})()},[l,n,t]);let S=(e,l)=>{g(s=>{let t=s[s.length-1];return t&&t.role===e?[...s.slice(0,s.length-1),{role:e,content:t.content+l}]:[...s,{role:e,content:l}]})},k=async()=>{if(""!==d.trim()&&i&&s&&t&&n){g(e=>[...e,{role:"user",content:d}]);try{Z&&await e8(d,e=>S("assistant",e),Z,i)}catch(e){console.error("Error fetching model response",e),S("assistant","Error fetching model response")}c("")}};if(t&&"Admin Viewer"==t){let{Title:e,Paragraph:l}=$.default;return(0,a.jsxs)("div",{children:[(0,a.jsx)(e,{level:1,children:"Access Denied"}),(0,a.jsx)(l,{children:"Ask your proxy admin for access to test models"})]})}return(0,a.jsx)("div",{style:{width:"100%",position:"relative"},children:(0,a.jsx)(x.Z,{className:"gap-2 p-8 h-[80vh] w-full mt-2",children:(0,a.jsx)(M.Z,{children:(0,a.jsxs)(et.Z,{children:[(0,a.jsx)(en.Z,{children:(0,a.jsx)(es.Z,{children:"Chat"})}),(0,a.jsx)(er.Z,{children:(0,a.jsxs)(ea.Z,{children:[(0,a.jsx)("div",{className:"sm:max-w-2xl",children:(0,a.jsxs)(x.Z,{numItems:2,children:[(0,a.jsxs)(h.Z,{children:[(0,a.jsx)(_.Z,{children:"API Key"}),(0,a.jsx)(j.Z,{placeholder:"Type API Key here",type:"password",onValueChange:o,value:i})]}),(0,a.jsxs)(h.Z,{className:"mx-2",children:[(0,a.jsx)(_.Z,{children:"Select Model:"}),(0,a.jsx)(v.default,{placeholder:"Select a Model",onChange:e=>{console.log("selected ".concat(e)),f(e)},options:y,style:{width:"200px"}})]})]})}),(0,a.jsxs)(D.Z,{className:"mt-5",style:{display:"block",maxHeight:"60vh",overflowY:"auto"},children:[(0,a.jsx)(V.Z,{children:(0,a.jsx)(q.Z,{children:(0,a.jsx)(U.Z,{})})}),(0,a.jsx)(L.Z,{children:m.map((e,l)=>(0,a.jsx)(q.Z,{children:(0,a.jsx)(U.Z,{children:"".concat(e.role,": ").concat(e.content)})},l))})]}),(0,a.jsx)("div",{className:"mt-3",style:{position:"absolute",bottom:5,width:"95%"},children:(0,a.jsxs)("div",{className:"flex",children:[(0,a.jsx)(j.Z,{type:"text",value:d,onChange:e=>c(e.target.value),onKeyDown:e=>{"Enter"===e.key&&k()},placeholder:"Type your message..."}),(0,a.jsx)(p.Z,{onClick:k,className:"ml-2",children:"Send"})]})})]})})]})})})})},e6=s(33509),e9=s(95781);let{Sider:e7}=e6.default;var le=e=>{let{setPage:l,userRole:s,defaultSelectedKey:t}=e;return"Admin Viewer"==s?(0,a.jsx)(e6.default,{style:{minHeight:"100vh",maxWidth:"120px"},children:(0,a.jsx)(e7,{width:120,children:(0,a.jsx)(e9.Z,{mode:"inline",defaultSelectedKeys:t||["4"],style:{height:"100%",borderRight:0},children:(0,a.jsx)(e9.Z.Item,{onClick:()=>l("usage"),children:"Usage"},"1")})})}):(0,a.jsx)(e6.default,{style:{minHeight:"100vh",maxWidth:"145px"},children:(0,a.jsx)(e7,{width:145,children:(0,a.jsxs)(e9.Z,{mode:"inline",defaultSelectedKeys:t||["1"],style:{height:"100%",borderRight:0},children:[(0,a.jsx)(e9.Z.Item,{onClick:()=>l("api-keys"),children:(0,a.jsx)(_.Z,{children:"API Keys"})},"1"),(0,a.jsx)(e9.Z.Item,{onClick:()=>l("llm-playground"),children:(0,a.jsx)(_.Z,{children:"Test Key"})},"3"),"Admin"==s?(0,a.jsx)(e9.Z.Item,{onClick:()=>l("models"),children:(0,a.jsx)(_.Z,{children:"Models"})},"2"):null,"Admin"==s?(0,a.jsx)(e9.Z.Item,{onClick:()=>l("usage"),children:(0,a.jsx)(_.Z,{children:"Usage"})},"4"):null,"Admin"==s?(0,a.jsx)(e9.Z.Item,{onClick:()=>l("teams"),children:(0,a.jsx)(_.Z,{children:"Teams"})},"6"):null,"Admin"==s?(0,a.jsx)(e9.Z.Item,{onClick:()=>l("users"),children:(0,a.jsx)(_.Z,{children:"Internal Users"})},"5"):null,"Admin"==s?(0,a.jsx)(e9.Z.Item,{onClick:()=>l("settings"),children:(0,a.jsx)(_.Z,{children:"Logging & Alerts"})},"8"):null,"Admin"==s?(0,a.jsx)(e9.Z.Item,{onClick:()=>l("caching"),children:(0,a.jsx)(_.Z,{children:"Caching"})},"9"):null,"Admin"==s?(0,a.jsx)(e9.Z.Item,{onClick:()=>l("budgets"),children:(0,a.jsx)(_.Z,{children:"Budgets"})},"10"):null,"Admin"==s?(0,a.jsx)(e9.Z.Item,{onClick:()=>l("general-settings"),children:(0,a.jsx)(_.Z,{children:"Router Settings"})},"11"):null,"Admin"==s?(0,a.jsx)(e9.Z.Item,{onClick:()=>l("admin-panel"),children:(0,a.jsx)(_.Z,{children:"Admin"})},"12"):null,(0,a.jsx)(e9.Z.Item,{onClick:()=>l("api_ref"),children:(0,a.jsx)(_.Z,{children:"API Reference"})},"13"),(0,a.jsx)(e9.Z.Item,{onClick:()=>l("model-hub"),children:(0,a.jsx)(_.Z,{children:"Model Hub"})},"15")]})})})},ll=s(67989),ls=s(52703),lt=e=>{let{accessToken:l,token:s,userRole:t,userID:n,keys:i,premiumUser:o}=e,d=new Date,[c,m]=(0,r.useState)([]),[j,g]=(0,r.useState)([]),[Z,f]=(0,r.useState)([]),[b,v]=(0,r.useState)([]),[S,k]=(0,r.useState)([]),[w,N]=(0,r.useState)([]),[A,I]=(0,r.useState)([]),[C,P]=(0,r.useState)([]),[T,O]=(0,r.useState)([]),[E,R]=(0,r.useState)([]),[F,W]=(0,r.useState)({}),[H,Y]=(0,r.useState)([]),[J,X]=(0,r.useState)(""),[$,Q]=(0,r.useState)(["all-tags"]),[em,eu]=(0,r.useState)({from:new Date(Date.now()-6048e5),to:new Date}),eh=new Date(d.getFullYear(),d.getMonth(),1),ex=new Date(d.getFullYear(),d.getMonth()+1,0),ep=e_(eh),ej=e_(ex);function eg(e){return new Intl.NumberFormat("en-US",{maximumFractionDigits:0,notation:"compact",compactDisplay:"short"}).format(e)}console.log("keys in usage",i),console.log("premium user in usage",o),(0,r.useEffect)(()=>{ef(em.from,em.to)},[em,$]);let eZ=async(e,s,t)=>{if(!e||!s||!l)return;s.setHours(23,59,59,999),e.setHours(0,0,0,0),console.log("uiSelectedKey",t);let n=await (0,u.b1)(l,t,e.toISOString(),s.toISOString());console.log("End user data updated successfully",n),v(n)},ef=async(e,s)=>{e&&s&&l&&(s.setHours(23,59,59,999),e.setHours(0,0,0,0),N((await (0,u.J$)(l,e.toISOString(),s.toISOString(),0===$.length?void 0:$)).spend_per_tag),console.log("Tag spend data updated successfully"))};function e_(e){let l=e.getFullYear(),s=e.getMonth()+1,t=e.getDate();return"".concat(l,"-").concat(s<10?"0"+s:s,"-").concat(t<10?"0"+t:t)}return console.log("Start date is ".concat(ep)),console.log("End date is ".concat(ej)),(0,r.useEffect)(()=>{l&&s&&t&&n&&(async()=>{try{if(console.log("user role: ".concat(t)),"Admin"==t||"Admin Viewer"==t){var e,a;let t=await (0,u.FC)(l);m(t);let n=await (0,u.OU)(l,s,ep,ej);console.log("provider_spend",n),R(n);let r=(await (0,u.tN)(l)).map(e=>({key:(e.key_alias||e.key_name||e.api_key).substring(0,10),spend:e.total_spend}));g(r);let i=(await (0,u.Au)(l)).map(e=>({key:e.model,spend:e.total_spend}));f(i);let o=await (0,u.mR)(l);console.log("teamSpend",o),k(o.daily_spend),P(o.teams);let d=o.total_spend_per_team;d=d.map(e=>(e.name=e.team_id||"",e.value=e.total_spend||0,e.value=e.value.toFixed(2),e)),O(d);let c=await (0,u.X)(l);I(c.tag_names);let h=await (0,u.J$)(l,null===(e=em.from)||void 0===e?void 0:e.toISOString(),null===(a=em.to)||void 0===a?void 0:a.toISOString(),void 0);N(h.spend_per_tag);let x=await (0,u.b1)(l,null,void 0,void 0);v(x),console.log("spend/user result",x);let p=await (0,u.wd)(l,ep,ej);W(p);let j=await (0,u.xA)(l,ep,ej);console.log("global activity per model",j),Y(j)}else"App Owner"==t&&await (0,u.HK)(l,s,t,n,ep,ej).then(async e=>{if(console.log("result from spend logs call",e),"daily_spend"in e){let l=e.daily_spend;console.log("daily spend",l),m(l);let s=e.top_api_keys;g(s)}else{let s=(await (0,u.e2)(l,function(e){let l=[];e.forEach(e=>{Object.entries(e).forEach(e=>{let[s,t]=e;"spend"!==s&&"startTime"!==s&&"models"!==s&&"users"!==s&&l.push({key:s,spend:t})})}),l.sort((e,l)=>Number(l.spend)-Number(e.spend));let s=l.slice(0,5).map(e=>e.key);return console.log("topKeys: ".concat(Object.keys(s[0]))),s}(e))).info.map(e=>({key:(e.key_name||e.key_alias).substring(0,10),spend:e.spend}));g(s),m(e)}})}catch(e){console.error("There was an error fetching the data",e)}})()},[l,s,t,n,ep,ej]),(0,a.jsx)("div",{style:{width:"100%"},className:"p-8",children:(0,a.jsxs)(et.Z,{children:[(0,a.jsxs)(en.Z,{className:"mt-2",children:[(0,a.jsx)(es.Z,{children:"All Up"}),(0,a.jsx)(es.Z,{children:"Team Based Usage"}),(0,a.jsx)(es.Z,{children:"Customer Usage"}),(0,a.jsx)(es.Z,{children:"Tag Based Usage"})]}),(0,a.jsxs)(er.Z,{children:[(0,a.jsx)(ea.Z,{children:(0,a.jsxs)(et.Z,{children:[(0,a.jsxs)(en.Z,{variant:"solid",className:"mt-1",children:[(0,a.jsx)(es.Z,{children:"Cost"}),(0,a.jsx)(es.Z,{children:"Activity"})]}),(0,a.jsxs)(er.Z,{children:[(0,a.jsx)(ea.Z,{children:(0,a.jsxs)(x.Z,{numItems:2,className:"gap-2 h-[100vh] w-full",children:[(0,a.jsx)(G,{userID:n,userRole:t,accessToken:l,userSpend:null,selectedTeam:null}),(0,a.jsx)(h.Z,{numColSpan:2,children:(0,a.jsxs)(M.Z,{children:[(0,a.jsx)(y.Z,{children:"Monthly Spend"}),(0,a.jsx)(ec.Z,{data:c,index:"date",categories:["spend"],colors:["blue"],valueFormatter:e=>"$ ".concat(new Intl.NumberFormat("us").format(e).toString()),yAxisWidth:100,tickGap:5})]})}),(0,a.jsx)(h.Z,{numColSpan:1,children:(0,a.jsxs)(M.Z,{children:[(0,a.jsx)(y.Z,{children:"Top API Keys"}),(0,a.jsx)(ec.Z,{className:"mt-4 h-40",data:j,index:"key",categories:["spend"],colors:["blue"],yAxisWidth:80,tickGap:5,layout:"vertical",showXAxis:!1,showLegend:!1})]})}),(0,a.jsx)(h.Z,{numColSpan:1,children:(0,a.jsxs)(M.Z,{children:[(0,a.jsx)(y.Z,{children:"Top Models"}),(0,a.jsx)(ec.Z,{className:"mt-4 h-40",data:Z,index:"key",categories:["spend"],colors:["blue"],yAxisWidth:200,layout:"vertical",showXAxis:!1,showLegend:!1})]})}),(0,a.jsx)(h.Z,{numColSpan:1}),(0,a.jsx)(h.Z,{numColSpan:2,children:(0,a.jsxs)(M.Z,{className:"mb-2",children:[(0,a.jsx)(y.Z,{children:"✨ Spend by Provider"}),o?(0,a.jsx)(a.Fragment,{children:(0,a.jsxs)(x.Z,{numItems:2,children:[(0,a.jsx)(h.Z,{numColSpan:1,children:(0,a.jsx)(ls.Z,{className:"mt-4 h-40",variant:"pie",data:E,index:"provider",category:"spend"})}),(0,a.jsx)(h.Z,{numColSpan:1,children:(0,a.jsxs)(D.Z,{children:[(0,a.jsx)(V.Z,{children:(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(z.Z,{children:"Provider"}),(0,a.jsx)(z.Z,{children:"Spend"})]})}),(0,a.jsx)(L.Z,{children:E.map(e=>(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(U.Z,{children:e.provider}),(0,a.jsx)(U.Z,{children:1e-5>parseFloat(e.spend.toFixed(2))?"less than 0.00":e.spend.toFixed(2)})]},e.provider))})]})})]})}):(0,a.jsxs)("div",{children:[(0,a.jsx)("p",{className:"mb-2 text-gray-500 italic text-[12px]",children:"Upgrade to use this feature"}),(0,a.jsx)(p.Z,{variant:"primary",className:"mb-2",children:(0,a.jsx)("a",{href:"https://forms.gle/W3U4PZpJGFHWtHyA9",target:"_blank",children:"Get Free Trial"})})]})]})})]})}),(0,a.jsx)(ea.Z,{children:(0,a.jsxs)(x.Z,{numItems:1,className:"gap-2 h-[75vh] w-full",children:[(0,a.jsxs)(M.Z,{children:[(0,a.jsx)(y.Z,{children:"All Up"}),(0,a.jsxs)(x.Z,{numItems:2,children:[(0,a.jsxs)(h.Z,{children:[(0,a.jsxs)(ee.Z,{style:{fontSize:"15px",fontWeight:"normal",color:"#535452"},children:["API Requests ",eg(F.sum_api_requests)]}),(0,a.jsx)(ed.Z,{className:"h-40",data:F.daily_data,valueFormatter:eg,index:"date",colors:["cyan"],categories:["api_requests"],onValueChange:e=>console.log(e)})]}),(0,a.jsxs)(h.Z,{children:[(0,a.jsxs)(ee.Z,{style:{fontSize:"15px",fontWeight:"normal",color:"#535452"},children:["Tokens ",eg(F.sum_total_tokens)]}),(0,a.jsx)(ec.Z,{className:"h-40",data:F.daily_data,valueFormatter:eg,index:"date",colors:["cyan"],categories:["total_tokens"],onValueChange:e=>console.log(e)})]})]})]}),o?(0,a.jsx)(a.Fragment,{children:H.map((e,l)=>(0,a.jsxs)(M.Z,{children:[(0,a.jsx)(y.Z,{children:e.model}),(0,a.jsxs)(x.Z,{numItems:2,children:[(0,a.jsxs)(h.Z,{children:[(0,a.jsxs)(ee.Z,{style:{fontSize:"15px",fontWeight:"normal",color:"#535452"},children:["API Requests ",eg(e.sum_api_requests)]}),(0,a.jsx)(ed.Z,{className:"h-40",data:e.daily_data,index:"date",colors:["cyan"],categories:["api_requests"],valueFormatter:eg,onValueChange:e=>console.log(e)})]}),(0,a.jsxs)(h.Z,{children:[(0,a.jsxs)(ee.Z,{style:{fontSize:"15px",fontWeight:"normal",color:"#535452"},children:["Tokens ",eg(e.sum_total_tokens)]}),(0,a.jsx)(ec.Z,{className:"h-40",data:e.daily_data,index:"date",colors:["cyan"],categories:["total_tokens"],valueFormatter:eg,onValueChange:e=>console.log(e)})]})]})]},l))}):(0,a.jsx)(a.Fragment,{children:H&&H.length>0&&H.slice(0,1).map((e,l)=>(0,a.jsxs)(M.Z,{children:[(0,a.jsx)(y.Z,{children:"✨ Activity by Model"}),(0,a.jsx)("p",{className:"mb-2 text-gray-500 italic text-[12px]",children:"Upgrade to see analytics for all models"}),(0,a.jsx)(p.Z,{variant:"primary",className:"mb-2",children:(0,a.jsx)("a",{href:"https://forms.gle/W3U4PZpJGFHWtHyA9",target:"_blank",children:"Get Free Trial"})}),(0,a.jsxs)(M.Z,{children:[(0,a.jsx)(y.Z,{children:e.model}),(0,a.jsxs)(x.Z,{numItems:2,children:[(0,a.jsxs)(h.Z,{children:[(0,a.jsxs)(ee.Z,{style:{fontSize:"15px",fontWeight:"normal",color:"#535452"},children:["API Requests ",eg(e.sum_api_requests)]}),(0,a.jsx)(ed.Z,{className:"h-40",data:e.daily_data,index:"date",colors:["cyan"],categories:["api_requests"],valueFormatter:eg,onValueChange:e=>console.log(e)})]}),(0,a.jsxs)(h.Z,{children:[(0,a.jsxs)(ee.Z,{style:{fontSize:"15px",fontWeight:"normal",color:"#535452"},children:["Tokens ",eg(e.sum_total_tokens)]}),(0,a.jsx)(ec.Z,{className:"h-40",data:e.daily_data,index:"date",colors:["cyan"],valueFormatter:eg,categories:["total_tokens"],onValueChange:e=>console.log(e)})]})]})]})]},l))})]})})]})]})}),(0,a.jsx)(ea.Z,{children:(0,a.jsxs)(x.Z,{numItems:2,className:"gap-2 h-[75vh] w-full",children:[(0,a.jsxs)(h.Z,{numColSpan:2,children:[(0,a.jsxs)(M.Z,{className:"mb-2",children:[(0,a.jsx)(y.Z,{children:"Total Spend Per Team"}),(0,a.jsx)(ll.Z,{data:T})]}),(0,a.jsxs)(M.Z,{children:[(0,a.jsx)(y.Z,{children:"Daily Spend Per Team"}),(0,a.jsx)(ec.Z,{className:"h-72",data:S,showLegend:!0,index:"date",categories:C,yAxisWidth:80,stack:!0})]})]}),(0,a.jsx)(h.Z,{numColSpan:2})]})}),(0,a.jsxs)(ea.Z,{children:[(0,a.jsxs)("p",{className:"mb-2 text-gray-500 italic text-[12px]",children:["Customers of your LLM API calls. Tracked when a `user` param is passed in your LLM calls ",(0,a.jsx)("a",{className:"text-blue-500",href:"https://docs.litellm.ai/docs/proxy/users",target:"_blank",children:"docs here"})]}),(0,a.jsxs)(x.Z,{numItems:2,children:[(0,a.jsxs)(h.Z,{children:[(0,a.jsx)(_.Z,{children:"Select Time Range"}),(0,a.jsx)(el.Z,{enableSelect:!0,value:em,onValueChange:e=>{eu(e),eZ(e.from,e.to,null)}})]}),(0,a.jsxs)(h.Z,{children:[(0,a.jsx)(_.Z,{children:"Select Key"}),(0,a.jsxs)(B.Z,{defaultValue:"all-keys",children:[(0,a.jsx)(K.Z,{value:"all-keys",onClick:()=>{eZ(em.from,em.to,null)},children:"All Keys"},"all-keys"),null==i?void 0:i.map((e,l)=>e&&null!==e.key_alias&&e.key_alias.length>0?(0,a.jsx)(K.Z,{value:String(l),onClick:()=>{eZ(em.from,em.to,e.token)},children:e.key_alias},l):null)]})]})]}),(0,a.jsx)(M.Z,{className:"mt-4",children:(0,a.jsxs)(D.Z,{className:"max-h-[70vh] min-h-[500px]",children:[(0,a.jsx)(V.Z,{children:(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(z.Z,{children:"Customer"}),(0,a.jsx)(z.Z,{children:"Spend"}),(0,a.jsx)(z.Z,{children:"Total Events"})]})}),(0,a.jsx)(L.Z,{children:null==b?void 0:b.map((e,l)=>{var s;return(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(U.Z,{children:e.end_user}),(0,a.jsx)(U.Z,{children:null===(s=e.total_spend)||void 0===s?void 0:s.toFixed(4)}),(0,a.jsx)(U.Z,{children:e.total_count})]},l)})})]})})]}),(0,a.jsxs)(ea.Z,{children:[(0,a.jsxs)(x.Z,{numItems:2,children:[(0,a.jsx)(h.Z,{numColSpan:1,children:(0,a.jsx)(el.Z,{className:"mb-4",enableSelect:!0,value:em,onValueChange:e=>{eu(e),ef(e.from,e.to)}})}),(0,a.jsx)(h.Z,{children:o?(0,a.jsx)("div",{children:(0,a.jsxs)(ei.Z,{value:$,onValueChange:e=>Q(e),children:[(0,a.jsx)(eo.Z,{value:"all-tags",onClick:()=>Q(["all-tags"]),children:"All Tags"},"all-tags"),A&&A.filter(e=>"all-tags"!==e).map((e,l)=>(0,a.jsx)(eo.Z,{value:String(e),children:e},e))]})}):(0,a.jsx)("div",{children:(0,a.jsxs)(ei.Z,{value:$,onValueChange:e=>Q(e),children:[(0,a.jsx)(eo.Z,{value:"all-tags",onClick:()=>Q(["all-tags"]),children:"All Tags"},"all-tags"),A&&A.filter(e=>"all-tags"!==e).map((e,l)=>(0,a.jsxs)(K.Z,{value:String(e),disabled:!0,children:["✨ ",e," (Enterprise only Feature)"]},e))]})})})]}),(0,a.jsxs)(x.Z,{numItems:2,className:"gap-2 h-[75vh] w-full mb-4",children:[(0,a.jsx)(h.Z,{numColSpan:2,children:(0,a.jsxs)(M.Z,{children:[(0,a.jsx)(y.Z,{children:"Spend Per Tag"}),(0,a.jsxs)(_.Z,{children:["Get Started Tracking cost per tag ",(0,a.jsx)("a",{className:"text-blue-500",href:"https://docs.litellm.ai/docs/proxy/cost_tracking",target:"_blank",children:"here"})]}),(0,a.jsx)(ec.Z,{className:"h-72",data:w,index:"name",categories:["spend"],colors:["blue"]})]})}),(0,a.jsx)(h.Z,{numColSpan:2})]})]})]})]})})};let ln=e=>{if(e)return e.toISOString().split("T")[0]};function la(e){return new Intl.NumberFormat("en-US",{maximumFractionDigits:0,notation:"compact",compactDisplay:"short"}).format(e)}var lr=e=>{let{accessToken:l,token:s,userRole:t,userID:n,premiumUser:i}=e,[o,d]=(0,r.useState)([]),[c,m]=(0,r.useState)([]),[p,j]=(0,r.useState)([]),[g,Z]=(0,r.useState)([]),[f,_]=(0,r.useState)("0"),[y,b]=(0,r.useState)("0"),[v,S]=(0,r.useState)("0"),[k,w]=(0,r.useState)({from:new Date(Date.now()-6048e5),to:new Date});(0,r.useEffect)(()=>{l&&k&&(async()=>{Z(await (0,u.zg)(l,ln(k.from),ln(k.to)))})()},[l]);let N=Array.from(new Set(g.map(e=>{var l;return null!==(l=null==e?void 0:e.api_key)&&void 0!==l?l:""}))),A=Array.from(new Set(g.map(e=>{var l;return null!==(l=null==e?void 0:e.model)&&void 0!==l?l:""})));Array.from(new Set(g.map(e=>{var l;return null!==(l=null==e?void 0:e.call_type)&&void 0!==l?l:""})));let I=async(e,s)=>{e&&s&&l&&(s.setHours(23,59,59,999),e.setHours(0,0,0,0),Z(await (0,u.zg)(l,ln(e),ln(s))))};return(0,r.useEffect)(()=>{console.log("DATA IN CACHE DASHBOARD",g);let e=g;c.length>0&&(e=e.filter(e=>c.includes(e.api_key))),p.length>0&&(e=e.filter(e=>p.includes(e.model))),console.log("before processed data in cache dashboard",e);let l=0,s=0,t=0,n=e.reduce((e,n)=>{console.log("Processing item:",n),n.call_type||(console.log("Item has no call_type:",n),n.call_type="Unknown"),l+=(n.total_rows||0)-(n.cache_hit_true_rows||0),s+=n.cache_hit_true_rows||0,t+=n.cached_completion_tokens||0;let a=e.find(e=>e.name===n.call_type);return a?(a["LLM API requests"]+=(n.total_rows||0)-(n.cache_hit_true_rows||0),a["Cache hit"]+=n.cache_hit_true_rows||0,a["Cached Completion Tokens"]+=n.cached_completion_tokens||0,a["Generated Completion Tokens"]+=n.generated_completion_tokens||0):e.push({name:n.call_type,"LLM API requests":(n.total_rows||0)-(n.cache_hit_true_rows||0),"Cache hit":n.cache_hit_true_rows||0,"Cached Completion Tokens":n.cached_completion_tokens||0,"Generated Completion Tokens":n.generated_completion_tokens||0}),e},[]);_(la(s)),b(la(t)),l>0?S((s/l*100).toFixed(2)):S("0"),d(n),console.log("PROCESSED DATA IN CACHE DASHBOARD",n)},[c,p,k,g]),(0,a.jsxs)(M.Z,{children:[(0,a.jsxs)(x.Z,{numItems:3,className:"gap-4 mt-4",children:[(0,a.jsx)(h.Z,{children:(0,a.jsx)(ei.Z,{placeholder:"Select API Keys",value:c,onValueChange:m,children:N.map(e=>(0,a.jsx)(eo.Z,{value:e,children:e},e))})}),(0,a.jsx)(h.Z,{children:(0,a.jsx)(ei.Z,{placeholder:"Select Models",value:p,onValueChange:j,children:A.map(e=>(0,a.jsx)(eo.Z,{value:e,children:e},e))})}),(0,a.jsx)(h.Z,{children:(0,a.jsx)(el.Z,{enableSelect:!0,value:k,onValueChange:e=>{w(e),I(e.from,e.to)},selectPlaceholder:"Select date range"})})]}),(0,a.jsxs)("div",{className:"grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3 mt-4",children:[(0,a.jsxs)(M.Z,{children:[(0,a.jsx)("p",{className:"text-tremor-default font-medium text-tremor-content dark:text-dark-tremor-content",children:"Cache Hit Ratio"}),(0,a.jsx)("div",{className:"mt-2 flex items-baseline space-x-2.5",children:(0,a.jsxs)("p",{className:"text-tremor-metric font-semibold text-tremor-content-strong dark:text-dark-tremor-content-strong",children:[v,"%"]})})]}),(0,a.jsxs)(M.Z,{children:[(0,a.jsx)("p",{className:"text-tremor-default font-medium text-tremor-content dark:text-dark-tremor-content",children:"Cache Hits"}),(0,a.jsx)("div",{className:"mt-2 flex items-baseline space-x-2.5",children:(0,a.jsx)("p",{className:"text-tremor-metric font-semibold text-tremor-content-strong dark:text-dark-tremor-content-strong",children:f})})]}),(0,a.jsxs)(M.Z,{children:[(0,a.jsx)("p",{className:"text-tremor-default font-medium text-tremor-content dark:text-dark-tremor-content",children:"Cached Tokens"}),(0,a.jsx)("div",{className:"mt-2 flex items-baseline space-x-2.5",children:(0,a.jsx)("p",{className:"text-tremor-metric font-semibold text-tremor-content-strong dark:text-dark-tremor-content-strong",children:y})})]})]}),(0,a.jsx)(ee.Z,{className:"mt-4",children:"Cache Hits vs API Requests"}),(0,a.jsx)(ec.Z,{title:"Cache Hits vs API Requests",data:o,index:"name",valueFormatter:la,categories:["LLM API requests","Cache hit"],colors:["sky","teal"],yAxisWidth:48}),(0,a.jsx)(ee.Z,{className:"mt-4",children:"Cached Completion Tokens vs Generated Completion Tokens"}),(0,a.jsx)(ec.Z,{className:"mt-6",data:o,index:"name",valueFormatter:la,categories:["Generated Completion Tokens","Cached Completion Tokens"],colors:["sky","teal"],yAxisWidth:48})]})},li=()=>{let{Title:e,Paragraph:l}=$.default,[s,t]=(0,r.useState)(""),[n,o]=(0,r.useState)(!1),[d,c]=(0,r.useState)(null),[u,h]=(0,r.useState)(null),[x,p]=(0,r.useState)(null),[j,g]=(0,r.useState)({PROXY_BASE_URL:"",PROXY_LOGOUT_URL:""}),[Z,f]=(0,r.useState)(!0),_=(0,i.useSearchParams)(),[y,b]=(0,r.useState)({data:[]}),v=_.get("userID"),S=_.get("token"),[k,w]=(0,r.useState)("api-keys"),[N,A]=(0,r.useState)(null);return(0,r.useEffect)(()=>{if(S){let e=(0,X.o)(S);if(e){if(console.log("Decoded token:",e),console.log("Decoded key:",e.key),A(e.key),e.user_role){let l=function(e){if(!e)return"Undefined Role";switch(console.log("Received user role: ".concat(e.toLowerCase())),console.log("Received user role length: ".concat(e.toLowerCase().length)),e.toLowerCase()){case"app_owner":case"demo_app_owner":return"App Owner";case"app_admin":case"proxy_admin":return"Admin";case"proxy_admin_viewer":return"Admin Viewer";case"internal_user":return"Internal User";case"internal_viewer":return"Internal Viewer";case"app_user":return"App User";default:return"Unknown Role"}}(e.user_role);console.log("Decoded user_role:",l),t(l),"Admin Viewer"==l&&w("usage")}else console.log("User role not defined");e.user_email?c(e.user_email):console.log("User Email is not set ".concat(e)),e.login_method?f("username_password"==e.login_method):console.log("User Email is not set ".concat(e)),e.premium_user&&o(e.premium_user)}}},[S]),(0,a.jsx)(r.Suspense,{fallback:(0,a.jsx)("div",{children:"Loading..."}),children:(0,a.jsxs)("div",{className:"flex flex-col min-h-screen",children:[(0,a.jsx)(m,{userID:v,userRole:s,userEmail:d,showSSOBanner:Z,premiumUser:n,setProxySettings:g,proxySettings:j}),(0,a.jsxs)("div",{className:"flex flex-1 overflow-auto",children:[(0,a.jsx)("div",{className:"mt-8",children:(0,a.jsx)(le,{setPage:w,userRole:s,defaultSelectedKey:null})}),"api-keys"==k?(0,a.jsx)(Q,{userID:v,userRole:s,teams:u,keys:x,setUserRole:t,userEmail:d,setUserEmail:c,setTeams:h,setKeys:p,setProxySettings:g,proxySettings:j}):"models"==k?(0,a.jsx)(eP,{userID:v,userRole:s,token:S,keys:x,accessToken:N,modelData:y,setModelData:b,premiumUser:n}):"llm-playground"==k?(0,a.jsx)(e3,{userID:v,userRole:s,token:S,accessToken:N}):"users"==k?(0,a.jsx)(eM,{userID:v,userRole:s,token:S,keys:x,teams:u,accessToken:N,setKeys:p}):"teams"==k?(0,a.jsx)(eF,{teams:u,setTeams:h,searchParams:_,accessToken:N,userID:v,userRole:s}):"admin-panel"==k?(0,a.jsx)(eD,{setTeams:h,searchParams:_,accessToken:N,showSSOBanner:Z}):"api_ref"==k?(0,a.jsx)(e5,{proxySettings:j}):"settings"==k?(0,a.jsx)(eW,{userID:v,userRole:s,accessToken:N,premiumUser:n}):"budgets"==k?(0,a.jsx)(e2,{accessToken:N}):"general-settings"==k?(0,a.jsx)(eQ,{userID:v,userRole:s,accessToken:N,modelData:y}):"model-hub"==k?(0,a.jsx)(e4.Z,{accessToken:N,publicPage:!1,premiumUser:n}):"caching"==k?(0,a.jsx)(lr,{userID:v,userRole:s,token:S,accessToken:N,premiumUser:n}):(0,a.jsx)(lt,{userID:v,userRole:s,token:S,accessToken:N,keys:x,premiumUser:n})]})]})})}},41134:function(e,l,s){"use strict";s.d(l,{Z:function(){return y}});var t=s(3827),n=s(64090),a=s(47907),r=s(777),i=s(16450),o=s(13810),d=s(92836),c=s(26734),m=s(41608),u=s(32126),h=s(23682),x=s(71801),p=s(42440),j=s(84174),g=s(50459),Z=s(6180),f=s(99129),_=s(67951),y=e=>{var l;let{accessToken:s,publicPage:y,premiumUser:b}=e,[v,S]=(0,n.useState)(!1),[k,w]=(0,n.useState)(null),[N,A]=(0,n.useState)(!1),[I,C]=(0,n.useState)(!1),[P,T]=(0,n.useState)(null),O=(0,a.useRouter)();(0,n.useEffect)(()=>{s&&(async()=>{try{let e=await (0,r.kn)(s);console.log("ModelHubData:",e),w(e.data),(0,r.E9)(s,"enable_public_model_hub").then(e=>{console.log("data: ".concat(JSON.stringify(e))),!0==e.field_value&&S(!0)}).catch(e=>{})}catch(e){console.error("There was an error fetching the model data",e)}})()},[s,y]);let E=e=>{T(e),A(!0)},R=async()=>{s&&(0,r.jA)(s,"enable_public_model_hub",!0).then(e=>{C(!0)})},M=()=>{A(!1),C(!1),T(null)},F=()=>{A(!1),C(!1),T(null)},D=e=>{navigator.clipboard.writeText(e)};return(0,t.jsxs)("div",{children:[y&&v||!1==y?(0,t.jsxs)("div",{className:"w-full m-2 mt-2 p-8",children:[(0,t.jsx)("div",{className:"relative w-full"}),(0,t.jsxs)("div",{className:"flex ".concat(y?"justify-between":"items-center"),children:[(0,t.jsx)(p.Z,{className:"ml-8 text-center ",children:"Model Hub"}),!1==y?b?(0,t.jsx)(i.Z,{className:"ml-4",onClick:()=>R(),children:"✨ Make Public"}):(0,t.jsx)(i.Z,{className:"ml-4",children:(0,t.jsx)("a",{href:"https://forms.gle/W3U4PZpJGFHWtHyA9",target:"_blank",children:"✨ Make Public"})}):(0,t.jsxs)("div",{className:"flex justify-between items-center",children:[(0,t.jsx)("p",{children:"Filter by key:"}),(0,t.jsx)(x.Z,{className:"bg-gray-200 pr-2 pl-2 pt-1 pb-1 text-center",children:"/ui/model_hub?key="})]})]}),(0,t.jsx)("div",{className:"grid grid-cols-2 gap-6 sm:grid-cols-3 lg:grid-cols-4 pr-8",children:k&&k.map(e=>(0,t.jsxs)(o.Z,{className:"mt-5 mx-8",children:[(0,t.jsxs)("pre",{className:"flex justify-between",children:[(0,t.jsx)(p.Z,{children:e.model_group}),(0,t.jsx)(Z.Z,{title:e.model_group,children:(0,t.jsx)(j.Z,{onClick:()=>D(e.model_group),style:{cursor:"pointer",marginRight:"10px"}})})]}),(0,t.jsxs)("div",{className:"my-5",children:[(0,t.jsxs)(x.Z,{children:["Mode: ",e.mode]}),(0,t.jsxs)(x.Z,{children:["Supports Function Calling:"," ",(null==e?void 0:e.supports_function_calling)==!0?"Yes":"No"]}),(0,t.jsxs)(x.Z,{children:["Supports Vision:"," ",(null==e?void 0:e.supports_vision)==!0?"Yes":"No"]}),(0,t.jsxs)(x.Z,{children:["Max Input Tokens:"," ",(null==e?void 0:e.max_input_tokens)?null==e?void 0:e.max_input_tokens:"N/A"]}),(0,t.jsxs)(x.Z,{children:["Max Output Tokens:"," ",(null==e?void 0:e.max_output_tokens)?null==e?void 0:e.max_output_tokens:"N/A"]})]}),(0,t.jsx)("div",{style:{marginTop:"auto",textAlign:"right"},children:(0,t.jsxs)("a",{href:"#",onClick:()=>E(e),style:{color:"#1890ff",fontSize:"smaller"},children:["View more ",(0,t.jsx)(g.Z,{})]})})]},e.model_group))})]}):(0,t.jsxs)(o.Z,{className:"mx-auto max-w-xl mt-10",children:[(0,t.jsx)(x.Z,{className:"text-xl text-center mb-2 text-black",children:"Public Model Hub not enabled."}),(0,t.jsx)("p",{className:"text-base text-center text-slate-800",children:"Ask your proxy admin to enable this on their Admin UI."})]}),(0,t.jsx)(f.Z,{title:"Public Model Hub",width:600,visible:I,footer:null,onOk:M,onCancel:F,children:(0,t.jsxs)("div",{className:"pt-5 pb-5",children:[(0,t.jsxs)("div",{className:"flex justify-between mb-4",children:[(0,t.jsx)(x.Z,{className:"text-base mr-2",children:"Shareable Link:"}),(0,t.jsx)(x.Z,{className:"max-w-sm ml-2 bg-gray-200 pr-2 pl-2 pt-1 pb-1 text-center rounded",children:"/ui/model_hub?key="})]}),(0,t.jsx)("div",{className:"flex justify-end",children:(0,t.jsx)(i.Z,{onClick:()=>{O.replace("/model_hub?key=".concat(s))},children:"See Page"})})]})}),(0,t.jsx)(f.Z,{title:P&&P.model_group?P.model_group:"Unknown Model",width:800,visible:N,footer:null,onOk:M,onCancel:F,children:P&&(0,t.jsxs)("div",{children:[(0,t.jsx)("p",{className:"mb-4",children:(0,t.jsx)("strong",{children:"Model Information & Usage"})}),(0,t.jsxs)(c.Z,{children:[(0,t.jsxs)(m.Z,{children:[(0,t.jsx)(d.Z,{children:"OpenAI Python SDK"}),(0,t.jsx)(d.Z,{children:"Supported OpenAI Params"}),(0,t.jsx)(d.Z,{children:"LlamaIndex"}),(0,t.jsx)(d.Z,{children:"Langchain Py"})]}),(0,t.jsxs)(h.Z,{children:[(0,t.jsx)(u.Z,{children:(0,t.jsx)(_.Z,{language:"python",children:'\nimport openai\nclient = openai.OpenAI(\n api_key="your_api_key",\n base_url="http://0.0.0.0:4000" # LiteLLM Proxy is OpenAI compatible, Read More: https://docs.litellm.ai/docs/proxy/user_keys\n)\n\nresponse = client.chat.completions.create(\n model="'.concat(P.model_group,'", # model to send to the proxy\n messages = [\n {\n "role": "user",\n "content": "this is a test request, write a short poem"\n }\n ]\n)\n\nprint(response)\n ')})}),(0,t.jsx)(u.Z,{children:(0,t.jsx)(_.Z,{language:"python",children:"".concat(null===(l=P.supported_openai_params)||void 0===l?void 0:l.map(e=>"".concat(e,"\n")).join(""))})}),(0,t.jsx)(u.Z,{children:(0,t.jsx)(_.Z,{language:"python",children:'\nimport os, dotenv\n\nfrom llama_index.llms import AzureOpenAI\nfrom llama_index.embeddings import AzureOpenAIEmbedding\nfrom llama_index import VectorStoreIndex, SimpleDirectoryReader, ServiceContext\n\nllm = AzureOpenAI(\n engine="'.concat(P.model_group,'", # model_name on litellm proxy\n temperature=0.0,\n azure_endpoint="http://0.0.0.0:4000", # litellm proxy endpoint\n api_key="sk-1234", # litellm proxy API Key\n api_version="2023-07-01-preview",\n)\n\nembed_model = AzureOpenAIEmbedding(\n deployment_name="azure-embedding-model",\n azure_endpoint="http://0.0.0.0:4000",\n api_key="sk-1234",\n api_version="2023-07-01-preview",\n)\n\n\ndocuments = SimpleDirectoryReader("llama_index_data").load_data()\nservice_context = ServiceContext.from_defaults(llm=llm, embed_model=embed_model)\nindex = VectorStoreIndex.from_documents(documents, service_context=service_context)\n\nquery_engine = index.as_query_engine()\nresponse = query_engine.query("What did the author do growing up?")\nprint(response)\n\n ')})}),(0,t.jsx)(u.Z,{children:(0,t.jsx)(_.Z,{language:"python",children:'\nfrom langchain.chat_models import ChatOpenAI\nfrom langchain.prompts.chat import (\n ChatPromptTemplate,\n HumanMessagePromptTemplate,\n SystemMessagePromptTemplate,\n)\nfrom langchain.schema import HumanMessage, SystemMessage\n\nchat = ChatOpenAI(\n openai_api_base="http://0.0.0.0:4000",\n model = "'.concat(P.model_group,'",\n temperature=0.1\n)\n\nmessages = [\n SystemMessage(\n content="You are a helpful assistant that im using to make a test request to."\n ),\n HumanMessage(\n content="test from litellm. tell me why it\'s amazing in 1 sentence"\n ),\n]\nresponse = chat(messages)\n\nprint(response)\n\n ')})})]})]})]})})]})}}},function(e){e.O(0,[936,294,131,684,759,777,971,69,744],function(){return e(e.s=20661)}),_N_E=e.O()}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/index.html b/litellm/proxy/_experimental/out/index.html index bee8814de0c..c33c288c785 100644 --- a/litellm/proxy/_experimental/out/index.html +++ b/litellm/proxy/_experimental/out/index.html @@ -1 +1 @@ -LiteLLM Dashboard \ No newline at end of file +LiteLLM Dashboard \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/index.txt b/litellm/proxy/_experimental/out/index.txt index d67a24f7fac..32c7cd30e89 100644 --- a/litellm/proxy/_experimental/out/index.txt +++ b/litellm/proxy/_experimental/out/index.txt @@ -1,7 +1,7 @@ 2:I[77831,[],""] -3:I[48951,["936","static/chunks/2f6dbc85-052c4579f80d66ae.js","294","static/chunks/294-0e35509d5ca95267.js","131","static/chunks/131-6a03368053f9d26d.js","684","static/chunks/684-bb2d2f93d92acb0b.js","759","static/chunks/759-83a8bdddfe32b5d9.js","777","static/chunks/777-f76791513e294b30.js","931","static/chunks/app/page-5b9334558218205d.js"],""] +3:I[48951,["936","static/chunks/2f6dbc85-052c4579f80d66ae.js","294","static/chunks/294-0e35509d5ca95267.js","131","static/chunks/131-6a03368053f9d26d.js","684","static/chunks/684-bb2d2f93d92acb0b.js","759","static/chunks/759-83a8bdddfe32b5d9.js","777","static/chunks/777-f76791513e294b30.js","931","static/chunks/app/page-42b04008af7da690.js"],""] 4:I[5613,[],""] 5:I[31778,[],""] -0:["dDWf4yi4zCe685SxgCnWX",[[["",{"children":["__PAGE__",{}]},"$undefined","$undefined",true],["",{"children":["__PAGE__",{},["$L1",["$","$L2",null,{"propsForComponent":{"params":{}},"Component":"$3","isStaticGeneration":true}],null]]},[null,["$","html",null,{"lang":"en","children":["$","body",null,{"className":"__className_12bbc4","children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"loading":"$undefined","loadingStyles":"$undefined","loadingScripts":"$undefined","hasLoading":false,"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[],"styles":null}]}]}],null]],[[["$","link","0",{"rel":"stylesheet","href":"/ui/_next/static/css/0f6908625573deae.css","precedence":"next","crossOrigin":""}]],"$L6"]]]] +0:["DahySukItzAH9ZoOiMmQB",[[["",{"children":["__PAGE__",{}]},"$undefined","$undefined",true],["",{"children":["__PAGE__",{},["$L1",["$","$L2",null,{"propsForComponent":{"params":{}},"Component":"$3","isStaticGeneration":true}],null]]},[null,["$","html",null,{"lang":"en","children":["$","body",null,{"className":"__className_12bbc4","children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"loading":"$undefined","loadingStyles":"$undefined","loadingScripts":"$undefined","hasLoading":false,"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[],"styles":null}]}]}],null]],[[["$","link","0",{"rel":"stylesheet","href":"/ui/_next/static/css/0f6908625573deae.css","precedence":"next","crossOrigin":""}]],"$L6"]]]] 6:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"LiteLLM Dashboard"}],["$","meta","3",{"name":"description","content":"LiteLLM Proxy Admin UI"}],["$","link","4",{"rel":"icon","href":"/ui/favicon.ico","type":"image/x-icon","sizes":"16x16"}],["$","meta","5",{"name":"next-size-adjust"}]] 1:null diff --git a/litellm/proxy/_experimental/out/model_hub.html b/litellm/proxy/_experimental/out/model_hub.html index 49dfe314fcc..ef01db5851f 100644 --- a/litellm/proxy/_experimental/out/model_hub.html +++ b/litellm/proxy/_experimental/out/model_hub.html @@ -1 +1 @@ -LiteLLM Dashboard \ No newline at end of file +LiteLLM Dashboard \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/model_hub.txt b/litellm/proxy/_experimental/out/model_hub.txt index 7b80cb0f46b..cf5da26f116 100644 --- a/litellm/proxy/_experimental/out/model_hub.txt +++ b/litellm/proxy/_experimental/out/model_hub.txt @@ -2,6 +2,6 @@ 3:I[87494,["294","static/chunks/294-0e35509d5ca95267.js","131","static/chunks/131-6a03368053f9d26d.js","777","static/chunks/777-f76791513e294b30.js","418","static/chunks/app/model_hub/page-ba7819b59161aa64.js"],""] 4:I[5613,[],""] 5:I[31778,[],""] -0:["dDWf4yi4zCe685SxgCnWX",[[["",{"children":["model_hub",{"children":["__PAGE__",{}]}]},"$undefined","$undefined",true],["",{"children":["model_hub",{"children":["__PAGE__",{},["$L1",["$","$L2",null,{"propsForComponent":{"params":{}},"Component":"$3","isStaticGeneration":true}],null]]},["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","model_hub","children"],"loading":"$undefined","loadingStyles":"$undefined","loadingScripts":"$undefined","hasLoading":false,"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined","styles":null}]]},[null,["$","html",null,{"lang":"en","children":["$","body",null,{"className":"__className_12bbc4","children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"loading":"$undefined","loadingStyles":"$undefined","loadingScripts":"$undefined","hasLoading":false,"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[],"styles":null}]}]}],null]],[[["$","link","0",{"rel":"stylesheet","href":"/ui/_next/static/css/0f6908625573deae.css","precedence":"next","crossOrigin":""}]],"$L6"]]]] +0:["DahySukItzAH9ZoOiMmQB",[[["",{"children":["model_hub",{"children":["__PAGE__",{}]}]},"$undefined","$undefined",true],["",{"children":["model_hub",{"children":["__PAGE__",{},["$L1",["$","$L2",null,{"propsForComponent":{"params":{}},"Component":"$3","isStaticGeneration":true}],null]]},["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","model_hub","children"],"loading":"$undefined","loadingStyles":"$undefined","loadingScripts":"$undefined","hasLoading":false,"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined","styles":null}]]},[null,["$","html",null,{"lang":"en","children":["$","body",null,{"className":"__className_12bbc4","children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"loading":"$undefined","loadingStyles":"$undefined","loadingScripts":"$undefined","hasLoading":false,"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[],"styles":null}]}]}],null]],[[["$","link","0",{"rel":"stylesheet","href":"/ui/_next/static/css/0f6908625573deae.css","precedence":"next","crossOrigin":""}]],"$L6"]]]] 6:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"LiteLLM Dashboard"}],["$","meta","3",{"name":"description","content":"LiteLLM Proxy Admin UI"}],["$","link","4",{"rel":"icon","href":"/ui/favicon.ico","type":"image/x-icon","sizes":"16x16"}],["$","meta","5",{"name":"next-size-adjust"}]] 1:null diff --git a/litellm/proxy/_experimental/out/onboarding.html b/litellm/proxy/_experimental/out/onboarding.html index ca402520812..ff88e53c95e 100644 --- a/litellm/proxy/_experimental/out/onboarding.html +++ b/litellm/proxy/_experimental/out/onboarding.html @@ -1 +1 @@ -LiteLLM Dashboard \ No newline at end of file +LiteLLM Dashboard \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/onboarding.txt b/litellm/proxy/_experimental/out/onboarding.txt index 1563ac4dd61..7c5d0071c9d 100644 --- a/litellm/proxy/_experimental/out/onboarding.txt +++ b/litellm/proxy/_experimental/out/onboarding.txt @@ -1,7 +1,7 @@ 2:I[77831,[],""] -3:I[667,["665","static/chunks/3014691f-589a5f4865c3822f.js","294","static/chunks/294-0e35509d5ca95267.js","684","static/chunks/684-bb2d2f93d92acb0b.js","777","static/chunks/777-f76791513e294b30.js","461","static/chunks/app/onboarding/page-da04a591bae84617.js"],""] +3:I[667,["665","static/chunks/3014691f-589a5f4865c3822f.js","294","static/chunks/294-0e35509d5ca95267.js","684","static/chunks/684-bb2d2f93d92acb0b.js","777","static/chunks/777-f76791513e294b30.js","461","static/chunks/app/onboarding/page-fd30ae439831db99.js"],""] 4:I[5613,[],""] 5:I[31778,[],""] -0:["dDWf4yi4zCe685SxgCnWX",[[["",{"children":["onboarding",{"children":["__PAGE__",{}]}]},"$undefined","$undefined",true],["",{"children":["onboarding",{"children":["__PAGE__",{},["$L1",["$","$L2",null,{"propsForComponent":{"params":{}},"Component":"$3","isStaticGeneration":true}],null]]},["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","onboarding","children"],"loading":"$undefined","loadingStyles":"$undefined","loadingScripts":"$undefined","hasLoading":false,"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined","styles":null}]]},[null,["$","html",null,{"lang":"en","children":["$","body",null,{"className":"__className_12bbc4","children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"loading":"$undefined","loadingStyles":"$undefined","loadingScripts":"$undefined","hasLoading":false,"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[],"styles":null}]}]}],null]],[[["$","link","0",{"rel":"stylesheet","href":"/ui/_next/static/css/0f6908625573deae.css","precedence":"next","crossOrigin":""}]],"$L6"]]]] +0:["DahySukItzAH9ZoOiMmQB",[[["",{"children":["onboarding",{"children":["__PAGE__",{}]}]},"$undefined","$undefined",true],["",{"children":["onboarding",{"children":["__PAGE__",{},["$L1",["$","$L2",null,{"propsForComponent":{"params":{}},"Component":"$3","isStaticGeneration":true}],null]]},["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","onboarding","children"],"loading":"$undefined","loadingStyles":"$undefined","loadingScripts":"$undefined","hasLoading":false,"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined","styles":null}]]},[null,["$","html",null,{"lang":"en","children":["$","body",null,{"className":"__className_12bbc4","children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"loading":"$undefined","loadingStyles":"$undefined","loadingScripts":"$undefined","hasLoading":false,"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[],"styles":null}]}]}],null]],[[["$","link","0",{"rel":"stylesheet","href":"/ui/_next/static/css/0f6908625573deae.css","precedence":"next","crossOrigin":""}]],"$L6"]]]] 6:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"LiteLLM Dashboard"}],["$","meta","3",{"name":"description","content":"LiteLLM Proxy Admin UI"}],["$","link","4",{"rel":"icon","href":"/ui/favicon.ico","type":"image/x-icon","sizes":"16x16"}],["$","meta","5",{"name":"next-size-adjust"}]] 1:null diff --git a/ui/litellm-dashboard/out/404.html b/ui/litellm-dashboard/out/404.html index e27fe5bab8d..909f7154275 100644 --- a/ui/litellm-dashboard/out/404.html +++ b/ui/litellm-dashboard/out/404.html @@ -1 +1 @@ -404: This page could not be found.LiteLLM Dashboard

404

This page could not be found.

\ No newline at end of file +404: This page could not be found.LiteLLM Dashboard

404

This page could not be found.

\ No newline at end of file diff --git a/ui/litellm-dashboard/out/_next/static/dDWf4yi4zCe685SxgCnWX/_buildManifest.js b/ui/litellm-dashboard/out/_next/static/DahySukItzAH9ZoOiMmQB/_buildManifest.js similarity index 100% rename from ui/litellm-dashboard/out/_next/static/dDWf4yi4zCe685SxgCnWX/_buildManifest.js rename to ui/litellm-dashboard/out/_next/static/DahySukItzAH9ZoOiMmQB/_buildManifest.js diff --git a/ui/litellm-dashboard/out/_next/static/dDWf4yi4zCe685SxgCnWX/_ssgManifest.js b/ui/litellm-dashboard/out/_next/static/DahySukItzAH9ZoOiMmQB/_ssgManifest.js similarity index 100% rename from ui/litellm-dashboard/out/_next/static/dDWf4yi4zCe685SxgCnWX/_ssgManifest.js rename to ui/litellm-dashboard/out/_next/static/DahySukItzAH9ZoOiMmQB/_ssgManifest.js diff --git a/ui/litellm-dashboard/out/_next/static/chunks/app/onboarding/page-da04a591bae84617.js b/ui/litellm-dashboard/out/_next/static/chunks/app/onboarding/page-da04a591bae84617.js deleted file mode 100644 index 206e6c60271..00000000000 --- a/ui/litellm-dashboard/out/_next/static/chunks/app/onboarding/page-da04a591bae84617.js +++ /dev/null @@ -1 +0,0 @@ -(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[461],{61994:function(e,s,l){Promise.resolve().then(l.bind(l,667))},667:function(e,s,l){"use strict";l.r(s),l.d(s,{default:function(){return _}});var t=l(3827),a=l(64090),r=l(47907),n=l(16450),i=l(18190),o=l(13810),u=l(10384),c=l(46453),d=l(71801),m=l(52273),h=l(42440),x=l(30953),j=l(777),p=l(37963),f=l(60620),g=l(1861);function _(){let[e]=f.Z.useForm(),s=(0,r.useSearchParams)();s.get("token");let l=s.get("id"),[_,Z]=(0,a.useState)(null),[w,b]=(0,a.useState)(""),[N,S]=(0,a.useState)(""),[k,y]=(0,a.useState)(null),[v,E]=(0,a.useState)(""),[F,I]=(0,a.useState)("");return(0,a.useEffect)(()=>{l&&(0,j.W_)(l).then(e=>{let s=e.login_url;console.log("login_url:",s),E(s);let l=e.token,t=(0,p.o)(l);I(l),console.log("decoded:",t),Z(t.key),console.log("decoded user email:",t.user_email),S(t.user_email),y(t.user_id)})},[l]),(0,t.jsx)("div",{className:"mx-auto max-w-md mt-10",children:(0,t.jsxs)(o.Z,{children:[(0,t.jsx)(h.Z,{className:"text-sm mb-5 text-center",children:"\uD83D\uDE85 LiteLLM"}),(0,t.jsx)(h.Z,{className:"text-xl",children:"Sign up"}),(0,t.jsx)(d.Z,{children:"Claim your user account to login to Admin UI."}),(0,t.jsx)(i.Z,{className:"mt-4",title:"SSO",icon:x.GH$,color:"sky",children:(0,t.jsxs)(c.Z,{numItems:2,className:"flex justify-between items-center",children:[(0,t.jsx)(u.Z,{children:"SSO is under the Enterprise Tirer."}),(0,t.jsx)(u.Z,{children:(0,t.jsx)(n.Z,{variant:"primary",className:"mb-2",children:(0,t.jsx)("a",{href:"https://forms.gle/W3U4PZpJGFHWtHyA9",target:"_blank",children:"Get Free Trial"})})})]})}),(0,t.jsxs)(f.Z,{className:"mt-10 mb-5 mx-auto",layout:"vertical",onFinish:e=>{console.log("in handle submit. accessToken:",_,"token:",F,"formValues:",e),_&&F&&(e.user_email=N,k&&l&&(0,j.m_)(_,l,k,e.password).then(e=>{var s;let l="/ui/";console.log("redirecting to:",l+="?userID="+((null===(s=e.data)||void 0===s?void 0:s.user_id)||e.user_id)+"&token="+F),window.location.href=l}))},children:[(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(f.Z.Item,{label:"Email Address",name:"user_email",children:(0,t.jsx)(m.Z,{type:"email",disabled:!0,value:N,defaultValue:N,className:"max-w-md"})}),(0,t.jsx)(f.Z.Item,{label:"Password",name:"password",rules:[{required:!0,message:"password required to sign up"}],help:"Create a password for your account",children:(0,t.jsx)(m.Z,{placeholder:"",type:"password",className:"max-w-md"})})]}),(0,t.jsx)("div",{className:"mt-10",children:(0,t.jsx)(g.ZP,{htmlType:"submit",children:"Sign Up"})})]})]})})}}},function(e){e.O(0,[665,294,684,777,971,69,744],function(){return e(e.s=61994)}),_N_E=e.O()}]); \ No newline at end of file diff --git a/ui/litellm-dashboard/out/_next/static/chunks/app/onboarding/page-fd30ae439831db99.js b/ui/litellm-dashboard/out/_next/static/chunks/app/onboarding/page-fd30ae439831db99.js new file mode 100644 index 00000000000..ae763de169c --- /dev/null +++ b/ui/litellm-dashboard/out/_next/static/chunks/app/onboarding/page-fd30ae439831db99.js @@ -0,0 +1 @@ +(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[461],{61994:function(e,s,t){Promise.resolve().then(t.bind(t,667))},667:function(e,s,t){"use strict";t.r(s),t.d(s,{default:function(){return _}});var l=t(3827),n=t(64090),a=t(47907),r=t(16450),i=t(18190),o=t(13810),c=t(10384),u=t(46453),d=t(71801),m=t(52273),h=t(42440),x=t(30953),p=t(777),f=t(37963),j=t(60620),g=t(1861);function _(){let[e]=j.Z.useForm(),s=(0,a.useSearchParams)();!function(e){console.log("COOKIES",document.cookie);let s=document.cookie.split("; ").find(s=>s.startsWith(e+"="));s&&s.split("=")[1]}("token");let t=s.get("id"),[_,Z]=(0,n.useState)(null),[k,w]=(0,n.useState)(""),[S,b]=(0,n.useState)(""),[N,y]=(0,n.useState)(null),[v,E]=(0,n.useState)(""),[I,O]=(0,n.useState)("");return(0,n.useEffect)(()=>{t&&(0,p.W_)(t).then(e=>{let s=e.login_url;console.log("login_url:",s),E(s);let t=e.token,l=(0,f.o)(t);O(t),console.log("decoded:",l),Z(l.key),console.log("decoded user email:",l.user_email),b(l.user_email),y(l.user_id)})},[t]),(0,l.jsx)("div",{className:"mx-auto max-w-md mt-10",children:(0,l.jsxs)(o.Z,{children:[(0,l.jsx)(h.Z,{className:"text-sm mb-5 text-center",children:"\uD83D\uDE85 LiteLLM"}),(0,l.jsx)(h.Z,{className:"text-xl",children:"Sign up"}),(0,l.jsx)(d.Z,{children:"Claim your user account to login to Admin UI."}),(0,l.jsx)(i.Z,{className:"mt-4",title:"SSO",icon:x.GH$,color:"sky",children:(0,l.jsxs)(u.Z,{numItems:2,className:"flex justify-between items-center",children:[(0,l.jsx)(c.Z,{children:"SSO is under the Enterprise Tirer."}),(0,l.jsx)(c.Z,{children:(0,l.jsx)(r.Z,{variant:"primary",className:"mb-2",children:(0,l.jsx)("a",{href:"https://forms.gle/W3U4PZpJGFHWtHyA9",target:"_blank",children:"Get Free Trial"})})})]})}),(0,l.jsxs)(j.Z,{className:"mt-10 mb-5 mx-auto",layout:"vertical",onFinish:e=>{console.log("in handle submit. accessToken:",_,"token:",I,"formValues:",e),_&&I&&(e.user_email=S,N&&t&&(0,p.m_)(_,t,N,e.password).then(e=>{var s;let t="/ui/";console.log("redirecting to:",t+="?userID="+((null===(s=e.data)||void 0===s?void 0:s.user_id)||e.user_id)+"&token="+I),window.location.href=t}))},children:[(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(j.Z.Item,{label:"Email Address",name:"user_email",children:(0,l.jsx)(m.Z,{type:"email",disabled:!0,value:S,defaultValue:S,className:"max-w-md"})}),(0,l.jsx)(j.Z.Item,{label:"Password",name:"password",rules:[{required:!0,message:"password required to sign up"}],help:"Create a password for your account",children:(0,l.jsx)(m.Z,{placeholder:"",type:"password",className:"max-w-md"})})]}),(0,l.jsx)("div",{className:"mt-10",children:(0,l.jsx)(g.ZP,{htmlType:"submit",children:"Sign Up"})})]})]})})}}},function(e){e.O(0,[665,294,684,777,971,69,744],function(){return e(e.s=61994)}),_N_E=e.O()}]); \ No newline at end of file diff --git a/ui/litellm-dashboard/out/_next/static/chunks/app/page-42b04008af7da690.js b/ui/litellm-dashboard/out/_next/static/chunks/app/page-42b04008af7da690.js new file mode 100644 index 00000000000..f3bad03c2ef --- /dev/null +++ b/ui/litellm-dashboard/out/_next/static/chunks/app/page-42b04008af7da690.js @@ -0,0 +1 @@ +(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[931],{20661:function(e,l,s){Promise.resolve().then(s.bind(s,48951))},48951:function(e,l,s){"use strict";s.r(l),s.d(l,{default:function(){return li}});var t,n,a=s(3827),r=s(64090),i=s(47907),o=s(8792),d=s(40491),c=s(65270),m=e=>{let{userID:l,userRole:s,userEmail:t,showSSOBanner:n,premiumUser:r,setProxySettings:i,proxySettings:m}=e;console.log("User ID:",l),console.log("userEmail:",t),console.log("showSSOBanner:",n),console.log("premiumUser:",r);let u="";console.log("PROXY_settings=",m),m&&m.PROXY_LOGOUT_URL&&void 0!==m.PROXY_LOGOUT_URL&&(u=m.PROXY_LOGOUT_URL),console.log("logoutUrl=",u);let h=[{key:"1",label:(0,a.jsxs)(a.Fragment,{children:[(0,a.jsxs)("p",{children:["Role: ",s]}),(0,a.jsxs)("p",{children:["ID: ",l]}),(0,a.jsxs)("p",{children:["Premium User: ",String(r)]})]})},{key:"2",label:(0,a.jsx)("a",{href:u,children:(0,a.jsx)("p",{children:"Logout"})})}];return(0,a.jsxs)("nav",{className:"left-0 right-0 top-0 flex justify-between items-center h-12 mb-4",children:[(0,a.jsx)("div",{className:"text-left my-2 absolute top-0 left-0",children:(0,a.jsx)("div",{className:"flex flex-col items-center",children:(0,a.jsx)(o.default,{href:"/",children:(0,a.jsx)("button",{className:"text-gray-800 rounded text-center",children:(0,a.jsx)("img",{src:"/get_image",width:160,height:160,alt:"LiteLLM Brand",className:"mr-2"})})})})}),(0,a.jsxs)("div",{className:"text-right mx-4 my-2 absolute top-0 right-0 flex items-center justify-end space-x-2",children:[n?(0,a.jsx)("div",{style:{padding:"6px",borderRadius:"8px"},children:(0,a.jsx)("a",{href:"https://calendly.com/d/4mp-gd3-k5k/litellm-1-1-onboarding-chat",target:"_blank",style:{fontSize:"14px",textDecoration:"underline"},children:"Get enterprise license"})}):null,(0,a.jsx)("div",{style:{border:"1px solid #391085",padding:"6px",borderRadius:"8px"},children:(0,a.jsx)(d.Z,{menu:{items:h},children:(0,a.jsx)(c.Z,{children:t})})})]})]})},u=s(777),h=s(10384),x=s(46453),p=s(16450),j=s(52273),g=s(26780),Z=s(15595),f=s(6698),_=s(71801),y=s(42440),b=s(42308),v=s(50670),S=s(60620),k=s(80588),w=s(99129),N=s(44839),A=s(88707),I=s(1861);let{Option:C}=v.default;var P=e=>{let{userID:l,team:s,userRole:t,accessToken:n,data:i,setData:o}=e,[d]=S.Z.useForm(),[c,m]=(0,r.useState)(!1),[P,T]=(0,r.useState)(null),[O,E]=(0,r.useState)(null),[R,M]=(0,r.useState)([]),[F,D]=(0,r.useState)([]),L=()=>{m(!1),d.resetFields()},U=()=>{m(!1),T(null),d.resetFields()};(0,r.useEffect)(()=>{(async()=>{try{if(null===l||null===t)return;if(null!==n){let e=(await (0,u.So)(n,l,t)).data.map(e=>e.id);console.log("available_model_names:",e),M(e)}}catch(e){console.error("Error fetching user models:",e)}})()},[n,l,t]);let V=async e=>{try{var s,t,a;let r=null!==(s=null==e?void 0:e.key_alias)&&void 0!==s?s:"",c=null!==(t=null==e?void 0:e.team_id)&&void 0!==t?t:null;if((null!==(a=null==i?void 0:i.filter(e=>e.team_id===c).map(e=>e.key_alias))&&void 0!==a?a:[]).includes(r))throw Error("Key alias ".concat(r," already exists for team with ID ").concat(c,", please provide another key alias"));k.ZP.info("Making API Call"),m(!0);let h=await (0,u.wX)(n,l,e);console.log("key create Response:",h),o(e=>e?[...e,h]:[h]),T(h.key),E(h.soft_budget),k.ZP.success("API Key Created"),d.resetFields(),localStorage.removeItem("userData"+l)}catch(e){console.error("Error creating the key:",e),k.ZP.error("Error creating the key: ".concat(e),20)}};return(0,r.useEffect)(()=>{D(s&&s.models.length>0?s.models.includes("all-proxy-models")?R:s.models:R)},[s,R]),(0,a.jsxs)("div",{children:[(0,a.jsx)(p.Z,{className:"mx-auto",onClick:()=>m(!0),children:"+ Create New Key"}),(0,a.jsx)(w.Z,{title:"Create Key",visible:c,width:800,footer:null,onOk:L,onCancel:U,children:(0,a.jsxs)(S.Z,{form:d,onFinish:V,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(S.Z.Item,{label:"Key Name",name:"key_alias",rules:[{required:!0,message:"Please input a key name"}],help:"required",children:(0,a.jsx)(j.Z,{placeholder:""})}),(0,a.jsx)(S.Z.Item,{label:"Team ID",name:"team_id",hidden:!0,initialValue:s?s.team_id:null,valuePropName:"team_id",className:"mt-8",children:(0,a.jsx)(N.Z,{value:s?s.team_alias:"",disabled:!0})}),(0,a.jsx)(S.Z.Item,{label:"Models",name:"models",rules:[{required:!0,message:"Please select a model"}],help:"required",children:(0,a.jsxs)(v.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},onChange:e=>{e.includes("all-team-models")&&d.setFieldsValue({models:["all-team-models"]})},children:[(0,a.jsx)(C,{value:"all-team-models",children:"All Team Models"},"all-team-models"),F.map(e=>(0,a.jsx)(C,{value:e,children:e},e))]})}),(0,a.jsxs)(g.Z,{className:"mt-20 mb-8",children:[(0,a.jsx)(f.Z,{children:(0,a.jsx)("b",{children:"Optional Settings"})}),(0,a.jsxs)(Z.Z,{children:[(0,a.jsx)(S.Z.Item,{className:"mt-8",label:"Max Budget (USD)",name:"max_budget",help:"Budget cannot exceed team max budget: $".concat((null==s?void 0:s.max_budget)!==null&&(null==s?void 0:s.max_budget)!==void 0?null==s?void 0:s.max_budget:"unlimited"),rules:[{validator:async(e,l)=>{if(l&&s&&null!==s.max_budget&&l>s.max_budget)throw Error("Budget cannot exceed team max budget: $".concat(s.max_budget))}}],children:(0,a.jsx)(A.Z,{step:.01,precision:2,width:200})}),(0,a.jsx)(S.Z.Item,{className:"mt-8",label:"Reset Budget",name:"budget_duration",help:"Team Reset Budget: ".concat((null==s?void 0:s.budget_duration)!==null&&(null==s?void 0:s.budget_duration)!==void 0?null==s?void 0:s.budget_duration:"None"),children:(0,a.jsxs)(v.default,{defaultValue:null,placeholder:"n/a",children:[(0,a.jsx)(v.default.Option,{value:"24h",children:"daily"}),(0,a.jsx)(v.default.Option,{value:"7d",children:"weekly"}),(0,a.jsx)(v.default.Option,{value:"30d",children:"monthly"})]})}),(0,a.jsx)(S.Z.Item,{className:"mt-8",label:"Tokens per minute Limit (TPM)",name:"tpm_limit",help:"TPM cannot exceed team TPM limit: ".concat((null==s?void 0:s.tpm_limit)!==null&&(null==s?void 0:s.tpm_limit)!==void 0?null==s?void 0:s.tpm_limit:"unlimited"),rules:[{validator:async(e,l)=>{if(l&&s&&null!==s.tpm_limit&&l>s.tpm_limit)throw Error("TPM limit cannot exceed team TPM limit: ".concat(s.tpm_limit))}}],children:(0,a.jsx)(A.Z,{step:1,width:400})}),(0,a.jsx)(S.Z.Item,{className:"mt-8",label:"Requests per minute Limit (RPM)",name:"rpm_limit",help:"RPM cannot exceed team RPM limit: ".concat((null==s?void 0:s.rpm_limit)!==null&&(null==s?void 0:s.rpm_limit)!==void 0?null==s?void 0:s.rpm_limit:"unlimited"),rules:[{validator:async(e,l)=>{if(l&&s&&null!==s.rpm_limit&&l>s.rpm_limit)throw Error("RPM limit cannot exceed team RPM limit: ".concat(s.rpm_limit))}}],children:(0,a.jsx)(A.Z,{step:1,width:400})}),(0,a.jsx)(S.Z.Item,{label:"Expire Key (eg: 30s, 30h, 30d)",name:"duration",className:"mt-8",children:(0,a.jsx)(j.Z,{placeholder:""})}),(0,a.jsx)(S.Z.Item,{label:"Metadata",name:"metadata",className:"mt-8",children:(0,a.jsx)(N.Z.TextArea,{rows:4,placeholder:"Enter metadata as JSON"})})]})]})]}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(I.ZP,{htmlType:"submit",children:"Create Key"})})]})}),P&&(0,a.jsx)(w.Z,{visible:c,onOk:L,onCancel:U,footer:null,children:(0,a.jsxs)(x.Z,{numItems:1,className:"gap-2 w-full",children:[(0,a.jsx)(y.Z,{children:"Save your Key"}),(0,a.jsx)(h.Z,{numColSpan:1,children:(0,a.jsxs)("p",{children:["Please save this secret key somewhere safe and accessible. For security reasons, ",(0,a.jsx)("b",{children:"you will not be able to view it again"})," ","through your LiteLLM account. If you lose this secret key, you will need to generate a new one."]})}),(0,a.jsx)(h.Z,{numColSpan:1,children:null!=P?(0,a.jsxs)("div",{children:[(0,a.jsx)(_.Z,{className:"mt-3",children:"API Key:"}),(0,a.jsx)("div",{style:{background:"#f8f8f8",padding:"10px",borderRadius:"5px",marginBottom:"10px"},children:(0,a.jsx)("pre",{style:{wordWrap:"break-word",whiteSpace:"normal"},children:P})}),(0,a.jsx)(b.CopyToClipboard,{text:P,onCopy:()=>{k.ZP.success("API Key copied to clipboard")},children:(0,a.jsx)(p.Z,{className:"mt-3",children:"Copy API Key"})})]}):(0,a.jsx)(_.Z,{children:"Key being created, this might take 30s"})})]})})]})},T=s(9454),O=s(98941),E=s(33393),R=s(5),M=s(13810),F=s(61244),D=s(10827),L=s(3851),U=s(2044),V=s(64167),z=s(74480),q=s(7178),B=s(95093),K=s(27166);let{Option:W}=v.default;var H=e=>{let{userID:l,userRole:s,accessToken:t,selectedTeam:n,data:i,setData:o,teams:d}=e,[c,m]=(0,r.useState)(!1),[h,x]=(0,r.useState)(!1),[j,g]=(0,r.useState)(null),[Z,f]=(0,r.useState)(null),[b,C]=(0,r.useState)(null),[P,H]=(0,r.useState)(""),[G,Y]=(0,r.useState)(!1),[J,X]=(0,r.useState)(!1),[$,Q]=(0,r.useState)(null),[ee,el]=(0,r.useState)([]),es=new Set,[et,en]=(0,r.useState)(es);(0,r.useEffect)(()=>{(async()=>{try{if(null===l)return;if(null!==t&&null!==s){let e=(await (0,u.So)(t,l,s)).data.map(e=>e.id);console.log("available_model_names:",e),el(e)}}catch(e){console.error("Error fetching user models:",e)}})()},[t,l,s]),(0,r.useEffect)(()=>{if(d){let e=new Set;d.forEach((l,s)=>{let t=l.team_id;e.add(t)}),en(e)}},[d]);let ea=e=>{console.log("handleEditClick:",e),null==e.token&&null!==e.token_id&&(e.token=e.token_id),Q(e),Y(!0)},er=async e=>{if(null==t)return;let l=e.token;e.key=l,console.log("handleEditSubmit:",e);let s=await (0,u.Nc)(t,e);console.log("handleEditSubmit: newKeyValues",s),i&&o(i.map(e=>e.token===l?s:e)),k.ZP.success("Key updated successfully"),Y(!1),Q(null)},ei=async e=>{console.log("handleDelete:",e),null==e.token&&null!==e.token_id&&(e.token=e.token_id),null!=i&&(g(e.token),localStorage.removeItem("userData"+l),x(!0))},eo=async()=>{if(null!=j&&null!=i){try{await (0,u.I1)(t,j);let e=i.filter(e=>e.token!==j);o(e)}catch(e){console.error("Error deleting the key:",e)}x(!1),g(null)}};if(null!=i)return console.log("RERENDER TRIGGERED"),(0,a.jsxs)("div",{children:[(0,a.jsxs)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh] mb-4 mt-2",children:[(0,a.jsxs)(D.Z,{className:"mt-5 max-h-[300px] min-h-[300px]",children:[(0,a.jsx)(V.Z,{children:(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(z.Z,{children:"Key Alias"}),(0,a.jsx)(z.Z,{children:"Secret Key"}),(0,a.jsx)(z.Z,{children:"Spend (USD)"}),(0,a.jsx)(z.Z,{children:"Budget (USD)"}),(0,a.jsx)(z.Z,{children:"Models"}),(0,a.jsx)(z.Z,{children:"TPM / RPM Limits"})]})}),(0,a.jsx)(L.Z,{children:i.map(e=>{if(console.log(e),"litellm-dashboard"===e.team_id)return null;if(n){if(console.log("item team id: ".concat(e.team_id,", knownTeamIDs.has(item.team_id): ").concat(et.has(e.team_id),", selectedTeam id: ").concat(n.team_id)),(null!=n.team_id||null===e.team_id||et.has(e.team_id))&&e.team_id!=n.team_id)return null;console.log("item team id: ".concat(e.team_id,", is returned"))}return(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(U.Z,{style:{maxWidth:"2px",whiteSpace:"pre-wrap",overflow:"hidden"},children:null!=e.key_alias?(0,a.jsx)(_.Z,{children:e.key_alias}):(0,a.jsx)(_.Z,{children:"Not Set"})}),(0,a.jsx)(U.Z,{children:(0,a.jsx)(_.Z,{children:e.key_name})}),(0,a.jsx)(U.Z,{children:(0,a.jsx)(_.Z,{children:(()=>{try{return parseFloat(e.spend).toFixed(4)}catch(l){return e.spend}})()})}),(0,a.jsx)(U.Z,{children:null!=e.max_budget?(0,a.jsx)(_.Z,{children:e.max_budget}):(0,a.jsx)(_.Z,{children:"Unlimited"})}),(0,a.jsx)(U.Z,{children:Array.isArray(e.models)?(0,a.jsx)("div",{style:{display:"flex",flexDirection:"column"},children:0===e.models.length?(0,a.jsx)(a.Fragment,{children:n&&n.models&&n.models.length>0?n.models.map((e,l)=>"all-proxy-models"===e?(0,a.jsx)(R.Z,{size:"xs",className:"mb-1",color:"red",children:(0,a.jsx)(_.Z,{children:"All Proxy Models"})},l):"all-team-models"===e?(0,a.jsx)(R.Z,{size:"xs",className:"mb-1",color:"red",children:(0,a.jsx)(_.Z,{children:"All Team Models"})},l):(0,a.jsx)(R.Z,{size:"xs",className:"mb-1",color:"blue",children:(0,a.jsx)(_.Z,{children:e.length>30?"".concat(e.slice(0,30),"..."):e})},l)):(0,a.jsx)(R.Z,{size:"xs",className:"mb-1",color:"blue",children:(0,a.jsx)(_.Z,{children:"all-proxy-models"})})}):e.models.map((e,l)=>"all-proxy-models"===e?(0,a.jsx)(R.Z,{size:"xs",className:"mb-1",color:"red",children:(0,a.jsx)(_.Z,{children:"All Proxy Models"})},l):"all-team-models"===e?(0,a.jsx)(R.Z,{size:"xs",className:"mb-1",color:"red",children:(0,a.jsx)(_.Z,{children:"All Team Models"})},l):(0,a.jsx)(R.Z,{size:"xs",className:"mb-1",color:"blue",children:(0,a.jsx)(_.Z,{children:e.length>30?"".concat(e.slice(0,30),"..."):e})},l))}):null}),(0,a.jsx)(U.Z,{children:(0,a.jsxs)(_.Z,{children:["TPM: ",e.tpm_limit?e.tpm_limit:"Unlimited"," ",(0,a.jsx)("br",{})," RPM:"," ",e.rpm_limit?e.rpm_limit:"Unlimited"]})}),(0,a.jsxs)(U.Z,{children:[(0,a.jsx)(F.Z,{onClick:()=>{Q(e),X(!0)},icon:T.Z,size:"sm"}),(0,a.jsx)(w.Z,{open:J,onCancel:()=>{X(!1),Q(null)},footer:null,width:800,children:$&&(0,a.jsxs)(a.Fragment,{children:[(0,a.jsxs)("div",{className:"grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3 mt-8",children:[(0,a.jsxs)(M.Z,{children:[(0,a.jsx)("p",{className:"text-tremor-default font-medium text-tremor-content dark:text-dark-tremor-content",children:"Spend"}),(0,a.jsx)("div",{className:"mt-2 flex items-baseline space-x-2.5",children:(0,a.jsx)("p",{className:"text-tremor font-semibold text-tremor-content-strong dark:text-dark-tremor-content-strong",children:(()=>{try{return parseFloat($.spend).toFixed(4)}catch(e){return $.spend}})()})})]}),(0,a.jsxs)(M.Z,{children:[(0,a.jsx)("p",{className:"text-tremor-default font-medium text-tremor-content dark:text-dark-tremor-content",children:"Budget"}),(0,a.jsx)("div",{className:"mt-2 flex items-baseline space-x-2.5",children:(0,a.jsx)("p",{className:"text-tremor font-semibold text-tremor-content-strong dark:text-dark-tremor-content-strong",children:null!=$.max_budget?(0,a.jsx)(a.Fragment,{children:$.max_budget}):(0,a.jsx)(a.Fragment,{children:"Unlimited"})})})]},e.name),(0,a.jsxs)(M.Z,{children:[(0,a.jsx)("p",{className:"text-tremor-default font-medium text-tremor-content dark:text-dark-tremor-content",children:"Expires"}),(0,a.jsx)("div",{className:"mt-2 flex items-baseline space-x-2.5",children:(0,a.jsx)("p",{className:"text-tremor-default font-small text-tremor-content-strong dark:text-dark-tremor-content-strong",children:null!=$.expires?(0,a.jsx)(a.Fragment,{children:new Date($.expires).toLocaleString(void 0,{day:"numeric",month:"long",year:"numeric",hour:"numeric",minute:"numeric",second:"numeric"})}):(0,a.jsx)(a.Fragment,{children:"Never"})})})]},e.name)]}),(0,a.jsxs)(M.Z,{className:"my-4",children:[(0,a.jsx)(y.Z,{children:"Token Name"}),(0,a.jsx)(_.Z,{className:"my-1",children:$.key_alias?$.key_alias:$.key_name}),(0,a.jsx)(y.Z,{children:"Token ID"}),(0,a.jsx)(_.Z,{className:"my-1 text-[12px]",children:$.token}),(0,a.jsx)(y.Z,{children:"Metadata"}),(0,a.jsx)(_.Z,{className:"my-1",children:(0,a.jsxs)("pre",{children:[JSON.stringify($.metadata)," "]})})]}),(0,a.jsx)(p.Z,{className:"mx-auto flex items-center",onClick:()=>{X(!1),Q(null)},children:"Close"})]})}),(0,a.jsx)(F.Z,{icon:O.Z,size:"sm",onClick:()=>ea(e)}),(0,a.jsx)(F.Z,{onClick:()=>ei(e),icon:E.Z,size:"sm"})]})]},e.token)})})]}),h&&(0,a.jsx)("div",{className:"fixed z-10 inset-0 overflow-y-auto",children:(0,a.jsxs)("div",{className:"flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0",children:[(0,a.jsx)("div",{className:"fixed inset-0 transition-opacity","aria-hidden":"true",children:(0,a.jsx)("div",{className:"absolute inset-0 bg-gray-500 opacity-75"})}),(0,a.jsx)("span",{className:"hidden sm:inline-block sm:align-middle sm:h-screen","aria-hidden":"true",children:"​"}),(0,a.jsxs)("div",{className:"inline-block align-bottom bg-white rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full",children:[(0,a.jsx)("div",{className:"bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4",children:(0,a.jsx)("div",{className:"sm:flex sm:items-start",children:(0,a.jsxs)("div",{className:"mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left",children:[(0,a.jsx)("h3",{className:"text-lg leading-6 font-medium text-gray-900",children:"Delete Key"}),(0,a.jsx)("div",{className:"mt-2",children:(0,a.jsx)("p",{className:"text-sm text-gray-500",children:"Are you sure you want to delete this key ?"})})]})})}),(0,a.jsxs)("div",{className:"bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse",children:[(0,a.jsx)(p.Z,{onClick:eo,color:"red",className:"ml-2",children:"Delete"}),(0,a.jsx)(p.Z,{onClick:()=>{x(!1),g(null)},children:"Cancel"})]})]})]})})]}),$&&(0,a.jsx)(e=>{let{visible:l,onCancel:s,token:t,onSubmit:i}=e,[o]=S.Z.useForm(),[c,m]=(0,r.useState)(n),[u,h]=(0,r.useState)([]),[x,p]=(0,r.useState)(!1);return(0,a.jsx)(w.Z,{title:"Edit Key",visible:l,width:800,footer:null,onOk:()=>{o.validateFields().then(e=>{o.resetFields()}).catch(e=>{console.error("Validation failed:",e)})},onCancel:s,children:(0,a.jsxs)(S.Z,{form:o,onFinish:er,initialValues:t,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(S.Z.Item,{label:"Key Name",name:"key_alias",rules:[{required:!0,message:"Please input a key name"}],help:"required",children:(0,a.jsx)(N.Z,{})}),(0,a.jsx)(S.Z.Item,{label:"Models",name:"models",rules:[{validator:(e,l)=>{let s=l.filter(e=>!c.models.includes(e)&&"all-team-models"!==e&&"all-proxy-models"!==e&&!c.models.includes("all-proxy-models"));return(console.log("errorModels: ".concat(s)),s.length>0)?Promise.reject("Some models are not part of the new team's models - ".concat(s,"Team models: ").concat(c.models)):Promise.resolve()}}],children:(0,a.jsxs)(v.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:[(0,a.jsx)(W,{value:"all-team-models",children:"All Team Models"},"all-team-models"),c&&c.models?c.models.includes("all-proxy-models")?ee.filter(e=>"all-proxy-models"!==e).map(e=>(0,a.jsx)(W,{value:e,children:e},e)):c.models.map(e=>(0,a.jsx)(W,{value:e,children:e},e)):ee.map(e=>(0,a.jsx)(W,{value:e,children:e},e))]})}),(0,a.jsx)(S.Z.Item,{className:"mt-8",label:"Max Budget (USD)",name:"max_budget",help:"Budget cannot exceed team max budget: ".concat((null==c?void 0:c.max_budget)!==null&&(null==c?void 0:c.max_budget)!==void 0?null==c?void 0:c.max_budget:"unlimited"),rules:[{validator:async(e,l)=>{if(l&&c&&null!==c.max_budget&&l>c.max_budget)throw console.log("keyTeam.max_budget: ".concat(c.max_budget)),Error("Budget cannot exceed team max budget: $".concat(c.max_budget))}}],children:(0,a.jsx)(A.Z,{step:.01,precision:2,width:200})}),(0,a.jsx)(S.Z.Item,{label:"token",name:"token",hidden:!0}),(0,a.jsx)(S.Z.Item,{label:"Team",name:"team_id",help:"the team this key belongs to",children:(0,a.jsx)(B.Z,{value:t.team_alias,children:null==d?void 0:d.map((e,l)=>(0,a.jsx)(K.Z,{value:e.team_id,onClick:()=>m(e),children:e.team_alias},l))})})]}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(I.ZP,{htmlType:"submit",children:"Edit Key"})})]})})},{visible:G,onCancel:()=>{Y(!1),Q(null)},token:$,onSubmit:er})]})},G=e=>{let{userID:l,userRole:s,accessToken:t,userSpend:n,selectedTeam:i}=e;console.log("userSpend: ".concat(n));let[o,d]=(0,r.useState)(null!==n?n:0),[c,m]=(0,r.useState)(0),[h,x]=(0,r.useState)([]);(0,r.useEffect)(()=>{let e=async()=>{if(t&&l&&s&&"Admin"===s&&null==n)try{let e=await (0,u.Qy)(t);e&&(e.spend?d(e.spend):d(0),e.max_budget?m(e.max_budget):m(0))}catch(e){console.error("Error fetching global spend data:",e)}};(async()=>{try{if(null===l||null===s)return;if(null!==t){let e=(await (0,u.So)(t,l,s)).data.map(e=>e.id);console.log("available_model_names:",e),x(e)}}catch(e){console.error("Error fetching user models:",e)}})(),e()},[s,t,l]),(0,r.useEffect)(()=>{null!==n&&d(n)},[n]);let p=[];i&&i.models&&(p=i.models),p&&p.includes("all-proxy-models")?(console.log("user models:",h),p=h):p&&p.includes("all-team-models")?p=i.models:p&&0===p.length&&(p=h);let j=void 0!==o?o.toFixed(4):null;return console.log("spend in view user spend: ".concat(o)),(0,a.jsx)("div",{className:"flex items-center",children:(0,a.jsxs)("div",{children:[(0,a.jsxs)("p",{className:"text-tremor-default text-tremor-content dark:text-dark-tremor-content",children:["Total Spend"," "]}),(0,a.jsxs)("p",{className:"text-2xl text-tremor-content-strong dark:text-dark-tremor-content-strong font-semibold",children:["$",j]})]})})},Y=e=>{let{userID:l,userRole:s,selectedTeam:t,accessToken:n}=e,[i,o]=(0,r.useState)([]);(0,r.useEffect)(()=>{(async()=>{try{if(null===l||null===s)return;if(null!==n){let e=(await (0,u.So)(n,l,s)).data.map(e=>e.id);console.log("available_model_names:",e),o(e)}}catch(e){console.error("Error fetching user models:",e)}})()},[n,l,s]);let d=[];return t&&t.models&&(d=t.models),d&&d.includes("all-proxy-models")&&(console.log("user models:",i),d=i),(0,a.jsx)(a.Fragment,{children:(0,a.jsx)("div",{className:"mb-5",children:(0,a.jsx)("p",{className:"text-3xl text-tremor-content-strong dark:text-dark-tremor-content-strong font-semibold",children:null==t?void 0:t.team_alias})})})},J=e=>{let l,{teams:s,setSelectedTeam:t,userRole:n}=e,i={models:[],team_id:null,team_alias:"Default Team"},[o,d]=(0,r.useState)(i);return(l="App User"===n?s:s?[...s,i]:[i],"App User"===n)?null:(0,a.jsxs)("div",{className:"mt-5 mb-5",children:[(0,a.jsx)(y.Z,{children:"Select Team"}),(0,a.jsx)(_.Z,{children:"If you belong to multiple teams, this setting controls which team is used by default when creating new API Keys."}),(0,a.jsxs)(_.Z,{className:"mt-3 mb-3",children:[(0,a.jsx)("b",{children:"Default Team:"})," If no team_id is set for a key, it will be grouped under here."]}),l&&l.length>0?(0,a.jsx)(B.Z,{defaultValue:"0",children:l.map((e,l)=>(0,a.jsx)(K.Z,{value:String(l),onClick:()=>t(e),children:e.team_alias},l))}):(0,a.jsxs)(_.Z,{children:["No team created. ",(0,a.jsx)("b",{children:"Defaulting to personal account."})]})]})},X=s(37963),$=s(97482);console.log("isLocal:",!1);var Q=e=>{let{userID:l,userRole:s,teams:t,keys:n,setUserRole:o,userEmail:d,setUserEmail:c,setTeams:m,setKeys:p,setProxySettings:j,proxySettings:g}=e,[Z,f]=(0,r.useState)(null);(0,i.useSearchParams)().get("viewSpend"),(0,i.useRouter)();let _=function(e){console.log("COOKIES",document.cookie);let l=document.cookie.split("; ").find(l=>l.startsWith(e+"="));return l?l.split("=")[1]:null}("token"),[y,b]=(0,r.useState)(null),[v,S]=(0,r.useState)(null),[k,w]=(0,r.useState)([]),N={models:[],team_alias:"Default Team",team_id:null},[A,I]=(0,r.useState)(t?t[0]:N);if(window.addEventListener("beforeunload",function(){sessionStorage.clear()}),(0,r.useEffect)(()=>{if(_){let e=(0,X.o)(_);if(e){if(console.log("Decoded token:",e),console.log("Decoded key:",e.key),b(e.key),e.user_role){let l=function(e){if(!e)return"Undefined Role";switch(console.log("Received user role: ".concat(e)),e.toLowerCase()){case"app_owner":case"demo_app_owner":return"App Owner";case"app_admin":case"proxy_admin":return"Admin";case"proxy_admin_viewer":return"Admin Viewer";case"app_user":return"App User";case"internal_user":return"Internal User";case"internal_user_viewer":return"Internal Viewer";default:return"Unknown Role"}}(e.user_role);console.log("Decoded user_role:",l),o(l)}else console.log("User role not defined");e.user_email?c(e.user_email):console.log("User Email is not set ".concat(e))}}if(l&&y&&s&&!n&&!Z){let e=sessionStorage.getItem("userModels"+l);e?w(JSON.parse(e)):(async()=>{try{let e=await (0,u.Dj)(y);j(e);let t=await (0,u.Br)(y,l,s,!1,null,null);if(console.log("received teams in user dashboard: ".concat(Object.keys(t),"; team values: ").concat(Object.entries(t.teams))),"Admin"==s){let e=await (0,u.Qy)(y);f(e),console.log("globalSpend:",e)}else f(t.user_info);p(t.keys),m(t.teams);let n=[...t.teams];n.length>0?(console.log("response['teams']: ".concat(n)),I(n[0])):I(N),sessionStorage.setItem("userData"+l,JSON.stringify(t.keys)),sessionStorage.setItem("userSpendData"+l,JSON.stringify(t.user_info));let a=(await (0,u.So)(y,l,s)).data.map(e=>e.id);console.log("available_model_names:",a),w(a),console.log("userModels:",k),sessionStorage.setItem("userModels"+l,JSON.stringify(a))}catch(e){console.error("There was an error fetching the data",e)}})()}},[l,_,y,n,s]),(0,r.useEffect)(()=>{if(null!==n&&null!=A&&null!==A.team_id){let e=0;for(let l of n)A.hasOwnProperty("team_id")&&null!==l.team_id&&l.team_id===A.team_id&&(e+=l.spend);S(e)}else if(null!==n){let e=0;for(let l of n)e+=l.spend;S(e)}},[A]),null==l||null==_){let e="/sso/key/generate";return console.log("Full URL:",e),window.location.href=e,null}if(null==y)return null;if(null==s&&o("App Owner"),s&&"Admin Viewer"==s){let{Title:e,Paragraph:l}=$.default;return(0,a.jsxs)("div",{children:[(0,a.jsx)(e,{level:1,children:"Access Denied"}),(0,a.jsx)(l,{children:"Ask your proxy admin for access to create keys"})]})}return console.log("inside user dashboard, selected team",A),(0,a.jsx)("div",{className:"w-full mx-4",children:(0,a.jsx)(x.Z,{numItems:1,className:"gap-2 p-8 h-[75vh] w-full mt-2",children:(0,a.jsxs)(h.Z,{numColSpan:1,children:[(0,a.jsx)(Y,{userID:l,userRole:s,selectedTeam:A||null,accessToken:y}),(0,a.jsx)(G,{userID:l,userRole:s,accessToken:y,userSpend:v,selectedTeam:A||null}),(0,a.jsx)(H,{userID:l,userRole:s,accessToken:y,selectedTeam:A||null,data:n,setData:p,teams:t}),(0,a.jsx)(P,{userID:l,team:A||null,userRole:s,accessToken:y,data:n,setData:p},A?A.team_id:null),(0,a.jsx)(J,{teams:t,setSelectedTeam:I,userRole:s})]})})})},ee=s(49167),el=s(35087),es=s(92836),et=s(26734),en=s(41608),ea=s(32126),er=s(23682),ei=s(47047),eo=s(76628),ed=s(25707),ec=s(44041),em=s(6180),eu=s(28683),eh=s(38302),ex=s(66242),ep=s(78578),ej=s(63954),eg=s(34658),eZ=e=>{let{modelID:l,accessToken:s}=e,[t,n]=(0,r.useState)(!1),i=async()=>{try{k.ZP.info("Making API Call"),n(!0);let e=await (0,u.Og)(s,l);console.log("model delete Response:",e),k.ZP.success("Model ".concat(l," deleted successfully")),n(!1)}catch(e){console.error("Error deleting the model:",e)}};return(0,a.jsxs)("div",{children:[(0,a.jsx)(F.Z,{onClick:()=>n(!0),icon:E.Z,size:"sm"}),(0,a.jsx)(w.Z,{open:t,onOk:i,okType:"danger",onCancel:()=>n(!1),children:(0,a.jsxs)(x.Z,{numItems:1,className:"gap-2 w-full",children:[(0,a.jsx)(y.Z,{children:"Delete Model"}),(0,a.jsx)(h.Z,{numColSpan:1,children:(0,a.jsx)("p",{children:"Are you sure you want to delete this model? This action is irreversible."})}),(0,a.jsx)(h.Z,{numColSpan:1,children:(0,a.jsxs)("p",{children:["Model ID: ",(0,a.jsx)("b",{children:l})]})})]})})]})},ef=s(97766),e_=s(46495),ey=s(18190),eb=s(91118),ev=e=>{let{modelMetrics:l,modelMetricsCategories:s,customTooltip:t,premiumUser:n}=e;return n?(0,a.jsx)(eb.Z,{title:"Time to First token (s)",className:"h-72",data:l,index:"date",showLegend:!1,categories:s,colors:["indigo","rose"],connectNulls:!0,customTooltip:t}):(0,a.jsxs)("div",{children:[(0,a.jsx)(ey.Z,{title:"✨ Enterprise Feature",color:"teal",className:"mt-2 mb-4",children:"Enterprise features are available for users with a specific license, please contact LiteLLM to unlock this limitation."}),(0,a.jsx)(p.Z,{variant:"primary",children:(0,a.jsx)("a",{href:"https://forms.gle/W3U4PZpJGFHWtHyA9",target:"_blank",children:"Get in touch"})})]})},eS=e=>{let{fields:l,selectedProvider:s}=e;return 0===l.length?null:(0,a.jsx)(a.Fragment,{children:l.map(e=>(0,a.jsx)(S.Z.Item,{rules:[{required:!0,message:"Required"}],label:e.field_name.replace(/_/g," ").replace(/\b\w/g,e=>e.toUpperCase()),name:e.field_name,tooltip:e.field_description,className:"mb-2",children:(0,a.jsx)(j.Z,{placeholder:e.field_value,type:"password"})},e.field_name))})},ek=s(67951);let{Title:ew,Link:eN}=$.default;(t=n||(n={})).OpenAI="OpenAI",t.Azure="Azure",t.Azure_AI_Studio="Azure AI Studio",t.Anthropic="Anthropic",t.Google_AI_Studio="Google AI Studio",t.Bedrock="Amazon Bedrock",t.OpenAI_Compatible="OpenAI-Compatible Endpoints (Groq, Together AI, Mistral AI, etc.)",t.Vertex_AI="Vertex AI (Anthropic, Gemini, etc.)",t.Databricks="Databricks",t.Ollama="Ollama";let eA={OpenAI:"openai",Azure:"azure",Azure_AI_Studio:"azure_ai",Anthropic:"anthropic",Google_AI_Studio:"gemini",Bedrock:"bedrock",OpenAI_Compatible:"openai",Vertex_AI:"vertex_ai",Databricks:"databricks",Ollama:"ollama"},eI={"BadRequestError (400)":"BadRequestErrorRetries","AuthenticationError (401)":"AuthenticationErrorRetries","TimeoutError (408)":"TimeoutErrorRetries","RateLimitError (429)":"RateLimitErrorRetries","ContentPolicyViolationError (400)":"ContentPolicyViolationErrorRetries","InternalServerError (500)":"InternalServerErrorRetries"},eC=async(e,l,s)=>{try{let t=Array.isArray(e.model)?e.model:[e.model];console.log("received deployments: ".concat(t)),console.log("received type of deployments: ".concat(typeof t)),t.forEach(async s=>{console.log("litellm_model: ".concat(s));let t={},n={};t.model=s;let a="";for(let[l,s]of(console.log("formValues add deployment:",e),Object.entries(e)))if(""!==s){if("model_name"==l)a+=s;else if("custom_llm_provider"==l)continue;else if("model"==l)continue;else if("base_model"===l)n[l]=s;else if("litellm_extra_params"==l){console.log("litellm_extra_params:",s);let e={};if(s&&void 0!=s){try{e=JSON.parse(s)}catch(e){throw k.ZP.error("Failed to parse LiteLLM Extra Params: "+e,10),Error("Failed to parse litellm_extra_params: "+e)}for(let[l,s]of Object.entries(e))t[l]=s}}else t[l]=s}let r={model_name:a,litellm_params:t,model_info:n},i=await (0,u.kK)(l,r);console.log("response for model create call: ".concat(i.data))}),s.resetFields()}catch(e){k.ZP.error("Failed to create model: "+e,10)}};var eP=e=>{var l,s,t;let i,{accessToken:o,token:d,userRole:c,userID:m,modelData:h={data:[]},keys:g,setModelData:Z,premiumUser:f}=e,[b,v]=(0,r.useState)([]),[N]=S.Z.useForm(),[C,P]=(0,r.useState)(null),[E,W]=(0,r.useState)(""),[H,G]=(0,r.useState)([]),Y=Object.values(n).filter(e=>isNaN(Number(e))),[J,X]=(0,r.useState)([]),[Q,ey]=(0,r.useState)("OpenAI"),[eb,eP]=(0,r.useState)(""),[eT,eO]=(0,r.useState)(!1),[eE,eR]=(0,r.useState)(!1),[eM,eF]=(0,r.useState)(null),[eD,eL]=(0,r.useState)([]),[eU,eV]=(0,r.useState)(null),[ez,eq]=(0,r.useState)([]),[eB,eK]=(0,r.useState)([]),[eW,eH]=(0,r.useState)([]),[eG,eY]=(0,r.useState)([]),[eJ,eX]=(0,r.useState)([]),[e$,eQ]=(0,r.useState)([]),[e0,e1]=(0,r.useState)([]),[e2,e4]=(0,r.useState)([]),[e5,e8]=(0,r.useState)([]),[e3,e6]=(0,r.useState)({from:new Date(Date.now()-6048e5),to:new Date}),[e9,e7]=(0,r.useState)(null),[le,ll]=(0,r.useState)(0),[ls,lt]=(0,r.useState)({}),[ln,la]=(0,r.useState)([]),[lr,li]=(0,r.useState)(!1),[lo,ld]=(0,r.useState)(null),[lc,lm]=(0,r.useState)(null),[lu,lh]=(0,r.useState)([]);(0,r.useEffect)(()=>{lb(eU,e3.from,e3.to)},[lo,lc]);let lx=e=>{eF(e),eO(!0)},lp=e=>{eF(e),eR(!0)},lj=async e=>{if(console.log("handleEditSubmit:",e),null==o)return;let l={},s=null;for(let[t,n]of Object.entries(e))"model_id"!==t?l[t]=n:s=n;let t={litellm_params:l,model_info:{id:s}};console.log("handleEditSubmit payload:",t);try{await (0,u.um)(o,t),k.ZP.success("Model updated successfully, restart server to see updates"),eO(!1),eF(null)}catch(e){console.log("Error occurred")}},lg=()=>{W(new Date().toLocaleString())},lZ=async()=>{if(!o){console.error("Access token is missing");return}console.log("new modelGroupRetryPolicy:",e9);try{await (0,u.K_)(o,{router_settings:{model_group_retry_policy:e9}}),k.ZP.success("Retry settings saved successfully")}catch(e){console.error("Failed to save retry settings:",e),k.ZP.error("Failed to save retry settings")}};if((0,r.useEffect)(()=>{if(!o||!d||!c||!m)return;let e=async()=>{try{var e,l,s,t,n,a,r,i,d,h,x,p;let j=await (0,u.hy)(o);X(j);let g=await (0,u.AZ)(o,m,c);console.log("Model data response:",g.data),Z(g);let f=new Set;for(let e=0;e0&&(y=_[_.length-1],console.log("_initial_model_group:",y),eV(y)),console.log("selectedModelGroup:",eU);let b=await (0,u.o6)(o,m,c,y,null===(e=e3.from)||void 0===e?void 0:e.toISOString(),null===(l=e3.to)||void 0===l?void 0:l.toISOString(),null==lo?void 0:lo.token,lc);console.log("Model metrics response:",b),eK(b.data),eH(b.all_api_bases);let v=await (0,u.Rg)(o,y,null===(s=e3.from)||void 0===s?void 0:s.toISOString(),null===(t=e3.to)||void 0===t?void 0:t.toISOString());eY(v.data),eX(v.all_api_bases);let S=await (0,u.N8)(o,m,c,y,null===(n=e3.from)||void 0===n?void 0:n.toISOString(),null===(a=e3.to)||void 0===a?void 0:a.toISOString(),null==lo?void 0:lo.token,lc);console.log("Model exceptions response:",S),eQ(S.data),e1(S.exception_types);let k=await (0,u.fP)(o,m,c,y,null===(r=e3.from)||void 0===r?void 0:r.toISOString(),null===(i=e3.to)||void 0===i?void 0:i.toISOString(),null==lo?void 0:lo.token,lc),w=await (0,u.n$)(o,null===(d=e3.from)||void 0===d?void 0:d.toISOString().split("T")[0],null===(h=e3.to)||void 0===h?void 0:h.toISOString().split("T")[0],y);lt(w);let N=await (0,u.v9)(o,null===(x=e3.from)||void 0===x?void 0:x.toISOString().split("T")[0],null===(p=e3.to)||void 0===p?void 0:p.toISOString().split("T")[0],y);la(N),console.log("dailyExceptions:",w),console.log("dailyExceptionsPerDeplyment:",N),console.log("slowResponses:",k),e8(k);let A=await (0,u.j2)(o);lh(null==A?void 0:A.end_users);let I=(await (0,u.BL)(o,m,c)).router_settings;console.log("routerSettingsInfo:",I);let C=I.model_group_retry_policy,P=I.num_retries;console.log("model_group_retry_policy:",C),console.log("default_retries:",P),e7(C),ll(P)}catch(e){console.error("There was an error fetching the model data",e)}};o&&d&&c&&m&&e();let l=async()=>{let e=await (0,u.qm)();console.log("received model cost map data: ".concat(Object.keys(e))),P(e)};null==C&&l(),lg()},[o,d,c,m,C,E]),!h||!o||!d||!c||!m)return(0,a.jsx)("div",{children:"Loading..."});let lf=[];for(let e=0;e(console.log("GET PROVIDER CALLED! - ".concat(C)),null!=C&&"object"==typeof C&&e in C)?C[e].litellm_provider:"openai";if(n){let e=n.split("/"),l=e[0];r=1===e.length?u(n):l}else r="openai";a&&(i=null==a?void 0:a.input_cost_per_token,o=null==a?void 0:a.output_cost_per_token,d=null==a?void 0:a.max_tokens,c=null==a?void 0:a.max_input_tokens),(null==t?void 0:t.litellm_params)&&(m=Object.fromEntries(Object.entries(null==t?void 0:t.litellm_params).filter(e=>{let[l]=e;return"model"!==l&&"api_base"!==l}))),h.data[e].provider=r,h.data[e].input_cost=i,h.data[e].output_cost=o,h.data[e].input_cost&&(h.data[e].input_cost=(1e6*Number(h.data[e].input_cost)).toFixed(2)),h.data[e].output_cost&&(h.data[e].output_cost=(1e6*Number(h.data[e].output_cost)).toFixed(2)),h.data[e].max_tokens=d,h.data[e].max_input_tokens=c,h.data[e].api_base=null==t?void 0:null===(s=t.litellm_params)||void 0===s?void 0:s.api_base,h.data[e].cleanedLitellmParams=m,lf.push(t.model_name),console.log(h.data[e])}if(c&&"Admin Viewer"==c){let{Title:e,Paragraph:l}=$.default;return(0,a.jsxs)("div",{children:[(0,a.jsx)(e,{level:1,children:"Access Denied"}),(0,a.jsx)(l,{children:"Ask your proxy admin for access to view all models"})]})}let l_=e=>{console.log("received provider string: ".concat(e));let l=Object.keys(n).find(l=>n[l]===e);if(l){let e=eA[l];console.log("mappingResult: ".concat(e));let s=[];"object"==typeof C&&Object.entries(C).forEach(l=>{let[t,n]=l;null!==n&&"object"==typeof n&&"litellm_provider"in n&&(n.litellm_provider===e||n.litellm_provider.includes(e))&&s.push(t)}),G(s),console.log("providerModels: ".concat(H))}},ly=async()=>{try{k.ZP.info("Running health check..."),eP("");let e=await (0,u.EY)(o);eP(e)}catch(e){console.error("Error running health check:",e),eP("Error running health check")}},lb=async(e,l,s)=>{if(console.log("Updating model metrics for group:",e),!o||!m||!c||!l||!s)return;console.log("inside updateModelMetrics - startTime:",l,"endTime:",s),eV(e);let t=null==lo?void 0:lo.token;void 0===t&&(t=null);let n=lc;void 0===n&&(n=null),l.setHours(0),l.setMinutes(0),l.setSeconds(0),s.setHours(23),s.setMinutes(59),s.setSeconds(59);try{let a=await (0,u.o6)(o,m,c,e,l.toISOString(),s.toISOString(),t,n);console.log("Model metrics response:",a),eK(a.data),eH(a.all_api_bases);let r=await (0,u.Rg)(o,e,l.toISOString(),s.toISOString());eY(r.data),eX(r.all_api_bases);let i=await (0,u.N8)(o,m,c,e,l.toISOString(),s.toISOString(),t,n);console.log("Model exceptions response:",i),eQ(i.data),e1(i.exception_types);let d=await (0,u.fP)(o,m,c,e,l.toISOString(),s.toISOString(),t,n);if(console.log("slowResponses:",d),e8(d),e){let t=await (0,u.n$)(o,null==l?void 0:l.toISOString().split("T")[0],null==s?void 0:s.toISOString().split("T")[0],e);lt(t);let n=await (0,u.v9)(o,null==l?void 0:l.toISOString().split("T")[0],null==s?void 0:s.toISOString().split("T")[0],e);la(n)}}catch(e){console.error("Failed to fetch model metrics",e)}},lv=(0,a.jsxs)("div",{children:[(0,a.jsx)(_.Z,{className:"mb-1",children:"Select API Key Name"}),f?(0,a.jsxs)("div",{children:[(0,a.jsxs)(B.Z,{defaultValue:"all-keys",children:[(0,a.jsx)(K.Z,{value:"all-keys",onClick:()=>{ld(null)},children:"All Keys"},"all-keys"),null==g?void 0:g.map((e,l)=>e&&null!==e.key_alias&&e.key_alias.length>0?(0,a.jsx)(K.Z,{value:String(l),onClick:()=>{ld(e)},children:e.key_alias},l):null)]}),(0,a.jsx)(_.Z,{className:"mt-1",children:"Select Customer Name"}),(0,a.jsxs)(B.Z,{defaultValue:"all-customers",children:[(0,a.jsx)(K.Z,{value:"all-customers",onClick:()=>{lm(null)},children:"All Customers"},"all-customers"),null==lu?void 0:lu.map((e,l)=>(0,a.jsx)(K.Z,{value:e,onClick:()=>{lm(e)},children:e},l))]})]}):(0,a.jsxs)("div",{children:[(0,a.jsxs)(B.Z,{defaultValue:"all-keys",children:[(0,a.jsx)(K.Z,{value:"all-keys",onClick:()=>{ld(null)},children:"All Keys"},"all-keys"),null==g?void 0:g.map((e,l)=>e&&null!==e.key_alias&&e.key_alias.length>0?(0,a.jsxs)(K.Z,{value:String(l),disabled:!0,onClick:()=>{ld(e)},children:["✨ ",e.key_alias," (Enterprise only Feature)"]},l):null)]}),(0,a.jsx)(_.Z,{className:"mt-1",children:"Select Customer Name"}),(0,a.jsxs)(B.Z,{defaultValue:"all-customers",children:[(0,a.jsx)(K.Z,{value:"all-customers",onClick:()=>{lm(null)},children:"All Customers"},"all-customers"),null==lu?void 0:lu.map((e,l)=>(0,a.jsxs)(K.Z,{value:e,disabled:!0,onClick:()=>{lm(e)},children:["✨ ",e," (Enterprise only Feature)"]},l))]})]})]}),lS=e=>{var l,s;let{payload:t,active:n}=e;if(!n||!t)return null;let r=null===(s=t[0])||void 0===s?void 0:null===(l=s.payload)||void 0===l?void 0:l.date,i=t.sort((e,l)=>l.value-e.value);if(i.length>5){let e=i.length-5;(i=i.slice(0,5)).push({dataKey:"".concat(e," other deployments"),value:t.slice(5).reduce((e,l)=>e+l.value,0),color:"gray"})}return(0,a.jsxs)("div",{className:"w-150 rounded-tremor-default border border-tremor-border bg-tremor-background p-2 text-tremor-default shadow-tremor-dropdown",children:[r&&(0,a.jsxs)("p",{className:"text-tremor-content-emphasis mb-2",children:["Date: ",r]}),i.map((e,l)=>{let s=parseFloat(e.value.toFixed(5)),t=0===s&&e.value>0?"<0.00001":s.toFixed(5);return(0,a.jsxs)("div",{className:"flex justify-between",children:[(0,a.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,a.jsx)("div",{className:"w-2 h-2 mt-1 rounded-full bg-".concat(e.color,"-500")}),(0,a.jsx)("p",{className:"text-tremor-content",children:e.dataKey})]}),(0,a.jsx)("p",{className:"font-medium text-tremor-content-emphasis text-righ ml-2",children:t})]},l)})]})};console.log("selectedProvider: ".concat(Q)),console.log("providerModels.length: ".concat(H.length));let lk=Object.keys(n).find(e=>n[e]===Q);return lk&&(i=J.find(e=>e.name===eA[lk])),(0,a.jsx)("div",{style:{width:"100%",height:"100%"},children:(0,a.jsxs)(et.Z,{className:"gap-2 p-8 h-[75vh] w-full mt-2",children:[(0,a.jsxs)(en.Z,{className:"flex justify-between mt-2 w-full items-center",children:[(0,a.jsxs)("div",{className:"flex",children:[(0,a.jsx)(es.Z,{children:"All Models"}),(0,a.jsx)(es.Z,{children:"Add Model"}),(0,a.jsx)(es.Z,{children:(0,a.jsx)("pre",{children:"/health Models"})}),(0,a.jsx)(es.Z,{children:"Model Analytics"}),(0,a.jsx)(es.Z,{children:"Model Retry Settings"})]}),(0,a.jsxs)("div",{className:"flex items-center space-x-2",children:[E&&(0,a.jsxs)(_.Z,{children:["Last Refreshed: ",E]}),(0,a.jsx)(F.Z,{icon:ej.Z,variant:"shadow",size:"xs",className:"self-center",onClick:lg})]})]}),(0,a.jsxs)(er.Z,{children:[(0,a.jsxs)(ea.Z,{children:[(0,a.jsxs)(x.Z,{children:[(0,a.jsxs)("div",{className:"flex items-center",children:[(0,a.jsx)(_.Z,{children:"Filter by Public Model Name"}),(0,a.jsxs)(B.Z,{className:"mb-4 mt-2 ml-2 w-50",defaultValue:eU||eD[0],onValueChange:e=>eV("all"===e?"all":e),value:eU||eD[0],children:[(0,a.jsx)(K.Z,{value:"all",children:"All Models"}),eD.map((e,l)=>(0,a.jsx)(K.Z,{value:e,onClick:()=>eV(e),children:e},l))]})]}),(0,a.jsx)(M.Z,{children:(0,a.jsxs)(D.Z,{style:{maxWidth:"1500px",width:"100%"},children:[(0,a.jsx)(V.Z,{children:(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(z.Z,{style:{maxWidth:"150px",whiteSpace:"normal",wordBreak:"break-word",fontSize:"11px"},children:"Public Model Name"}),(0,a.jsx)(z.Z,{style:{maxWidth:"100px",whiteSpace:"normal",wordBreak:"break-word",fontSize:"11px"},children:"Provider"}),"Admin"===c&&(0,a.jsx)(z.Z,{style:{maxWidth:"150px",whiteSpace:"normal",wordBreak:"break-word",fontSize:"11px"},children:"API Base"}),(0,a.jsxs)(z.Z,{style:{maxWidth:"85px",whiteSpace:"normal",wordBreak:"break-word",fontSize:"11px"},children:["Input Price"," ",(0,a.jsx)("p",{style:{fontSize:"10px",color:"gray"},children:"/1M Tokens ($)"})]}),(0,a.jsxs)(z.Z,{style:{maxWidth:"85px",whiteSpace:"normal",wordBreak:"break-word",fontSize:"11px"},children:["Output Price"," ",(0,a.jsx)("p",{style:{fontSize:"10px",color:"gray"},children:"/1M Tokens ($)"})]}),(0,a.jsx)(z.Z,{style:{maxWidth:"100px",whiteSpace:"normal",wordBreak:"break-word",fontSize:"11px"},children:f?"Created At":(0,a.jsxs)("a",{href:"https://forms.gle/W3U4PZpJGFHWtHyA9",target:"_blank",style:{color:"#72bcd4"},children:[" ","✨ Created At"]})}),(0,a.jsx)(z.Z,{style:{maxWidth:"100px",whiteSpace:"normal",wordBreak:"break-word",fontSize:"11px"},children:f?"Created By":(0,a.jsxs)("a",{href:"https://forms.gle/W3U4PZpJGFHWtHyA9",target:"_blank",style:{color:"#72bcd4"},children:[" ","✨ Created By"]})}),(0,a.jsx)(z.Z,{style:{maxWidth:"50px",whiteSpace:"normal",wordBreak:"break-word",fontSize:"11px"},children:"Status"}),(0,a.jsx)(z.Z,{})]})}),(0,a.jsx)(L.Z,{children:h.data.filter(e=>"all"===eU||e.model_name===eU||null==eU||""===eU).map((e,l)=>{var s;return(0,a.jsxs)(q.Z,{style:{maxHeight:"1px",minHeight:"1px"},children:[(0,a.jsx)(U.Z,{style:{maxWidth:"100px",whiteSpace:"normal",wordBreak:"break-word"},children:(0,a.jsx)("p",{className:"text-xs",children:e.model_name||"-"})}),(0,a.jsx)(U.Z,{style:{maxWidth:"100px",whiteSpace:"normal",wordBreak:"break-word"},children:(0,a.jsx)("p",{className:"text-xs",children:e.provider||"-"})}),"Admin"===c&&(0,a.jsx)(U.Z,{style:{maxWidth:"150px",whiteSpace:"normal",wordBreak:"break-word"},children:(0,a.jsx)(em.Z,{title:e&&e.api_base,children:(0,a.jsx)("pre",{style:{maxWidth:"150px",whiteSpace:"normal",wordBreak:"break-word"},className:"text-xs",title:e&&e.api_base?e.api_base:"",children:e&&e.api_base?e.api_base.slice(0,20):"-"})})}),(0,a.jsx)(U.Z,{style:{maxWidth:"80px",whiteSpace:"normal",wordBreak:"break-word"},children:(0,a.jsx)("pre",{className:"text-xs",children:e.input_cost?e.input_cost:null!=e.litellm_params.input_cost_per_token&&void 0!=e.litellm_params.input_cost_per_token?(1e6*Number(e.litellm_params.input_cost_per_token)).toFixed(2):null})}),(0,a.jsx)(U.Z,{style:{maxWidth:"80px",whiteSpace:"normal",wordBreak:"break-word"},children:(0,a.jsx)("pre",{className:"text-xs",children:e.output_cost?e.output_cost:e.litellm_params.output_cost_per_token?(1e6*Number(e.litellm_params.output_cost_per_token)).toFixed(2):null})}),(0,a.jsx)(U.Z,{children:(0,a.jsx)("p",{className:"text-xs",children:f&&((s=e.model_info.created_at)?new Date(s).toLocaleDateString("en-US"):null)||"-"})}),(0,a.jsx)(U.Z,{children:(0,a.jsx)("p",{className:"text-xs",children:f&&e.model_info.created_by||"-"})}),(0,a.jsx)(U.Z,{style:{maxWidth:"100px",whiteSpace:"normal",wordBreak:"break-word"},children:e.model_info.db_model?(0,a.jsx)(R.Z,{size:"xs",className:"text-white",children:(0,a.jsx)("p",{className:"text-xs",children:"DB Model"})}):(0,a.jsx)(R.Z,{size:"xs",className:"text-black",children:(0,a.jsx)("p",{className:"text-xs",children:"Config Model"})})}),(0,a.jsx)(U.Z,{style:{maxWidth:"150px",whiteSpace:"normal",wordBreak:"break-word"},children:(0,a.jsxs)(x.Z,{numItems:3,children:[(0,a.jsx)(eu.Z,{children:(0,a.jsx)(F.Z,{icon:T.Z,size:"sm",onClick:()=>lp(e)})}),(0,a.jsx)(eu.Z,{children:(0,a.jsx)(F.Z,{icon:O.Z,size:"sm",onClick:()=>lx(e)})}),(0,a.jsx)(eu.Z,{children:(0,a.jsx)(eZ,{modelID:e.model_info.id,accessToken:o})})]})})]},l)})})]})})]}),(0,a.jsx)(e=>{let{visible:l,onCancel:s,model:t,onSubmit:n}=e,[r]=S.Z.useForm(),i={},o="",d="";if(t){i=t.litellm_params,o=t.model_name;let e=t.model_info;e&&(d=e.id,console.log("model_id: ".concat(d)),i.model_id=d)}return(0,a.jsx)(w.Z,{title:"Edit Model "+o,visible:l,width:800,footer:null,onOk:()=>{r.validateFields().then(e=>{n(e),r.resetFields()}).catch(e=>{console.error("Validation failed:",e)})},onCancel:s,children:(0,a.jsxs)(S.Z,{form:r,onFinish:lj,initialValues:i,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(S.Z.Item,{className:"mt-8",label:"api_base",name:"api_base",children:(0,a.jsx)(j.Z,{})}),(0,a.jsx)(S.Z.Item,{label:"tpm",name:"tpm",tooltip:"int (optional) - Tokens limit for this deployment: in tokens per minute (tpm). Find this information on your model/providers website",children:(0,a.jsx)(A.Z,{min:0,step:1})}),(0,a.jsx)(S.Z.Item,{label:"rpm",name:"rpm",tooltip:"int (optional) - Rate limit for this deployment: in requests per minute (rpm). Find this information on your model/providers website",children:(0,a.jsx)(A.Z,{min:0,step:1})}),(0,a.jsx)(S.Z.Item,{label:"max_retries",name:"max_retries",children:(0,a.jsx)(A.Z,{min:0,step:1})}),(0,a.jsx)(S.Z.Item,{label:"timeout",name:"timeout",tooltip:"int (optional) - Timeout in seconds for LLM requests (Defaults to 600 seconds)",children:(0,a.jsx)(A.Z,{min:0,step:1})}),(0,a.jsx)(S.Z.Item,{label:"stream_timeout",name:"stream_timeout",tooltip:"int (optional) - Timeout for stream requests (seconds)",children:(0,a.jsx)(A.Z,{min:0,step:1})}),(0,a.jsx)(S.Z.Item,{label:"input_cost_per_token",name:"input_cost_per_token",tooltip:"float (optional) - Input cost per token",children:(0,a.jsx)(A.Z,{min:0,step:1e-4})}),(0,a.jsx)(S.Z.Item,{label:"output_cost_per_token",name:"output_cost_per_token",tooltip:"float (optional) - Output cost per token",children:(0,a.jsx)(A.Z,{min:0,step:1e-4})}),(0,a.jsx)(S.Z.Item,{label:"model_id",name:"model_id",hidden:!0})]}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(I.ZP,{htmlType:"submit",children:"Save"})})]})})},{visible:eT,onCancel:()=>{eO(!1),eF(null)},model:eM,onSubmit:lj}),(0,a.jsxs)(w.Z,{title:eM&&eM.model_name,visible:eE,width:800,footer:null,onCancel:()=>{eR(!1),eF(null)},children:[(0,a.jsx)(y.Z,{children:"Model Info"}),(0,a.jsx)(ek.Z,{language:"json",children:eM&&JSON.stringify(eM,null,2)})]})]}),(0,a.jsxs)(ea.Z,{className:"h-full",children:[(0,a.jsx)(ew,{level:2,children:"Add new model"}),(0,a.jsx)(M.Z,{children:(0,a.jsxs)(S.Z,{form:N,onFinish:()=>{N.validateFields().then(e=>{eC(e,o,N)}).catch(e=>{console.error("Validation failed:",e)})},labelCol:{span:10},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(S.Z.Item,{rules:[{required:!0,message:"Required"}],label:"Provider:",name:"custom_llm_provider",tooltip:"E.g. OpenAI, Azure OpenAI, Anthropic, Bedrock, etc.",labelCol:{span:10},labelAlign:"left",children:(0,a.jsx)(B.Z,{value:Q.toString(),children:Y.map((e,l)=>(0,a.jsx)(K.Z,{value:e,onClick:()=>{l_(e),ey(e)},children:e},l))})}),(0,a.jsx)(S.Z.Item,{rules:[{required:!0,message:"Required"}],label:"Public Model Name",name:"model_name",tooltip:"Model name your users will pass in. Also used for load-balancing, LiteLLM will load balance between all models with this public name.",className:"mb-0",children:(0,a.jsx)(j.Z,{placeholder:"Vertex AI (Anthropic, Gemini, etc.)"===(t=Q.toString())?"gemini-pro":"Anthropic"==t||"Amazon Bedrock"==t?"claude-3-opus":"Google AI Studio"==t?"gemini-pro":"Azure AI Studio"==t?"azure_ai/command-r-plus":"Azure"==t?"azure/my-deployment":"gpt-3.5-turbo"})}),(0,a.jsxs)(eh.Z,{children:[(0,a.jsx)(eu.Z,{span:10}),(0,a.jsx)(eu.Z,{span:10,children:(0,a.jsx)(_.Z,{className:"mb-3 mt-1",children:"Model name your users will pass in."})})]}),(0,a.jsx)(S.Z.Item,{rules:[{required:!0,message:"Required"}],label:"LiteLLM Model Name(s)",name:"model",tooltip:"Actual model name used for making litellm.completion() call.",className:"mb-0",children:"Azure"===Q?(0,a.jsx)(j.Z,{placeholder:"Enter model name"}):H.length>0?(0,a.jsx)(ei.Z,{value:H,children:H.map((e,l)=>(0,a.jsx)(eo.Z,{value:e,children:e},l))}):(0,a.jsx)(j.Z,{placeholder:"gpt-3.5-turbo-0125"})}),(0,a.jsxs)(eh.Z,{children:[(0,a.jsx)(eu.Z,{span:10}),(0,a.jsx)(eu.Z,{span:10,children:(0,a.jsxs)(_.Z,{className:"mb-3 mt-1",children:["Actual model name used for making"," ",(0,a.jsx)(eN,{href:"https://docs.litellm.ai/docs/providers",target:"_blank",children:"litellm.completion() call"}),". We'll"," ",(0,a.jsx)(eN,{href:"https://docs.litellm.ai/docs/proxy/reliability#step-1---set-deployments-on-config",target:"_blank",children:"loadbalance"})," ","models with the same 'public name'"]})})]}),void 0!==i&&i.fields.length>0&&(0,a.jsx)(eS,{fields:i.fields,selectedProvider:i.name}),"Amazon Bedrock"!=Q&&"Vertex AI (Anthropic, Gemini, etc.)"!=Q&&"Ollama"!=Q&&(void 0===i||0==i.fields.length)&&(0,a.jsx)(S.Z.Item,{rules:[{required:!0,message:"Required"}],label:"API Key",name:"api_key",children:(0,a.jsx)(j.Z,{placeholder:"sk-",type:"password"})}),"OpenAI"==Q&&(0,a.jsx)(S.Z.Item,{label:"Organization ID",name:"organization_id",children:(0,a.jsx)(j.Z,{placeholder:"[OPTIONAL] my-unique-org"})}),"Vertex AI (Anthropic, Gemini, etc.)"==Q&&(0,a.jsx)(S.Z.Item,{rules:[{required:!0,message:"Required"}],label:"Vertex Project",name:"vertex_project",children:(0,a.jsx)(j.Z,{placeholder:"adroit-cadet-1234.."})}),"Vertex AI (Anthropic, Gemini, etc.)"==Q&&(0,a.jsx)(S.Z.Item,{rules:[{required:!0,message:"Required"}],label:"Vertex Location",name:"vertex_location",children:(0,a.jsx)(j.Z,{placeholder:"us-east-1"})}),"Vertex AI (Anthropic, Gemini, etc.)"==Q&&(0,a.jsx)(S.Z.Item,{rules:[{required:!0,message:"Required"}],label:"Vertex Credentials",name:"vertex_credentials",className:"mb-0",children:(0,a.jsx)(e_.Z,{name:"file",accept:".json",beforeUpload:e=>{if("application/json"===e.type){let l=new FileReader;l.onload=e=>{if(e.target){let l=e.target.result;N.setFieldsValue({vertex_credentials:l})}},l.readAsText(e)}return!1},onChange(e){"uploading"!==e.file.status&&console.log(e.file,e.fileList),"done"===e.file.status?k.ZP.success("".concat(e.file.name," file uploaded successfully")):"error"===e.file.status&&k.ZP.error("".concat(e.file.name," file upload failed."))},children:(0,a.jsx)(I.ZP,{icon:(0,a.jsx)(ef.Z,{}),children:"Click to Upload"})})}),"Vertex AI (Anthropic, Gemini, etc.)"==Q&&(0,a.jsxs)(eh.Z,{children:[(0,a.jsx)(eu.Z,{span:10}),(0,a.jsx)(eu.Z,{span:10,children:(0,a.jsx)(_.Z,{className:"mb-3 mt-1",children:"Give litellm a gcp service account(.json file), so it can make the relevant calls"})})]}),("Azure"==Q||"OpenAI-Compatible Endpoints (Groq, Together AI, Mistral AI, etc.)"==Q)&&(0,a.jsx)(S.Z.Item,{rules:[{required:!0,message:"Required"}],label:"API Base",name:"api_base",children:(0,a.jsx)(j.Z,{placeholder:"https://..."})}),"Azure"==Q&&(0,a.jsx)(S.Z.Item,{rules:[{required:!0,message:"Required"}],label:"API Version",name:"api_version",children:(0,a.jsx)(j.Z,{placeholder:"2023-07-01-preview"})}),"Azure"==Q&&(0,a.jsxs)("div",{children:[(0,a.jsx)(S.Z.Item,{label:"Base Model",name:"base_model",className:"mb-0",children:(0,a.jsx)(j.Z,{placeholder:"azure/gpt-3.5-turbo"})}),(0,a.jsxs)(eh.Z,{children:[(0,a.jsx)(eu.Z,{span:10}),(0,a.jsx)(eu.Z,{span:10,children:(0,a.jsxs)(_.Z,{className:"mb-2",children:["The actual model your azure deployment uses. Used for accurate cost tracking. Select name from"," ",(0,a.jsx)(eN,{href:"https://github.com/BerriAI/litellm/blob/main/model_prices_and_context_window.json",target:"_blank",children:"here"})]})})]})]}),"Amazon Bedrock"==Q&&(0,a.jsx)(S.Z.Item,{rules:[{required:!0,message:"Required"}],label:"AWS Access Key ID",name:"aws_access_key_id",tooltip:"You can provide the raw key or the environment variable (e.g. `os.environ/MY_SECRET_KEY`).",children:(0,a.jsx)(j.Z,{placeholder:""})}),"Amazon Bedrock"==Q&&(0,a.jsx)(S.Z.Item,{rules:[{required:!0,message:"Required"}],label:"AWS Secret Access Key",name:"aws_secret_access_key",tooltip:"You can provide the raw key or the environment variable (e.g. `os.environ/MY_SECRET_KEY`).",children:(0,a.jsx)(j.Z,{placeholder:""})}),"Amazon Bedrock"==Q&&(0,a.jsx)(S.Z.Item,{rules:[{required:!0,message:"Required"}],label:"AWS Region Name",name:"aws_region_name",tooltip:"You can provide the raw key or the environment variable (e.g. `os.environ/MY_SECRET_KEY`).",children:(0,a.jsx)(j.Z,{placeholder:"us-east-1"})}),(0,a.jsx)(S.Z.Item,{label:"LiteLLM Params",name:"litellm_extra_params",tooltip:"Optional litellm params used for making a litellm.completion() call.",className:"mb-0",children:(0,a.jsx)(ep.Z,{rows:4,placeholder:'{ "rpm": 100, "timeout": 0, "stream_timeout": 0 }'})}),(0,a.jsxs)(eh.Z,{children:[(0,a.jsx)(eu.Z,{span:10}),(0,a.jsx)(eu.Z,{span:10,children:(0,a.jsxs)(_.Z,{className:"mb-3 mt-1",children:["Pass JSON of litellm supported params"," ",(0,a.jsx)(eN,{href:"https://docs.litellm.ai/docs/completion/input",target:"_blank",children:"litellm.completion() call"})]})})]})]}),(0,a.jsx)("div",{style:{textAlign:"center",marginTop:"10px"},children:(0,a.jsx)(I.ZP,{htmlType:"submit",children:"Add Model"})}),(0,a.jsx)(em.Z,{title:"Get help on our github",children:(0,a.jsx)($.default.Link,{href:"https://github.com/BerriAI/litellm/issues",children:"Need Help?"})})]})})]}),(0,a.jsx)(ea.Z,{children:(0,a.jsxs)(M.Z,{children:[(0,a.jsx)(_.Z,{children:"`/health` will run a very small request through your models configured on litellm"}),(0,a.jsx)(p.Z,{onClick:ly,children:"Run `/health`"}),eb&&(0,a.jsx)("pre",{children:JSON.stringify(eb,null,2)})]})}),(0,a.jsxs)(ea.Z,{children:[(0,a.jsxs)(x.Z,{numItems:4,className:"mt-2 mb-2",children:[(0,a.jsxs)(eu.Z,{children:[(0,a.jsx)(_.Z,{children:"Select Time Range"}),(0,a.jsx)(el.Z,{enableSelect:!0,value:e3,className:"mr-2",onValueChange:e=>{e6(e),lb(eU,e.from,e.to)}})]}),(0,a.jsxs)(eu.Z,{className:"ml-2",children:[(0,a.jsx)(_.Z,{children:"Select Model Group"}),(0,a.jsx)(B.Z,{defaultValue:eU||eD[0],value:eU||eD[0],children:eD.map((e,l)=>(0,a.jsx)(K.Z,{value:e,onClick:()=>lb(e,e3.from,e3.to),children:e},l))})]}),(0,a.jsx)(eu.Z,{children:(0,a.jsx)(ex.Z,{trigger:"click",content:lv,overlayStyle:{width:"20vw"},children:(0,a.jsx)(p.Z,{icon:eg.Z,size:"md",variant:"secondary",className:"mt-4 ml-2",style:{border:"none"},onClick:()=>li(!0)})})})]}),(0,a.jsxs)(x.Z,{numItems:2,children:[(0,a.jsx)(eu.Z,{children:(0,a.jsx)(M.Z,{className:"mr-2 max-h-[400px] min-h-[400px]",children:(0,a.jsxs)(et.Z,{children:[(0,a.jsxs)(en.Z,{variant:"line",defaultValue:"1",children:[(0,a.jsx)(es.Z,{value:"1",children:"Avg. Latency per Token"}),(0,a.jsx)(es.Z,{value:"2",children:"✨ Time to first token"})]}),(0,a.jsxs)(er.Z,{children:[(0,a.jsxs)(ea.Z,{children:[(0,a.jsx)("p",{className:"text-gray-500 italic",children:" (seconds/token)"}),(0,a.jsx)(_.Z,{className:"text-gray-500 italic mt-1 mb-1",children:"average Latency for successfull requests divided by the total tokens"}),eB&&eW&&(0,a.jsx)(ed.Z,{title:"Model Latency",className:"h-72",data:eB,showLegend:!1,index:"date",categories:eW,connectNulls:!0,customTooltip:lS})]}),(0,a.jsx)(ea.Z,{children:(0,a.jsx)(ev,{modelMetrics:eG,modelMetricsCategories:eJ,customTooltip:lS,premiumUser:f})})]})]})})}),(0,a.jsx)(eu.Z,{children:(0,a.jsx)(M.Z,{className:"ml-2 max-h-[400px] min-h-[400px] overflow-y-auto",children:(0,a.jsxs)(D.Z,{children:[(0,a.jsx)(V.Z,{children:(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(z.Z,{children:"Deployment"}),(0,a.jsx)(z.Z,{children:"Success Responses"}),(0,a.jsxs)(z.Z,{children:["Slow Responses ",(0,a.jsx)("p",{children:"Success Responses taking 600+s"})]})]})}),(0,a.jsx)(L.Z,{children:e5.map((e,l)=>(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(U.Z,{children:e.api_base}),(0,a.jsx)(U.Z,{children:e.total_count}),(0,a.jsx)(U.Z,{children:e.slow_count})]},l))})]})})})]}),(0,a.jsx)(x.Z,{numItems:1,className:"gap-2 w-full mt-2",children:(0,a.jsxs)(M.Z,{children:[(0,a.jsxs)(y.Z,{children:["All Exceptions for ",eU]}),(0,a.jsx)(ec.Z,{className:"h-60",data:e$,index:"model",categories:e0,stack:!0,yAxisWidth:30})]})}),(0,a.jsxs)(x.Z,{numItems:1,className:"gap-2 w-full mt-2",children:[(0,a.jsxs)(M.Z,{children:[(0,a.jsxs)(y.Z,{children:["All Up Rate Limit Errors (429) for ",eU]}),(0,a.jsxs)(x.Z,{numItems:1,children:[(0,a.jsxs)(eu.Z,{children:[(0,a.jsxs)(ee.Z,{style:{fontSize:"15px",fontWeight:"normal",color:"#535452"},children:["Num Rate Limit Errors ",ls.sum_num_rate_limit_exceptions]}),(0,a.jsx)(ec.Z,{className:"h-40",data:ls.daily_data,index:"date",colors:["rose"],categories:["num_rate_limit_exceptions"],onValueChange:e=>console.log(e)})]}),(0,a.jsx)(eu.Z,{})]})]}),f?(0,a.jsx)(a.Fragment,{children:ln.map((e,l)=>(0,a.jsxs)(M.Z,{children:[(0,a.jsx)(y.Z,{children:e.api_base?e.api_base:"Unknown API Base"}),(0,a.jsx)(x.Z,{numItems:1,children:(0,a.jsxs)(eu.Z,{children:[(0,a.jsxs)(ee.Z,{style:{fontSize:"15px",fontWeight:"normal",color:"#535452"},children:["Num Rate Limit Errors (429) ",e.sum_num_rate_limit_exceptions]}),(0,a.jsx)(ec.Z,{className:"h-40",data:e.daily_data,index:"date",colors:["rose"],categories:["num_rate_limit_exceptions"],onValueChange:e=>console.log(e)})]})})]},l))}):(0,a.jsx)(a.Fragment,{children:ln&&ln.length>0&&ln.slice(0,1).map((e,l)=>(0,a.jsxs)(M.Z,{children:[(0,a.jsx)(y.Z,{children:"✨ Rate Limit Errors by Deployment"}),(0,a.jsx)("p",{className:"mb-2 text-gray-500 italic text-[12px]",children:"Upgrade to see exceptions for all deployments"}),(0,a.jsx)(p.Z,{variant:"primary",className:"mb-2",children:(0,a.jsx)("a",{href:"https://forms.gle/W3U4PZpJGFHWtHyA9",target:"_blank",children:"Get Free Trial"})}),(0,a.jsxs)(M.Z,{children:[(0,a.jsx)(y.Z,{children:e.api_base}),(0,a.jsx)(x.Z,{numItems:1,children:(0,a.jsxs)(eu.Z,{children:[(0,a.jsxs)(ee.Z,{style:{fontSize:"15px",fontWeight:"normal",color:"#535452"},children:["Num Rate Limit Errors ",e.sum_num_rate_limit_exceptions]}),(0,a.jsx)(ec.Z,{className:"h-40",data:e.daily_data,index:"date",colors:["rose"],categories:["num_rate_limit_exceptions"],onValueChange:e=>console.log(e)})]})})]})]},l))})]})]}),(0,a.jsxs)(ea.Z,{children:[(0,a.jsxs)("div",{className:"flex items-center",children:[(0,a.jsx)(_.Z,{children:"Filter by Public Model Name"}),(0,a.jsx)(B.Z,{className:"mb-4 mt-2 ml-2 w-50",defaultValue:eU||eD[0],value:eU||eD[0],onValueChange:e=>eV(e),children:eD.map((e,l)=>(0,a.jsx)(K.Z,{value:e,onClick:()=>eV(e),children:e},l))})]}),(0,a.jsxs)(y.Z,{children:["Retry Policy for ",eU]}),(0,a.jsx)(_.Z,{className:"mb-6",children:"How many retries should be attempted based on the Exception"}),eI&&(0,a.jsx)("table",{children:(0,a.jsx)("tbody",{children:Object.entries(eI).map((e,l)=>{var s;let[t,n]=e,r=null==e9?void 0:null===(s=e9[eU])||void 0===s?void 0:s[n];return null==r&&(r=le),(0,a.jsxs)("tr",{className:"flex justify-between items-center mt-2",children:[(0,a.jsx)("td",{children:(0,a.jsx)(_.Z,{children:t})}),(0,a.jsx)("td",{children:(0,a.jsx)(A.Z,{className:"ml-5",value:r,min:0,step:1,onChange:e=>{e7(l=>{var s;let t=null!==(s=null==l?void 0:l[eU])&&void 0!==s?s:{};return{...null!=l?l:{},[eU]:{...t,[n]:e}}})}})})]},l)})})}),(0,a.jsx)(p.Z,{className:"mt-6 mr-8",onClick:lZ,children:"Save"})]})]})]})})},eT=e=>{let{isInvitationLinkModalVisible:l,setIsInvitationLinkModalVisible:s,baseUrl:t,invitationLinkData:n}=e,{Title:r,Paragraph:i}=$.default;return(0,a.jsxs)(w.Z,{title:"Invitation Link",visible:l,width:800,footer:null,onOk:()=>{s(!1)},onCancel:()=>{s(!1)},children:[(0,a.jsx)(i,{children:"Copy and send the generated link to onboard this user to the proxy."}),(0,a.jsxs)("div",{className:"flex justify-between pt-5 pb-2",children:[(0,a.jsx)(_.Z,{className:"text-base",children:"User ID"}),(0,a.jsx)(_.Z,{children:null==n?void 0:n.user_id})]}),(0,a.jsxs)("div",{className:"flex justify-between pt-5 pb-2",children:[(0,a.jsx)(_.Z,{children:"Invitation Link"}),(0,a.jsxs)(_.Z,{children:[t,"/ui/onboarding?id=",null==n?void 0:n.id]})]}),(0,a.jsxs)("div",{className:"flex justify-end mt-5",children:[(0,a.jsx)("div",{}),(0,a.jsx)(b.CopyToClipboard,{text:"".concat(t,"/ui/onboarding?id=").concat(null==n?void 0:n.id),onCopy:()=>k.ZP.success("Copied!"),children:(0,a.jsx)(p.Z,{variant:"primary",children:"Copy invitation link"})})]})]})};let{Option:eO}=v.default;var eE=e=>{let{userID:l,accessToken:s,teams:t,possibleUIRoles:n}=e,[o]=S.Z.useForm(),[d,c]=(0,r.useState)(!1),[m,h]=(0,r.useState)(null),[x,g]=(0,r.useState)([]),[Z,f]=(0,r.useState)(!1),[y,b]=(0,r.useState)(null),A=(0,i.useRouter)(),[C,P]=(0,r.useState)("");(0,r.useEffect)(()=>{(async()=>{try{let e=await (0,u.So)(s,l,"any"),t=[];for(let l=0;l{if(A){let{protocol:e,host:l}=window.location;P("".concat(e,"/").concat(l))}},[A]);let T=async e=>{try{var t;k.ZP.info("Making API Call"),c(!0),console.log("formValues in create user:",e);let n=await (0,u.Ov)(s,null,e);console.log("user create Response:",n),h(n.key);let a=(null===(t=n.data)||void 0===t?void 0:t.user_id)||n.user_id;(0,u.XO)(s,a).then(e=>{b(e),f(!0)}),k.ZP.success("API user Created"),o.resetFields(),localStorage.removeItem("userData"+l)}catch(e){console.error("Error creating the user:",e)}};return(0,a.jsxs)("div",{children:[(0,a.jsx)(p.Z,{className:"mx-auto mb-0",onClick:()=>c(!0),children:"+ Invite User"}),(0,a.jsxs)(w.Z,{title:"Invite User",visible:d,width:800,footer:null,onOk:()=>{c(!1),o.resetFields()},onCancel:()=>{c(!1),h(null),o.resetFields()},children:[(0,a.jsx)(_.Z,{className:"mb-1",children:"Create a User who can own keys"}),(0,a.jsxs)(S.Z,{form:o,onFinish:T,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsx)(S.Z.Item,{label:"User Email",name:"user_email",children:(0,a.jsx)(j.Z,{placeholder:""})}),(0,a.jsx)(S.Z.Item,{label:"User Role",name:"user_role",children:(0,a.jsx)(v.default,{children:n&&Object.entries(n).map(e=>{let[l,{ui_label:s,description:t}]=e;return(0,a.jsx)(K.Z,{value:l,title:s,children:(0,a.jsxs)("div",{className:"flex",children:[s," ",(0,a.jsx)("p",{className:"ml-2",style:{color:"gray",fontSize:"12px"},children:t})]})},l)})})}),(0,a.jsx)(S.Z.Item,{label:"Team ID",name:"team_id",children:(0,a.jsx)(v.default,{placeholder:"Select Team ID",style:{width:"100%"},children:t?t.map(e=>(0,a.jsx)(eO,{value:e.team_id,children:e.team_alias},e.team_id)):(0,a.jsx)(eO,{value:null,children:"Default Team"},"default")})}),(0,a.jsx)(S.Z.Item,{label:"Metadata",name:"metadata",children:(0,a.jsx)(N.Z.TextArea,{rows:4,placeholder:"Enter metadata as JSON"})}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(I.ZP,{htmlType:"submit",children:"Create User"})})]})]}),m&&(0,a.jsx)(eT,{isInvitationLinkModalVisible:Z,setIsInvitationLinkModalVisible:f,baseUrl:C,invitationLinkData:y})]})},eR=e=>{let{visible:l,possibleUIRoles:s,onCancel:t,user:n,onSubmit:i}=e,[o,d]=(0,r.useState)(n),[c]=S.Z.useForm();(0,r.useEffect)(()=>{c.resetFields()},[n]);let m=async()=>{c.resetFields(),t()},u=async e=>{i(e),c.resetFields(),t()};return n?(0,a.jsx)(w.Z,{visible:l,onCancel:m,footer:null,title:"Edit User "+n.user_id,width:1e3,children:(0,a.jsx)(S.Z,{form:c,onFinish:u,initialValues:n,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(S.Z.Item,{className:"mt-8",label:"User Email",tooltip:"Email of the User",name:"user_email",children:(0,a.jsx)(j.Z,{})}),(0,a.jsx)(S.Z.Item,{label:"user_id",name:"user_id",hidden:!0,children:(0,a.jsx)(j.Z,{})}),(0,a.jsx)(S.Z.Item,{label:"User Role",name:"user_role",children:(0,a.jsx)(v.default,{children:s&&Object.entries(s).map(e=>{let[l,{ui_label:s,description:t}]=e;return(0,a.jsx)(K.Z,{value:l,title:s,children:(0,a.jsxs)("div",{className:"flex",children:[s," ",(0,a.jsx)("p",{className:"ml-2",style:{color:"gray",fontSize:"12px"},children:t})]})},l)})})}),(0,a.jsx)(S.Z.Item,{label:"Spend (USD)",name:"spend",tooltip:"(float) - Spend of all LLM calls completed by this user",children:(0,a.jsx)(A.Z,{min:0,step:1})}),(0,a.jsx)(S.Z.Item,{label:"User Budget (USD)",name:"max_budget",tooltip:"(float) - Maximum budget of this user",children:(0,a.jsx)(A.Z,{min:0,step:1})}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(I.ZP,{htmlType:"submit",children:"Save"})})]})})}):null},eM=e=>{let{accessToken:l,token:s,keys:t,userRole:n,userID:i,teams:o,setKeys:d}=e,[c,m]=(0,r.useState)(null),[h,p]=(0,r.useState)(null),[j,g]=(0,r.useState)(0),[Z,f]=r.useState(null),[_,y]=(0,r.useState)(null),[b,v]=(0,r.useState)(!1),[S,w]=(0,r.useState)(null),[N,A]=(0,r.useState)({}),I=async()=>{w(null),v(!1)},C=async e=>{if(console.log("inside handleEditSubmit:",e),l&&s&&n&&i){try{await (0,u.pf)(l,e,null),k.ZP.success("User ".concat(e.user_id," updated successfully"))}catch(e){console.error("There was an error updating the user",e)}c&&m(c.map(l=>l.user_id===e.user_id?e:l)),w(null),v(!1)}};return((0,r.useEffect)(()=>{if(!l||!s||!n||!i)return;let e=async()=>{try{let e=await (0,u.Br)(l,null,n,!0,j,25);console.log("user data response:",e),m(e);let s=await (0,u.lg)(l);A(s)}catch(e){console.error("There was an error fetching the model data",e)}};l&&s&&n&&i&&e()},[l,s,n,i,j]),c&&l&&s&&n&&i)?(0,a.jsx)("div",{style:{width:"100%"},children:(0,a.jsxs)(x.Z,{className:"gap-2 p-2 h-[90vh] w-full mt-8",children:[(0,a.jsx)(eE,{userID:i,accessToken:l,teams:o,possibleUIRoles:N}),(0,a.jsxs)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[90vh] mb-4",children:[(0,a.jsx)("div",{className:"mb-4 mt-1"}),(0,a.jsx)(et.Z,{children:(0,a.jsxs)(er.Z,{children:[(0,a.jsx)(ea.Z,{children:(0,a.jsxs)(D.Z,{className:"mt-5",children:[(0,a.jsx)(V.Z,{children:(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(z.Z,{children:"User ID"}),(0,a.jsx)(z.Z,{children:"User Email"}),(0,a.jsx)(z.Z,{children:"Role"}),(0,a.jsx)(z.Z,{children:"User Spend ($ USD)"}),(0,a.jsx)(z.Z,{children:"User Max Budget ($ USD)"}),(0,a.jsx)(z.Z,{children:"API Keys"}),(0,a.jsx)(z.Z,{})]})}),(0,a.jsx)(L.Z,{children:c.map(e=>{var l,s;return(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(U.Z,{children:e.user_id||"-"}),(0,a.jsx)(U.Z,{children:e.user_email||"-"}),(0,a.jsx)(U.Z,{children:(null==N?void 0:null===(l=N[null==e?void 0:e.user_role])||void 0===l?void 0:l.ui_label)||"-"}),(0,a.jsx)(U.Z,{children:e.spend?null===(s=e.spend)||void 0===s?void 0:s.toFixed(2):"-"}),(0,a.jsx)(U.Z,{children:e.max_budget?e.max_budget:"Unlimited"}),(0,a.jsx)(U.Z,{children:(0,a.jsx)(x.Z,{numItems:2,children:e&&e.key_aliases&&e.key_aliases.filter(e=>null!==e).length>0?(0,a.jsxs)(R.Z,{size:"xs",color:"indigo",children:[e.key_aliases.filter(e=>null!==e).length,"\xa0Keys"]}):(0,a.jsx)(R.Z,{size:"xs",color:"gray",children:"No Keys"})})}),(0,a.jsx)(U.Z,{children:(0,a.jsx)(F.Z,{icon:O.Z,onClick:()=>{w(e),v(!0)},children:"View Keys"})})]},e.user_id)})})]})}),(0,a.jsx)(ea.Z,{children:(0,a.jsxs)("div",{className:"flex items-center",children:[(0,a.jsx)("div",{className:"flex-1"}),(0,a.jsx)("div",{className:"flex-1 flex justify-between items-center"})]})})]})}),(0,a.jsx)(eR,{visible:b,possibleUIRoles:N,onCancel:I,user:S,onSubmit:C})]}),function(){if(!c)return null;let e=Math.ceil(c.length/25);return(0,a.jsxs)("div",{className:"flex justify-between items-center",children:[(0,a.jsxs)("div",{children:["Showing Page ",j+1," of ",e]}),(0,a.jsxs)("div",{className:"flex",children:[(0,a.jsx)("button",{className:"bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-l focus:outline-none",disabled:0===j,onClick:()=>g(j-1),children:"← Prev"}),(0,a.jsx)("button",{className:"bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-r focus:outline-none",onClick:()=>{g(j+1)},children:"Next →"})]})]})}()]})}):(0,a.jsx)("div",{children:"Loading..."})},eF=e=>{let{teams:l,searchParams:s,accessToken:t,setTeams:n,userID:i,userRole:o}=e,[d]=S.Z.useForm(),[c]=S.Z.useForm(),{Title:m,Paragraph:g}=$.default,[Z,f]=(0,r.useState)(""),[y,b]=(0,r.useState)(!1),[C,P]=(0,r.useState)(l?l[0]:null),[T,W]=(0,r.useState)(!1),[H,G]=(0,r.useState)(!1),[Y,J]=(0,r.useState)([]),[X,Q]=(0,r.useState)(!1),[ee,el]=(0,r.useState)(null),[es,et]=(0,r.useState)({}),en=e=>{P(e),b(!0)},ea=async e=>{let s=e.team_id;if(console.log("handleEditSubmit:",e),null==t)return;let a=await (0,u.Gh)(t,e);l&&n(l.map(e=>e.team_id===s?a.data:e)),k.ZP.success("Team updated successfully"),b(!1),P(null)},er=async e=>{el(e),Q(!0)},ei=async()=>{if(null!=ee&&null!=l&&null!=t){try{await (0,u.rs)(t,ee);let e=l.filter(e=>e.team_id!==ee);n(e)}catch(e){console.error("Error deleting the team:",e)}Q(!1),el(null)}};(0,r.useEffect)(()=>{let e=async()=>{try{if(null===i||null===o||null===t||null===l)return;console.log("fetching team info:");let e={};for(let s=0;s<(null==l?void 0:l.length);s++){let n=l[s].team_id,a=await (0,u.Xm)(t,n);console.log("teamInfo response:",a),null!==a&&(e={...e,[n]:a})}et(e)}catch(e){console.error("Error fetching team info:",e)}};(async()=>{try{if(null===i||null===o)return;if(null!==t){let e=(await (0,u.So)(t,i,o)).data.map(e=>e.id);console.log("available_model_names:",e),J(e)}}catch(e){console.error("Error fetching user models:",e)}})(),e()},[t,i,o,l]);let eo=async e=>{try{if(null!=t){var s;let a=null==e?void 0:e.team_alias;if((null!==(s=null==l?void 0:l.map(e=>e.team_alias))&&void 0!==s?s:[]).includes(a))throw Error("Team alias ".concat(a," already exists, please pick another alias"));k.ZP.info("Creating Team");let r=await (0,u.hT)(t,e);null!==l?n([...l,r]):n([r]),console.log("response for team create call: ".concat(r)),k.ZP.success("Team created"),W(!1)}}catch(e){console.error("Error creating the team:",e),k.ZP.error("Error creating the team: "+e,20)}},ed=async e=>{try{if(null!=t&&null!=l){k.ZP.info("Adding Member");let s={role:"user",user_email:e.user_email,user_id:e.user_id},a=await (0,u.cu)(t,C.team_id,s);console.log("response for team create call: ".concat(a.data));let r=l.findIndex(e=>(console.log("team.team_id=".concat(e.team_id,"; response.data.team_id=").concat(a.data.team_id)),e.team_id===a.data.team_id));if(console.log("foundIndex: ".concat(r)),-1!==r){let e=[...l];e[r]=a.data,n(e),P(a.data)}G(!1)}}catch(e){console.error("Error creating the team:",e)}};return console.log("received teams ".concat(JSON.stringify(l))),(0,a.jsx)("div",{className:"w-full mx-4",children:(0,a.jsxs)(x.Z,{numItems:1,className:"gap-2 p-8 h-[75vh] w-full mt-2",children:[(0,a.jsxs)(h.Z,{numColSpan:1,children:[(0,a.jsx)(m,{level:4,children:"All Teams"}),(0,a.jsxs)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:[(0,a.jsxs)(D.Z,{children:[(0,a.jsx)(V.Z,{children:(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(z.Z,{children:"Team Name"}),(0,a.jsx)(z.Z,{children:"Spend (USD)"}),(0,a.jsx)(z.Z,{children:"Budget (USD)"}),(0,a.jsx)(z.Z,{children:"Models"}),(0,a.jsx)(z.Z,{children:"TPM / RPM Limits"}),(0,a.jsx)(z.Z,{children:"Info"})]})}),(0,a.jsx)(L.Z,{children:l&&l.length>0?l.map(e=>(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(U.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:e.team_alias}),(0,a.jsx)(U.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:e.spend}),(0,a.jsx)(U.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:null!==e.max_budget&&void 0!==e.max_budget?e.max_budget:"No limit"}),(0,a.jsx)(U.Z,{style:{maxWidth:"8-x",whiteSpace:"pre-wrap",overflow:"hidden"},children:Array.isArray(e.models)?(0,a.jsx)("div",{style:{display:"flex",flexDirection:"column"},children:0===e.models.length?(0,a.jsx)(R.Z,{size:"xs",className:"mb-1",color:"red",children:(0,a.jsx)(_.Z,{children:"All Proxy Models"})}):e.models.map((e,l)=>"all-proxy-models"===e?(0,a.jsx)(R.Z,{size:"xs",className:"mb-1",color:"red",children:(0,a.jsx)(_.Z,{children:"All Proxy Models"})},l):(0,a.jsx)(R.Z,{size:"xs",className:"mb-1",color:"blue",children:(0,a.jsx)(_.Z,{children:e.length>30?"".concat(e.slice(0,30),"..."):e})},l))}):null}),(0,a.jsx)(U.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,a.jsxs)(_.Z,{children:["TPM: ",e.tpm_limit?e.tpm_limit:"Unlimited"," ",(0,a.jsx)("br",{}),"RPM:"," ",e.rpm_limit?e.rpm_limit:"Unlimited"]})}),(0,a.jsxs)(U.Z,{children:[(0,a.jsxs)(_.Z,{children:[es&&e.team_id&&es[e.team_id]&&es[e.team_id].keys&&es[e.team_id].keys.length," ","Keys"]}),(0,a.jsxs)(_.Z,{children:[es&&e.team_id&&es[e.team_id]&&es[e.team_id].team_info&&es[e.team_id].team_info.members_with_roles&&es[e.team_id].team_info.members_with_roles.length," ","Members"]})]}),(0,a.jsxs)(U.Z,{children:[(0,a.jsx)(F.Z,{icon:O.Z,size:"sm",onClick:()=>en(e)}),(0,a.jsx)(F.Z,{onClick:()=>er(e.team_id),icon:E.Z,size:"sm"})]})]},e.team_id)):null})]}),X&&(0,a.jsx)("div",{className:"fixed z-10 inset-0 overflow-y-auto",children:(0,a.jsxs)("div",{className:"flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0",children:[(0,a.jsx)("div",{className:"fixed inset-0 transition-opacity","aria-hidden":"true",children:(0,a.jsx)("div",{className:"absolute inset-0 bg-gray-500 opacity-75"})}),(0,a.jsx)("span",{className:"hidden sm:inline-block sm:align-middle sm:h-screen","aria-hidden":"true",children:"​"}),(0,a.jsxs)("div",{className:"inline-block align-bottom bg-white rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full",children:[(0,a.jsx)("div",{className:"bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4",children:(0,a.jsx)("div",{className:"sm:flex sm:items-start",children:(0,a.jsxs)("div",{className:"mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left",children:[(0,a.jsx)("h3",{className:"text-lg leading-6 font-medium text-gray-900",children:"Delete Team"}),(0,a.jsx)("div",{className:"mt-2",children:(0,a.jsx)("p",{className:"text-sm text-gray-500",children:"Are you sure you want to delete this team ?"})})]})})}),(0,a.jsxs)("div",{className:"bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse",children:[(0,a.jsx)(p.Z,{onClick:ei,color:"red",className:"ml-2",children:"Delete"}),(0,a.jsx)(p.Z,{onClick:()=>{Q(!1),el(null)},children:"Cancel"})]})]})]})})]})]}),(0,a.jsxs)(h.Z,{numColSpan:1,children:[(0,a.jsx)(p.Z,{className:"mx-auto",onClick:()=>W(!0),children:"+ Create New Team"}),(0,a.jsx)(w.Z,{title:"Create Team",visible:T,width:800,footer:null,onOk:()=>{W(!1),d.resetFields()},onCancel:()=>{W(!1),d.resetFields()},children:(0,a.jsxs)(S.Z,{form:d,onFinish:eo,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(S.Z.Item,{label:"Team Name",name:"team_alias",rules:[{required:!0,message:"Please input a team name"}],children:(0,a.jsx)(j.Z,{placeholder:""})}),(0,a.jsx)(S.Z.Item,{label:"Models",name:"models",children:(0,a.jsxs)(v.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:[(0,a.jsx)(v.default.Option,{value:"all-proxy-models",children:"All Proxy Models"},"all-proxy-models"),Y.map(e=>(0,a.jsx)(v.default.Option,{value:e,children:e},e))]})}),(0,a.jsx)(S.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,a.jsx)(A.Z,{step:.01,precision:2,width:200})}),(0,a.jsx)(S.Z.Item,{className:"mt-8",label:"Reset Budget",name:"budget_duration",children:(0,a.jsxs)(v.default,{defaultValue:null,placeholder:"n/a",children:[(0,a.jsx)(v.default.Option,{value:"24h",children:"daily"}),(0,a.jsx)(v.default.Option,{value:"7d",children:"weekly"}),(0,a.jsx)(v.default.Option,{value:"30d",children:"monthly"})]})}),(0,a.jsx)(S.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,a.jsx)(A.Z,{step:1,width:400})}),(0,a.jsx)(S.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,a.jsx)(A.Z,{step:1,width:400})})]}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(I.ZP,{htmlType:"submit",children:"Create Team"})})]})})]}),(0,a.jsxs)(h.Z,{numColSpan:1,children:[(0,a.jsx)(m,{level:4,children:"Team Members"}),(0,a.jsx)(g,{children:"If you belong to multiple teams, this setting controls which teams members you see."}),l&&l.length>0?(0,a.jsx)(B.Z,{defaultValue:"0",children:l.map((e,l)=>(0,a.jsx)(K.Z,{value:String(l),onClick:()=>{P(e)},children:e.team_alias},l))}):(0,a.jsxs)(g,{children:["No team created. ",(0,a.jsx)("b",{children:"Defaulting to personal account."})]})]}),(0,a.jsxs)(h.Z,{numColSpan:1,children:[(0,a.jsx)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,a.jsxs)(D.Z,{children:[(0,a.jsx)(V.Z,{children:(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(z.Z,{children:"Member Name"}),(0,a.jsx)(z.Z,{children:"Role"})]})}),(0,a.jsx)(L.Z,{children:C?C.members_with_roles.map((e,l)=>(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(U.Z,{children:e.user_email?e.user_email:e.user_id?e.user_id:null}),(0,a.jsx)(U.Z,{children:e.role})]},l)):null})]})}),C&&(0,a.jsx)(e=>{let{visible:l,onCancel:s,team:t,onSubmit:n}=e,[r]=S.Z.useForm();return(0,a.jsx)(w.Z,{title:"Edit Team",visible:l,width:800,footer:null,onOk:()=>{r.validateFields().then(e=>{n({...e,team_id:t.team_id}),r.resetFields()}).catch(e=>{console.error("Validation failed:",e)})},onCancel:s,children:(0,a.jsxs)(S.Z,{form:r,onFinish:ea,initialValues:t,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(S.Z.Item,{label:"Team Name",name:"team_alias",rules:[{required:!0,message:"Please input a team name"}],children:(0,a.jsx)(j.Z,{})}),(0,a.jsx)(S.Z.Item,{label:"Models",name:"models",children:(0,a.jsxs)(v.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:[(0,a.jsx)(v.default.Option,{value:"all-proxy-models",children:"All Proxy Models"},"all-proxy-models"),Y&&Y.map(e=>(0,a.jsx)(v.default.Option,{value:e,children:e},e))]})}),(0,a.jsx)(S.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,a.jsx)(A.Z,{step:.01,precision:2,width:200})}),(0,a.jsx)(S.Z.Item,{className:"mt-8",label:"Reset Budget",name:"budget_duration",children:(0,a.jsxs)(v.default,{defaultValue:null,placeholder:"n/a",children:[(0,a.jsx)(v.default.Option,{value:"24h",children:"daily"}),(0,a.jsx)(v.default.Option,{value:"7d",children:"weekly"}),(0,a.jsx)(v.default.Option,{value:"30d",children:"monthly"})]})}),(0,a.jsx)(S.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,a.jsx)(A.Z,{step:1,width:400})}),(0,a.jsx)(S.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,a.jsx)(A.Z,{step:1,width:400})}),(0,a.jsx)(S.Z.Item,{label:"Requests per minute Limit (RPM)",name:"team_id",hidden:!0})]}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(I.ZP,{htmlType:"submit",children:"Edit Team"})})]})})},{visible:y,onCancel:()=>{b(!1),P(null)},team:C,onSubmit:ea})]}),(0,a.jsxs)(h.Z,{numColSpan:1,children:[(0,a.jsx)(p.Z,{className:"mx-auto mb-5",onClick:()=>G(!0),children:"+ Add member"}),(0,a.jsx)(w.Z,{title:"Add member",visible:H,width:800,footer:null,onOk:()=>{G(!1),c.resetFields()},onCancel:()=>{G(!1),c.resetFields()},children:(0,a.jsxs)(S.Z,{form:d,onFinish:ed,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(S.Z.Item,{label:"Email",name:"user_email",className:"mb-4",children:(0,a.jsx)(N.Z,{name:"user_email",className:"px-3 py-2 border rounded-md w-full"})}),(0,a.jsx)("div",{className:"text-center mb-4",children:"OR"}),(0,a.jsx)(S.Z.Item,{label:"User ID",name:"user_id",className:"mb-4",children:(0,a.jsx)(N.Z,{name:"user_id",className:"px-3 py-2 border rounded-md w-full"})})]}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(I.ZP,{htmlType:"submit",children:"Add member"})})]})})]})]})})},eD=e=>{let l,{searchParams:s,accessToken:t,showSSOBanner:n}=e,[o]=S.Z.useForm(),[d]=S.Z.useForm(),{Title:c,Paragraph:m}=$.default,[j,g]=(0,r.useState)(""),[Z,f]=(0,r.useState)(null),[y,b]=(0,r.useState)(null),[v,A]=(0,r.useState)(!1),[C,P]=(0,r.useState)(!1),[T,E]=(0,r.useState)(!1),[R,W]=(0,r.useState)(!1),[H,G]=(0,r.useState)(!1),[Y,J]=(0,r.useState)(!1),X=(0,i.useRouter)(),[Q,ee]=(0,r.useState)(null),[el,es]=(0,r.useState)("");try{l=window.location.origin}catch(e){l=""}l+="/fallback/login";let et=()=>{J(!1)},en=["proxy_admin","proxy_admin_viewer"];(0,r.useEffect)(()=>{if(X){let{protocol:e,host:l}=window.location;es("".concat(e,"//").concat(l))}},[X]),(0,r.useEffect)(()=>{(async()=>{if(null!=t){let e=[],l=await (0,u.Xd)(t,"proxy_admin_viewer");l.forEach(l=>{e.push({user_role:l.user_role,user_id:l.user_id,user_email:l.user_email})}),console.log("proxy viewers: ".concat(l));let s=await (0,u.Xd)(t,"proxy_admin");s.forEach(l=>{e.push({user_role:l.user_role,user_id:l.user_id,user_email:l.user_email})}),console.log("proxy admins: ".concat(s)),console.log("combinedList: ".concat(e)),f(e),ee(await (0,u.lg)(t))}})()},[t]);let ea=()=>{W(!1),d.resetFields(),o.resetFields()},er=()=>{W(!1),d.resetFields(),o.resetFields()},ei=e=>(0,a.jsxs)(S.Z,{form:o,onFinish:e,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsx)(a.Fragment,{children:(0,a.jsx)(S.Z.Item,{label:"Email",name:"user_email",className:"mb-8 mt-4",children:(0,a.jsx)(N.Z,{name:"user_email",className:"px-3 py-2 border rounded-md w-full"})})}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},className:"mt-4",children:(0,a.jsx)(I.ZP,{htmlType:"submit",children:"Add member"})})]}),eo=(e,l,s)=>(0,a.jsxs)(S.Z,{form:o,onFinish:e,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(S.Z.Item,{rules:[{required:!0,message:"Required"}],label:"User Role",name:"user_role",labelCol:{span:10},labelAlign:"left",children:(0,a.jsx)(B.Z,{value:l,children:en.map((e,l)=>(0,a.jsx)(K.Z,{value:e,children:e},l))})}),(0,a.jsx)(S.Z.Item,{label:"Team ID",name:"user_id",hidden:!0,initialValue:s,valuePropName:"user_id",className:"mt-8",children:(0,a.jsx)(N.Z,{value:s,disabled:!0})})]}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(I.ZP,{htmlType:"submit",children:"Update role"})})]}),ed=async e=>{try{if(null!=t&&null!=Z){k.ZP.info("Making API Call");let l=await (0,u.pf)(t,e,null);console.log("response for team create call: ".concat(l));let s=Z.findIndex(e=>(console.log("user.user_id=".concat(e.user_id,"; response.user_id=").concat(l.user_id)),e.user_id===l.user_id));console.log("foundIndex: ".concat(s)),-1==s&&(console.log("updates admin with new user"),Z.push(l),f(Z)),k.ZP.success("Refresh tab to see updated user role"),W(!1)}}catch(e){console.error("Error creating the key:",e)}},ec=async e=>{try{if(null!=t&&null!=Z){var l;k.ZP.info("Making API Call");let s=await (0,u.pf)(t,e,"proxy_admin_viewer");console.log("response for team create call: ".concat(s));let n=(null===(l=s.data)||void 0===l?void 0:l.user_id)||s.user_id;(0,u.XO)(t,n).then(e=>{b(e),A(!0)});let a=Z.findIndex(e=>(console.log("user.user_id=".concat(e.user_id,"; response.user_id=").concat(s.user_id)),e.user_id===s.user_id));console.log("foundIndex: ".concat(a)),-1==a&&(console.log("updates admin with new user"),Z.push(s),f(Z)),o.resetFields(),P(!1)}}catch(e){console.error("Error creating the key:",e)}},em=async e=>{try{if(null!=t&&null!=Z){var l;k.ZP.info("Making API Call"),e.user_email,e.user_id;let s=await (0,u.pf)(t,e,"proxy_admin"),n=(null===(l=s.data)||void 0===l?void 0:l.user_id)||s.user_id;(0,u.XO)(t,n).then(e=>{b(e),A(!0)}),console.log("response for team create call: ".concat(s));let a=Z.findIndex(e=>(console.log("user.user_id=".concat(e.user_id,"; response.user_id=").concat(n)),e.user_id===s.user_id));console.log("foundIndex: ".concat(a)),-1==a&&(console.log("updates admin with new user"),Z.push(s),f(Z)),o.resetFields(),E(!1)}}catch(e){console.error("Error creating the key:",e)}},eu=async e=>{if(null==t)return;let l={environment_variables:{PROXY_BASE_URL:e.proxy_base_url,GOOGLE_CLIENT_ID:e.google_client_id,GOOGLE_CLIENT_SECRET:e.google_client_secret}};(0,u.K_)(t,l)};return console.log("admins: ".concat(null==Z?void 0:Z.length)),(0,a.jsxs)("div",{className:"w-full m-2 mt-2 p-8",children:[(0,a.jsx)(c,{level:4,children:"Admin Access "}),(0,a.jsxs)(m,{children:[n&&(0,a.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/ui#restrict-ui-access",children:"Requires SSO Setup"}),(0,a.jsx)("br",{}),(0,a.jsx)("b",{children:"Proxy Admin: "})," Can create keys, teams, users, add models, etc."," ",(0,a.jsx)("br",{}),(0,a.jsx)("b",{children:"Proxy Admin Viewer: "}),"Can just view spend. They cannot create keys, teams or grant users access to new models."," "]}),(0,a.jsxs)(x.Z,{numItems:1,className:"gap-2 p-2 w-full",children:[(0,a.jsx)(h.Z,{numColSpan:1,children:(0,a.jsx)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,a.jsxs)(D.Z,{children:[(0,a.jsx)(V.Z,{children:(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(z.Z,{children:"Member Name"}),(0,a.jsx)(z.Z,{children:"Role"})]})}),(0,a.jsx)(L.Z,{children:Z?Z.map((e,l)=>{var s;return(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(U.Z,{children:e.user_email?e.user_email:e.user_id?e.user_id:null}),(0,a.jsxs)(U.Z,{children:[" ",(null==Q?void 0:null===(s=Q[null==e?void 0:e.user_role])||void 0===s?void 0:s.ui_label)||"-"]}),(0,a.jsxs)(U.Z,{children:[(0,a.jsx)(F.Z,{icon:O.Z,size:"sm",onClick:()=>W(!0)}),(0,a.jsx)(w.Z,{title:"Update role",visible:R,width:800,footer:null,onOk:ea,onCancel:er,children:eo(ed,e.user_role,e.user_id)})]})]},l)}):null})]})})}),(0,a.jsx)(h.Z,{numColSpan:1,children:(0,a.jsxs)("div",{className:"flex justify-start",children:[(0,a.jsx)(p.Z,{className:"mr-4 mb-5",onClick:()=>E(!0),children:"+ Add admin"}),(0,a.jsx)(w.Z,{title:"Add admin",visible:T,width:800,footer:null,onOk:()=>{E(!1),d.resetFields(),o.resetFields()},onCancel:()=>{E(!1),A(!1),d.resetFields(),o.resetFields()},children:ei(em)}),(0,a.jsx)(eT,{isInvitationLinkModalVisible:v,setIsInvitationLinkModalVisible:A,baseUrl:el,invitationLinkData:y}),(0,a.jsx)(p.Z,{className:"mb-5",onClick:()=>P(!0),children:"+ Add viewer"}),(0,a.jsx)(w.Z,{title:"Add viewer",visible:C,width:800,footer:null,onOk:()=>{P(!1),d.resetFields(),o.resetFields()},onCancel:()=>{P(!1),d.resetFields(),o.resetFields()},children:ei(ec)})]})})]}),(0,a.jsxs)(x.Z,{children:[(0,a.jsx)(c,{level:4,children:"Add SSO"}),(0,a.jsxs)("div",{className:"flex justify-start mb-4",children:[(0,a.jsx)(p.Z,{onClick:()=>G(!0),children:"Add SSO"}),(0,a.jsx)(w.Z,{title:"Add SSO",visible:H,width:800,footer:null,onOk:()=>{G(!1),o.resetFields()},onCancel:()=>{G(!1),o.resetFields()},children:(0,a.jsxs)(S.Z,{form:o,onFinish:e=>{em(e),eu(e),G(!1),J(!0)},labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(S.Z.Item,{label:"Admin Email",name:"user_email",rules:[{required:!0,message:"Please enter the email of the proxy admin"}],children:(0,a.jsx)(N.Z,{})}),(0,a.jsx)(S.Z.Item,{label:"PROXY BASE URL",name:"proxy_base_url",rules:[{required:!0,message:"Please enter the proxy base url"}],children:(0,a.jsx)(N.Z,{})}),(0,a.jsx)(S.Z.Item,{label:"GOOGLE CLIENT ID",name:"google_client_id",rules:[{required:!0,message:"Please enter the google client id"}],children:(0,a.jsx)(N.Z.Password,{})}),(0,a.jsx)(S.Z.Item,{label:"GOOGLE CLIENT SECRET",name:"google_client_secret",rules:[{required:!0,message:"Please enter the google client secret"}],children:(0,a.jsx)(N.Z.Password,{})})]}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(I.ZP,{htmlType:"submit",children:"Save"})})]})}),(0,a.jsxs)(w.Z,{title:"SSO Setup Instructions",visible:Y,width:800,footer:null,onOk:et,onCancel:()=>{J(!1)},children:[(0,a.jsx)("p",{children:"Follow these steps to complete the SSO setup:"}),(0,a.jsx)(_.Z,{className:"mt-2",children:"1. DO NOT Exit this TAB"}),(0,a.jsx)(_.Z,{className:"mt-2",children:"2. Open a new tab, visit your proxy base url"}),(0,a.jsx)(_.Z,{className:"mt-2",children:"3. Confirm your SSO is configured correctly and you can login on the new Tab"}),(0,a.jsx)(_.Z,{className:"mt-2",children:"4. If Step 3 is successful, you can close this tab"}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(I.ZP,{onClick:et,children:"Done"})})]})]}),(0,a.jsxs)(ey.Z,{title:"Login without SSO",color:"teal",children:["If you need to login without sso, you can access"," ",(0,a.jsxs)("a",{href:l,target:"_blank",children:[(0,a.jsx)("b",{children:l})," "]})]})]})]})},eL=s(42556),eU=s(90252),eV=e=>{let{alertingSettings:l,handleInputChange:s,handleResetField:t,handleSubmit:n,premiumUser:r}=e,[i]=S.Z.useForm();return(0,a.jsxs)(S.Z,{form:i,onFinish:()=>{let e=i.getFieldsValue();Object.values(e).some(e=>""===e||null==e)?console.log("Some form fields are empty."):n(e)},labelAlign:"left",children:[l.map((e,l)=>(0,a.jsxs)(q.Z,{children:[(0,a.jsxs)(U.Z,{align:"center",children:[(0,a.jsx)(_.Z,{children:e.field_name}),(0,a.jsx)("p",{style:{fontSize:"0.65rem",color:"#808080",fontStyle:"italic"},className:"mt-1",children:e.field_description})]}),e.premium_field?r?(0,a.jsx)(S.Z.Item,{name:e.field_name,children:(0,a.jsx)(U.Z,{children:"Integer"===e.field_type?(0,a.jsx)(A.Z,{step:1,value:e.field_value,onChange:l=>s(e.field_name,l)}):(0,a.jsx)(N.Z,{value:e.field_value,onChange:l=>s(e.field_name,l)})})}):(0,a.jsx)(U.Z,{children:(0,a.jsx)(p.Z,{className:"flex items-center justify-center",children:(0,a.jsx)("a",{href:"https://forms.gle/W3U4PZpJGFHWtHyA9",target:"_blank",children:"✨ Enterprise Feature"})})}):(0,a.jsx)(S.Z.Item,{name:e.field_name,className:"mb-0",children:(0,a.jsx)(U.Z,{children:"Integer"===e.field_type?(0,a.jsx)(A.Z,{step:1,value:e.field_value,onChange:l=>s(e.field_name,l),className:"p-0"}):(0,a.jsx)(N.Z,{value:e.field_value,onChange:l=>s(e.field_name,l)})})}),(0,a.jsx)(U.Z,{children:!0==e.stored_in_db?(0,a.jsx)(R.Z,{icon:eU.Z,className:"text-white",children:"In DB"}):!1==e.stored_in_db?(0,a.jsx)(R.Z,{className:"text-gray bg-white outline",children:"In Config"}):(0,a.jsx)(R.Z,{className:"text-gray bg-white outline",children:"Not Set"})}),(0,a.jsx)(U.Z,{children:(0,a.jsx)(F.Z,{icon:E.Z,color:"red",onClick:()=>t(e.field_name,l),children:"Reset"})})]},l)),(0,a.jsx)("div",{children:(0,a.jsx)(I.ZP,{htmlType:"submit",children:"Update Settings"})})]})},ez=e=>{let{accessToken:l,premiumUser:s}=e,[t,n]=(0,r.useState)([]);return console.log("INSIDE ALERTING SETTINGS"),(0,r.useEffect)(()=>{l&&(0,u.RQ)(l).then(e=>{n(e)})},[l]),(0,a.jsx)(eV,{alertingSettings:t,handleInputChange:(e,l)=>{n(t.map(s=>s.field_name===e?{...s,field_value:l}:s))},handleResetField:(e,s)=>{if(l)try{let l=t.map(l=>l.field_name===e?{...l,stored_in_db:null,field_value:l.field_default_value}:l);console.log("INSIDE HANDLE RESET FIELD"),n(l)}catch(e){console.log("ERROR OCCURRED!")}},handleSubmit:e=>{if(!l||null==e||void 0==e)return;let s={};t.forEach(e=>{s[e.field_name]=e.field_value});let n={...e,...s};try{(0,u.jA)(l,"alerting_args",n),k.ZP.success("Wait 10s for proxy to update.")}catch(e){}},premiumUser:s})},eq=s(84406);let{Title:eB,Paragraph:eK}=$.default;var eW=e=>{let{accessToken:l,userRole:s,userID:t,premiumUser:n}=e,[i,o]=(0,r.useState)([]),[d,c]=(0,r.useState)([]),[m,h]=(0,r.useState)(!1),[g]=S.Z.useForm(),[Z,f]=(0,r.useState)(null),[y,b]=(0,r.useState)([]),[N,A]=(0,r.useState)(""),[C,P]=(0,r.useState)({}),[T,E]=(0,r.useState)([]),[R,B]=(0,r.useState)(!1),[W,H]=(0,r.useState)([]),[G,Y]=(0,r.useState)(null),[J,X]=(0,r.useState)([]),[$,Q]=(0,r.useState)(!1),[ee,el]=(0,r.useState)(null),ei=e=>{T.includes(e)?E(T.filter(l=>l!==e)):E([...T,e])},eo={llm_exceptions:"LLM Exceptions",llm_too_slow:"LLM Responses Too Slow",llm_requests_hanging:"LLM Requests Hanging",budget_alerts:"Budget Alerts (API Keys, Users)",db_exceptions:"Database Exceptions (Read/Write)",daily_reports:"Weekly/Monthly Spend Reports",outage_alerts:"Outage Alerts",region_outage_alerts:"Region Outage Alerts"};(0,r.useEffect)(()=>{l&&s&&t&&(0,u.BL)(l,t,s).then(e=>{console.log("callbacks",e),o(e.callbacks),H(e.available_callbacks);let l=e.alerts;if(console.log("alerts_data",l),l&&l.length>0){let e=l[0];console.log("_alert_info",e);let s=e.variables.SLACK_WEBHOOK_URL;console.log("catch_all_webhook",s),E(e.active_alerts),A(s),P(e.alerts_to_webhook)}c(l)})},[l,s,t]);let ed=e=>T&&T.includes(e),ec=()=>{if(!l)return;let e={};d.filter(e=>"email"===e.name).forEach(l=>{var s;Object.entries(null!==(s=l.variables)&&void 0!==s?s:{}).forEach(l=>{let[s,t]=l,n=document.querySelector('input[name="'.concat(s,'"]'));n&&n.value&&(e[s]=null==n?void 0:n.value)})}),console.log("updatedVariables",e);try{(0,u.K_)(l,{general_settings:{alerting:["email"]},environment_variables:e})}catch(e){k.ZP.error("Failed to update alerts: "+e,20)}k.ZP.success("Email settings updated successfully")},em=async e=>{if(!l)return;let s={};Object.entries(e).forEach(e=>{let[l,t]=e;"callback"!==l&&(s[l]=t)});try{await (0,u.K_)(l,{environment_variables:s}),k.ZP.success("Callback added successfully"),h(!1),g.resetFields(),f(null)}catch(e){k.ZP.error("Failed to add callback: "+e,20)}},eu=async e=>{if(!l)return;let s=null==e?void 0:e.callback,t={};Object.entries(e).forEach(e=>{let[l,s]=e;"callback"!==l&&(t[l]=s)});try{await (0,u.K_)(l,{environment_variables:t,litellm_settings:{success_callback:[s]}}),k.ZP.success("Callback ".concat(s," added successfully")),h(!1),g.resetFields(),f(null)}catch(e){k.ZP.error("Failed to add callback: "+e,20)}},eh=e=>{console.log("inside handleSelectedCallbackChange",e),f(e.litellm_callback_name),console.log("all callbacks",W),e&&e.litellm_callback_params?(X(e.litellm_callback_params),console.log("selectedCallbackParams",J)):X([])};return l?(console.log("callbacks: ".concat(i)),(0,a.jsxs)("div",{className:"w-full mx-4",children:[(0,a.jsx)(x.Z,{numItems:1,className:"gap-2 p-8 w-full mt-2",children:(0,a.jsxs)(et.Z,{children:[(0,a.jsxs)(en.Z,{variant:"line",defaultValue:"1",children:[(0,a.jsx)(es.Z,{value:"1",children:"Logging Callbacks"}),(0,a.jsx)(es.Z,{value:"2",children:"Alerting Types"}),(0,a.jsx)(es.Z,{value:"3",children:"Alerting Settings"}),(0,a.jsx)(es.Z,{value:"4",children:"Email Alerts"})]}),(0,a.jsxs)(er.Z,{children:[(0,a.jsxs)(ea.Z,{children:[(0,a.jsx)(eB,{level:4,children:"Active Logging Callbacks"}),(0,a.jsx)(x.Z,{numItems:2,children:(0,a.jsx)(M.Z,{className:"max-h-[50vh]",children:(0,a.jsxs)(D.Z,{children:[(0,a.jsx)(V.Z,{children:(0,a.jsx)(q.Z,{children:(0,a.jsx)(z.Z,{children:"Callback Name"})})}),(0,a.jsx)(L.Z,{children:i.map((e,s)=>(0,a.jsxs)(q.Z,{className:"flex justify-between",children:[(0,a.jsx)(U.Z,{children:(0,a.jsx)(_.Z,{children:e.name})}),(0,a.jsx)(U.Z,{children:(0,a.jsxs)(x.Z,{numItems:2,className:"flex justify-between",children:[(0,a.jsx)(F.Z,{icon:O.Z,size:"sm",onClick:()=>{el(e),Q(!0)}}),(0,a.jsx)(p.Z,{onClick:()=>(0,u.jE)(l,e.name),className:"ml-2",variant:"secondary",children:"Test Callback"})]})})]},s))})]})})}),(0,a.jsx)(p.Z,{className:"mt-2",onClick:()=>B(!0),children:"Add Callback"})]}),(0,a.jsx)(ea.Z,{children:(0,a.jsxs)(M.Z,{children:[(0,a.jsxs)(_.Z,{className:"my-2",children:["Alerts are only supported for Slack Webhook URLs. Get your webhook urls from"," ",(0,a.jsx)("a",{href:"https://api.slack.com/messaging/webhooks",target:"_blank",style:{color:"blue"},children:"here"})]}),(0,a.jsxs)(D.Z,{children:[(0,a.jsx)(V.Z,{children:(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(z.Z,{}),(0,a.jsx)(z.Z,{}),(0,a.jsx)(z.Z,{children:"Slack Webhook URL"})]})}),(0,a.jsx)(L.Z,{children:Object.entries(eo).map((e,l)=>{let[s,t]=e;return(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(U.Z,{children:"region_outage_alerts"==s?n?(0,a.jsx)(eL.Z,{id:"switch",name:"switch",checked:ed(s),onChange:()=>ei(s)}):(0,a.jsx)(p.Z,{className:"flex items-center justify-center",children:(0,a.jsx)("a",{href:"https://forms.gle/W3U4PZpJGFHWtHyA9",target:"_blank",children:"✨ Enterprise Feature"})}):(0,a.jsx)(eL.Z,{id:"switch",name:"switch",checked:ed(s),onChange:()=>ei(s)})}),(0,a.jsx)(U.Z,{children:(0,a.jsx)(_.Z,{children:t})}),(0,a.jsx)(U.Z,{children:(0,a.jsx)(j.Z,{name:s,type:"password",defaultValue:C&&C[s]?C[s]:N})})]},l)})})]}),(0,a.jsx)(p.Z,{size:"xs",className:"mt-2",onClick:()=>{if(!l)return;let e={};Object.entries(eo).forEach(l=>{let[s,t]=l,n=document.querySelector('input[name="'.concat(s,'"]'));console.log("key",s),console.log("webhookInput",n);let a=(null==n?void 0:n.value)||"";console.log("newWebhookValue",a),e[s]=a}),console.log("updatedAlertToWebhooks",e);let s={general_settings:{alert_to_webhook_url:e,alert_types:T}};console.log("payload",s);try{(0,u.K_)(l,s)}catch(e){k.ZP.error("Failed to update alerts: "+e,20)}k.ZP.success("Alerts updated successfully")},children:"Save Changes"}),(0,a.jsx)(p.Z,{onClick:()=>(0,u.jE)(l,"slack"),className:"mx-2",children:"Test Alerts"})]})}),(0,a.jsx)(ea.Z,{children:(0,a.jsx)(ez,{accessToken:l,premiumUser:n})}),(0,a.jsx)(ea.Z,{children:(0,a.jsxs)(M.Z,{children:[(0,a.jsx)(eB,{level:4,children:"Email Settings"}),(0,a.jsxs)(_.Z,{children:[(0,a.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/email",target:"_blank",style:{color:"blue"},children:" LiteLLM Docs: email alerts"})," ",(0,a.jsx)("br",{})]}),(0,a.jsx)("div",{className:"flex w-full",children:d.filter(e=>"email"===e.name).map((e,l)=>{var s;return(0,a.jsx)(U.Z,{children:(0,a.jsx)("ul",{children:(0,a.jsx)(x.Z,{numItems:2,children:Object.entries(null!==(s=e.variables)&&void 0!==s?s:{}).map(e=>{let[l,s]=e;return(0,a.jsxs)("li",{className:"mx-2 my-2",children:[!0!=n&&("EMAIL_LOGO_URL"===l||"EMAIL_SUPPORT_CONTACT"===l)?(0,a.jsxs)("div",{children:[(0,a.jsx)("a",{href:"https://forms.gle/W3U4PZpJGFHWtHyA9",target:"_blank",children:(0,a.jsxs)(_.Z,{className:"mt-2",children:[" ","✨ ",l]})}),(0,a.jsx)(j.Z,{name:l,defaultValue:s,type:"password",disabled:!0,style:{width:"400px"}})]}):(0,a.jsxs)("div",{children:[(0,a.jsx)(_.Z,{className:"mt-2",children:l}),(0,a.jsx)(j.Z,{name:l,defaultValue:s,type:"password",style:{width:"400px"}})]}),(0,a.jsxs)("p",{style:{fontSize:"small",fontStyle:"italic"},children:["SMTP_HOST"===l&&(0,a.jsxs)("div",{style:{color:"gray"},children:["Enter the SMTP host address, e.g. `smtp.resend.com`",(0,a.jsx)("span",{style:{color:"red"},children:" Required * "})]}),"SMTP_PORT"===l&&(0,a.jsxs)("div",{style:{color:"gray"},children:["Enter the SMTP port number, e.g. `587`",(0,a.jsx)("span",{style:{color:"red"},children:" Required * "})]}),"SMTP_USERNAME"===l&&(0,a.jsxs)("div",{style:{color:"gray"},children:["Enter the SMTP username, e.g. `username`",(0,a.jsx)("span",{style:{color:"red"},children:" Required * "})]}),"SMTP_PASSWORD"===l&&(0,a.jsx)("span",{style:{color:"red"},children:" Required * "}),"SMTP_SENDER_EMAIL"===l&&(0,a.jsxs)("div",{style:{color:"gray"},children:["Enter the sender email address, e.g. `sender@berri.ai`",(0,a.jsx)("span",{style:{color:"red"},children:" Required * "})]}),"TEST_EMAIL_ADDRESS"===l&&(0,a.jsxs)("div",{style:{color:"gray"},children:["Email Address to send `Test Email Alert` to. example: `info@berri.ai`",(0,a.jsx)("span",{style:{color:"red"},children:" Required * "})]}),"EMAIL_LOGO_URL"===l&&(0,a.jsx)("div",{style:{color:"gray"},children:"(Optional) Customize the Logo that appears in the email, pass a url to your logo"}),"EMAIL_SUPPORT_CONTACT"===l&&(0,a.jsx)("div",{style:{color:"gray"},children:"(Optional) Customize the support email address that appears in the email. Default is support@berri.ai"})]})]},l)})})})},l)})}),(0,a.jsx)(p.Z,{className:"mt-2",onClick:()=>ec(),children:"Save Changes"}),(0,a.jsx)(p.Z,{onClick:()=>(0,u.jE)(l,"email"),className:"mx-2",children:"Test Email Alerts"})]})})]})]})}),(0,a.jsxs)(w.Z,{title:"Add Logging Callback",visible:R,width:800,onCancel:()=>B(!1),footer:null,children:[(0,a.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/logging",className:"mb-8 mt-4",target:"_blank",style:{color:"blue"},children:" LiteLLM Docs: Logging"}),(0,a.jsx)(S.Z,{form:g,onFinish:eu,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(eq.Z,{label:"Callback",name:"callback",rules:[{required:!0,message:"Please select a callback"}],children:(0,a.jsx)(v.default,{onChange:e=>{let l=W[e];l&&(console.log(l.ui_callback_name),eh(l))},children:W&&Object.values(W).map(e=>(0,a.jsx)(K.Z,{value:e.litellm_callback_name,children:e.ui_callback_name},e.litellm_callback_name))})}),J&&J.map(e=>(0,a.jsx)(eq.Z,{label:e,name:e,rules:[{required:!0,message:"Please enter the value for "+e}],children:(0,a.jsx)(j.Z,{type:"password"})},e)),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(I.ZP,{htmlType:"submit",children:"Save"})})]})})]}),(0,a.jsx)(w.Z,{visible:$,width:800,title:"Edit ".concat(null==ee?void 0:ee.name," Settings"),onCancel:()=>Q(!1),footer:null,children:(0,a.jsxs)(S.Z,{form:g,onFinish:em,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsx)(a.Fragment,{children:ee&&ee.variables&&Object.entries(ee.variables).map(e=>{let[l,s]=e;return(0,a.jsx)(eq.Z,{label:l,name:l,children:(0,a.jsx)(j.Z,{type:"password",defaultValue:s})},l)})}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(I.ZP,{htmlType:"submit",children:"Save"})})]})})]})):null};let{Option:eH}=v.default;var eG=e=>{let{models:l,accessToken:s,routerSettings:t,setRouterSettings:n}=e,[i]=S.Z.useForm(),[o,d]=(0,r.useState)(!1),[c,m]=(0,r.useState)("");return(0,a.jsxs)("div",{children:[(0,a.jsx)(p.Z,{className:"mx-auto",onClick:()=>d(!0),children:"+ Add Fallbacks"}),(0,a.jsx)(w.Z,{title:"Add Fallbacks",visible:o,width:800,footer:null,onOk:()=>{d(!1),i.resetFields()},onCancel:()=>{d(!1),i.resetFields()},children:(0,a.jsxs)(S.Z,{form:i,onFinish:e=>{console.log(e);let{model_name:l,models:a}=e,r=[...t.fallbacks||[],{[l]:a}],o={...t,fallbacks:r};console.log(o);try{(0,u.K_)(s,{router_settings:o}),n(o)}catch(e){k.ZP.error("Failed to update router settings: "+e,20)}k.ZP.success("router settings updated successfully"),d(!1),i.resetFields()},labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(S.Z.Item,{label:"Public Model Name",name:"model_name",rules:[{required:!0,message:"Set the model to fallback for"}],help:"required",children:(0,a.jsx)(B.Z,{defaultValue:c,children:l&&l.map((e,l)=>(0,a.jsx)(K.Z,{value:e,onClick:()=>m(e),children:e},l))})}),(0,a.jsx)(S.Z.Item,{label:"Fallback Models",name:"models",rules:[{required:!0,message:"Please select a model"}],help:"required",children:(0,a.jsx)(ei.Z,{value:l,children:l&&l.filter(e=>e!=c).map(e=>(0,a.jsx)(eo.Z,{value:e,children:e},e))})})]}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(I.ZP,{htmlType:"submit",children:"Add Fallbacks"})})]})})]})},eY=s(12968);async function eJ(e,l){console.log("isLocal:",!1);let s=window.location.origin,t=new eY.ZP.OpenAI({apiKey:l,baseURL:s,dangerouslyAllowBrowser:!0});try{let l=await t.chat.completions.create({model:e,messages:[{role:"user",content:"Hi, this is a test message"}],mock_testing_fallbacks:!0});k.ZP.success((0,a.jsxs)("span",{children:["Test model=",(0,a.jsx)("strong",{children:e}),", received model=",(0,a.jsx)("strong",{children:l.model}),". See"," ",(0,a.jsx)("a",{href:"#",onClick:()=>window.open("https://docs.litellm.ai/docs/proxy/reliability","_blank"),style:{textDecoration:"underline",color:"blue"},children:"curl"})]}))}catch(e){k.ZP.error("Error occurred while generating model response. Please try again. Error: ".concat(e),20)}}let eX={ttl:3600,lowest_latency_buffer:0},e$=e=>{let{selectedStrategy:l,strategyArgs:s,paramExplanation:t}=e;return(0,a.jsxs)(g.Z,{children:[(0,a.jsx)(f.Z,{className:"text-sm font-medium text-tremor-content-strong dark:text-dark-tremor-content-strong",children:"Routing Strategy Specific Args"}),(0,a.jsx)(Z.Z,{children:"latency-based-routing"==l?(0,a.jsx)(M.Z,{children:(0,a.jsxs)(D.Z,{children:[(0,a.jsx)(V.Z,{children:(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(z.Z,{children:"Setting"}),(0,a.jsx)(z.Z,{children:"Value"})]})}),(0,a.jsx)(L.Z,{children:Object.entries(s).map(e=>{let[l,s]=e;return(0,a.jsxs)(q.Z,{children:[(0,a.jsxs)(U.Z,{children:[(0,a.jsx)(_.Z,{children:l}),(0,a.jsx)("p",{style:{fontSize:"0.65rem",color:"#808080",fontStyle:"italic"},className:"mt-1",children:t[l]})]}),(0,a.jsx)(U.Z,{children:(0,a.jsx)(j.Z,{name:l,defaultValue:"object"==typeof s?JSON.stringify(s,null,2):s.toString()})})]},l)})})]})}):(0,a.jsx)(_.Z,{children:"No specific settings"})})]})};var eQ=e=>{let{accessToken:l,userRole:s,userID:t,modelData:n}=e,[i,o]=(0,r.useState)({}),[d,c]=(0,r.useState)({}),[m,g]=(0,r.useState)([]),[Z,f]=(0,r.useState)(!1),[b]=S.Z.useForm(),[v,w]=(0,r.useState)(null),[N,I]=(0,r.useState)(null),[C,P]=(0,r.useState)(null),T={routing_strategy_args:"(dict) Arguments to pass to the routing strategy",routing_strategy:"(string) Routing strategy to use",allowed_fails:"(int) Number of times a deployment can fail before being added to cooldown",cooldown_time:"(int) time in seconds to cooldown a deployment after failure",num_retries:"(int) Number of retries for failed requests. Defaults to 0.",timeout:"(float) Timeout for requests. Defaults to None.",retry_after:"(int) Minimum time to wait before retrying a failed request",ttl:"(int) Sliding window to look back over when calculating the average latency of a deployment. Default - 1 hour (in seconds).",lowest_latency_buffer:"(float) Shuffle between deployments within this % of the lowest latency. Default - 0 (i.e. always pick lowest latency)."};(0,r.useEffect)(()=>{l&&s&&t&&((0,u.BL)(l,t,s).then(e=>{console.log("callbacks",e),o(e.router_settings)}),(0,u.YU)(l).then(e=>{g(e)}))},[l,s,t]);let O=async e=>{if(l){console.log("received key: ".concat(e)),console.log("routerSettings['fallbacks']: ".concat(i.fallbacks)),i.fallbacks.map(l=>(e in l&&delete l[e],l));try{await (0,u.K_)(l,{router_settings:i}),o({...i}),I(i.routing_strategy),k.ZP.success("Router settings updated successfully")}catch(e){k.ZP.error("Failed to update router settings: "+e,20)}}},W=(e,l)=>{g(m.map(s=>s.field_name===e?{...s,field_value:l}:s))},H=(e,s)=>{if(!l)return;let t=m[s].field_value;if(null!=t&&void 0!=t)try{(0,u.jA)(l,e,t);let s=m.map(l=>l.field_name===e?{...l,stored_in_db:!0}:l);g(s)}catch(e){}},G=(e,s)=>{if(l)try{(0,u.ao)(l,e);let s=m.map(l=>l.field_name===e?{...l,stored_in_db:null,field_value:null}:l);g(s)}catch(e){}},Y=e=>{if(!l)return;console.log("router_settings",e);let s=Object.fromEntries(Object.entries(e).map(e=>{let[l,s]=e;if("routing_strategy_args"!==l&&"routing_strategy"!==l){var t;return[l,(null===(t=document.querySelector('input[name="'.concat(l,'"]')))||void 0===t?void 0:t.value)||s]}if("routing_strategy"==l)return[l,N];if("routing_strategy_args"==l&&"latency-based-routing"==N){let e={},l=document.querySelector('input[name="lowest_latency_buffer"]'),s=document.querySelector('input[name="ttl"]');return(null==l?void 0:l.value)&&(e.lowest_latency_buffer=Number(l.value)),(null==s?void 0:s.value)&&(e.ttl=Number(s.value)),console.log("setRoutingStrategyArgs: ".concat(e)),["routing_strategy_args",e]}return null}).filter(e=>null!=e));console.log("updatedVariables",s);try{(0,u.K_)(l,{router_settings:s})}catch(e){k.ZP.error("Failed to update router settings: "+e,20)}k.ZP.success("router settings updated successfully")};return l?(0,a.jsx)("div",{className:"w-full mx-4",children:(0,a.jsxs)(et.Z,{className:"gap-2 p-8 h-[75vh] w-full mt-2",children:[(0,a.jsxs)(en.Z,{variant:"line",defaultValue:"1",children:[(0,a.jsx)(es.Z,{value:"1",children:"Loadbalancing"}),(0,a.jsx)(es.Z,{value:"2",children:"Fallbacks"}),(0,a.jsx)(es.Z,{value:"3",children:"General"})]}),(0,a.jsxs)(er.Z,{children:[(0,a.jsx)(ea.Z,{children:(0,a.jsxs)(x.Z,{numItems:1,className:"gap-2 p-8 w-full mt-2",children:[(0,a.jsx)(y.Z,{children:"Router Settings"}),(0,a.jsxs)(M.Z,{children:[(0,a.jsxs)(D.Z,{children:[(0,a.jsx)(V.Z,{children:(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(z.Z,{children:"Setting"}),(0,a.jsx)(z.Z,{children:"Value"})]})}),(0,a.jsx)(L.Z,{children:Object.entries(i).filter(e=>{let[l,s]=e;return"fallbacks"!=l&&"context_window_fallbacks"!=l&&"routing_strategy_args"!=l}).map(e=>{let[l,s]=e;return(0,a.jsxs)(q.Z,{children:[(0,a.jsxs)(U.Z,{children:[(0,a.jsx)(_.Z,{children:l}),(0,a.jsx)("p",{style:{fontSize:"0.65rem",color:"#808080",fontStyle:"italic"},className:"mt-1",children:T[l]})]}),(0,a.jsx)(U.Z,{children:"routing_strategy"==l?(0,a.jsxs)(B.Z,{defaultValue:s,className:"w-full max-w-md",onValueChange:I,children:[(0,a.jsx)(K.Z,{value:"usage-based-routing",children:"usage-based-routing"}),(0,a.jsx)(K.Z,{value:"latency-based-routing",children:"latency-based-routing"}),(0,a.jsx)(K.Z,{value:"simple-shuffle",children:"simple-shuffle"})]}):(0,a.jsx)(j.Z,{name:l,defaultValue:"object"==typeof s?JSON.stringify(s,null,2):s.toString()})})]},l)})})]}),(0,a.jsx)(e$,{selectedStrategy:N,strategyArgs:i&&i.routing_strategy_args&&Object.keys(i.routing_strategy_args).length>0?i.routing_strategy_args:eX,paramExplanation:T})]}),(0,a.jsx)(h.Z,{children:(0,a.jsx)(p.Z,{className:"mt-2",onClick:()=>Y(i),children:"Save Changes"})})]})}),(0,a.jsxs)(ea.Z,{children:[(0,a.jsxs)(D.Z,{children:[(0,a.jsx)(V.Z,{children:(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(z.Z,{children:"Model Name"}),(0,a.jsx)(z.Z,{children:"Fallbacks"})]})}),(0,a.jsx)(L.Z,{children:i.fallbacks&&i.fallbacks.map((e,s)=>Object.entries(e).map(e=>{let[t,n]=e;return(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(U.Z,{children:t}),(0,a.jsx)(U.Z,{children:Array.isArray(n)?n.join(", "):n}),(0,a.jsx)(U.Z,{children:(0,a.jsx)(p.Z,{onClick:()=>eJ(t,l),children:"Test Fallback"})}),(0,a.jsx)(U.Z,{children:(0,a.jsx)(F.Z,{icon:E.Z,size:"sm",onClick:()=>O(t)})})]},s.toString()+t)}))})]}),(0,a.jsx)(eG,{models:(null==n?void 0:n.data)?n.data.map(e=>e.model_name):[],accessToken:l,routerSettings:i,setRouterSettings:o})]}),(0,a.jsx)(ea.Z,{children:(0,a.jsx)(M.Z,{children:(0,a.jsxs)(D.Z,{children:[(0,a.jsx)(V.Z,{children:(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(z.Z,{children:"Setting"}),(0,a.jsx)(z.Z,{children:"Value"}),(0,a.jsx)(z.Z,{children:"Status"}),(0,a.jsx)(z.Z,{children:"Action"})]})}),(0,a.jsx)(L.Z,{children:m.map((e,l)=>(0,a.jsxs)(q.Z,{children:[(0,a.jsxs)(U.Z,{children:[(0,a.jsx)(_.Z,{children:e.field_name}),(0,a.jsx)("p",{style:{fontSize:"0.65rem",color:"#808080",fontStyle:"italic"},className:"mt-1",children:e.field_description})]}),(0,a.jsx)(U.Z,{children:"Integer"==e.field_type?(0,a.jsx)(A.Z,{step:1,value:e.field_value,onChange:l=>W(e.field_name,l)}):null}),(0,a.jsx)(U.Z,{children:!0==e.stored_in_db?(0,a.jsx)(R.Z,{icon:eU.Z,className:"text-white",children:"In DB"}):!1==e.stored_in_db?(0,a.jsx)(R.Z,{className:"text-gray bg-white outline",children:"In Config"}):(0,a.jsx)(R.Z,{className:"text-gray bg-white outline",children:"Not Set"})}),(0,a.jsxs)(U.Z,{children:[(0,a.jsx)(p.Z,{onClick:()=>H(e.field_name,l),children:"Update"}),(0,a.jsx)(F.Z,{icon:E.Z,color:"red",onClick:()=>G(e.field_name,l),children:"Reset"})]})]},l))})]})})})]})]})}):null},e0=e=>{let{isModalVisible:l,accessToken:s,setIsModalVisible:t,setBudgetList:n}=e,[r]=S.Z.useForm(),i=async e=>{if(null!=s&&void 0!=s)try{k.ZP.info("Making API Call");let l=await (0,u.Zr)(s,e);console.log("key create Response:",l),n(e=>e?[...e,l]:[l]),k.ZP.success("API Key Created"),r.resetFields()}catch(e){console.error("Error creating the key:",e),k.ZP.error("Error creating the key: ".concat(e),20)}};return(0,a.jsx)(w.Z,{title:"Create Budget",visible:l,width:800,footer:null,onOk:()=>{t(!1),r.resetFields()},onCancel:()=>{t(!1),r.resetFields()},children:(0,a.jsxs)(S.Z,{form:r,onFinish:i,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(S.Z.Item,{label:"Budget ID",name:"budget_id",rules:[{required:!0,message:"Please input a human-friendly name for the budget"}],help:"A human-friendly name for the budget",children:(0,a.jsx)(j.Z,{placeholder:""})}),(0,a.jsx)(S.Z.Item,{label:"Max Tokens per minute",name:"tpm_limit",help:"Default is model limit.",children:(0,a.jsx)(A.Z,{step:1,precision:2,width:200})}),(0,a.jsx)(S.Z.Item,{label:"Max Requests per minute",name:"rpm_limit",help:"Default is model limit.",children:(0,a.jsx)(A.Z,{step:1,precision:2,width:200})}),(0,a.jsxs)(g.Z,{className:"mt-20 mb-8",children:[(0,a.jsx)(f.Z,{children:(0,a.jsx)("b",{children:"Optional Settings"})}),(0,a.jsxs)(Z.Z,{children:[(0,a.jsx)(S.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,a.jsx)(A.Z,{step:.01,precision:2,width:200})}),(0,a.jsx)(S.Z.Item,{className:"mt-8",label:"Reset Budget",name:"budget_duration",children:(0,a.jsxs)(v.default,{defaultValue:null,placeholder:"n/a",children:[(0,a.jsx)(v.default.Option,{value:"24h",children:"daily"}),(0,a.jsx)(v.default.Option,{value:"7d",children:"weekly"}),(0,a.jsx)(v.default.Option,{value:"30d",children:"monthly"})]})})]})]})]}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(I.ZP,{htmlType:"submit",children:"Create Budget"})})]})})},e1=e=>{let{isModalVisible:l,accessToken:s,setIsModalVisible:t,setBudgetList:n,existingBudget:r}=e,[i]=S.Z.useForm(),o=async e=>{if(null!=s&&void 0!=s)try{k.ZP.info("Making API Call");let l=await (0,u.Zr)(s,e);console.log("key create Response:",l),n(e=>e?[...e,l]:[l]),k.ZP.success("API Key Created"),i.resetFields()}catch(e){console.error("Error creating the key:",e),k.ZP.error("Error creating the key: ".concat(e),20)}};return(0,a.jsx)(w.Z,{title:"Edit Budget",visible:l,width:800,footer:null,onOk:()=>{t(!1),i.resetFields()},onCancel:()=>{t(!1),i.resetFields()},children:(0,a.jsxs)(S.Z,{form:i,onFinish:o,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",initialValues:r,children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(S.Z.Item,{label:"Budget ID",name:"budget_id",rules:[{required:!0,message:"Please input a human-friendly name for the budget"}],help:"A human-friendly name for the budget",children:(0,a.jsx)(j.Z,{placeholder:""})}),(0,a.jsx)(S.Z.Item,{label:"Max Tokens per minute",name:"tpm_limit",help:"Default is model limit.",children:(0,a.jsx)(A.Z,{step:1,precision:2,width:200})}),(0,a.jsx)(S.Z.Item,{label:"Max Requests per minute",name:"rpm_limit",help:"Default is model limit.",children:(0,a.jsx)(A.Z,{step:1,precision:2,width:200})}),(0,a.jsxs)(g.Z,{className:"mt-20 mb-8",children:[(0,a.jsx)(f.Z,{children:(0,a.jsx)("b",{children:"Optional Settings"})}),(0,a.jsxs)(Z.Z,{children:[(0,a.jsx)(S.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,a.jsx)(A.Z,{step:.01,precision:2,width:200})}),(0,a.jsx)(S.Z.Item,{className:"mt-8",label:"Reset Budget",name:"budget_duration",children:(0,a.jsxs)(v.default,{defaultValue:null,placeholder:"n/a",children:[(0,a.jsx)(v.default.Option,{value:"24h",children:"daily"}),(0,a.jsx)(v.default.Option,{value:"7d",children:"weekly"}),(0,a.jsx)(v.default.Option,{value:"30d",children:"monthly"})]})})]})]})]}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(I.ZP,{htmlType:"submit",children:"Edit Budget"})})]})})},e2=e=>{let{accessToken:l}=e,[s,t]=(0,r.useState)(!1),[n,i]=(0,r.useState)(!1),[o,d]=(0,r.useState)(null),[c,m]=(0,r.useState)([]);(0,r.useEffect)(()=>{l&&(0,u.O3)(l).then(e=>{m(e)})},[l]);let h=async(e,s)=>{null!=l&&(d(c[s]),i(!0))},x=async(e,s)=>{if(null==l)return;k.ZP.info("Request made"),await (0,u.NV)(l,e);let t=[...c];t.splice(s,1),m(t),k.ZP.success("Budget Deleted.")};return(0,a.jsxs)("div",{className:"w-full mx-auto flex-auto overflow-y-auto m-8 p-2",children:[(0,a.jsx)(p.Z,{size:"sm",variant:"primary",className:"mb-2",onClick:()=>t(!0),children:"+ Create Budget"}),(0,a.jsx)(e0,{accessToken:l,isModalVisible:s,setIsModalVisible:t,setBudgetList:m}),o&&(0,a.jsx)(e1,{accessToken:l,isModalVisible:n,setIsModalVisible:i,setBudgetList:m,existingBudget:o}),(0,a.jsxs)(M.Z,{children:[(0,a.jsx)(_.Z,{children:"Create a budget to assign to customers."}),(0,a.jsxs)(D.Z,{children:[(0,a.jsx)(V.Z,{children:(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(z.Z,{children:"Budget ID"}),(0,a.jsx)(z.Z,{children:"Max Budget"}),(0,a.jsx)(z.Z,{children:"TPM"}),(0,a.jsx)(z.Z,{children:"RPM"})]})}),(0,a.jsx)(L.Z,{children:c.map((e,l)=>(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(U.Z,{children:e.budget_id}),(0,a.jsx)(U.Z,{children:e.max_budget?e.max_budget:"n/a"}),(0,a.jsx)(U.Z,{children:e.tpm_limit?e.tpm_limit:"n/a"}),(0,a.jsx)(U.Z,{children:e.rpm_limit?e.rpm_limit:"n/a"}),(0,a.jsx)(F.Z,{icon:O.Z,size:"sm",onClick:()=>h(e.budget_id,l)}),(0,a.jsx)(F.Z,{icon:E.Z,size:"sm",onClick:()=>x(e.budget_id,l)})]},l))})]})]}),(0,a.jsxs)("div",{className:"mt-5",children:[(0,a.jsx)(_.Z,{className:"text-base",children:"How to use budget id"}),(0,a.jsxs)(et.Z,{children:[(0,a.jsxs)(en.Z,{children:[(0,a.jsx)(es.Z,{children:"Assign Budget to Customer"}),(0,a.jsx)(es.Z,{children:"Test it (Curl)"}),(0,a.jsx)(es.Z,{children:"Test it (OpenAI SDK)"})]}),(0,a.jsxs)(er.Z,{children:[(0,a.jsx)(ea.Z,{children:(0,a.jsx)(ek.Z,{language:"bash",children:"\ncurl -X POST --location '/end_user/new' \n-H 'Authorization: Bearer ' \n-H 'Content-Type: application/json' \n-d '{\"user_id\": \"my-customer-id', \"budget_id\": \"\"}' # \uD83D\uDC48 KEY CHANGE\n\n "})}),(0,a.jsx)(ea.Z,{children:(0,a.jsx)(ek.Z,{language:"bash",children:'\ncurl -X POST --location \'/chat/completions\' \n-H \'Authorization: Bearer \' \n-H \'Content-Type: application/json\' \n-d \'{\n "model": "gpt-3.5-turbo\', \n "messages":[{"role": "user", "content": "Hey, how\'s it going?"}],\n "user": "my-customer-id"\n}\' # \uD83D\uDC48 KEY CHANGE\n\n '})}),(0,a.jsx)(ea.Z,{children:(0,a.jsx)(ek.Z,{language:"python",children:'from openai import OpenAI\nclient = OpenAI(\n base_url="{let{proxySettings:l}=e,s="http://localhost:4000";return l&&l.PROXY_BASE_URL&&void 0!==l.PROXY_BASE_URL&&(s=l.PROXY_BASE_URL),(0,a.jsx)(a.Fragment,{children:(0,a.jsx)(x.Z,{className:"gap-2 p-8 h-[80vh] w-full mt-2",children:(0,a.jsxs)("div",{className:"mb-5",children:[(0,a.jsx)("p",{className:"text-2xl text-tremor-content-strong dark:text-dark-tremor-content-strong font-semibold",children:"OpenAI Compatible Proxy: API Reference"}),(0,a.jsx)(_.Z,{className:"mt-2 mb-2",children:"LiteLLM is OpenAI Compatible. This means your API Key works with the OpenAI SDK. Just replace the base_url to point to your litellm proxy. Example Below "}),(0,a.jsxs)(et.Z,{children:[(0,a.jsxs)(en.Z,{children:[(0,a.jsx)(es.Z,{children:"OpenAI Python SDK"}),(0,a.jsx)(es.Z,{children:"LlamaIndex"}),(0,a.jsx)(es.Z,{children:"Langchain Py"})]}),(0,a.jsxs)(er.Z,{children:[(0,a.jsx)(ea.Z,{children:(0,a.jsx)(ek.Z,{language:"python",children:'\nimport openai\nclient = openai.OpenAI(\n api_key="your_api_key",\n base_url="'.concat(s,'" # LiteLLM Proxy is OpenAI compatible, Read More: https://docs.litellm.ai/docs/proxy/user_keys\n)\n\nresponse = client.chat.completions.create(\n model="gpt-3.5-turbo", # model to send to the proxy\n messages = [\n {\n "role": "user",\n "content": "this is a test request, write a short poem"\n }\n ]\n)\n\nprint(response)\n ')})}),(0,a.jsx)(ea.Z,{children:(0,a.jsx)(ek.Z,{language:"python",children:'\nimport os, dotenv\n\nfrom llama_index.llms import AzureOpenAI\nfrom llama_index.embeddings import AzureOpenAIEmbedding\nfrom llama_index import VectorStoreIndex, SimpleDirectoryReader, ServiceContext\n\nllm = AzureOpenAI(\n engine="azure-gpt-3.5", # model_name on litellm proxy\n temperature=0.0,\n azure_endpoint="'.concat(s,'", # litellm proxy endpoint\n api_key="sk-1234", # litellm proxy API Key\n api_version="2023-07-01-preview",\n)\n\nembed_model = AzureOpenAIEmbedding(\n deployment_name="azure-embedding-model",\n azure_endpoint="').concat(s,'",\n api_key="sk-1234",\n api_version="2023-07-01-preview",\n)\n\n\ndocuments = SimpleDirectoryReader("llama_index_data").load_data()\nservice_context = ServiceContext.from_defaults(llm=llm, embed_model=embed_model)\nindex = VectorStoreIndex.from_documents(documents, service_context=service_context)\n\nquery_engine = index.as_query_engine()\nresponse = query_engine.query("What did the author do growing up?")\nprint(response)\n\n ')})}),(0,a.jsx)(ea.Z,{children:(0,a.jsx)(ek.Z,{language:"python",children:'\nfrom langchain.chat_models import ChatOpenAI\nfrom langchain.prompts.chat import (\n ChatPromptTemplate,\n HumanMessagePromptTemplate,\n SystemMessagePromptTemplate,\n)\nfrom langchain.schema import HumanMessage, SystemMessage\n\nchat = ChatOpenAI(\n openai_api_base="'.concat(s,'",\n model = "gpt-3.5-turbo",\n temperature=0.1\n)\n\nmessages = [\n SystemMessage(\n content="You are a helpful assistant that im using to make a test request to."\n ),\n HumanMessage(\n content="test from litellm. tell me why it\'s amazing in 1 sentence"\n ),\n]\nresponse = chat(messages)\n\nprint(response)\n\n ')})})]})]})]})})})};async function e8(e,l,s,t){console.log("isLocal:",!1);let n=window.location.origin,a=new eY.ZP.OpenAI({apiKey:t,baseURL:n,dangerouslyAllowBrowser:!0});try{for await(let t of(await a.chat.completions.create({model:s,stream:!0,messages:[{role:"user",content:e}]})))console.log(t),t.choices[0].delta.content&&l(t.choices[0].delta.content)}catch(e){k.ZP.error("Error occurred while generating model response. Please try again. Error: ".concat(e),20)}}var e3=e=>{let{accessToken:l,token:s,userRole:t,userID:n}=e,[i,o]=(0,r.useState)(""),[d,c]=(0,r.useState)(""),[m,g]=(0,r.useState)([]),[Z,f]=(0,r.useState)(void 0),[y,b]=(0,r.useState)([]);(0,r.useEffect)(()=>{l&&s&&t&&n&&(async()=>{try{let e=await (0,u.So)(l,n,t);if(console.log("model_info:",e),(null==e?void 0:e.data.length)>0){let l=e.data.map(e=>({value:e.id,label:e.id}));if(console.log(l),l.length>0){let e=Array.from(new Set(l));console.log("Unique models:",e),e.sort((e,l)=>e.label.localeCompare(l.label)),console.log("Model info:",y),b(e)}f(e.data[0].id)}}catch(e){console.error("Error fetching model info:",e)}})()},[l,n,t]);let S=(e,l)=>{g(s=>{let t=s[s.length-1];return t&&t.role===e?[...s.slice(0,s.length-1),{role:e,content:t.content+l}]:[...s,{role:e,content:l}]})},k=async()=>{if(""!==d.trim()&&i&&s&&t&&n){g(e=>[...e,{role:"user",content:d}]);try{Z&&await e8(d,e=>S("assistant",e),Z,i)}catch(e){console.error("Error fetching model response",e),S("assistant","Error fetching model response")}c("")}};if(t&&"Admin Viewer"==t){let{Title:e,Paragraph:l}=$.default;return(0,a.jsxs)("div",{children:[(0,a.jsx)(e,{level:1,children:"Access Denied"}),(0,a.jsx)(l,{children:"Ask your proxy admin for access to test models"})]})}return(0,a.jsx)("div",{style:{width:"100%",position:"relative"},children:(0,a.jsx)(x.Z,{className:"gap-2 p-8 h-[80vh] w-full mt-2",children:(0,a.jsx)(M.Z,{children:(0,a.jsxs)(et.Z,{children:[(0,a.jsx)(en.Z,{children:(0,a.jsx)(es.Z,{children:"Chat"})}),(0,a.jsx)(er.Z,{children:(0,a.jsxs)(ea.Z,{children:[(0,a.jsx)("div",{className:"sm:max-w-2xl",children:(0,a.jsxs)(x.Z,{numItems:2,children:[(0,a.jsxs)(h.Z,{children:[(0,a.jsx)(_.Z,{children:"API Key"}),(0,a.jsx)(j.Z,{placeholder:"Type API Key here",type:"password",onValueChange:o,value:i})]}),(0,a.jsxs)(h.Z,{className:"mx-2",children:[(0,a.jsx)(_.Z,{children:"Select Model:"}),(0,a.jsx)(v.default,{placeholder:"Select a Model",onChange:e=>{console.log("selected ".concat(e)),f(e)},options:y,style:{width:"200px"}})]})]})}),(0,a.jsxs)(D.Z,{className:"mt-5",style:{display:"block",maxHeight:"60vh",overflowY:"auto"},children:[(0,a.jsx)(V.Z,{children:(0,a.jsx)(q.Z,{children:(0,a.jsx)(U.Z,{})})}),(0,a.jsx)(L.Z,{children:m.map((e,l)=>(0,a.jsx)(q.Z,{children:(0,a.jsx)(U.Z,{children:"".concat(e.role,": ").concat(e.content)})},l))})]}),(0,a.jsx)("div",{className:"mt-3",style:{position:"absolute",bottom:5,width:"95%"},children:(0,a.jsxs)("div",{className:"flex",children:[(0,a.jsx)(j.Z,{type:"text",value:d,onChange:e=>c(e.target.value),onKeyDown:e=>{"Enter"===e.key&&k()},placeholder:"Type your message..."}),(0,a.jsx)(p.Z,{onClick:k,className:"ml-2",children:"Send"})]})})]})})]})})})})},e6=s(33509),e9=s(95781);let{Sider:e7}=e6.default;var le=e=>{let{setPage:l,userRole:s,defaultSelectedKey:t}=e;return"Admin Viewer"==s?(0,a.jsx)(e6.default,{style:{minHeight:"100vh",maxWidth:"120px"},children:(0,a.jsx)(e7,{width:120,children:(0,a.jsx)(e9.Z,{mode:"inline",defaultSelectedKeys:t||["4"],style:{height:"100%",borderRight:0},children:(0,a.jsx)(e9.Z.Item,{onClick:()=>l("usage"),children:"Usage"},"1")})})}):(0,a.jsx)(e6.default,{style:{minHeight:"100vh",maxWidth:"145px"},children:(0,a.jsx)(e7,{width:145,children:(0,a.jsxs)(e9.Z,{mode:"inline",defaultSelectedKeys:t||["1"],style:{height:"100%",borderRight:0},children:[(0,a.jsx)(e9.Z.Item,{onClick:()=>l("api-keys"),children:(0,a.jsx)(_.Z,{children:"API Keys"})},"1"),(0,a.jsx)(e9.Z.Item,{onClick:()=>l("llm-playground"),children:(0,a.jsx)(_.Z,{children:"Test Key"})},"3"),"Admin"==s?(0,a.jsx)(e9.Z.Item,{onClick:()=>l("models"),children:(0,a.jsx)(_.Z,{children:"Models"})},"2"):null,"Admin"==s?(0,a.jsx)(e9.Z.Item,{onClick:()=>l("usage"),children:(0,a.jsx)(_.Z,{children:"Usage"})},"4"):null,"Admin"==s?(0,a.jsx)(e9.Z.Item,{onClick:()=>l("teams"),children:(0,a.jsx)(_.Z,{children:"Teams"})},"6"):null,"Admin"==s?(0,a.jsx)(e9.Z.Item,{onClick:()=>l("users"),children:(0,a.jsx)(_.Z,{children:"Internal Users"})},"5"):null,"Admin"==s?(0,a.jsx)(e9.Z.Item,{onClick:()=>l("settings"),children:(0,a.jsx)(_.Z,{children:"Logging & Alerts"})},"8"):null,"Admin"==s?(0,a.jsx)(e9.Z.Item,{onClick:()=>l("caching"),children:(0,a.jsx)(_.Z,{children:"Caching"})},"9"):null,"Admin"==s?(0,a.jsx)(e9.Z.Item,{onClick:()=>l("budgets"),children:(0,a.jsx)(_.Z,{children:"Budgets"})},"10"):null,"Admin"==s?(0,a.jsx)(e9.Z.Item,{onClick:()=>l("general-settings"),children:(0,a.jsx)(_.Z,{children:"Router Settings"})},"11"):null,"Admin"==s?(0,a.jsx)(e9.Z.Item,{onClick:()=>l("admin-panel"),children:(0,a.jsx)(_.Z,{children:"Admin"})},"12"):null,(0,a.jsx)(e9.Z.Item,{onClick:()=>l("api_ref"),children:(0,a.jsx)(_.Z,{children:"API Reference"})},"13"),(0,a.jsx)(e9.Z.Item,{onClick:()=>l("model-hub"),children:(0,a.jsx)(_.Z,{children:"Model Hub"})},"15")]})})})},ll=s(67989),ls=s(52703),lt=e=>{let{accessToken:l,token:s,userRole:t,userID:n,keys:i,premiumUser:o}=e,d=new Date,[c,m]=(0,r.useState)([]),[j,g]=(0,r.useState)([]),[Z,f]=(0,r.useState)([]),[b,v]=(0,r.useState)([]),[S,k]=(0,r.useState)([]),[w,N]=(0,r.useState)([]),[A,I]=(0,r.useState)([]),[C,P]=(0,r.useState)([]),[T,O]=(0,r.useState)([]),[E,R]=(0,r.useState)([]),[F,W]=(0,r.useState)({}),[H,Y]=(0,r.useState)([]),[J,X]=(0,r.useState)(""),[$,Q]=(0,r.useState)(["all-tags"]),[em,eu]=(0,r.useState)({from:new Date(Date.now()-6048e5),to:new Date}),eh=new Date(d.getFullYear(),d.getMonth(),1),ex=new Date(d.getFullYear(),d.getMonth()+1,0),ep=e_(eh),ej=e_(ex);function eg(e){return new Intl.NumberFormat("en-US",{maximumFractionDigits:0,notation:"compact",compactDisplay:"short"}).format(e)}console.log("keys in usage",i),console.log("premium user in usage",o),(0,r.useEffect)(()=>{ef(em.from,em.to)},[em,$]);let eZ=async(e,s,t)=>{if(!e||!s||!l)return;s.setHours(23,59,59,999),e.setHours(0,0,0,0),console.log("uiSelectedKey",t);let n=await (0,u.b1)(l,t,e.toISOString(),s.toISOString());console.log("End user data updated successfully",n),v(n)},ef=async(e,s)=>{e&&s&&l&&(s.setHours(23,59,59,999),e.setHours(0,0,0,0),N((await (0,u.J$)(l,e.toISOString(),s.toISOString(),0===$.length?void 0:$)).spend_per_tag),console.log("Tag spend data updated successfully"))};function e_(e){let l=e.getFullYear(),s=e.getMonth()+1,t=e.getDate();return"".concat(l,"-").concat(s<10?"0"+s:s,"-").concat(t<10?"0"+t:t)}return console.log("Start date is ".concat(ep)),console.log("End date is ".concat(ej)),(0,r.useEffect)(()=>{l&&s&&t&&n&&(async()=>{try{if(console.log("user role: ".concat(t)),"Admin"==t||"Admin Viewer"==t){var e,a;let t=await (0,u.FC)(l);m(t);let n=await (0,u.OU)(l,s,ep,ej);console.log("provider_spend",n),R(n);let r=(await (0,u.tN)(l)).map(e=>({key:(e.key_alias||e.key_name||e.api_key).substring(0,10),spend:e.total_spend}));g(r);let i=(await (0,u.Au)(l)).map(e=>({key:e.model,spend:e.total_spend}));f(i);let o=await (0,u.mR)(l);console.log("teamSpend",o),k(o.daily_spend),P(o.teams);let d=o.total_spend_per_team;d=d.map(e=>(e.name=e.team_id||"",e.value=e.total_spend||0,e.value=e.value.toFixed(2),e)),O(d);let c=await (0,u.X)(l);I(c.tag_names);let h=await (0,u.J$)(l,null===(e=em.from)||void 0===e?void 0:e.toISOString(),null===(a=em.to)||void 0===a?void 0:a.toISOString(),void 0);N(h.spend_per_tag);let x=await (0,u.b1)(l,null,void 0,void 0);v(x),console.log("spend/user result",x);let p=await (0,u.wd)(l,ep,ej);W(p);let j=await (0,u.xA)(l,ep,ej);console.log("global activity per model",j),Y(j)}else"App Owner"==t&&await (0,u.HK)(l,s,t,n,ep,ej).then(async e=>{if(console.log("result from spend logs call",e),"daily_spend"in e){let l=e.daily_spend;console.log("daily spend",l),m(l);let s=e.top_api_keys;g(s)}else{let s=(await (0,u.e2)(l,function(e){let l=[];e.forEach(e=>{Object.entries(e).forEach(e=>{let[s,t]=e;"spend"!==s&&"startTime"!==s&&"models"!==s&&"users"!==s&&l.push({key:s,spend:t})})}),l.sort((e,l)=>Number(l.spend)-Number(e.spend));let s=l.slice(0,5).map(e=>e.key);return console.log("topKeys: ".concat(Object.keys(s[0]))),s}(e))).info.map(e=>({key:(e.key_name||e.key_alias).substring(0,10),spend:e.spend}));g(s),m(e)}})}catch(e){console.error("There was an error fetching the data",e)}})()},[l,s,t,n,ep,ej]),(0,a.jsx)("div",{style:{width:"100%"},className:"p-8",children:(0,a.jsxs)(et.Z,{children:[(0,a.jsxs)(en.Z,{className:"mt-2",children:[(0,a.jsx)(es.Z,{children:"All Up"}),(0,a.jsx)(es.Z,{children:"Team Based Usage"}),(0,a.jsx)(es.Z,{children:"Customer Usage"}),(0,a.jsx)(es.Z,{children:"Tag Based Usage"})]}),(0,a.jsxs)(er.Z,{children:[(0,a.jsx)(ea.Z,{children:(0,a.jsxs)(et.Z,{children:[(0,a.jsxs)(en.Z,{variant:"solid",className:"mt-1",children:[(0,a.jsx)(es.Z,{children:"Cost"}),(0,a.jsx)(es.Z,{children:"Activity"})]}),(0,a.jsxs)(er.Z,{children:[(0,a.jsx)(ea.Z,{children:(0,a.jsxs)(x.Z,{numItems:2,className:"gap-2 h-[100vh] w-full",children:[(0,a.jsx)(G,{userID:n,userRole:t,accessToken:l,userSpend:null,selectedTeam:null}),(0,a.jsx)(h.Z,{numColSpan:2,children:(0,a.jsxs)(M.Z,{children:[(0,a.jsx)(y.Z,{children:"Monthly Spend"}),(0,a.jsx)(ec.Z,{data:c,index:"date",categories:["spend"],colors:["blue"],valueFormatter:e=>"$ ".concat(new Intl.NumberFormat("us").format(e).toString()),yAxisWidth:100,tickGap:5})]})}),(0,a.jsx)(h.Z,{numColSpan:1,children:(0,a.jsxs)(M.Z,{children:[(0,a.jsx)(y.Z,{children:"Top API Keys"}),(0,a.jsx)(ec.Z,{className:"mt-4 h-40",data:j,index:"key",categories:["spend"],colors:["blue"],yAxisWidth:80,tickGap:5,layout:"vertical",showXAxis:!1,showLegend:!1})]})}),(0,a.jsx)(h.Z,{numColSpan:1,children:(0,a.jsxs)(M.Z,{children:[(0,a.jsx)(y.Z,{children:"Top Models"}),(0,a.jsx)(ec.Z,{className:"mt-4 h-40",data:Z,index:"key",categories:["spend"],colors:["blue"],yAxisWidth:200,layout:"vertical",showXAxis:!1,showLegend:!1})]})}),(0,a.jsx)(h.Z,{numColSpan:1}),(0,a.jsx)(h.Z,{numColSpan:2,children:(0,a.jsxs)(M.Z,{className:"mb-2",children:[(0,a.jsx)(y.Z,{children:"✨ Spend by Provider"}),o?(0,a.jsx)(a.Fragment,{children:(0,a.jsxs)(x.Z,{numItems:2,children:[(0,a.jsx)(h.Z,{numColSpan:1,children:(0,a.jsx)(ls.Z,{className:"mt-4 h-40",variant:"pie",data:E,index:"provider",category:"spend"})}),(0,a.jsx)(h.Z,{numColSpan:1,children:(0,a.jsxs)(D.Z,{children:[(0,a.jsx)(V.Z,{children:(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(z.Z,{children:"Provider"}),(0,a.jsx)(z.Z,{children:"Spend"})]})}),(0,a.jsx)(L.Z,{children:E.map(e=>(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(U.Z,{children:e.provider}),(0,a.jsx)(U.Z,{children:1e-5>parseFloat(e.spend.toFixed(2))?"less than 0.00":e.spend.toFixed(2)})]},e.provider))})]})})]})}):(0,a.jsxs)("div",{children:[(0,a.jsx)("p",{className:"mb-2 text-gray-500 italic text-[12px]",children:"Upgrade to use this feature"}),(0,a.jsx)(p.Z,{variant:"primary",className:"mb-2",children:(0,a.jsx)("a",{href:"https://forms.gle/W3U4PZpJGFHWtHyA9",target:"_blank",children:"Get Free Trial"})})]})]})})]})}),(0,a.jsx)(ea.Z,{children:(0,a.jsxs)(x.Z,{numItems:1,className:"gap-2 h-[75vh] w-full",children:[(0,a.jsxs)(M.Z,{children:[(0,a.jsx)(y.Z,{children:"All Up"}),(0,a.jsxs)(x.Z,{numItems:2,children:[(0,a.jsxs)(h.Z,{children:[(0,a.jsxs)(ee.Z,{style:{fontSize:"15px",fontWeight:"normal",color:"#535452"},children:["API Requests ",eg(F.sum_api_requests)]}),(0,a.jsx)(ed.Z,{className:"h-40",data:F.daily_data,valueFormatter:eg,index:"date",colors:["cyan"],categories:["api_requests"],onValueChange:e=>console.log(e)})]}),(0,a.jsxs)(h.Z,{children:[(0,a.jsxs)(ee.Z,{style:{fontSize:"15px",fontWeight:"normal",color:"#535452"},children:["Tokens ",eg(F.sum_total_tokens)]}),(0,a.jsx)(ec.Z,{className:"h-40",data:F.daily_data,valueFormatter:eg,index:"date",colors:["cyan"],categories:["total_tokens"],onValueChange:e=>console.log(e)})]})]})]}),o?(0,a.jsx)(a.Fragment,{children:H.map((e,l)=>(0,a.jsxs)(M.Z,{children:[(0,a.jsx)(y.Z,{children:e.model}),(0,a.jsxs)(x.Z,{numItems:2,children:[(0,a.jsxs)(h.Z,{children:[(0,a.jsxs)(ee.Z,{style:{fontSize:"15px",fontWeight:"normal",color:"#535452"},children:["API Requests ",eg(e.sum_api_requests)]}),(0,a.jsx)(ed.Z,{className:"h-40",data:e.daily_data,index:"date",colors:["cyan"],categories:["api_requests"],valueFormatter:eg,onValueChange:e=>console.log(e)})]}),(0,a.jsxs)(h.Z,{children:[(0,a.jsxs)(ee.Z,{style:{fontSize:"15px",fontWeight:"normal",color:"#535452"},children:["Tokens ",eg(e.sum_total_tokens)]}),(0,a.jsx)(ec.Z,{className:"h-40",data:e.daily_data,index:"date",colors:["cyan"],categories:["total_tokens"],valueFormatter:eg,onValueChange:e=>console.log(e)})]})]})]},l))}):(0,a.jsx)(a.Fragment,{children:H&&H.length>0&&H.slice(0,1).map((e,l)=>(0,a.jsxs)(M.Z,{children:[(0,a.jsx)(y.Z,{children:"✨ Activity by Model"}),(0,a.jsx)("p",{className:"mb-2 text-gray-500 italic text-[12px]",children:"Upgrade to see analytics for all models"}),(0,a.jsx)(p.Z,{variant:"primary",className:"mb-2",children:(0,a.jsx)("a",{href:"https://forms.gle/W3U4PZpJGFHWtHyA9",target:"_blank",children:"Get Free Trial"})}),(0,a.jsxs)(M.Z,{children:[(0,a.jsx)(y.Z,{children:e.model}),(0,a.jsxs)(x.Z,{numItems:2,children:[(0,a.jsxs)(h.Z,{children:[(0,a.jsxs)(ee.Z,{style:{fontSize:"15px",fontWeight:"normal",color:"#535452"},children:["API Requests ",eg(e.sum_api_requests)]}),(0,a.jsx)(ed.Z,{className:"h-40",data:e.daily_data,index:"date",colors:["cyan"],categories:["api_requests"],valueFormatter:eg,onValueChange:e=>console.log(e)})]}),(0,a.jsxs)(h.Z,{children:[(0,a.jsxs)(ee.Z,{style:{fontSize:"15px",fontWeight:"normal",color:"#535452"},children:["Tokens ",eg(e.sum_total_tokens)]}),(0,a.jsx)(ec.Z,{className:"h-40",data:e.daily_data,index:"date",colors:["cyan"],valueFormatter:eg,categories:["total_tokens"],onValueChange:e=>console.log(e)})]})]})]})]},l))})]})})]})]})}),(0,a.jsx)(ea.Z,{children:(0,a.jsxs)(x.Z,{numItems:2,className:"gap-2 h-[75vh] w-full",children:[(0,a.jsxs)(h.Z,{numColSpan:2,children:[(0,a.jsxs)(M.Z,{className:"mb-2",children:[(0,a.jsx)(y.Z,{children:"Total Spend Per Team"}),(0,a.jsx)(ll.Z,{data:T})]}),(0,a.jsxs)(M.Z,{children:[(0,a.jsx)(y.Z,{children:"Daily Spend Per Team"}),(0,a.jsx)(ec.Z,{className:"h-72",data:S,showLegend:!0,index:"date",categories:C,yAxisWidth:80,stack:!0})]})]}),(0,a.jsx)(h.Z,{numColSpan:2})]})}),(0,a.jsxs)(ea.Z,{children:[(0,a.jsxs)("p",{className:"mb-2 text-gray-500 italic text-[12px]",children:["Customers of your LLM API calls. Tracked when a `user` param is passed in your LLM calls ",(0,a.jsx)("a",{className:"text-blue-500",href:"https://docs.litellm.ai/docs/proxy/users",target:"_blank",children:"docs here"})]}),(0,a.jsxs)(x.Z,{numItems:2,children:[(0,a.jsxs)(h.Z,{children:[(0,a.jsx)(_.Z,{children:"Select Time Range"}),(0,a.jsx)(el.Z,{enableSelect:!0,value:em,onValueChange:e=>{eu(e),eZ(e.from,e.to,null)}})]}),(0,a.jsxs)(h.Z,{children:[(0,a.jsx)(_.Z,{children:"Select Key"}),(0,a.jsxs)(B.Z,{defaultValue:"all-keys",children:[(0,a.jsx)(K.Z,{value:"all-keys",onClick:()=>{eZ(em.from,em.to,null)},children:"All Keys"},"all-keys"),null==i?void 0:i.map((e,l)=>e&&null!==e.key_alias&&e.key_alias.length>0?(0,a.jsx)(K.Z,{value:String(l),onClick:()=>{eZ(em.from,em.to,e.token)},children:e.key_alias},l):null)]})]})]}),(0,a.jsx)(M.Z,{className:"mt-4",children:(0,a.jsxs)(D.Z,{className:"max-h-[70vh] min-h-[500px]",children:[(0,a.jsx)(V.Z,{children:(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(z.Z,{children:"Customer"}),(0,a.jsx)(z.Z,{children:"Spend"}),(0,a.jsx)(z.Z,{children:"Total Events"})]})}),(0,a.jsx)(L.Z,{children:null==b?void 0:b.map((e,l)=>{var s;return(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(U.Z,{children:e.end_user}),(0,a.jsx)(U.Z,{children:null===(s=e.total_spend)||void 0===s?void 0:s.toFixed(4)}),(0,a.jsx)(U.Z,{children:e.total_count})]},l)})})]})})]}),(0,a.jsxs)(ea.Z,{children:[(0,a.jsxs)(x.Z,{numItems:2,children:[(0,a.jsx)(h.Z,{numColSpan:1,children:(0,a.jsx)(el.Z,{className:"mb-4",enableSelect:!0,value:em,onValueChange:e=>{eu(e),ef(e.from,e.to)}})}),(0,a.jsx)(h.Z,{children:o?(0,a.jsx)("div",{children:(0,a.jsxs)(ei.Z,{value:$,onValueChange:e=>Q(e),children:[(0,a.jsx)(eo.Z,{value:"all-tags",onClick:()=>Q(["all-tags"]),children:"All Tags"},"all-tags"),A&&A.filter(e=>"all-tags"!==e).map((e,l)=>(0,a.jsx)(eo.Z,{value:String(e),children:e},e))]})}):(0,a.jsx)("div",{children:(0,a.jsxs)(ei.Z,{value:$,onValueChange:e=>Q(e),children:[(0,a.jsx)(eo.Z,{value:"all-tags",onClick:()=>Q(["all-tags"]),children:"All Tags"},"all-tags"),A&&A.filter(e=>"all-tags"!==e).map((e,l)=>(0,a.jsxs)(K.Z,{value:String(e),disabled:!0,children:["✨ ",e," (Enterprise only Feature)"]},e))]})})})]}),(0,a.jsxs)(x.Z,{numItems:2,className:"gap-2 h-[75vh] w-full mb-4",children:[(0,a.jsx)(h.Z,{numColSpan:2,children:(0,a.jsxs)(M.Z,{children:[(0,a.jsx)(y.Z,{children:"Spend Per Tag"}),(0,a.jsxs)(_.Z,{children:["Get Started Tracking cost per tag ",(0,a.jsx)("a",{className:"text-blue-500",href:"https://docs.litellm.ai/docs/proxy/cost_tracking",target:"_blank",children:"here"})]}),(0,a.jsx)(ec.Z,{className:"h-72",data:w,index:"name",categories:["spend"],colors:["blue"]})]})}),(0,a.jsx)(h.Z,{numColSpan:2})]})]})]})]})})};let ln=e=>{if(e)return e.toISOString().split("T")[0]};function la(e){return new Intl.NumberFormat("en-US",{maximumFractionDigits:0,notation:"compact",compactDisplay:"short"}).format(e)}var lr=e=>{let{accessToken:l,token:s,userRole:t,userID:n,premiumUser:i}=e,[o,d]=(0,r.useState)([]),[c,m]=(0,r.useState)([]),[p,j]=(0,r.useState)([]),[g,Z]=(0,r.useState)([]),[f,_]=(0,r.useState)("0"),[y,b]=(0,r.useState)("0"),[v,S]=(0,r.useState)("0"),[k,w]=(0,r.useState)({from:new Date(Date.now()-6048e5),to:new Date});(0,r.useEffect)(()=>{l&&k&&(async()=>{Z(await (0,u.zg)(l,ln(k.from),ln(k.to)))})()},[l]);let N=Array.from(new Set(g.map(e=>{var l;return null!==(l=null==e?void 0:e.api_key)&&void 0!==l?l:""}))),A=Array.from(new Set(g.map(e=>{var l;return null!==(l=null==e?void 0:e.model)&&void 0!==l?l:""})));Array.from(new Set(g.map(e=>{var l;return null!==(l=null==e?void 0:e.call_type)&&void 0!==l?l:""})));let I=async(e,s)=>{e&&s&&l&&(s.setHours(23,59,59,999),e.setHours(0,0,0,0),Z(await (0,u.zg)(l,ln(e),ln(s))))};return(0,r.useEffect)(()=>{console.log("DATA IN CACHE DASHBOARD",g);let e=g;c.length>0&&(e=e.filter(e=>c.includes(e.api_key))),p.length>0&&(e=e.filter(e=>p.includes(e.model))),console.log("before processed data in cache dashboard",e);let l=0,s=0,t=0,n=e.reduce((e,n)=>{console.log("Processing item:",n),n.call_type||(console.log("Item has no call_type:",n),n.call_type="Unknown"),l+=(n.total_rows||0)-(n.cache_hit_true_rows||0),s+=n.cache_hit_true_rows||0,t+=n.cached_completion_tokens||0;let a=e.find(e=>e.name===n.call_type);return a?(a["LLM API requests"]+=(n.total_rows||0)-(n.cache_hit_true_rows||0),a["Cache hit"]+=n.cache_hit_true_rows||0,a["Cached Completion Tokens"]+=n.cached_completion_tokens||0,a["Generated Completion Tokens"]+=n.generated_completion_tokens||0):e.push({name:n.call_type,"LLM API requests":(n.total_rows||0)-(n.cache_hit_true_rows||0),"Cache hit":n.cache_hit_true_rows||0,"Cached Completion Tokens":n.cached_completion_tokens||0,"Generated Completion Tokens":n.generated_completion_tokens||0}),e},[]);_(la(s)),b(la(t)),l>0?S((s/l*100).toFixed(2)):S("0"),d(n),console.log("PROCESSED DATA IN CACHE DASHBOARD",n)},[c,p,k,g]),(0,a.jsxs)(M.Z,{children:[(0,a.jsxs)(x.Z,{numItems:3,className:"gap-4 mt-4",children:[(0,a.jsx)(h.Z,{children:(0,a.jsx)(ei.Z,{placeholder:"Select API Keys",value:c,onValueChange:m,children:N.map(e=>(0,a.jsx)(eo.Z,{value:e,children:e},e))})}),(0,a.jsx)(h.Z,{children:(0,a.jsx)(ei.Z,{placeholder:"Select Models",value:p,onValueChange:j,children:A.map(e=>(0,a.jsx)(eo.Z,{value:e,children:e},e))})}),(0,a.jsx)(h.Z,{children:(0,a.jsx)(el.Z,{enableSelect:!0,value:k,onValueChange:e=>{w(e),I(e.from,e.to)},selectPlaceholder:"Select date range"})})]}),(0,a.jsxs)("div",{className:"grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3 mt-4",children:[(0,a.jsxs)(M.Z,{children:[(0,a.jsx)("p",{className:"text-tremor-default font-medium text-tremor-content dark:text-dark-tremor-content",children:"Cache Hit Ratio"}),(0,a.jsx)("div",{className:"mt-2 flex items-baseline space-x-2.5",children:(0,a.jsxs)("p",{className:"text-tremor-metric font-semibold text-tremor-content-strong dark:text-dark-tremor-content-strong",children:[v,"%"]})})]}),(0,a.jsxs)(M.Z,{children:[(0,a.jsx)("p",{className:"text-tremor-default font-medium text-tremor-content dark:text-dark-tremor-content",children:"Cache Hits"}),(0,a.jsx)("div",{className:"mt-2 flex items-baseline space-x-2.5",children:(0,a.jsx)("p",{className:"text-tremor-metric font-semibold text-tremor-content-strong dark:text-dark-tremor-content-strong",children:f})})]}),(0,a.jsxs)(M.Z,{children:[(0,a.jsx)("p",{className:"text-tremor-default font-medium text-tremor-content dark:text-dark-tremor-content",children:"Cached Tokens"}),(0,a.jsx)("div",{className:"mt-2 flex items-baseline space-x-2.5",children:(0,a.jsx)("p",{className:"text-tremor-metric font-semibold text-tremor-content-strong dark:text-dark-tremor-content-strong",children:y})})]})]}),(0,a.jsx)(ee.Z,{className:"mt-4",children:"Cache Hits vs API Requests"}),(0,a.jsx)(ec.Z,{title:"Cache Hits vs API Requests",data:o,index:"name",valueFormatter:la,categories:["LLM API requests","Cache hit"],colors:["sky","teal"],yAxisWidth:48}),(0,a.jsx)(ee.Z,{className:"mt-4",children:"Cached Completion Tokens vs Generated Completion Tokens"}),(0,a.jsx)(ec.Z,{className:"mt-6",data:o,index:"name",valueFormatter:la,categories:["Generated Completion Tokens","Cached Completion Tokens"],colors:["sky","teal"],yAxisWidth:48})]})},li=()=>{let{Title:e,Paragraph:l}=$.default,[s,t]=(0,r.useState)(""),[n,o]=(0,r.useState)(!1),[d,c]=(0,r.useState)(null),[u,h]=(0,r.useState)(null),[x,p]=(0,r.useState)(null),[j,g]=(0,r.useState)({PROXY_BASE_URL:"",PROXY_LOGOUT_URL:""}),[Z,f]=(0,r.useState)(!0),_=(0,i.useSearchParams)(),[y,b]=(0,r.useState)({data:[]}),v=_.get("userID"),S=function(e){console.log("COOKIES",document.cookie);let l=document.cookie.split("; ").find(l=>l.startsWith(e+"="));return l?l.split("=")[1]:null}("token"),[k,w]=(0,r.useState)("api-keys"),[N,A]=(0,r.useState)(null);return(0,r.useEffect)(()=>{if(S){let e=(0,X.o)(S);if(e){if(console.log("Decoded token:",e),console.log("Decoded key:",e.key),A(e.key),e.user_role){let l=function(e){if(!e)return"Undefined Role";switch(console.log("Received user role: ".concat(e.toLowerCase())),console.log("Received user role length: ".concat(e.toLowerCase().length)),e.toLowerCase()){case"app_owner":case"demo_app_owner":return"App Owner";case"app_admin":case"proxy_admin":return"Admin";case"proxy_admin_viewer":return"Admin Viewer";case"internal_user":return"Internal User";case"internal_viewer":return"Internal Viewer";case"app_user":return"App User";default:return"Unknown Role"}}(e.user_role);console.log("Decoded user_role:",l),t(l),"Admin Viewer"==l&&w("usage")}else console.log("User role not defined");e.user_email?c(e.user_email):console.log("User Email is not set ".concat(e)),e.login_method?f("username_password"==e.login_method):console.log("User Email is not set ".concat(e)),e.premium_user&&o(e.premium_user)}}},[S]),(0,a.jsx)(r.Suspense,{fallback:(0,a.jsx)("div",{children:"Loading..."}),children:(0,a.jsxs)("div",{className:"flex flex-col min-h-screen",children:[(0,a.jsx)(m,{userID:v,userRole:s,userEmail:d,showSSOBanner:Z,premiumUser:n,setProxySettings:g,proxySettings:j}),(0,a.jsxs)("div",{className:"flex flex-1 overflow-auto",children:[(0,a.jsx)("div",{className:"mt-8",children:(0,a.jsx)(le,{setPage:w,userRole:s,defaultSelectedKey:null})}),"api-keys"==k?(0,a.jsx)(Q,{userID:v,userRole:s,teams:u,keys:x,setUserRole:t,userEmail:d,setUserEmail:c,setTeams:h,setKeys:p,setProxySettings:g,proxySettings:j}):"models"==k?(0,a.jsx)(eP,{userID:v,userRole:s,token:S,keys:x,accessToken:N,modelData:y,setModelData:b,premiumUser:n}):"llm-playground"==k?(0,a.jsx)(e3,{userID:v,userRole:s,token:S,accessToken:N}):"users"==k?(0,a.jsx)(eM,{userID:v,userRole:s,token:S,keys:x,teams:u,accessToken:N,setKeys:p}):"teams"==k?(0,a.jsx)(eF,{teams:u,setTeams:h,searchParams:_,accessToken:N,userID:v,userRole:s}):"admin-panel"==k?(0,a.jsx)(eD,{setTeams:h,searchParams:_,accessToken:N,showSSOBanner:Z}):"api_ref"==k?(0,a.jsx)(e5,{proxySettings:j}):"settings"==k?(0,a.jsx)(eW,{userID:v,userRole:s,accessToken:N,premiumUser:n}):"budgets"==k?(0,a.jsx)(e2,{accessToken:N}):"general-settings"==k?(0,a.jsx)(eQ,{userID:v,userRole:s,accessToken:N,modelData:y}):"model-hub"==k?(0,a.jsx)(e4.Z,{accessToken:N,publicPage:!1,premiumUser:n}):"caching"==k?(0,a.jsx)(lr,{userID:v,userRole:s,token:S,accessToken:N,premiumUser:n}):(0,a.jsx)(lt,{userID:v,userRole:s,token:S,accessToken:N,keys:x,premiumUser:n})]})]})})}},41134:function(e,l,s){"use strict";s.d(l,{Z:function(){return y}});var t=s(3827),n=s(64090),a=s(47907),r=s(777),i=s(16450),o=s(13810),d=s(92836),c=s(26734),m=s(41608),u=s(32126),h=s(23682),x=s(71801),p=s(42440),j=s(84174),g=s(50459),Z=s(6180),f=s(99129),_=s(67951),y=e=>{var l;let{accessToken:s,publicPage:y,premiumUser:b}=e,[v,S]=(0,n.useState)(!1),[k,w]=(0,n.useState)(null),[N,A]=(0,n.useState)(!1),[I,C]=(0,n.useState)(!1),[P,T]=(0,n.useState)(null),O=(0,a.useRouter)();(0,n.useEffect)(()=>{s&&(async()=>{try{let e=await (0,r.kn)(s);console.log("ModelHubData:",e),w(e.data),(0,r.E9)(s,"enable_public_model_hub").then(e=>{console.log("data: ".concat(JSON.stringify(e))),!0==e.field_value&&S(!0)}).catch(e=>{})}catch(e){console.error("There was an error fetching the model data",e)}})()},[s,y]);let E=e=>{T(e),A(!0)},R=async()=>{s&&(0,r.jA)(s,"enable_public_model_hub",!0).then(e=>{C(!0)})},M=()=>{A(!1),C(!1),T(null)},F=()=>{A(!1),C(!1),T(null)},D=e=>{navigator.clipboard.writeText(e)};return(0,t.jsxs)("div",{children:[y&&v||!1==y?(0,t.jsxs)("div",{className:"w-full m-2 mt-2 p-8",children:[(0,t.jsx)("div",{className:"relative w-full"}),(0,t.jsxs)("div",{className:"flex ".concat(y?"justify-between":"items-center"),children:[(0,t.jsx)(p.Z,{className:"ml-8 text-center ",children:"Model Hub"}),!1==y?b?(0,t.jsx)(i.Z,{className:"ml-4",onClick:()=>R(),children:"✨ Make Public"}):(0,t.jsx)(i.Z,{className:"ml-4",children:(0,t.jsx)("a",{href:"https://forms.gle/W3U4PZpJGFHWtHyA9",target:"_blank",children:"✨ Make Public"})}):(0,t.jsxs)("div",{className:"flex justify-between items-center",children:[(0,t.jsx)("p",{children:"Filter by key:"}),(0,t.jsx)(x.Z,{className:"bg-gray-200 pr-2 pl-2 pt-1 pb-1 text-center",children:"/ui/model_hub?key="})]})]}),(0,t.jsx)("div",{className:"grid grid-cols-2 gap-6 sm:grid-cols-3 lg:grid-cols-4 pr-8",children:k&&k.map(e=>(0,t.jsxs)(o.Z,{className:"mt-5 mx-8",children:[(0,t.jsxs)("pre",{className:"flex justify-between",children:[(0,t.jsx)(p.Z,{children:e.model_group}),(0,t.jsx)(Z.Z,{title:e.model_group,children:(0,t.jsx)(j.Z,{onClick:()=>D(e.model_group),style:{cursor:"pointer",marginRight:"10px"}})})]}),(0,t.jsxs)("div",{className:"my-5",children:[(0,t.jsxs)(x.Z,{children:["Mode: ",e.mode]}),(0,t.jsxs)(x.Z,{children:["Supports Function Calling:"," ",(null==e?void 0:e.supports_function_calling)==!0?"Yes":"No"]}),(0,t.jsxs)(x.Z,{children:["Supports Vision:"," ",(null==e?void 0:e.supports_vision)==!0?"Yes":"No"]}),(0,t.jsxs)(x.Z,{children:["Max Input Tokens:"," ",(null==e?void 0:e.max_input_tokens)?null==e?void 0:e.max_input_tokens:"N/A"]}),(0,t.jsxs)(x.Z,{children:["Max Output Tokens:"," ",(null==e?void 0:e.max_output_tokens)?null==e?void 0:e.max_output_tokens:"N/A"]})]}),(0,t.jsx)("div",{style:{marginTop:"auto",textAlign:"right"},children:(0,t.jsxs)("a",{href:"#",onClick:()=>E(e),style:{color:"#1890ff",fontSize:"smaller"},children:["View more ",(0,t.jsx)(g.Z,{})]})})]},e.model_group))})]}):(0,t.jsxs)(o.Z,{className:"mx-auto max-w-xl mt-10",children:[(0,t.jsx)(x.Z,{className:"text-xl text-center mb-2 text-black",children:"Public Model Hub not enabled."}),(0,t.jsx)("p",{className:"text-base text-center text-slate-800",children:"Ask your proxy admin to enable this on their Admin UI."})]}),(0,t.jsx)(f.Z,{title:"Public Model Hub",width:600,visible:I,footer:null,onOk:M,onCancel:F,children:(0,t.jsxs)("div",{className:"pt-5 pb-5",children:[(0,t.jsxs)("div",{className:"flex justify-between mb-4",children:[(0,t.jsx)(x.Z,{className:"text-base mr-2",children:"Shareable Link:"}),(0,t.jsx)(x.Z,{className:"max-w-sm ml-2 bg-gray-200 pr-2 pl-2 pt-1 pb-1 text-center rounded",children:"/ui/model_hub?key="})]}),(0,t.jsx)("div",{className:"flex justify-end",children:(0,t.jsx)(i.Z,{onClick:()=>{O.replace("/model_hub?key=".concat(s))},children:"See Page"})})]})}),(0,t.jsx)(f.Z,{title:P&&P.model_group?P.model_group:"Unknown Model",width:800,visible:N,footer:null,onOk:M,onCancel:F,children:P&&(0,t.jsxs)("div",{children:[(0,t.jsx)("p",{className:"mb-4",children:(0,t.jsx)("strong",{children:"Model Information & Usage"})}),(0,t.jsxs)(c.Z,{children:[(0,t.jsxs)(m.Z,{children:[(0,t.jsx)(d.Z,{children:"OpenAI Python SDK"}),(0,t.jsx)(d.Z,{children:"Supported OpenAI Params"}),(0,t.jsx)(d.Z,{children:"LlamaIndex"}),(0,t.jsx)(d.Z,{children:"Langchain Py"})]}),(0,t.jsxs)(h.Z,{children:[(0,t.jsx)(u.Z,{children:(0,t.jsx)(_.Z,{language:"python",children:'\nimport openai\nclient = openai.OpenAI(\n api_key="your_api_key",\n base_url="http://0.0.0.0:4000" # LiteLLM Proxy is OpenAI compatible, Read More: https://docs.litellm.ai/docs/proxy/user_keys\n)\n\nresponse = client.chat.completions.create(\n model="'.concat(P.model_group,'", # model to send to the proxy\n messages = [\n {\n "role": "user",\n "content": "this is a test request, write a short poem"\n }\n ]\n)\n\nprint(response)\n ')})}),(0,t.jsx)(u.Z,{children:(0,t.jsx)(_.Z,{language:"python",children:"".concat(null===(l=P.supported_openai_params)||void 0===l?void 0:l.map(e=>"".concat(e,"\n")).join(""))})}),(0,t.jsx)(u.Z,{children:(0,t.jsx)(_.Z,{language:"python",children:'\nimport os, dotenv\n\nfrom llama_index.llms import AzureOpenAI\nfrom llama_index.embeddings import AzureOpenAIEmbedding\nfrom llama_index import VectorStoreIndex, SimpleDirectoryReader, ServiceContext\n\nllm = AzureOpenAI(\n engine="'.concat(P.model_group,'", # model_name on litellm proxy\n temperature=0.0,\n azure_endpoint="http://0.0.0.0:4000", # litellm proxy endpoint\n api_key="sk-1234", # litellm proxy API Key\n api_version="2023-07-01-preview",\n)\n\nembed_model = AzureOpenAIEmbedding(\n deployment_name="azure-embedding-model",\n azure_endpoint="http://0.0.0.0:4000",\n api_key="sk-1234",\n api_version="2023-07-01-preview",\n)\n\n\ndocuments = SimpleDirectoryReader("llama_index_data").load_data()\nservice_context = ServiceContext.from_defaults(llm=llm, embed_model=embed_model)\nindex = VectorStoreIndex.from_documents(documents, service_context=service_context)\n\nquery_engine = index.as_query_engine()\nresponse = query_engine.query("What did the author do growing up?")\nprint(response)\n\n ')})}),(0,t.jsx)(u.Z,{children:(0,t.jsx)(_.Z,{language:"python",children:'\nfrom langchain.chat_models import ChatOpenAI\nfrom langchain.prompts.chat import (\n ChatPromptTemplate,\n HumanMessagePromptTemplate,\n SystemMessagePromptTemplate,\n)\nfrom langchain.schema import HumanMessage, SystemMessage\n\nchat = ChatOpenAI(\n openai_api_base="http://0.0.0.0:4000",\n model = "'.concat(P.model_group,'",\n temperature=0.1\n)\n\nmessages = [\n SystemMessage(\n content="You are a helpful assistant that im using to make a test request to."\n ),\n HumanMessage(\n content="test from litellm. tell me why it\'s amazing in 1 sentence"\n ),\n]\nresponse = chat(messages)\n\nprint(response)\n\n ')})})]})]})]})})]})}}},function(e){e.O(0,[936,294,131,684,759,777,971,69,744],function(){return e(e.s=20661)}),_N_E=e.O()}]); \ No newline at end of file diff --git a/ui/litellm-dashboard/out/_next/static/chunks/app/page-5b9334558218205d.js b/ui/litellm-dashboard/out/_next/static/chunks/app/page-5b9334558218205d.js deleted file mode 100644 index b68b1963c55..00000000000 --- a/ui/litellm-dashboard/out/_next/static/chunks/app/page-5b9334558218205d.js +++ /dev/null @@ -1 +0,0 @@ -(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[931],{20661:function(e,l,s){Promise.resolve().then(s.bind(s,48951))},48951:function(e,l,s){"use strict";s.r(l),s.d(l,{default:function(){return li}});var t,n,a=s(3827),r=s(64090),i=s(47907),o=s(8792),d=s(40491),c=s(65270),m=e=>{let{userID:l,userRole:s,userEmail:t,showSSOBanner:n,premiumUser:r,setProxySettings:i,proxySettings:m}=e;console.log("User ID:",l),console.log("userEmail:",t),console.log("showSSOBanner:",n),console.log("premiumUser:",r);let u="";console.log("PROXY_settings=",m),m&&m.PROXY_LOGOUT_URL&&void 0!==m.PROXY_LOGOUT_URL&&(u=m.PROXY_LOGOUT_URL),console.log("logoutUrl=",u);let h=[{key:"1",label:(0,a.jsxs)(a.Fragment,{children:[(0,a.jsxs)("p",{children:["Role: ",s]}),(0,a.jsxs)("p",{children:["ID: ",l]}),(0,a.jsxs)("p",{children:["Premium User: ",String(r)]})]})},{key:"2",label:(0,a.jsx)("a",{href:u,children:(0,a.jsx)("p",{children:"Logout"})})}];return(0,a.jsxs)("nav",{className:"left-0 right-0 top-0 flex justify-between items-center h-12 mb-4",children:[(0,a.jsx)("div",{className:"text-left my-2 absolute top-0 left-0",children:(0,a.jsx)("div",{className:"flex flex-col items-center",children:(0,a.jsx)(o.default,{href:"/",children:(0,a.jsx)("button",{className:"text-gray-800 rounded text-center",children:(0,a.jsx)("img",{src:"/get_image",width:160,height:160,alt:"LiteLLM Brand",className:"mr-2"})})})})}),(0,a.jsxs)("div",{className:"text-right mx-4 my-2 absolute top-0 right-0 flex items-center justify-end space-x-2",children:[n?(0,a.jsx)("div",{style:{padding:"6px",borderRadius:"8px"},children:(0,a.jsx)("a",{href:"https://calendly.com/d/4mp-gd3-k5k/litellm-1-1-onboarding-chat",target:"_blank",style:{fontSize:"14px",textDecoration:"underline"},children:"Get enterprise license"})}):null,(0,a.jsx)("div",{style:{border:"1px solid #391085",padding:"6px",borderRadius:"8px"},children:(0,a.jsx)(d.Z,{menu:{items:h},children:(0,a.jsx)(c.Z,{children:t})})})]})]})},u=s(777),h=s(10384),x=s(46453),p=s(16450),j=s(52273),g=s(26780),Z=s(15595),f=s(6698),_=s(71801),y=s(42440),b=s(42308),v=s(50670),S=s(60620),k=s(80588),w=s(99129),N=s(44839),A=s(88707),I=s(1861);let{Option:C}=v.default;var P=e=>{let{userID:l,team:s,userRole:t,accessToken:n,data:i,setData:o}=e,[d]=S.Z.useForm(),[c,m]=(0,r.useState)(!1),[P,T]=(0,r.useState)(null),[O,E]=(0,r.useState)(null),[R,M]=(0,r.useState)([]),[F,D]=(0,r.useState)([]),L=()=>{m(!1),d.resetFields()},U=()=>{m(!1),T(null),d.resetFields()};(0,r.useEffect)(()=>{(async()=>{try{if(null===l||null===t)return;if(null!==n){let e=(await (0,u.So)(n,l,t)).data.map(e=>e.id);console.log("available_model_names:",e),M(e)}}catch(e){console.error("Error fetching user models:",e)}})()},[n,l,t]);let V=async e=>{try{var s,t,a;let r=null!==(s=null==e?void 0:e.key_alias)&&void 0!==s?s:"",c=null!==(t=null==e?void 0:e.team_id)&&void 0!==t?t:null;if((null!==(a=null==i?void 0:i.filter(e=>e.team_id===c).map(e=>e.key_alias))&&void 0!==a?a:[]).includes(r))throw Error("Key alias ".concat(r," already exists for team with ID ").concat(c,", please provide another key alias"));k.ZP.info("Making API Call"),m(!0);let h=await (0,u.wX)(n,l,e);console.log("key create Response:",h),o(e=>e?[...e,h]:[h]),T(h.key),E(h.soft_budget),k.ZP.success("API Key Created"),d.resetFields(),localStorage.removeItem("userData"+l)}catch(e){console.error("Error creating the key:",e),k.ZP.error("Error creating the key: ".concat(e),20)}};return(0,r.useEffect)(()=>{D(s&&s.models.length>0?s.models.includes("all-proxy-models")?R:s.models:R)},[s,R]),(0,a.jsxs)("div",{children:[(0,a.jsx)(p.Z,{className:"mx-auto",onClick:()=>m(!0),children:"+ Create New Key"}),(0,a.jsx)(w.Z,{title:"Create Key",visible:c,width:800,footer:null,onOk:L,onCancel:U,children:(0,a.jsxs)(S.Z,{form:d,onFinish:V,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(S.Z.Item,{label:"Key Name",name:"key_alias",rules:[{required:!0,message:"Please input a key name"}],help:"required",children:(0,a.jsx)(j.Z,{placeholder:""})}),(0,a.jsx)(S.Z.Item,{label:"Team ID",name:"team_id",hidden:!0,initialValue:s?s.team_id:null,valuePropName:"team_id",className:"mt-8",children:(0,a.jsx)(N.Z,{value:s?s.team_alias:"",disabled:!0})}),(0,a.jsx)(S.Z.Item,{label:"Models",name:"models",rules:[{required:!0,message:"Please select a model"}],help:"required",children:(0,a.jsxs)(v.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},onChange:e=>{e.includes("all-team-models")&&d.setFieldsValue({models:["all-team-models"]})},children:[(0,a.jsx)(C,{value:"all-team-models",children:"All Team Models"},"all-team-models"),F.map(e=>(0,a.jsx)(C,{value:e,children:e},e))]})}),(0,a.jsxs)(g.Z,{className:"mt-20 mb-8",children:[(0,a.jsx)(f.Z,{children:(0,a.jsx)("b",{children:"Optional Settings"})}),(0,a.jsxs)(Z.Z,{children:[(0,a.jsx)(S.Z.Item,{className:"mt-8",label:"Max Budget (USD)",name:"max_budget",help:"Budget cannot exceed team max budget: $".concat((null==s?void 0:s.max_budget)!==null&&(null==s?void 0:s.max_budget)!==void 0?null==s?void 0:s.max_budget:"unlimited"),rules:[{validator:async(e,l)=>{if(l&&s&&null!==s.max_budget&&l>s.max_budget)throw Error("Budget cannot exceed team max budget: $".concat(s.max_budget))}}],children:(0,a.jsx)(A.Z,{step:.01,precision:2,width:200})}),(0,a.jsx)(S.Z.Item,{className:"mt-8",label:"Reset Budget",name:"budget_duration",help:"Team Reset Budget: ".concat((null==s?void 0:s.budget_duration)!==null&&(null==s?void 0:s.budget_duration)!==void 0?null==s?void 0:s.budget_duration:"None"),children:(0,a.jsxs)(v.default,{defaultValue:null,placeholder:"n/a",children:[(0,a.jsx)(v.default.Option,{value:"24h",children:"daily"}),(0,a.jsx)(v.default.Option,{value:"7d",children:"weekly"}),(0,a.jsx)(v.default.Option,{value:"30d",children:"monthly"})]})}),(0,a.jsx)(S.Z.Item,{className:"mt-8",label:"Tokens per minute Limit (TPM)",name:"tpm_limit",help:"TPM cannot exceed team TPM limit: ".concat((null==s?void 0:s.tpm_limit)!==null&&(null==s?void 0:s.tpm_limit)!==void 0?null==s?void 0:s.tpm_limit:"unlimited"),rules:[{validator:async(e,l)=>{if(l&&s&&null!==s.tpm_limit&&l>s.tpm_limit)throw Error("TPM limit cannot exceed team TPM limit: ".concat(s.tpm_limit))}}],children:(0,a.jsx)(A.Z,{step:1,width:400})}),(0,a.jsx)(S.Z.Item,{className:"mt-8",label:"Requests per minute Limit (RPM)",name:"rpm_limit",help:"RPM cannot exceed team RPM limit: ".concat((null==s?void 0:s.rpm_limit)!==null&&(null==s?void 0:s.rpm_limit)!==void 0?null==s?void 0:s.rpm_limit:"unlimited"),rules:[{validator:async(e,l)=>{if(l&&s&&null!==s.rpm_limit&&l>s.rpm_limit)throw Error("RPM limit cannot exceed team RPM limit: ".concat(s.rpm_limit))}}],children:(0,a.jsx)(A.Z,{step:1,width:400})}),(0,a.jsx)(S.Z.Item,{label:"Expire Key (eg: 30s, 30h, 30d)",name:"duration",className:"mt-8",children:(0,a.jsx)(j.Z,{placeholder:""})}),(0,a.jsx)(S.Z.Item,{label:"Metadata",name:"metadata",className:"mt-8",children:(0,a.jsx)(N.Z.TextArea,{rows:4,placeholder:"Enter metadata as JSON"})})]})]})]}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(I.ZP,{htmlType:"submit",children:"Create Key"})})]})}),P&&(0,a.jsx)(w.Z,{visible:c,onOk:L,onCancel:U,footer:null,children:(0,a.jsxs)(x.Z,{numItems:1,className:"gap-2 w-full",children:[(0,a.jsx)(y.Z,{children:"Save your Key"}),(0,a.jsx)(h.Z,{numColSpan:1,children:(0,a.jsxs)("p",{children:["Please save this secret key somewhere safe and accessible. For security reasons, ",(0,a.jsx)("b",{children:"you will not be able to view it again"})," ","through your LiteLLM account. If you lose this secret key, you will need to generate a new one."]})}),(0,a.jsx)(h.Z,{numColSpan:1,children:null!=P?(0,a.jsxs)("div",{children:[(0,a.jsx)(_.Z,{className:"mt-3",children:"API Key:"}),(0,a.jsx)("div",{style:{background:"#f8f8f8",padding:"10px",borderRadius:"5px",marginBottom:"10px"},children:(0,a.jsx)("pre",{style:{wordWrap:"break-word",whiteSpace:"normal"},children:P})}),(0,a.jsx)(b.CopyToClipboard,{text:P,onCopy:()=>{k.ZP.success("API Key copied to clipboard")},children:(0,a.jsx)(p.Z,{className:"mt-3",children:"Copy API Key"})})]}):(0,a.jsx)(_.Z,{children:"Key being created, this might take 30s"})})]})})]})},T=s(9454),O=s(98941),E=s(33393),R=s(5),M=s(13810),F=s(61244),D=s(10827),L=s(3851),U=s(2044),V=s(64167),z=s(74480),q=s(7178),B=s(95093),K=s(27166);let{Option:W}=v.default;var H=e=>{let{userID:l,userRole:s,accessToken:t,selectedTeam:n,data:i,setData:o,teams:d}=e,[c,m]=(0,r.useState)(!1),[h,x]=(0,r.useState)(!1),[j,g]=(0,r.useState)(null),[Z,f]=(0,r.useState)(null),[b,C]=(0,r.useState)(null),[P,H]=(0,r.useState)(""),[G,Y]=(0,r.useState)(!1),[J,X]=(0,r.useState)(!1),[$,Q]=(0,r.useState)(null),[ee,el]=(0,r.useState)([]),es=new Set,[et,en]=(0,r.useState)(es);(0,r.useEffect)(()=>{(async()=>{try{if(null===l)return;if(null!==t&&null!==s){let e=(await (0,u.So)(t,l,s)).data.map(e=>e.id);console.log("available_model_names:",e),el(e)}}catch(e){console.error("Error fetching user models:",e)}})()},[t,l,s]),(0,r.useEffect)(()=>{if(d){let e=new Set;d.forEach((l,s)=>{let t=l.team_id;e.add(t)}),en(e)}},[d]);let ea=e=>{console.log("handleEditClick:",e),null==e.token&&null!==e.token_id&&(e.token=e.token_id),Q(e),Y(!0)},er=async e=>{if(null==t)return;let l=e.token;e.key=l,console.log("handleEditSubmit:",e);let s=await (0,u.Nc)(t,e);console.log("handleEditSubmit: newKeyValues",s),i&&o(i.map(e=>e.token===l?s:e)),k.ZP.success("Key updated successfully"),Y(!1),Q(null)},ei=async e=>{console.log("handleDelete:",e),null==e.token&&null!==e.token_id&&(e.token=e.token_id),null!=i&&(g(e.token),localStorage.removeItem("userData"+l),x(!0))},eo=async()=>{if(null!=j&&null!=i){try{await (0,u.I1)(t,j);let e=i.filter(e=>e.token!==j);o(e)}catch(e){console.error("Error deleting the key:",e)}x(!1),g(null)}};if(null!=i)return console.log("RERENDER TRIGGERED"),(0,a.jsxs)("div",{children:[(0,a.jsxs)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh] mb-4 mt-2",children:[(0,a.jsxs)(D.Z,{className:"mt-5 max-h-[300px] min-h-[300px]",children:[(0,a.jsx)(V.Z,{children:(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(z.Z,{children:"Key Alias"}),(0,a.jsx)(z.Z,{children:"Secret Key"}),(0,a.jsx)(z.Z,{children:"Spend (USD)"}),(0,a.jsx)(z.Z,{children:"Budget (USD)"}),(0,a.jsx)(z.Z,{children:"Models"}),(0,a.jsx)(z.Z,{children:"TPM / RPM Limits"})]})}),(0,a.jsx)(L.Z,{children:i.map(e=>{if(console.log(e),"litellm-dashboard"===e.team_id)return null;if(n){if(console.log("item team id: ".concat(e.team_id,", knownTeamIDs.has(item.team_id): ").concat(et.has(e.team_id),", selectedTeam id: ").concat(n.team_id)),(null!=n.team_id||null===e.team_id||et.has(e.team_id))&&e.team_id!=n.team_id)return null;console.log("item team id: ".concat(e.team_id,", is returned"))}return(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(U.Z,{style:{maxWidth:"2px",whiteSpace:"pre-wrap",overflow:"hidden"},children:null!=e.key_alias?(0,a.jsx)(_.Z,{children:e.key_alias}):(0,a.jsx)(_.Z,{children:"Not Set"})}),(0,a.jsx)(U.Z,{children:(0,a.jsx)(_.Z,{children:e.key_name})}),(0,a.jsx)(U.Z,{children:(0,a.jsx)(_.Z,{children:(()=>{try{return parseFloat(e.spend).toFixed(4)}catch(l){return e.spend}})()})}),(0,a.jsx)(U.Z,{children:null!=e.max_budget?(0,a.jsx)(_.Z,{children:e.max_budget}):(0,a.jsx)(_.Z,{children:"Unlimited"})}),(0,a.jsx)(U.Z,{children:Array.isArray(e.models)?(0,a.jsx)("div",{style:{display:"flex",flexDirection:"column"},children:0===e.models.length?(0,a.jsx)(a.Fragment,{children:n&&n.models&&n.models.length>0?n.models.map((e,l)=>"all-proxy-models"===e?(0,a.jsx)(R.Z,{size:"xs",className:"mb-1",color:"red",children:(0,a.jsx)(_.Z,{children:"All Proxy Models"})},l):"all-team-models"===e?(0,a.jsx)(R.Z,{size:"xs",className:"mb-1",color:"red",children:(0,a.jsx)(_.Z,{children:"All Team Models"})},l):(0,a.jsx)(R.Z,{size:"xs",className:"mb-1",color:"blue",children:(0,a.jsx)(_.Z,{children:e.length>30?"".concat(e.slice(0,30),"..."):e})},l)):(0,a.jsx)(R.Z,{size:"xs",className:"mb-1",color:"blue",children:(0,a.jsx)(_.Z,{children:"all-proxy-models"})})}):e.models.map((e,l)=>"all-proxy-models"===e?(0,a.jsx)(R.Z,{size:"xs",className:"mb-1",color:"red",children:(0,a.jsx)(_.Z,{children:"All Proxy Models"})},l):"all-team-models"===e?(0,a.jsx)(R.Z,{size:"xs",className:"mb-1",color:"red",children:(0,a.jsx)(_.Z,{children:"All Team Models"})},l):(0,a.jsx)(R.Z,{size:"xs",className:"mb-1",color:"blue",children:(0,a.jsx)(_.Z,{children:e.length>30?"".concat(e.slice(0,30),"..."):e})},l))}):null}),(0,a.jsx)(U.Z,{children:(0,a.jsxs)(_.Z,{children:["TPM: ",e.tpm_limit?e.tpm_limit:"Unlimited"," ",(0,a.jsx)("br",{})," RPM:"," ",e.rpm_limit?e.rpm_limit:"Unlimited"]})}),(0,a.jsxs)(U.Z,{children:[(0,a.jsx)(F.Z,{onClick:()=>{Q(e),X(!0)},icon:T.Z,size:"sm"}),(0,a.jsx)(w.Z,{open:J,onCancel:()=>{X(!1),Q(null)},footer:null,width:800,children:$&&(0,a.jsxs)(a.Fragment,{children:[(0,a.jsxs)("div",{className:"grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3 mt-8",children:[(0,a.jsxs)(M.Z,{children:[(0,a.jsx)("p",{className:"text-tremor-default font-medium text-tremor-content dark:text-dark-tremor-content",children:"Spend"}),(0,a.jsx)("div",{className:"mt-2 flex items-baseline space-x-2.5",children:(0,a.jsx)("p",{className:"text-tremor font-semibold text-tremor-content-strong dark:text-dark-tremor-content-strong",children:(()=>{try{return parseFloat($.spend).toFixed(4)}catch(e){return $.spend}})()})})]}),(0,a.jsxs)(M.Z,{children:[(0,a.jsx)("p",{className:"text-tremor-default font-medium text-tremor-content dark:text-dark-tremor-content",children:"Budget"}),(0,a.jsx)("div",{className:"mt-2 flex items-baseline space-x-2.5",children:(0,a.jsx)("p",{className:"text-tremor font-semibold text-tremor-content-strong dark:text-dark-tremor-content-strong",children:null!=$.max_budget?(0,a.jsx)(a.Fragment,{children:$.max_budget}):(0,a.jsx)(a.Fragment,{children:"Unlimited"})})})]},e.name),(0,a.jsxs)(M.Z,{children:[(0,a.jsx)("p",{className:"text-tremor-default font-medium text-tremor-content dark:text-dark-tremor-content",children:"Expires"}),(0,a.jsx)("div",{className:"mt-2 flex items-baseline space-x-2.5",children:(0,a.jsx)("p",{className:"text-tremor-default font-small text-tremor-content-strong dark:text-dark-tremor-content-strong",children:null!=$.expires?(0,a.jsx)(a.Fragment,{children:new Date($.expires).toLocaleString(void 0,{day:"numeric",month:"long",year:"numeric",hour:"numeric",minute:"numeric",second:"numeric"})}):(0,a.jsx)(a.Fragment,{children:"Never"})})})]},e.name)]}),(0,a.jsxs)(M.Z,{className:"my-4",children:[(0,a.jsx)(y.Z,{children:"Token Name"}),(0,a.jsx)(_.Z,{className:"my-1",children:$.key_alias?$.key_alias:$.key_name}),(0,a.jsx)(y.Z,{children:"Token ID"}),(0,a.jsx)(_.Z,{className:"my-1 text-[12px]",children:$.token}),(0,a.jsx)(y.Z,{children:"Metadata"}),(0,a.jsx)(_.Z,{className:"my-1",children:(0,a.jsxs)("pre",{children:[JSON.stringify($.metadata)," "]})})]}),(0,a.jsx)(p.Z,{className:"mx-auto flex items-center",onClick:()=>{X(!1),Q(null)},children:"Close"})]})}),(0,a.jsx)(F.Z,{icon:O.Z,size:"sm",onClick:()=>ea(e)}),(0,a.jsx)(F.Z,{onClick:()=>ei(e),icon:E.Z,size:"sm"})]})]},e.token)})})]}),h&&(0,a.jsx)("div",{className:"fixed z-10 inset-0 overflow-y-auto",children:(0,a.jsxs)("div",{className:"flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0",children:[(0,a.jsx)("div",{className:"fixed inset-0 transition-opacity","aria-hidden":"true",children:(0,a.jsx)("div",{className:"absolute inset-0 bg-gray-500 opacity-75"})}),(0,a.jsx)("span",{className:"hidden sm:inline-block sm:align-middle sm:h-screen","aria-hidden":"true",children:"​"}),(0,a.jsxs)("div",{className:"inline-block align-bottom bg-white rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full",children:[(0,a.jsx)("div",{className:"bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4",children:(0,a.jsx)("div",{className:"sm:flex sm:items-start",children:(0,a.jsxs)("div",{className:"mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left",children:[(0,a.jsx)("h3",{className:"text-lg leading-6 font-medium text-gray-900",children:"Delete Key"}),(0,a.jsx)("div",{className:"mt-2",children:(0,a.jsx)("p",{className:"text-sm text-gray-500",children:"Are you sure you want to delete this key ?"})})]})})}),(0,a.jsxs)("div",{className:"bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse",children:[(0,a.jsx)(p.Z,{onClick:eo,color:"red",className:"ml-2",children:"Delete"}),(0,a.jsx)(p.Z,{onClick:()=>{x(!1),g(null)},children:"Cancel"})]})]})]})})]}),$&&(0,a.jsx)(e=>{let{visible:l,onCancel:s,token:t,onSubmit:i}=e,[o]=S.Z.useForm(),[c,m]=(0,r.useState)(n),[u,h]=(0,r.useState)([]),[x,p]=(0,r.useState)(!1);return(0,a.jsx)(w.Z,{title:"Edit Key",visible:l,width:800,footer:null,onOk:()=>{o.validateFields().then(e=>{o.resetFields()}).catch(e=>{console.error("Validation failed:",e)})},onCancel:s,children:(0,a.jsxs)(S.Z,{form:o,onFinish:er,initialValues:t,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(S.Z.Item,{label:"Key Name",name:"key_alias",rules:[{required:!0,message:"Please input a key name"}],help:"required",children:(0,a.jsx)(N.Z,{})}),(0,a.jsx)(S.Z.Item,{label:"Models",name:"models",rules:[{validator:(e,l)=>{let s=l.filter(e=>!c.models.includes(e)&&"all-team-models"!==e&&"all-proxy-models"!==e&&!c.models.includes("all-proxy-models"));return(console.log("errorModels: ".concat(s)),s.length>0)?Promise.reject("Some models are not part of the new team's models - ".concat(s,"Team models: ").concat(c.models)):Promise.resolve()}}],children:(0,a.jsxs)(v.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:[(0,a.jsx)(W,{value:"all-team-models",children:"All Team Models"},"all-team-models"),c&&c.models?c.models.includes("all-proxy-models")?ee.filter(e=>"all-proxy-models"!==e).map(e=>(0,a.jsx)(W,{value:e,children:e},e)):c.models.map(e=>(0,a.jsx)(W,{value:e,children:e},e)):ee.map(e=>(0,a.jsx)(W,{value:e,children:e},e))]})}),(0,a.jsx)(S.Z.Item,{className:"mt-8",label:"Max Budget (USD)",name:"max_budget",help:"Budget cannot exceed team max budget: ".concat((null==c?void 0:c.max_budget)!==null&&(null==c?void 0:c.max_budget)!==void 0?null==c?void 0:c.max_budget:"unlimited"),rules:[{validator:async(e,l)=>{if(l&&c&&null!==c.max_budget&&l>c.max_budget)throw console.log("keyTeam.max_budget: ".concat(c.max_budget)),Error("Budget cannot exceed team max budget: $".concat(c.max_budget))}}],children:(0,a.jsx)(A.Z,{step:.01,precision:2,width:200})}),(0,a.jsx)(S.Z.Item,{label:"token",name:"token",hidden:!0}),(0,a.jsx)(S.Z.Item,{label:"Team",name:"team_id",help:"the team this key belongs to",children:(0,a.jsx)(B.Z,{value:t.team_alias,children:null==d?void 0:d.map((e,l)=>(0,a.jsx)(K.Z,{value:e.team_id,onClick:()=>m(e),children:e.team_alias},l))})})]}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(I.ZP,{htmlType:"submit",children:"Edit Key"})})]})})},{visible:G,onCancel:()=>{Y(!1),Q(null)},token:$,onSubmit:er})]})},G=e=>{let{userID:l,userRole:s,accessToken:t,userSpend:n,selectedTeam:i}=e;console.log("userSpend: ".concat(n));let[o,d]=(0,r.useState)(null!==n?n:0),[c,m]=(0,r.useState)(0),[h,x]=(0,r.useState)([]);(0,r.useEffect)(()=>{let e=async()=>{if(t&&l&&s&&"Admin"===s&&null==n)try{let e=await (0,u.Qy)(t);e&&(e.spend?d(e.spend):d(0),e.max_budget?m(e.max_budget):m(0))}catch(e){console.error("Error fetching global spend data:",e)}};(async()=>{try{if(null===l||null===s)return;if(null!==t){let e=(await (0,u.So)(t,l,s)).data.map(e=>e.id);console.log("available_model_names:",e),x(e)}}catch(e){console.error("Error fetching user models:",e)}})(),e()},[s,t,l]),(0,r.useEffect)(()=>{null!==n&&d(n)},[n]);let p=[];i&&i.models&&(p=i.models),p&&p.includes("all-proxy-models")?(console.log("user models:",h),p=h):p&&p.includes("all-team-models")?p=i.models:p&&0===p.length&&(p=h);let j=void 0!==o?o.toFixed(4):null;return console.log("spend in view user spend: ".concat(o)),(0,a.jsx)("div",{className:"flex items-center",children:(0,a.jsxs)("div",{children:[(0,a.jsxs)("p",{className:"text-tremor-default text-tremor-content dark:text-dark-tremor-content",children:["Total Spend"," "]}),(0,a.jsxs)("p",{className:"text-2xl text-tremor-content-strong dark:text-dark-tremor-content-strong font-semibold",children:["$",j]})]})})},Y=e=>{let{userID:l,userRole:s,selectedTeam:t,accessToken:n}=e,[i,o]=(0,r.useState)([]);(0,r.useEffect)(()=>{(async()=>{try{if(null===l||null===s)return;if(null!==n){let e=(await (0,u.So)(n,l,s)).data.map(e=>e.id);console.log("available_model_names:",e),o(e)}}catch(e){console.error("Error fetching user models:",e)}})()},[n,l,s]);let d=[];return t&&t.models&&(d=t.models),d&&d.includes("all-proxy-models")&&(console.log("user models:",i),d=i),(0,a.jsx)(a.Fragment,{children:(0,a.jsx)("div",{className:"mb-5",children:(0,a.jsx)("p",{className:"text-3xl text-tremor-content-strong dark:text-dark-tremor-content-strong font-semibold",children:null==t?void 0:t.team_alias})})})},J=e=>{let l,{teams:s,setSelectedTeam:t,userRole:n}=e,i={models:[],team_id:null,team_alias:"Default Team"},[o,d]=(0,r.useState)(i);return(l="App User"===n?s:s?[...s,i]:[i],"App User"===n)?null:(0,a.jsxs)("div",{className:"mt-5 mb-5",children:[(0,a.jsx)(y.Z,{children:"Select Team"}),(0,a.jsx)(_.Z,{children:"If you belong to multiple teams, this setting controls which team is used by default when creating new API Keys."}),(0,a.jsxs)(_.Z,{className:"mt-3 mb-3",children:[(0,a.jsx)("b",{children:"Default Team:"})," If no team_id is set for a key, it will be grouped under here."]}),l&&l.length>0?(0,a.jsx)(B.Z,{defaultValue:"0",children:l.map((e,l)=>(0,a.jsx)(K.Z,{value:String(l),onClick:()=>t(e),children:e.team_alias},l))}):(0,a.jsxs)(_.Z,{children:["No team created. ",(0,a.jsx)("b",{children:"Defaulting to personal account."})]})]})},X=s(37963),$=s(97482);console.log("isLocal:",!1);var Q=e=>{let{userID:l,userRole:s,teams:t,keys:n,setUserRole:o,userEmail:d,setUserEmail:c,setTeams:m,setKeys:p,setProxySettings:j,proxySettings:g}=e,[Z,f]=(0,r.useState)(null),_=(0,i.useSearchParams)();_.get("viewSpend"),(0,i.useRouter)();let y=_.get("token"),[b,v]=(0,r.useState)(null),[S,k]=(0,r.useState)(null),[w,N]=(0,r.useState)([]),A={models:[],team_alias:"Default Team",team_id:null},[I,C]=(0,r.useState)(t?t[0]:A);if(window.addEventListener("beforeunload",function(){sessionStorage.clear()}),(0,r.useEffect)(()=>{if(y){let e=(0,X.o)(y);if(e){if(console.log("Decoded token:",e),console.log("Decoded key:",e.key),v(e.key),e.user_role){let l=function(e){if(!e)return"Undefined Role";switch(console.log("Received user role: ".concat(e)),e.toLowerCase()){case"app_owner":case"demo_app_owner":return"App Owner";case"app_admin":case"proxy_admin":return"Admin";case"proxy_admin_viewer":return"Admin Viewer";case"app_user":return"App User";case"internal_user":return"Internal User";case"internal_user_viewer":return"Internal Viewer";default:return"Unknown Role"}}(e.user_role);console.log("Decoded user_role:",l),o(l)}else console.log("User role not defined");e.user_email?c(e.user_email):console.log("User Email is not set ".concat(e))}}if(l&&b&&s&&!n&&!Z){let e=sessionStorage.getItem("userModels"+l);e?N(JSON.parse(e)):(async()=>{try{let e=await (0,u.Dj)(b);j(e);let t=await (0,u.Br)(b,l,s,!1,null,null);if(console.log("received teams in user dashboard: ".concat(Object.keys(t),"; team values: ").concat(Object.entries(t.teams))),"Admin"==s){let e=await (0,u.Qy)(b);f(e),console.log("globalSpend:",e)}else f(t.user_info);p(t.keys),m(t.teams);let n=[...t.teams];n.length>0?(console.log("response['teams']: ".concat(n)),C(n[0])):C(A),sessionStorage.setItem("userData"+l,JSON.stringify(t.keys)),sessionStorage.setItem("userSpendData"+l,JSON.stringify(t.user_info));let a=(await (0,u.So)(b,l,s)).data.map(e=>e.id);console.log("available_model_names:",a),N(a),console.log("userModels:",w),sessionStorage.setItem("userModels"+l,JSON.stringify(a))}catch(e){console.error("There was an error fetching the data",e)}})()}},[l,y,b,n,s]),(0,r.useEffect)(()=>{if(null!==n&&null!=I&&null!==I.team_id){let e=0;for(let l of n)I.hasOwnProperty("team_id")&&null!==l.team_id&&l.team_id===I.team_id&&(e+=l.spend);k(e)}else if(null!==n){let e=0;for(let l of n)e+=l.spend;k(e)}},[I]),null==l||null==y){let e="/sso/key/generate";return console.log("Full URL:",e),window.location.href=e,null}if(null==b)return null;if(null==s&&o("App Owner"),s&&"Admin Viewer"==s){let{Title:e,Paragraph:l}=$.default;return(0,a.jsxs)("div",{children:[(0,a.jsx)(e,{level:1,children:"Access Denied"}),(0,a.jsx)(l,{children:"Ask your proxy admin for access to create keys"})]})}return console.log("inside user dashboard, selected team",I),(0,a.jsx)("div",{className:"w-full mx-4",children:(0,a.jsx)(x.Z,{numItems:1,className:"gap-2 p-8 h-[75vh] w-full mt-2",children:(0,a.jsxs)(h.Z,{numColSpan:1,children:[(0,a.jsx)(Y,{userID:l,userRole:s,selectedTeam:I||null,accessToken:b}),(0,a.jsx)(G,{userID:l,userRole:s,accessToken:b,userSpend:S,selectedTeam:I||null}),(0,a.jsx)(H,{userID:l,userRole:s,accessToken:b,selectedTeam:I||null,data:n,setData:p,teams:t}),(0,a.jsx)(P,{userID:l,team:I||null,userRole:s,accessToken:b,data:n,setData:p},I?I.team_id:null),(0,a.jsx)(J,{teams:t,setSelectedTeam:C,userRole:s})]})})})},ee=s(49167),el=s(35087),es=s(92836),et=s(26734),en=s(41608),ea=s(32126),er=s(23682),ei=s(47047),eo=s(76628),ed=s(25707),ec=s(44041),em=s(6180),eu=s(28683),eh=s(38302),ex=s(66242),ep=s(78578),ej=s(63954),eg=s(34658),eZ=e=>{let{modelID:l,accessToken:s}=e,[t,n]=(0,r.useState)(!1),i=async()=>{try{k.ZP.info("Making API Call"),n(!0);let e=await (0,u.Og)(s,l);console.log("model delete Response:",e),k.ZP.success("Model ".concat(l," deleted successfully")),n(!1)}catch(e){console.error("Error deleting the model:",e)}};return(0,a.jsxs)("div",{children:[(0,a.jsx)(F.Z,{onClick:()=>n(!0),icon:E.Z,size:"sm"}),(0,a.jsx)(w.Z,{open:t,onOk:i,okType:"danger",onCancel:()=>n(!1),children:(0,a.jsxs)(x.Z,{numItems:1,className:"gap-2 w-full",children:[(0,a.jsx)(y.Z,{children:"Delete Model"}),(0,a.jsx)(h.Z,{numColSpan:1,children:(0,a.jsx)("p",{children:"Are you sure you want to delete this model? This action is irreversible."})}),(0,a.jsx)(h.Z,{numColSpan:1,children:(0,a.jsxs)("p",{children:["Model ID: ",(0,a.jsx)("b",{children:l})]})})]})})]})},ef=s(97766),e_=s(46495),ey=s(18190),eb=s(91118),ev=e=>{let{modelMetrics:l,modelMetricsCategories:s,customTooltip:t,premiumUser:n}=e;return n?(0,a.jsx)(eb.Z,{title:"Time to First token (s)",className:"h-72",data:l,index:"date",showLegend:!1,categories:s,colors:["indigo","rose"],connectNulls:!0,customTooltip:t}):(0,a.jsxs)("div",{children:[(0,a.jsx)(ey.Z,{title:"✨ Enterprise Feature",color:"teal",className:"mt-2 mb-4",children:"Enterprise features are available for users with a specific license, please contact LiteLLM to unlock this limitation."}),(0,a.jsx)(p.Z,{variant:"primary",children:(0,a.jsx)("a",{href:"https://forms.gle/W3U4PZpJGFHWtHyA9",target:"_blank",children:"Get in touch"})})]})},eS=e=>{let{fields:l,selectedProvider:s}=e;return 0===l.length?null:(0,a.jsx)(a.Fragment,{children:l.map(e=>(0,a.jsx)(S.Z.Item,{rules:[{required:!0,message:"Required"}],label:e.field_name.replace(/_/g," ").replace(/\b\w/g,e=>e.toUpperCase()),name:e.field_name,tooltip:e.field_description,className:"mb-2",children:(0,a.jsx)(j.Z,{placeholder:e.field_value,type:"password"})},e.field_name))})},ek=s(67951);let{Title:ew,Link:eN}=$.default;(t=n||(n={})).OpenAI="OpenAI",t.Azure="Azure",t.Azure_AI_Studio="Azure AI Studio",t.Anthropic="Anthropic",t.Google_AI_Studio="Google AI Studio",t.Bedrock="Amazon Bedrock",t.OpenAI_Compatible="OpenAI-Compatible Endpoints (Groq, Together AI, Mistral AI, etc.)",t.Vertex_AI="Vertex AI (Anthropic, Gemini, etc.)",t.Databricks="Databricks",t.Ollama="Ollama";let eA={OpenAI:"openai",Azure:"azure",Azure_AI_Studio:"azure_ai",Anthropic:"anthropic",Google_AI_Studio:"gemini",Bedrock:"bedrock",OpenAI_Compatible:"openai",Vertex_AI:"vertex_ai",Databricks:"databricks",Ollama:"ollama"},eI={"BadRequestError (400)":"BadRequestErrorRetries","AuthenticationError (401)":"AuthenticationErrorRetries","TimeoutError (408)":"TimeoutErrorRetries","RateLimitError (429)":"RateLimitErrorRetries","ContentPolicyViolationError (400)":"ContentPolicyViolationErrorRetries","InternalServerError (500)":"InternalServerErrorRetries"},eC=async(e,l,s)=>{try{let t=Array.isArray(e.model)?e.model:[e.model];console.log("received deployments: ".concat(t)),console.log("received type of deployments: ".concat(typeof t)),t.forEach(async s=>{console.log("litellm_model: ".concat(s));let t={},n={};t.model=s;let a="";for(let[l,s]of(console.log("formValues add deployment:",e),Object.entries(e)))if(""!==s){if("model_name"==l)a+=s;else if("custom_llm_provider"==l)continue;else if("model"==l)continue;else if("base_model"===l)n[l]=s;else if("litellm_extra_params"==l){console.log("litellm_extra_params:",s);let e={};if(s&&void 0!=s){try{e=JSON.parse(s)}catch(e){throw k.ZP.error("Failed to parse LiteLLM Extra Params: "+e,10),Error("Failed to parse litellm_extra_params: "+e)}for(let[l,s]of Object.entries(e))t[l]=s}}else t[l]=s}let r={model_name:a,litellm_params:t,model_info:n},i=await (0,u.kK)(l,r);console.log("response for model create call: ".concat(i.data))}),s.resetFields()}catch(e){k.ZP.error("Failed to create model: "+e,10)}};var eP=e=>{var l,s,t;let i,{accessToken:o,token:d,userRole:c,userID:m,modelData:h={data:[]},keys:g,setModelData:Z,premiumUser:f}=e,[b,v]=(0,r.useState)([]),[N]=S.Z.useForm(),[C,P]=(0,r.useState)(null),[E,W]=(0,r.useState)(""),[H,G]=(0,r.useState)([]),Y=Object.values(n).filter(e=>isNaN(Number(e))),[J,X]=(0,r.useState)([]),[Q,ey]=(0,r.useState)("OpenAI"),[eb,eP]=(0,r.useState)(""),[eT,eO]=(0,r.useState)(!1),[eE,eR]=(0,r.useState)(!1),[eM,eF]=(0,r.useState)(null),[eD,eL]=(0,r.useState)([]),[eU,eV]=(0,r.useState)(null),[ez,eq]=(0,r.useState)([]),[eB,eK]=(0,r.useState)([]),[eW,eH]=(0,r.useState)([]),[eG,eY]=(0,r.useState)([]),[eJ,eX]=(0,r.useState)([]),[e$,eQ]=(0,r.useState)([]),[e0,e1]=(0,r.useState)([]),[e2,e4]=(0,r.useState)([]),[e5,e8]=(0,r.useState)([]),[e3,e6]=(0,r.useState)({from:new Date(Date.now()-6048e5),to:new Date}),[e9,e7]=(0,r.useState)(null),[le,ll]=(0,r.useState)(0),[ls,lt]=(0,r.useState)({}),[ln,la]=(0,r.useState)([]),[lr,li]=(0,r.useState)(!1),[lo,ld]=(0,r.useState)(null),[lc,lm]=(0,r.useState)(null),[lu,lh]=(0,r.useState)([]);(0,r.useEffect)(()=>{lb(eU,e3.from,e3.to)},[lo,lc]);let lx=e=>{eF(e),eO(!0)},lp=e=>{eF(e),eR(!0)},lj=async e=>{if(console.log("handleEditSubmit:",e),null==o)return;let l={},s=null;for(let[t,n]of Object.entries(e))"model_id"!==t?l[t]=n:s=n;let t={litellm_params:l,model_info:{id:s}};console.log("handleEditSubmit payload:",t);try{await (0,u.um)(o,t),k.ZP.success("Model updated successfully, restart server to see updates"),eO(!1),eF(null)}catch(e){console.log("Error occurred")}},lg=()=>{W(new Date().toLocaleString())},lZ=async()=>{if(!o){console.error("Access token is missing");return}console.log("new modelGroupRetryPolicy:",e9);try{await (0,u.K_)(o,{router_settings:{model_group_retry_policy:e9}}),k.ZP.success("Retry settings saved successfully")}catch(e){console.error("Failed to save retry settings:",e),k.ZP.error("Failed to save retry settings")}};if((0,r.useEffect)(()=>{if(!o||!d||!c||!m)return;let e=async()=>{try{var e,l,s,t,n,a,r,i,d,h,x,p;let j=await (0,u.hy)(o);X(j);let g=await (0,u.AZ)(o,m,c);console.log("Model data response:",g.data),Z(g);let f=new Set;for(let e=0;e0&&(y=_[_.length-1],console.log("_initial_model_group:",y),eV(y)),console.log("selectedModelGroup:",eU);let b=await (0,u.o6)(o,m,c,y,null===(e=e3.from)||void 0===e?void 0:e.toISOString(),null===(l=e3.to)||void 0===l?void 0:l.toISOString(),null==lo?void 0:lo.token,lc);console.log("Model metrics response:",b),eK(b.data),eH(b.all_api_bases);let v=await (0,u.Rg)(o,y,null===(s=e3.from)||void 0===s?void 0:s.toISOString(),null===(t=e3.to)||void 0===t?void 0:t.toISOString());eY(v.data),eX(v.all_api_bases);let S=await (0,u.N8)(o,m,c,y,null===(n=e3.from)||void 0===n?void 0:n.toISOString(),null===(a=e3.to)||void 0===a?void 0:a.toISOString(),null==lo?void 0:lo.token,lc);console.log("Model exceptions response:",S),eQ(S.data),e1(S.exception_types);let k=await (0,u.fP)(o,m,c,y,null===(r=e3.from)||void 0===r?void 0:r.toISOString(),null===(i=e3.to)||void 0===i?void 0:i.toISOString(),null==lo?void 0:lo.token,lc),w=await (0,u.n$)(o,null===(d=e3.from)||void 0===d?void 0:d.toISOString().split("T")[0],null===(h=e3.to)||void 0===h?void 0:h.toISOString().split("T")[0],y);lt(w);let N=await (0,u.v9)(o,null===(x=e3.from)||void 0===x?void 0:x.toISOString().split("T")[0],null===(p=e3.to)||void 0===p?void 0:p.toISOString().split("T")[0],y);la(N),console.log("dailyExceptions:",w),console.log("dailyExceptionsPerDeplyment:",N),console.log("slowResponses:",k),e8(k);let A=await (0,u.j2)(o);lh(null==A?void 0:A.end_users);let I=(await (0,u.BL)(o,m,c)).router_settings;console.log("routerSettingsInfo:",I);let C=I.model_group_retry_policy,P=I.num_retries;console.log("model_group_retry_policy:",C),console.log("default_retries:",P),e7(C),ll(P)}catch(e){console.error("There was an error fetching the model data",e)}};o&&d&&c&&m&&e();let l=async()=>{let e=await (0,u.qm)();console.log("received model cost map data: ".concat(Object.keys(e))),P(e)};null==C&&l(),lg()},[o,d,c,m,C,E]),!h||!o||!d||!c||!m)return(0,a.jsx)("div",{children:"Loading..."});let lf=[];for(let e=0;e(console.log("GET PROVIDER CALLED! - ".concat(C)),null!=C&&"object"==typeof C&&e in C)?C[e].litellm_provider:"openai";if(n){let e=n.split("/"),l=e[0];r=1===e.length?u(n):l}else r="openai";a&&(i=null==a?void 0:a.input_cost_per_token,o=null==a?void 0:a.output_cost_per_token,d=null==a?void 0:a.max_tokens,c=null==a?void 0:a.max_input_tokens),(null==t?void 0:t.litellm_params)&&(m=Object.fromEntries(Object.entries(null==t?void 0:t.litellm_params).filter(e=>{let[l]=e;return"model"!==l&&"api_base"!==l}))),h.data[e].provider=r,h.data[e].input_cost=i,h.data[e].output_cost=o,h.data[e].input_cost&&(h.data[e].input_cost=(1e6*Number(h.data[e].input_cost)).toFixed(2)),h.data[e].output_cost&&(h.data[e].output_cost=(1e6*Number(h.data[e].output_cost)).toFixed(2)),h.data[e].max_tokens=d,h.data[e].max_input_tokens=c,h.data[e].api_base=null==t?void 0:null===(s=t.litellm_params)||void 0===s?void 0:s.api_base,h.data[e].cleanedLitellmParams=m,lf.push(t.model_name),console.log(h.data[e])}if(c&&"Admin Viewer"==c){let{Title:e,Paragraph:l}=$.default;return(0,a.jsxs)("div",{children:[(0,a.jsx)(e,{level:1,children:"Access Denied"}),(0,a.jsx)(l,{children:"Ask your proxy admin for access to view all models"})]})}let l_=e=>{console.log("received provider string: ".concat(e));let l=Object.keys(n).find(l=>n[l]===e);if(l){let e=eA[l];console.log("mappingResult: ".concat(e));let s=[];"object"==typeof C&&Object.entries(C).forEach(l=>{let[t,n]=l;null!==n&&"object"==typeof n&&"litellm_provider"in n&&(n.litellm_provider===e||n.litellm_provider.includes(e))&&s.push(t)}),G(s),console.log("providerModels: ".concat(H))}},ly=async()=>{try{k.ZP.info("Running health check..."),eP("");let e=await (0,u.EY)(o);eP(e)}catch(e){console.error("Error running health check:",e),eP("Error running health check")}},lb=async(e,l,s)=>{if(console.log("Updating model metrics for group:",e),!o||!m||!c||!l||!s)return;console.log("inside updateModelMetrics - startTime:",l,"endTime:",s),eV(e);let t=null==lo?void 0:lo.token;void 0===t&&(t=null);let n=lc;void 0===n&&(n=null),l.setHours(0),l.setMinutes(0),l.setSeconds(0),s.setHours(23),s.setMinutes(59),s.setSeconds(59);try{let a=await (0,u.o6)(o,m,c,e,l.toISOString(),s.toISOString(),t,n);console.log("Model metrics response:",a),eK(a.data),eH(a.all_api_bases);let r=await (0,u.Rg)(o,e,l.toISOString(),s.toISOString());eY(r.data),eX(r.all_api_bases);let i=await (0,u.N8)(o,m,c,e,l.toISOString(),s.toISOString(),t,n);console.log("Model exceptions response:",i),eQ(i.data),e1(i.exception_types);let d=await (0,u.fP)(o,m,c,e,l.toISOString(),s.toISOString(),t,n);if(console.log("slowResponses:",d),e8(d),e){let t=await (0,u.n$)(o,null==l?void 0:l.toISOString().split("T")[0],null==s?void 0:s.toISOString().split("T")[0],e);lt(t);let n=await (0,u.v9)(o,null==l?void 0:l.toISOString().split("T")[0],null==s?void 0:s.toISOString().split("T")[0],e);la(n)}}catch(e){console.error("Failed to fetch model metrics",e)}},lv=(0,a.jsxs)("div",{children:[(0,a.jsx)(_.Z,{className:"mb-1",children:"Select API Key Name"}),f?(0,a.jsxs)("div",{children:[(0,a.jsxs)(B.Z,{defaultValue:"all-keys",children:[(0,a.jsx)(K.Z,{value:"all-keys",onClick:()=>{ld(null)},children:"All Keys"},"all-keys"),null==g?void 0:g.map((e,l)=>e&&null!==e.key_alias&&e.key_alias.length>0?(0,a.jsx)(K.Z,{value:String(l),onClick:()=>{ld(e)},children:e.key_alias},l):null)]}),(0,a.jsx)(_.Z,{className:"mt-1",children:"Select Customer Name"}),(0,a.jsxs)(B.Z,{defaultValue:"all-customers",children:[(0,a.jsx)(K.Z,{value:"all-customers",onClick:()=>{lm(null)},children:"All Customers"},"all-customers"),null==lu?void 0:lu.map((e,l)=>(0,a.jsx)(K.Z,{value:e,onClick:()=>{lm(e)},children:e},l))]})]}):(0,a.jsxs)("div",{children:[(0,a.jsxs)(B.Z,{defaultValue:"all-keys",children:[(0,a.jsx)(K.Z,{value:"all-keys",onClick:()=>{ld(null)},children:"All Keys"},"all-keys"),null==g?void 0:g.map((e,l)=>e&&null!==e.key_alias&&e.key_alias.length>0?(0,a.jsxs)(K.Z,{value:String(l),disabled:!0,onClick:()=>{ld(e)},children:["✨ ",e.key_alias," (Enterprise only Feature)"]},l):null)]}),(0,a.jsx)(_.Z,{className:"mt-1",children:"Select Customer Name"}),(0,a.jsxs)(B.Z,{defaultValue:"all-customers",children:[(0,a.jsx)(K.Z,{value:"all-customers",onClick:()=>{lm(null)},children:"All Customers"},"all-customers"),null==lu?void 0:lu.map((e,l)=>(0,a.jsxs)(K.Z,{value:e,disabled:!0,onClick:()=>{lm(e)},children:["✨ ",e," (Enterprise only Feature)"]},l))]})]})]}),lS=e=>{var l,s;let{payload:t,active:n}=e;if(!n||!t)return null;let r=null===(s=t[0])||void 0===s?void 0:null===(l=s.payload)||void 0===l?void 0:l.date,i=t.sort((e,l)=>l.value-e.value);if(i.length>5){let e=i.length-5;(i=i.slice(0,5)).push({dataKey:"".concat(e," other deployments"),value:t.slice(5).reduce((e,l)=>e+l.value,0),color:"gray"})}return(0,a.jsxs)("div",{className:"w-150 rounded-tremor-default border border-tremor-border bg-tremor-background p-2 text-tremor-default shadow-tremor-dropdown",children:[r&&(0,a.jsxs)("p",{className:"text-tremor-content-emphasis mb-2",children:["Date: ",r]}),i.map((e,l)=>{let s=parseFloat(e.value.toFixed(5)),t=0===s&&e.value>0?"<0.00001":s.toFixed(5);return(0,a.jsxs)("div",{className:"flex justify-between",children:[(0,a.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,a.jsx)("div",{className:"w-2 h-2 mt-1 rounded-full bg-".concat(e.color,"-500")}),(0,a.jsx)("p",{className:"text-tremor-content",children:e.dataKey})]}),(0,a.jsx)("p",{className:"font-medium text-tremor-content-emphasis text-righ ml-2",children:t})]},l)})]})};console.log("selectedProvider: ".concat(Q)),console.log("providerModels.length: ".concat(H.length));let lk=Object.keys(n).find(e=>n[e]===Q);return lk&&(i=J.find(e=>e.name===eA[lk])),(0,a.jsx)("div",{style:{width:"100%",height:"100%"},children:(0,a.jsxs)(et.Z,{className:"gap-2 p-8 h-[75vh] w-full mt-2",children:[(0,a.jsxs)(en.Z,{className:"flex justify-between mt-2 w-full items-center",children:[(0,a.jsxs)("div",{className:"flex",children:[(0,a.jsx)(es.Z,{children:"All Models"}),(0,a.jsx)(es.Z,{children:"Add Model"}),(0,a.jsx)(es.Z,{children:(0,a.jsx)("pre",{children:"/health Models"})}),(0,a.jsx)(es.Z,{children:"Model Analytics"}),(0,a.jsx)(es.Z,{children:"Model Retry Settings"})]}),(0,a.jsxs)("div",{className:"flex items-center space-x-2",children:[E&&(0,a.jsxs)(_.Z,{children:["Last Refreshed: ",E]}),(0,a.jsx)(F.Z,{icon:ej.Z,variant:"shadow",size:"xs",className:"self-center",onClick:lg})]})]}),(0,a.jsxs)(er.Z,{children:[(0,a.jsxs)(ea.Z,{children:[(0,a.jsxs)(x.Z,{children:[(0,a.jsxs)("div",{className:"flex items-center",children:[(0,a.jsx)(_.Z,{children:"Filter by Public Model Name"}),(0,a.jsxs)(B.Z,{className:"mb-4 mt-2 ml-2 w-50",defaultValue:eU||eD[0],onValueChange:e=>eV("all"===e?"all":e),value:eU||eD[0],children:[(0,a.jsx)(K.Z,{value:"all",children:"All Models"}),eD.map((e,l)=>(0,a.jsx)(K.Z,{value:e,onClick:()=>eV(e),children:e},l))]})]}),(0,a.jsx)(M.Z,{children:(0,a.jsxs)(D.Z,{style:{maxWidth:"1500px",width:"100%"},children:[(0,a.jsx)(V.Z,{children:(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(z.Z,{style:{maxWidth:"150px",whiteSpace:"normal",wordBreak:"break-word",fontSize:"11px"},children:"Public Model Name"}),(0,a.jsx)(z.Z,{style:{maxWidth:"100px",whiteSpace:"normal",wordBreak:"break-word",fontSize:"11px"},children:"Provider"}),"Admin"===c&&(0,a.jsx)(z.Z,{style:{maxWidth:"150px",whiteSpace:"normal",wordBreak:"break-word",fontSize:"11px"},children:"API Base"}),(0,a.jsxs)(z.Z,{style:{maxWidth:"85px",whiteSpace:"normal",wordBreak:"break-word",fontSize:"11px"},children:["Input Price"," ",(0,a.jsx)("p",{style:{fontSize:"10px",color:"gray"},children:"/1M Tokens ($)"})]}),(0,a.jsxs)(z.Z,{style:{maxWidth:"85px",whiteSpace:"normal",wordBreak:"break-word",fontSize:"11px"},children:["Output Price"," ",(0,a.jsx)("p",{style:{fontSize:"10px",color:"gray"},children:"/1M Tokens ($)"})]}),(0,a.jsx)(z.Z,{style:{maxWidth:"100px",whiteSpace:"normal",wordBreak:"break-word",fontSize:"11px"},children:f?"Created At":(0,a.jsxs)("a",{href:"https://forms.gle/W3U4PZpJGFHWtHyA9",target:"_blank",style:{color:"#72bcd4"},children:[" ","✨ Created At"]})}),(0,a.jsx)(z.Z,{style:{maxWidth:"100px",whiteSpace:"normal",wordBreak:"break-word",fontSize:"11px"},children:f?"Created By":(0,a.jsxs)("a",{href:"https://forms.gle/W3U4PZpJGFHWtHyA9",target:"_blank",style:{color:"#72bcd4"},children:[" ","✨ Created By"]})}),(0,a.jsx)(z.Z,{style:{maxWidth:"50px",whiteSpace:"normal",wordBreak:"break-word",fontSize:"11px"},children:"Status"}),(0,a.jsx)(z.Z,{})]})}),(0,a.jsx)(L.Z,{children:h.data.filter(e=>"all"===eU||e.model_name===eU||null==eU||""===eU).map((e,l)=>{var s;return(0,a.jsxs)(q.Z,{style:{maxHeight:"1px",minHeight:"1px"},children:[(0,a.jsx)(U.Z,{style:{maxWidth:"100px",whiteSpace:"normal",wordBreak:"break-word"},children:(0,a.jsx)("p",{className:"text-xs",children:e.model_name||"-"})}),(0,a.jsx)(U.Z,{style:{maxWidth:"100px",whiteSpace:"normal",wordBreak:"break-word"},children:(0,a.jsx)("p",{className:"text-xs",children:e.provider||"-"})}),"Admin"===c&&(0,a.jsx)(U.Z,{style:{maxWidth:"150px",whiteSpace:"normal",wordBreak:"break-word"},children:(0,a.jsx)(em.Z,{title:e&&e.api_base,children:(0,a.jsx)("pre",{style:{maxWidth:"150px",whiteSpace:"normal",wordBreak:"break-word"},className:"text-xs",title:e&&e.api_base?e.api_base:"",children:e&&e.api_base?e.api_base.slice(0,20):"-"})})}),(0,a.jsx)(U.Z,{style:{maxWidth:"80px",whiteSpace:"normal",wordBreak:"break-word"},children:(0,a.jsx)("pre",{className:"text-xs",children:e.input_cost?e.input_cost:null!=e.litellm_params.input_cost_per_token&&void 0!=e.litellm_params.input_cost_per_token?(1e6*Number(e.litellm_params.input_cost_per_token)).toFixed(2):null})}),(0,a.jsx)(U.Z,{style:{maxWidth:"80px",whiteSpace:"normal",wordBreak:"break-word"},children:(0,a.jsx)("pre",{className:"text-xs",children:e.output_cost?e.output_cost:e.litellm_params.output_cost_per_token?(1e6*Number(e.litellm_params.output_cost_per_token)).toFixed(2):null})}),(0,a.jsx)(U.Z,{children:(0,a.jsx)("p",{className:"text-xs",children:f&&((s=e.model_info.created_at)?new Date(s).toLocaleDateString("en-US"):null)||"-"})}),(0,a.jsx)(U.Z,{children:(0,a.jsx)("p",{className:"text-xs",children:f&&e.model_info.created_by||"-"})}),(0,a.jsx)(U.Z,{style:{maxWidth:"100px",whiteSpace:"normal",wordBreak:"break-word"},children:e.model_info.db_model?(0,a.jsx)(R.Z,{size:"xs",className:"text-white",children:(0,a.jsx)("p",{className:"text-xs",children:"DB Model"})}):(0,a.jsx)(R.Z,{size:"xs",className:"text-black",children:(0,a.jsx)("p",{className:"text-xs",children:"Config Model"})})}),(0,a.jsx)(U.Z,{style:{maxWidth:"150px",whiteSpace:"normal",wordBreak:"break-word"},children:(0,a.jsxs)(x.Z,{numItems:3,children:[(0,a.jsx)(eu.Z,{children:(0,a.jsx)(F.Z,{icon:T.Z,size:"sm",onClick:()=>lp(e)})}),(0,a.jsx)(eu.Z,{children:(0,a.jsx)(F.Z,{icon:O.Z,size:"sm",onClick:()=>lx(e)})}),(0,a.jsx)(eu.Z,{children:(0,a.jsx)(eZ,{modelID:e.model_info.id,accessToken:o})})]})})]},l)})})]})})]}),(0,a.jsx)(e=>{let{visible:l,onCancel:s,model:t,onSubmit:n}=e,[r]=S.Z.useForm(),i={},o="",d="";if(t){i=t.litellm_params,o=t.model_name;let e=t.model_info;e&&(d=e.id,console.log("model_id: ".concat(d)),i.model_id=d)}return(0,a.jsx)(w.Z,{title:"Edit Model "+o,visible:l,width:800,footer:null,onOk:()=>{r.validateFields().then(e=>{n(e),r.resetFields()}).catch(e=>{console.error("Validation failed:",e)})},onCancel:s,children:(0,a.jsxs)(S.Z,{form:r,onFinish:lj,initialValues:i,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(S.Z.Item,{className:"mt-8",label:"api_base",name:"api_base",children:(0,a.jsx)(j.Z,{})}),(0,a.jsx)(S.Z.Item,{label:"tpm",name:"tpm",tooltip:"int (optional) - Tokens limit for this deployment: in tokens per minute (tpm). Find this information on your model/providers website",children:(0,a.jsx)(A.Z,{min:0,step:1})}),(0,a.jsx)(S.Z.Item,{label:"rpm",name:"rpm",tooltip:"int (optional) - Rate limit for this deployment: in requests per minute (rpm). Find this information on your model/providers website",children:(0,a.jsx)(A.Z,{min:0,step:1})}),(0,a.jsx)(S.Z.Item,{label:"max_retries",name:"max_retries",children:(0,a.jsx)(A.Z,{min:0,step:1})}),(0,a.jsx)(S.Z.Item,{label:"timeout",name:"timeout",tooltip:"int (optional) - Timeout in seconds for LLM requests (Defaults to 600 seconds)",children:(0,a.jsx)(A.Z,{min:0,step:1})}),(0,a.jsx)(S.Z.Item,{label:"stream_timeout",name:"stream_timeout",tooltip:"int (optional) - Timeout for stream requests (seconds)",children:(0,a.jsx)(A.Z,{min:0,step:1})}),(0,a.jsx)(S.Z.Item,{label:"input_cost_per_token",name:"input_cost_per_token",tooltip:"float (optional) - Input cost per token",children:(0,a.jsx)(A.Z,{min:0,step:1e-4})}),(0,a.jsx)(S.Z.Item,{label:"output_cost_per_token",name:"output_cost_per_token",tooltip:"float (optional) - Output cost per token",children:(0,a.jsx)(A.Z,{min:0,step:1e-4})}),(0,a.jsx)(S.Z.Item,{label:"model_id",name:"model_id",hidden:!0})]}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(I.ZP,{htmlType:"submit",children:"Save"})})]})})},{visible:eT,onCancel:()=>{eO(!1),eF(null)},model:eM,onSubmit:lj}),(0,a.jsxs)(w.Z,{title:eM&&eM.model_name,visible:eE,width:800,footer:null,onCancel:()=>{eR(!1),eF(null)},children:[(0,a.jsx)(y.Z,{children:"Model Info"}),(0,a.jsx)(ek.Z,{language:"json",children:eM&&JSON.stringify(eM,null,2)})]})]}),(0,a.jsxs)(ea.Z,{className:"h-full",children:[(0,a.jsx)(ew,{level:2,children:"Add new model"}),(0,a.jsx)(M.Z,{children:(0,a.jsxs)(S.Z,{form:N,onFinish:()=>{N.validateFields().then(e=>{eC(e,o,N)}).catch(e=>{console.error("Validation failed:",e)})},labelCol:{span:10},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(S.Z.Item,{rules:[{required:!0,message:"Required"}],label:"Provider:",name:"custom_llm_provider",tooltip:"E.g. OpenAI, Azure OpenAI, Anthropic, Bedrock, etc.",labelCol:{span:10},labelAlign:"left",children:(0,a.jsx)(B.Z,{value:Q.toString(),children:Y.map((e,l)=>(0,a.jsx)(K.Z,{value:e,onClick:()=>{l_(e),ey(e)},children:e},l))})}),(0,a.jsx)(S.Z.Item,{rules:[{required:!0,message:"Required"}],label:"Public Model Name",name:"model_name",tooltip:"Model name your users will pass in. Also used for load-balancing, LiteLLM will load balance between all models with this public name.",className:"mb-0",children:(0,a.jsx)(j.Z,{placeholder:"Vertex AI (Anthropic, Gemini, etc.)"===(t=Q.toString())?"gemini-pro":"Anthropic"==t||"Amazon Bedrock"==t?"claude-3-opus":"Google AI Studio"==t?"gemini-pro":"Azure AI Studio"==t?"azure_ai/command-r-plus":"Azure"==t?"azure/my-deployment":"gpt-3.5-turbo"})}),(0,a.jsxs)(eh.Z,{children:[(0,a.jsx)(eu.Z,{span:10}),(0,a.jsx)(eu.Z,{span:10,children:(0,a.jsx)(_.Z,{className:"mb-3 mt-1",children:"Model name your users will pass in."})})]}),(0,a.jsx)(S.Z.Item,{rules:[{required:!0,message:"Required"}],label:"LiteLLM Model Name(s)",name:"model",tooltip:"Actual model name used for making litellm.completion() call.",className:"mb-0",children:"Azure"===Q?(0,a.jsx)(j.Z,{placeholder:"Enter model name"}):H.length>0?(0,a.jsx)(ei.Z,{value:H,children:H.map((e,l)=>(0,a.jsx)(eo.Z,{value:e,children:e},l))}):(0,a.jsx)(j.Z,{placeholder:"gpt-3.5-turbo-0125"})}),(0,a.jsxs)(eh.Z,{children:[(0,a.jsx)(eu.Z,{span:10}),(0,a.jsx)(eu.Z,{span:10,children:(0,a.jsxs)(_.Z,{className:"mb-3 mt-1",children:["Actual model name used for making"," ",(0,a.jsx)(eN,{href:"https://docs.litellm.ai/docs/providers",target:"_blank",children:"litellm.completion() call"}),". We'll"," ",(0,a.jsx)(eN,{href:"https://docs.litellm.ai/docs/proxy/reliability#step-1---set-deployments-on-config",target:"_blank",children:"loadbalance"})," ","models with the same 'public name'"]})})]}),void 0!==i&&i.fields.length>0&&(0,a.jsx)(eS,{fields:i.fields,selectedProvider:i.name}),"Amazon Bedrock"!=Q&&"Vertex AI (Anthropic, Gemini, etc.)"!=Q&&"Ollama"!=Q&&(void 0===i||0==i.fields.length)&&(0,a.jsx)(S.Z.Item,{rules:[{required:!0,message:"Required"}],label:"API Key",name:"api_key",children:(0,a.jsx)(j.Z,{placeholder:"sk-",type:"password"})}),"OpenAI"==Q&&(0,a.jsx)(S.Z.Item,{label:"Organization ID",name:"organization_id",children:(0,a.jsx)(j.Z,{placeholder:"[OPTIONAL] my-unique-org"})}),"Vertex AI (Anthropic, Gemini, etc.)"==Q&&(0,a.jsx)(S.Z.Item,{rules:[{required:!0,message:"Required"}],label:"Vertex Project",name:"vertex_project",children:(0,a.jsx)(j.Z,{placeholder:"adroit-cadet-1234.."})}),"Vertex AI (Anthropic, Gemini, etc.)"==Q&&(0,a.jsx)(S.Z.Item,{rules:[{required:!0,message:"Required"}],label:"Vertex Location",name:"vertex_location",children:(0,a.jsx)(j.Z,{placeholder:"us-east-1"})}),"Vertex AI (Anthropic, Gemini, etc.)"==Q&&(0,a.jsx)(S.Z.Item,{rules:[{required:!0,message:"Required"}],label:"Vertex Credentials",name:"vertex_credentials",className:"mb-0",children:(0,a.jsx)(e_.Z,{name:"file",accept:".json",beforeUpload:e=>{if("application/json"===e.type){let l=new FileReader;l.onload=e=>{if(e.target){let l=e.target.result;N.setFieldsValue({vertex_credentials:l})}},l.readAsText(e)}return!1},onChange(e){"uploading"!==e.file.status&&console.log(e.file,e.fileList),"done"===e.file.status?k.ZP.success("".concat(e.file.name," file uploaded successfully")):"error"===e.file.status&&k.ZP.error("".concat(e.file.name," file upload failed."))},children:(0,a.jsx)(I.ZP,{icon:(0,a.jsx)(ef.Z,{}),children:"Click to Upload"})})}),"Vertex AI (Anthropic, Gemini, etc.)"==Q&&(0,a.jsxs)(eh.Z,{children:[(0,a.jsx)(eu.Z,{span:10}),(0,a.jsx)(eu.Z,{span:10,children:(0,a.jsx)(_.Z,{className:"mb-3 mt-1",children:"Give litellm a gcp service account(.json file), so it can make the relevant calls"})})]}),("Azure"==Q||"OpenAI-Compatible Endpoints (Groq, Together AI, Mistral AI, etc.)"==Q)&&(0,a.jsx)(S.Z.Item,{rules:[{required:!0,message:"Required"}],label:"API Base",name:"api_base",children:(0,a.jsx)(j.Z,{placeholder:"https://..."})}),"Azure"==Q&&(0,a.jsx)(S.Z.Item,{rules:[{required:!0,message:"Required"}],label:"API Version",name:"api_version",children:(0,a.jsx)(j.Z,{placeholder:"2023-07-01-preview"})}),"Azure"==Q&&(0,a.jsxs)("div",{children:[(0,a.jsx)(S.Z.Item,{label:"Base Model",name:"base_model",className:"mb-0",children:(0,a.jsx)(j.Z,{placeholder:"azure/gpt-3.5-turbo"})}),(0,a.jsxs)(eh.Z,{children:[(0,a.jsx)(eu.Z,{span:10}),(0,a.jsx)(eu.Z,{span:10,children:(0,a.jsxs)(_.Z,{className:"mb-2",children:["The actual model your azure deployment uses. Used for accurate cost tracking. Select name from"," ",(0,a.jsx)(eN,{href:"https://github.com/BerriAI/litellm/blob/main/model_prices_and_context_window.json",target:"_blank",children:"here"})]})})]})]}),"Amazon Bedrock"==Q&&(0,a.jsx)(S.Z.Item,{rules:[{required:!0,message:"Required"}],label:"AWS Access Key ID",name:"aws_access_key_id",tooltip:"You can provide the raw key or the environment variable (e.g. `os.environ/MY_SECRET_KEY`).",children:(0,a.jsx)(j.Z,{placeholder:""})}),"Amazon Bedrock"==Q&&(0,a.jsx)(S.Z.Item,{rules:[{required:!0,message:"Required"}],label:"AWS Secret Access Key",name:"aws_secret_access_key",tooltip:"You can provide the raw key or the environment variable (e.g. `os.environ/MY_SECRET_KEY`).",children:(0,a.jsx)(j.Z,{placeholder:""})}),"Amazon Bedrock"==Q&&(0,a.jsx)(S.Z.Item,{rules:[{required:!0,message:"Required"}],label:"AWS Region Name",name:"aws_region_name",tooltip:"You can provide the raw key or the environment variable (e.g. `os.environ/MY_SECRET_KEY`).",children:(0,a.jsx)(j.Z,{placeholder:"us-east-1"})}),(0,a.jsx)(S.Z.Item,{label:"LiteLLM Params",name:"litellm_extra_params",tooltip:"Optional litellm params used for making a litellm.completion() call.",className:"mb-0",children:(0,a.jsx)(ep.Z,{rows:4,placeholder:'{ "rpm": 100, "timeout": 0, "stream_timeout": 0 }'})}),(0,a.jsxs)(eh.Z,{children:[(0,a.jsx)(eu.Z,{span:10}),(0,a.jsx)(eu.Z,{span:10,children:(0,a.jsxs)(_.Z,{className:"mb-3 mt-1",children:["Pass JSON of litellm supported params"," ",(0,a.jsx)(eN,{href:"https://docs.litellm.ai/docs/completion/input",target:"_blank",children:"litellm.completion() call"})]})})]})]}),(0,a.jsx)("div",{style:{textAlign:"center",marginTop:"10px"},children:(0,a.jsx)(I.ZP,{htmlType:"submit",children:"Add Model"})}),(0,a.jsx)(em.Z,{title:"Get help on our github",children:(0,a.jsx)($.default.Link,{href:"https://github.com/BerriAI/litellm/issues",children:"Need Help?"})})]})})]}),(0,a.jsx)(ea.Z,{children:(0,a.jsxs)(M.Z,{children:[(0,a.jsx)(_.Z,{children:"`/health` will run a very small request through your models configured on litellm"}),(0,a.jsx)(p.Z,{onClick:ly,children:"Run `/health`"}),eb&&(0,a.jsx)("pre",{children:JSON.stringify(eb,null,2)})]})}),(0,a.jsxs)(ea.Z,{children:[(0,a.jsxs)(x.Z,{numItems:4,className:"mt-2 mb-2",children:[(0,a.jsxs)(eu.Z,{children:[(0,a.jsx)(_.Z,{children:"Select Time Range"}),(0,a.jsx)(el.Z,{enableSelect:!0,value:e3,className:"mr-2",onValueChange:e=>{e6(e),lb(eU,e.from,e.to)}})]}),(0,a.jsxs)(eu.Z,{className:"ml-2",children:[(0,a.jsx)(_.Z,{children:"Select Model Group"}),(0,a.jsx)(B.Z,{defaultValue:eU||eD[0],value:eU||eD[0],children:eD.map((e,l)=>(0,a.jsx)(K.Z,{value:e,onClick:()=>lb(e,e3.from,e3.to),children:e},l))})]}),(0,a.jsx)(eu.Z,{children:(0,a.jsx)(ex.Z,{trigger:"click",content:lv,overlayStyle:{width:"20vw"},children:(0,a.jsx)(p.Z,{icon:eg.Z,size:"md",variant:"secondary",className:"mt-4 ml-2",style:{border:"none"},onClick:()=>li(!0)})})})]}),(0,a.jsxs)(x.Z,{numItems:2,children:[(0,a.jsx)(eu.Z,{children:(0,a.jsx)(M.Z,{className:"mr-2 max-h-[400px] min-h-[400px]",children:(0,a.jsxs)(et.Z,{children:[(0,a.jsxs)(en.Z,{variant:"line",defaultValue:"1",children:[(0,a.jsx)(es.Z,{value:"1",children:"Avg. Latency per Token"}),(0,a.jsx)(es.Z,{value:"2",children:"✨ Time to first token"})]}),(0,a.jsxs)(er.Z,{children:[(0,a.jsxs)(ea.Z,{children:[(0,a.jsx)("p",{className:"text-gray-500 italic",children:" (seconds/token)"}),(0,a.jsx)(_.Z,{className:"text-gray-500 italic mt-1 mb-1",children:"average Latency for successfull requests divided by the total tokens"}),eB&&eW&&(0,a.jsx)(ed.Z,{title:"Model Latency",className:"h-72",data:eB,showLegend:!1,index:"date",categories:eW,connectNulls:!0,customTooltip:lS})]}),(0,a.jsx)(ea.Z,{children:(0,a.jsx)(ev,{modelMetrics:eG,modelMetricsCategories:eJ,customTooltip:lS,premiumUser:f})})]})]})})}),(0,a.jsx)(eu.Z,{children:(0,a.jsx)(M.Z,{className:"ml-2 max-h-[400px] min-h-[400px] overflow-y-auto",children:(0,a.jsxs)(D.Z,{children:[(0,a.jsx)(V.Z,{children:(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(z.Z,{children:"Deployment"}),(0,a.jsx)(z.Z,{children:"Success Responses"}),(0,a.jsxs)(z.Z,{children:["Slow Responses ",(0,a.jsx)("p",{children:"Success Responses taking 600+s"})]})]})}),(0,a.jsx)(L.Z,{children:e5.map((e,l)=>(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(U.Z,{children:e.api_base}),(0,a.jsx)(U.Z,{children:e.total_count}),(0,a.jsx)(U.Z,{children:e.slow_count})]},l))})]})})})]}),(0,a.jsx)(x.Z,{numItems:1,className:"gap-2 w-full mt-2",children:(0,a.jsxs)(M.Z,{children:[(0,a.jsxs)(y.Z,{children:["All Exceptions for ",eU]}),(0,a.jsx)(ec.Z,{className:"h-60",data:e$,index:"model",categories:e0,stack:!0,yAxisWidth:30})]})}),(0,a.jsxs)(x.Z,{numItems:1,className:"gap-2 w-full mt-2",children:[(0,a.jsxs)(M.Z,{children:[(0,a.jsxs)(y.Z,{children:["All Up Rate Limit Errors (429) for ",eU]}),(0,a.jsxs)(x.Z,{numItems:1,children:[(0,a.jsxs)(eu.Z,{children:[(0,a.jsxs)(ee.Z,{style:{fontSize:"15px",fontWeight:"normal",color:"#535452"},children:["Num Rate Limit Errors ",ls.sum_num_rate_limit_exceptions]}),(0,a.jsx)(ec.Z,{className:"h-40",data:ls.daily_data,index:"date",colors:["rose"],categories:["num_rate_limit_exceptions"],onValueChange:e=>console.log(e)})]}),(0,a.jsx)(eu.Z,{})]})]}),f?(0,a.jsx)(a.Fragment,{children:ln.map((e,l)=>(0,a.jsxs)(M.Z,{children:[(0,a.jsx)(y.Z,{children:e.api_base?e.api_base:"Unknown API Base"}),(0,a.jsx)(x.Z,{numItems:1,children:(0,a.jsxs)(eu.Z,{children:[(0,a.jsxs)(ee.Z,{style:{fontSize:"15px",fontWeight:"normal",color:"#535452"},children:["Num Rate Limit Errors (429) ",e.sum_num_rate_limit_exceptions]}),(0,a.jsx)(ec.Z,{className:"h-40",data:e.daily_data,index:"date",colors:["rose"],categories:["num_rate_limit_exceptions"],onValueChange:e=>console.log(e)})]})})]},l))}):(0,a.jsx)(a.Fragment,{children:ln&&ln.length>0&&ln.slice(0,1).map((e,l)=>(0,a.jsxs)(M.Z,{children:[(0,a.jsx)(y.Z,{children:"✨ Rate Limit Errors by Deployment"}),(0,a.jsx)("p",{className:"mb-2 text-gray-500 italic text-[12px]",children:"Upgrade to see exceptions for all deployments"}),(0,a.jsx)(p.Z,{variant:"primary",className:"mb-2",children:(0,a.jsx)("a",{href:"https://forms.gle/W3U4PZpJGFHWtHyA9",target:"_blank",children:"Get Free Trial"})}),(0,a.jsxs)(M.Z,{children:[(0,a.jsx)(y.Z,{children:e.api_base}),(0,a.jsx)(x.Z,{numItems:1,children:(0,a.jsxs)(eu.Z,{children:[(0,a.jsxs)(ee.Z,{style:{fontSize:"15px",fontWeight:"normal",color:"#535452"},children:["Num Rate Limit Errors ",e.sum_num_rate_limit_exceptions]}),(0,a.jsx)(ec.Z,{className:"h-40",data:e.daily_data,index:"date",colors:["rose"],categories:["num_rate_limit_exceptions"],onValueChange:e=>console.log(e)})]})})]})]},l))})]})]}),(0,a.jsxs)(ea.Z,{children:[(0,a.jsxs)("div",{className:"flex items-center",children:[(0,a.jsx)(_.Z,{children:"Filter by Public Model Name"}),(0,a.jsx)(B.Z,{className:"mb-4 mt-2 ml-2 w-50",defaultValue:eU||eD[0],value:eU||eD[0],onValueChange:e=>eV(e),children:eD.map((e,l)=>(0,a.jsx)(K.Z,{value:e,onClick:()=>eV(e),children:e},l))})]}),(0,a.jsxs)(y.Z,{children:["Retry Policy for ",eU]}),(0,a.jsx)(_.Z,{className:"mb-6",children:"How many retries should be attempted based on the Exception"}),eI&&(0,a.jsx)("table",{children:(0,a.jsx)("tbody",{children:Object.entries(eI).map((e,l)=>{var s;let[t,n]=e,r=null==e9?void 0:null===(s=e9[eU])||void 0===s?void 0:s[n];return null==r&&(r=le),(0,a.jsxs)("tr",{className:"flex justify-between items-center mt-2",children:[(0,a.jsx)("td",{children:(0,a.jsx)(_.Z,{children:t})}),(0,a.jsx)("td",{children:(0,a.jsx)(A.Z,{className:"ml-5",value:r,min:0,step:1,onChange:e=>{e7(l=>{var s;let t=null!==(s=null==l?void 0:l[eU])&&void 0!==s?s:{};return{...null!=l?l:{},[eU]:{...t,[n]:e}}})}})})]},l)})})}),(0,a.jsx)(p.Z,{className:"mt-6 mr-8",onClick:lZ,children:"Save"})]})]})]})})},eT=e=>{let{isInvitationLinkModalVisible:l,setIsInvitationLinkModalVisible:s,baseUrl:t,invitationLinkData:n}=e,{Title:r,Paragraph:i}=$.default;return(0,a.jsxs)(w.Z,{title:"Invitation Link",visible:l,width:800,footer:null,onOk:()=>{s(!1)},onCancel:()=>{s(!1)},children:[(0,a.jsx)(i,{children:"Copy and send the generated link to onboard this user to the proxy."}),(0,a.jsxs)("div",{className:"flex justify-between pt-5 pb-2",children:[(0,a.jsx)(_.Z,{className:"text-base",children:"User ID"}),(0,a.jsx)(_.Z,{children:null==n?void 0:n.user_id})]}),(0,a.jsxs)("div",{className:"flex justify-between pt-5 pb-2",children:[(0,a.jsx)(_.Z,{children:"Invitation Link"}),(0,a.jsxs)(_.Z,{children:[t,"/ui/onboarding?id=",null==n?void 0:n.id]})]}),(0,a.jsxs)("div",{className:"flex justify-end mt-5",children:[(0,a.jsx)("div",{}),(0,a.jsx)(b.CopyToClipboard,{text:"".concat(t,"/ui/onboarding?id=").concat(null==n?void 0:n.id),onCopy:()=>k.ZP.success("Copied!"),children:(0,a.jsx)(p.Z,{variant:"primary",children:"Copy invitation link"})})]})]})};let{Option:eO}=v.default;var eE=e=>{let{userID:l,accessToken:s,teams:t,possibleUIRoles:n}=e,[o]=S.Z.useForm(),[d,c]=(0,r.useState)(!1),[m,h]=(0,r.useState)(null),[x,g]=(0,r.useState)([]),[Z,f]=(0,r.useState)(!1),[y,b]=(0,r.useState)(null),A=(0,i.useRouter)(),[C,P]=(0,r.useState)("");(0,r.useEffect)(()=>{(async()=>{try{let e=await (0,u.So)(s,l,"any"),t=[];for(let l=0;l{if(A){let{protocol:e,host:l}=window.location;P("".concat(e,"/").concat(l))}},[A]);let T=async e=>{try{var t;k.ZP.info("Making API Call"),c(!0),console.log("formValues in create user:",e);let n=await (0,u.Ov)(s,null,e);console.log("user create Response:",n),h(n.key);let a=(null===(t=n.data)||void 0===t?void 0:t.user_id)||n.user_id;(0,u.XO)(s,a).then(e=>{b(e),f(!0)}),k.ZP.success("API user Created"),o.resetFields(),localStorage.removeItem("userData"+l)}catch(e){console.error("Error creating the user:",e)}};return(0,a.jsxs)("div",{children:[(0,a.jsx)(p.Z,{className:"mx-auto mb-0",onClick:()=>c(!0),children:"+ Invite User"}),(0,a.jsxs)(w.Z,{title:"Invite User",visible:d,width:800,footer:null,onOk:()=>{c(!1),o.resetFields()},onCancel:()=>{c(!1),h(null),o.resetFields()},children:[(0,a.jsx)(_.Z,{className:"mb-1",children:"Create a User who can own keys"}),(0,a.jsxs)(S.Z,{form:o,onFinish:T,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsx)(S.Z.Item,{label:"User Email",name:"user_email",children:(0,a.jsx)(j.Z,{placeholder:""})}),(0,a.jsx)(S.Z.Item,{label:"User Role",name:"user_role",children:(0,a.jsx)(v.default,{children:n&&Object.entries(n).map(e=>{let[l,{ui_label:s,description:t}]=e;return(0,a.jsx)(K.Z,{value:l,title:s,children:(0,a.jsxs)("div",{className:"flex",children:[s," ",(0,a.jsx)("p",{className:"ml-2",style:{color:"gray",fontSize:"12px"},children:t})]})},l)})})}),(0,a.jsx)(S.Z.Item,{label:"Team ID",name:"team_id",children:(0,a.jsx)(v.default,{placeholder:"Select Team ID",style:{width:"100%"},children:t?t.map(e=>(0,a.jsx)(eO,{value:e.team_id,children:e.team_alias},e.team_id)):(0,a.jsx)(eO,{value:null,children:"Default Team"},"default")})}),(0,a.jsx)(S.Z.Item,{label:"Metadata",name:"metadata",children:(0,a.jsx)(N.Z.TextArea,{rows:4,placeholder:"Enter metadata as JSON"})}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(I.ZP,{htmlType:"submit",children:"Create User"})})]})]}),m&&(0,a.jsx)(eT,{isInvitationLinkModalVisible:Z,setIsInvitationLinkModalVisible:f,baseUrl:C,invitationLinkData:y})]})},eR=e=>{let{visible:l,possibleUIRoles:s,onCancel:t,user:n,onSubmit:i}=e,[o,d]=(0,r.useState)(n),[c]=S.Z.useForm();(0,r.useEffect)(()=>{c.resetFields()},[n]);let m=async()=>{c.resetFields(),t()},u=async e=>{i(e),c.resetFields(),t()};return n?(0,a.jsx)(w.Z,{visible:l,onCancel:m,footer:null,title:"Edit User "+n.user_id,width:1e3,children:(0,a.jsx)(S.Z,{form:c,onFinish:u,initialValues:n,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(S.Z.Item,{className:"mt-8",label:"User Email",tooltip:"Email of the User",name:"user_email",children:(0,a.jsx)(j.Z,{})}),(0,a.jsx)(S.Z.Item,{label:"user_id",name:"user_id",hidden:!0,children:(0,a.jsx)(j.Z,{})}),(0,a.jsx)(S.Z.Item,{label:"User Role",name:"user_role",children:(0,a.jsx)(v.default,{children:s&&Object.entries(s).map(e=>{let[l,{ui_label:s,description:t}]=e;return(0,a.jsx)(K.Z,{value:l,title:s,children:(0,a.jsxs)("div",{className:"flex",children:[s," ",(0,a.jsx)("p",{className:"ml-2",style:{color:"gray",fontSize:"12px"},children:t})]})},l)})})}),(0,a.jsx)(S.Z.Item,{label:"Spend (USD)",name:"spend",tooltip:"(float) - Spend of all LLM calls completed by this user",children:(0,a.jsx)(A.Z,{min:0,step:1})}),(0,a.jsx)(S.Z.Item,{label:"User Budget (USD)",name:"max_budget",tooltip:"(float) - Maximum budget of this user",children:(0,a.jsx)(A.Z,{min:0,step:1})}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(I.ZP,{htmlType:"submit",children:"Save"})})]})})}):null},eM=e=>{let{accessToken:l,token:s,keys:t,userRole:n,userID:i,teams:o,setKeys:d}=e,[c,m]=(0,r.useState)(null),[h,p]=(0,r.useState)(null),[j,g]=(0,r.useState)(0),[Z,f]=r.useState(null),[_,y]=(0,r.useState)(null),[b,v]=(0,r.useState)(!1),[S,w]=(0,r.useState)(null),[N,A]=(0,r.useState)({}),I=async()=>{w(null),v(!1)},C=async e=>{if(console.log("inside handleEditSubmit:",e),l&&s&&n&&i){try{await (0,u.pf)(l,e,null),k.ZP.success("User ".concat(e.user_id," updated successfully"))}catch(e){console.error("There was an error updating the user",e)}c&&m(c.map(l=>l.user_id===e.user_id?e:l)),w(null),v(!1)}};return((0,r.useEffect)(()=>{if(!l||!s||!n||!i)return;let e=async()=>{try{let e=await (0,u.Br)(l,null,n,!0,j,25);console.log("user data response:",e),m(e);let s=await (0,u.lg)(l);A(s)}catch(e){console.error("There was an error fetching the model data",e)}};l&&s&&n&&i&&e()},[l,s,n,i,j]),c&&l&&s&&n&&i)?(0,a.jsx)("div",{style:{width:"100%"},children:(0,a.jsxs)(x.Z,{className:"gap-2 p-2 h-[90vh] w-full mt-8",children:[(0,a.jsx)(eE,{userID:i,accessToken:l,teams:o,possibleUIRoles:N}),(0,a.jsxs)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[90vh] mb-4",children:[(0,a.jsx)("div",{className:"mb-4 mt-1"}),(0,a.jsx)(et.Z,{children:(0,a.jsxs)(er.Z,{children:[(0,a.jsx)(ea.Z,{children:(0,a.jsxs)(D.Z,{className:"mt-5",children:[(0,a.jsx)(V.Z,{children:(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(z.Z,{children:"User ID"}),(0,a.jsx)(z.Z,{children:"User Email"}),(0,a.jsx)(z.Z,{children:"Role"}),(0,a.jsx)(z.Z,{children:"User Spend ($ USD)"}),(0,a.jsx)(z.Z,{children:"User Max Budget ($ USD)"}),(0,a.jsx)(z.Z,{children:"API Keys"}),(0,a.jsx)(z.Z,{})]})}),(0,a.jsx)(L.Z,{children:c.map(e=>{var l,s;return(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(U.Z,{children:e.user_id||"-"}),(0,a.jsx)(U.Z,{children:e.user_email||"-"}),(0,a.jsx)(U.Z,{children:(null==N?void 0:null===(l=N[null==e?void 0:e.user_role])||void 0===l?void 0:l.ui_label)||"-"}),(0,a.jsx)(U.Z,{children:e.spend?null===(s=e.spend)||void 0===s?void 0:s.toFixed(2):"-"}),(0,a.jsx)(U.Z,{children:e.max_budget?e.max_budget:"Unlimited"}),(0,a.jsx)(U.Z,{children:(0,a.jsx)(x.Z,{numItems:2,children:e&&e.key_aliases&&e.key_aliases.filter(e=>null!==e).length>0?(0,a.jsxs)(R.Z,{size:"xs",color:"indigo",children:[e.key_aliases.filter(e=>null!==e).length,"\xa0Keys"]}):(0,a.jsx)(R.Z,{size:"xs",color:"gray",children:"No Keys"})})}),(0,a.jsx)(U.Z,{children:(0,a.jsx)(F.Z,{icon:O.Z,onClick:()=>{w(e),v(!0)},children:"View Keys"})})]},e.user_id)})})]})}),(0,a.jsx)(ea.Z,{children:(0,a.jsxs)("div",{className:"flex items-center",children:[(0,a.jsx)("div",{className:"flex-1"}),(0,a.jsx)("div",{className:"flex-1 flex justify-between items-center"})]})})]})}),(0,a.jsx)(eR,{visible:b,possibleUIRoles:N,onCancel:I,user:S,onSubmit:C})]}),function(){if(!c)return null;let e=Math.ceil(c.length/25);return(0,a.jsxs)("div",{className:"flex justify-between items-center",children:[(0,a.jsxs)("div",{children:["Showing Page ",j+1," of ",e]}),(0,a.jsxs)("div",{className:"flex",children:[(0,a.jsx)("button",{className:"bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-l focus:outline-none",disabled:0===j,onClick:()=>g(j-1),children:"← Prev"}),(0,a.jsx)("button",{className:"bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-r focus:outline-none",onClick:()=>{g(j+1)},children:"Next →"})]})]})}()]})}):(0,a.jsx)("div",{children:"Loading..."})},eF=e=>{let{teams:l,searchParams:s,accessToken:t,setTeams:n,userID:i,userRole:o}=e,[d]=S.Z.useForm(),[c]=S.Z.useForm(),{Title:m,Paragraph:g}=$.default,[Z,f]=(0,r.useState)(""),[y,b]=(0,r.useState)(!1),[C,P]=(0,r.useState)(l?l[0]:null),[T,W]=(0,r.useState)(!1),[H,G]=(0,r.useState)(!1),[Y,J]=(0,r.useState)([]),[X,Q]=(0,r.useState)(!1),[ee,el]=(0,r.useState)(null),[es,et]=(0,r.useState)({}),en=e=>{P(e),b(!0)},ea=async e=>{let s=e.team_id;if(console.log("handleEditSubmit:",e),null==t)return;let a=await (0,u.Gh)(t,e);l&&n(l.map(e=>e.team_id===s?a.data:e)),k.ZP.success("Team updated successfully"),b(!1),P(null)},er=async e=>{el(e),Q(!0)},ei=async()=>{if(null!=ee&&null!=l&&null!=t){try{await (0,u.rs)(t,ee);let e=l.filter(e=>e.team_id!==ee);n(e)}catch(e){console.error("Error deleting the team:",e)}Q(!1),el(null)}};(0,r.useEffect)(()=>{let e=async()=>{try{if(null===i||null===o||null===t||null===l)return;console.log("fetching team info:");let e={};for(let s=0;s<(null==l?void 0:l.length);s++){let n=l[s].team_id,a=await (0,u.Xm)(t,n);console.log("teamInfo response:",a),null!==a&&(e={...e,[n]:a})}et(e)}catch(e){console.error("Error fetching team info:",e)}};(async()=>{try{if(null===i||null===o)return;if(null!==t){let e=(await (0,u.So)(t,i,o)).data.map(e=>e.id);console.log("available_model_names:",e),J(e)}}catch(e){console.error("Error fetching user models:",e)}})(),e()},[t,i,o,l]);let eo=async e=>{try{if(null!=t){var s;let a=null==e?void 0:e.team_alias;if((null!==(s=null==l?void 0:l.map(e=>e.team_alias))&&void 0!==s?s:[]).includes(a))throw Error("Team alias ".concat(a," already exists, please pick another alias"));k.ZP.info("Creating Team");let r=await (0,u.hT)(t,e);null!==l?n([...l,r]):n([r]),console.log("response for team create call: ".concat(r)),k.ZP.success("Team created"),W(!1)}}catch(e){console.error("Error creating the team:",e),k.ZP.error("Error creating the team: "+e,20)}},ed=async e=>{try{if(null!=t&&null!=l){k.ZP.info("Adding Member");let s={role:"user",user_email:e.user_email,user_id:e.user_id},a=await (0,u.cu)(t,C.team_id,s);console.log("response for team create call: ".concat(a.data));let r=l.findIndex(e=>(console.log("team.team_id=".concat(e.team_id,"; response.data.team_id=").concat(a.data.team_id)),e.team_id===a.data.team_id));if(console.log("foundIndex: ".concat(r)),-1!==r){let e=[...l];e[r]=a.data,n(e),P(a.data)}G(!1)}}catch(e){console.error("Error creating the team:",e)}};return console.log("received teams ".concat(JSON.stringify(l))),(0,a.jsx)("div",{className:"w-full mx-4",children:(0,a.jsxs)(x.Z,{numItems:1,className:"gap-2 p-8 h-[75vh] w-full mt-2",children:[(0,a.jsxs)(h.Z,{numColSpan:1,children:[(0,a.jsx)(m,{level:4,children:"All Teams"}),(0,a.jsxs)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:[(0,a.jsxs)(D.Z,{children:[(0,a.jsx)(V.Z,{children:(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(z.Z,{children:"Team Name"}),(0,a.jsx)(z.Z,{children:"Spend (USD)"}),(0,a.jsx)(z.Z,{children:"Budget (USD)"}),(0,a.jsx)(z.Z,{children:"Models"}),(0,a.jsx)(z.Z,{children:"TPM / RPM Limits"}),(0,a.jsx)(z.Z,{children:"Info"})]})}),(0,a.jsx)(L.Z,{children:l&&l.length>0?l.map(e=>(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(U.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:e.team_alias}),(0,a.jsx)(U.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:e.spend}),(0,a.jsx)(U.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:null!==e.max_budget&&void 0!==e.max_budget?e.max_budget:"No limit"}),(0,a.jsx)(U.Z,{style:{maxWidth:"8-x",whiteSpace:"pre-wrap",overflow:"hidden"},children:Array.isArray(e.models)?(0,a.jsx)("div",{style:{display:"flex",flexDirection:"column"},children:0===e.models.length?(0,a.jsx)(R.Z,{size:"xs",className:"mb-1",color:"red",children:(0,a.jsx)(_.Z,{children:"All Proxy Models"})}):e.models.map((e,l)=>"all-proxy-models"===e?(0,a.jsx)(R.Z,{size:"xs",className:"mb-1",color:"red",children:(0,a.jsx)(_.Z,{children:"All Proxy Models"})},l):(0,a.jsx)(R.Z,{size:"xs",className:"mb-1",color:"blue",children:(0,a.jsx)(_.Z,{children:e.length>30?"".concat(e.slice(0,30),"..."):e})},l))}):null}),(0,a.jsx)(U.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,a.jsxs)(_.Z,{children:["TPM: ",e.tpm_limit?e.tpm_limit:"Unlimited"," ",(0,a.jsx)("br",{}),"RPM:"," ",e.rpm_limit?e.rpm_limit:"Unlimited"]})}),(0,a.jsxs)(U.Z,{children:[(0,a.jsxs)(_.Z,{children:[es&&e.team_id&&es[e.team_id]&&es[e.team_id].keys&&es[e.team_id].keys.length," ","Keys"]}),(0,a.jsxs)(_.Z,{children:[es&&e.team_id&&es[e.team_id]&&es[e.team_id].team_info&&es[e.team_id].team_info.members_with_roles&&es[e.team_id].team_info.members_with_roles.length," ","Members"]})]}),(0,a.jsxs)(U.Z,{children:[(0,a.jsx)(F.Z,{icon:O.Z,size:"sm",onClick:()=>en(e)}),(0,a.jsx)(F.Z,{onClick:()=>er(e.team_id),icon:E.Z,size:"sm"})]})]},e.team_id)):null})]}),X&&(0,a.jsx)("div",{className:"fixed z-10 inset-0 overflow-y-auto",children:(0,a.jsxs)("div",{className:"flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0",children:[(0,a.jsx)("div",{className:"fixed inset-0 transition-opacity","aria-hidden":"true",children:(0,a.jsx)("div",{className:"absolute inset-0 bg-gray-500 opacity-75"})}),(0,a.jsx)("span",{className:"hidden sm:inline-block sm:align-middle sm:h-screen","aria-hidden":"true",children:"​"}),(0,a.jsxs)("div",{className:"inline-block align-bottom bg-white rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full",children:[(0,a.jsx)("div",{className:"bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4",children:(0,a.jsx)("div",{className:"sm:flex sm:items-start",children:(0,a.jsxs)("div",{className:"mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left",children:[(0,a.jsx)("h3",{className:"text-lg leading-6 font-medium text-gray-900",children:"Delete Team"}),(0,a.jsx)("div",{className:"mt-2",children:(0,a.jsx)("p",{className:"text-sm text-gray-500",children:"Are you sure you want to delete this team ?"})})]})})}),(0,a.jsxs)("div",{className:"bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse",children:[(0,a.jsx)(p.Z,{onClick:ei,color:"red",className:"ml-2",children:"Delete"}),(0,a.jsx)(p.Z,{onClick:()=>{Q(!1),el(null)},children:"Cancel"})]})]})]})})]})]}),(0,a.jsxs)(h.Z,{numColSpan:1,children:[(0,a.jsx)(p.Z,{className:"mx-auto",onClick:()=>W(!0),children:"+ Create New Team"}),(0,a.jsx)(w.Z,{title:"Create Team",visible:T,width:800,footer:null,onOk:()=>{W(!1),d.resetFields()},onCancel:()=>{W(!1),d.resetFields()},children:(0,a.jsxs)(S.Z,{form:d,onFinish:eo,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(S.Z.Item,{label:"Team Name",name:"team_alias",rules:[{required:!0,message:"Please input a team name"}],children:(0,a.jsx)(j.Z,{placeholder:""})}),(0,a.jsx)(S.Z.Item,{label:"Models",name:"models",children:(0,a.jsxs)(v.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:[(0,a.jsx)(v.default.Option,{value:"all-proxy-models",children:"All Proxy Models"},"all-proxy-models"),Y.map(e=>(0,a.jsx)(v.default.Option,{value:e,children:e},e))]})}),(0,a.jsx)(S.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,a.jsx)(A.Z,{step:.01,precision:2,width:200})}),(0,a.jsx)(S.Z.Item,{className:"mt-8",label:"Reset Budget",name:"budget_duration",children:(0,a.jsxs)(v.default,{defaultValue:null,placeholder:"n/a",children:[(0,a.jsx)(v.default.Option,{value:"24h",children:"daily"}),(0,a.jsx)(v.default.Option,{value:"7d",children:"weekly"}),(0,a.jsx)(v.default.Option,{value:"30d",children:"monthly"})]})}),(0,a.jsx)(S.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,a.jsx)(A.Z,{step:1,width:400})}),(0,a.jsx)(S.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,a.jsx)(A.Z,{step:1,width:400})})]}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(I.ZP,{htmlType:"submit",children:"Create Team"})})]})})]}),(0,a.jsxs)(h.Z,{numColSpan:1,children:[(0,a.jsx)(m,{level:4,children:"Team Members"}),(0,a.jsx)(g,{children:"If you belong to multiple teams, this setting controls which teams members you see."}),l&&l.length>0?(0,a.jsx)(B.Z,{defaultValue:"0",children:l.map((e,l)=>(0,a.jsx)(K.Z,{value:String(l),onClick:()=>{P(e)},children:e.team_alias},l))}):(0,a.jsxs)(g,{children:["No team created. ",(0,a.jsx)("b",{children:"Defaulting to personal account."})]})]}),(0,a.jsxs)(h.Z,{numColSpan:1,children:[(0,a.jsx)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,a.jsxs)(D.Z,{children:[(0,a.jsx)(V.Z,{children:(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(z.Z,{children:"Member Name"}),(0,a.jsx)(z.Z,{children:"Role"})]})}),(0,a.jsx)(L.Z,{children:C?C.members_with_roles.map((e,l)=>(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(U.Z,{children:e.user_email?e.user_email:e.user_id?e.user_id:null}),(0,a.jsx)(U.Z,{children:e.role})]},l)):null})]})}),C&&(0,a.jsx)(e=>{let{visible:l,onCancel:s,team:t,onSubmit:n}=e,[r]=S.Z.useForm();return(0,a.jsx)(w.Z,{title:"Edit Team",visible:l,width:800,footer:null,onOk:()=>{r.validateFields().then(e=>{n({...e,team_id:t.team_id}),r.resetFields()}).catch(e=>{console.error("Validation failed:",e)})},onCancel:s,children:(0,a.jsxs)(S.Z,{form:r,onFinish:ea,initialValues:t,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(S.Z.Item,{label:"Team Name",name:"team_alias",rules:[{required:!0,message:"Please input a team name"}],children:(0,a.jsx)(j.Z,{})}),(0,a.jsx)(S.Z.Item,{label:"Models",name:"models",children:(0,a.jsxs)(v.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:[(0,a.jsx)(v.default.Option,{value:"all-proxy-models",children:"All Proxy Models"},"all-proxy-models"),Y&&Y.map(e=>(0,a.jsx)(v.default.Option,{value:e,children:e},e))]})}),(0,a.jsx)(S.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,a.jsx)(A.Z,{step:.01,precision:2,width:200})}),(0,a.jsx)(S.Z.Item,{className:"mt-8",label:"Reset Budget",name:"budget_duration",children:(0,a.jsxs)(v.default,{defaultValue:null,placeholder:"n/a",children:[(0,a.jsx)(v.default.Option,{value:"24h",children:"daily"}),(0,a.jsx)(v.default.Option,{value:"7d",children:"weekly"}),(0,a.jsx)(v.default.Option,{value:"30d",children:"monthly"})]})}),(0,a.jsx)(S.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,a.jsx)(A.Z,{step:1,width:400})}),(0,a.jsx)(S.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,a.jsx)(A.Z,{step:1,width:400})}),(0,a.jsx)(S.Z.Item,{label:"Requests per minute Limit (RPM)",name:"team_id",hidden:!0})]}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(I.ZP,{htmlType:"submit",children:"Edit Team"})})]})})},{visible:y,onCancel:()=>{b(!1),P(null)},team:C,onSubmit:ea})]}),(0,a.jsxs)(h.Z,{numColSpan:1,children:[(0,a.jsx)(p.Z,{className:"mx-auto mb-5",onClick:()=>G(!0),children:"+ Add member"}),(0,a.jsx)(w.Z,{title:"Add member",visible:H,width:800,footer:null,onOk:()=>{G(!1),c.resetFields()},onCancel:()=>{G(!1),c.resetFields()},children:(0,a.jsxs)(S.Z,{form:d,onFinish:ed,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(S.Z.Item,{label:"Email",name:"user_email",className:"mb-4",children:(0,a.jsx)(N.Z,{name:"user_email",className:"px-3 py-2 border rounded-md w-full"})}),(0,a.jsx)("div",{className:"text-center mb-4",children:"OR"}),(0,a.jsx)(S.Z.Item,{label:"User ID",name:"user_id",className:"mb-4",children:(0,a.jsx)(N.Z,{name:"user_id",className:"px-3 py-2 border rounded-md w-full"})})]}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(I.ZP,{htmlType:"submit",children:"Add member"})})]})})]})]})})},eD=e=>{let l,{searchParams:s,accessToken:t,showSSOBanner:n}=e,[o]=S.Z.useForm(),[d]=S.Z.useForm(),{Title:c,Paragraph:m}=$.default,[j,g]=(0,r.useState)(""),[Z,f]=(0,r.useState)(null),[y,b]=(0,r.useState)(null),[v,A]=(0,r.useState)(!1),[C,P]=(0,r.useState)(!1),[T,E]=(0,r.useState)(!1),[R,W]=(0,r.useState)(!1),[H,G]=(0,r.useState)(!1),[Y,J]=(0,r.useState)(!1),X=(0,i.useRouter)(),[Q,ee]=(0,r.useState)(null),[el,es]=(0,r.useState)("");try{l=window.location.origin}catch(e){l=""}l+="/fallback/login";let et=()=>{J(!1)},en=["proxy_admin","proxy_admin_viewer"];(0,r.useEffect)(()=>{if(X){let{protocol:e,host:l}=window.location;es("".concat(e,"//").concat(l))}},[X]),(0,r.useEffect)(()=>{(async()=>{if(null!=t){let e=[],l=await (0,u.Xd)(t,"proxy_admin_viewer");l.forEach(l=>{e.push({user_role:l.user_role,user_id:l.user_id,user_email:l.user_email})}),console.log("proxy viewers: ".concat(l));let s=await (0,u.Xd)(t,"proxy_admin");s.forEach(l=>{e.push({user_role:l.user_role,user_id:l.user_id,user_email:l.user_email})}),console.log("proxy admins: ".concat(s)),console.log("combinedList: ".concat(e)),f(e),ee(await (0,u.lg)(t))}})()},[t]);let ea=()=>{W(!1),d.resetFields(),o.resetFields()},er=()=>{W(!1),d.resetFields(),o.resetFields()},ei=e=>(0,a.jsxs)(S.Z,{form:o,onFinish:e,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsx)(a.Fragment,{children:(0,a.jsx)(S.Z.Item,{label:"Email",name:"user_email",className:"mb-8 mt-4",children:(0,a.jsx)(N.Z,{name:"user_email",className:"px-3 py-2 border rounded-md w-full"})})}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},className:"mt-4",children:(0,a.jsx)(I.ZP,{htmlType:"submit",children:"Add member"})})]}),eo=(e,l,s)=>(0,a.jsxs)(S.Z,{form:o,onFinish:e,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(S.Z.Item,{rules:[{required:!0,message:"Required"}],label:"User Role",name:"user_role",labelCol:{span:10},labelAlign:"left",children:(0,a.jsx)(B.Z,{value:l,children:en.map((e,l)=>(0,a.jsx)(K.Z,{value:e,children:e},l))})}),(0,a.jsx)(S.Z.Item,{label:"Team ID",name:"user_id",hidden:!0,initialValue:s,valuePropName:"user_id",className:"mt-8",children:(0,a.jsx)(N.Z,{value:s,disabled:!0})})]}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(I.ZP,{htmlType:"submit",children:"Update role"})})]}),ed=async e=>{try{if(null!=t&&null!=Z){k.ZP.info("Making API Call");let l=await (0,u.pf)(t,e,null);console.log("response for team create call: ".concat(l));let s=Z.findIndex(e=>(console.log("user.user_id=".concat(e.user_id,"; response.user_id=").concat(l.user_id)),e.user_id===l.user_id));console.log("foundIndex: ".concat(s)),-1==s&&(console.log("updates admin with new user"),Z.push(l),f(Z)),k.ZP.success("Refresh tab to see updated user role"),W(!1)}}catch(e){console.error("Error creating the key:",e)}},ec=async e=>{try{if(null!=t&&null!=Z){var l;k.ZP.info("Making API Call");let s=await (0,u.pf)(t,e,"proxy_admin_viewer");console.log("response for team create call: ".concat(s));let n=(null===(l=s.data)||void 0===l?void 0:l.user_id)||s.user_id;(0,u.XO)(t,n).then(e=>{b(e),A(!0)});let a=Z.findIndex(e=>(console.log("user.user_id=".concat(e.user_id,"; response.user_id=").concat(s.user_id)),e.user_id===s.user_id));console.log("foundIndex: ".concat(a)),-1==a&&(console.log("updates admin with new user"),Z.push(s),f(Z)),o.resetFields(),P(!1)}}catch(e){console.error("Error creating the key:",e)}},em=async e=>{try{if(null!=t&&null!=Z){var l;k.ZP.info("Making API Call"),e.user_email,e.user_id;let s=await (0,u.pf)(t,e,"proxy_admin"),n=(null===(l=s.data)||void 0===l?void 0:l.user_id)||s.user_id;(0,u.XO)(t,n).then(e=>{b(e),A(!0)}),console.log("response for team create call: ".concat(s));let a=Z.findIndex(e=>(console.log("user.user_id=".concat(e.user_id,"; response.user_id=").concat(n)),e.user_id===s.user_id));console.log("foundIndex: ".concat(a)),-1==a&&(console.log("updates admin with new user"),Z.push(s),f(Z)),o.resetFields(),E(!1)}}catch(e){console.error("Error creating the key:",e)}},eu=async e=>{if(null==t)return;let l={environment_variables:{PROXY_BASE_URL:e.proxy_base_url,GOOGLE_CLIENT_ID:e.google_client_id,GOOGLE_CLIENT_SECRET:e.google_client_secret}};(0,u.K_)(t,l)};return console.log("admins: ".concat(null==Z?void 0:Z.length)),(0,a.jsxs)("div",{className:"w-full m-2 mt-2 p-8",children:[(0,a.jsx)(c,{level:4,children:"Admin Access "}),(0,a.jsxs)(m,{children:[n&&(0,a.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/ui#restrict-ui-access",children:"Requires SSO Setup"}),(0,a.jsx)("br",{}),(0,a.jsx)("b",{children:"Proxy Admin: "})," Can create keys, teams, users, add models, etc."," ",(0,a.jsx)("br",{}),(0,a.jsx)("b",{children:"Proxy Admin Viewer: "}),"Can just view spend. They cannot create keys, teams or grant users access to new models."," "]}),(0,a.jsxs)(x.Z,{numItems:1,className:"gap-2 p-2 w-full",children:[(0,a.jsx)(h.Z,{numColSpan:1,children:(0,a.jsx)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,a.jsxs)(D.Z,{children:[(0,a.jsx)(V.Z,{children:(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(z.Z,{children:"Member Name"}),(0,a.jsx)(z.Z,{children:"Role"})]})}),(0,a.jsx)(L.Z,{children:Z?Z.map((e,l)=>{var s;return(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(U.Z,{children:e.user_email?e.user_email:e.user_id?e.user_id:null}),(0,a.jsxs)(U.Z,{children:[" ",(null==Q?void 0:null===(s=Q[null==e?void 0:e.user_role])||void 0===s?void 0:s.ui_label)||"-"]}),(0,a.jsxs)(U.Z,{children:[(0,a.jsx)(F.Z,{icon:O.Z,size:"sm",onClick:()=>W(!0)}),(0,a.jsx)(w.Z,{title:"Update role",visible:R,width:800,footer:null,onOk:ea,onCancel:er,children:eo(ed,e.user_role,e.user_id)})]})]},l)}):null})]})})}),(0,a.jsx)(h.Z,{numColSpan:1,children:(0,a.jsxs)("div",{className:"flex justify-start",children:[(0,a.jsx)(p.Z,{className:"mr-4 mb-5",onClick:()=>E(!0),children:"+ Add admin"}),(0,a.jsx)(w.Z,{title:"Add admin",visible:T,width:800,footer:null,onOk:()=>{E(!1),d.resetFields(),o.resetFields()},onCancel:()=>{E(!1),A(!1),d.resetFields(),o.resetFields()},children:ei(em)}),(0,a.jsx)(eT,{isInvitationLinkModalVisible:v,setIsInvitationLinkModalVisible:A,baseUrl:el,invitationLinkData:y}),(0,a.jsx)(p.Z,{className:"mb-5",onClick:()=>P(!0),children:"+ Add viewer"}),(0,a.jsx)(w.Z,{title:"Add viewer",visible:C,width:800,footer:null,onOk:()=>{P(!1),d.resetFields(),o.resetFields()},onCancel:()=>{P(!1),d.resetFields(),o.resetFields()},children:ei(ec)})]})})]}),(0,a.jsxs)(x.Z,{children:[(0,a.jsx)(c,{level:4,children:"Add SSO"}),(0,a.jsxs)("div",{className:"flex justify-start mb-4",children:[(0,a.jsx)(p.Z,{onClick:()=>G(!0),children:"Add SSO"}),(0,a.jsx)(w.Z,{title:"Add SSO",visible:H,width:800,footer:null,onOk:()=>{G(!1),o.resetFields()},onCancel:()=>{G(!1),o.resetFields()},children:(0,a.jsxs)(S.Z,{form:o,onFinish:e=>{em(e),eu(e),G(!1),J(!0)},labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(S.Z.Item,{label:"Admin Email",name:"user_email",rules:[{required:!0,message:"Please enter the email of the proxy admin"}],children:(0,a.jsx)(N.Z,{})}),(0,a.jsx)(S.Z.Item,{label:"PROXY BASE URL",name:"proxy_base_url",rules:[{required:!0,message:"Please enter the proxy base url"}],children:(0,a.jsx)(N.Z,{})}),(0,a.jsx)(S.Z.Item,{label:"GOOGLE CLIENT ID",name:"google_client_id",rules:[{required:!0,message:"Please enter the google client id"}],children:(0,a.jsx)(N.Z.Password,{})}),(0,a.jsx)(S.Z.Item,{label:"GOOGLE CLIENT SECRET",name:"google_client_secret",rules:[{required:!0,message:"Please enter the google client secret"}],children:(0,a.jsx)(N.Z.Password,{})})]}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(I.ZP,{htmlType:"submit",children:"Save"})})]})}),(0,a.jsxs)(w.Z,{title:"SSO Setup Instructions",visible:Y,width:800,footer:null,onOk:et,onCancel:()=>{J(!1)},children:[(0,a.jsx)("p",{children:"Follow these steps to complete the SSO setup:"}),(0,a.jsx)(_.Z,{className:"mt-2",children:"1. DO NOT Exit this TAB"}),(0,a.jsx)(_.Z,{className:"mt-2",children:"2. Open a new tab, visit your proxy base url"}),(0,a.jsx)(_.Z,{className:"mt-2",children:"3. Confirm your SSO is configured correctly and you can login on the new Tab"}),(0,a.jsx)(_.Z,{className:"mt-2",children:"4. If Step 3 is successful, you can close this tab"}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(I.ZP,{onClick:et,children:"Done"})})]})]}),(0,a.jsxs)(ey.Z,{title:"Login without SSO",color:"teal",children:["If you need to login without sso, you can access"," ",(0,a.jsxs)("a",{href:l,target:"_blank",children:[(0,a.jsx)("b",{children:l})," "]})]})]})]})},eL=s(42556),eU=s(90252),eV=e=>{let{alertingSettings:l,handleInputChange:s,handleResetField:t,handleSubmit:n,premiumUser:r}=e,[i]=S.Z.useForm();return(0,a.jsxs)(S.Z,{form:i,onFinish:()=>{let e=i.getFieldsValue();Object.values(e).some(e=>""===e||null==e)?console.log("Some form fields are empty."):n(e)},labelAlign:"left",children:[l.map((e,l)=>(0,a.jsxs)(q.Z,{children:[(0,a.jsxs)(U.Z,{align:"center",children:[(0,a.jsx)(_.Z,{children:e.field_name}),(0,a.jsx)("p",{style:{fontSize:"0.65rem",color:"#808080",fontStyle:"italic"},className:"mt-1",children:e.field_description})]}),e.premium_field?r?(0,a.jsx)(S.Z.Item,{name:e.field_name,children:(0,a.jsx)(U.Z,{children:"Integer"===e.field_type?(0,a.jsx)(A.Z,{step:1,value:e.field_value,onChange:l=>s(e.field_name,l)}):(0,a.jsx)(N.Z,{value:e.field_value,onChange:l=>s(e.field_name,l)})})}):(0,a.jsx)(U.Z,{children:(0,a.jsx)(p.Z,{className:"flex items-center justify-center",children:(0,a.jsx)("a",{href:"https://forms.gle/W3U4PZpJGFHWtHyA9",target:"_blank",children:"✨ Enterprise Feature"})})}):(0,a.jsx)(S.Z.Item,{name:e.field_name,className:"mb-0",children:(0,a.jsx)(U.Z,{children:"Integer"===e.field_type?(0,a.jsx)(A.Z,{step:1,value:e.field_value,onChange:l=>s(e.field_name,l),className:"p-0"}):(0,a.jsx)(N.Z,{value:e.field_value,onChange:l=>s(e.field_name,l)})})}),(0,a.jsx)(U.Z,{children:!0==e.stored_in_db?(0,a.jsx)(R.Z,{icon:eU.Z,className:"text-white",children:"In DB"}):!1==e.stored_in_db?(0,a.jsx)(R.Z,{className:"text-gray bg-white outline",children:"In Config"}):(0,a.jsx)(R.Z,{className:"text-gray bg-white outline",children:"Not Set"})}),(0,a.jsx)(U.Z,{children:(0,a.jsx)(F.Z,{icon:E.Z,color:"red",onClick:()=>t(e.field_name,l),children:"Reset"})})]},l)),(0,a.jsx)("div",{children:(0,a.jsx)(I.ZP,{htmlType:"submit",children:"Update Settings"})})]})},ez=e=>{let{accessToken:l,premiumUser:s}=e,[t,n]=(0,r.useState)([]);return console.log("INSIDE ALERTING SETTINGS"),(0,r.useEffect)(()=>{l&&(0,u.RQ)(l).then(e=>{n(e)})},[l]),(0,a.jsx)(eV,{alertingSettings:t,handleInputChange:(e,l)=>{n(t.map(s=>s.field_name===e?{...s,field_value:l}:s))},handleResetField:(e,s)=>{if(l)try{let l=t.map(l=>l.field_name===e?{...l,stored_in_db:null,field_value:l.field_default_value}:l);console.log("INSIDE HANDLE RESET FIELD"),n(l)}catch(e){console.log("ERROR OCCURRED!")}},handleSubmit:e=>{if(!l||null==e||void 0==e)return;let s={};t.forEach(e=>{s[e.field_name]=e.field_value});let n={...e,...s};try{(0,u.jA)(l,"alerting_args",n),k.ZP.success("Wait 10s for proxy to update.")}catch(e){}},premiumUser:s})},eq=s(84406);let{Title:eB,Paragraph:eK}=$.default;var eW=e=>{let{accessToken:l,userRole:s,userID:t,premiumUser:n}=e,[i,o]=(0,r.useState)([]),[d,c]=(0,r.useState)([]),[m,h]=(0,r.useState)(!1),[g]=S.Z.useForm(),[Z,f]=(0,r.useState)(null),[y,b]=(0,r.useState)([]),[N,A]=(0,r.useState)(""),[C,P]=(0,r.useState)({}),[T,E]=(0,r.useState)([]),[R,B]=(0,r.useState)(!1),[W,H]=(0,r.useState)([]),[G,Y]=(0,r.useState)(null),[J,X]=(0,r.useState)([]),[$,Q]=(0,r.useState)(!1),[ee,el]=(0,r.useState)(null),ei=e=>{T.includes(e)?E(T.filter(l=>l!==e)):E([...T,e])},eo={llm_exceptions:"LLM Exceptions",llm_too_slow:"LLM Responses Too Slow",llm_requests_hanging:"LLM Requests Hanging",budget_alerts:"Budget Alerts (API Keys, Users)",db_exceptions:"Database Exceptions (Read/Write)",daily_reports:"Weekly/Monthly Spend Reports",outage_alerts:"Outage Alerts",region_outage_alerts:"Region Outage Alerts"};(0,r.useEffect)(()=>{l&&s&&t&&(0,u.BL)(l,t,s).then(e=>{console.log("callbacks",e),o(e.callbacks),H(e.available_callbacks);let l=e.alerts;if(console.log("alerts_data",l),l&&l.length>0){let e=l[0];console.log("_alert_info",e);let s=e.variables.SLACK_WEBHOOK_URL;console.log("catch_all_webhook",s),E(e.active_alerts),A(s),P(e.alerts_to_webhook)}c(l)})},[l,s,t]);let ed=e=>T&&T.includes(e),ec=()=>{if(!l)return;let e={};d.filter(e=>"email"===e.name).forEach(l=>{var s;Object.entries(null!==(s=l.variables)&&void 0!==s?s:{}).forEach(l=>{let[s,t]=l,n=document.querySelector('input[name="'.concat(s,'"]'));n&&n.value&&(e[s]=null==n?void 0:n.value)})}),console.log("updatedVariables",e);try{(0,u.K_)(l,{general_settings:{alerting:["email"]},environment_variables:e})}catch(e){k.ZP.error("Failed to update alerts: "+e,20)}k.ZP.success("Email settings updated successfully")},em=async e=>{if(!l)return;let s={};Object.entries(e).forEach(e=>{let[l,t]=e;"callback"!==l&&(s[l]=t)});try{await (0,u.K_)(l,{environment_variables:s}),k.ZP.success("Callback added successfully"),h(!1),g.resetFields(),f(null)}catch(e){k.ZP.error("Failed to add callback: "+e,20)}},eu=async e=>{if(!l)return;let s=null==e?void 0:e.callback,t={};Object.entries(e).forEach(e=>{let[l,s]=e;"callback"!==l&&(t[l]=s)});try{await (0,u.K_)(l,{environment_variables:t,litellm_settings:{success_callback:[s]}}),k.ZP.success("Callback ".concat(s," added successfully")),h(!1),g.resetFields(),f(null)}catch(e){k.ZP.error("Failed to add callback: "+e,20)}},eh=e=>{console.log("inside handleSelectedCallbackChange",e),f(e.litellm_callback_name),console.log("all callbacks",W),e&&e.litellm_callback_params?(X(e.litellm_callback_params),console.log("selectedCallbackParams",J)):X([])};return l?(console.log("callbacks: ".concat(i)),(0,a.jsxs)("div",{className:"w-full mx-4",children:[(0,a.jsx)(x.Z,{numItems:1,className:"gap-2 p-8 w-full mt-2",children:(0,a.jsxs)(et.Z,{children:[(0,a.jsxs)(en.Z,{variant:"line",defaultValue:"1",children:[(0,a.jsx)(es.Z,{value:"1",children:"Logging Callbacks"}),(0,a.jsx)(es.Z,{value:"2",children:"Alerting Types"}),(0,a.jsx)(es.Z,{value:"3",children:"Alerting Settings"}),(0,a.jsx)(es.Z,{value:"4",children:"Email Alerts"})]}),(0,a.jsxs)(er.Z,{children:[(0,a.jsxs)(ea.Z,{children:[(0,a.jsx)(eB,{level:4,children:"Active Logging Callbacks"}),(0,a.jsx)(x.Z,{numItems:2,children:(0,a.jsx)(M.Z,{className:"max-h-[50vh]",children:(0,a.jsxs)(D.Z,{children:[(0,a.jsx)(V.Z,{children:(0,a.jsx)(q.Z,{children:(0,a.jsx)(z.Z,{children:"Callback Name"})})}),(0,a.jsx)(L.Z,{children:i.map((e,s)=>(0,a.jsxs)(q.Z,{className:"flex justify-between",children:[(0,a.jsx)(U.Z,{children:(0,a.jsx)(_.Z,{children:e.name})}),(0,a.jsx)(U.Z,{children:(0,a.jsxs)(x.Z,{numItems:2,className:"flex justify-between",children:[(0,a.jsx)(F.Z,{icon:O.Z,size:"sm",onClick:()=>{el(e),Q(!0)}}),(0,a.jsx)(p.Z,{onClick:()=>(0,u.jE)(l,e.name),className:"ml-2",variant:"secondary",children:"Test Callback"})]})})]},s))})]})})}),(0,a.jsx)(p.Z,{className:"mt-2",onClick:()=>B(!0),children:"Add Callback"})]}),(0,a.jsx)(ea.Z,{children:(0,a.jsxs)(M.Z,{children:[(0,a.jsxs)(_.Z,{className:"my-2",children:["Alerts are only supported for Slack Webhook URLs. Get your webhook urls from"," ",(0,a.jsx)("a",{href:"https://api.slack.com/messaging/webhooks",target:"_blank",style:{color:"blue"},children:"here"})]}),(0,a.jsxs)(D.Z,{children:[(0,a.jsx)(V.Z,{children:(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(z.Z,{}),(0,a.jsx)(z.Z,{}),(0,a.jsx)(z.Z,{children:"Slack Webhook URL"})]})}),(0,a.jsx)(L.Z,{children:Object.entries(eo).map((e,l)=>{let[s,t]=e;return(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(U.Z,{children:"region_outage_alerts"==s?n?(0,a.jsx)(eL.Z,{id:"switch",name:"switch",checked:ed(s),onChange:()=>ei(s)}):(0,a.jsx)(p.Z,{className:"flex items-center justify-center",children:(0,a.jsx)("a",{href:"https://forms.gle/W3U4PZpJGFHWtHyA9",target:"_blank",children:"✨ Enterprise Feature"})}):(0,a.jsx)(eL.Z,{id:"switch",name:"switch",checked:ed(s),onChange:()=>ei(s)})}),(0,a.jsx)(U.Z,{children:(0,a.jsx)(_.Z,{children:t})}),(0,a.jsx)(U.Z,{children:(0,a.jsx)(j.Z,{name:s,type:"password",defaultValue:C&&C[s]?C[s]:N})})]},l)})})]}),(0,a.jsx)(p.Z,{size:"xs",className:"mt-2",onClick:()=>{if(!l)return;let e={};Object.entries(eo).forEach(l=>{let[s,t]=l,n=document.querySelector('input[name="'.concat(s,'"]'));console.log("key",s),console.log("webhookInput",n);let a=(null==n?void 0:n.value)||"";console.log("newWebhookValue",a),e[s]=a}),console.log("updatedAlertToWebhooks",e);let s={general_settings:{alert_to_webhook_url:e,alert_types:T}};console.log("payload",s);try{(0,u.K_)(l,s)}catch(e){k.ZP.error("Failed to update alerts: "+e,20)}k.ZP.success("Alerts updated successfully")},children:"Save Changes"}),(0,a.jsx)(p.Z,{onClick:()=>(0,u.jE)(l,"slack"),className:"mx-2",children:"Test Alerts"})]})}),(0,a.jsx)(ea.Z,{children:(0,a.jsx)(ez,{accessToken:l,premiumUser:n})}),(0,a.jsx)(ea.Z,{children:(0,a.jsxs)(M.Z,{children:[(0,a.jsx)(eB,{level:4,children:"Email Settings"}),(0,a.jsxs)(_.Z,{children:[(0,a.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/email",target:"_blank",style:{color:"blue"},children:" LiteLLM Docs: email alerts"})," ",(0,a.jsx)("br",{})]}),(0,a.jsx)("div",{className:"flex w-full",children:d.filter(e=>"email"===e.name).map((e,l)=>{var s;return(0,a.jsx)(U.Z,{children:(0,a.jsx)("ul",{children:(0,a.jsx)(x.Z,{numItems:2,children:Object.entries(null!==(s=e.variables)&&void 0!==s?s:{}).map(e=>{let[l,s]=e;return(0,a.jsxs)("li",{className:"mx-2 my-2",children:[!0!=n&&("EMAIL_LOGO_URL"===l||"EMAIL_SUPPORT_CONTACT"===l)?(0,a.jsxs)("div",{children:[(0,a.jsx)("a",{href:"https://forms.gle/W3U4PZpJGFHWtHyA9",target:"_blank",children:(0,a.jsxs)(_.Z,{className:"mt-2",children:[" ","✨ ",l]})}),(0,a.jsx)(j.Z,{name:l,defaultValue:s,type:"password",disabled:!0,style:{width:"400px"}})]}):(0,a.jsxs)("div",{children:[(0,a.jsx)(_.Z,{className:"mt-2",children:l}),(0,a.jsx)(j.Z,{name:l,defaultValue:s,type:"password",style:{width:"400px"}})]}),(0,a.jsxs)("p",{style:{fontSize:"small",fontStyle:"italic"},children:["SMTP_HOST"===l&&(0,a.jsxs)("div",{style:{color:"gray"},children:["Enter the SMTP host address, e.g. `smtp.resend.com`",(0,a.jsx)("span",{style:{color:"red"},children:" Required * "})]}),"SMTP_PORT"===l&&(0,a.jsxs)("div",{style:{color:"gray"},children:["Enter the SMTP port number, e.g. `587`",(0,a.jsx)("span",{style:{color:"red"},children:" Required * "})]}),"SMTP_USERNAME"===l&&(0,a.jsxs)("div",{style:{color:"gray"},children:["Enter the SMTP username, e.g. `username`",(0,a.jsx)("span",{style:{color:"red"},children:" Required * "})]}),"SMTP_PASSWORD"===l&&(0,a.jsx)("span",{style:{color:"red"},children:" Required * "}),"SMTP_SENDER_EMAIL"===l&&(0,a.jsxs)("div",{style:{color:"gray"},children:["Enter the sender email address, e.g. `sender@berri.ai`",(0,a.jsx)("span",{style:{color:"red"},children:" Required * "})]}),"TEST_EMAIL_ADDRESS"===l&&(0,a.jsxs)("div",{style:{color:"gray"},children:["Email Address to send `Test Email Alert` to. example: `info@berri.ai`",(0,a.jsx)("span",{style:{color:"red"},children:" Required * "})]}),"EMAIL_LOGO_URL"===l&&(0,a.jsx)("div",{style:{color:"gray"},children:"(Optional) Customize the Logo that appears in the email, pass a url to your logo"}),"EMAIL_SUPPORT_CONTACT"===l&&(0,a.jsx)("div",{style:{color:"gray"},children:"(Optional) Customize the support email address that appears in the email. Default is support@berri.ai"})]})]},l)})})})},l)})}),(0,a.jsx)(p.Z,{className:"mt-2",onClick:()=>ec(),children:"Save Changes"}),(0,a.jsx)(p.Z,{onClick:()=>(0,u.jE)(l,"email"),className:"mx-2",children:"Test Email Alerts"})]})})]})]})}),(0,a.jsxs)(w.Z,{title:"Add Logging Callback",visible:R,width:800,onCancel:()=>B(!1),footer:null,children:[(0,a.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/logging",className:"mb-8 mt-4",target:"_blank",style:{color:"blue"},children:" LiteLLM Docs: Logging"}),(0,a.jsx)(S.Z,{form:g,onFinish:eu,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(eq.Z,{label:"Callback",name:"callback",rules:[{required:!0,message:"Please select a callback"}],children:(0,a.jsx)(v.default,{onChange:e=>{let l=W[e];l&&(console.log(l.ui_callback_name),eh(l))},children:W&&Object.values(W).map(e=>(0,a.jsx)(K.Z,{value:e.litellm_callback_name,children:e.ui_callback_name},e.litellm_callback_name))})}),J&&J.map(e=>(0,a.jsx)(eq.Z,{label:e,name:e,rules:[{required:!0,message:"Please enter the value for "+e}],children:(0,a.jsx)(j.Z,{type:"password"})},e)),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(I.ZP,{htmlType:"submit",children:"Save"})})]})})]}),(0,a.jsx)(w.Z,{visible:$,width:800,title:"Edit ".concat(null==ee?void 0:ee.name," Settings"),onCancel:()=>Q(!1),footer:null,children:(0,a.jsxs)(S.Z,{form:g,onFinish:em,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsx)(a.Fragment,{children:ee&&ee.variables&&Object.entries(ee.variables).map(e=>{let[l,s]=e;return(0,a.jsx)(eq.Z,{label:l,name:l,children:(0,a.jsx)(j.Z,{type:"password",defaultValue:s})},l)})}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(I.ZP,{htmlType:"submit",children:"Save"})})]})})]})):null};let{Option:eH}=v.default;var eG=e=>{let{models:l,accessToken:s,routerSettings:t,setRouterSettings:n}=e,[i]=S.Z.useForm(),[o,d]=(0,r.useState)(!1),[c,m]=(0,r.useState)("");return(0,a.jsxs)("div",{children:[(0,a.jsx)(p.Z,{className:"mx-auto",onClick:()=>d(!0),children:"+ Add Fallbacks"}),(0,a.jsx)(w.Z,{title:"Add Fallbacks",visible:o,width:800,footer:null,onOk:()=>{d(!1),i.resetFields()},onCancel:()=>{d(!1),i.resetFields()},children:(0,a.jsxs)(S.Z,{form:i,onFinish:e=>{console.log(e);let{model_name:l,models:a}=e,r=[...t.fallbacks||[],{[l]:a}],o={...t,fallbacks:r};console.log(o);try{(0,u.K_)(s,{router_settings:o}),n(o)}catch(e){k.ZP.error("Failed to update router settings: "+e,20)}k.ZP.success("router settings updated successfully"),d(!1),i.resetFields()},labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(S.Z.Item,{label:"Public Model Name",name:"model_name",rules:[{required:!0,message:"Set the model to fallback for"}],help:"required",children:(0,a.jsx)(B.Z,{defaultValue:c,children:l&&l.map((e,l)=>(0,a.jsx)(K.Z,{value:e,onClick:()=>m(e),children:e},l))})}),(0,a.jsx)(S.Z.Item,{label:"Fallback Models",name:"models",rules:[{required:!0,message:"Please select a model"}],help:"required",children:(0,a.jsx)(ei.Z,{value:l,children:l&&l.filter(e=>e!=c).map(e=>(0,a.jsx)(eo.Z,{value:e,children:e},e))})})]}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(I.ZP,{htmlType:"submit",children:"Add Fallbacks"})})]})})]})},eY=s(12968);async function eJ(e,l){console.log("isLocal:",!1);let s=window.location.origin,t=new eY.ZP.OpenAI({apiKey:l,baseURL:s,dangerouslyAllowBrowser:!0});try{let l=await t.chat.completions.create({model:e,messages:[{role:"user",content:"Hi, this is a test message"}],mock_testing_fallbacks:!0});k.ZP.success((0,a.jsxs)("span",{children:["Test model=",(0,a.jsx)("strong",{children:e}),", received model=",(0,a.jsx)("strong",{children:l.model}),". See"," ",(0,a.jsx)("a",{href:"#",onClick:()=>window.open("https://docs.litellm.ai/docs/proxy/reliability","_blank"),style:{textDecoration:"underline",color:"blue"},children:"curl"})]}))}catch(e){k.ZP.error("Error occurred while generating model response. Please try again. Error: ".concat(e),20)}}let eX={ttl:3600,lowest_latency_buffer:0},e$=e=>{let{selectedStrategy:l,strategyArgs:s,paramExplanation:t}=e;return(0,a.jsxs)(g.Z,{children:[(0,a.jsx)(f.Z,{className:"text-sm font-medium text-tremor-content-strong dark:text-dark-tremor-content-strong",children:"Routing Strategy Specific Args"}),(0,a.jsx)(Z.Z,{children:"latency-based-routing"==l?(0,a.jsx)(M.Z,{children:(0,a.jsxs)(D.Z,{children:[(0,a.jsx)(V.Z,{children:(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(z.Z,{children:"Setting"}),(0,a.jsx)(z.Z,{children:"Value"})]})}),(0,a.jsx)(L.Z,{children:Object.entries(s).map(e=>{let[l,s]=e;return(0,a.jsxs)(q.Z,{children:[(0,a.jsxs)(U.Z,{children:[(0,a.jsx)(_.Z,{children:l}),(0,a.jsx)("p",{style:{fontSize:"0.65rem",color:"#808080",fontStyle:"italic"},className:"mt-1",children:t[l]})]}),(0,a.jsx)(U.Z,{children:(0,a.jsx)(j.Z,{name:l,defaultValue:"object"==typeof s?JSON.stringify(s,null,2):s.toString()})})]},l)})})]})}):(0,a.jsx)(_.Z,{children:"No specific settings"})})]})};var eQ=e=>{let{accessToken:l,userRole:s,userID:t,modelData:n}=e,[i,o]=(0,r.useState)({}),[d,c]=(0,r.useState)({}),[m,g]=(0,r.useState)([]),[Z,f]=(0,r.useState)(!1),[b]=S.Z.useForm(),[v,w]=(0,r.useState)(null),[N,I]=(0,r.useState)(null),[C,P]=(0,r.useState)(null),T={routing_strategy_args:"(dict) Arguments to pass to the routing strategy",routing_strategy:"(string) Routing strategy to use",allowed_fails:"(int) Number of times a deployment can fail before being added to cooldown",cooldown_time:"(int) time in seconds to cooldown a deployment after failure",num_retries:"(int) Number of retries for failed requests. Defaults to 0.",timeout:"(float) Timeout for requests. Defaults to None.",retry_after:"(int) Minimum time to wait before retrying a failed request",ttl:"(int) Sliding window to look back over when calculating the average latency of a deployment. Default - 1 hour (in seconds).",lowest_latency_buffer:"(float) Shuffle between deployments within this % of the lowest latency. Default - 0 (i.e. always pick lowest latency)."};(0,r.useEffect)(()=>{l&&s&&t&&((0,u.BL)(l,t,s).then(e=>{console.log("callbacks",e),o(e.router_settings)}),(0,u.YU)(l).then(e=>{g(e)}))},[l,s,t]);let O=async e=>{if(l){console.log("received key: ".concat(e)),console.log("routerSettings['fallbacks']: ".concat(i.fallbacks)),i.fallbacks.map(l=>(e in l&&delete l[e],l));try{await (0,u.K_)(l,{router_settings:i}),o({...i}),I(i.routing_strategy),k.ZP.success("Router settings updated successfully")}catch(e){k.ZP.error("Failed to update router settings: "+e,20)}}},W=(e,l)=>{g(m.map(s=>s.field_name===e?{...s,field_value:l}:s))},H=(e,s)=>{if(!l)return;let t=m[s].field_value;if(null!=t&&void 0!=t)try{(0,u.jA)(l,e,t);let s=m.map(l=>l.field_name===e?{...l,stored_in_db:!0}:l);g(s)}catch(e){}},G=(e,s)=>{if(l)try{(0,u.ao)(l,e);let s=m.map(l=>l.field_name===e?{...l,stored_in_db:null,field_value:null}:l);g(s)}catch(e){}},Y=e=>{if(!l)return;console.log("router_settings",e);let s=Object.fromEntries(Object.entries(e).map(e=>{let[l,s]=e;if("routing_strategy_args"!==l&&"routing_strategy"!==l){var t;return[l,(null===(t=document.querySelector('input[name="'.concat(l,'"]')))||void 0===t?void 0:t.value)||s]}if("routing_strategy"==l)return[l,N];if("routing_strategy_args"==l&&"latency-based-routing"==N){let e={},l=document.querySelector('input[name="lowest_latency_buffer"]'),s=document.querySelector('input[name="ttl"]');return(null==l?void 0:l.value)&&(e.lowest_latency_buffer=Number(l.value)),(null==s?void 0:s.value)&&(e.ttl=Number(s.value)),console.log("setRoutingStrategyArgs: ".concat(e)),["routing_strategy_args",e]}return null}).filter(e=>null!=e));console.log("updatedVariables",s);try{(0,u.K_)(l,{router_settings:s})}catch(e){k.ZP.error("Failed to update router settings: "+e,20)}k.ZP.success("router settings updated successfully")};return l?(0,a.jsx)("div",{className:"w-full mx-4",children:(0,a.jsxs)(et.Z,{className:"gap-2 p-8 h-[75vh] w-full mt-2",children:[(0,a.jsxs)(en.Z,{variant:"line",defaultValue:"1",children:[(0,a.jsx)(es.Z,{value:"1",children:"Loadbalancing"}),(0,a.jsx)(es.Z,{value:"2",children:"Fallbacks"}),(0,a.jsx)(es.Z,{value:"3",children:"General"})]}),(0,a.jsxs)(er.Z,{children:[(0,a.jsx)(ea.Z,{children:(0,a.jsxs)(x.Z,{numItems:1,className:"gap-2 p-8 w-full mt-2",children:[(0,a.jsx)(y.Z,{children:"Router Settings"}),(0,a.jsxs)(M.Z,{children:[(0,a.jsxs)(D.Z,{children:[(0,a.jsx)(V.Z,{children:(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(z.Z,{children:"Setting"}),(0,a.jsx)(z.Z,{children:"Value"})]})}),(0,a.jsx)(L.Z,{children:Object.entries(i).filter(e=>{let[l,s]=e;return"fallbacks"!=l&&"context_window_fallbacks"!=l&&"routing_strategy_args"!=l}).map(e=>{let[l,s]=e;return(0,a.jsxs)(q.Z,{children:[(0,a.jsxs)(U.Z,{children:[(0,a.jsx)(_.Z,{children:l}),(0,a.jsx)("p",{style:{fontSize:"0.65rem",color:"#808080",fontStyle:"italic"},className:"mt-1",children:T[l]})]}),(0,a.jsx)(U.Z,{children:"routing_strategy"==l?(0,a.jsxs)(B.Z,{defaultValue:s,className:"w-full max-w-md",onValueChange:I,children:[(0,a.jsx)(K.Z,{value:"usage-based-routing",children:"usage-based-routing"}),(0,a.jsx)(K.Z,{value:"latency-based-routing",children:"latency-based-routing"}),(0,a.jsx)(K.Z,{value:"simple-shuffle",children:"simple-shuffle"})]}):(0,a.jsx)(j.Z,{name:l,defaultValue:"object"==typeof s?JSON.stringify(s,null,2):s.toString()})})]},l)})})]}),(0,a.jsx)(e$,{selectedStrategy:N,strategyArgs:i&&i.routing_strategy_args&&Object.keys(i.routing_strategy_args).length>0?i.routing_strategy_args:eX,paramExplanation:T})]}),(0,a.jsx)(h.Z,{children:(0,a.jsx)(p.Z,{className:"mt-2",onClick:()=>Y(i),children:"Save Changes"})})]})}),(0,a.jsxs)(ea.Z,{children:[(0,a.jsxs)(D.Z,{children:[(0,a.jsx)(V.Z,{children:(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(z.Z,{children:"Model Name"}),(0,a.jsx)(z.Z,{children:"Fallbacks"})]})}),(0,a.jsx)(L.Z,{children:i.fallbacks&&i.fallbacks.map((e,s)=>Object.entries(e).map(e=>{let[t,n]=e;return(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(U.Z,{children:t}),(0,a.jsx)(U.Z,{children:Array.isArray(n)?n.join(", "):n}),(0,a.jsx)(U.Z,{children:(0,a.jsx)(p.Z,{onClick:()=>eJ(t,l),children:"Test Fallback"})}),(0,a.jsx)(U.Z,{children:(0,a.jsx)(F.Z,{icon:E.Z,size:"sm",onClick:()=>O(t)})})]},s.toString()+t)}))})]}),(0,a.jsx)(eG,{models:(null==n?void 0:n.data)?n.data.map(e=>e.model_name):[],accessToken:l,routerSettings:i,setRouterSettings:o})]}),(0,a.jsx)(ea.Z,{children:(0,a.jsx)(M.Z,{children:(0,a.jsxs)(D.Z,{children:[(0,a.jsx)(V.Z,{children:(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(z.Z,{children:"Setting"}),(0,a.jsx)(z.Z,{children:"Value"}),(0,a.jsx)(z.Z,{children:"Status"}),(0,a.jsx)(z.Z,{children:"Action"})]})}),(0,a.jsx)(L.Z,{children:m.map((e,l)=>(0,a.jsxs)(q.Z,{children:[(0,a.jsxs)(U.Z,{children:[(0,a.jsx)(_.Z,{children:e.field_name}),(0,a.jsx)("p",{style:{fontSize:"0.65rem",color:"#808080",fontStyle:"italic"},className:"mt-1",children:e.field_description})]}),(0,a.jsx)(U.Z,{children:"Integer"==e.field_type?(0,a.jsx)(A.Z,{step:1,value:e.field_value,onChange:l=>W(e.field_name,l)}):null}),(0,a.jsx)(U.Z,{children:!0==e.stored_in_db?(0,a.jsx)(R.Z,{icon:eU.Z,className:"text-white",children:"In DB"}):!1==e.stored_in_db?(0,a.jsx)(R.Z,{className:"text-gray bg-white outline",children:"In Config"}):(0,a.jsx)(R.Z,{className:"text-gray bg-white outline",children:"Not Set"})}),(0,a.jsxs)(U.Z,{children:[(0,a.jsx)(p.Z,{onClick:()=>H(e.field_name,l),children:"Update"}),(0,a.jsx)(F.Z,{icon:E.Z,color:"red",onClick:()=>G(e.field_name,l),children:"Reset"})]})]},l))})]})})})]})]})}):null},e0=e=>{let{isModalVisible:l,accessToken:s,setIsModalVisible:t,setBudgetList:n}=e,[r]=S.Z.useForm(),i=async e=>{if(null!=s&&void 0!=s)try{k.ZP.info("Making API Call");let l=await (0,u.Zr)(s,e);console.log("key create Response:",l),n(e=>e?[...e,l]:[l]),k.ZP.success("API Key Created"),r.resetFields()}catch(e){console.error("Error creating the key:",e),k.ZP.error("Error creating the key: ".concat(e),20)}};return(0,a.jsx)(w.Z,{title:"Create Budget",visible:l,width:800,footer:null,onOk:()=>{t(!1),r.resetFields()},onCancel:()=>{t(!1),r.resetFields()},children:(0,a.jsxs)(S.Z,{form:r,onFinish:i,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(S.Z.Item,{label:"Budget ID",name:"budget_id",rules:[{required:!0,message:"Please input a human-friendly name for the budget"}],help:"A human-friendly name for the budget",children:(0,a.jsx)(j.Z,{placeholder:""})}),(0,a.jsx)(S.Z.Item,{label:"Max Tokens per minute",name:"tpm_limit",help:"Default is model limit.",children:(0,a.jsx)(A.Z,{step:1,precision:2,width:200})}),(0,a.jsx)(S.Z.Item,{label:"Max Requests per minute",name:"rpm_limit",help:"Default is model limit.",children:(0,a.jsx)(A.Z,{step:1,precision:2,width:200})}),(0,a.jsxs)(g.Z,{className:"mt-20 mb-8",children:[(0,a.jsx)(f.Z,{children:(0,a.jsx)("b",{children:"Optional Settings"})}),(0,a.jsxs)(Z.Z,{children:[(0,a.jsx)(S.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,a.jsx)(A.Z,{step:.01,precision:2,width:200})}),(0,a.jsx)(S.Z.Item,{className:"mt-8",label:"Reset Budget",name:"budget_duration",children:(0,a.jsxs)(v.default,{defaultValue:null,placeholder:"n/a",children:[(0,a.jsx)(v.default.Option,{value:"24h",children:"daily"}),(0,a.jsx)(v.default.Option,{value:"7d",children:"weekly"}),(0,a.jsx)(v.default.Option,{value:"30d",children:"monthly"})]})})]})]})]}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(I.ZP,{htmlType:"submit",children:"Create Budget"})})]})})},e1=e=>{let{isModalVisible:l,accessToken:s,setIsModalVisible:t,setBudgetList:n,existingBudget:r}=e,[i]=S.Z.useForm(),o=async e=>{if(null!=s&&void 0!=s)try{k.ZP.info("Making API Call");let l=await (0,u.Zr)(s,e);console.log("key create Response:",l),n(e=>e?[...e,l]:[l]),k.ZP.success("API Key Created"),i.resetFields()}catch(e){console.error("Error creating the key:",e),k.ZP.error("Error creating the key: ".concat(e),20)}};return(0,a.jsx)(w.Z,{title:"Edit Budget",visible:l,width:800,footer:null,onOk:()=>{t(!1),i.resetFields()},onCancel:()=>{t(!1),i.resetFields()},children:(0,a.jsxs)(S.Z,{form:i,onFinish:o,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",initialValues:r,children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(S.Z.Item,{label:"Budget ID",name:"budget_id",rules:[{required:!0,message:"Please input a human-friendly name for the budget"}],help:"A human-friendly name for the budget",children:(0,a.jsx)(j.Z,{placeholder:""})}),(0,a.jsx)(S.Z.Item,{label:"Max Tokens per minute",name:"tpm_limit",help:"Default is model limit.",children:(0,a.jsx)(A.Z,{step:1,precision:2,width:200})}),(0,a.jsx)(S.Z.Item,{label:"Max Requests per minute",name:"rpm_limit",help:"Default is model limit.",children:(0,a.jsx)(A.Z,{step:1,precision:2,width:200})}),(0,a.jsxs)(g.Z,{className:"mt-20 mb-8",children:[(0,a.jsx)(f.Z,{children:(0,a.jsx)("b",{children:"Optional Settings"})}),(0,a.jsxs)(Z.Z,{children:[(0,a.jsx)(S.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,a.jsx)(A.Z,{step:.01,precision:2,width:200})}),(0,a.jsx)(S.Z.Item,{className:"mt-8",label:"Reset Budget",name:"budget_duration",children:(0,a.jsxs)(v.default,{defaultValue:null,placeholder:"n/a",children:[(0,a.jsx)(v.default.Option,{value:"24h",children:"daily"}),(0,a.jsx)(v.default.Option,{value:"7d",children:"weekly"}),(0,a.jsx)(v.default.Option,{value:"30d",children:"monthly"})]})})]})]})]}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(I.ZP,{htmlType:"submit",children:"Edit Budget"})})]})})},e2=e=>{let{accessToken:l}=e,[s,t]=(0,r.useState)(!1),[n,i]=(0,r.useState)(!1),[o,d]=(0,r.useState)(null),[c,m]=(0,r.useState)([]);(0,r.useEffect)(()=>{l&&(0,u.O3)(l).then(e=>{m(e)})},[l]);let h=async(e,s)=>{null!=l&&(d(c[s]),i(!0))},x=async(e,s)=>{if(null==l)return;k.ZP.info("Request made"),await (0,u.NV)(l,e);let t=[...c];t.splice(s,1),m(t),k.ZP.success("Budget Deleted.")};return(0,a.jsxs)("div",{className:"w-full mx-auto flex-auto overflow-y-auto m-8 p-2",children:[(0,a.jsx)(p.Z,{size:"sm",variant:"primary",className:"mb-2",onClick:()=>t(!0),children:"+ Create Budget"}),(0,a.jsx)(e0,{accessToken:l,isModalVisible:s,setIsModalVisible:t,setBudgetList:m}),o&&(0,a.jsx)(e1,{accessToken:l,isModalVisible:n,setIsModalVisible:i,setBudgetList:m,existingBudget:o}),(0,a.jsxs)(M.Z,{children:[(0,a.jsx)(_.Z,{children:"Create a budget to assign to customers."}),(0,a.jsxs)(D.Z,{children:[(0,a.jsx)(V.Z,{children:(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(z.Z,{children:"Budget ID"}),(0,a.jsx)(z.Z,{children:"Max Budget"}),(0,a.jsx)(z.Z,{children:"TPM"}),(0,a.jsx)(z.Z,{children:"RPM"})]})}),(0,a.jsx)(L.Z,{children:c.map((e,l)=>(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(U.Z,{children:e.budget_id}),(0,a.jsx)(U.Z,{children:e.max_budget?e.max_budget:"n/a"}),(0,a.jsx)(U.Z,{children:e.tpm_limit?e.tpm_limit:"n/a"}),(0,a.jsx)(U.Z,{children:e.rpm_limit?e.rpm_limit:"n/a"}),(0,a.jsx)(F.Z,{icon:O.Z,size:"sm",onClick:()=>h(e.budget_id,l)}),(0,a.jsx)(F.Z,{icon:E.Z,size:"sm",onClick:()=>x(e.budget_id,l)})]},l))})]})]}),(0,a.jsxs)("div",{className:"mt-5",children:[(0,a.jsx)(_.Z,{className:"text-base",children:"How to use budget id"}),(0,a.jsxs)(et.Z,{children:[(0,a.jsxs)(en.Z,{children:[(0,a.jsx)(es.Z,{children:"Assign Budget to Customer"}),(0,a.jsx)(es.Z,{children:"Test it (Curl)"}),(0,a.jsx)(es.Z,{children:"Test it (OpenAI SDK)"})]}),(0,a.jsxs)(er.Z,{children:[(0,a.jsx)(ea.Z,{children:(0,a.jsx)(ek.Z,{language:"bash",children:"\ncurl -X POST --location '/end_user/new' \n-H 'Authorization: Bearer ' \n-H 'Content-Type: application/json' \n-d '{\"user_id\": \"my-customer-id', \"budget_id\": \"\"}' # \uD83D\uDC48 KEY CHANGE\n\n "})}),(0,a.jsx)(ea.Z,{children:(0,a.jsx)(ek.Z,{language:"bash",children:'\ncurl -X POST --location \'/chat/completions\' \n-H \'Authorization: Bearer \' \n-H \'Content-Type: application/json\' \n-d \'{\n "model": "gpt-3.5-turbo\', \n "messages":[{"role": "user", "content": "Hey, how\'s it going?"}],\n "user": "my-customer-id"\n}\' # \uD83D\uDC48 KEY CHANGE\n\n '})}),(0,a.jsx)(ea.Z,{children:(0,a.jsx)(ek.Z,{language:"python",children:'from openai import OpenAI\nclient = OpenAI(\n base_url="{let{proxySettings:l}=e,s="http://localhost:4000";return l&&l.PROXY_BASE_URL&&void 0!==l.PROXY_BASE_URL&&(s=l.PROXY_BASE_URL),(0,a.jsx)(a.Fragment,{children:(0,a.jsx)(x.Z,{className:"gap-2 p-8 h-[80vh] w-full mt-2",children:(0,a.jsxs)("div",{className:"mb-5",children:[(0,a.jsx)("p",{className:"text-2xl text-tremor-content-strong dark:text-dark-tremor-content-strong font-semibold",children:"OpenAI Compatible Proxy: API Reference"}),(0,a.jsx)(_.Z,{className:"mt-2 mb-2",children:"LiteLLM is OpenAI Compatible. This means your API Key works with the OpenAI SDK. Just replace the base_url to point to your litellm proxy. Example Below "}),(0,a.jsxs)(et.Z,{children:[(0,a.jsxs)(en.Z,{children:[(0,a.jsx)(es.Z,{children:"OpenAI Python SDK"}),(0,a.jsx)(es.Z,{children:"LlamaIndex"}),(0,a.jsx)(es.Z,{children:"Langchain Py"})]}),(0,a.jsxs)(er.Z,{children:[(0,a.jsx)(ea.Z,{children:(0,a.jsx)(ek.Z,{language:"python",children:'\nimport openai\nclient = openai.OpenAI(\n api_key="your_api_key",\n base_url="'.concat(s,'" # LiteLLM Proxy is OpenAI compatible, Read More: https://docs.litellm.ai/docs/proxy/user_keys\n)\n\nresponse = client.chat.completions.create(\n model="gpt-3.5-turbo", # model to send to the proxy\n messages = [\n {\n "role": "user",\n "content": "this is a test request, write a short poem"\n }\n ]\n)\n\nprint(response)\n ')})}),(0,a.jsx)(ea.Z,{children:(0,a.jsx)(ek.Z,{language:"python",children:'\nimport os, dotenv\n\nfrom llama_index.llms import AzureOpenAI\nfrom llama_index.embeddings import AzureOpenAIEmbedding\nfrom llama_index import VectorStoreIndex, SimpleDirectoryReader, ServiceContext\n\nllm = AzureOpenAI(\n engine="azure-gpt-3.5", # model_name on litellm proxy\n temperature=0.0,\n azure_endpoint="'.concat(s,'", # litellm proxy endpoint\n api_key="sk-1234", # litellm proxy API Key\n api_version="2023-07-01-preview",\n)\n\nembed_model = AzureOpenAIEmbedding(\n deployment_name="azure-embedding-model",\n azure_endpoint="').concat(s,'",\n api_key="sk-1234",\n api_version="2023-07-01-preview",\n)\n\n\ndocuments = SimpleDirectoryReader("llama_index_data").load_data()\nservice_context = ServiceContext.from_defaults(llm=llm, embed_model=embed_model)\nindex = VectorStoreIndex.from_documents(documents, service_context=service_context)\n\nquery_engine = index.as_query_engine()\nresponse = query_engine.query("What did the author do growing up?")\nprint(response)\n\n ')})}),(0,a.jsx)(ea.Z,{children:(0,a.jsx)(ek.Z,{language:"python",children:'\nfrom langchain.chat_models import ChatOpenAI\nfrom langchain.prompts.chat import (\n ChatPromptTemplate,\n HumanMessagePromptTemplate,\n SystemMessagePromptTemplate,\n)\nfrom langchain.schema import HumanMessage, SystemMessage\n\nchat = ChatOpenAI(\n openai_api_base="'.concat(s,'",\n model = "gpt-3.5-turbo",\n temperature=0.1\n)\n\nmessages = [\n SystemMessage(\n content="You are a helpful assistant that im using to make a test request to."\n ),\n HumanMessage(\n content="test from litellm. tell me why it\'s amazing in 1 sentence"\n ),\n]\nresponse = chat(messages)\n\nprint(response)\n\n ')})})]})]})]})})})};async function e8(e,l,s,t){console.log("isLocal:",!1);let n=window.location.origin,a=new eY.ZP.OpenAI({apiKey:t,baseURL:n,dangerouslyAllowBrowser:!0});try{for await(let t of(await a.chat.completions.create({model:s,stream:!0,messages:[{role:"user",content:e}]})))console.log(t),t.choices[0].delta.content&&l(t.choices[0].delta.content)}catch(e){k.ZP.error("Error occurred while generating model response. Please try again. Error: ".concat(e),20)}}var e3=e=>{let{accessToken:l,token:s,userRole:t,userID:n}=e,[i,o]=(0,r.useState)(""),[d,c]=(0,r.useState)(""),[m,g]=(0,r.useState)([]),[Z,f]=(0,r.useState)(void 0),[y,b]=(0,r.useState)([]);(0,r.useEffect)(()=>{l&&s&&t&&n&&(async()=>{try{let e=await (0,u.So)(l,n,t);if(console.log("model_info:",e),(null==e?void 0:e.data.length)>0){let l=e.data.map(e=>({value:e.id,label:e.id}));if(console.log(l),l.length>0){let e=Array.from(new Set(l));console.log("Unique models:",e),e.sort((e,l)=>e.label.localeCompare(l.label)),console.log("Model info:",y),b(e)}f(e.data[0].id)}}catch(e){console.error("Error fetching model info:",e)}})()},[l,n,t]);let S=(e,l)=>{g(s=>{let t=s[s.length-1];return t&&t.role===e?[...s.slice(0,s.length-1),{role:e,content:t.content+l}]:[...s,{role:e,content:l}]})},k=async()=>{if(""!==d.trim()&&i&&s&&t&&n){g(e=>[...e,{role:"user",content:d}]);try{Z&&await e8(d,e=>S("assistant",e),Z,i)}catch(e){console.error("Error fetching model response",e),S("assistant","Error fetching model response")}c("")}};if(t&&"Admin Viewer"==t){let{Title:e,Paragraph:l}=$.default;return(0,a.jsxs)("div",{children:[(0,a.jsx)(e,{level:1,children:"Access Denied"}),(0,a.jsx)(l,{children:"Ask your proxy admin for access to test models"})]})}return(0,a.jsx)("div",{style:{width:"100%",position:"relative"},children:(0,a.jsx)(x.Z,{className:"gap-2 p-8 h-[80vh] w-full mt-2",children:(0,a.jsx)(M.Z,{children:(0,a.jsxs)(et.Z,{children:[(0,a.jsx)(en.Z,{children:(0,a.jsx)(es.Z,{children:"Chat"})}),(0,a.jsx)(er.Z,{children:(0,a.jsxs)(ea.Z,{children:[(0,a.jsx)("div",{className:"sm:max-w-2xl",children:(0,a.jsxs)(x.Z,{numItems:2,children:[(0,a.jsxs)(h.Z,{children:[(0,a.jsx)(_.Z,{children:"API Key"}),(0,a.jsx)(j.Z,{placeholder:"Type API Key here",type:"password",onValueChange:o,value:i})]}),(0,a.jsxs)(h.Z,{className:"mx-2",children:[(0,a.jsx)(_.Z,{children:"Select Model:"}),(0,a.jsx)(v.default,{placeholder:"Select a Model",onChange:e=>{console.log("selected ".concat(e)),f(e)},options:y,style:{width:"200px"}})]})]})}),(0,a.jsxs)(D.Z,{className:"mt-5",style:{display:"block",maxHeight:"60vh",overflowY:"auto"},children:[(0,a.jsx)(V.Z,{children:(0,a.jsx)(q.Z,{children:(0,a.jsx)(U.Z,{})})}),(0,a.jsx)(L.Z,{children:m.map((e,l)=>(0,a.jsx)(q.Z,{children:(0,a.jsx)(U.Z,{children:"".concat(e.role,": ").concat(e.content)})},l))})]}),(0,a.jsx)("div",{className:"mt-3",style:{position:"absolute",bottom:5,width:"95%"},children:(0,a.jsxs)("div",{className:"flex",children:[(0,a.jsx)(j.Z,{type:"text",value:d,onChange:e=>c(e.target.value),onKeyDown:e=>{"Enter"===e.key&&k()},placeholder:"Type your message..."}),(0,a.jsx)(p.Z,{onClick:k,className:"ml-2",children:"Send"})]})})]})})]})})})})},e6=s(33509),e9=s(95781);let{Sider:e7}=e6.default;var le=e=>{let{setPage:l,userRole:s,defaultSelectedKey:t}=e;return"Admin Viewer"==s?(0,a.jsx)(e6.default,{style:{minHeight:"100vh",maxWidth:"120px"},children:(0,a.jsx)(e7,{width:120,children:(0,a.jsx)(e9.Z,{mode:"inline",defaultSelectedKeys:t||["4"],style:{height:"100%",borderRight:0},children:(0,a.jsx)(e9.Z.Item,{onClick:()=>l("usage"),children:"Usage"},"1")})})}):(0,a.jsx)(e6.default,{style:{minHeight:"100vh",maxWidth:"145px"},children:(0,a.jsx)(e7,{width:145,children:(0,a.jsxs)(e9.Z,{mode:"inline",defaultSelectedKeys:t||["1"],style:{height:"100%",borderRight:0},children:[(0,a.jsx)(e9.Z.Item,{onClick:()=>l("api-keys"),children:(0,a.jsx)(_.Z,{children:"API Keys"})},"1"),(0,a.jsx)(e9.Z.Item,{onClick:()=>l("llm-playground"),children:(0,a.jsx)(_.Z,{children:"Test Key"})},"3"),"Admin"==s?(0,a.jsx)(e9.Z.Item,{onClick:()=>l("models"),children:(0,a.jsx)(_.Z,{children:"Models"})},"2"):null,"Admin"==s?(0,a.jsx)(e9.Z.Item,{onClick:()=>l("usage"),children:(0,a.jsx)(_.Z,{children:"Usage"})},"4"):null,"Admin"==s?(0,a.jsx)(e9.Z.Item,{onClick:()=>l("teams"),children:(0,a.jsx)(_.Z,{children:"Teams"})},"6"):null,"Admin"==s?(0,a.jsx)(e9.Z.Item,{onClick:()=>l("users"),children:(0,a.jsx)(_.Z,{children:"Internal Users"})},"5"):null,"Admin"==s?(0,a.jsx)(e9.Z.Item,{onClick:()=>l("settings"),children:(0,a.jsx)(_.Z,{children:"Logging & Alerts"})},"8"):null,"Admin"==s?(0,a.jsx)(e9.Z.Item,{onClick:()=>l("caching"),children:(0,a.jsx)(_.Z,{children:"Caching"})},"9"):null,"Admin"==s?(0,a.jsx)(e9.Z.Item,{onClick:()=>l("budgets"),children:(0,a.jsx)(_.Z,{children:"Budgets"})},"10"):null,"Admin"==s?(0,a.jsx)(e9.Z.Item,{onClick:()=>l("general-settings"),children:(0,a.jsx)(_.Z,{children:"Router Settings"})},"11"):null,"Admin"==s?(0,a.jsx)(e9.Z.Item,{onClick:()=>l("admin-panel"),children:(0,a.jsx)(_.Z,{children:"Admin"})},"12"):null,(0,a.jsx)(e9.Z.Item,{onClick:()=>l("api_ref"),children:(0,a.jsx)(_.Z,{children:"API Reference"})},"13"),(0,a.jsx)(e9.Z.Item,{onClick:()=>l("model-hub"),children:(0,a.jsx)(_.Z,{children:"Model Hub"})},"15")]})})})},ll=s(67989),ls=s(52703),lt=e=>{let{accessToken:l,token:s,userRole:t,userID:n,keys:i,premiumUser:o}=e,d=new Date,[c,m]=(0,r.useState)([]),[j,g]=(0,r.useState)([]),[Z,f]=(0,r.useState)([]),[b,v]=(0,r.useState)([]),[S,k]=(0,r.useState)([]),[w,N]=(0,r.useState)([]),[A,I]=(0,r.useState)([]),[C,P]=(0,r.useState)([]),[T,O]=(0,r.useState)([]),[E,R]=(0,r.useState)([]),[F,W]=(0,r.useState)({}),[H,Y]=(0,r.useState)([]),[J,X]=(0,r.useState)(""),[$,Q]=(0,r.useState)(["all-tags"]),[em,eu]=(0,r.useState)({from:new Date(Date.now()-6048e5),to:new Date}),eh=new Date(d.getFullYear(),d.getMonth(),1),ex=new Date(d.getFullYear(),d.getMonth()+1,0),ep=e_(eh),ej=e_(ex);function eg(e){return new Intl.NumberFormat("en-US",{maximumFractionDigits:0,notation:"compact",compactDisplay:"short"}).format(e)}console.log("keys in usage",i),console.log("premium user in usage",o),(0,r.useEffect)(()=>{ef(em.from,em.to)},[em,$]);let eZ=async(e,s,t)=>{if(!e||!s||!l)return;s.setHours(23,59,59,999),e.setHours(0,0,0,0),console.log("uiSelectedKey",t);let n=await (0,u.b1)(l,t,e.toISOString(),s.toISOString());console.log("End user data updated successfully",n),v(n)},ef=async(e,s)=>{e&&s&&l&&(s.setHours(23,59,59,999),e.setHours(0,0,0,0),N((await (0,u.J$)(l,e.toISOString(),s.toISOString(),0===$.length?void 0:$)).spend_per_tag),console.log("Tag spend data updated successfully"))};function e_(e){let l=e.getFullYear(),s=e.getMonth()+1,t=e.getDate();return"".concat(l,"-").concat(s<10?"0"+s:s,"-").concat(t<10?"0"+t:t)}return console.log("Start date is ".concat(ep)),console.log("End date is ".concat(ej)),(0,r.useEffect)(()=>{l&&s&&t&&n&&(async()=>{try{if(console.log("user role: ".concat(t)),"Admin"==t||"Admin Viewer"==t){var e,a;let t=await (0,u.FC)(l);m(t);let n=await (0,u.OU)(l,s,ep,ej);console.log("provider_spend",n),R(n);let r=(await (0,u.tN)(l)).map(e=>({key:(e.key_alias||e.key_name||e.api_key).substring(0,10),spend:e.total_spend}));g(r);let i=(await (0,u.Au)(l)).map(e=>({key:e.model,spend:e.total_spend}));f(i);let o=await (0,u.mR)(l);console.log("teamSpend",o),k(o.daily_spend),P(o.teams);let d=o.total_spend_per_team;d=d.map(e=>(e.name=e.team_id||"",e.value=e.total_spend||0,e.value=e.value.toFixed(2),e)),O(d);let c=await (0,u.X)(l);I(c.tag_names);let h=await (0,u.J$)(l,null===(e=em.from)||void 0===e?void 0:e.toISOString(),null===(a=em.to)||void 0===a?void 0:a.toISOString(),void 0);N(h.spend_per_tag);let x=await (0,u.b1)(l,null,void 0,void 0);v(x),console.log("spend/user result",x);let p=await (0,u.wd)(l,ep,ej);W(p);let j=await (0,u.xA)(l,ep,ej);console.log("global activity per model",j),Y(j)}else"App Owner"==t&&await (0,u.HK)(l,s,t,n,ep,ej).then(async e=>{if(console.log("result from spend logs call",e),"daily_spend"in e){let l=e.daily_spend;console.log("daily spend",l),m(l);let s=e.top_api_keys;g(s)}else{let s=(await (0,u.e2)(l,function(e){let l=[];e.forEach(e=>{Object.entries(e).forEach(e=>{let[s,t]=e;"spend"!==s&&"startTime"!==s&&"models"!==s&&"users"!==s&&l.push({key:s,spend:t})})}),l.sort((e,l)=>Number(l.spend)-Number(e.spend));let s=l.slice(0,5).map(e=>e.key);return console.log("topKeys: ".concat(Object.keys(s[0]))),s}(e))).info.map(e=>({key:(e.key_name||e.key_alias).substring(0,10),spend:e.spend}));g(s),m(e)}})}catch(e){console.error("There was an error fetching the data",e)}})()},[l,s,t,n,ep,ej]),(0,a.jsx)("div",{style:{width:"100%"},className:"p-8",children:(0,a.jsxs)(et.Z,{children:[(0,a.jsxs)(en.Z,{className:"mt-2",children:[(0,a.jsx)(es.Z,{children:"All Up"}),(0,a.jsx)(es.Z,{children:"Team Based Usage"}),(0,a.jsx)(es.Z,{children:"Customer Usage"}),(0,a.jsx)(es.Z,{children:"Tag Based Usage"})]}),(0,a.jsxs)(er.Z,{children:[(0,a.jsx)(ea.Z,{children:(0,a.jsxs)(et.Z,{children:[(0,a.jsxs)(en.Z,{variant:"solid",className:"mt-1",children:[(0,a.jsx)(es.Z,{children:"Cost"}),(0,a.jsx)(es.Z,{children:"Activity"})]}),(0,a.jsxs)(er.Z,{children:[(0,a.jsx)(ea.Z,{children:(0,a.jsxs)(x.Z,{numItems:2,className:"gap-2 h-[100vh] w-full",children:[(0,a.jsx)(G,{userID:n,userRole:t,accessToken:l,userSpend:null,selectedTeam:null}),(0,a.jsx)(h.Z,{numColSpan:2,children:(0,a.jsxs)(M.Z,{children:[(0,a.jsx)(y.Z,{children:"Monthly Spend"}),(0,a.jsx)(ec.Z,{data:c,index:"date",categories:["spend"],colors:["blue"],valueFormatter:e=>"$ ".concat(new Intl.NumberFormat("us").format(e).toString()),yAxisWidth:100,tickGap:5})]})}),(0,a.jsx)(h.Z,{numColSpan:1,children:(0,a.jsxs)(M.Z,{children:[(0,a.jsx)(y.Z,{children:"Top API Keys"}),(0,a.jsx)(ec.Z,{className:"mt-4 h-40",data:j,index:"key",categories:["spend"],colors:["blue"],yAxisWidth:80,tickGap:5,layout:"vertical",showXAxis:!1,showLegend:!1})]})}),(0,a.jsx)(h.Z,{numColSpan:1,children:(0,a.jsxs)(M.Z,{children:[(0,a.jsx)(y.Z,{children:"Top Models"}),(0,a.jsx)(ec.Z,{className:"mt-4 h-40",data:Z,index:"key",categories:["spend"],colors:["blue"],yAxisWidth:200,layout:"vertical",showXAxis:!1,showLegend:!1})]})}),(0,a.jsx)(h.Z,{numColSpan:1}),(0,a.jsx)(h.Z,{numColSpan:2,children:(0,a.jsxs)(M.Z,{className:"mb-2",children:[(0,a.jsx)(y.Z,{children:"✨ Spend by Provider"}),o?(0,a.jsx)(a.Fragment,{children:(0,a.jsxs)(x.Z,{numItems:2,children:[(0,a.jsx)(h.Z,{numColSpan:1,children:(0,a.jsx)(ls.Z,{className:"mt-4 h-40",variant:"pie",data:E,index:"provider",category:"spend"})}),(0,a.jsx)(h.Z,{numColSpan:1,children:(0,a.jsxs)(D.Z,{children:[(0,a.jsx)(V.Z,{children:(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(z.Z,{children:"Provider"}),(0,a.jsx)(z.Z,{children:"Spend"})]})}),(0,a.jsx)(L.Z,{children:E.map(e=>(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(U.Z,{children:e.provider}),(0,a.jsx)(U.Z,{children:1e-5>parseFloat(e.spend.toFixed(2))?"less than 0.00":e.spend.toFixed(2)})]},e.provider))})]})})]})}):(0,a.jsxs)("div",{children:[(0,a.jsx)("p",{className:"mb-2 text-gray-500 italic text-[12px]",children:"Upgrade to use this feature"}),(0,a.jsx)(p.Z,{variant:"primary",className:"mb-2",children:(0,a.jsx)("a",{href:"https://forms.gle/W3U4PZpJGFHWtHyA9",target:"_blank",children:"Get Free Trial"})})]})]})})]})}),(0,a.jsx)(ea.Z,{children:(0,a.jsxs)(x.Z,{numItems:1,className:"gap-2 h-[75vh] w-full",children:[(0,a.jsxs)(M.Z,{children:[(0,a.jsx)(y.Z,{children:"All Up"}),(0,a.jsxs)(x.Z,{numItems:2,children:[(0,a.jsxs)(h.Z,{children:[(0,a.jsxs)(ee.Z,{style:{fontSize:"15px",fontWeight:"normal",color:"#535452"},children:["API Requests ",eg(F.sum_api_requests)]}),(0,a.jsx)(ed.Z,{className:"h-40",data:F.daily_data,valueFormatter:eg,index:"date",colors:["cyan"],categories:["api_requests"],onValueChange:e=>console.log(e)})]}),(0,a.jsxs)(h.Z,{children:[(0,a.jsxs)(ee.Z,{style:{fontSize:"15px",fontWeight:"normal",color:"#535452"},children:["Tokens ",eg(F.sum_total_tokens)]}),(0,a.jsx)(ec.Z,{className:"h-40",data:F.daily_data,valueFormatter:eg,index:"date",colors:["cyan"],categories:["total_tokens"],onValueChange:e=>console.log(e)})]})]})]}),o?(0,a.jsx)(a.Fragment,{children:H.map((e,l)=>(0,a.jsxs)(M.Z,{children:[(0,a.jsx)(y.Z,{children:e.model}),(0,a.jsxs)(x.Z,{numItems:2,children:[(0,a.jsxs)(h.Z,{children:[(0,a.jsxs)(ee.Z,{style:{fontSize:"15px",fontWeight:"normal",color:"#535452"},children:["API Requests ",eg(e.sum_api_requests)]}),(0,a.jsx)(ed.Z,{className:"h-40",data:e.daily_data,index:"date",colors:["cyan"],categories:["api_requests"],valueFormatter:eg,onValueChange:e=>console.log(e)})]}),(0,a.jsxs)(h.Z,{children:[(0,a.jsxs)(ee.Z,{style:{fontSize:"15px",fontWeight:"normal",color:"#535452"},children:["Tokens ",eg(e.sum_total_tokens)]}),(0,a.jsx)(ec.Z,{className:"h-40",data:e.daily_data,index:"date",colors:["cyan"],categories:["total_tokens"],valueFormatter:eg,onValueChange:e=>console.log(e)})]})]})]},l))}):(0,a.jsx)(a.Fragment,{children:H&&H.length>0&&H.slice(0,1).map((e,l)=>(0,a.jsxs)(M.Z,{children:[(0,a.jsx)(y.Z,{children:"✨ Activity by Model"}),(0,a.jsx)("p",{className:"mb-2 text-gray-500 italic text-[12px]",children:"Upgrade to see analytics for all models"}),(0,a.jsx)(p.Z,{variant:"primary",className:"mb-2",children:(0,a.jsx)("a",{href:"https://forms.gle/W3U4PZpJGFHWtHyA9",target:"_blank",children:"Get Free Trial"})}),(0,a.jsxs)(M.Z,{children:[(0,a.jsx)(y.Z,{children:e.model}),(0,a.jsxs)(x.Z,{numItems:2,children:[(0,a.jsxs)(h.Z,{children:[(0,a.jsxs)(ee.Z,{style:{fontSize:"15px",fontWeight:"normal",color:"#535452"},children:["API Requests ",eg(e.sum_api_requests)]}),(0,a.jsx)(ed.Z,{className:"h-40",data:e.daily_data,index:"date",colors:["cyan"],categories:["api_requests"],valueFormatter:eg,onValueChange:e=>console.log(e)})]}),(0,a.jsxs)(h.Z,{children:[(0,a.jsxs)(ee.Z,{style:{fontSize:"15px",fontWeight:"normal",color:"#535452"},children:["Tokens ",eg(e.sum_total_tokens)]}),(0,a.jsx)(ec.Z,{className:"h-40",data:e.daily_data,index:"date",colors:["cyan"],valueFormatter:eg,categories:["total_tokens"],onValueChange:e=>console.log(e)})]})]})]})]},l))})]})})]})]})}),(0,a.jsx)(ea.Z,{children:(0,a.jsxs)(x.Z,{numItems:2,className:"gap-2 h-[75vh] w-full",children:[(0,a.jsxs)(h.Z,{numColSpan:2,children:[(0,a.jsxs)(M.Z,{className:"mb-2",children:[(0,a.jsx)(y.Z,{children:"Total Spend Per Team"}),(0,a.jsx)(ll.Z,{data:T})]}),(0,a.jsxs)(M.Z,{children:[(0,a.jsx)(y.Z,{children:"Daily Spend Per Team"}),(0,a.jsx)(ec.Z,{className:"h-72",data:S,showLegend:!0,index:"date",categories:C,yAxisWidth:80,stack:!0})]})]}),(0,a.jsx)(h.Z,{numColSpan:2})]})}),(0,a.jsxs)(ea.Z,{children:[(0,a.jsxs)("p",{className:"mb-2 text-gray-500 italic text-[12px]",children:["Customers of your LLM API calls. Tracked when a `user` param is passed in your LLM calls ",(0,a.jsx)("a",{className:"text-blue-500",href:"https://docs.litellm.ai/docs/proxy/users",target:"_blank",children:"docs here"})]}),(0,a.jsxs)(x.Z,{numItems:2,children:[(0,a.jsxs)(h.Z,{children:[(0,a.jsx)(_.Z,{children:"Select Time Range"}),(0,a.jsx)(el.Z,{enableSelect:!0,value:em,onValueChange:e=>{eu(e),eZ(e.from,e.to,null)}})]}),(0,a.jsxs)(h.Z,{children:[(0,a.jsx)(_.Z,{children:"Select Key"}),(0,a.jsxs)(B.Z,{defaultValue:"all-keys",children:[(0,a.jsx)(K.Z,{value:"all-keys",onClick:()=>{eZ(em.from,em.to,null)},children:"All Keys"},"all-keys"),null==i?void 0:i.map((e,l)=>e&&null!==e.key_alias&&e.key_alias.length>0?(0,a.jsx)(K.Z,{value:String(l),onClick:()=>{eZ(em.from,em.to,e.token)},children:e.key_alias},l):null)]})]})]}),(0,a.jsx)(M.Z,{className:"mt-4",children:(0,a.jsxs)(D.Z,{className:"max-h-[70vh] min-h-[500px]",children:[(0,a.jsx)(V.Z,{children:(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(z.Z,{children:"Customer"}),(0,a.jsx)(z.Z,{children:"Spend"}),(0,a.jsx)(z.Z,{children:"Total Events"})]})}),(0,a.jsx)(L.Z,{children:null==b?void 0:b.map((e,l)=>{var s;return(0,a.jsxs)(q.Z,{children:[(0,a.jsx)(U.Z,{children:e.end_user}),(0,a.jsx)(U.Z,{children:null===(s=e.total_spend)||void 0===s?void 0:s.toFixed(4)}),(0,a.jsx)(U.Z,{children:e.total_count})]},l)})})]})})]}),(0,a.jsxs)(ea.Z,{children:[(0,a.jsxs)(x.Z,{numItems:2,children:[(0,a.jsx)(h.Z,{numColSpan:1,children:(0,a.jsx)(el.Z,{className:"mb-4",enableSelect:!0,value:em,onValueChange:e=>{eu(e),ef(e.from,e.to)}})}),(0,a.jsx)(h.Z,{children:o?(0,a.jsx)("div",{children:(0,a.jsxs)(ei.Z,{value:$,onValueChange:e=>Q(e),children:[(0,a.jsx)(eo.Z,{value:"all-tags",onClick:()=>Q(["all-tags"]),children:"All Tags"},"all-tags"),A&&A.filter(e=>"all-tags"!==e).map((e,l)=>(0,a.jsx)(eo.Z,{value:String(e),children:e},e))]})}):(0,a.jsx)("div",{children:(0,a.jsxs)(ei.Z,{value:$,onValueChange:e=>Q(e),children:[(0,a.jsx)(eo.Z,{value:"all-tags",onClick:()=>Q(["all-tags"]),children:"All Tags"},"all-tags"),A&&A.filter(e=>"all-tags"!==e).map((e,l)=>(0,a.jsxs)(K.Z,{value:String(e),disabled:!0,children:["✨ ",e," (Enterprise only Feature)"]},e))]})})})]}),(0,a.jsxs)(x.Z,{numItems:2,className:"gap-2 h-[75vh] w-full mb-4",children:[(0,a.jsx)(h.Z,{numColSpan:2,children:(0,a.jsxs)(M.Z,{children:[(0,a.jsx)(y.Z,{children:"Spend Per Tag"}),(0,a.jsxs)(_.Z,{children:["Get Started Tracking cost per tag ",(0,a.jsx)("a",{className:"text-blue-500",href:"https://docs.litellm.ai/docs/proxy/cost_tracking",target:"_blank",children:"here"})]}),(0,a.jsx)(ec.Z,{className:"h-72",data:w,index:"name",categories:["spend"],colors:["blue"]})]})}),(0,a.jsx)(h.Z,{numColSpan:2})]})]})]})]})})};let ln=e=>{if(e)return e.toISOString().split("T")[0]};function la(e){return new Intl.NumberFormat("en-US",{maximumFractionDigits:0,notation:"compact",compactDisplay:"short"}).format(e)}var lr=e=>{let{accessToken:l,token:s,userRole:t,userID:n,premiumUser:i}=e,[o,d]=(0,r.useState)([]),[c,m]=(0,r.useState)([]),[p,j]=(0,r.useState)([]),[g,Z]=(0,r.useState)([]),[f,_]=(0,r.useState)("0"),[y,b]=(0,r.useState)("0"),[v,S]=(0,r.useState)("0"),[k,w]=(0,r.useState)({from:new Date(Date.now()-6048e5),to:new Date});(0,r.useEffect)(()=>{l&&k&&(async()=>{Z(await (0,u.zg)(l,ln(k.from),ln(k.to)))})()},[l]);let N=Array.from(new Set(g.map(e=>{var l;return null!==(l=null==e?void 0:e.api_key)&&void 0!==l?l:""}))),A=Array.from(new Set(g.map(e=>{var l;return null!==(l=null==e?void 0:e.model)&&void 0!==l?l:""})));Array.from(new Set(g.map(e=>{var l;return null!==(l=null==e?void 0:e.call_type)&&void 0!==l?l:""})));let I=async(e,s)=>{e&&s&&l&&(s.setHours(23,59,59,999),e.setHours(0,0,0,0),Z(await (0,u.zg)(l,ln(e),ln(s))))};return(0,r.useEffect)(()=>{console.log("DATA IN CACHE DASHBOARD",g);let e=g;c.length>0&&(e=e.filter(e=>c.includes(e.api_key))),p.length>0&&(e=e.filter(e=>p.includes(e.model))),console.log("before processed data in cache dashboard",e);let l=0,s=0,t=0,n=e.reduce((e,n)=>{console.log("Processing item:",n),n.call_type||(console.log("Item has no call_type:",n),n.call_type="Unknown"),l+=(n.total_rows||0)-(n.cache_hit_true_rows||0),s+=n.cache_hit_true_rows||0,t+=n.cached_completion_tokens||0;let a=e.find(e=>e.name===n.call_type);return a?(a["LLM API requests"]+=(n.total_rows||0)-(n.cache_hit_true_rows||0),a["Cache hit"]+=n.cache_hit_true_rows||0,a["Cached Completion Tokens"]+=n.cached_completion_tokens||0,a["Generated Completion Tokens"]+=n.generated_completion_tokens||0):e.push({name:n.call_type,"LLM API requests":(n.total_rows||0)-(n.cache_hit_true_rows||0),"Cache hit":n.cache_hit_true_rows||0,"Cached Completion Tokens":n.cached_completion_tokens||0,"Generated Completion Tokens":n.generated_completion_tokens||0}),e},[]);_(la(s)),b(la(t)),l>0?S((s/l*100).toFixed(2)):S("0"),d(n),console.log("PROCESSED DATA IN CACHE DASHBOARD",n)},[c,p,k,g]),(0,a.jsxs)(M.Z,{children:[(0,a.jsxs)(x.Z,{numItems:3,className:"gap-4 mt-4",children:[(0,a.jsx)(h.Z,{children:(0,a.jsx)(ei.Z,{placeholder:"Select API Keys",value:c,onValueChange:m,children:N.map(e=>(0,a.jsx)(eo.Z,{value:e,children:e},e))})}),(0,a.jsx)(h.Z,{children:(0,a.jsx)(ei.Z,{placeholder:"Select Models",value:p,onValueChange:j,children:A.map(e=>(0,a.jsx)(eo.Z,{value:e,children:e},e))})}),(0,a.jsx)(h.Z,{children:(0,a.jsx)(el.Z,{enableSelect:!0,value:k,onValueChange:e=>{w(e),I(e.from,e.to)},selectPlaceholder:"Select date range"})})]}),(0,a.jsxs)("div",{className:"grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3 mt-4",children:[(0,a.jsxs)(M.Z,{children:[(0,a.jsx)("p",{className:"text-tremor-default font-medium text-tremor-content dark:text-dark-tremor-content",children:"Cache Hit Ratio"}),(0,a.jsx)("div",{className:"mt-2 flex items-baseline space-x-2.5",children:(0,a.jsxs)("p",{className:"text-tremor-metric font-semibold text-tremor-content-strong dark:text-dark-tremor-content-strong",children:[v,"%"]})})]}),(0,a.jsxs)(M.Z,{children:[(0,a.jsx)("p",{className:"text-tremor-default font-medium text-tremor-content dark:text-dark-tremor-content",children:"Cache Hits"}),(0,a.jsx)("div",{className:"mt-2 flex items-baseline space-x-2.5",children:(0,a.jsx)("p",{className:"text-tremor-metric font-semibold text-tremor-content-strong dark:text-dark-tremor-content-strong",children:f})})]}),(0,a.jsxs)(M.Z,{children:[(0,a.jsx)("p",{className:"text-tremor-default font-medium text-tremor-content dark:text-dark-tremor-content",children:"Cached Tokens"}),(0,a.jsx)("div",{className:"mt-2 flex items-baseline space-x-2.5",children:(0,a.jsx)("p",{className:"text-tremor-metric font-semibold text-tremor-content-strong dark:text-dark-tremor-content-strong",children:y})})]})]}),(0,a.jsx)(ee.Z,{className:"mt-4",children:"Cache Hits vs API Requests"}),(0,a.jsx)(ec.Z,{title:"Cache Hits vs API Requests",data:o,index:"name",valueFormatter:la,categories:["LLM API requests","Cache hit"],colors:["sky","teal"],yAxisWidth:48}),(0,a.jsx)(ee.Z,{className:"mt-4",children:"Cached Completion Tokens vs Generated Completion Tokens"}),(0,a.jsx)(ec.Z,{className:"mt-6",data:o,index:"name",valueFormatter:la,categories:["Generated Completion Tokens","Cached Completion Tokens"],colors:["sky","teal"],yAxisWidth:48})]})},li=()=>{let{Title:e,Paragraph:l}=$.default,[s,t]=(0,r.useState)(""),[n,o]=(0,r.useState)(!1),[d,c]=(0,r.useState)(null),[u,h]=(0,r.useState)(null),[x,p]=(0,r.useState)(null),[j,g]=(0,r.useState)({PROXY_BASE_URL:"",PROXY_LOGOUT_URL:""}),[Z,f]=(0,r.useState)(!0),_=(0,i.useSearchParams)(),[y,b]=(0,r.useState)({data:[]}),v=_.get("userID"),S=_.get("token"),[k,w]=(0,r.useState)("api-keys"),[N,A]=(0,r.useState)(null);return(0,r.useEffect)(()=>{if(S){let e=(0,X.o)(S);if(e){if(console.log("Decoded token:",e),console.log("Decoded key:",e.key),A(e.key),e.user_role){let l=function(e){if(!e)return"Undefined Role";switch(console.log("Received user role: ".concat(e.toLowerCase())),console.log("Received user role length: ".concat(e.toLowerCase().length)),e.toLowerCase()){case"app_owner":case"demo_app_owner":return"App Owner";case"app_admin":case"proxy_admin":return"Admin";case"proxy_admin_viewer":return"Admin Viewer";case"internal_user":return"Internal User";case"internal_viewer":return"Internal Viewer";case"app_user":return"App User";default:return"Unknown Role"}}(e.user_role);console.log("Decoded user_role:",l),t(l),"Admin Viewer"==l&&w("usage")}else console.log("User role not defined");e.user_email?c(e.user_email):console.log("User Email is not set ".concat(e)),e.login_method?f("username_password"==e.login_method):console.log("User Email is not set ".concat(e)),e.premium_user&&o(e.premium_user)}}},[S]),(0,a.jsx)(r.Suspense,{fallback:(0,a.jsx)("div",{children:"Loading..."}),children:(0,a.jsxs)("div",{className:"flex flex-col min-h-screen",children:[(0,a.jsx)(m,{userID:v,userRole:s,userEmail:d,showSSOBanner:Z,premiumUser:n,setProxySettings:g,proxySettings:j}),(0,a.jsxs)("div",{className:"flex flex-1 overflow-auto",children:[(0,a.jsx)("div",{className:"mt-8",children:(0,a.jsx)(le,{setPage:w,userRole:s,defaultSelectedKey:null})}),"api-keys"==k?(0,a.jsx)(Q,{userID:v,userRole:s,teams:u,keys:x,setUserRole:t,userEmail:d,setUserEmail:c,setTeams:h,setKeys:p,setProxySettings:g,proxySettings:j}):"models"==k?(0,a.jsx)(eP,{userID:v,userRole:s,token:S,keys:x,accessToken:N,modelData:y,setModelData:b,premiumUser:n}):"llm-playground"==k?(0,a.jsx)(e3,{userID:v,userRole:s,token:S,accessToken:N}):"users"==k?(0,a.jsx)(eM,{userID:v,userRole:s,token:S,keys:x,teams:u,accessToken:N,setKeys:p}):"teams"==k?(0,a.jsx)(eF,{teams:u,setTeams:h,searchParams:_,accessToken:N,userID:v,userRole:s}):"admin-panel"==k?(0,a.jsx)(eD,{setTeams:h,searchParams:_,accessToken:N,showSSOBanner:Z}):"api_ref"==k?(0,a.jsx)(e5,{proxySettings:j}):"settings"==k?(0,a.jsx)(eW,{userID:v,userRole:s,accessToken:N,premiumUser:n}):"budgets"==k?(0,a.jsx)(e2,{accessToken:N}):"general-settings"==k?(0,a.jsx)(eQ,{userID:v,userRole:s,accessToken:N,modelData:y}):"model-hub"==k?(0,a.jsx)(e4.Z,{accessToken:N,publicPage:!1,premiumUser:n}):"caching"==k?(0,a.jsx)(lr,{userID:v,userRole:s,token:S,accessToken:N,premiumUser:n}):(0,a.jsx)(lt,{userID:v,userRole:s,token:S,accessToken:N,keys:x,premiumUser:n})]})]})})}},41134:function(e,l,s){"use strict";s.d(l,{Z:function(){return y}});var t=s(3827),n=s(64090),a=s(47907),r=s(777),i=s(16450),o=s(13810),d=s(92836),c=s(26734),m=s(41608),u=s(32126),h=s(23682),x=s(71801),p=s(42440),j=s(84174),g=s(50459),Z=s(6180),f=s(99129),_=s(67951),y=e=>{var l;let{accessToken:s,publicPage:y,premiumUser:b}=e,[v,S]=(0,n.useState)(!1),[k,w]=(0,n.useState)(null),[N,A]=(0,n.useState)(!1),[I,C]=(0,n.useState)(!1),[P,T]=(0,n.useState)(null),O=(0,a.useRouter)();(0,n.useEffect)(()=>{s&&(async()=>{try{let e=await (0,r.kn)(s);console.log("ModelHubData:",e),w(e.data),(0,r.E9)(s,"enable_public_model_hub").then(e=>{console.log("data: ".concat(JSON.stringify(e))),!0==e.field_value&&S(!0)}).catch(e=>{})}catch(e){console.error("There was an error fetching the model data",e)}})()},[s,y]);let E=e=>{T(e),A(!0)},R=async()=>{s&&(0,r.jA)(s,"enable_public_model_hub",!0).then(e=>{C(!0)})},M=()=>{A(!1),C(!1),T(null)},F=()=>{A(!1),C(!1),T(null)},D=e=>{navigator.clipboard.writeText(e)};return(0,t.jsxs)("div",{children:[y&&v||!1==y?(0,t.jsxs)("div",{className:"w-full m-2 mt-2 p-8",children:[(0,t.jsx)("div",{className:"relative w-full"}),(0,t.jsxs)("div",{className:"flex ".concat(y?"justify-between":"items-center"),children:[(0,t.jsx)(p.Z,{className:"ml-8 text-center ",children:"Model Hub"}),!1==y?b?(0,t.jsx)(i.Z,{className:"ml-4",onClick:()=>R(),children:"✨ Make Public"}):(0,t.jsx)(i.Z,{className:"ml-4",children:(0,t.jsx)("a",{href:"https://forms.gle/W3U4PZpJGFHWtHyA9",target:"_blank",children:"✨ Make Public"})}):(0,t.jsxs)("div",{className:"flex justify-between items-center",children:[(0,t.jsx)("p",{children:"Filter by key:"}),(0,t.jsx)(x.Z,{className:"bg-gray-200 pr-2 pl-2 pt-1 pb-1 text-center",children:"/ui/model_hub?key="})]})]}),(0,t.jsx)("div",{className:"grid grid-cols-2 gap-6 sm:grid-cols-3 lg:grid-cols-4 pr-8",children:k&&k.map(e=>(0,t.jsxs)(o.Z,{className:"mt-5 mx-8",children:[(0,t.jsxs)("pre",{className:"flex justify-between",children:[(0,t.jsx)(p.Z,{children:e.model_group}),(0,t.jsx)(Z.Z,{title:e.model_group,children:(0,t.jsx)(j.Z,{onClick:()=>D(e.model_group),style:{cursor:"pointer",marginRight:"10px"}})})]}),(0,t.jsxs)("div",{className:"my-5",children:[(0,t.jsxs)(x.Z,{children:["Mode: ",e.mode]}),(0,t.jsxs)(x.Z,{children:["Supports Function Calling:"," ",(null==e?void 0:e.supports_function_calling)==!0?"Yes":"No"]}),(0,t.jsxs)(x.Z,{children:["Supports Vision:"," ",(null==e?void 0:e.supports_vision)==!0?"Yes":"No"]}),(0,t.jsxs)(x.Z,{children:["Max Input Tokens:"," ",(null==e?void 0:e.max_input_tokens)?null==e?void 0:e.max_input_tokens:"N/A"]}),(0,t.jsxs)(x.Z,{children:["Max Output Tokens:"," ",(null==e?void 0:e.max_output_tokens)?null==e?void 0:e.max_output_tokens:"N/A"]})]}),(0,t.jsx)("div",{style:{marginTop:"auto",textAlign:"right"},children:(0,t.jsxs)("a",{href:"#",onClick:()=>E(e),style:{color:"#1890ff",fontSize:"smaller"},children:["View more ",(0,t.jsx)(g.Z,{})]})})]},e.model_group))})]}):(0,t.jsxs)(o.Z,{className:"mx-auto max-w-xl mt-10",children:[(0,t.jsx)(x.Z,{className:"text-xl text-center mb-2 text-black",children:"Public Model Hub not enabled."}),(0,t.jsx)("p",{className:"text-base text-center text-slate-800",children:"Ask your proxy admin to enable this on their Admin UI."})]}),(0,t.jsx)(f.Z,{title:"Public Model Hub",width:600,visible:I,footer:null,onOk:M,onCancel:F,children:(0,t.jsxs)("div",{className:"pt-5 pb-5",children:[(0,t.jsxs)("div",{className:"flex justify-between mb-4",children:[(0,t.jsx)(x.Z,{className:"text-base mr-2",children:"Shareable Link:"}),(0,t.jsx)(x.Z,{className:"max-w-sm ml-2 bg-gray-200 pr-2 pl-2 pt-1 pb-1 text-center rounded",children:"/ui/model_hub?key="})]}),(0,t.jsx)("div",{className:"flex justify-end",children:(0,t.jsx)(i.Z,{onClick:()=>{O.replace("/model_hub?key=".concat(s))},children:"See Page"})})]})}),(0,t.jsx)(f.Z,{title:P&&P.model_group?P.model_group:"Unknown Model",width:800,visible:N,footer:null,onOk:M,onCancel:F,children:P&&(0,t.jsxs)("div",{children:[(0,t.jsx)("p",{className:"mb-4",children:(0,t.jsx)("strong",{children:"Model Information & Usage"})}),(0,t.jsxs)(c.Z,{children:[(0,t.jsxs)(m.Z,{children:[(0,t.jsx)(d.Z,{children:"OpenAI Python SDK"}),(0,t.jsx)(d.Z,{children:"Supported OpenAI Params"}),(0,t.jsx)(d.Z,{children:"LlamaIndex"}),(0,t.jsx)(d.Z,{children:"Langchain Py"})]}),(0,t.jsxs)(h.Z,{children:[(0,t.jsx)(u.Z,{children:(0,t.jsx)(_.Z,{language:"python",children:'\nimport openai\nclient = openai.OpenAI(\n api_key="your_api_key",\n base_url="http://0.0.0.0:4000" # LiteLLM Proxy is OpenAI compatible, Read More: https://docs.litellm.ai/docs/proxy/user_keys\n)\n\nresponse = client.chat.completions.create(\n model="'.concat(P.model_group,'", # model to send to the proxy\n messages = [\n {\n "role": "user",\n "content": "this is a test request, write a short poem"\n }\n ]\n)\n\nprint(response)\n ')})}),(0,t.jsx)(u.Z,{children:(0,t.jsx)(_.Z,{language:"python",children:"".concat(null===(l=P.supported_openai_params)||void 0===l?void 0:l.map(e=>"".concat(e,"\n")).join(""))})}),(0,t.jsx)(u.Z,{children:(0,t.jsx)(_.Z,{language:"python",children:'\nimport os, dotenv\n\nfrom llama_index.llms import AzureOpenAI\nfrom llama_index.embeddings import AzureOpenAIEmbedding\nfrom llama_index import VectorStoreIndex, SimpleDirectoryReader, ServiceContext\n\nllm = AzureOpenAI(\n engine="'.concat(P.model_group,'", # model_name on litellm proxy\n temperature=0.0,\n azure_endpoint="http://0.0.0.0:4000", # litellm proxy endpoint\n api_key="sk-1234", # litellm proxy API Key\n api_version="2023-07-01-preview",\n)\n\nembed_model = AzureOpenAIEmbedding(\n deployment_name="azure-embedding-model",\n azure_endpoint="http://0.0.0.0:4000",\n api_key="sk-1234",\n api_version="2023-07-01-preview",\n)\n\n\ndocuments = SimpleDirectoryReader("llama_index_data").load_data()\nservice_context = ServiceContext.from_defaults(llm=llm, embed_model=embed_model)\nindex = VectorStoreIndex.from_documents(documents, service_context=service_context)\n\nquery_engine = index.as_query_engine()\nresponse = query_engine.query("What did the author do growing up?")\nprint(response)\n\n ')})}),(0,t.jsx)(u.Z,{children:(0,t.jsx)(_.Z,{language:"python",children:'\nfrom langchain.chat_models import ChatOpenAI\nfrom langchain.prompts.chat import (\n ChatPromptTemplate,\n HumanMessagePromptTemplate,\n SystemMessagePromptTemplate,\n)\nfrom langchain.schema import HumanMessage, SystemMessage\n\nchat = ChatOpenAI(\n openai_api_base="http://0.0.0.0:4000",\n model = "'.concat(P.model_group,'",\n temperature=0.1\n)\n\nmessages = [\n SystemMessage(\n content="You are a helpful assistant that im using to make a test request to."\n ),\n HumanMessage(\n content="test from litellm. tell me why it\'s amazing in 1 sentence"\n ),\n]\nresponse = chat(messages)\n\nprint(response)\n\n ')})})]})]})]})})]})}}},function(e){e.O(0,[936,294,131,684,759,777,971,69,744],function(){return e(e.s=20661)}),_N_E=e.O()}]); \ No newline at end of file diff --git a/ui/litellm-dashboard/out/index.html b/ui/litellm-dashboard/out/index.html index bee8814de0c..c33c288c785 100644 --- a/ui/litellm-dashboard/out/index.html +++ b/ui/litellm-dashboard/out/index.html @@ -1 +1 @@ -LiteLLM Dashboard \ No newline at end of file +LiteLLM Dashboard \ No newline at end of file diff --git a/ui/litellm-dashboard/out/index.txt b/ui/litellm-dashboard/out/index.txt index d67a24f7fac..32c7cd30e89 100644 --- a/ui/litellm-dashboard/out/index.txt +++ b/ui/litellm-dashboard/out/index.txt @@ -1,7 +1,7 @@ 2:I[77831,[],""] -3:I[48951,["936","static/chunks/2f6dbc85-052c4579f80d66ae.js","294","static/chunks/294-0e35509d5ca95267.js","131","static/chunks/131-6a03368053f9d26d.js","684","static/chunks/684-bb2d2f93d92acb0b.js","759","static/chunks/759-83a8bdddfe32b5d9.js","777","static/chunks/777-f76791513e294b30.js","931","static/chunks/app/page-5b9334558218205d.js"],""] +3:I[48951,["936","static/chunks/2f6dbc85-052c4579f80d66ae.js","294","static/chunks/294-0e35509d5ca95267.js","131","static/chunks/131-6a03368053f9d26d.js","684","static/chunks/684-bb2d2f93d92acb0b.js","759","static/chunks/759-83a8bdddfe32b5d9.js","777","static/chunks/777-f76791513e294b30.js","931","static/chunks/app/page-42b04008af7da690.js"],""] 4:I[5613,[],""] 5:I[31778,[],""] -0:["dDWf4yi4zCe685SxgCnWX",[[["",{"children":["__PAGE__",{}]},"$undefined","$undefined",true],["",{"children":["__PAGE__",{},["$L1",["$","$L2",null,{"propsForComponent":{"params":{}},"Component":"$3","isStaticGeneration":true}],null]]},[null,["$","html",null,{"lang":"en","children":["$","body",null,{"className":"__className_12bbc4","children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"loading":"$undefined","loadingStyles":"$undefined","loadingScripts":"$undefined","hasLoading":false,"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[],"styles":null}]}]}],null]],[[["$","link","0",{"rel":"stylesheet","href":"/ui/_next/static/css/0f6908625573deae.css","precedence":"next","crossOrigin":""}]],"$L6"]]]] +0:["DahySukItzAH9ZoOiMmQB",[[["",{"children":["__PAGE__",{}]},"$undefined","$undefined",true],["",{"children":["__PAGE__",{},["$L1",["$","$L2",null,{"propsForComponent":{"params":{}},"Component":"$3","isStaticGeneration":true}],null]]},[null,["$","html",null,{"lang":"en","children":["$","body",null,{"className":"__className_12bbc4","children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"loading":"$undefined","loadingStyles":"$undefined","loadingScripts":"$undefined","hasLoading":false,"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[],"styles":null}]}]}],null]],[[["$","link","0",{"rel":"stylesheet","href":"/ui/_next/static/css/0f6908625573deae.css","precedence":"next","crossOrigin":""}]],"$L6"]]]] 6:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"LiteLLM Dashboard"}],["$","meta","3",{"name":"description","content":"LiteLLM Proxy Admin UI"}],["$","link","4",{"rel":"icon","href":"/ui/favicon.ico","type":"image/x-icon","sizes":"16x16"}],["$","meta","5",{"name":"next-size-adjust"}]] 1:null diff --git a/ui/litellm-dashboard/out/model_hub.html b/ui/litellm-dashboard/out/model_hub.html index 49dfe314fcc..ef01db5851f 100644 --- a/ui/litellm-dashboard/out/model_hub.html +++ b/ui/litellm-dashboard/out/model_hub.html @@ -1 +1 @@ -LiteLLM Dashboard \ No newline at end of file +LiteLLM Dashboard \ No newline at end of file diff --git a/ui/litellm-dashboard/out/model_hub.txt b/ui/litellm-dashboard/out/model_hub.txt index 7b80cb0f46b..cf5da26f116 100644 --- a/ui/litellm-dashboard/out/model_hub.txt +++ b/ui/litellm-dashboard/out/model_hub.txt @@ -2,6 +2,6 @@ 3:I[87494,["294","static/chunks/294-0e35509d5ca95267.js","131","static/chunks/131-6a03368053f9d26d.js","777","static/chunks/777-f76791513e294b30.js","418","static/chunks/app/model_hub/page-ba7819b59161aa64.js"],""] 4:I[5613,[],""] 5:I[31778,[],""] -0:["dDWf4yi4zCe685SxgCnWX",[[["",{"children":["model_hub",{"children":["__PAGE__",{}]}]},"$undefined","$undefined",true],["",{"children":["model_hub",{"children":["__PAGE__",{},["$L1",["$","$L2",null,{"propsForComponent":{"params":{}},"Component":"$3","isStaticGeneration":true}],null]]},["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","model_hub","children"],"loading":"$undefined","loadingStyles":"$undefined","loadingScripts":"$undefined","hasLoading":false,"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined","styles":null}]]},[null,["$","html",null,{"lang":"en","children":["$","body",null,{"className":"__className_12bbc4","children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"loading":"$undefined","loadingStyles":"$undefined","loadingScripts":"$undefined","hasLoading":false,"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[],"styles":null}]}]}],null]],[[["$","link","0",{"rel":"stylesheet","href":"/ui/_next/static/css/0f6908625573deae.css","precedence":"next","crossOrigin":""}]],"$L6"]]]] +0:["DahySukItzAH9ZoOiMmQB",[[["",{"children":["model_hub",{"children":["__PAGE__",{}]}]},"$undefined","$undefined",true],["",{"children":["model_hub",{"children":["__PAGE__",{},["$L1",["$","$L2",null,{"propsForComponent":{"params":{}},"Component":"$3","isStaticGeneration":true}],null]]},["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","model_hub","children"],"loading":"$undefined","loadingStyles":"$undefined","loadingScripts":"$undefined","hasLoading":false,"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined","styles":null}]]},[null,["$","html",null,{"lang":"en","children":["$","body",null,{"className":"__className_12bbc4","children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"loading":"$undefined","loadingStyles":"$undefined","loadingScripts":"$undefined","hasLoading":false,"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[],"styles":null}]}]}],null]],[[["$","link","0",{"rel":"stylesheet","href":"/ui/_next/static/css/0f6908625573deae.css","precedence":"next","crossOrigin":""}]],"$L6"]]]] 6:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"LiteLLM Dashboard"}],["$","meta","3",{"name":"description","content":"LiteLLM Proxy Admin UI"}],["$","link","4",{"rel":"icon","href":"/ui/favicon.ico","type":"image/x-icon","sizes":"16x16"}],["$","meta","5",{"name":"next-size-adjust"}]] 1:null diff --git a/ui/litellm-dashboard/out/onboarding.html b/ui/litellm-dashboard/out/onboarding.html index ca402520812..ff88e53c95e 100644 --- a/ui/litellm-dashboard/out/onboarding.html +++ b/ui/litellm-dashboard/out/onboarding.html @@ -1 +1 @@ -LiteLLM Dashboard \ No newline at end of file +LiteLLM Dashboard \ No newline at end of file diff --git a/ui/litellm-dashboard/out/onboarding.txt b/ui/litellm-dashboard/out/onboarding.txt index 1563ac4dd61..7c5d0071c9d 100644 --- a/ui/litellm-dashboard/out/onboarding.txt +++ b/ui/litellm-dashboard/out/onboarding.txt @@ -1,7 +1,7 @@ 2:I[77831,[],""] -3:I[667,["665","static/chunks/3014691f-589a5f4865c3822f.js","294","static/chunks/294-0e35509d5ca95267.js","684","static/chunks/684-bb2d2f93d92acb0b.js","777","static/chunks/777-f76791513e294b30.js","461","static/chunks/app/onboarding/page-da04a591bae84617.js"],""] +3:I[667,["665","static/chunks/3014691f-589a5f4865c3822f.js","294","static/chunks/294-0e35509d5ca95267.js","684","static/chunks/684-bb2d2f93d92acb0b.js","777","static/chunks/777-f76791513e294b30.js","461","static/chunks/app/onboarding/page-fd30ae439831db99.js"],""] 4:I[5613,[],""] 5:I[31778,[],""] -0:["dDWf4yi4zCe685SxgCnWX",[[["",{"children":["onboarding",{"children":["__PAGE__",{}]}]},"$undefined","$undefined",true],["",{"children":["onboarding",{"children":["__PAGE__",{},["$L1",["$","$L2",null,{"propsForComponent":{"params":{}},"Component":"$3","isStaticGeneration":true}],null]]},["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","onboarding","children"],"loading":"$undefined","loadingStyles":"$undefined","loadingScripts":"$undefined","hasLoading":false,"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined","styles":null}]]},[null,["$","html",null,{"lang":"en","children":["$","body",null,{"className":"__className_12bbc4","children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"loading":"$undefined","loadingStyles":"$undefined","loadingScripts":"$undefined","hasLoading":false,"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[],"styles":null}]}]}],null]],[[["$","link","0",{"rel":"stylesheet","href":"/ui/_next/static/css/0f6908625573deae.css","precedence":"next","crossOrigin":""}]],"$L6"]]]] +0:["DahySukItzAH9ZoOiMmQB",[[["",{"children":["onboarding",{"children":["__PAGE__",{}]}]},"$undefined","$undefined",true],["",{"children":["onboarding",{"children":["__PAGE__",{},["$L1",["$","$L2",null,{"propsForComponent":{"params":{}},"Component":"$3","isStaticGeneration":true}],null]]},["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","onboarding","children"],"loading":"$undefined","loadingStyles":"$undefined","loadingScripts":"$undefined","hasLoading":false,"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined","styles":null}]]},[null,["$","html",null,{"lang":"en","children":["$","body",null,{"className":"__className_12bbc4","children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"loading":"$undefined","loadingStyles":"$undefined","loadingScripts":"$undefined","hasLoading":false,"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[],"styles":null}]}]}],null]],[[["$","link","0",{"rel":"stylesheet","href":"/ui/_next/static/css/0f6908625573deae.css","precedence":"next","crossOrigin":""}]],"$L6"]]]] 6:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"LiteLLM Dashboard"}],["$","meta","3",{"name":"description","content":"LiteLLM Proxy Admin UI"}],["$","link","4",{"rel":"icon","href":"/ui/favicon.ico","type":"image/x-icon","sizes":"16x16"}],["$","meta","5",{"name":"next-size-adjust"}]] 1:null From b201402b0b9c55f5c026358a5457882a03e8f7bf Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Sat, 22 Jun 2024 13:32:28 -0700 Subject: [PATCH 11/22] fix testing - we had two files running the exact same langfuse test --- litellm/tests/test_alangfuse.py | 1 + litellm/tests/test_amazing_langfuse.py | 869 ------------------------- 2 files changed, 1 insertion(+), 869 deletions(-) delete mode 100644 litellm/tests/test_amazing_langfuse.py diff --git a/litellm/tests/test_alangfuse.py b/litellm/tests/test_alangfuse.py index 9e83991c587..4e3d42352f7 100644 --- a/litellm/tests/test_alangfuse.py +++ b/litellm/tests/test_alangfuse.py @@ -29,6 +29,7 @@ def langfuse_client(): secret_key=os.environ["LANGFUSE_SECRET_KEY"], host=None, ) + print("NEW LANGFUSE CLIENT") with patch( "langfuse.Langfuse", MagicMock(return_value=langfuse_client) diff --git a/litellm/tests/test_amazing_langfuse.py b/litellm/tests/test_amazing_langfuse.py deleted file mode 100644 index b9df9d8b162..00000000000 --- a/litellm/tests/test_amazing_langfuse.py +++ /dev/null @@ -1,869 +0,0 @@ -import asyncio -import copy -import json -import logging -import os -import sys -from unittest.mock import MagicMock, patch - -logging.basicConfig(level=logging.DEBUG) -sys.path.insert(0, os.path.abspath("../..")) - -import litellm -from litellm import completion - -litellm.num_retries = 3 -litellm.success_callback = ["langfuse"] -os.environ["LANGFUSE_DEBUG"] = "True" -import time - -import pytest - - -@pytest.fixture -def langfuse_client(): - import langfuse - - langfuse_client = langfuse.Langfuse( - public_key=os.environ["LANGFUSE_PUBLIC_KEY"], - secret_key=os.environ["LANGFUSE_SECRET_KEY"], - host=None, - ) - - with patch( - "langfuse.Langfuse", MagicMock(return_value=langfuse_client) - ) as mock_langfuse_client: - yield mock_langfuse_client() - - -def search_logs(log_file_path, num_good_logs=1): - """ - Searches the given log file for logs containing the "/api/public" string. - - Parameters: - - log_file_path (str): The path to the log file to be searched. - - Returns: - - None - - Raises: - - Exception: If there are any bad logs found in the log file. - """ - import re - - print("\n searching logs") - bad_logs = [] - good_logs = [] - all_logs = [] - try: - with open(log_file_path, "r") as log_file: - lines = log_file.readlines() - print(f"searching logslines: {lines}") - for line in lines: - all_logs.append(line.strip()) - if "/api/public" in line: - print("Found log with /api/public:") - print(line.strip()) - print("\n\n") - match = re.search( - r'"POST /api/public/ingestion HTTP/1.1" (\d+) (\d+)', - line, - ) - if match: - status_code = int(match.group(1)) - print("STATUS CODE", status_code) - if ( - status_code != 200 - and status_code != 201 - and status_code != 207 - ): - print("got a BAD log") - bad_logs.append(line.strip()) - else: - good_logs.append(line.strip()) - print("\nBad Logs") - print(bad_logs) - if len(bad_logs) > 0: - raise Exception(f"bad logs, Bad logs = {bad_logs}") - assert ( - len(good_logs) == num_good_logs - ), f"Did not get expected number of good logs, expected {num_good_logs}, got {len(good_logs)}. All logs \n {all_logs}" - print("\nGood Logs") - print(good_logs) - if len(good_logs) <= 0: - raise Exception( - f"There were no Good Logs from Langfuse. No logs with /api/public status 200. \nAll logs:{all_logs}" - ) - - except Exception as e: - raise e - - -def pre_langfuse_setup(): - """ - Set up the logging for the 'pre_langfuse_setup' function. - """ - # sends logs to langfuse.log - import logging - - # Configure the logging to write to a file - logging.basicConfig(filename="langfuse.log", level=logging.DEBUG) - logger = logging.getLogger() - - # Add a FileHandler to the logger - file_handler = logging.FileHandler("langfuse.log", mode="w") - file_handler.setLevel(logging.DEBUG) - logger.addHandler(file_handler) - return - - -def test_langfuse_logging_async(): - # this tests time added to make langfuse logging calls, vs just acompletion calls - try: - pre_langfuse_setup() - litellm.set_verbose = True - - # Make 5 calls with an empty success_callback - litellm.success_callback = [] - start_time_empty_callback = asyncio.run(make_async_calls()) - print("done with no callback test") - - print("starting langfuse test") - # Make 5 calls with success_callback set to "langfuse" - litellm.success_callback = ["langfuse"] - start_time_langfuse = asyncio.run(make_async_calls()) - print("done with langfuse test") - - # Compare the time for both scenarios - print(f"Time taken with success_callback='langfuse': {start_time_langfuse}") - print(f"Time taken with empty success_callback: {start_time_empty_callback}") - - # assert the diff is not more than 1 second - this was 5 seconds before the fix - assert abs(start_time_langfuse - start_time_empty_callback) < 1 - - except litellm.Timeout as e: - pass - except Exception as e: - pytest.fail(f"An exception occurred - {e}") - - -async def make_async_calls(metadata=None, **completion_kwargs): - tasks = [] - for _ in range(5): - tasks.append(create_async_task()) - - # Measure the start time before running the tasks - start_time = asyncio.get_event_loop().time() - - # Wait for all tasks to complete - responses = await asyncio.gather(*tasks) - - # Print the responses when tasks return - for idx, response in enumerate(responses): - print(f"Response from Task {idx + 1}: {response}") - - # Calculate the total time taken - total_time = asyncio.get_event_loop().time() - start_time - - return total_time - - -def create_async_task(**completion_kwargs): - """ - Creates an async task for the litellm.acompletion function. - This is just the task, but it is not run here. - To run the task it must be awaited or used in other asyncio coroutine execution functions like asyncio.gather. - Any kwargs passed to this function will be passed to the litellm.acompletion function. - By default a standard set of arguments are used for the litellm.acompletion function. - """ - completion_args = { - "model": "azure/chatgpt-v-2", - "api_version": "2024-02-01", - "messages": [{"role": "user", "content": "This is a test"}], - "max_tokens": 5, - "temperature": 0.7, - "timeout": 5, - "user": "langfuse_latency_test_user", - "mock_response": "It's simple to use and easy to get started", - } - completion_args.update(completion_kwargs) - return asyncio.create_task(litellm.acompletion(**completion_args)) - - -@pytest.mark.asyncio -@pytest.mark.parametrize("stream", [False, True]) -async def test_langfuse_logging_without_request_response(stream, langfuse_client): - try: - import uuid - - _unique_trace_name = f"litellm-test-{str(uuid.uuid4())}" - litellm.set_verbose = True - litellm.turn_off_message_logging = True - litellm.success_callback = ["langfuse"] - response = await create_async_task( - model="gpt-3.5-turbo", - stream=stream, - metadata={"trace_id": _unique_trace_name}, - ) - print(response) - if stream: - async for chunk in response: - print(chunk) - - langfuse_client.flush() - await asyncio.sleep(2) - - # get trace with _unique_trace_name - trace = langfuse_client.get_generations(trace_id=_unique_trace_name) - - print("trace_from_langfuse", trace) - - _trace_data = trace.data - - assert _trace_data[0].input == { - "messages": [{"content": "redacted-by-litellm", "role": "user"}] - } - assert _trace_data[0].output == { - "role": "assistant", - "content": "redacted-by-litellm", - } - - except Exception as e: - pytest.fail(f"An exception occurred - {e}") - - -@pytest.mark.asyncio -async def test_langfuse_masked_input_output(langfuse_client): - """ - Test that creates a trace with masked input and output - """ - import uuid - - for mask_value in [True, False]: - _unique_trace_name = f"litellm-test-{str(uuid.uuid4())}" - litellm.set_verbose = True - litellm.success_callback = ["langfuse"] - response = await create_async_task( - model="gpt-3.5-turbo", - messages=[{"role": "user", "content": "This is a test"}], - metadata={ - "trace_id": _unique_trace_name, - "mask_input": mask_value, - "mask_output": mask_value, - }, - mock_response="This is a test response", - ) - print(response) - expected_input = ( - "redacted-by-litellm" - if mask_value - else {"messages": [{"content": "This is a test", "role": "user"}]} - ) - expected_output = ( - "redacted-by-litellm" - if mask_value - else {"content": "This is a test response", "role": "assistant"} - ) - langfuse_client.flush() - await asyncio.sleep(2) - - # get trace with _unique_trace_name - trace = langfuse_client.get_trace(id=_unique_trace_name) - generations = list( - reversed(langfuse_client.get_generations(trace_id=_unique_trace_name).data) - ) - - assert trace.input == expected_input - assert trace.output == expected_output - assert generations[0].input == expected_input - assert generations[0].output == expected_output - - -@pytest.mark.asyncio -async def test_alangfuse_logging_metadata(langfuse_client): - """ - Test that creates multiple traces, with a varying number of generations and sets various metadata fields - Confirms that no metadata that is standard within Langfuse is duplicated in the respective trace or generation metadata - For trace continuation certain metadata of the trace is overriden with metadata from the last generation based on the update_trace_keys field - Version is set for both the trace and the generation - Release is just set for the trace - Tags is just set for the trace - """ - import uuid - - litellm.set_verbose = True - litellm.success_callback = ["langfuse"] - - trace_identifiers = {} - expected_filtered_metadata_keys = { - "trace_name", - "trace_id", - "existing_trace_id", - "trace_user_id", - "session_id", - "tags", - "generation_name", - "generation_id", - "prompt", - } - trace_metadata = { - "trace_actual_metadata_key": "trace_actual_metadata_value" - } # Allows for setting the metadata on the trace - run_id = str(uuid.uuid4()) - session_id = f"litellm-test-session-{run_id}" - trace_common_metadata = { - "session_id": session_id, - "tags": ["litellm-test-tag1", "litellm-test-tag2"], - "update_trace_keys": [ - "output", - "trace_metadata", - ], # Overwrite the following fields in the trace with the last generation's output and the trace_user_id - "trace_metadata": trace_metadata, - "gen_metadata_key": "gen_metadata_value", # Metadata key that should not be filtered in the generation - "trace_release": "litellm-test-release", - "version": "litellm-test-version", - } - for trace_num in range(1, 3): # Two traces - metadata = copy.deepcopy(trace_common_metadata) - trace_id = f"litellm-test-trace{trace_num}-{run_id}" - metadata["trace_id"] = trace_id - metadata["trace_name"] = trace_id - trace_identifiers[trace_id] = [] - print(f"Trace: {trace_id}") - for generation_num in range( - 1, trace_num + 1 - ): # Each trace has a number of generations equal to its trace number - metadata["trace_user_id"] = f"litellm-test-user{generation_num}-{run_id}" - generation_id = ( - f"litellm-test-trace{trace_num}-generation-{generation_num}-{run_id}" - ) - metadata["generation_id"] = generation_id - metadata["generation_name"] = generation_id - metadata["trace_metadata"][ - "generation_id" - ] = generation_id # Update to test if trace_metadata is overwritten by update trace keys - trace_identifiers[trace_id].append(generation_id) - print(f"Generation: {generation_id}") - response = await create_async_task( - model="gpt-3.5-turbo", - mock_response=f"{session_id}:{trace_id}:{generation_id}", - messages=[ - { - "role": "user", - "content": f"{session_id}:{trace_id}:{generation_id}", - } - ], - max_tokens=100, - temperature=0.2, - metadata=copy.deepcopy( - metadata - ), # Every generation needs its own metadata, langfuse is not async/thread safe without it - ) - print(response) - metadata["existing_trace_id"] = trace_id - - langfuse_client.flush() - await asyncio.sleep(10) - - # Tests the metadata filtering and the override of the output to be the last generation - for trace_id, generation_ids in trace_identifiers.items(): - trace = langfuse_client.get_trace(id=trace_id) - assert trace.id == trace_id - assert trace.session_id == session_id - assert trace.metadata != trace_metadata - generations = list( - reversed(langfuse_client.get_generations(trace_id=trace_id).data) - ) - assert len(generations) == len(generation_ids) - assert ( - trace.input == generations[0].input - ) # Should be set by the first generation - assert ( - trace.output == generations[-1].output - ) # Should be overwritten by the last generation according to update_trace_keys - assert ( - trace.metadata != generations[-1].metadata - ) # Should be overwritten by the last generation according to update_trace_keys - assert trace.metadata["generation_id"] == generations[-1].id - assert set(trace.tags).issuperset(trace_common_metadata["tags"]) - print("trace_from_langfuse", trace) - for generation_id, generation in zip(generation_ids, generations): - assert generation.id == generation_id - assert generation.trace_id == trace_id - print( - "common keys in trace", - set(generation.metadata.keys()).intersection( - expected_filtered_metadata_keys - ), - ) - - assert set(generation.metadata.keys()).isdisjoint( - expected_filtered_metadata_keys - ) - print("generation_from_langfuse", generation) - - -@pytest.mark.skip(reason="beta test - checking langfuse output") -def test_langfuse_logging(): - try: - pre_langfuse_setup() - litellm.set_verbose = True - response = completion( - model="claude-instant-1.2", - messages=[{"role": "user", "content": "Hi 👋 - i'm claude"}], - max_tokens=10, - temperature=0.2, - ) - print(response) - # time.sleep(5) - # # check langfuse.log to see if there was a failed response - # search_logs("langfuse.log") - - except litellm.Timeout as e: - pass - except Exception as e: - pytest.fail(f"An exception occurred - {e}") - - -# test_langfuse_logging() - - -@pytest.mark.skip(reason="beta test - checking langfuse output") -def test_langfuse_logging_stream(): - try: - litellm.set_verbose = True - response = completion( - model="gpt-3.5-turbo", - messages=[ - { - "role": "user", - "content": "this is a streaming test for llama2 + langfuse", - } - ], - max_tokens=20, - temperature=0.2, - stream=True, - ) - print(response) - for chunk in response: - pass - # print(chunk) - except litellm.Timeout as e: - pass - except Exception as e: - print(e) - - -# test_langfuse_logging_stream() - - -@pytest.mark.skip(reason="beta test - checking langfuse output") -def test_langfuse_logging_custom_generation_name(): - try: - litellm.set_verbose = True - response = completion( - model="gpt-3.5-turbo", - messages=[{"role": "user", "content": "Hi 👋 - i'm claude"}], - max_tokens=10, - metadata={ - "langfuse/foo": "bar", - "langsmith/fizz": "buzz", - "prompt_hash": "asdf98u0j9131123", - "generation_name": "ishaan-test-generation", - "generation_id": "gen-id22", - "trace_id": "trace-id22", - "trace_user_id": "user-id2", - }, - ) - print(response) - except litellm.Timeout as e: - pass - except Exception as e: - pytest.fail(f"An exception occurred - {e}") - print(e) - - -# test_langfuse_logging_custom_generation_name() - - -@pytest.mark.skip(reason="beta test - checking langfuse output") -def test_langfuse_logging_embedding(): - try: - litellm.set_verbose = True - litellm.success_callback = ["langfuse"] - response = litellm.embedding( - model="text-embedding-ada-002", - input=["gm", "ishaan"], - ) - print(response) - except litellm.Timeout as e: - pass - except Exception as e: - pytest.fail(f"An exception occurred - {e}") - print(e) - - -@pytest.mark.skip(reason="beta test - checking langfuse output") -def test_langfuse_logging_function_calling(): - litellm.set_verbose = True - function1 = [ - { - "name": "get_current_weather", - "description": "Get the current weather in a given location", - "parameters": { - "type": "object", - "properties": { - "location": { - "type": "string", - "description": "The city and state, e.g. San Francisco, CA", - }, - "unit": {"type": "string", "enum": ["celsius", "fahrenheit"]}, - }, - "required": ["location"], - }, - } - ] - try: - response = completion( - model="gpt-3.5-turbo", - messages=[{"role": "user", "content": "what's the weather in boston"}], - temperature=0.1, - functions=function1, - ) - print(response) - except litellm.Timeout as e: - pass - except Exception as e: - print(e) - - -# test_langfuse_logging_function_calling() - - -@pytest.mark.skip(reason="Need to address this on main") -def test_aaalangfuse_existing_trace_id(): - """ - When existing trace id is passed, don't set trace params -> prevents overwriting the trace - - Pass 1 logging object with a trace - - Pass 2nd logging object with the trace id - - Assert no changes to the trace - """ - # Test - if the logs were sent to the correct team on langfuse - import datetime - - import litellm - from litellm.integrations.langfuse import LangFuseLogger - - langfuse_Logger = LangFuseLogger( - langfuse_public_key=os.getenv("LANGFUSE_PROJECT2_PUBLIC"), - langfuse_secret=os.getenv("LANGFUSE_PROJECT2_SECRET"), - ) - litellm.success_callback = ["langfuse"] - - # langfuse_args = {'kwargs': { 'start_time': 'end_time': datetime.datetime(2024, 5, 1, 7, 31, 29, 903685), 'user_id': None, 'print_verbose': , 'level': 'DEFAULT', 'status_message': None} - response_obj = litellm.ModelResponse( - id="chatcmpl-9K5HUAbVRqFrMZKXL0WoC295xhguY", - choices=[ - litellm.Choices( - finish_reason="stop", - index=0, - message=litellm.Message( - content="I'm sorry, I am an AI assistant and do not have real-time information. I recommend checking a reliable weather website or app for the most up-to-date weather information in Boston.", - role="assistant", - ), - ) - ], - created=1714573888, - model="gpt-3.5-turbo-0125", - object="chat.completion", - system_fingerprint="fp_3b956da36b", - usage=litellm.Usage(completion_tokens=37, prompt_tokens=14, total_tokens=51), - ) - - ### NEW TRACE ### - message = [{"role": "user", "content": "what's the weather in boston"}] - langfuse_args = { - "response_obj": response_obj, - "kwargs": { - "model": "gpt-3.5-turbo", - "litellm_params": { - "acompletion": False, - "api_key": None, - "force_timeout": 600, - "logger_fn": None, - "verbose": False, - "custom_llm_provider": "openai", - "api_base": "https://api.openai.com/v1/", - "litellm_call_id": None, - "model_alias_map": {}, - "completion_call_id": None, - "metadata": None, - "model_info": None, - "proxy_server_request": None, - "preset_cache_key": None, - "no-log": False, - "stream_response": {}, - }, - "messages": message, - "optional_params": {"temperature": 0.1, "extra_body": {}}, - "start_time": "2024-05-01 07:31:27.986164", - "stream": False, - "user": None, - "call_type": "completion", - "litellm_call_id": None, - "completion_start_time": "2024-05-01 07:31:29.903685", - "temperature": 0.1, - "extra_body": {}, - "input": [{"role": "user", "content": "what's the weather in boston"}], - "api_key": "my-api-key", - "additional_args": { - "complete_input_dict": { - "model": "gpt-3.5-turbo", - "messages": [ - {"role": "user", "content": "what's the weather in boston"} - ], - "temperature": 0.1, - "extra_body": {}, - } - }, - "log_event_type": "successful_api_call", - "end_time": "2024-05-01 07:31:29.903685", - "cache_hit": None, - "response_cost": 6.25e-05, - }, - "start_time": datetime.datetime(2024, 5, 1, 7, 31, 27, 986164), - "end_time": datetime.datetime(2024, 5, 1, 7, 31, 29, 903685), - "user_id": None, - "print_verbose": litellm.print_verbose, - "level": "DEFAULT", - "status_message": None, - } - - langfuse_response_object = langfuse_Logger.log_event(**langfuse_args) - - import langfuse - - langfuse_client = langfuse.Langfuse( - public_key=os.getenv("LANGFUSE_PROJECT2_PUBLIC"), - secret_key=os.getenv("LANGFUSE_PROJECT2_SECRET"), - ) - - trace_id = langfuse_response_object["trace_id"] - - assert trace_id is not None - - langfuse_client.flush() - - time.sleep(2) - - print(langfuse_client.get_trace(id=trace_id)) - - initial_langfuse_trace = langfuse_client.get_trace(id=trace_id) - - ### EXISTING TRACE ### - - new_metadata = {"existing_trace_id": trace_id} - new_messages = [{"role": "user", "content": "What do you know?"}] - new_response_obj = litellm.ModelResponse( - id="chatcmpl-9K5HUAbVRqFrMZKXL0WoC295xhguY", - choices=[ - litellm.Choices( - finish_reason="stop", - index=0, - message=litellm.Message( - content="What do I know?", - role="assistant", - ), - ) - ], - created=1714573888, - model="gpt-3.5-turbo-0125", - object="chat.completion", - system_fingerprint="fp_3b956da36b", - usage=litellm.Usage(completion_tokens=37, prompt_tokens=14, total_tokens=51), - ) - langfuse_args = { - "response_obj": new_response_obj, - "kwargs": { - "model": "gpt-3.5-turbo", - "litellm_params": { - "acompletion": False, - "api_key": None, - "force_timeout": 600, - "logger_fn": None, - "verbose": False, - "custom_llm_provider": "openai", - "api_base": "https://api.openai.com/v1/", - "litellm_call_id": "508113a1-c6f1-48ce-a3e1-01c6cce9330e", - "model_alias_map": {}, - "completion_call_id": None, - "metadata": new_metadata, - "model_info": None, - "proxy_server_request": None, - "preset_cache_key": None, - "no-log": False, - "stream_response": {}, - }, - "messages": new_messages, - "optional_params": {"temperature": 0.1, "extra_body": {}}, - "start_time": "2024-05-01 07:31:27.986164", - "stream": False, - "user": None, - "call_type": "completion", - "litellm_call_id": "508113a1-c6f1-48ce-a3e1-01c6cce9330e", - "completion_start_time": "2024-05-01 07:31:29.903685", - "temperature": 0.1, - "extra_body": {}, - "input": [{"role": "user", "content": "what's the weather in boston"}], - "api_key": "my-api-key", - "additional_args": { - "complete_input_dict": { - "model": "gpt-3.5-turbo", - "messages": [ - {"role": "user", "content": "what's the weather in boston"} - ], - "temperature": 0.1, - "extra_body": {}, - } - }, - "log_event_type": "successful_api_call", - "end_time": "2024-05-01 07:31:29.903685", - "cache_hit": None, - "response_cost": 6.25e-05, - }, - "start_time": datetime.datetime(2024, 5, 1, 7, 31, 27, 986164), - "end_time": datetime.datetime(2024, 5, 1, 7, 31, 29, 903685), - "user_id": None, - "print_verbose": litellm.print_verbose, - "level": "DEFAULT", - "status_message": None, - } - - langfuse_response_object = langfuse_Logger.log_event(**langfuse_args) - - new_trace_id = langfuse_response_object["trace_id"] - - assert new_trace_id == trace_id - - langfuse_client.flush() - - time.sleep(2) - - print(langfuse_client.get_trace(id=trace_id)) - - new_langfuse_trace = langfuse_client.get_trace(id=trace_id) - - initial_langfuse_trace_dict = dict(initial_langfuse_trace) - initial_langfuse_trace_dict.pop("updatedAt") - initial_langfuse_trace_dict.pop("timestamp") - - new_langfuse_trace_dict = dict(new_langfuse_trace) - new_langfuse_trace_dict.pop("updatedAt") - new_langfuse_trace_dict.pop("timestamp") - - assert initial_langfuse_trace_dict == new_langfuse_trace_dict - - -@pytest.mark.skipif( - condition=not os.environ.get("OPENAI_API_KEY", False), - reason="Authentication missing for openai", -) -def test_langfuse_logging_tool_calling(): - litellm.set_verbose = True - - def get_current_weather(location, unit="fahrenheit"): - """Get the current weather in a given location""" - if "tokyo" in location.lower(): - return json.dumps( - {"location": "Tokyo", "temperature": "10", "unit": "celsius"} - ) - elif "san francisco" in location.lower(): - return json.dumps( - {"location": "San Francisco", "temperature": "72", "unit": "fahrenheit"} - ) - elif "paris" in location.lower(): - return json.dumps( - {"location": "Paris", "temperature": "22", "unit": "celsius"} - ) - else: - return json.dumps({"location": location, "temperature": "unknown"}) - - messages = [ - { - "role": "user", - "content": "What's the weather like in San Francisco, Tokyo, and Paris?", - } - ] - tools = [ - { - "type": "function", - "function": { - "name": "get_current_weather", - "description": "Get the current weather in a given location", - "parameters": { - "type": "object", - "properties": { - "location": { - "type": "string", - "description": "The city and state, e.g. San Francisco, CA", - }, - "unit": {"type": "string", "enum": ["celsius", "fahrenheit"]}, - }, - "required": ["location"], - }, - }, - } - ] - - response = litellm.completion( - model="gpt-3.5-turbo-1106", - messages=messages, - tools=tools, - tool_choice="auto", # auto is default, but we'll be explicit - ) - print("\nLLM Response1:\n", response) - response_message = response.choices[0].message - tool_calls = response.choices[0].message.tool_calls - - -# test_langfuse_logging_tool_calling() - - -def get_langfuse_prompt(name: str): - import langfuse - from langfuse import Langfuse - - try: - langfuse = Langfuse( - public_key=os.environ["LANGFUSE_DEV_PUBLIC_KEY"], - secret_key=os.environ["LANGFUSE_DEV_SK_KEY"], - host=os.environ["LANGFUSE_HOST"], - ) - - # Get current production version of a text prompt - prompt = langfuse.get_prompt(name=name) - return prompt - except Exception as e: - raise Exception(f"Error getting prompt: {e}") - - -@pytest.mark.asyncio -@pytest.mark.skip( - reason="local only test, use this to verify if we can send request to litellm proxy server" -) -async def test_make_request(): - response = await litellm.acompletion( - model="openai/llama3", - api_key="sk-1234", - base_url="http://localhost:4000", - messages=[{"role": "user", "content": "Hi 👋 - i'm claude"}], - extra_body={ - "metadata": { - "tags": ["openai"], - "prompt": get_langfuse_prompt("test-chat"), - } - }, - ) From c44e5a3d93e0eed884fa88e64d743025f54aa8fd Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Sat, 22 Jun 2024 13:40:34 -0700 Subject: [PATCH 12/22] testing - use in memory langfuse client cache --- litellm/tests/test_alangfuse.py | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/litellm/tests/test_alangfuse.py b/litellm/tests/test_alangfuse.py index 4e3d42352f7..a074b110bed 100644 --- a/litellm/tests/test_alangfuse.py +++ b/litellm/tests/test_alangfuse.py @@ -4,6 +4,7 @@ import json import logging import os import sys +from typing import Any from unittest.mock import MagicMock, patch logging.basicConfig(level=logging.DEBUG) @@ -19,17 +20,28 @@ import time import pytest +in_memory_langfuse_client: dict[str, Any] = {} + @pytest.fixture def langfuse_client(): import langfuse - langfuse_client = langfuse.Langfuse( - public_key=os.environ["LANGFUSE_PUBLIC_KEY"], - secret_key=os.environ["LANGFUSE_SECRET_KEY"], - host=None, + _langfuse_cache_key = ( + f"{os.environ['LANGFUSE_PUBLIC_KEY']}-{os.environ['LANGFUSE_SECRET_KEY']}" ) - print("NEW LANGFUSE CLIENT") + # use a in memory langfuse client for testing, RAM util on ci/cd gets too high when we init many langfuse clients + if _langfuse_cache_key in in_memory_langfuse_clients: + langfuse_client = in_memory_langfuse_clients[_langfuse_cache_key] + else: + langfuse_client = langfuse.Langfuse( + public_key=os.environ["LANGFUSE_PUBLIC_KEY"], + secret_key=os.environ["LANGFUSE_SECRET_KEY"], + host=None, + ) + in_memory_langfuse_clients[_langfuse_cache_key] = langfuse_client + + print("NEW LANGFUSE CLIENT") with patch( "langfuse.Langfuse", MagicMock(return_value=langfuse_client) From ab38a90be0d3f47a6c096b25a72853088c843bca Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Sat, 22 Jun 2024 13:45:34 -0700 Subject: [PATCH 13/22] fix /audio/speech --- litellm/proxy/_types.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/litellm/proxy/_types.py b/litellm/proxy/_types.py index 8c8059d704c..0883763d1c6 100644 --- a/litellm/proxy/_types.py +++ b/litellm/proxy/_types.py @@ -188,6 +188,9 @@ class LiteLLMRoutes(enum.Enum): # audio transcription "/audio/transcriptions", "/v1/audio/transcriptions", + # audio Speech + "/audio/speech", + "/v1/audio/speech", # moderations "/moderations", "/v1/moderations", From cb828a464a114a9e13633b6d469a6f75f323877a Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Sat, 22 Jun 2024 13:58:09 -0700 Subject: [PATCH 14/22] fix langfuse tests in_memory_langfuse_clients --- litellm/tests/test_alangfuse.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/litellm/tests/test_alangfuse.py b/litellm/tests/test_alangfuse.py index a074b110bed..a70e35f259a 100644 --- a/litellm/tests/test_alangfuse.py +++ b/litellm/tests/test_alangfuse.py @@ -20,8 +20,6 @@ import time import pytest -in_memory_langfuse_client: dict[str, Any] = {} - @pytest.fixture def langfuse_client(): @@ -31,15 +29,15 @@ def langfuse_client(): f"{os.environ['LANGFUSE_PUBLIC_KEY']}-{os.environ['LANGFUSE_SECRET_KEY']}" ) # use a in memory langfuse client for testing, RAM util on ci/cd gets too high when we init many langfuse clients - if _langfuse_cache_key in in_memory_langfuse_clients: - langfuse_client = in_memory_langfuse_clients[_langfuse_cache_key] + if _langfuse_cache_key in litellm.in_memory_llm_clients_cache: + langfuse_client = litellm.in_memory_llm_clients_cache[_langfuse_cache_key] else: langfuse_client = langfuse.Langfuse( public_key=os.environ["LANGFUSE_PUBLIC_KEY"], secret_key=os.environ["LANGFUSE_SECRET_KEY"], host=None, ) - in_memory_langfuse_clients[_langfuse_cache_key] = langfuse_client + litellm.in_memory_llm_clients_cache[_langfuse_cache_key] = langfuse_client print("NEW LANGFUSE CLIENT") From a31a05d45d67866acd123eba54348d4486895148 Mon Sep 17 00:00:00 2001 From: Krrish Dholakia Date: Sat, 22 Jun 2024 14:41:22 -0700 Subject: [PATCH 15/22] feat(dynamic_rate_limiter.py): working e2e --- litellm/__init__.py | 1 + litellm/proxy/_super_secret_config.yaml | 2 + litellm/proxy/hooks/dynamic_rate_limiter.py | 59 +++- litellm/proxy/proxy_server.py | 16 +- litellm/proxy/utils.py | 49 ++- .../tests/test_dynamic_rate_limit_handler.py | 314 +++++++++++++++++- litellm/tests/test_router.py | 3 + 7 files changed, 420 insertions(+), 24 deletions(-) diff --git a/litellm/__init__.py b/litellm/__init__.py index 09bc0ab5ff5..f07ce880928 100644 --- a/litellm/__init__.py +++ b/litellm/__init__.py @@ -737,6 +737,7 @@ from .utils import ( client, exception_type, get_optional_params, + get_response_string, modify_integration, token_counter, create_pretrained_tokenizer, diff --git a/litellm/proxy/_super_secret_config.yaml b/litellm/proxy/_super_secret_config.yaml index ef88f75f613..04a4806c126 100644 --- a/litellm/proxy/_super_secret_config.yaml +++ b/litellm/proxy/_super_secret_config.yaml @@ -30,6 +30,7 @@ model_list: api_key: os.environ/AZURE_API_KEY api_version: 2024-02-15-preview model: azure/chatgpt-v-2 + tpm: 100 model_name: gpt-3.5-turbo - litellm_params: model: anthropic.claude-3-sonnet-20240229-v1:0 @@ -40,6 +41,7 @@ model_list: api_version: 2024-02-15-preview model: azure/chatgpt-v-2 drop_params: True + tpm: 100 model_name: gpt-3.5-turbo - model_name: tts litellm_params: diff --git a/litellm/proxy/hooks/dynamic_rate_limiter.py b/litellm/proxy/hooks/dynamic_rate_limiter.py index c0511e30c82..8b132ff9eef 100644 --- a/litellm/proxy/hooks/dynamic_rate_limiter.py +++ b/litellm/proxy/hooks/dynamic_rate_limiter.py @@ -55,11 +55,21 @@ class DynamicRateLimiterCache: Raises: - Exception, if unable to connect to cache client (if redis caching enabled) """ - dt = get_utc_datetime() - current_minute = dt.strftime("%H-%M") + try: + dt = get_utc_datetime() + current_minute = dt.strftime("%H-%M") - key_name = "{}:{}".format(current_minute, model) - await self.cache.async_set_cache_sadd(key=key_name, value=value, ttl=self.ttl) + key_name = "{}:{}".format(current_minute, model) + await self.cache.async_set_cache_sadd( + key=key_name, value=value, ttl=self.ttl + ) + except Exception as e: + verbose_proxy_logger.error( + "litellm.proxy.hooks.dynamic_rate_limiter.py::async_set_cache_sadd(): Exception occured - {}\n{}".format( + str(e), traceback.format_exc() + ) + ) + raise e class _PROXY_DynamicRateLimitHandler(CustomLogger): @@ -79,7 +89,7 @@ class _PROXY_DynamicRateLimitHandler(CustomLogger): Returns - Tuple[available_tpm, model_tpm, active_projects] - - available_tpm: int or null + - available_tpm: int or null - always 0 or positive. - remaining_model_tpm: int or null. If available tpm is int, then this will be too. - active_projects: int or null """ @@ -108,6 +118,8 @@ class _PROXY_DynamicRateLimitHandler(CustomLogger): else: available_tpm = remaining_model_tpm + if available_tpm is not None and available_tpm < 0: + available_tpm = 0 return available_tpm, remaining_model_tpm, active_projects async def async_pre_call_hook( @@ -150,9 +162,44 @@ class _PROXY_DynamicRateLimitHandler(CustomLogger): elif available_tpm is not None: ## UPDATE CACHE WITH ACTIVE PROJECT asyncio.create_task( - self.internal_usage_cache.async_set_cache_sadd( + self.internal_usage_cache.async_set_cache_sadd( # this is a set model=data["model"], # type: ignore value=[user_api_key_dict.team_id or "default_team"], ) ) return None + + async def async_post_call_success_hook( + self, user_api_key_dict: UserAPIKeyAuth, response + ): + try: + if isinstance(response, ModelResponse): + model_info = self.llm_router.get_model_info( + id=response._hidden_params["model_id"] + ) + assert ( + model_info is not None + ), "Model info for model with id={} is None".format( + response._hidden_params["model_id"] + ) + available_tpm, remaining_model_tpm, active_projects = ( + await self.check_available_tpm(model=model_info["model_name"]) + ) + response._hidden_params["additional_headers"] = { + "x-litellm-model_group": model_info["model_name"], + "x-ratelimit-remaining-litellm-project-tokens": available_tpm, + "x-ratelimit-remaining-model-tokens": remaining_model_tpm, + "x-ratelimit-current-active-projects": active_projects, + } + + return response + return await super().async_post_call_success_hook( + user_api_key_dict, response + ) + except Exception as e: + verbose_proxy_logger.error( + "litellm.proxy.hooks.dynamic_rate_limiter.py::async_post_call_success_hook(): Exception occured - {}\n{}".format( + str(e), traceback.format_exc() + ) + ) + return response diff --git a/litellm/proxy/proxy_server.py b/litellm/proxy/proxy_server.py index b2eaea8f36a..1e51980e60b 100644 --- a/litellm/proxy/proxy_server.py +++ b/litellm/proxy/proxy_server.py @@ -433,6 +433,7 @@ def get_custom_headers( version: Optional[str] = None, model_region: Optional[str] = None, fastest_response_batch_completion: Optional[bool] = None, + **kwargs, ) -> dict: exclude_values = {"", None} headers = { @@ -448,6 +449,7 @@ def get_custom_headers( if fastest_response_batch_completion is not None else None ), + **{k: str(v) for k, v in kwargs.items()}, } try: return { @@ -3063,6 +3065,14 @@ async def chat_completion( headers=custom_headers, ) + ### CALL HOOKS ### - modify outgoing data + response = await proxy_logging_obj.post_call_success_hook( + user_api_key_dict=user_api_key_dict, response=response + ) + + hidden_params = getattr(response, "_hidden_params", {}) or {} + additional_headers: dict = hidden_params.get("additional_headers", {}) or {} + fastapi_response.headers.update( get_custom_headers( user_api_key_dict=user_api_key_dict, @@ -3072,14 +3082,10 @@ async def chat_completion( version=version, model_region=getattr(user_api_key_dict, "allowed_model_region", ""), fastest_response_batch_completion=fastest_response_batch_completion, + **additional_headers, ) ) - ### CALL HOOKS ### - modify outgoing data - response = await proxy_logging_obj.post_call_success_hook( - user_api_key_dict=user_api_key_dict, response=response - ) - return response except RejectedRequestError as e: _data = e.request_data diff --git a/litellm/proxy/utils.py b/litellm/proxy/utils.py index 5acba95c2ef..a242fca6639 100644 --- a/litellm/proxy/utils.py +++ b/litellm/proxy/utils.py @@ -584,8 +584,15 @@ class ProxyLogging: for callback in litellm.callbacks: try: - if isinstance(callback, CustomLogger): - await callback.async_post_call_failure_hook( + _callback: Optional[CustomLogger] = None + if isinstance(callback, str): + _callback = litellm.litellm_core_utils.litellm_logging.get_custom_logger_compatible_class( + callback + ) + else: + _callback = callback # type: ignore + if _callback is not None and isinstance(_callback, CustomLogger): + await _callback.async_post_call_failure_hook( user_api_key_dict=user_api_key_dict, original_exception=original_exception, ) @@ -606,8 +613,15 @@ class ProxyLogging: """ for callback in litellm.callbacks: try: - if isinstance(callback, CustomLogger): - await callback.async_post_call_success_hook( + _callback: Optional[CustomLogger] = None + if isinstance(callback, str): + _callback = litellm.litellm_core_utils.litellm_logging.get_custom_logger_compatible_class( + callback + ) + else: + _callback = callback # type: ignore + if _callback is not None and isinstance(_callback, CustomLogger): + await _callback.async_post_call_success_hook( user_api_key_dict=user_api_key_dict, response=response ) except Exception as e: @@ -625,14 +639,25 @@ class ProxyLogging: Covers: 1. /chat/completions """ - for callback in litellm.callbacks: - try: - if isinstance(callback, CustomLogger): - await callback.async_post_call_streaming_hook( - user_api_key_dict=user_api_key_dict, response=response - ) - except Exception as e: - raise e + response_str: Optional[str] = None + if isinstance(response, ModelResponse): + response_str = litellm.get_response_string(response_obj=response) + if response_str is not None: + for callback in litellm.callbacks: + try: + _callback: Optional[CustomLogger] = None + if isinstance(callback, str): + _callback = litellm.litellm_core_utils.litellm_logging.get_custom_logger_compatible_class( + callback + ) + else: + _callback = callback # type: ignore + if _callback is not None and isinstance(_callback, CustomLogger): + await _callback.async_post_call_streaming_hook( + user_api_key_dict=user_api_key_dict, response=response_str + ) + except Exception as e: + raise e return response async def post_call_streaming_hook( diff --git a/litellm/tests/test_dynamic_rate_limit_handler.py b/litellm/tests/test_dynamic_rate_limit_handler.py index df9e2588106..c3fcca6a6be 100644 --- a/litellm/tests/test_dynamic_rate_limit_handler.py +++ b/litellm/tests/test_dynamic_rate_limit_handler.py @@ -22,6 +22,7 @@ import pytest import litellm from litellm import DualCache, Router +from litellm.proxy._types import UserAPIKeyAuth from litellm.proxy.hooks.dynamic_rate_limiter import ( _PROXY_DynamicRateLimitHandler as DynamicRateLimitHandler, ) @@ -74,6 +75,11 @@ def mock_response() -> litellm.ModelResponse: ) +@pytest.fixture +def user_api_key_auth() -> UserAPIKeyAuth: + return UserAPIKeyAuth() + + @pytest.mark.parametrize("num_projects", [1, 2, 100]) @pytest.mark.asyncio async def test_available_tpm(num_projects, dynamic_rate_limit_handler): @@ -112,6 +118,62 @@ async def test_available_tpm(num_projects, dynamic_rate_limit_handler): assert availability == expected_availability +@pytest.mark.asyncio +async def test_rate_limit_raised(dynamic_rate_limit_handler, user_api_key_auth): + """ + Unit test. Tests if rate limit error raised when quota exhausted. + """ + from fastapi import HTTPException + + model = "my-fake-model" + ## SET CACHE W/ ACTIVE PROJECTS + projects = [str(uuid.uuid4())] + + await dynamic_rate_limit_handler.internal_usage_cache.async_set_cache_sadd( + model=model, value=projects + ) + + model_tpm = 0 + llm_router = Router( + model_list=[ + { + "model_name": model, + "litellm_params": { + "model": "gpt-3.5-turbo", + "api_key": "my-key", + "api_base": "my-base", + "tpm": model_tpm, + }, + } + ] + ) + dynamic_rate_limit_handler.update_variables(llm_router=llm_router) + + ## CHECK AVAILABLE TPM PER PROJECT + + availability, _, _ = await dynamic_rate_limit_handler.check_available_tpm( + model=model + ) + + expected_availability = int(model_tpm / 1) + + assert availability == expected_availability + + ## CHECK if exception raised + + try: + await dynamic_rate_limit_handler.async_pre_call_hook( + user_api_key_dict=user_api_key_auth, + cache=DualCache(), + data={"model": model}, + call_type="completion", + ) + pytest.fail("Expected this to raise HTTPexception") + except HTTPException as e: + assert e.status_code == 429 # check if rate limit error raised + pass + + @pytest.mark.asyncio async def test_base_case(dynamic_rate_limit_handler, mock_response): """ @@ -122,9 +184,12 @@ async def test_base_case(dynamic_rate_limit_handler, mock_response): = allow request to go through - update token usage - exhaust all tpm with just 1 project + - assert ratelimiterror raised at 100%+1 tpm """ model = "my-fake-model" + ## model tpm - 50 model_tpm = 50 + ## tpm per request - 10 setattr( mock_response, "usage", @@ -148,7 +213,144 @@ async def test_base_case(dynamic_rate_limit_handler, mock_response): dynamic_rate_limit_handler.update_variables(llm_router=llm_router) prev_availability: Optional[int] = None + allowed_fails = 1 for _ in range(5): + try: + # check availability + availability, _, _ = await dynamic_rate_limit_handler.check_available_tpm( + model=model + ) + + ## assert availability updated + if prev_availability is not None and availability is not None: + assert availability == prev_availability - 10 + + print( + "prev_availability={}, availability={}".format( + prev_availability, availability + ) + ) + + prev_availability = availability + + # make call + await llm_router.acompletion( + model=model, messages=[{"role": "user", "content": "hey!"}] + ) + + await asyncio.sleep(3) + except Exception: + if allowed_fails > 0: + allowed_fails -= 1 + else: + raise + + +@pytest.mark.asyncio +async def test_update_cache( + dynamic_rate_limit_handler, mock_response, user_api_key_auth +): + """ + Check if active project correctly updated + """ + model = "my-fake-model" + model_tpm = 50 + + llm_router = Router( + model_list=[ + { + "model_name": model, + "litellm_params": { + "model": "gpt-3.5-turbo", + "api_key": "my-key", + "api_base": "my-base", + "tpm": model_tpm, + "mock_response": mock_response, + }, + } + ] + ) + dynamic_rate_limit_handler.update_variables(llm_router=llm_router) + + ## INITIAL ACTIVE PROJECTS - ASSERT NONE + _, _, active_projects = await dynamic_rate_limit_handler.check_available_tpm( + model=model + ) + + assert active_projects is None + + ## MAKE CALL + await dynamic_rate_limit_handler.async_pre_call_hook( + user_api_key_dict=user_api_key_auth, + cache=DualCache(), + data={"model": model}, + call_type="completion", + ) + + await asyncio.sleep(2) + ## INITIAL ACTIVE PROJECTS - ASSERT 1 + _, _, active_projects = await dynamic_rate_limit_handler.check_available_tpm( + model=model + ) + + assert active_projects == 1 + + +@pytest.mark.parametrize("num_projects", [2]) +@pytest.mark.asyncio +async def test_multiple_projects( + dynamic_rate_limit_handler, mock_response, num_projects +): + """ + If 2 active project + + it should split 50% each + + - assert available tpm is 0 after 50%+1 tpm calls + """ + model = "my-fake-model" + model_tpm = 50 + total_tokens_per_call = 10 + step_tokens_per_call_per_project = total_tokens_per_call / num_projects + + available_tpm_per_project = int(model_tpm / num_projects) + + ## SET CACHE W/ ACTIVE PROJECTS + projects = [str(uuid.uuid4()) for _ in range(num_projects)] + await dynamic_rate_limit_handler.internal_usage_cache.async_set_cache_sadd( + model=model, value=projects + ) + + expected_runs = int(available_tpm_per_project / step_tokens_per_call_per_project) + + setattr( + mock_response, + "usage", + litellm.Usage( + prompt_tokens=5, completion_tokens=5, total_tokens=total_tokens_per_call + ), + ) + + llm_router = Router( + model_list=[ + { + "model_name": model, + "litellm_params": { + "model": "gpt-3.5-turbo", + "api_key": "my-key", + "api_base": "my-base", + "tpm": model_tpm, + "mock_response": mock_response, + }, + } + ] + ) + dynamic_rate_limit_handler.update_variables(llm_router=llm_router) + + prev_availability: Optional[int] = None + + print("expected_runs: {}".format(expected_runs)) + for i in range(expected_runs + 1): # check availability availability, _, _ = await dynamic_rate_limit_handler.check_available_tpm( model=model @@ -156,7 +358,15 @@ async def test_base_case(dynamic_rate_limit_handler, mock_response): ## assert availability updated if prev_availability is not None and availability is not None: - assert availability == prev_availability - 10 + assert ( + availability == prev_availability - step_tokens_per_call_per_project + ), "Current Availability: Got={}, Expected={}, Step={}, Tokens per step={}, Initial model tpm={}".format( + availability, + prev_availability - 10, + i, + step_tokens_per_call_per_project, + model_tpm, + ) print( "prev_availability={}, availability={}".format( @@ -172,3 +382,105 @@ async def test_base_case(dynamic_rate_limit_handler, mock_response): ) await asyncio.sleep(3) + + # check availability + availability, _, _ = await dynamic_rate_limit_handler.check_available_tpm( + model=model + ) + assert availability == 0 + + +@pytest.mark.parametrize("num_projects", [2]) +@pytest.mark.asyncio +async def test_multiple_projects_e2e( + dynamic_rate_limit_handler, mock_response, num_projects +): + """ + 2 parallel calls with different keys, same model + + If 2 active project + + it should split 50% each + + - assert available tpm is 0 after 50%+1 tpm calls + """ + model = "my-fake-model" + model_tpm = 50 + total_tokens_per_call = 10 + step_tokens_per_call_per_project = total_tokens_per_call / num_projects + + available_tpm_per_project = int(model_tpm / num_projects) + + ## SET CACHE W/ ACTIVE PROJECTS + projects = [str(uuid.uuid4()) for _ in range(num_projects)] + await dynamic_rate_limit_handler.internal_usage_cache.async_set_cache_sadd( + model=model, value=projects + ) + + expected_runs = int(available_tpm_per_project / step_tokens_per_call_per_project) + + setattr( + mock_response, + "usage", + litellm.Usage( + prompt_tokens=5, completion_tokens=5, total_tokens=total_tokens_per_call + ), + ) + + llm_router = Router( + model_list=[ + { + "model_name": model, + "litellm_params": { + "model": "gpt-3.5-turbo", + "api_key": "my-key", + "api_base": "my-base", + "tpm": model_tpm, + "mock_response": mock_response, + }, + } + ] + ) + dynamic_rate_limit_handler.update_variables(llm_router=llm_router) + + prev_availability: Optional[int] = None + + print("expected_runs: {}".format(expected_runs)) + for i in range(expected_runs + 1): + # check availability + availability, _, _ = await dynamic_rate_limit_handler.check_available_tpm( + model=model + ) + + ## assert availability updated + if prev_availability is not None and availability is not None: + assert ( + availability == prev_availability - step_tokens_per_call_per_project + ), "Current Availability: Got={}, Expected={}, Step={}, Tokens per step={}, Initial model tpm={}".format( + availability, + prev_availability - 10, + i, + step_tokens_per_call_per_project, + model_tpm, + ) + + print( + "prev_availability={}, availability={}".format( + prev_availability, availability + ) + ) + + prev_availability = availability + + # make call + await llm_router.acompletion( + model=model, messages=[{"role": "user", "content": "hey!"}] + ) + + await asyncio.sleep(3) + + # check availability + availability, _, _ = await dynamic_rate_limit_handler.check_available_tpm( + model=model + ) + assert availability == 0 diff --git a/litellm/tests/test_router.py b/litellm/tests/test_router.py index 55cf250e745..2e881432736 100644 --- a/litellm/tests/test_router.py +++ b/litellm/tests/test_router.py @@ -1768,6 +1768,9 @@ def mock_response() -> litellm.ModelResponse: @pytest.mark.asyncio async def test_router_model_usage(mock_response): + """ + Test if tracking used model tpm works as expected + """ model = "my-fake-model" model_tpm = 100 setattr( From fc4e900a232d206429da61d55b2fc4a09275243a Mon Sep 17 00:00:00 2001 From: Krrish Dholakia Date: Sat, 22 Jun 2024 15:26:58 -0700 Subject: [PATCH 16/22] docs(team_budgets.md): update docs with script for testing dynamic rate limiting --- docs/my-website/docs/proxy/team_budgets.md | 57 ++++++++++++++++- litellm/proxy/_new_secret_config.yaml | 71 +++------------------- 2 files changed, 65 insertions(+), 63 deletions(-) diff --git a/docs/my-website/docs/proxy/team_budgets.md b/docs/my-website/docs/proxy/team_budgets.md index d7f6d7fdc9c..f6b7c22824f 100644 --- a/docs/my-website/docs/proxy/team_budgets.md +++ b/docs/my-website/docs/proxy/team_budgets.md @@ -167,8 +167,12 @@ model_list: mock_response: hello-world tpm: 60 -general_settings: - callbacks: ["dynamic_rate_limiting"] +litellm_settings: + callbacks: ["dynamic_rate_limiter"] + +general_settings: + master_key: sk-1234 # OR set `LITELLM_MASTER_KEY=".."` in your .env + database_url: postgres://.. # OR set `DATABASE_URL=".."` in your .env ``` 2. Start proxy @@ -186,6 +190,55 @@ litellm --config /path/to/config.yaml - Mock response returns 30 total tokens / request - Each team will only be able to make 1 request per minute """ +import requests +from openai import OpenAI, RateLimitError + +def create_key(api_key: str, base_url: str): + response = requests.post( + url="{}/key/generate".format(base_url), + json={}, + headers={ + "Authorization": "Bearer {}".format(api_key) + } + ) + + _response = response.json() + + print(f"_response: {_response}") + return _response["key"] + +key_1 = create_key(api_key="sk-1234", base_url="http://0.0.0.0:4000") +key_2 = create_key(api_key="sk-1234", base_url="http://0.0.0.0:4000") + +# call proxy with key 1 - works +openai_client_1 = OpenAI(api_key=key_1, base_url="http://0.0.0.0:4000") + +response = openai_client_1.chat.completions.with_raw_response.create( + model="my-fake-model", messages=[{"role": "user", "content": "Hello world!"}], +) + +print("Headers for call - {}".format(response.headers)) +_response = response.parse() +print("Total tokens for call - {}".format(_response.usage.total_tokens)) + + +# call proxy with key 2 - works +openai_client_2 = OpenAI(api_key=key_1, base_url="http://0.0.0.0:4000") + +response = openai_client_2.chat.completions.with_raw_response.create( + model="my-fake-model", messages=[{"role": "user", "content": "Hello world!"}], +) + +print("Headers for call - {}".format(response.headers)) +_response = response.parse() +print("Total tokens for call - {}".format(_response.usage.total_tokens)) +# call proxy with key 2 - fails +try: + openai_client_2.chat.completions.with_raw_response.create(model="my-fake-model", messages=[{"role": "user", "content": "Hey, how's it going?"}]) + raise Exception("This should have failed!") +except RateLimitError as e: + print("This was rate limited b/c - {}".format(str(e))) + ``` \ No newline at end of file diff --git a/litellm/proxy/_new_secret_config.yaml b/litellm/proxy/_new_secret_config.yaml index 866ca0ab0a8..01f09ca02b1 100644 --- a/litellm/proxy/_new_secret_config.yaml +++ b/litellm/proxy/_new_secret_config.yaml @@ -1,61 +1,10 @@ -environment_variables: - LANGFUSE_PUBLIC_KEY: Q6K8MQN6L7sPYSJiFKM9eNrETOx6V/FxVPup4FqdKsZK1hyR4gyanlQ2KHLg5D5afng99uIt0JCEQ2jiKF9UxFvtnb4BbJ4qpeceH+iK8v/bdg== - LANGFUSE_SECRET_KEY: 5xQ7KMa6YMLsm+H/Pf1VmlqWq1NON5IoCxABhkUBeSck7ftsj2CmpkL2ZwrxwrktgiTUBH+3gJYBX+XBk7lqOOUpvmiLjol/E5lCqq0M1CqLWA== - SLACK_WEBHOOK_URL: RJjhS0Hhz0/s07sCIf1OTXmTGodpK9L2K9p953Z+fOX0l2SkPFT6mB9+yIrLufmlwEaku5NNEBKy//+AG01yOd+7wV1GhK65vfj3B/gTN8t5cuVnR4vFxKY5Rx4eSGLtzyAs+aIBTp4GoNXDIjroCqfCjPkItEZWCg== -general_settings: - alerting: - - slack - alerting_threshold: 300 - database_connection_pool_limit: 100 - database_connection_timeout: 60 - disable_master_key_return: true - health_check_interval: 300 - proxy_batch_write_at: 60 - ui_access_mode: all - # master_key: sk-1234 -litellm_settings: - allowed_fails: 3 - failure_callback: - - prometheus - num_retries: 3 - service_callback: - - prometheus_system - success_callback: - - langfuse - - prometheus - - langsmith -model_list: -- litellm_params: - model: gpt-3.5-turbo - model_name: gpt-3.5-turbo -- litellm_params: - api_base: https://openai-function-calling-workers.tasslexyz.workers.dev/ - api_key: my-fake-key - model: openai/my-fake-model - stream_timeout: 0.001 - model_name: fake-openai-endpoint -- litellm_params: - api_base: https://openai-function-calling-workers.tasslexyz.workers.dev/ - api_key: my-fake-key - model: openai/my-fake-model-2 - stream_timeout: 0.001 - model_name: fake-openai-endpoint -- litellm_params: - api_base: os.environ/AZURE_API_BASE - api_key: os.environ/AZURE_API_KEY - api_version: 2023-07-01-preview - model: azure/chatgpt-v-2 - stream_timeout: 0.001 - model_name: azure-gpt-3.5 -- litellm_params: - api_key: os.environ/OPENAI_API_KEY - model: text-embedding-ada-002 - model_name: text-embedding-ada-002 -- litellm_params: - model: text-completion-openai/gpt-3.5-turbo-instruct - model_name: gpt-instruct -router_settings: - enable_pre_call_checks: true - redis_host: os.environ/REDIS_HOST - redis_password: os.environ/REDIS_PASSWORD - redis_port: os.environ/REDIS_PORT +model_list: + - model_name: my-fake-model + litellm_params: + model: gpt-3.5-turbo + api_key: my-fake-key + mock_response: hello-world + tpm: 60 + +litellm_settings: + callbacks: ["dynamic_rate_limiter"] \ No newline at end of file From bae73771285ee767ab2210499fa1f123bd9fb97a Mon Sep 17 00:00:00 2001 From: Krrish Dholakia Date: Sat, 22 Jun 2024 15:42:05 -0700 Subject: [PATCH 17/22] docs(team_budgets.md): fix script / --- docs/my-website/docs/proxy/team_budgets.md | 21 ++++++++++++++++----- litellm/proxy/hooks/dynamic_rate_limiter.py | 6 +++--- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/docs/my-website/docs/proxy/team_budgets.md b/docs/my-website/docs/proxy/team_budgets.md index f6b7c22824f..9ab0c07866a 100644 --- a/docs/my-website/docs/proxy/team_budgets.md +++ b/docs/my-website/docs/proxy/team_budgets.md @@ -154,7 +154,9 @@ litellm_remaining_team_budget_metric{team_alias="QA Prod Bot",team_id="de35b29e- ### Dynamic TPM Allocation -Prevent teams from gobbling too much quota. +Prevent projects from gobbling too much quota. + +Dynamically allocate TPM quota to api keys, based on active keys in that minute. 1. Setup config.yaml @@ -190,6 +192,12 @@ litellm --config /path/to/config.yaml - Mock response returns 30 total tokens / request - Each team will only be able to make 1 request per minute """ +""" +- Run 2 concurrent teams calling same model +- model has 60 TPM +- Mock response returns 30 total tokens / request +- Each team will only be able to make 1 request per minute +""" import requests from openai import OpenAI, RateLimitError @@ -204,7 +212,6 @@ def create_key(api_key: str, base_url: str): _response = response.json() - print(f"_response: {_response}") return _response["key"] key_1 = create_key(api_key="sk-1234", base_url="http://0.0.0.0:4000") @@ -217,19 +224,19 @@ response = openai_client_1.chat.completions.with_raw_response.create( model="my-fake-model", messages=[{"role": "user", "content": "Hello world!"}], ) -print("Headers for call - {}".format(response.headers)) +print("Headers for call 1 - {}".format(response.headers)) _response = response.parse() print("Total tokens for call - {}".format(_response.usage.total_tokens)) # call proxy with key 2 - works -openai_client_2 = OpenAI(api_key=key_1, base_url="http://0.0.0.0:4000") +openai_client_2 = OpenAI(api_key=key_2, base_url="http://0.0.0.0:4000") response = openai_client_2.chat.completions.with_raw_response.create( model="my-fake-model", messages=[{"role": "user", "content": "Hello world!"}], ) -print("Headers for call - {}".format(response.headers)) +print("Headers for call 2 - {}".format(response.headers)) _response = response.parse() print("Total tokens for call - {}".format(_response.usage.total_tokens)) # call proxy with key 2 - fails @@ -239,6 +246,10 @@ try: except RateLimitError as e: print("This was rate limited b/c - {}".format(str(e))) +``` +**Expected Response** +``` +This was rate limited b/c - Error code: 429 - {'error': {'message': {'error': 'Key= over available TPM=0. Model TPM=0, Active keys=2'}, 'type': 'None', 'param': 'None', 'code': 429}} ``` \ No newline at end of file diff --git a/litellm/proxy/hooks/dynamic_rate_limiter.py b/litellm/proxy/hooks/dynamic_rate_limiter.py index 8b132ff9eef..95f0ccc13e0 100644 --- a/litellm/proxy/hooks/dynamic_rate_limiter.py +++ b/litellm/proxy/hooks/dynamic_rate_limiter.py @@ -151,8 +151,8 @@ class _PROXY_DynamicRateLimitHandler(CustomLogger): raise HTTPException( status_code=429, detail={ - "error": "Team={} over available TPM={}. Model TPM={}, Active teams={}".format( - user_api_key_dict.team_id, + "error": "Key={} over available TPM={}. Model TPM={}, Active keys={}".format( + user_api_key_dict.api_key, available_tpm, model_tpm, active_projects, @@ -164,7 +164,7 @@ class _PROXY_DynamicRateLimitHandler(CustomLogger): asyncio.create_task( self.internal_usage_cache.async_set_cache_sadd( # this is a set model=data["model"], # type: ignore - value=[user_api_key_dict.team_id or "default_team"], + value=[user_api_key_dict.token or "default_key"], ) ) return None From c4b1540ce067f93f5546000731e2cf2dae91a143 Mon Sep 17 00:00:00 2001 From: Krrish Dholakia Date: Sat, 22 Jun 2024 15:45:52 -0700 Subject: [PATCH 18/22] fix(utils.py): support streamingchoices in 'get_response_string --- litellm/utils.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/litellm/utils.py b/litellm/utils.py index b734ae465ad..2b9660bfc54 100644 --- a/litellm/utils.py +++ b/litellm/utils.py @@ -3896,12 +3896,16 @@ def get_formatted_prompt( def get_response_string(response_obj: ModelResponse) -> str: - _choices: List[Choices] = response_obj.choices # type: ignore + _choices: List[Union[Choices, StreamingChoices]] = response_obj.choices response_str = "" for choice in _choices: - if choice.message.content is not None: - response_str += choice.message.content + if isinstance(choice, Choices): + if choice.message.content is not None: + response_str += choice.message.content + elif isinstance(choice, StreamingChoices): + if choice.delta.content is not None: + response_str += choice.delta.content return response_str From 4fc8efd640c5bba33b2b6604a2772a6716215fd9 Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Sat, 22 Jun 2024 18:00:40 -0700 Subject: [PATCH 19/22] =?UTF-8?q?bump:=20version=201.40.23=20=E2=86=92=201?= =?UTF-8?q?.40.24?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pyproject.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index f590b9f2199..3254ae2e2d0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "litellm" -version = "1.40.23" +version = "1.40.24" description = "Library to easily interface with LLM API providers" authors = ["BerriAI"] license = "MIT" @@ -90,7 +90,7 @@ requires = ["poetry-core", "wheel"] build-backend = "poetry.core.masonry.api" [tool.commitizen] -version = "1.40.23" +version = "1.40.24" version_files = [ "pyproject.toml:^version" ] From 73254987dac2473256fec4010d6fd79a16d0c55e Mon Sep 17 00:00:00 2001 From: Krrish Dholakia Date: Sat, 22 Jun 2024 20:20:39 -0700 Subject: [PATCH 20/22] fix(vertex_httpx.py): ignore vertex finish reason - wait for stream to end Fixes https://github.com/BerriAI/litellm/issues/4339 --- litellm/llms/vertex_httpx.py | 6 ++++-- litellm/tests/test_streaming.py | 18 +++++++++++++----- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/litellm/llms/vertex_httpx.py b/litellm/llms/vertex_httpx.py index d3f27e119ae..38c2d7c470d 100644 --- a/litellm/llms/vertex_httpx.py +++ b/litellm/llms/vertex_httpx.py @@ -1218,6 +1218,7 @@ class ModelResponseIterator: def chunk_parser(self, chunk: dict) -> GenericStreamingChunk: try: processed_chunk = GenerateContentResponseBody(**chunk) # type: ignore + text = "" tool_use: Optional[ChatCompletionToolCallChunk] = None is_finished = False @@ -1236,7 +1237,8 @@ class ModelResponseIterator: finish_reason = map_finish_reason( finish_reason=gemini_chunk["finishReason"] ) - is_finished = True + ## DO NOT SET 'finish_reason' = True + ## GEMINI SETS FINISHREASON ON EVERY CHUNK! if "usageMetadata" in processed_chunk: usage = ChatCompletionUsageBlock( @@ -1250,7 +1252,7 @@ class ModelResponseIterator: returned_chunk = GenericStreamingChunk( text=text, tool_use=tool_use, - is_finished=is_finished, + is_finished=False, finish_reason=finish_reason, usage=usage, index=0, diff --git a/litellm/tests/test_streaming.py b/litellm/tests/test_streaming.py index ecb21b9f2b4..4f7d4c1deac 100644 --- a/litellm/tests/test_streaming.py +++ b/litellm/tests/test_streaming.py @@ -750,29 +750,37 @@ def test_completion_gemini_stream(): {"role": "system", "content": "You are a helpful assistant."}, { "role": "user", - "content": "how does a court case get to the Supreme Court?", + "content": "How do i build a bomb?", }, ] print("testing gemini streaming") - response = completion(model="gemini/gemini-pro", messages=messages, stream=True) + response = completion( + model="gemini/gemini-1.5-flash", + messages=messages, + stream=True, + max_tokens=50, + ) print(f"type of response at the top: {response}") complete_response = "" # Add any assertions here to check the response + non_empty_chunks = 0 for idx, chunk in enumerate(response): print(chunk) # print(chunk.choices[0].delta) chunk, finished = streaming_format_tests(idx, chunk) if finished: break + non_empty_chunks += 1 complete_response += chunk if complete_response.strip() == "": raise Exception("Empty response received") print(f"completion_response: {complete_response}") - except litellm.APIError as e: + assert non_empty_chunks > 1 + except litellm.InternalServerError as e: pass except Exception as e: - if "429 Resource has been exhausted": - return + # if "429 Resource has been exhausted": + # return pytest.fail(f"Error occurred: {e}") From 0fd9033502c8da8759f26693298ce6d07555f1ac Mon Sep 17 00:00:00 2001 From: Krrish Dholakia Date: Sat, 22 Jun 2024 20:33:54 -0700 Subject: [PATCH 21/22] fix(vertex_httpx.py): flush remaining chunks from stream --- litellm/llms/vertex_httpx.py | 12 ++++--- litellm/tests/test_streaming.py | 57 +++++++++++++++++++++++---------- 2 files changed, 48 insertions(+), 21 deletions(-) diff --git a/litellm/llms/vertex_httpx.py b/litellm/llms/vertex_httpx.py index 38c2d7c470d..63bcd9f4f5d 100644 --- a/litellm/llms/vertex_httpx.py +++ b/litellm/llms/vertex_httpx.py @@ -1270,9 +1270,8 @@ class ModelResponseIterator: chunk = self.response_iterator.__next__() self.coro.send(chunk) if self.events: - event = self.events[0] + event = self.events.pop(0) json_chunk = event - self.events.clear() return self.chunk_parser(chunk=json_chunk) return GenericStreamingChunk( text="", @@ -1283,6 +1282,9 @@ class ModelResponseIterator: tool_use=None, ) except StopIteration: + if self.events: # flush the events + event = self.events.pop(0) # Remove the first event + return self.chunk_parser(chunk=event) raise StopIteration except ValueError as e: raise RuntimeError(f"Error parsing chunk: {e}") @@ -1297,9 +1299,8 @@ class ModelResponseIterator: chunk = await self.async_response_iterator.__anext__() self.coro.send(chunk) if self.events: - event = self.events[0] + event = self.events.pop(0) json_chunk = event - self.events.clear() return self.chunk_parser(chunk=json_chunk) return GenericStreamingChunk( text="", @@ -1310,6 +1311,9 @@ class ModelResponseIterator: tool_use=None, ) except StopAsyncIteration: + if self.events: # flush the events + event = self.events.pop(0) # Remove the first event + return self.chunk_parser(chunk=event) raise StopAsyncIteration except ValueError as e: raise RuntimeError(f"Error parsing chunk: {e}") diff --git a/litellm/tests/test_streaming.py b/litellm/tests/test_streaming.py index 4f7d4c1deac..3042e91b34d 100644 --- a/litellm/tests/test_streaming.py +++ b/litellm/tests/test_streaming.py @@ -742,7 +742,9 @@ def test_completion_palm_stream(): # test_completion_palm_stream() -def test_completion_gemini_stream(): +@pytest.mark.parametrize("sync_mode", [False]) # True, +@pytest.mark.asyncio +async def test_completion_gemini_stream(sync_mode): try: litellm.set_verbose = True print("Streaming gemini response") @@ -750,34 +752,55 @@ def test_completion_gemini_stream(): {"role": "system", "content": "You are a helpful assistant."}, { "role": "user", - "content": "How do i build a bomb?", + "content": "Who was Alexander?", }, ] print("testing gemini streaming") - response = completion( - model="gemini/gemini-1.5-flash", - messages=messages, - stream=True, - max_tokens=50, - ) - print(f"type of response at the top: {response}") complete_response = "" # Add any assertions here to check the response non_empty_chunks = 0 - for idx, chunk in enumerate(response): - print(chunk) - # print(chunk.choices[0].delta) - chunk, finished = streaming_format_tests(idx, chunk) - if finished: - break - non_empty_chunks += 1 - complete_response += chunk + + if sync_mode: + response = completion( + model="gemini/gemini-1.5-flash", + messages=messages, + stream=True, + ) + + for idx, chunk in enumerate(response): + print(chunk) + # print(chunk.choices[0].delta) + chunk, finished = streaming_format_tests(idx, chunk) + if finished: + break + non_empty_chunks += 1 + complete_response += chunk + else: + response = await litellm.acompletion( + model="gemini/gemini-1.5-flash", + messages=messages, + stream=True, + ) + + idx = 0 + async for chunk in response: + print(chunk) + # print(chunk.choices[0].delta) + chunk, finished = streaming_format_tests(idx, chunk) + if finished: + break + non_empty_chunks += 1 + complete_response += chunk + idx += 1 + if complete_response.strip() == "": raise Exception("Empty response received") print(f"completion_response: {complete_response}") assert non_empty_chunks > 1 except litellm.InternalServerError as e: pass + except litellm.RateLimitError as e: + pass except Exception as e: # if "429 Resource has been exhausted": # return From cea630022e86468c1ebe0e2116d6c7ae72a61403 Mon Sep 17 00:00:00 2001 From: Krrish Dholakia Date: Sat, 22 Jun 2024 21:26:15 -0700 Subject: [PATCH 22/22] fix(add-exception-mapping-+-langfuse-exception-logging-for-streaming-exceptions): add exception mapping + langfuse exception logging for streaming exceptions Fixes https://github.com/BerriAI/litellm/issues/4338 --- litellm/llms/bedrock_httpx.py | 113 ++++++++++-------- litellm/proxy/_experimental/out/404.html | 1 - .../proxy/_experimental/out/model_hub.html | 1 - .../proxy/_experimental/out/onboarding.html | 1 - litellm/proxy/_new_secret_config.yaml | 10 +- litellm/proxy/proxy_server.py | 5 +- litellm/utils.py | 26 +++- 7 files changed, 89 insertions(+), 68 deletions(-) delete mode 100644 litellm/proxy/_experimental/out/404.html delete mode 100644 litellm/proxy/_experimental/out/model_hub.html delete mode 100644 litellm/proxy/_experimental/out/onboarding.html diff --git a/litellm/llms/bedrock_httpx.py b/litellm/llms/bedrock_httpx.py index 510bf7c7c67..84ab10907cc 100644 --- a/litellm/llms/bedrock_httpx.py +++ b/litellm/llms/bedrock_httpx.py @@ -1,63 +1,64 @@ # What is this? ## Initial implementation of calling bedrock via httpx client (allows for async calls). ## V1 - covers cohere + anthropic claude-3 support -from functools import partial -import os, types +import copy import json -from enum import Enum -import requests, copy # type: ignore +import os import time +import types +import urllib.parse +import uuid +from enum import Enum +from functools import partial from typing import ( + Any, + AsyncIterator, Callable, - Optional, + Iterator, List, Literal, - Union, - Any, - TypedDict, + Optional, Tuple, - Iterator, - AsyncIterator, -) -from litellm.utils import ( - ModelResponse, - Usage, - CustomStreamWrapper, - get_secret, + TypedDict, + Union, ) + +import httpx # type: ignore +import requests # type: ignore + +import litellm +from litellm.caching import DualCache from litellm.litellm_core_utils.core_helpers import map_finish_reason from litellm.litellm_core_utils.litellm_logging import Logging -from litellm.types.utils import Message, Choices -import litellm, uuid -from .prompt_templates.factory import ( - prompt_factory, - custom_prompt, - cohere_message_pt, - construct_tool_use_system_prompt, - extract_between_tags, - parse_xml_params, - contains_tag, - _bedrock_converse_messages_pt, - _bedrock_tools_pt, -) from litellm.llms.custom_httpx.http_handler import ( AsyncHTTPHandler, HTTPHandler, _get_async_httpx_client, _get_httpx_client, ) -from .base import BaseLLM -import httpx # type: ignore -from .bedrock import BedrockError, convert_messages_to_prompt, ModelResponseIterator from litellm.types.llms.bedrock import * -import urllib.parse from litellm.types.llms.openai import ( + ChatCompletionDeltaChunk, ChatCompletionResponseMessage, ChatCompletionToolCallChunk, ChatCompletionToolCallFunctionChunk, - ChatCompletionDeltaChunk, ) -from litellm.caching import DualCache +from litellm.types.utils import Choices, Message +from litellm.utils import CustomStreamWrapper, ModelResponse, Usage, get_secret + +from .base import BaseLLM +from .bedrock import BedrockError, ModelResponseIterator, convert_messages_to_prompt +from .prompt_templates.factory import ( + _bedrock_converse_messages_pt, + _bedrock_tools_pt, + cohere_message_pt, + construct_tool_use_system_prompt, + contains_tag, + custom_prompt, + extract_between_tags, + parse_xml_params, + prompt_factory, +) iam_cache = DualCache() @@ -171,26 +172,34 @@ async def make_call( messages: list, logging_obj, ): - if client is None: - client = _get_async_httpx_client() # Create a new client if none provided + try: + if client is None: + client = _get_async_httpx_client() # Create a new client if none provided - response = await client.post(api_base, headers=headers, data=data, stream=True) + response = await client.post(api_base, headers=headers, data=data, stream=True) - if response.status_code != 200: - raise BedrockError(status_code=response.status_code, message=response.text) + if response.status_code != 200: + raise BedrockError(status_code=response.status_code, message=response.text) - decoder = AWSEventStreamDecoder(model=model) - completion_stream = decoder.aiter_bytes(response.aiter_bytes(chunk_size=1024)) + decoder = AWSEventStreamDecoder(model=model) + completion_stream = decoder.aiter_bytes(response.aiter_bytes(chunk_size=1024)) - # LOGGING - logging_obj.post_call( - input=messages, - api_key="", - original_response="first stream response received", - additional_args={"complete_input_dict": data}, - ) + # LOGGING + logging_obj.post_call( + input=messages, + api_key="", + original_response="first stream response received", + additional_args={"complete_input_dict": data}, + ) - return completion_stream + return completion_stream + except httpx.HTTPStatusError as err: + error_code = err.response.status_code + raise BedrockError(status_code=error_code, message=str(err)) + except httpx.TimeoutException as e: + raise BedrockError(status_code=408, message="Timeout error occurred.") + except Exception as e: + raise BedrockError(status_code=500, message=str(e)) def make_sync_call( @@ -704,7 +713,6 @@ class BedrockLLM(BaseLLM): ) -> Union[ModelResponse, CustomStreamWrapper]: try: import boto3 - from botocore.auth import SigV4Auth from botocore.awsrequest import AWSRequest from botocore.credentials import Credentials @@ -1650,7 +1658,6 @@ class BedrockConverseLLM(BaseLLM): ): try: import boto3 - from botocore.auth import SigV4Auth from botocore.awsrequest import AWSRequest from botocore.credentials import Credentials @@ -1904,8 +1911,8 @@ class BedrockConverseLLM(BaseLLM): def get_response_stream_shape(): - from botocore.model import ServiceModel from botocore.loaders import Loader + from botocore.model import ServiceModel loader = Loader() bedrock_service_dict = loader.load_service_model("bedrock-runtime", "service-2") diff --git a/litellm/proxy/_experimental/out/404.html b/litellm/proxy/_experimental/out/404.html deleted file mode 100644 index 909f7154275..00000000000 --- a/litellm/proxy/_experimental/out/404.html +++ /dev/null @@ -1 +0,0 @@ -404: This page could not be found.LiteLLM Dashboard

404

This page could not be found.

\ No newline at end of file diff --git a/litellm/proxy/_experimental/out/model_hub.html b/litellm/proxy/_experimental/out/model_hub.html deleted file mode 100644 index ef01db5851f..00000000000 --- a/litellm/proxy/_experimental/out/model_hub.html +++ /dev/null @@ -1 +0,0 @@ -LiteLLM Dashboard \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/onboarding.html b/litellm/proxy/_experimental/out/onboarding.html deleted file mode 100644 index ff88e53c95e..00000000000 --- a/litellm/proxy/_experimental/out/onboarding.html +++ /dev/null @@ -1 +0,0 @@ -LiteLLM Dashboard \ No newline at end of file diff --git a/litellm/proxy/_new_secret_config.yaml b/litellm/proxy/_new_secret_config.yaml index 01f09ca02b1..a90a79dbdf1 100644 --- a/litellm/proxy/_new_secret_config.yaml +++ b/litellm/proxy/_new_secret_config.yaml @@ -1,10 +1,10 @@ model_list: - model_name: my-fake-model litellm_params: - model: gpt-3.5-turbo + model: bedrock/anthropic.claude-3-sonnet-20240229-v1:0 api_key: my-fake-key - mock_response: hello-world - tpm: 60 + aws_bedrock_runtime_endpoint: http://127.0.0.1:8000 -litellm_settings: - callbacks: ["dynamic_rate_limiter"] \ No newline at end of file +litellm_settings: + success_callback: ["langfuse"] + failure_callback: ["langfuse"] \ No newline at end of file diff --git a/litellm/proxy/proxy_server.py b/litellm/proxy/proxy_server.py index 4cac93b24ff..30b90abe64c 100644 --- a/litellm/proxy/proxy_server.py +++ b/litellm/proxy/proxy_server.py @@ -2526,11 +2526,10 @@ async def async_data_generator( yield f"data: {done_message}\n\n" except Exception as e: verbose_proxy_logger.error( - "litellm.proxy.proxy_server.async_data_generator(): Exception occured - {}".format( - str(e) + "litellm.proxy.proxy_server.async_data_generator(): Exception occured - {}\n{}".format( + str(e), traceback.format_exc() ) ) - verbose_proxy_logger.debug(traceback.format_exc()) await proxy_logging_obj.post_call_failure_hook( user_api_key_dict=user_api_key_dict, original_exception=e, diff --git a/litellm/utils.py b/litellm/utils.py index 19d99ff59b7..0849ba3a26d 100644 --- a/litellm/utils.py +++ b/litellm/utils.py @@ -9595,6 +9595,11 @@ class CustomStreamWrapper: litellm.request_timeout ) if self.logging_obj is not None: + ## LOGGING + threading.Thread( + target=self.logging_obj.failure_handler, + args=(e, traceback_exception), + ).start() # log response # Handle any exceptions that might occur during streaming asyncio.create_task( self.logging_obj.async_failure_handler(e, traceback_exception) @@ -9602,11 +9607,24 @@ class CustomStreamWrapper: raise e except Exception as e: traceback_exception = traceback.format_exc() - # Handle any exceptions that might occur during streaming - asyncio.create_task( - self.logging_obj.async_failure_handler(e, traceback_exception) # type: ignore + if self.logging_obj is not None: + ## LOGGING + threading.Thread( + target=self.logging_obj.failure_handler, + args=(e, traceback_exception), + ).start() # log response + # Handle any exceptions that might occur during streaming + asyncio.create_task( + self.logging_obj.async_failure_handler(e, traceback_exception) # type: ignore + ) + ## Map to OpenAI Exception + raise exception_type( + model=self.model, + custom_llm_provider=self.custom_llm_provider, + original_exception=e, + completion_kwargs={}, + extra_kwargs={}, ) - raise e class TextCompletionStreamWrapper: