From da835ad10a310ae8e3cb94cfb55ccca3788ecd52 Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Wed, 27 Mar 2024 14:35:17 -0700 Subject: [PATCH 01/54] (fix) bump uvicorn on proxy docker builds --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index cd63c1242..9e6298363 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,7 +5,7 @@ fastapi>=0.109.1 # server dep pydantic>=2.5 # openai req. backoff==2.2.1 # server dep pyyaml>=6.0.1 # server dep -uvicorn==0.22.0 # server dep +uvicorn==0.29.0 # server dep gunicorn==21.2.0 # server dep boto3==1.34.34 # aws bedrock/sagemaker calls redis==5.0.0 # caching From c97724df7de3d3dcf6f4db7d2ad7b867296facce Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Wed, 27 Mar 2024 15:51:00 -0700 Subject: [PATCH 02/54] (fix) remove background tasks --- litellm/proxy/proxy_server.py | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/litellm/proxy/proxy_server.py b/litellm/proxy/proxy_server.py index 8fa2862f2..311d3d2be 100644 --- a/litellm/proxy/proxy_server.py +++ b/litellm/proxy/proxy_server.py @@ -130,7 +130,6 @@ from fastapi import ( HTTPException, status, Depends, - BackgroundTasks, Header, Response, Form, @@ -2896,7 +2895,6 @@ async def completion( fastapi_response: Response, model: Optional[str] = None, user_api_key_dict: UserAPIKeyAuth = Depends(user_api_key_auth), - background_tasks: BackgroundTasks = BackgroundTasks(), ): global user_temperature, user_request_timeout, user_max_tokens, user_api_base try: @@ -3062,7 +3060,6 @@ async def chat_completion( fastapi_response: Response, model: Optional[str] = None, user_api_key_dict: UserAPIKeyAuth = Depends(user_api_key_auth), - background_tasks: BackgroundTasks = BackgroundTasks(), ): global general_settings, user_debug, proxy_logging_obj, llm_model_list try: @@ -3299,7 +3296,6 @@ async def embeddings( request: Request, model: Optional[str] = None, user_api_key_dict: UserAPIKeyAuth = Depends(user_api_key_auth), - background_tasks: BackgroundTasks = BackgroundTasks(), ): global proxy_logging_obj try: @@ -3475,7 +3471,6 @@ async def embeddings( async def image_generation( request: Request, user_api_key_dict: UserAPIKeyAuth = Depends(user_api_key_auth), - background_tasks: BackgroundTasks = BackgroundTasks(), ): global proxy_logging_obj try: @@ -6158,7 +6153,7 @@ async def block_team( raise Exception("No DB Connected.") record = await prisma_client.db.litellm_teamtable.update( - where={"team_id": data.team_id}, data={"blocked": True} + where={"team_id": data.team_id}, data={"blocked": True} # type: ignore ) return record @@ -6180,7 +6175,7 @@ async def unblock_team( raise Exception("No DB Connected.") record = await prisma_client.db.litellm_teamtable.update( - where={"team_id": data.team_id}, data={"blocked": False} + where={"team_id": data.team_id}, data={"blocked": False} # type: ignore ) return record @@ -6783,7 +6778,6 @@ async def async_queue_request( request: Request, model: Optional[str] = None, user_api_key_dict: UserAPIKeyAuth = Depends(user_api_key_auth), - background_tasks: BackgroundTasks = BackgroundTasks(), ): global general_settings, user_debug, proxy_logging_obj """ From 1e856443e17098e09191021524004587291860f8 Mon Sep 17 00:00:00 2001 From: Krrish Dholakia Date: Wed, 27 Mar 2024 16:02:36 -0700 Subject: [PATCH 03/54] feat(proxy/utils.py): enable updating db in a separate server --- litellm/llms/custom_httpx/httpx_handler.py | 38 ++++++++++++++++++++++ litellm/proxy/_new_secret_config.yaml | 17 +++++----- litellm/proxy/auth/handle_jwt.py | 35 +------------------- litellm/proxy/proxy_cli.py | 2 -- litellm/proxy/proxy_server.py | 22 ++++++++++--- litellm/proxy/utils.py | 32 +++++++++++++----- 6 files changed, 89 insertions(+), 57 deletions(-) create mode 100644 litellm/llms/custom_httpx/httpx_handler.py diff --git a/litellm/llms/custom_httpx/httpx_handler.py b/litellm/llms/custom_httpx/httpx_handler.py new file mode 100644 index 000000000..3f3bd09ba --- /dev/null +++ b/litellm/llms/custom_httpx/httpx_handler.py @@ -0,0 +1,38 @@ +from typing import Optional +import httpx + + +class HTTPHandler: + def __init__(self, concurrent_limit=1000): + # Create a client with a connection pool + self.client = httpx.AsyncClient( + limits=httpx.Limits( + max_connections=concurrent_limit, + max_keepalive_connections=concurrent_limit, + ) + ) + + async def close(self): + # Close the client when you're done with it + await self.client.aclose() + + async def get( + self, url: str, params: Optional[dict] = None, headers: Optional[dict] = None + ): + response = await self.client.get(url, params=params, headers=headers) + return response + + async def post( + self, + url: str, + data: Optional[dict] = None, + params: Optional[dict] = None, + headers: Optional[dict] = None, + ): + try: + response = await self.client.post( + url, data=data, params=params, headers=headers + ) + return response + except Exception as e: + raise e diff --git a/litellm/proxy/_new_secret_config.yaml b/litellm/proxy/_new_secret_config.yaml index bd277bbdf..07a24dd7e 100644 --- a/litellm/proxy/_new_secret_config.yaml +++ b/litellm/proxy/_new_secret_config.yaml @@ -1,21 +1,22 @@ model_list: -- model_name: fake_openai +- model_name: fake-openai-endpoint litellm_params: model: openai/my-fake-model api_key: my-fake-key - api_base: http://0.0.0.0:8080 + api_base: https://exampleopenaiendpoint-production.up.railway.app/ - model_name: gpt-3.5-turbo litellm_params: model: gpt-3.5-turbo-1106 api_key: os.environ/OPENAI_API_KEY -litellm_settings: - cache: true - cache_params: - type: redis - callbacks: ["batch_redis_requests"] - # success_callbacks: ["langfuse"] +# litellm_settings: +# cache: true +# cache_params: +# type: redis +# callbacks: ["batch_redis_requests"] +# # success_callbacks: ["langfuse"] general_settings: master_key: sk-1234 + disable_spend_logs: true database_url: "postgresql://neondb_owner:hz8tyUlJ5ivV@ep-cool-sunset-a5ywubeh.us-east-2.aws.neon.tech/neondb?sslmode=require" \ No newline at end of file diff --git a/litellm/proxy/auth/handle_jwt.py b/litellm/proxy/auth/handle_jwt.py index 08ffc0955..4689ffe7b 100644 --- a/litellm/proxy/auth/handle_jwt.py +++ b/litellm/proxy/auth/handle_jwt.py @@ -6,7 +6,6 @@ Currently only supports admin. JWT token must have 'litellm_proxy_admin' in scope. """ -import httpx import jwt import json import os @@ -14,42 +13,10 @@ from litellm.caching import DualCache from litellm._logging import verbose_proxy_logger from litellm.proxy._types import LiteLLM_JWTAuth, LiteLLM_UserTable from litellm.proxy.utils import PrismaClient +from litellm.llms.custom_httpx.httpx_handler import HTTPHandler from typing import Optional -class HTTPHandler: - def __init__(self, concurrent_limit=1000): - # Create a client with a connection pool - self.client = httpx.AsyncClient( - limits=httpx.Limits( - max_connections=concurrent_limit, - max_keepalive_connections=concurrent_limit, - ) - ) - - async def close(self): - # Close the client when you're done with it - await self.client.aclose() - - async def get( - self, url: str, params: Optional[dict] = None, headers: Optional[dict] = None - ): - response = await self.client.get(url, params=params, headers=headers) - return response - - async def post( - self, - url: str, - data: Optional[dict] = None, - params: Optional[dict] = None, - headers: Optional[dict] = None, - ): - response = await self.client.post( - url, data=data, params=params, headers=headers - ) - return response - - class JWTHandler: """ - treat the sub id passed in as the user id diff --git a/litellm/proxy/proxy_cli.py b/litellm/proxy/proxy_cli.py index b1d7b8026..b8d792696 100644 --- a/litellm/proxy/proxy_cli.py +++ b/litellm/proxy/proxy_cli.py @@ -21,8 +21,6 @@ telemetry = None def append_query_params(url, params): from litellm._logging import verbose_proxy_logger - from litellm._logging import verbose_proxy_logger - verbose_proxy_logger.debug(f"url: {url}") verbose_proxy_logger.debug(f"params: {params}") parsed_url = urlparse.urlparse(url) diff --git a/litellm/proxy/proxy_server.py b/litellm/proxy/proxy_server.py index 8fa2862f2..f2918a04d 100644 --- a/litellm/proxy/proxy_server.py +++ b/litellm/proxy/proxy_server.py @@ -97,7 +97,6 @@ from litellm.proxy.utils import ( _is_projected_spend_over_limit, _get_projected_spend_over_limit, update_spend, - monitor_spend_list, ) from litellm.proxy.secret_managers.google_kms import load_google_kms from litellm.proxy.secret_managers.aws_secret_manager import load_aws_secret_manager @@ -118,6 +117,7 @@ from litellm.proxy.auth.auth_checks import ( allowed_routes_check, get_actual_routes, ) +from litellm.llms.custom_httpx.httpx_handler import HTTPHandler try: from litellm._version import version @@ -305,6 +305,8 @@ proxy_logging_obj = ProxyLogging(user_api_key_cache=user_api_key_cache) async_result = None celery_app_conn = None celery_fn = None # Redis Queue for handling requests +### DB WRITER ### +db_writer_client: Optional[HTTPHandler] = None ### logger ### @@ -1363,7 +1365,15 @@ async def update_database( payload["spend"] = response_cost if prisma_client is not None: - await prisma_client.insert_data(data=payload, table_name="spend") + prisma_client.spend_log_transactons.append(payload) + # if db_writer_client is not None: + # print("Tries to make call") + # response = await db_writer_client.post( + # url="http://0.0.0.0:3000/spend/update", + # data=json.dumps(payload), + # headers={"Content-Type": "application/json"}, + # ) + # print(f"response: {response}") except Exception as e: verbose_proxy_logger.debug( f"Update Spend Logs DB failed to execute - {str(e)}\n{traceback.format_exc()}" @@ -2693,7 +2703,7 @@ def on_backoff(details): @router.on_event("startup") async def startup_event(): - global prisma_client, master_key, use_background_health_checks, llm_router, llm_model_list, general_settings, proxy_budget_rescheduler_min_time, proxy_budget_rescheduler_max_time, litellm_proxy_admin_name + global prisma_client, master_key, use_background_health_checks, llm_router, llm_model_list, general_settings, proxy_budget_rescheduler_min_time, proxy_budget_rescheduler_max_time, litellm_proxy_admin_name, db_writer_client import json ### LOAD MASTER KEY ### @@ -2726,6 +2736,8 @@ async def startup_event(): ## COST TRACKING ## cost_tracking() + db_writer_client = HTTPHandler() + 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 ## JWT AUTH ## @@ -2836,7 +2848,7 @@ async def startup_event(): update_spend, "interval", seconds=batch_writing_interval, - args=[prisma_client], + args=[prisma_client, db_writer_client], ) scheduler.start() @@ -7985,6 +7997,8 @@ async def shutdown_event(): await jwt_handler.close() + if db_writer_client is not None: + await db_writer_client.close() ## RESET CUSTOM VARIABLES ## cleanup_router_config_variables() diff --git a/litellm/proxy/utils.py b/litellm/proxy/utils.py index ba8d70804..1d5f5f819 100644 --- a/litellm/proxy/utils.py +++ b/litellm/proxy/utils.py @@ -13,6 +13,7 @@ from litellm.proxy._types import ( Member, ) from litellm.caching import DualCache +from litellm.llms.custom_httpx.httpx_handler import HTTPHandler from litellm.proxy.hooks.parallel_request_limiter import ( _PROXY_MaxParallelRequestsHandler, ) @@ -1716,6 +1717,11 @@ def get_logging_payload(kwargs, response_obj, start_time, end_time): # hash the api_key api_key = hash_token(api_key) + # jsonify datetime object + # if isinstance(start_time, datetime): + # start_time = start_time.isoformat() + # if isinstance(end_time, datetime): + # end_time = end_time.isoformat() # clean up litellm metadata if isinstance(metadata, dict): clean_metadata = {} @@ -1866,9 +1872,7 @@ async def reset_budget(prisma_client: PrismaClient): ) -async def update_spend( - prisma_client: PrismaClient, -): +async def update_spend(prisma_client: PrismaClient, db_writer_client: HTTPHandler): """ Batch write updates to db. @@ -1995,13 +1999,23 @@ async def update_spend( except Exception as e: raise e + ### UPDATE SPEND LOGS ### + # if len(prisma_client.spend_log_transactons) > 0: + # response = await db_writer_client.post( + # url="http://0.0.0.0:3000/spend/update", + # data=prisma_client.spend_log_transactons, + # headers={"Content-Type": "application/json"}, + # ) + # if response.status_code == 200: + # prisma_client.spend_log_transactons = [] -async def monitor_spend_list(prisma_client: PrismaClient): - """ - Check the length of each spend list, if it exceeds a threshold (e.g. 100 items) - write to db - """ - if len(prisma_client.user_list_transactons) > 10000: - await update_spend(prisma_client=prisma_client) + +# async def monitor_spend_list(prisma_client: PrismaClient): +# """ +# Check the length of each spend list, if it exceeds a threshold (e.g. 100 items) - write to db +# """ +# if len(prisma_client.user_list_transactons) > 10000: +# await update_spend(prisma_client=prisma_client) async def _read_request_body(request): From e4e4dd01cdb10098d1a3142aa3f5875eab85c67a Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Wed, 27 Mar 2024 16:18:08 -0700 Subject: [PATCH 04/54] (fix) access router model names in constant time --- litellm/proxy/proxy_server.py | 53 ++++++++--------------------------- 1 file changed, 11 insertions(+), 42 deletions(-) diff --git a/litellm/proxy/proxy_server.py b/litellm/proxy/proxy_server.py index 8fa2862f2..9dbcf8b57 100644 --- a/litellm/proxy/proxy_server.py +++ b/litellm/proxy/proxy_server.py @@ -2630,11 +2630,7 @@ async def async_data_generator(response, user_api_key_dict): verbose_proxy_logger.debug( f"\033[1;31mAn error occurred: {e}\n\n Debug this by setting `--debug`, e.g. `litellm --model gpt-3.5-turbo --debug`" ) - router_model_names = ( - [m["model_name"] for m in llm_model_list] - if llm_model_list is not None - else [] - ) + router_model_names = llm_router.model_names if llm_router is not None else [] if user_debug: traceback.print_exc() @@ -2958,11 +2954,7 @@ async def completion( start_time = time.time() ### ROUTE THE REQUESTs ### - router_model_names = ( - [m["model_name"] for m in llm_model_list] - if llm_model_list is not None - else [] - ) + router_model_names = llm_router.model_names if llm_router is not None else [] # skip router if user passed their key if "api_key" in data: response = await litellm.atext_completion(**data) @@ -3176,11 +3168,8 @@ async def chat_completion( start_time = time.time() ### ROUTE THE REQUEST ### - router_model_names = ( - [m["model_name"] for m in llm_model_list] - if llm_model_list is not None - else [] - ) + # Do not change this - it should be a constant time fetch - ALWAYS + router_model_names = llm_router.model_names if llm_router is not None else [] # skip router if user passed their key if "api_key" in data: tasks.append(litellm.acompletion(**data)) @@ -3253,11 +3242,7 @@ async def chat_completion( verbose_proxy_logger.debug( f"\033[1;31mAn error occurred: {e}\n\n Debug this by setting `--debug`, e.g. `litellm --model gpt-3.5-turbo --debug`" ) - router_model_names = ( - [m["model_name"] for m in llm_model_list] - if llm_model_list is not None - else [] - ) + router_model_names = llm_router.model_names if llm_router is not None else [] if user_debug: traceback.print_exc() @@ -3365,11 +3350,7 @@ async def embeddings( if data["model"] in litellm.model_alias_map: data["model"] = litellm.model_alias_map[data["model"]] - router_model_names = ( - [m["model_name"] for m in llm_model_list] - if llm_model_list is not None - else [] - ) + router_model_names = llm_router.model_names if llm_router is not None else [] if ( "input" in data and isinstance(data["input"], list) @@ -3541,11 +3522,7 @@ async def image_generation( if data["model"] in litellm.model_alias_map: data["model"] = litellm.model_alias_map[data["model"]] - router_model_names = ( - [m["model_name"] for m in llm_model_list] - if llm_model_list is not None - else [] - ) + router_model_names = llm_router.model_names if llm_router is not None else [] ### CALL HOOKS ### - modify incoming data / reject request before calling the model data = await proxy_logging_obj.pre_call_hook( @@ -3689,11 +3666,7 @@ async def audio_transcriptions( **data, } # add the team-specific configs to the completion call - router_model_names = ( - [m["model_name"] for m in llm_model_list] - if llm_model_list is not None - else [] - ) + router_model_names = llm_router.model_names if llm_router is not None else [] assert ( file.filename is not None @@ -3858,11 +3831,7 @@ async def moderations( **data, } # add the team-specific configs to the completion call - router_model_names = ( - [m["model_name"] for m in llm_model_list] - if llm_model_list is not None - else [] - ) + router_model_names = llm_router.model_names if llm_router is not None else [] ### CALL HOOKS ### - modify incoming data / reject request before calling the model data = await proxy_logging_obj.pre_call_hook( @@ -6158,7 +6127,7 @@ async def block_team( raise Exception("No DB Connected.") record = await prisma_client.db.litellm_teamtable.update( - where={"team_id": data.team_id}, data={"blocked": True} + where={"team_id": data.team_id}, data={"blocked": True} # type: ignore ) return record @@ -6180,7 +6149,7 @@ async def unblock_team( raise Exception("No DB Connected.") record = await prisma_client.db.litellm_teamtable.update( - where={"team_id": data.team_id}, data={"blocked": False} + where={"team_id": data.team_id}, data={"blocked": False} # type: ignore ) return record From 9d0ce1aefdc676cf5625adea28eb986e86dd7061 Mon Sep 17 00:00:00 2001 From: Krrish Dholakia Date: Wed, 27 Mar 2024 17:08:55 -0700 Subject: [PATCH 05/54] feat(proxy_server.py): new `/spend/calculate` endpoint Allows user to calculate spend before making the call --- litellm/proxy/proxy_server.py | 77 +++++++++++++++++++++++++++++++++-- 1 file changed, 74 insertions(+), 3 deletions(-) diff --git a/litellm/proxy/proxy_server.py b/litellm/proxy/proxy_server.py index 8fa2862f2..4b00e9bd7 100644 --- a/litellm/proxy/proxy_server.py +++ b/litellm/proxy/proxy_server.py @@ -4343,7 +4343,7 @@ async def info_key_fn( @router.get( "/spend/keys", - tags=["budget & spend Tracking"], + tags=["Budget & Spend Tracking"], dependencies=[Depends(user_api_key_auth)], ) async def spend_key_fn(): @@ -4375,7 +4375,7 @@ async def spend_key_fn(): @router.get( "/spend/users", - tags=["budget & spend Tracking"], + tags=["Budget & Spend Tracking"], dependencies=[Depends(user_api_key_auth)], ) async def spend_user_fn( @@ -4427,7 +4427,7 @@ async def spend_user_fn( @router.get( "/spend/tags", - tags=["budget & spend Tracking"], + tags=["Budget & Spend Tracking"], dependencies=[Depends(user_api_key_auth)], responses={ 200: {"model": List[LiteLLM_SpendLogs]}, @@ -4500,6 +4500,77 @@ async def view_spend_tags( ) +@router.post( + "/spend/calculate", + tags=["Budget & Spend Tracking"], + dependencies=[Depends(user_api_key_auth)], + responses={ + 200: { + "cost": { + "description": "The calculated cost", + "example": 0.0, + "type": "float", + } + } + }, +) +async def calculate_spend(request: Request): + """ + Accepts all the params of completion_cost. + + Calculate spend **before** making call: + + ``` + curl --location 'http://localhost:4000/spend/calculate' + --header 'Authorization: Bearer sk-1234' + --header 'Content-Type: application/json' + --data '{ + "model": "anthropic.claude-v2", + "messages": [{"role": "user", "content": "Hey, how'''s it going?"}] + }' + ``` + + Calculate spend **after** making call: + + ``` + curl --location 'http://localhost:4000/spend/calculate' + --header 'Authorization: Bearer sk-1234' + --header 'Content-Type: application/json' + --data '{ + "completion_response": { + "id": "chatcmpl-123", + "object": "chat.completion", + "created": 1677652288, + "model": "gpt-3.5-turbo-0125", + "system_fingerprint": "fp_44709d6fcb", + "choices": [{ + "index": 0, + "message": { + "role": "assistant", + "content": "Hello there, how may I assist you today?" + }, + "logprobs": null, + "finish_reason": "stop" + }] + "usage": { + "prompt_tokens": 9, + "completion_tokens": 12, + "total_tokens": 21 + } + } + }' + ``` + """ + from litellm import completion_cost + + data = await request.json() + if "completion_response" in data: + data["completion_response"] = litellm.ModelResponse( + **data["completion_response"] + ) + return {"cost": completion_cost(**data)} + + @router.get( "/spend/logs", tags=["Budget & Spend Tracking"], From 4eb93832e4bea6a4fc1acfac698e8b216f4743c0 Mon Sep 17 00:00:00 2001 From: Krrish Dholakia Date: Wed, 27 Mar 2024 17:36:27 -0700 Subject: [PATCH 06/54] feat(auth_checks.py): enable admin to enforce 'user' param for all openai endpoints --- litellm/proxy/_types.py | 2 ++ litellm/proxy/auth/auth_checks.py | 15 ++++++++++++++- litellm/proxy/proxy_server.py | 19 +++++++++++++++++++ litellm/proxy/utils.py | 6 ++++++ 4 files changed, 41 insertions(+), 1 deletion(-) diff --git a/litellm/proxy/_types.py b/litellm/proxy/_types.py index 9704a2f19..75396233e 100644 --- a/litellm/proxy/_types.py +++ b/litellm/proxy/_types.py @@ -698,6 +698,8 @@ class LiteLLM_VerificationTokenView(LiteLLM_VerificationToken): team_tpm_limit: Optional[int] = None team_rpm_limit: Optional[int] = None team_max_budget: Optional[float] = None + team_models: List = [] + team_blocked: bool = False soft_budget: Optional[float] = None team_model_aliases: Optional[Dict] = None diff --git a/litellm/proxy/auth/auth_checks.py b/litellm/proxy/auth/auth_checks.py index 37ec2065f..5246fb94d 100644 --- a/litellm/proxy/auth/auth_checks.py +++ b/litellm/proxy/auth/auth_checks.py @@ -15,7 +15,7 @@ from litellm.proxy._types import ( LiteLLM_TeamTable, LiteLLMRoutes, ) -from typing import Optional, Literal +from typing import Optional, Literal, Union from litellm.proxy.utils import PrismaClient from litellm.caching import DualCache @@ -26,6 +26,8 @@ def common_checks( request_body: dict, team_object: LiteLLM_TeamTable, end_user_object: Optional[LiteLLM_EndUserTable], + general_settings: dict, + route: str, ) -> bool: """ Common checks across jwt + key-based auth. @@ -34,6 +36,7 @@ def common_checks( 2. If team can call model 3. If team is in budget 4. If end_user ('user' passed to /chat/completions, /embeddings endpoint) is in budget + 5. [OPTIONAL] If 'enforce_end_user' enabled - did developer pass in 'user' param for openai endpoints """ _model = request_body.get("model", None) if team_object.blocked == True: @@ -65,6 +68,16 @@ def common_checks( raise Exception( f"End User={end_user_object.user_id} over budget. Spend={end_user_object.spend}, Budget={end_user_budget}" ) + # 5. [OPTIONAL] If 'enforce_user_param' enabled - did developer pass in 'user' param for openai endpoints + if ( + general_settings.get("enforce_user_param", None) is not None + and general_settings["enforce_user_param"] == True + ): + if route in LiteLLMRoutes.openai_routes.value and "user" not in request_body: + raise Exception( + f"'user' param not passed in. 'enforce_user_param'={general_settings['enforce_user_param']}" + ) + return True diff --git a/litellm/proxy/proxy_server.py b/litellm/proxy/proxy_server.py index 8fa2862f2..537ed1bab 100644 --- a/litellm/proxy/proxy_server.py +++ b/litellm/proxy/proxy_server.py @@ -440,6 +440,8 @@ async def user_api_key_auth( request_body=request_data, team_object=team_object, end_user_object=end_user_object, + general_settings=general_settings, + route=route, ) # save user object in cache await user_api_key_cache.async_set_cache( @@ -867,6 +869,23 @@ async def user_api_key_auth( f"ExceededTokenBudget: Current Team Spend: {valid_token.team_spend}; Max Budget for Team: {valid_token.team_max_budget}" ) + # Check 8: Additional Common Checks across jwt + key auth + _team_obj = LiteLLM_TeamTable( + team_id=valid_token.team_id, + max_budget=valid_token.team_max_budget, + spend=valid_token.team_spend, + tpm_limit=valid_token.team_tpm_limit, + rpm_limit=valid_token.team_rpm_limit, + blocked=valid_token.team_blocked, + models=valid_token.team_models, + ) + _ = common_checks( + request_body=request_data, + team_object=_team_obj, + end_user_object=None, + general_settings=general_settings, + route=route, + ) # Token passed all checks api_key = valid_token.token diff --git a/litellm/proxy/utils.py b/litellm/proxy/utils.py index ba8d70804..fd8421b50 100644 --- a/litellm/proxy/utils.py +++ b/litellm/proxy/utils.py @@ -1013,6 +1013,8 @@ class PrismaClient: t.max_budget AS team_max_budget, t.tpm_limit AS team_tpm_limit, t.rpm_limit AS team_rpm_limit, + t.models AS team_models, + t.blocked AS team_blocked, m.aliases as team_model_aliases FROM "LiteLLM_VerificationToken" AS v LEFT JOIN "LiteLLM_TeamTable" AS t ON v.team_id = t.team_id @@ -1023,6 +1025,10 @@ class PrismaClient: response = await self.db.query_first(query=sql_query) if response is not None: + if response["team_models"] is None: + response["team_models"] = [] + if response["team_blocked"] is None: + response["team_blocked"] = False response = LiteLLM_VerificationTokenView(**response) # for prisma we need to cast the expires time to str if response.expires is not None and isinstance( From d1fa22f9ed11025c14de7fb8ec7c75bd8c87270a Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Wed, 27 Mar 2024 19:00:52 -0700 Subject: [PATCH 07/54] (fix) ci/cd google deps --- .circleci/config.yml | 8 ++++---- .circleci/requirements.txt | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index b8084f1df..38b65099d 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -28,8 +28,8 @@ jobs: pip install "pytest==7.3.1" pip install "pytest-asyncio==0.21.1" pip install mypy - pip install "google-generativeai>=0.3.2" - pip install "google-cloud-aiplatform>=1.38.0" + pip install "google-generativeai==0.3.2" + pip install "google-cloud-aiplatform==1.43.0" pip install "boto3>=1.28.57" pip install "aioboto3>=12.3.0" pip install langchain @@ -152,8 +152,8 @@ jobs: pip install "pytest-mock==3.12.0" pip install "pytest-asyncio==0.21.1" pip install mypy - pip install "google-generativeai>=0.3.2" - pip install "google-cloud-aiplatform>=1.38.0" + pip install "google-generativeai==0.3.2" + pip install "google-cloud-aiplatform==1.43.0" pip install "boto3>=1.28.57" pip install "aioboto3>=12.3.0" pip install langchain diff --git a/.circleci/requirements.txt b/.circleci/requirements.txt index 4730fc28b..e9a59b7aa 100644 --- a/.circleci/requirements.txt +++ b/.circleci/requirements.txt @@ -10,5 +10,5 @@ anthropic boto3 orjson pydantic -google-cloud-aiplatform +google-cloud-aiplatform==1.43.0 redisvl==0.0.7 # semantic caching \ No newline at end of file From 73db5b45f82a1b8b929793024ec887a2c5d8120e Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Wed, 27 Mar 2024 19:04:07 -0700 Subject: [PATCH 08/54] (ci/cd) run again --- litellm/tests/test_completion.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/litellm/tests/test_completion.py b/litellm/tests/test_completion.py index 6d579acc0..30cca38e2 100644 --- a/litellm/tests/test_completion.py +++ b/litellm/tests/test_completion.py @@ -74,7 +74,7 @@ def test_completion_claude(): print(response.usage) print(response.usage.completion_tokens) print(response["usage"]["completion_tokens"]) - # print("new cost tracking") + # print("new costtracking") except Exception as e: if "overloaded_error" in str(e): pass From 0c69c05c54ad70129c9fbabe81272bc7ba2a7db0 Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Wed, 27 Mar 2024 19:14:25 -0700 Subject: [PATCH 09/54] (fix) google pip install pyarrow dep --- .circleci/config.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 38b65099d..991ac28f5 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -30,6 +30,7 @@ jobs: pip install mypy pip install "google-generativeai==0.3.2" pip install "google-cloud-aiplatform==1.43.0" + pip install pyarrow pip install "boto3>=1.28.57" pip install "aioboto3>=12.3.0" pip install langchain @@ -154,6 +155,7 @@ jobs: pip install mypy pip install "google-generativeai==0.3.2" pip install "google-cloud-aiplatform==1.43.0" + pip install pyarrow pip install "boto3>=1.28.57" pip install "aioboto3>=12.3.0" pip install langchain From 31383b18cbb9990d3200ce58815ced7f24a6ac65 Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Wed, 27 Mar 2024 19:18:39 -0700 Subject: [PATCH 10/54] (fix) cost tracking --- litellm/tests/test_completion.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/litellm/tests/test_completion.py b/litellm/tests/test_completion.py index 30cca38e2..6d579acc0 100644 --- a/litellm/tests/test_completion.py +++ b/litellm/tests/test_completion.py @@ -74,7 +74,7 @@ def test_completion_claude(): print(response.usage) print(response.usage.completion_tokens) print(response["usage"]["completion_tokens"]) - # print("new costtracking") + # print("new cost tracking") except Exception as e: if "overloaded_error" in str(e): pass From 5bd136e650303ebacbdf69e72bbf39f01bb96e8d Mon Sep 17 00:00:00 2001 From: Krish Dholakia Date: Wed, 27 Mar 2024 19:23:08 -0700 Subject: [PATCH 11/54] Updated config.yml --- .circleci/config.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index b8084f1df..3084c6a88 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -48,6 +48,7 @@ jobs: pip install argon2-cffi pip install "pytest-mock==3.12.0" pip install python-multipart + pip install google-cloud-aiplatform - save_cache: paths: - ./venv From 848b0ba67fcb2e41fdce9197886239a19eb76a66 Mon Sep 17 00:00:00 2001 From: Krish Dholakia Date: Wed, 27 Mar 2024 19:23:33 -0700 Subject: [PATCH 12/54] Updated config.yml --- .circleci/config.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index b8084f1df..3084c6a88 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -48,6 +48,7 @@ jobs: pip install argon2-cffi pip install "pytest-mock==3.12.0" pip install python-multipart + pip install google-cloud-aiplatform - save_cache: paths: - ./venv From 2926d5a8ebd1db7d5ff9b977855952393476b4da Mon Sep 17 00:00:00 2001 From: Krrish Dholakia Date: Wed, 27 Mar 2024 20:09:15 -0700 Subject: [PATCH 13/54] fix(proxy/utils.py): check cache before alerting user --- litellm/proxy/utils.py | 30 ++++++++++++++++++++++-------- litellm/utils.py | 1 - 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/litellm/proxy/utils.py b/litellm/proxy/utils.py index fd8421b50..057f70d8f 100644 --- a/litellm/proxy/utils.py +++ b/litellm/proxy/utils.py @@ -298,6 +298,7 @@ class ProxyLogging: return else: user_info = str(user_info) + # percent of max_budget left to spend if user_max_budget > 0: percent_left = (user_max_budget - user_current_spend) / user_max_budget @@ -317,22 +318,35 @@ class ProxyLogging: ) return + ## PREVENTITIVE ALERTING ## - https://github.com/BerriAI/litellm/issues/2727 + # - Alert once within 28d period + # - Cache this information + # - Don't re-alert, if alert already sent + _cache: DualCache = self.call_details["user_api_key_cache"] + # check if 5% of max budget is left if percent_left <= 0.05: message = "5% budget left for" + user_info - await self.alerting_handler( - message=message, - level="Medium", - ) + result = await _cache.async_get_cache(key=message) + if result is None: + await self.alerting_handler( + message=message, + level="Medium", + ) + await _cache.async_set_cache(key=message, value="SENT", ttl=2419200) + return # check if 15% of max budget is left if percent_left <= 0.15: message = "15% budget left for" + user_info - await self.alerting_handler( - message=message, - level="Low", - ) + result = await _cache.async_get_cache(key=message) + if result is None: + await self.alerting_handler( + message=message, + level="Low", + ) + await _cache.async_set_cache(key=message, value="SENT", ttl=2419200) return return diff --git a/litellm/utils.py b/litellm/utils.py index d31bed6cb..88b952031 100644 --- a/litellm/utils.py +++ b/litellm/utils.py @@ -2775,7 +2775,6 @@ def client(original_function): or isinstance(e, openai.Timeout) or isinstance(e, openai.APIConnectionError) ): - print_verbose(f"RETRY TRIGGERED!") kwargs["num_retries"] = num_retries return litellm.completion_with_retries(*args, **kwargs) elif ( From 9ef7afd2b44108f0240c2f5255d16d0f5f062d58 Mon Sep 17 00:00:00 2001 From: Krrish Dholakia Date: Wed, 27 Mar 2024 20:12:22 -0700 Subject: [PATCH 14/54] test(test_completion.py): skip unresponsive endpoint --- litellm/tests/test_completion.py | 1 + 1 file changed, 1 insertion(+) diff --git a/litellm/tests/test_completion.py b/litellm/tests/test_completion.py index 6d579acc0..e4d447908 100644 --- a/litellm/tests/test_completion.py +++ b/litellm/tests/test_completion.py @@ -1107,6 +1107,7 @@ def test_completion_openai_litellm_key(): # test_ completion_openai_litellm_key() +@pytest.mark.skip(reason="Unresponsive endpoint.[TODO] Rehost this somewhere else") def test_completion_ollama_hosted(): try: litellm.request_timeout = 20 # give ollama 20 seconds to response From 0737fdb3484247ee95c3f78e9dac9ed32549a599 Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Wed, 27 Mar 2024 20:35:45 -0700 Subject: [PATCH 15/54] (fix) remove deep copy for all requests --- litellm/proxy/proxy_server.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/litellm/proxy/proxy_server.py b/litellm/proxy/proxy_server.py index 8fa2862f2..c3a91bdfa 100644 --- a/litellm/proxy/proxy_server.py +++ b/litellm/proxy/proxy_server.py @@ -3084,7 +3084,6 @@ async def chat_completion( "url": str(request.url), "method": request.method, "headers": dict(request.headers), - "body": copy.copy(data), # use copy instead of deepcopy } ## Cache Controls @@ -3312,7 +3311,6 @@ async def embeddings( "url": str(request.url), "method": request.method, "headers": dict(request.headers), - "body": copy.copy(data), # use copy instead of deepcopy } if data.get("user", None) is None and user_api_key_dict.user_id is not None: @@ -3488,7 +3486,6 @@ async def image_generation( "url": str(request.url), "method": request.method, "headers": dict(request.headers), - "body": copy.copy(data), # use copy instead of deepcopy } if data.get("user", None) is None and user_api_key_dict.user_id is not None: @@ -3641,7 +3638,6 @@ async def audio_transcriptions( "url": str(request.url), "method": request.method, "headers": dict(request.headers), - "body": copy.copy(data), # use copy instead of deepcopy } if data.get("user", None) is None and user_api_key_dict.user_id is not None: @@ -3811,7 +3807,6 @@ async def moderations( "url": str(request.url), "method": request.method, "headers": dict(request.headers), - "body": copy.copy(data), # use copy instead of deepcopy } if data.get("user", None) is None and user_api_key_dict.user_id is not None: @@ -6802,7 +6797,6 @@ async def async_queue_request( "url": str(request.url), "method": request.method, "headers": dict(request.headers), - "body": copy.copy(data), # use copy instead of deepcopy } verbose_proxy_logger.debug("receiving data: %s", data) From f2e1d938f3ede577bb4c6be4175472c12df820a8 Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Wed, 27 Mar 2024 20:36:53 -0700 Subject: [PATCH 16/54] (fix) remove deep copy from all responses --- litellm/proxy/utils.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/litellm/proxy/utils.py b/litellm/proxy/utils.py index ba8d70804..bf9be1bd6 100644 --- a/litellm/proxy/utils.py +++ b/litellm/proxy/utils.py @@ -449,16 +449,15 @@ class ProxyLogging: Covers: 1. /chat/completions """ - new_response = copy.deepcopy(response) for callback in litellm.callbacks: try: if isinstance(callback, CustomLogger): await callback.async_post_call_success_hook( - user_api_key_dict=user_api_key_dict, response=new_response + user_api_key_dict=user_api_key_dict, response=response ) except Exception as e: raise e - return new_response + return response async def post_call_streaming_hook( self, From 37f189935a77519048e549f72c2fb313f4fef243 Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Wed, 27 Mar 2024 20:54:07 -0700 Subject: [PATCH 17/54] (fix) show user their role when rejecting /team/new requests --- litellm/proxy/proxy_server.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/litellm/proxy/proxy_server.py b/litellm/proxy/proxy_server.py index e705541a6..abbcd1435 100644 --- a/litellm/proxy/proxy_server.py +++ b/litellm/proxy/proxy_server.py @@ -5681,7 +5681,7 @@ async def new_team( raise HTTPException( status_code=400, detail={ - "error": f"tpm limit higher than user max. User tpm limit={user_api_key_dict.tpm_limit}" + "error": f"tpm limit higher than user max. User tpm limit={user_api_key_dict.tpm_limit}. User role={user_api_key_dict.user_role}" }, ) @@ -5693,7 +5693,7 @@ async def new_team( raise HTTPException( status_code=400, detail={ - "error": f"rpm limit higher than user max. User rpm limit={user_api_key_dict.rpm_limit}" + "error": f"rpm limit higher than user max. User rpm limit={user_api_key_dict.rpm_limit}. User role={user_api_key_dict.user_role}" }, ) @@ -5705,7 +5705,7 @@ async def new_team( raise HTTPException( status_code=400, detail={ - "error": f"max budget higher than user max. User max budget={user_api_key_dict.max_budget}" + "error": f"max budget higher than user max. User max budget={user_api_key_dict.max_budget}. User role={user_api_key_dict.user_role}" }, ) @@ -5715,7 +5715,7 @@ async def new_team( raise HTTPException( status_code=400, detail={ - "error": f"Model not in allowed user models. User allowed models={user_api_key_dict.models}" + "error": f"Model not in allowed user models. User allowed models={user_api_key_dict.models}. User role={user_api_key_dict.user_role}" }, ) From e6b929fff358dfc36bb6ffb891da55c43368ebcb Mon Sep 17 00:00:00 2001 From: Krrish Dholakia Date: Wed, 27 Mar 2024 20:58:23 -0700 Subject: [PATCH 18/54] docs(call_hooks.md): show admin how to enforce user param --- docs/my-website/docs/proxy/call_hooks.md | 12 ++++++++++++ docs/my-website/docs/proxy/configs.md | 1 + 2 files changed, 13 insertions(+) diff --git a/docs/my-website/docs/proxy/call_hooks.md b/docs/my-website/docs/proxy/call_hooks.md index 2110af3a9..392a47121 100644 --- a/docs/my-website/docs/proxy/call_hooks.md +++ b/docs/my-website/docs/proxy/call_hooks.md @@ -2,6 +2,7 @@ - Modify data before making llm api calls on proxy - Reject data before making llm api calls / before returning the response +- Enforce 'user' param for all openai endpoint calls See a complete example with our [parallel request rate limiter](https://github.com/BerriAI/litellm/blob/main/litellm/proxy/hooks/parallel_request_limiter.py) @@ -172,4 +173,15 @@ curl --location 'http://0.0.0.0:4000/chat/completions' \ } ], }' +``` + +## Advanced - Enforce 'user' param + +Set `enforce_user_param` to true, to require all calls to the openai endpoints to have the 'user' param. + +[**See Code**](https://github.com/BerriAI/litellm/blob/4777921a31c4c70e4d87b927cb233b6a09cd8b51/litellm/proxy/auth/auth_checks.py#L72) + +```yaml +general_settings: + enforce_user_param: True ``` \ No newline at end of file diff --git a/docs/my-website/docs/proxy/configs.md b/docs/my-website/docs/proxy/configs.md index b2a7e42ba..e83125f2a 100644 --- a/docs/my-website/docs/proxy/configs.md +++ b/docs/my-website/docs/proxy/configs.md @@ -602,6 +602,7 @@ general_settings: "disable_spend_logs": "boolean", # turn off writing each transaction to the db "disable_reset_budget": "boolean", # turn off reset budget scheduled task "enable_jwt_auth": "boolean", # allow proxy admin to auth in via jwt tokens with 'litellm_proxy_admin' in claims + "enforce_user_param": "boolean", # requires all openai endpoint requests to have a 'user' param "allowed_routes": "list", # list of allowed proxy API routes - a user can access. (currently JWT-Auth only) "key_management_system": "google_kms", # either google_kms or azure_kms "master_key": "string", From 526aa9230feaed753e81d504b304c136dd8d20cc Mon Sep 17 00:00:00 2001 From: Krrish Dholakia Date: Wed, 27 Mar 2024 21:04:51 -0700 Subject: [PATCH 19/54] docs(call_hooks.md): show result in docs --- docs/my-website/docs/proxy/call_hooks.md | 8 +++++++- docs/my-website/img/end_user_enforcement.png | Bin 0 -> 184377 bytes 2 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 docs/my-website/img/end_user_enforcement.png diff --git a/docs/my-website/docs/proxy/call_hooks.md b/docs/my-website/docs/proxy/call_hooks.md index 392a47121..3195e2e5a 100644 --- a/docs/my-website/docs/proxy/call_hooks.md +++ b/docs/my-website/docs/proxy/call_hooks.md @@ -1,3 +1,5 @@ +import Image from '@theme/IdealImage'; + # Modify / Reject Incoming Requests - Modify data before making llm api calls on proxy @@ -184,4 +186,8 @@ Set `enforce_user_param` to true, to require all calls to the openai endpoints t ```yaml general_settings: enforce_user_param: True -``` \ No newline at end of file +``` + +**Result** + + \ No newline at end of file diff --git a/docs/my-website/img/end_user_enforcement.png b/docs/my-website/img/end_user_enforcement.png new file mode 100644 index 0000000000000000000000000000000000000000..2de7b7e18f2fe0c7961a94ade5da089047e3143b GIT binary patch literal 184377 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 lp8jhnaZFlf<3+ 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 TpwbiMifzk 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 NN)jrO{ZQxK{{hnnT>t<8 literal 0 HcmV?d00001 From 29fb7e126f323c95ec0e2719e4b0d21b43ebc777 Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Wed, 27 Mar 2024 21:15:12 -0700 Subject: [PATCH 20/54] Revert "(fix) remove deep copy for all requests" This reverts commit 0737fdb3484247ee95c3f78e9dac9ed32549a599. --- litellm/proxy/proxy_server.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/litellm/proxy/proxy_server.py b/litellm/proxy/proxy_server.py index c3a91bdfa..8fa2862f2 100644 --- a/litellm/proxy/proxy_server.py +++ b/litellm/proxy/proxy_server.py @@ -3084,6 +3084,7 @@ async def chat_completion( "url": str(request.url), "method": request.method, "headers": dict(request.headers), + "body": copy.copy(data), # use copy instead of deepcopy } ## Cache Controls @@ -3311,6 +3312,7 @@ async def embeddings( "url": str(request.url), "method": request.method, "headers": dict(request.headers), + "body": copy.copy(data), # use copy instead of deepcopy } if data.get("user", None) is None and user_api_key_dict.user_id is not None: @@ -3486,6 +3488,7 @@ async def image_generation( "url": str(request.url), "method": request.method, "headers": dict(request.headers), + "body": copy.copy(data), # use copy instead of deepcopy } if data.get("user", None) is None and user_api_key_dict.user_id is not None: @@ -3638,6 +3641,7 @@ async def audio_transcriptions( "url": str(request.url), "method": request.method, "headers": dict(request.headers), + "body": copy.copy(data), # use copy instead of deepcopy } if data.get("user", None) is None and user_api_key_dict.user_id is not None: @@ -3807,6 +3811,7 @@ async def moderations( "url": str(request.url), "method": request.method, "headers": dict(request.headers), + "body": copy.copy(data), # use copy instead of deepcopy } if data.get("user", None) is None and user_api_key_dict.user_id is not None: @@ -6797,6 +6802,7 @@ async def async_queue_request( "url": str(request.url), "method": request.method, "headers": dict(request.headers), + "body": copy.copy(data), # use copy instead of deepcopy } verbose_proxy_logger.debug("receiving data: %s", data) From eaccafd42b12f0db8197ab558edd87c0f7cbd2ab Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Wed, 27 Mar 2024 21:30:16 -0700 Subject: [PATCH 21/54] =?UTF-8?q?bump:=20version=201.34.7=20=E2=86=92=201.?= =?UTF-8?q?34.8?= 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 9940c43e4..8cc95050e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "litellm" -version = "1.34.7" +version = "1.34.8" description = "Library to easily interface with LLM API providers" authors = ["BerriAI"] license = "MIT" @@ -80,7 +80,7 @@ requires = ["poetry-core", "wheel"] build-backend = "poetry.core.masonry.api" [tool.commitizen] -version = "1.34.7" +version = "1.34.8" version_files = [ "pyproject.toml:^version" ] From d5f6fe4efffcb11b90044d4baa2fd34c5301cb61 Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Wed, 27 Mar 2024 22:24:56 -0700 Subject: [PATCH 22/54] (docs) update UI --- docs/my-website/docs/proxy/ui.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/my-website/docs/proxy/ui.md b/docs/my-website/docs/proxy/ui.md index cca9d4434..2ffa43952 100644 --- a/docs/my-website/docs/proxy/ui.md +++ b/docs/my-website/docs/proxy/ui.md @@ -47,8 +47,9 @@ Your Proxy Swagger is available on the root of the Proxy: e.g.: `http://localhos Set the following in your .env on the Proxy ```shell -UI_USERNAME=ishaan-litellm -UI_PASSWORD=langchain +LITELLM_MASTER_KEY="sk-1234" # this is your master key for using the proxy server +UI_USERNAME=ishaan-litellm # username to sign in on UI +UI_PASSWORD=langchain # password to sign in on UI ``` On accessing the LiteLLM UI, you will be prompted to enter your username, password From 4a5ce43bd55c4c6874b584d5fc6a8be008b97712 Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Wed, 27 Mar 2024 22:25:53 -0700 Subject: [PATCH 23/54] (fix) raise exception when master key not set + trying to use ui --- litellm/proxy/proxy_server.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/litellm/proxy/proxy_server.py b/litellm/proxy/proxy_server.py index abbcd1435..73cbd55e4 100644 --- a/litellm/proxy/proxy_server.py +++ b/litellm/proxy/proxy_server.py @@ -5715,7 +5715,7 @@ async def new_team( raise HTTPException( status_code=400, detail={ - "error": f"Model not in allowed user models. User allowed models={user_api_key_dict.models}. User role={user_api_key_dict.user_role}" + "error": f"Model not in allowed user models. User allowed models={user_api_key_dict.models}. User id={user_api_key_dict.user_id}" }, ) @@ -7099,6 +7099,13 @@ async def login(request: Request): except ImportError: subprocess.run(["pip", "install", "python-multipart"]) global master_key + if master_key is None: + raise ProxyException( + message="Master Key not set for Proxy. Please set Master Key to use Admin UI. Set `LITELLM_MASTER_KEY` in .env or set general_settings:master_key in config.yaml. https://docs.litellm.ai/docs/proxy/virtual_keys. If set, use `--detailed_debug` to debug issue.", + type="auth_error", + param="master_key", + code=status.HTTP_500_INTERNAL_SERVER_ERROR, + ) form = await request.form() username = str(form.get("username")) password = str(form.get("password")) From b1d2eb8684abbc5ae27f836f7a44423bf333747d Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Thu, 28 Mar 2024 08:11:05 -0700 Subject: [PATCH 24/54] (feat) admin UI show models on team table --- ui/litellm-dashboard/src/components/teams.tsx | 26 +++++++++++-------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/ui/litellm-dashboard/src/components/teams.tsx b/ui/litellm-dashboard/src/components/teams.tsx index d1c02d17d..80993c891 100644 --- a/ui/litellm-dashboard/src/components/teams.tsx +++ b/ui/litellm-dashboard/src/components/teams.tsx @@ -157,7 +157,7 @@ const Team: React.FC = ({ }; console.log(`received teams ${teams}`); return ( -

+
All Teams @@ -168,6 +168,7 @@ const Team: React.FC = ({ Team Name Spend (USD) Budget (USD) + Models TPM / RPM Limits @@ -176,22 +177,25 @@ const Team: React.FC = ({ {teams && teams.length > 0 ? teams.map((team: any) => ( - {team["team_alias"]} - {team["spend"]} - + {team["team_alias"]} + {team["spend"]} + {team["max_budget"] ? team["max_budget"] : "No limit"} - + + {JSON.stringify(team["models"] ? team["models"] : [])} + + TPM Limit:{" "} {team.tpm_limit ? team.tpm_limit : "Unlimited"}{" "} -

RPM Limit:{" "} +

RPM Limit:{" "} {team.rpm_limit ? team.rpm_limit : "Unlimited"}
- + {/* - + */}
)) : null} @@ -293,7 +297,7 @@ const Team: React.FC = ({ Member Name Role - Action + {/* Action */} @@ -310,9 +314,9 @@ const Team: React.FC = ({ : null} {member["role"]} - + {/* - + */} ) ) From 7e3b09d0522e4193ae4456cd26e1936e73df61f6 Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Thu, 28 Mar 2024 08:12:35 -0700 Subject: [PATCH 25/54] (fix) update ui --- ui/litellm-dashboard/src/components/navbar.tsx | 3 --- 1 file changed, 3 deletions(-) diff --git a/ui/litellm-dashboard/src/components/navbar.tsx b/ui/litellm-dashboard/src/components/navbar.tsx index 753497e3b..ae27d51d8 100644 --- a/ui/litellm-dashboard/src/components/navbar.tsx +++ b/ui/litellm-dashboard/src/components/navbar.tsx @@ -59,9 +59,6 @@ const Navbar: React.FC = ({ target="_blank" className="mr-2" > -
) : null} From 76810e9217bec9865afd1a46d80e7b9f5c1e09c0 Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Thu, 28 Mar 2024 08:13:08 -0700 Subject: [PATCH 26/54] (feat) new ui build --- litellm/proxy/_experimental/out/404.html | 2 +- ...{layout-a188d05d2ecab3a2.js => layout-24ae10436e315256.js} | 2 +- .../out/_next/static/chunks/app/page-144687b251040a22.js | 1 - .../out/_next/static/chunks/app/page-2b5b48b67d7eccff.js | 1 + ...n-app-096338c8e1915716.js => main-app-9b4fb13a7db53edf.js} | 2 +- .../_buildManifest.js | 0 .../_ssgManifest.js | 0 litellm/proxy/_experimental/out/index.html | 2 +- litellm/proxy/_experimental/out/index.txt | 4 ++-- ui/litellm-dashboard/out/404.html | 2 +- .../out/_next/static/chunks/app/layout-24ae10436e315256.js | 1 + .../out/_next/static/chunks/app/page-2b5b48b67d7eccff.js | 1 + .../out/_next/static/chunks/main-app-9b4fb13a7db53edf.js | 1 + .../out/_next/static/tpFpoAscsg2XQqXwfShjz/_buildManifest.js | 1 + .../out/_next/static/tpFpoAscsg2XQqXwfShjz/_ssgManifest.js | 1 + ui/litellm-dashboard/out/index.html | 2 +- ui/litellm-dashboard/out/index.txt | 4 ++-- 17 files changed, 16 insertions(+), 11 deletions(-) rename litellm/proxy/_experimental/out/_next/static/chunks/app/{layout-a188d05d2ecab3a2.js => layout-24ae10436e315256.js} (60%) delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/app/page-144687b251040a22.js create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/app/page-2b5b48b67d7eccff.js rename litellm/proxy/_experimental/out/_next/static/chunks/{main-app-096338c8e1915716.js => main-app-9b4fb13a7db53edf.js} (54%) rename litellm/proxy/_experimental/out/_next/static/{aIO8mtlEIEUTmgL8cGjve => tpFpoAscsg2XQqXwfShjz}/_buildManifest.js (100%) rename litellm/proxy/_experimental/out/_next/static/{aIO8mtlEIEUTmgL8cGjve => tpFpoAscsg2XQqXwfShjz}/_ssgManifest.js (100%) create mode 100644 ui/litellm-dashboard/out/_next/static/chunks/app/layout-24ae10436e315256.js create mode 100644 ui/litellm-dashboard/out/_next/static/chunks/app/page-2b5b48b67d7eccff.js create mode 100644 ui/litellm-dashboard/out/_next/static/chunks/main-app-9b4fb13a7db53edf.js create mode 100644 ui/litellm-dashboard/out/_next/static/tpFpoAscsg2XQqXwfShjz/_buildManifest.js create mode 100644 ui/litellm-dashboard/out/_next/static/tpFpoAscsg2XQqXwfShjz/_ssgManifest.js diff --git a/litellm/proxy/_experimental/out/404.html b/litellm/proxy/_experimental/out/404.html index 423a55d1f..99d054e9c 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

404

This page could not be found.

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

404

This page could not be found.

\ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/app/layout-a188d05d2ecab3a2.js b/litellm/proxy/_experimental/out/_next/static/chunks/app/layout-24ae10436e315256.js similarity index 60% rename from litellm/proxy/_experimental/out/_next/static/chunks/app/layout-a188d05d2ecab3a2.js rename to litellm/proxy/_experimental/out/_next/static/chunks/app/layout-24ae10436e315256.js index fe5260feb..e261adc05 100644 --- a/litellm/proxy/_experimental/out/_next/static/chunks/app/layout-a188d05d2ecab3a2.js +++ b/litellm/proxy/_experimental/out/_next/static/chunks/app/layout-24ae10436e315256.js @@ -1 +1 @@ -(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[185],{11837:function(n,e,t){Promise.resolve().then(t.t.bind(t,99646,23)),Promise.resolve().then(t.t.bind(t,63385,23))},63385:function(){},99646:function(n){n.exports={style:{fontFamily:"'__Inter_c23dc8', '__Inter_Fallback_c23dc8'",fontStyle:"normal"},className:"__className_c23dc8"}}},function(n){n.O(0,[971,69,744],function(){return n(n.s=11837)}),_N_E=n.O()}]); \ No newline at end of file +(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[185],{87421:function(n,e,t){Promise.resolve().then(t.t.bind(t,99646,23)),Promise.resolve().then(t.t.bind(t,63385,23))},63385:function(){},99646:function(n){n.exports={style:{fontFamily:"'__Inter_c23dc8', '__Inter_Fallback_c23dc8'",fontStyle:"normal"},className:"__className_c23dc8"}}},function(n){n.O(0,[971,69,744],function(){return n(n.s=87421)}),_N_E=n.O()}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/app/page-144687b251040a22.js b/litellm/proxy/_experimental/out/_next/static/chunks/app/page-144687b251040a22.js deleted file mode 100644 index 761b3cd14..000000000 --- a/litellm/proxy/_experimental/out/_next/static/chunks/app/page-144687b251040a22.js +++ /dev/null @@ -1 +0,0 @@ -(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[931],{79615:function(e,t,s){Promise.resolve().then(s.bind(s,19914))},19914:function(e,t,s){"use strict";s.r(t),s.d(t,{default:function(){return eM}});var l=s(3827),r=s(64090),n=s(47907),a=s(8792),o=s(2179),i=e=>{let{userID:t,userRole:s,userEmail:r,showSSOBanner:n}=e;return console.log("User ID:",t),console.log("userEmail:",r),(0,l.jsxs)("nav",{className:"left-0 right-0 top-0 flex justify-between items-center h-12 mb-4",children:[(0,l.jsx)("div",{className:"text-left my-2 absolute top-0 left-0",children:(0,l.jsx)("div",{className:"flex flex-col items-center",children:(0,l.jsx)(a.default,{href:"/",children:(0,l.jsx)("button",{className:"text-gray-800 text-2xl py-1 rounded text-center",children:(0,l.jsx)("img",{src:"/get_image",width:200,height:200,alt:"LiteLLM Brand",className:"mr-2"})})})})}),(0,l.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,l.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/ui#setup-ssoauth-for-ui",target:"_blank",className:"mr-2",children:(0,l.jsx)(o.Z,{variant:"primary",size:"lg",children:"Enable SSO"})}):null,(0,l.jsxs)(o.Z,{variant:"secondary",size:"lg",children:[r,(0,l.jsxs)("p",{children:["Role: ",s]}),(0,l.jsxs)("p",{children:["ID: ",t]})]})]})]})},c=s(80588);let d=async(e,t,s)=>{try{if(console.log("Form Values in keyCreateCall:",s),s.description&&(s.metadata||(s.metadata={}),s.metadata.description=s.description,delete s.description,s.metadata=JSON.stringify(s.metadata)),s.metadata){console.log("formValues.metadata:",s.metadata);try{s.metadata=JSON.parse(s.metadata)}catch(e){throw c.ZP.error("Failed to parse metadata: "+e),Error("Failed to parse metadata: "+e)}}console.log("Form Values after check:",s);let l=await fetch("/key/generate",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({user_id:t,...s})});if(!l.ok){let e=await l.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let r=await l.json();return console.log("API Response:",r),r}catch(e){throw console.error("Failed to create key:",e),e}},h=async(e,t,s)=>{try{if(console.log("Form Values in keyCreateCall:",s),s.description&&(s.metadata||(s.metadata={}),s.metadata.description=s.description,delete s.description,s.metadata=JSON.stringify(s.metadata)),s.metadata){console.log("formValues.metadata:",s.metadata);try{s.metadata=JSON.parse(s.metadata)}catch(e){throw c.ZP.error("Failed to parse metadata: "+e),Error("Failed to parse metadata: "+e)}}console.log("Form Values after check:",s);let l=await fetch("/user/new",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({user_id:t,...s})});if(!l.ok){let e=await l.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let r=await l.json();return console.log("API Response:",r),r}catch(e){throw console.error("Failed to create key:",e),e}},m=async(e,t)=>{try{console.log("in keyDeleteCall:",t);let s=await fetch("/key/delete",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({keys:[t]})});if(!s.ok){let e=await s.text();throw c.ZP.error("Failed to delete key: "+e),Error("Network response was not ok")}let l=await s.json();return console.log(l),l}catch(e){throw console.error("Failed to create key:",e),e}},u=async function(e,t,s){let l=arguments.length>3&&void 0!==arguments[3]&&arguments[3];try{let r="/user/info";"App Owner"==s&&t&&(r="".concat(r,"?user_id=").concat(t)),console.log("in userInfoCall viewAll=",l),l&&(r="".concat(r,"?view_all=true"));let n=await fetch(r,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!n.ok){let e=await n.text();throw c.ZP.error(e),Error("Network response was not ok")}let a=await n.json();return console.log("API Response:",a),a}catch(e){throw console.error("Failed to create key:",e),e}},x=async e=>{try{let t=await fetch("/global/spend",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},p=async(e,t,s)=>{try{let t=await fetch("/v2/model/info",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},j=async(e,t,s)=>{try{let t=await fetch("/model/metrics",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},y=async(e,t,s)=>{try{let t=await fetch("/models",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},g=async(e,t)=>{try{let s="/global/spend/logs";console.log("in keySpendLogsCall:",s);let l=await fetch("".concat(s,"?api_key=").concat(t),{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw c.ZP.error(e),Error("Network response was not ok")}let r=await l.json();return console.log(r),r}catch(e){throw console.error("Failed to create key:",e),e}},w=async e=>{try{let t="/global/spend/teams";console.log("in teamSpendLogsCall:",t);let s=await fetch("".concat(t),{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!s.ok){let e=await s.text();throw c.ZP.error(e),Error("Network response was not ok")}let l=await s.json();return console.log(l),l}catch(e){throw console.error("Failed to create key:",e),e}},Z=async(e,t,s,l,r,n)=>{try{console.log("user role in spend logs call: ".concat(s));let t="/spend/logs";t="App Owner"==s?"".concat(t,"?user_id=").concat(l,"&start_date=").concat(r,"&end_date=").concat(n):"".concat(t,"?start_date=").concat(r,"&end_date=").concat(n);let a=await fetch(t,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!a.ok){let e=await a.text();throw c.ZP.error(e),Error("Network response was not ok")}let o=await a.json();return console.log(o),o}catch(e){throw console.error("Failed to create key:",e),e}},f=async e=>{try{let t=await fetch("/global/spend/logs",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to create key:",e),e}},k=async e=>{try{let t=await fetch("/global/spend/keys?limit=5",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to create key:",e),e}},_=async(e,t)=>{try{t&&JSON.stringify({api_key:t});let s={method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}};t&&(s.body=JSON.stringify({api_key:t}));let l=await fetch("/global/spend/end_users",s);if(!l.ok){let e=await l.text();throw c.ZP.error(e),Error("Network response was not ok")}let r=await l.json();return console.log(r),r}catch(e){throw console.error("Failed to create key:",e),e}},b=async e=>{try{let t=await fetch("/global/spend/models?limit=5",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to create key:",e),e}},v=async(e,t)=>{try{let s=await fetch("/v2/key/info",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({keys:t})});if(!s.ok){let e=await s.text();throw c.ZP.error(e),Error("Network response was not ok")}let l=await s.json();return console.log(l),l}catch(e){throw console.error("Failed to create key:",e),e}},S=async(e,t,s,l)=>{try{let r=await fetch("/user/request_model",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({models:[t],user_id:s,justification:l})});if(!r.ok){let e=await r.text();throw c.ZP.error("Failed to delete key: "+e),Error("Network response was not ok")}let n=await r.json();return console.log(n),n}catch(e){throw console.error("Failed to create key:",e),e}},N=async e=>{try{let t="/user/get_requests";console.log("in userGetRequesedtModelsCall:",t);let s=await fetch(t,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!s.ok){let e=await s.text();throw c.ZP.error("Failed to delete key: "+e),Error("Network response was not ok")}let l=await s.json();return console.log(l),l}catch(e){throw console.error("Failed to get requested models:",e),e}},A=async(e,t)=>{try{let s="/user/get_users?role=".concat(t);console.log("in userGetAllUsersCall:",s);let l=await fetch(s,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw c.ZP.error("Failed to delete key: "+e),Error("Network response was not ok")}let r=await l.json();return console.log(r),r}catch(e){throw console.error("Failed to get requested models:",e),e}},C=async(e,t)=>{try{console.log("Form Values in teamCreateCall:",t);let s=await fetch("/team/new",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...t})});if(!s.ok){let e=await s.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let l=await s.json();return console.log("API Response:",l),l}catch(e){throw console.error("Failed to create key:",e),e}},T=async(e,t,s)=>{try{console.log("Form Values in teamMemberAddCall:",s);let l=await fetch("/team/member_add",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({team_id:t,member:s})});if(!l.ok){let e=await l.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let r=await l.json();return console.log("API Response:",r),r}catch(e){throw console.error("Failed to create key:",e),e}},I=async(e,t)=>{try{console.log("Form Values in userUpdateUserCall:",t);let s=await fetch("/user/update",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({user_role:"proxy_admin_viewer",...t})});if(!s.ok){let e=await s.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let l=await s.json();return console.log("API Response:",l),l}catch(e){throw console.error("Failed to create key:",e),e}},E=async(e,t)=>{try{let s=await fetch("/global/predict/spend/logs",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({data:t})});if(!s.ok){let e=await s.text();throw c.ZP.error(e),Error("Network response was not ok")}let l=await s.json();return console.log(l),l}catch(e){throw console.error("Failed to create key:",e),e}},P=async e=>{try{console.log("Checking Slack Budget Alerts service health");let t=await fetch("/health/services?service=slack_budget_alerts",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error("Failed Slack Alert test: "+e),Error(e)}let s=await t.json();return c.ZP.success("Test Slack Alert worked - check your Slack!"),console.log("Service Health Response:",s),s}catch(e){throw console.error("Failed to perform health check:",e),e}};var F=s(10384),O=s(46453),M=s(13810),R=s(71801),D=s(42440),U=s(17189),L=s(12143),B=s(77171),z=s(42539),K=s(88707),V=s(1861);let{Option:W}=U.default;var q=e=>{let{userID:t,teamID:s,userRole:n,accessToken:a,data:i,userModels:h,setData:m}=e,[u]=L.Z.useForm(),[x,p]=(0,r.useState)(!1),[j,y]=(0,r.useState)(null),[g,w]=(0,r.useState)(null),Z=()=>{p(!1),u.resetFields()},f=()=>{p(!1),y(null),u.resetFields()},k=async e=>{try{c.ZP.info("Making API Call"),p(!0);let s=await d(a,t,e);console.log("key create Response:",s),m(e=>e?[...e,s]:[s]),y(s.key),w(s.soft_budget),c.ZP.success("API Key Created"),u.resetFields(),localStorage.removeItem("userData"+t)}catch(e){console.error("Error creating the key:",e)}},_=async()=>{try{console.log("Sending Slack alert...");let e=await P(a);console.log("slackBudgetAlertsHealthCheck Response:",e),console.log("Testing Slack alert successful")}catch(e){console.error("Error sending Slack alert:",e)}};return(0,l.jsxs)("div",{children:[(0,l.jsx)(o.Z,{className:"mx-auto",onClick:()=>p(!0),children:"+ Create New Key"}),(0,l.jsx)(B.Z,{title:"Create Key",visible:x,width:800,footer:null,onOk:Z,onCancel:f,children:(0,l.jsxs)(L.Z,{form:u,onFinish:k,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:["App Owner"===n||"Admin"===n?(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(L.Z.Item,{label:"Key Name",name:"key_alias",children:(0,l.jsx)(z.Z,{})}),(0,l.jsx)(L.Z.Item,{label:"Team ID",name:"team_id",children:(0,l.jsx)(z.Z,{placeholder:"ai_team",defaultValue:s||""})}),(0,l.jsx)(L.Z.Item,{label:"Models",name:"models",children:(0,l.jsx)(U.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:h.map(e=>(0,l.jsx)(W,{value:e,children:e},e))})}),(0,l.jsx)(L.Z.Item,{label:"Soft Budget (USD) Monthly",name:"soft_budget",initialValue:50,children:(0,l.jsx)(K.Z,{step:.01,precision:2,defaultValue:50,width:200})}),(0,l.jsx)(L.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,l.jsx)(K.Z,{step:.01,precision:2,width:200})}),(0,l.jsx)(L.Z.Item,{label:"Reset Budget",name:"budget_duration",children:(0,l.jsxs)(U.default,{defaultValue:null,placeholder:"n/a",children:[(0,l.jsx)(U.default.Option,{value:"24h",children:"daily"}),(0,l.jsx)(U.default.Option,{value:"30d",children:"monthly"})]})}),(0,l.jsx)(L.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})}),(0,l.jsx)(L.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})}),(0,l.jsx)(L.Z.Item,{label:"Expire Key (eg: 30s, 30h, 30d)",name:"duration",children:(0,l.jsx)(z.Z,{})}),(0,l.jsx)(L.Z.Item,{label:"Metadata",name:"metadata",children:(0,l.jsx)(z.Z.TextArea,{rows:4,placeholder:"Enter metadata as JSON"})})]}):(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(L.Z.Item,{label:"Key Name",name:"key_alias",children:(0,l.jsx)(z.Z,{})}),(0,l.jsx)(L.Z.Item,{label:"Team ID (Contact Group)",name:"team_id",children:(0,l.jsx)(z.Z,{placeholder:"ai_team"})}),(0,l.jsx)(L.Z.Item,{label:"Description",name:"description",children:(0,l.jsx)(z.Z.TextArea,{placeholder:"Enter description",rows:4})})]}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(V.ZP,{htmlType:"submit",children:"Create Key"})})]})}),j&&(0,l.jsx)(B.Z,{visible:x,onOk:Z,onCancel:f,footer:null,children:(0,l.jsx)(O.Z,{numItems:1,className:"gap-2 w-full",children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Save your Key"}),(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsxs)("p",{children:["Please save this secret key somewhere safe and accessible. For security reasons, ",(0,l.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,l.jsx)(F.Z,{numColSpan:1,children:null!=j?(0,l.jsxs)("div",{children:[(0,l.jsxs)(R.Z,{children:["API Key: ",j]}),(0,l.jsx)(D.Z,{className:"mt-6",children:"Budgets"}),(0,l.jsxs)(R.Z,{children:["Soft Limit Budget: $",g]}),(0,l.jsx)(o.Z,{className:"mt-3",onClick:_,children:"Test Slack Alert"}),(0,l.jsxs)(R.Z,{className:"mt-2",children:["(LiteLLM Docs -",(0,l.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/alerting",target:"_blank",className:"text-blue-500",children:"Set Up Slack Alerting)"})]})]}):(0,l.jsx)(R.Z,{children:"Key being created, this might take 30s"})})]})})})]})},G=s(33393),J=s(61244),$=s(10827),H=s(3851),Y=s(2044),X=s(64167),Q=s(74480),ee=s(7178),et=s(9853),es=s(56863),el=e=>{let{token:t,accessToken:s,keySpend:n,keyBudget:a,keyName:i}=e,[c,d]=(0,r.useState)(!1),[h,m]=(0,r.useState)(null),[u,x]=(0,r.useState)(""),[p,j]=(0,r.useState)(null),y=async()=>{try{if(null==s||null==t)return;console.log("accessToken: ".concat(s,"; token: ").concat(t));let e=await g(s,t);console.log("Response:",e),m(e);let l=await E(s,e);console.log("Response2:",l);let r=[...e,...l.response];m(r),x(l.predicted_spend),console.log("Combined Data:",r)}catch(e){console.error("There was an error fetching the data",e)}};return t?(0,l.jsxs)("div",{children:[(0,l.jsx)(o.Z,{size:"xs",onClick:()=>{console.log("Show Modal triggered"),d(!0),y()},variant:"secondary",children:"Spend Report"}),(0,l.jsxs)(B.Z,{visible:c,width:1400,onOk:()=>{d(!1)},onCancel:()=>{d(!1)},footer:null,children:[(0,l.jsxs)(D.Z,{style:{textAlign:"left"},children:["Key Name: ",i]}),(0,l.jsxs)(es.Z,{children:["Monthly Spend $",n]}),(0,l.jsx)(D.Z,{children:u}),(0,l.jsx)(M.Z,{className:"mt-6 mb-6",children:h&&(0,l.jsx)(et.Z,{className:"mt-6",data:h,colors:["blue","amber"],index:"date",categories:["spend","predicted_spend"],yAxisWidth:80})})]})]}):null},er=e=>{let{userID:t,accessToken:s,data:n,setData:a}=e,[i,c]=(0,r.useState)(!1),[d,h]=(0,r.useState)(!1),[u,x]=(0,r.useState)(null),p=async e=>{null!=n&&(x(e),localStorage.removeItem("userData"+t),h(!0))},j=async()=>{if(null!=u&&null!=n){try{await m(s,u);let e=n.filter(e=>e.token!==u);a(e)}catch(e){console.error("Error deleting the key:",e)}h(!1),x(null)}};if(null!=n)return console.log("RERENDER TRIGGERED"),(0,l.jsxs)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh] mb-4",children:[(0,l.jsxs)($.Z,{className:"mt-5",children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"Key Alias"}),(0,l.jsx)(Q.Z,{children:"Secret Key"}),(0,l.jsx)(Q.Z,{children:"Spend (USD)"}),(0,l.jsx)(Q.Z,{children:"Key Budget (USD)"}),(0,l.jsx)(Q.Z,{children:"Spend Report"}),(0,l.jsx)(Q.Z,{children:"Team ID"}),(0,l.jsx)(Q.Z,{children:"Metadata"}),(0,l.jsx)(Q.Z,{children:"Models"}),(0,l.jsx)(Q.Z,{children:"TPM / RPM Limits"}),(0,l.jsx)(Q.Z,{children:"Expires"})]})}),(0,l.jsx)(H.Z,{children:n.map(e=>(console.log(e),"litellm-dashboard"===e.team_id)?null:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",whiteSpace:"pre-wrap",overflow:"hidden"},children:null!=e.key_alias?(0,l.jsx)(R.Z,{children:e.key_alias}):(0,l.jsx)(R.Z,{children:"Not Set"})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:e.key_name})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:(()=>{try{return parseFloat(e.spend).toFixed(4)}catch(t){return e.spend}})()})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",whiteSpace:"pre-wrap",overflow:"hidden"},children:null!=e.max_budget?(0,l.jsx)(R.Z,{children:e.max_budget}):(0,l.jsx)(R.Z,{children:"Unlimited Budget"})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px"},children:(0,l.jsx)(el,{token:e.token,accessToken:s,keySpend:e.spend,keyBudget:e.max_budget,keyName:e.key_name})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:e.team_id})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:JSON.stringify(e.metadata).slice(0,400)})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:JSON.stringify(e.models)})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",overflowWrap:"break-word"},children:(0,l.jsxs)(R.Z,{children:["TPM Limit: ",e.tpm_limit?e.tpm_limit:"Unlimited"," ",(0,l.jsx)("br",{})," RPM Limit:"," ",e.rpm_limit?e.rpm_limit:"Unlimited"]})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",wordWrap:"break-word"},children:null!=e.expires?(0,l.jsx)(R.Z,{children:e.expires}):(0,l.jsx)(R.Z,{children:"Never"})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",wordWrap:"break-word"},children:(0,l.jsx)(J.Z,{onClick:()=>p(e.token),icon:G.Z,size:"sm"})})]},e.token))})]}),d&&(0,l.jsx)("div",{className:"fixed z-10 inset-0 overflow-y-auto",children:(0,l.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,l.jsx)("div",{className:"fixed inset-0 transition-opacity","aria-hidden":"true",children:(0,l.jsx)("div",{className:"absolute inset-0 bg-gray-500 opacity-75"})}),(0,l.jsx)("span",{className:"hidden sm:inline-block sm:align-middle sm:h-screen","aria-hidden":"true",children:"​"}),(0,l.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,l.jsx)("div",{className:"bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4",children:(0,l.jsx)("div",{className:"sm:flex sm:items-start",children:(0,l.jsxs)("div",{className:"mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left",children:[(0,l.jsx)("h3",{className:"text-lg leading-6 font-medium text-gray-900",children:"Delete Key"}),(0,l.jsx)("div",{className:"mt-2",children:(0,l.jsx)("p",{className:"text-sm text-gray-500",children:"Are you sure you want to delete this key ?"})})]})})}),(0,l.jsxs)("div",{className:"bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse",children:[(0,l.jsx)(o.Z,{onClick:j,color:"red",className:"ml-2",children:"Delete"}),(0,l.jsx)(o.Z,{onClick:()=>{h(!1),x(null)},children:"Cancel"})]})]})]})})]})},en=e=>{let{userID:t,userSpendData:s,userRole:n,accessToken:a}=e,[o,i]=(0,r.useState)(null==s?void 0:s.spend),[c,d]=(0,r.useState)((null==s?void 0:s.max_budget)||null);(0,r.useEffect)(()=>{(async()=>{if("Admin"===n)try{let e=await x(a);i(e.spend),d(e.max_budget||null)}catch(e){console.error("Error fetching global spend data:",e)}})()},[n,a]);let h=void 0!==o?o.toFixed(4):null;return(0,l.jsx)(l.Fragment,{children:(0,l.jsxs)(M.Z,{className:"mx-auto mb-4",children:[(0,l.jsxs)(es.Z,{children:["$",h]}),(0,l.jsxs)(D.Z,{children:["/ ",null!==c?"$".concat(c," limit"):"No limit"]})]})})},ea=s(36083),eo=s(68967),ei=s(27166),ec=e=>{let{teams:t,setSelectedTeam:s}=e,{Title:n,Paragraph:a}=ea.default,[o,i]=(0,r.useState)("");return(0,l.jsxs)("div",{className:"mt-10",children:[(0,l.jsx)(n,{level:4,children:"Default Team"}),(0,l.jsx)(a,{children:"If you belong to multiple teams, this setting controls which team is used by default when creating new API Keys."}),t&&t.length>0?(0,l.jsx)(eo.Z,{defaultValue:"0",children:t.map((e,t)=>(0,l.jsx)(ei.Z,{value:String(t),onClick:()=>s(e),children:e.team_alias},t))}):(0,l.jsxs)(a,{children:["No team created. ",(0,l.jsx)("b",{children:"Defaulting to personal account."})]})]})},ed=s(37963);console.log("isLocal:",!1);var eh=e=>{let{userID:t,userRole:s,teams:a,keys:o,setUserRole:i,userEmail:c,setUserEmail:d,setTeams:h,setKeys:m}=e,[p,j]=(0,r.useState)(null),g=(0,n.useSearchParams)();g.get("viewSpend"),(0,n.useRouter)();let w=g.get("token"),[Z,f]=(0,r.useState)(null),[k,_]=(0,r.useState)([]),[b,v]=(0,r.useState)(a?a[0]:null);if(window.addEventListener("beforeunload",function(){sessionStorage.clear()}),(0,r.useEffect)(()=>{if(w){let e=(0,ed.o)(w);if(e){if(console.log("Decoded token:",e),console.log("Decoded key:",e.key),f(e.key),e.user_role){let t=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";default:return"Unknown Role"}}(e.user_role);console.log("Decoded user_role:",t),i(t)}else console.log("User role not defined");e.user_email?d(e.user_email):console.log("User Email is not set ".concat(e))}}if(t&&Z&&s&&!o&&!p){let e=sessionStorage.getItem("userModels"+t);e?_(JSON.parse(e)):(async()=>{try{let e=await u(Z,t,s);if(console.log("received teams in user dashboard: ".concat(Object.keys(e),"; team values: ").concat(Object.entries(e.teams))),"Admin"==s){let e=await x(Z);j(e),console.log("globalSpend:",e)}else j(e.user_info);m(e.keys),h(e.teams),v(e.teams?e.teams[0]:null),sessionStorage.setItem("userData"+t,JSON.stringify(e.keys)),sessionStorage.setItem("userSpendData"+t,JSON.stringify(e.user_info));let l=(await y(Z,t,s)).data.map(e=>e.id);console.log("available_model_names:",l),_(l),console.log("userModels:",k),sessionStorage.setItem("userModels"+t,JSON.stringify(l))}catch(e){console.error("There was an error fetching the data",e)}})()}},[t,w,Z,o,s]),null==t||null==w){let e="/sso/key/generate";return console.log("Full URL:",e),window.location.href=e,null}if(null==Z)return null;if(null==s&&i("App Owner"),s&&"Admin Viewer"==s){let{Title:e,Paragraph:t}=ea.default;return(0,l.jsxs)("div",{children:[(0,l.jsx)(e,{level:1,children:"Access Denied"}),(0,l.jsx)(t,{children:"Ask your proxy admin for access to create keys"})]})}return(0,l.jsx)("div",{children:(0,l.jsx)(O.Z,{numItems:1,className:"gap-0 p-10 h-[75vh] w-full",children:(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(en,{userID:t,userSpendData:p,userRole:s,accessToken:Z}),(0,l.jsx)(er,{userID:t,accessToken:Z,data:o,setData:m}),(0,l.jsx)(q,{userID:t,teamID:b?b.team_id:null,userRole:s,userModels:k,accessToken:Z,data:o,setData:m}),(0,l.jsx)(ec,{teams:a,setSelectedTeam:v})]})})})},em=s(5);let{Option:eu}=U.default;var ex=e=>{let{userModels:t,accessToken:s,userID:n}=e,[a]=L.Z.useForm(),[i,d]=(0,r.useState)(!1),h=async e=>{try{c.ZP.info("Requesting access");let{selectedModel:t,accessReason:l}=e;await S(s,t,n,l),d(!0)}catch(e){console.error("Error requesting access:",e)}};return(0,l.jsxs)("div",{children:[(0,l.jsx)(o.Z,{size:"xs",onClick:()=>d(!0),children:"Request Access"}),(0,l.jsx)(B.Z,{title:"Request Access",visible:i,width:800,footer:null,onOk:()=>{d(!1),a.resetFields()},onCancel:()=>{d(!1),a.resetFields()},children:(0,l.jsxs)(L.Z,{form:a,onFinish:h,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsx)(L.Z.Item,{label:"Select Model",name:"selectedModel",children:(0,l.jsx)(U.default,{placeholder:"Select model",style:{width:"100%"},children:t.map(e=>(0,l.jsx)(eu,{value:e,children:e},e))})}),(0,l.jsx)(L.Z.Item,{label:"Reason for Access",name:"accessReason",children:(0,l.jsx)(z.Z.TextArea,{rows:4,placeholder:"Enter reason for access"})}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(o.Z,{children:"Request Access"})})]})})]})},ep=e=>{let{accessToken:t,token:s,userRole:n,userID:a}=e,[o,i]=(0,r.useState)({data:[]}),[c,d]=(0,r.useState)([]),[h,m]=(0,r.useState)([]);if((0,r.useEffect)(()=>{if(!t||!s||!n||!a)return;let e=async()=>{try{let e=await p(t,a,n);console.log("Model data response:",e.data),i(e);let s=await j(t,a,n);if(console.log("Model metrics response:",s),d(s),"Admin"===n&&t){let e=await N(t);console.log("Pending Requests:",h),m(e.requests||[])}}catch(e){console.error("There was an error fetching the model data",e)}};t&&s&&n&&a&&e()},[t,s,n,a]),!o||!t||!s||!n||!a)return(0,l.jsx)("div",{children:"Loading..."});let u=[];for(let e=0;e(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{children:(0,l.jsx)(D.Z,{children:e.model_name})}),(0,l.jsx)(Y.Z,{children:e.provider}),"Admin"===n&&(0,l.jsx)(Y.Z,{children:e.api_base}),(0,l.jsx)(Y.Z,{children:e.user_access?(0,l.jsx)(em.Z,{color:"green",children:"Yes"}):(0,l.jsx)(ex,{userModels:u,accessToken:t,userID:a})}),(0,l.jsx)(Y.Z,{children:e.input_cost}),(0,l.jsx)(Y.Z,{children:e.output_cost}),(0,l.jsx)(Y.Z,{children:e.max_tokens})]},e.model_name))})]})}),(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Model Statistics (Number Requests)"}),(0,l.jsx)(et.Z,{data:c,index:"model",categories:["num_requests"],colors:["blue"],yAxisWidth:400,layout:"vertical",tickGap:5})]}),(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Model Statistics (Latency)"}),(0,l.jsx)(et.Z,{data:c,index:"model",categories:["avg_latency_seconds"],colors:["red"],yAxisWidth:400,layout:"vertical",tickGap:5})]})]})})},ej=s(92836),ey=s(26734),eg=s(41608),ew=s(32126),eZ=s(23682);let{Option:ef}=U.default;var ek=e=>{let{userID:t,accessToken:s}=e,[n]=L.Z.useForm(),[a,i]=(0,r.useState)(!1),[d,m]=(0,r.useState)(null),[u,x]=(0,r.useState)([]);(0,r.useEffect)(()=>{(async()=>{try{let e=await y(s,t,"any"),l=[];for(let t=0;t{i(!1),n.resetFields()},j=()=>{i(!1),m(null),n.resetFields()},g=async e=>{try{c.ZP.info("Making API Call"),i(!0),console.log("formValues in create user:",e);let l=await h(s,t,e);console.log("user create Response:",l),m(l.key),c.ZP.success("API user Created"),n.resetFields(),localStorage.removeItem("userData"+t)}catch(e){console.error("Error creating the user:",e)}};return(0,l.jsxs)("div",{children:[(0,l.jsx)(o.Z,{className:"mx-auto",onClick:()=>i(!0),children:"+ Create New User"}),(0,l.jsx)(B.Z,{title:"Create User",visible:a,width:800,footer:null,onOk:p,onCancel:j,children:(0,l.jsxs)(L.Z,{form:n,onFinish:g,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsx)(L.Z.Item,{label:"User ID",name:"user_id",children:(0,l.jsx)(z.Z,{placeholder:"Enter User ID"})}),(0,l.jsx)(L.Z.Item,{label:"Team ID",name:"team_id",children:(0,l.jsx)(z.Z,{placeholder:"ai_team"})}),(0,l.jsx)(L.Z.Item,{label:"Models",name:"models",children:(0,l.jsx)(U.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:u.map(e=>(0,l.jsx)(ef,{value:e,children:e},e))})}),(0,l.jsx)(L.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,l.jsx)(K.Z,{step:.01,precision:2,width:200})}),(0,l.jsx)(L.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})}),(0,l.jsx)(L.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})}),(0,l.jsx)(L.Z.Item,{label:"Duration (eg: 30s, 30h, 30d)",name:"duration",children:(0,l.jsx)(z.Z,{})}),(0,l.jsx)(L.Z.Item,{label:"Metadata",name:"metadata",children:(0,l.jsx)(z.Z.TextArea,{rows:4,placeholder:"Enter metadata as JSON"})}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(V.ZP,{htmlType:"submit",children:"Create User"})})]})}),d&&(0,l.jsxs)(B.Z,{title:"Save Your User",visible:a,onOk:p,onCancel:j,footer:null,children:[(0,l.jsxs)("p",{children:["Please save this secret user somewhere safe and accessible. For security reasons, ",(0,l.jsx)("b",{children:"you will not be able to view it again"})," ","through your LiteLLM account. If you lose this secret user, you will need to generate a new one."]}),(0,l.jsx)("p",{children:null!=d?"API user: ".concat(d):"User being created, this might take 30s"})]})]})},e_=e=>{let{accessToken:t,token:s,keys:n,userRole:a,userID:o,setKeys:i}=e,[c,d]=(0,r.useState)(null),[h,m]=(0,r.useState)(null),[x,p]=(0,r.useState)(1);if((0,r.useEffect)(()=>{if(!t||!s||!a||!o)return;let e=async()=>{try{let e=await u(t,null,a,!0);console.log("user data response:",e),d(e)}catch(e){console.error("There was an error fetching the model data",e)}};t&&s&&a&&o&&!c&&e();let l=async()=>{try{let e=await _(t,null);console.log("user data response:",e),m(e)}catch(e){console.error("There was an error fetching the model data",e)}};a&&("Admin"==a||"Admin Viewer"==a)&&!h&&l()},[t,s,a,o]),!c||!t||!s||!a||!o)return(0,l.jsx)("div",{children:"Loading..."});let j=async e=>{try{let s=await _(t,e);console.log("user data response:",s),m(s)}catch(e){console.error("There was an error fetching the model data",e)}};return(0,l.jsx)("div",{style:{width:"100%"},children:(0,l.jsxs)(O.Z,{className:"gap-2 p-10 h-[75vh] w-full",children:[(0,l.jsx)(ek,{userID:o,accessToken:t}),(0,l.jsx)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh] mb-4",children:(0,l.jsxs)(ey.Z,{children:[(0,l.jsxs)(eg.Z,{variant:"line",defaultValue:"1",children:[(0,l.jsx)(ej.Z,{value:"1",children:"Key Owners"}),(0,l.jsx)(ej.Z,{value:"2",children:"End-Users"})]}),(0,l.jsxs)(eZ.Z,{children:[(0,l.jsx)(ew.Z,{children:(0,l.jsxs)($.Z,{className:"mt-5",children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"User ID"}),(0,l.jsx)(Q.Z,{children:"User Role"}),(0,l.jsx)(Q.Z,{children:"User Models"}),(0,l.jsx)(Q.Z,{children:"User Spend ($ USD)"}),(0,l.jsx)(Q.Z,{children:"User Max Budget ($ USD)"})]})}),(0,l.jsx)(H.Z,{children:c.map(e=>(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{children:e.user_id}),(0,l.jsx)(Y.Z,{children:e.user_role?e.user_role:"app_owner"}),(0,l.jsx)(Y.Z,{children:e.models&&e.models.length>0?e.models:"All Models"}),(0,l.jsx)(Y.Z,{children:e.spend?e.spend:0}),(0,l.jsx)(Y.Z,{children:e.max_budget?e.max_budget:"Unlimited"})]},e.user_id))})]})}),(0,l.jsxs)(ew.Z,{children:[(0,l.jsxs)("div",{className:"flex items-center",children:[(0,l.jsx)("div",{className:"flex-1"}),(0,l.jsxs)("div",{className:"flex-1 flex justify-between items-center",children:[(0,l.jsx)(R.Z,{className:"w-1/4 mr-2 text-right",children:"Key"}),(0,l.jsx)(eo.Z,{defaultValue:"1",className:"w-3/4",children:null==n?void 0:n.map((e,t)=>{if(e&&null!==e.key_name&&e.key_name.length>0)return(0,l.jsx)(ei.Z,{value:String(t),onClick:()=>j(e.token),children:e.key_name},t)})})]})]}),(0,l.jsxs)($.Z,{children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"End User"}),(0,l.jsx)(Q.Z,{children:"Spend"}),(0,l.jsx)(Q.Z,{children:"Total Events"})]})}),(0,l.jsx)(H.Z,{children:null==h?void 0:h.map((e,t)=>(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{children:e.end_user}),(0,l.jsx)(Y.Z,{children:e.total_spend}),(0,l.jsx)(Y.Z,{children:e.total_events})]},t))})]})]})]})]})}),function(){if(!c)return null;let e=Math.ceil(c.length/25),t=Math.min(25*x,c.length);return(0,l.jsxs)("div",{className:"flex justify-between items-center",children:[(0,l.jsxs)("div",{children:["Showing ",(x-1)*25+1," – ",t," of ",c.length]}),(0,l.jsxs)("div",{className:"flex",children:[(0,l.jsx)("button",{className:"bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-l focus:outline-none",disabled:1===x,onClick:()=>p(x-1),children:"← Prev"}),(0,l.jsx)("button",{className:"bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-r focus:outline-none",disabled:x===e,onClick:()=>p(x+1),children:"Next →"})]})]})}()]})})},eb=s(8510),ev=e=>{let{teams:t,searchParams:s,accessToken:n,setTeams:a,userID:i,userRole:d}=e,[h]=L.Z.useForm(),[m]=L.Z.useForm(),{Title:u,Paragraph:x}=ea.default,[p,j]=(0,r.useState)(""),[g,w]=(0,r.useState)(t?t[0]:null),[Z,f]=(0,r.useState)(!1),[k,_]=(0,r.useState)(!1),[b,v]=(0,r.useState)([]);(0,r.useEffect)(()=>{(async()=>{try{if(null===i||null===d)return;if(null!==n){let e=(await y(n,i,d)).data.map(e=>e.id);console.log("available_model_names:",e),v(e)}}catch(e){console.error("Error fetching user models:",e)}})()},[n,i,d]);let S=async e=>{try{if(null!=n){let s=await C(n,e);null!==t?a([...t,s]):a([s]),console.log("response for team create call: ".concat(s)),c.ZP.success("Team created"),f(!1)}}catch(e){console.error("Error creating the key:",e),c.ZP.error("Error creating the team: "+e)}},N=async e=>{try{if(null!=n&&null!=t){c.ZP.info("Making API Call");let s={role:"user",user_email:e.user_email,user_id:e.user_id},l=await T(n,g.team_id,s);console.log("response for team create call: ".concat(l.data));let r=t.findIndex(e=>(console.log("team.team_id=".concat(e.team_id,"; response.data.team_id=").concat(l.data.team_id)),e.team_id===l.data.team_id));if(console.log("foundIndex: ".concat(r)),-1!==r){let e=[...t];e[r]=l.data,a(e),w(l.data)}_(!1)}}catch(e){console.error("Error creating the key:",e)}};return console.log("received teams ".concat(t)),(0,l.jsx)("div",{className:"w-full",children:(0,l.jsxs)(O.Z,{numItems:1,className:"gap-2 p-2 h-[75vh] w-full",children:[(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(u,{level:4,children:"All Teams"}),(0,l.jsx)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,l.jsxs)($.Z,{children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"Team Name"}),(0,l.jsx)(Q.Z,{children:"Spend (USD)"}),(0,l.jsx)(Q.Z,{children:"Budget (USD)"}),(0,l.jsx)(Q.Z,{children:"TPM / RPM Limits"})]})}),(0,l.jsx)(H.Z,{children:t&&t.length>0?t.map(e=>(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{children:e.team_alias}),(0,l.jsx)(Y.Z,{children:e.spend}),(0,l.jsx)(Y.Z,{children:e.max_budget?e.max_budget:"No limit"}),(0,l.jsx)(Y.Z,{children:(0,l.jsxs)(R.Z,{children:["TPM Limit:"," ",e.tpm_limit?e.tpm_limit:"Unlimited"," ",(0,l.jsx)("br",{})," RPM Limit:"," ",e.rpm_limit?e.rpm_limit:"Unlimited"]})}),(0,l.jsx)(Y.Z,{children:(0,l.jsx)(J.Z,{icon:eb.Z,size:"sm"})})]},e.team_id)):null})]})})]}),(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(o.Z,{className:"mx-auto",onClick:()=>f(!0),children:"+ Create New Team"}),(0,l.jsx)(B.Z,{title:"Create Team",visible:Z,width:800,footer:null,onOk:()=>{f(!1),h.resetFields()},onCancel:()=>{f(!1),h.resetFields()},children:(0,l.jsxs)(L.Z,{form:h,onFinish:S,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(L.Z.Item,{label:"Team Name",name:"team_alias",children:(0,l.jsx)(z.Z,{})}),(0,l.jsx)(L.Z.Item,{label:"Models",name:"models",children:(0,l.jsx)(U.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:b.map(e=>(0,l.jsx)(U.default.Option,{value:e,children:e},e))})}),(0,l.jsx)(L.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,l.jsx)(K.Z,{step:.01,precision:2,width:200})}),(0,l.jsx)(L.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})}),(0,l.jsx)(L.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})})]}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(V.ZP,{htmlType:"submit",children:"Create Team"})})]})})]}),(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(u,{level:4,children:"Team Members"}),(0,l.jsx)(x,{children:"If you belong to multiple teams, this setting controls which teams members you see."}),t&&t.length>0?(0,l.jsx)(eo.Z,{defaultValue:"0",children:t.map((e,t)=>(0,l.jsx)(ei.Z,{value:String(t),onClick:()=>{w(e)},children:e.team_alias},t))}):(0,l.jsxs)(x,{children:["No team created. ",(0,l.jsx)("b",{children:"Defaulting to personal account."})]})]}),(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsx)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,l.jsxs)($.Z,{children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"Member Name"}),(0,l.jsx)(Q.Z,{children:"Role"}),(0,l.jsx)(Q.Z,{children:"Action"})]})}),(0,l.jsx)(H.Z,{children:g?g.members_with_roles.map((e,t)=>(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{children:e.user_email?e.user_email:e.user_id?e.user_id:null}),(0,l.jsx)(Y.Z,{children:e.role}),(0,l.jsx)(Y.Z,{children:(0,l.jsx)(J.Z,{icon:eb.Z,size:"sm"})})]},t)):null})]})})}),(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(o.Z,{className:"mx-auto mb-5",onClick:()=>_(!0),children:"+ Add member"}),(0,l.jsx)(B.Z,{title:"Add member",visible:k,width:800,footer:null,onOk:()=>{_(!1),m.resetFields()},onCancel:()=>{_(!1),m.resetFields()},children:(0,l.jsxs)(L.Z,{form:h,onFinish:N,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(L.Z.Item,{label:"Email",name:"user_email",className:"mb-4",children:(0,l.jsx)(z.Z,{name:"user_email",className:"px-3 py-2 border rounded-md w-full"})}),(0,l.jsx)("div",{className:"text-center mb-4",children:"OR"}),(0,l.jsx)(L.Z.Item,{label:"User ID",name:"user_id",className:"mb-4",children:(0,l.jsx)(z.Z,{name:"user_id",className:"px-3 py-2 border rounded-md w-full"})})]}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(V.ZP,{htmlType:"submit",children:"Add member"})})]})})]})]})})},eS=e=>{let{searchParams:t,accessToken:s}=e,[n]=L.Z.useForm(),[a]=L.Z.useForm(),{Title:i,Paragraph:d}=ea.default,[h,m]=(0,r.useState)(""),[u,x]=(0,r.useState)(null),[p,j]=(0,r.useState)(!1);(0,r.useEffect)(()=>{(async()=>{if(null!=s){let e=[],t=await A(s,"proxy_admin_viewer");t.forEach(t=>{e.push({user_role:t.user_role,user_id:t.user_id,user_email:t.user_email})}),console.log("proxy viewers: ".concat(t));let l=await A(s,"proxy_admin");l.forEach(t=>{e.push({user_role:t.user_role,user_id:t.user_id,user_email:t.user_email})}),console.log("proxy admins: ".concat(l)),console.log("combinedList: ".concat(e)),x(e)}})()},[s]);let y=async e=>{try{if(null!=s&&null!=u){c.ZP.info("Making API Call"),e.user_email,e.user_id;let t=await I(s,e);console.log("response for team create call: ".concat(t));let l=u.findIndex(e=>(console.log("user.user_id=".concat(e.user_id,"; response.user_id=").concat(t.user_id)),e.user_id===t.user_id));console.log("foundIndex: ".concat(l)),-1==l&&(console.log("updates admin with new user"),u.push(t),x(u)),j(!1)}}catch(e){console.error("Error creating the key:",e)}};return console.log("admins: ".concat(null==u?void 0:u.length)),(0,l.jsxs)("div",{className:"w-full m-2",children:[(0,l.jsx)(i,{level:4,children:"Restricted Access"}),(0,l.jsxs)(d,{children:["Add other people to just view spend. They cannot create keys, teams or grant users access to new models."," ",(0,l.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/ui#restrict-ui-access",children:"Requires SSO Setup"})]}),(0,l.jsxs)(O.Z,{numItems:1,className:"gap-2 p-0 w-full",children:[(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsx)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,l.jsxs)($.Z,{children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"Member Name"}),(0,l.jsx)(Q.Z,{children:"Role"}),(0,l.jsx)(Q.Z,{children:"Action"})]})}),(0,l.jsx)(H.Z,{children:u?u.map((e,t)=>(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{children:e.user_email?e.user_email:e.user_id?e.user_id:null}),(0,l.jsx)(Y.Z,{children:e.user_role}),(0,l.jsx)(Y.Z,{children:(0,l.jsx)(J.Z,{icon:eb.Z,size:"sm"})})]},t)):null})]})})}),(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(o.Z,{className:"mx-auto mb-5",onClick:()=>j(!0),children:"+ Add viewer"}),(0,l.jsx)(B.Z,{title:"Add viewer",visible:p,width:800,footer:null,onOk:()=>{j(!1),a.resetFields()},onCancel:()=>{j(!1),a.resetFields()},children:(0,l.jsxs)(L.Z,{form:n,onFinish:y,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(L.Z.Item,{label:"Email",name:"user_email",className:"mb-4",children:(0,l.jsx)(z.Z,{name:"user_email",className:"px-3 py-2 border rounded-md w-full"})}),(0,l.jsx)("div",{className:"text-center mb-4",children:"OR"}),(0,l.jsx)(L.Z.Item,{label:"User ID",name:"user_id",className:"mb-4",children:(0,l.jsx)(z.Z,{name:"user_id",className:"px-3 py-2 border rounded-md w-full"})})]}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(V.ZP,{htmlType:"submit",children:"Add member"})})]})})]})]})]})},eN=s(12968),eA=s(67951);async function eC(e,t,s,l){console.log("isLocal:",!1);let r=window.location.origin,n=new eN.ZP.OpenAI({apiKey:l,baseURL:r,dangerouslyAllowBrowser:!0});for await(let l of(await n.chat.completions.create({model:s,stream:!0,messages:[{role:"user",content:e}]})))console.log(l),l.choices[0].delta.content&&t(l.choices[0].delta.content)}var eT=e=>{let{accessToken:t,token:s,userRole:n,userID:a}=e,[o,i]=(0,r.useState)(""),[c,d]=(0,r.useState)([]),[h,m]=(0,r.useState)(void 0),[u,x]=(0,r.useState)(null);(0,r.useEffect)(()=>{t&&s&&n&&a&&(async()=>{let e=await y(t,a,n);console.log("model_info:",e),(null==e?void 0:e.data.length)>0&&(x(e.data),m(e.data[0].id))})()},[t,a,n]);let p=(e,t)=>{d(s=>{let l=s[s.length-1];return l&&l.role===e?[...s.slice(0,s.length-1),{role:e,content:l.content+t}]:[...s,{role:e,content:t}]})},j=async()=>{if(""!==o.trim()&&t&&s&&n&&a){d(e=>[...e,{role:"user",content:o}]);try{h&&await eC(o,e=>p("assistant",e),h,t)}catch(e){console.error("Error fetching model response",e),p("assistant","Error fetching model response")}i("")}};if(n&&"Admin Viewer"==n){let{Title:e,Paragraph:t}=ea.default;return(0,l.jsxs)("div",{children:[(0,l.jsx)(e,{level:1,children:"Access Denied"}),(0,l.jsx)(t,{children:"Ask your proxy admin for access to test models"})]})}return(0,l.jsx)("div",{style:{width:"100%",position:"relative"},children:(0,l.jsx)(O.Z,{className:"gap-2 p-10 h-[75vh] w-full",children:(0,l.jsx)(M.Z,{children:(0,l.jsxs)(ey.Z,{children:[(0,l.jsxs)(eg.Z,{className:"mt-4",children:[(0,l.jsx)(ej.Z,{children:"Chat"}),(0,l.jsx)(ej.Z,{children:"API Reference"})]}),(0,l.jsxs)(eZ.Z,{children:[(0,l.jsxs)(ew.Z,{children:[(0,l.jsxs)("div",{children:[(0,l.jsx)("label",{children:"Select Model:"}),(0,l.jsx)("select",{value:h||"",onChange:e=>m(e.target.value),children:null==u?void 0:u.map(e=>(0,l.jsx)("option",{value:e.id,children:e.id},e.id))})]}),(0,l.jsxs)($.Z,{className:"mt-5",style:{display:"block",maxHeight:"60vh",overflowY:"auto"},children:[(0,l.jsx)(X.Z,{children:(0,l.jsx)(ee.Z,{children:(0,l.jsx)(Y.Z,{children:(0,l.jsx)(D.Z,{children:"Chat"})})})}),(0,l.jsx)(H.Z,{children:c.map((e,t)=>(0,l.jsx)(ee.Z,{children:(0,l.jsx)(Y.Z,{children:"".concat(e.role,": ").concat(e.content)})},t))})]}),(0,l.jsx)("div",{className:"mt-3",style:{position:"absolute",bottom:5,width:"95%"},children:(0,l.jsxs)("div",{className:"flex",children:[(0,l.jsx)("input",{type:"text",value:o,onChange:e=>i(e.target.value),className:"flex-1 p-2 border rounded-md mr-2",placeholder:"Type your message..."}),(0,l.jsx)("button",{onClick:j,className:"p-2 bg-blue-500 text-white rounded-md",children:"Send"})]})})]}),(0,l.jsx)(ew.Z,{children:(0,l.jsxs)(ey.Z,{children:[(0,l.jsxs)(eg.Z,{children:[(0,l.jsx)(ej.Z,{children:"OpenAI Python SDK"}),(0,l.jsx)(ej.Z,{children:"LlamaIndex"}),(0,l.jsx)(ej.Z,{children:"Langchain Py"})]}),(0,l.jsxs)(eZ.Z,{children:[(0,l.jsx)(ew.Z,{children:(0,l.jsx)(eA.Z,{language:"python",children:'\nimport openai\nclient = openai.OpenAI(\n api_key="your_api_key",\n base_url="http://0.0.0.0:4000" # proxy base url\n)\n\nresponse = client.chat.completions.create(\n model="gpt-3.5-turbo", # model to use from Models Tab\n messages = [\n {\n "role": "user",\n "content": "this is a test request, write a short poem"\n }\n ],\n extra_body={\n "metadata": {\n "generation_name": "ishaan-generation-openai-client",\n "generation_id": "openai-client-gen-id22",\n "trace_id": "openai-client-trace-id22",\n "trace_user_id": "openai-client-user-id2"\n }\n }\n)\n\nprint(response)\n '})}),(0,l.jsx)(ew.Z,{children:(0,l.jsx)(eA.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="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,l.jsx)(ew.Z,{children:(0,l.jsx)(eA.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:8000",\n model = "gpt-3.5-turbo",\n temperature=0.1,\n extra_body={\n "metadata": {\n "generation_name": "ishaan-generation-langchain-client",\n "generation_id": "langchain-client-gen-id22",\n "trace_id": "langchain-client-trace-id22",\n "trace_user_id": "langchain-client-user-id2"\n }\n }\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 '})})]})]})})]})]})})})})},eI=s(33509),eE=s(30569);let{Sider:eP}=eI.default;var eF=e=>{let{setPage:t,userRole:s,defaultSelectedKey:r}=e;return"Admin Viewer"==s?(0,l.jsx)(eI.default,{style:{minHeight:"100vh",maxWidth:"120px"},children:(0,l.jsx)(eP,{width:120,children:(0,l.jsxs)(eE.Z,{mode:"inline",defaultSelectedKeys:r||["4"],style:{height:"100%",borderRight:0},children:[(0,l.jsx)(eE.Z.Item,{onClick:()=>t("api-keys"),children:"API Keys"},"4"),(0,l.jsx)(eE.Z.Item,{onClick:()=>t("models"),children:"Models"},"2"),(0,l.jsx)(eE.Z.Item,{onClick:()=>t("llm-playground"),children:"Chat UI"},"3"),(0,l.jsx)(eE.Z.Item,{onClick:()=>t("usage"),children:"Usage"},"1")]})})}):(0,l.jsx)(eI.default,{style:{minHeight:"100vh",maxWidth:"120px"},children:(0,l.jsx)(eP,{width:120,children:(0,l.jsxs)(eE.Z,{mode:"inline",defaultSelectedKeys:r||["1"],style:{height:"100%",borderRight:0},children:[(0,l.jsx)(eE.Z.Item,{onClick:()=>t("api-keys"),children:"API Keys"},"1"),(0,l.jsx)(eE.Z.Item,{onClick:()=>t("models"),children:"Models"},"2"),(0,l.jsx)(eE.Z.Item,{onClick:()=>t("llm-playground"),children:"Chat UI"},"3"),(0,l.jsx)(eE.Z.Item,{onClick:()=>t("usage"),children:"Usage"},"4"),"Admin"==s?(0,l.jsx)(eE.Z.Item,{onClick:()=>t("users"),children:"Users"},"5"):null,"Admin"==s?(0,l.jsx)(eE.Z.Item,{onClick:()=>t("teams"),children:"Teams"},"6"):null,"Admin"==s?(0,l.jsx)(eE.Z.Item,{onClick:()=>t("admin-panel"),children:"Admin"},"7"):null]})})})},eO=e=>{let{accessToken:t,token:s,userRole:n,userID:a}=e,o=new Date,[i,c]=(0,r.useState)([]),[d,h]=(0,r.useState)([]),[m,u]=(0,r.useState)([]),[x,p]=(0,r.useState)([]),[j,y]=(0,r.useState)([]),[g,_]=(0,r.useState)([]),[S,N]=(0,r.useState)([]),A=new Date(o.getFullYear(),o.getMonth(),1),C=new Date(o.getFullYear(),o.getMonth()+1,0),T=E(A),I=E(C);function E(e){let t=e.getFullYear(),s=e.getMonth()+1,l=e.getDate();return"".concat(t,"-").concat(s<10?"0"+s:s,"-").concat(l<10?"0"+l:l)}return console.log("Start date is ".concat(T)),console.log("End date is ".concat(I)),(0,r.useEffect)(()=>{t&&s&&n&&a&&(async()=>{try{if(console.log("user role: ".concat(n)),"Admin"==n||"Admin Viewer"==n){let e=await f(t);c(e);let s=(await k(t)).map(e=>({key:(e.key_name||e.key_alias||e.api_key).substring(0,7),spend:e.total_spend}));h(s);let l=(await b(t)).map(e=>({key:e.model,spend:e.total_spend}));u(l);let r=await w(t);console.log("teamSpend",r),y(r.daily_spend),_(r.teams),N(r.total_spend_per_team)}else"App Owner"==n&&await Z(t,s,n,a,T,I).then(async e=>{if(console.log("result from spend logs call",e),"daily_spend"in e){let t=e.daily_spend;console.log("daily spend",t),c(t);let s=e.top_api_keys;h(s)}else{let s=(await v(t,function(e){let t=[];e.forEach(e=>{Object.entries(e).forEach(e=>{let[s,l]=e;"spend"!==s&&"startTime"!==s&&"models"!==s&&"users"!==s&&t.push({key:s,spend:l})})}),t.sort((e,t)=>Number(t.spend)-Number(e.spend));let s=t.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||e.token).substring(0,7),spend:e.spend}));h(s),p(function(e){let t={};e.forEach(e=>{Object.entries(e.users).forEach(e=>{let[s,l]=e;""!==s&&null!=s&&"None"!=s&&(t[s]||(t[s]=0),t[s]+=l)})});let s=Object.entries(t).map(e=>{let[t,s]=e;return{user_id:t,spend:s}});s.sort((e,t)=>t.spend-e.spend);let l=s.slice(0,5);return console.log("topKeys: ".concat(Object.values(l[0]))),l}(e)),c(e)}})}catch(e){console.error("There was an error fetching the data",e)}})()},[t,s,n,a,T,I]),(0,l.jsx)("div",{style:{width:"100%"},children:(0,l.jsxs)(ey.Z,{children:[(0,l.jsxs)(eg.Z,{className:"mt-4",children:[(0,l.jsx)(ej.Z,{children:"All Up"}),(0,l.jsx)(ej.Z,{children:"Team Based Usage"})]}),(0,l.jsxs)(eZ.Z,{children:[(0,l.jsx)(ew.Z,{children:(0,l.jsxs)(O.Z,{numItems:2,className:"gap-2 p-10 h-[75vh] w-full",children:[(0,l.jsx)(F.Z,{numColSpan:2,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Monthly Spend"}),(0,l.jsx)(et.Z,{data:i,index:"date",categories:["spend"],colors:["blue"],valueFormatter:e=>"$ ".concat(new Intl.NumberFormat("us").format(e).toString()),yAxisWidth:100,tickGap:5})]})}),(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Top API Keys"}),(0,l.jsx)(et.Z,{className:"mt-4 h-40",data:d,index:"key",categories:["spend"],colors:["blue"],yAxisWidth:80,tickGap:5,layout:"vertical",showXAxis:!1,showLegend:!1})]})}),(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Top Users"}),(0,l.jsx)(et.Z,{className:"mt-4 h-40",data:x,index:"user_id",categories:["spend"],colors:["blue"],yAxisWidth:200,layout:"vertical",showXAxis:!1,showLegend:!1})]})}),(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Top Models"}),(0,l.jsx)(et.Z,{className:"mt-4 h-40",data:m,index:"key",categories:["spend"],colors:["blue"],yAxisWidth:200,layout:"vertical",showXAxis:!1,showLegend:!1})]})})]})}),(0,l.jsx)(ew.Z,{children:(0,l.jsxs)(O.Z,{numItems:2,className:"gap-2 p-10 h-[75vh] w-full",children:[(0,l.jsx)(F.Z,{numColSpan:2,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Daily Spend Per Team"}),(0,l.jsx)(et.Z,{className:"h-72",data:j,index:"date",categories:g,yAxisWidth:30,stack:!0})]})}),(0,l.jsx)(F.Z,{numColSpan:2,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Total Spend Per Team"}),(0,l.jsx)(et.Z,{className:"h-72",data:S,index:"team_id",categories:["total_spend"],yAxisWidth:30})]})})]})})]})]})})},eM=()=>{let{Title:e,Paragraph:t}=ea.default,[s,a]=(0,r.useState)(""),[o,c]=(0,r.useState)(null),[d,h]=(0,r.useState)(null),[m,u]=(0,r.useState)(null),[x,p]=(0,r.useState)(!0),j=(0,n.useSearchParams)(),y=j.get("userID"),g=j.get("token"),[w,Z]=(0,r.useState)("api-keys"),[f,k]=(0,r.useState)(null);return(0,r.useEffect)(()=>{if(g){let e=(0,ed.o)(g);if(e){if(console.log("Decoded token:",e),console.log("Decoded key:",e.key),k(e.key),e.user_role){let t=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"app_user":return"App User";default:return"Unknown Role"}}(e.user_role);console.log("Decoded user_role:",t),a(t),"Admin Viewer"==t&&Z("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?p("username_password"==e.login_method):console.log("User Email is not set ".concat(e))}}},[g]),(0,l.jsx)(r.Suspense,{fallback:(0,l.jsx)("div",{children:"Loading..."}),children:(0,l.jsxs)("div",{className:"flex flex-col min-h-screen",children:[(0,l.jsx)(i,{userID:y,userRole:s,userEmail:o,showSSOBanner:x}),(0,l.jsxs)("div",{className:"flex flex-1 overflow-auto",children:[(0,l.jsx)(eF,{setPage:Z,userRole:s,defaultSelectedKey:null}),"api-keys"==w?(0,l.jsx)(eh,{userID:y,userRole:s,teams:d,keys:m,setUserRole:a,userEmail:o,setUserEmail:c,setTeams:h,setKeys:u}):"models"==w?(0,l.jsx)(ep,{userID:y,userRole:s,token:g,accessToken:f}):"llm-playground"==w?(0,l.jsx)(eT,{userID:y,userRole:s,token:g,accessToken:f}):"users"==w?(0,l.jsx)(e_,{userID:y,userRole:s,token:g,keys:m,accessToken:f,setKeys:u}):"teams"==w?(0,l.jsx)(ev,{teams:d,setTeams:h,searchParams:j,accessToken:f,userID:y,userRole:s}):"admin-panel"==w?(0,l.jsx)(eS,{setTeams:h,searchParams:j,accessToken:f}):(0,l.jsx)(eO,{userID:y,userRole:s,token:g,accessToken:f})]})]})})}}},function(e){e.O(0,[730,971,69,744],function(){return e(e.s=79615)}),_N_E=e.O()}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/app/page-2b5b48b67d7eccff.js b/litellm/proxy/_experimental/out/_next/static/chunks/app/page-2b5b48b67d7eccff.js new file mode 100644 index 000000000..f1848d3af --- /dev/null +++ b/litellm/proxy/_experimental/out/_next/static/chunks/app/page-2b5b48b67d7eccff.js @@ -0,0 +1 @@ +(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[931],{20661:function(e,t,s){Promise.resolve().then(s.bind(s,92182))},92182:function(e,t,s){"use strict";s.r(t),s.d(t,{default:function(){return eM}});var l=s(3827),r=s(64090),a=s(47907),n=s(8792),o=s(2179),i=e=>{let{userID:t,userRole:s,userEmail:r,showSSOBanner:a}=e;return console.log("User ID:",t),console.log("userEmail:",r),(0,l.jsxs)("nav",{className:"left-0 right-0 top-0 flex justify-between items-center h-12 mb-4",children:[(0,l.jsx)("div",{className:"text-left my-2 absolute top-0 left-0",children:(0,l.jsx)("div",{className:"flex flex-col items-center",children:(0,l.jsx)(n.default,{href:"/",children:(0,l.jsx)("button",{className:"text-gray-800 text-2xl py-1 rounded text-center",children:(0,l.jsx)("img",{src:"/get_image",width:200,height:200,alt:"LiteLLM Brand",className:"mr-2"})})})})}),(0,l.jsxs)("div",{className:"text-right mx-4 my-2 absolute top-0 right-0 flex items-center justify-end space-x-2",children:[a?(0,l.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/ui#setup-ssoauth-for-ui",target:"_blank",className:"mr-2"}):null,(0,l.jsxs)(o.Z,{variant:"secondary",size:"lg",children:[r,(0,l.jsxs)("p",{children:["Role: ",s]}),(0,l.jsxs)("p",{children:["ID: ",t]})]})]})]})},c=s(80588);let d=async(e,t,s)=>{try{if(console.log("Form Values in keyCreateCall:",s),s.description&&(s.metadata||(s.metadata={}),s.metadata.description=s.description,delete s.description,s.metadata=JSON.stringify(s.metadata)),s.metadata){console.log("formValues.metadata:",s.metadata);try{s.metadata=JSON.parse(s.metadata)}catch(e){throw c.ZP.error("Failed to parse metadata: "+e),Error("Failed to parse metadata: "+e)}}console.log("Form Values after check:",s);let l=await fetch("/key/generate",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({user_id:t,...s})});if(!l.ok){let e=await l.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let r=await l.json();return console.log("API Response:",r),r}catch(e){throw console.error("Failed to create key:",e),e}},h=async(e,t,s)=>{try{if(console.log("Form Values in keyCreateCall:",s),s.description&&(s.metadata||(s.metadata={}),s.metadata.description=s.description,delete s.description,s.metadata=JSON.stringify(s.metadata)),s.metadata){console.log("formValues.metadata:",s.metadata);try{s.metadata=JSON.parse(s.metadata)}catch(e){throw c.ZP.error("Failed to parse metadata: "+e),Error("Failed to parse metadata: "+e)}}console.log("Form Values after check:",s);let l=await fetch("/user/new",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({user_id:t,...s})});if(!l.ok){let e=await l.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let r=await l.json();return console.log("API Response:",r),r}catch(e){throw console.error("Failed to create key:",e),e}},m=async(e,t)=>{try{console.log("in keyDeleteCall:",t);let s=await fetch("/key/delete",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({keys:[t]})});if(!s.ok){let e=await s.text();throw c.ZP.error("Failed to delete key: "+e),Error("Network response was not ok")}let l=await s.json();return console.log(l),l}catch(e){throw console.error("Failed to create key:",e),e}},u=async function(e,t,s){let l=arguments.length>3&&void 0!==arguments[3]&&arguments[3];try{let r="/user/info";"App Owner"==s&&t&&(r="".concat(r,"?user_id=").concat(t)),console.log("in userInfoCall viewAll=",l),l&&(r="".concat(r,"?view_all=true"));let a=await fetch(r,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!a.ok){let e=await a.text();throw c.ZP.error(e),Error("Network response was not ok")}let n=await a.json();return console.log("API Response:",n),n}catch(e){throw console.error("Failed to create key:",e),e}},x=async e=>{try{let t=await fetch("/global/spend",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},p=async(e,t,s)=>{try{let t=await fetch("/v2/model/info",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},j=async(e,t,s)=>{try{let t=await fetch("/model/metrics",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},y=async(e,t,s)=>{try{let t=await fetch("/models",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},g=async(e,t)=>{try{let s="/global/spend/logs";console.log("in keySpendLogsCall:",s);let l=await fetch("".concat(s,"?api_key=").concat(t),{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw c.ZP.error(e),Error("Network response was not ok")}let r=await l.json();return console.log(r),r}catch(e){throw console.error("Failed to create key:",e),e}},w=async e=>{try{let t="/global/spend/teams";console.log("in teamSpendLogsCall:",t);let s=await fetch("".concat(t),{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!s.ok){let e=await s.text();throw c.ZP.error(e),Error("Network response was not ok")}let l=await s.json();return console.log(l),l}catch(e){throw console.error("Failed to create key:",e),e}},Z=async(e,t,s,l,r,a)=>{try{console.log("user role in spend logs call: ".concat(s));let t="/spend/logs";t="App Owner"==s?"".concat(t,"?user_id=").concat(l,"&start_date=").concat(r,"&end_date=").concat(a):"".concat(t,"?start_date=").concat(r,"&end_date=").concat(a);let n=await fetch(t,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!n.ok){let e=await n.text();throw c.ZP.error(e),Error("Network response was not ok")}let o=await n.json();return console.log(o),o}catch(e){throw console.error("Failed to create key:",e),e}},f=async e=>{try{let t=await fetch("/global/spend/logs",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to create key:",e),e}},k=async e=>{try{let t=await fetch("/global/spend/keys?limit=5",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to create key:",e),e}},_=async(e,t)=>{try{t&&JSON.stringify({api_key:t});let s={method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}};t&&(s.body=JSON.stringify({api_key:t}));let l=await fetch("/global/spend/end_users",s);if(!l.ok){let e=await l.text();throw c.ZP.error(e),Error("Network response was not ok")}let r=await l.json();return console.log(r),r}catch(e){throw console.error("Failed to create key:",e),e}},b=async e=>{try{let t=await fetch("/global/spend/models?limit=5",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to create key:",e),e}},v=async(e,t)=>{try{let s=await fetch("/v2/key/info",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({keys:t})});if(!s.ok){let e=await s.text();throw c.ZP.error(e),Error("Network response was not ok")}let l=await s.json();return console.log(l),l}catch(e){throw console.error("Failed to create key:",e),e}},S=async(e,t,s,l)=>{try{let r=await fetch("/user/request_model",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({models:[t],user_id:s,justification:l})});if(!r.ok){let e=await r.text();throw c.ZP.error("Failed to delete key: "+e),Error("Network response was not ok")}let a=await r.json();return console.log(a),a}catch(e){throw console.error("Failed to create key:",e),e}},N=async e=>{try{let t="/user/get_requests";console.log("in userGetRequesedtModelsCall:",t);let s=await fetch(t,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!s.ok){let e=await s.text();throw c.ZP.error("Failed to delete key: "+e),Error("Network response was not ok")}let l=await s.json();return console.log(l),l}catch(e){throw console.error("Failed to get requested models:",e),e}},A=async(e,t)=>{try{let s="/user/get_users?role=".concat(t);console.log("in userGetAllUsersCall:",s);let l=await fetch(s,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw c.ZP.error("Failed to delete key: "+e),Error("Network response was not ok")}let r=await l.json();return console.log(r),r}catch(e){throw console.error("Failed to get requested models:",e),e}},C=async(e,t)=>{try{console.log("Form Values in teamCreateCall:",t);let s=await fetch("/team/new",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...t})});if(!s.ok){let e=await s.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let l=await s.json();return console.log("API Response:",l),l}catch(e){throw console.error("Failed to create key:",e),e}},T=async(e,t,s)=>{try{console.log("Form Values in teamMemberAddCall:",s);let l=await fetch("/team/member_add",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({team_id:t,member:s})});if(!l.ok){let e=await l.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let r=await l.json();return console.log("API Response:",r),r}catch(e){throw console.error("Failed to create key:",e),e}},I=async(e,t)=>{try{console.log("Form Values in userUpdateUserCall:",t);let s=await fetch("/user/update",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({user_role:"proxy_admin_viewer",...t})});if(!s.ok){let e=await s.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let l=await s.json();return console.log("API Response:",l),l}catch(e){throw console.error("Failed to create key:",e),e}},P=async(e,t)=>{try{let s=await fetch("/global/predict/spend/logs",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({data:t})});if(!s.ok){let e=await s.text();throw c.ZP.error(e),Error("Network response was not ok")}let l=await s.json();return console.log(l),l}catch(e){throw console.error("Failed to create key:",e),e}},E=async e=>{try{console.log("Checking Slack Budget Alerts service health");let t=await fetch("/health/services?service=slack_budget_alerts",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error("Failed Slack Alert test: "+e),Error(e)}let s=await t.json();return c.ZP.success("Test Slack Alert worked - check your Slack!"),console.log("Service Health Response:",s),s}catch(e){throw console.error("Failed to perform health check:",e),e}};var F=s(10384),O=s(46453),M=s(13810),R=s(71801),D=s(42440),U=s(17189),L=s(12143),B=s(77171),z=s(42539),K=s(88707),W=s(1861);let{Option:V}=U.default;var q=e=>{let{userID:t,teamID:s,userRole:a,accessToken:n,data:i,userModels:h,setData:m}=e,[u]=L.Z.useForm(),[x,p]=(0,r.useState)(!1),[j,y]=(0,r.useState)(null),[g,w]=(0,r.useState)(null),Z=()=>{p(!1),u.resetFields()},f=()=>{p(!1),y(null),u.resetFields()},k=async e=>{try{c.ZP.info("Making API Call"),p(!0);let s=await d(n,t,e);console.log("key create Response:",s),m(e=>e?[...e,s]:[s]),y(s.key),w(s.soft_budget),c.ZP.success("API Key Created"),u.resetFields(),localStorage.removeItem("userData"+t)}catch(e){console.error("Error creating the key:",e)}},_=async()=>{try{console.log("Sending Slack alert...");let e=await E(n);console.log("slackBudgetAlertsHealthCheck Response:",e),console.log("Testing Slack alert successful")}catch(e){console.error("Error sending Slack alert:",e)}};return(0,l.jsxs)("div",{children:[(0,l.jsx)(o.Z,{className:"mx-auto",onClick:()=>p(!0),children:"+ Create New Key"}),(0,l.jsx)(B.Z,{title:"Create Key",visible:x,width:800,footer:null,onOk:Z,onCancel:f,children:(0,l.jsxs)(L.Z,{form:u,onFinish:k,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:["App Owner"===a||"Admin"===a?(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(L.Z.Item,{label:"Key Name",name:"key_alias",children:(0,l.jsx)(z.Z,{})}),(0,l.jsx)(L.Z.Item,{label:"Team ID",name:"team_id",children:(0,l.jsx)(z.Z,{placeholder:"ai_team",defaultValue:s||""})}),(0,l.jsx)(L.Z.Item,{label:"Models",name:"models",children:(0,l.jsx)(U.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:h.map(e=>(0,l.jsx)(V,{value:e,children:e},e))})}),(0,l.jsx)(L.Z.Item,{label:"Soft Budget (USD) Monthly",name:"soft_budget",initialValue:50,children:(0,l.jsx)(K.Z,{step:.01,precision:2,defaultValue:50,width:200})}),(0,l.jsx)(L.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,l.jsx)(K.Z,{step:.01,precision:2,width:200})}),(0,l.jsx)(L.Z.Item,{label:"Reset Budget",name:"budget_duration",children:(0,l.jsxs)(U.default,{defaultValue:null,placeholder:"n/a",children:[(0,l.jsx)(U.default.Option,{value:"24h",children:"daily"}),(0,l.jsx)(U.default.Option,{value:"30d",children:"monthly"})]})}),(0,l.jsx)(L.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})}),(0,l.jsx)(L.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})}),(0,l.jsx)(L.Z.Item,{label:"Expire Key (eg: 30s, 30h, 30d)",name:"duration",children:(0,l.jsx)(z.Z,{})}),(0,l.jsx)(L.Z.Item,{label:"Metadata",name:"metadata",children:(0,l.jsx)(z.Z.TextArea,{rows:4,placeholder:"Enter metadata as JSON"})})]}):(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(L.Z.Item,{label:"Key Name",name:"key_alias",children:(0,l.jsx)(z.Z,{})}),(0,l.jsx)(L.Z.Item,{label:"Team ID (Contact Group)",name:"team_id",children:(0,l.jsx)(z.Z,{placeholder:"ai_team"})}),(0,l.jsx)(L.Z.Item,{label:"Description",name:"description",children:(0,l.jsx)(z.Z.TextArea,{placeholder:"Enter description",rows:4})})]}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(W.ZP,{htmlType:"submit",children:"Create Key"})})]})}),j&&(0,l.jsx)(B.Z,{visible:x,onOk:Z,onCancel:f,footer:null,children:(0,l.jsx)(O.Z,{numItems:1,className:"gap-2 w-full",children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Save your Key"}),(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsxs)("p",{children:["Please save this secret key somewhere safe and accessible. For security reasons, ",(0,l.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,l.jsx)(F.Z,{numColSpan:1,children:null!=j?(0,l.jsxs)("div",{children:[(0,l.jsxs)(R.Z,{children:["API Key: ",j]}),(0,l.jsx)(D.Z,{className:"mt-6",children:"Budgets"}),(0,l.jsxs)(R.Z,{children:["Soft Limit Budget: $",g]}),(0,l.jsx)(o.Z,{className:"mt-3",onClick:_,children:"Test Slack Alert"}),(0,l.jsxs)(R.Z,{className:"mt-2",children:["(LiteLLM Docs -",(0,l.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/alerting",target:"_blank",className:"text-blue-500",children:"Set Up Slack Alerting)"})]})]}):(0,l.jsx)(R.Z,{children:"Key being created, this might take 30s"})})]})})})]})},J=s(33393),G=s(61244),$=s(10827),H=s(3851),Y=s(2044),X=s(64167),Q=s(74480),ee=s(7178),et=s(9853),es=s(56863),el=e=>{let{token:t,accessToken:s,keySpend:a,keyBudget:n,keyName:i}=e,[c,d]=(0,r.useState)(!1),[h,m]=(0,r.useState)(null),[u,x]=(0,r.useState)(""),[p,j]=(0,r.useState)(null),y=async()=>{try{if(null==s||null==t)return;console.log("accessToken: ".concat(s,"; token: ").concat(t));let e=await g(s,t);console.log("Response:",e),m(e);let l=await P(s,e);console.log("Response2:",l);let r=[...e,...l.response];m(r),x(l.predicted_spend),console.log("Combined Data:",r)}catch(e){console.error("There was an error fetching the data",e)}};return t?(0,l.jsxs)("div",{children:[(0,l.jsx)(o.Z,{size:"xs",onClick:()=>{console.log("Show Modal triggered"),d(!0),y()},variant:"secondary",children:"Spend Report"}),(0,l.jsxs)(B.Z,{visible:c,width:1400,onOk:()=>{d(!1)},onCancel:()=>{d(!1)},footer:null,children:[(0,l.jsxs)(D.Z,{style:{textAlign:"left"},children:["Key Name: ",i]}),(0,l.jsxs)(es.Z,{children:["Monthly Spend $",a]}),(0,l.jsx)(D.Z,{children:u}),(0,l.jsx)(M.Z,{className:"mt-6 mb-6",children:h&&(0,l.jsx)(et.Z,{className:"mt-6",data:h,colors:["blue","amber"],index:"date",categories:["spend","predicted_spend"],yAxisWidth:80})})]})]}):null},er=e=>{let{userID:t,accessToken:s,data:a,setData:n}=e,[i,c]=(0,r.useState)(!1),[d,h]=(0,r.useState)(!1),[u,x]=(0,r.useState)(null),p=async e=>{null!=a&&(x(e),localStorage.removeItem("userData"+t),h(!0))},j=async()=>{if(null!=u&&null!=a){try{await m(s,u);let e=a.filter(e=>e.token!==u);n(e)}catch(e){console.error("Error deleting the key:",e)}h(!1),x(null)}};if(null!=a)return console.log("RERENDER TRIGGERED"),(0,l.jsxs)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh] mb-4",children:[(0,l.jsxs)($.Z,{className:"mt-5",children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"Key Alias"}),(0,l.jsx)(Q.Z,{children:"Secret Key"}),(0,l.jsx)(Q.Z,{children:"Spend (USD)"}),(0,l.jsx)(Q.Z,{children:"Key Budget (USD)"}),(0,l.jsx)(Q.Z,{children:"Spend Report"}),(0,l.jsx)(Q.Z,{children:"Team ID"}),(0,l.jsx)(Q.Z,{children:"Metadata"}),(0,l.jsx)(Q.Z,{children:"Models"}),(0,l.jsx)(Q.Z,{children:"TPM / RPM Limits"}),(0,l.jsx)(Q.Z,{children:"Expires"})]})}),(0,l.jsx)(H.Z,{children:a.map(e=>(console.log(e),"litellm-dashboard"===e.team_id)?null:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",whiteSpace:"pre-wrap",overflow:"hidden"},children:null!=e.key_alias?(0,l.jsx)(R.Z,{children:e.key_alias}):(0,l.jsx)(R.Z,{children:"Not Set"})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:e.key_name})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:(()=>{try{return parseFloat(e.spend).toFixed(4)}catch(t){return e.spend}})()})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",whiteSpace:"pre-wrap",overflow:"hidden"},children:null!=e.max_budget?(0,l.jsx)(R.Z,{children:e.max_budget}):(0,l.jsx)(R.Z,{children:"Unlimited Budget"})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px"},children:(0,l.jsx)(el,{token:e.token,accessToken:s,keySpend:e.spend,keyBudget:e.max_budget,keyName:e.key_name})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:e.team_id})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:JSON.stringify(e.metadata).slice(0,400)})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:JSON.stringify(e.models)})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",overflowWrap:"break-word"},children:(0,l.jsxs)(R.Z,{children:["TPM Limit: ",e.tpm_limit?e.tpm_limit:"Unlimited"," ",(0,l.jsx)("br",{})," RPM Limit:"," ",e.rpm_limit?e.rpm_limit:"Unlimited"]})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",wordWrap:"break-word"},children:null!=e.expires?(0,l.jsx)(R.Z,{children:e.expires}):(0,l.jsx)(R.Z,{children:"Never"})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",wordWrap:"break-word"},children:(0,l.jsx)(G.Z,{onClick:()=>p(e.token),icon:J.Z,size:"sm"})})]},e.token))})]}),d&&(0,l.jsx)("div",{className:"fixed z-10 inset-0 overflow-y-auto",children:(0,l.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,l.jsx)("div",{className:"fixed inset-0 transition-opacity","aria-hidden":"true",children:(0,l.jsx)("div",{className:"absolute inset-0 bg-gray-500 opacity-75"})}),(0,l.jsx)("span",{className:"hidden sm:inline-block sm:align-middle sm:h-screen","aria-hidden":"true",children:"​"}),(0,l.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,l.jsx)("div",{className:"bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4",children:(0,l.jsx)("div",{className:"sm:flex sm:items-start",children:(0,l.jsxs)("div",{className:"mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left",children:[(0,l.jsx)("h3",{className:"text-lg leading-6 font-medium text-gray-900",children:"Delete Key"}),(0,l.jsx)("div",{className:"mt-2",children:(0,l.jsx)("p",{className:"text-sm text-gray-500",children:"Are you sure you want to delete this key ?"})})]})})}),(0,l.jsxs)("div",{className:"bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse",children:[(0,l.jsx)(o.Z,{onClick:j,color:"red",className:"ml-2",children:"Delete"}),(0,l.jsx)(o.Z,{onClick:()=>{h(!1),x(null)},children:"Cancel"})]})]})]})})]})},ea=e=>{let{userID:t,userSpendData:s,userRole:a,accessToken:n}=e,[o,i]=(0,r.useState)(null==s?void 0:s.spend),[c,d]=(0,r.useState)((null==s?void 0:s.max_budget)||null);(0,r.useEffect)(()=>{(async()=>{if("Admin"===a)try{let e=await x(n);i(e.spend),d(e.max_budget||null)}catch(e){console.error("Error fetching global spend data:",e)}})()},[a,n]);let h=void 0!==o?o.toFixed(4):null;return(0,l.jsx)(l.Fragment,{children:(0,l.jsxs)(M.Z,{className:"mx-auto mb-4",children:[(0,l.jsxs)(es.Z,{children:["$",h]}),(0,l.jsxs)(D.Z,{children:["/ ",null!==c?"$".concat(c," limit"):"No limit"]})]})})},en=s(36083),eo=s(68967),ei=s(27166),ec=e=>{let{teams:t,setSelectedTeam:s}=e,{Title:a,Paragraph:n}=en.default,[o,i]=(0,r.useState)("");return(0,l.jsxs)("div",{className:"mt-10",children:[(0,l.jsx)(a,{level:4,children:"Default Team"}),(0,l.jsx)(n,{children:"If you belong to multiple teams, this setting controls which team is used by default when creating new API Keys."}),t&&t.length>0?(0,l.jsx)(eo.Z,{defaultValue:"0",children:t.map((e,t)=>(0,l.jsx)(ei.Z,{value:String(t),onClick:()=>s(e),children:e.team_alias},t))}):(0,l.jsxs)(n,{children:["No team created. ",(0,l.jsx)("b",{children:"Defaulting to personal account."})]})]})},ed=s(37963);console.log("isLocal:",!1);var eh=e=>{let{userID:t,userRole:s,teams:n,keys:o,setUserRole:i,userEmail:c,setUserEmail:d,setTeams:h,setKeys:m}=e,[p,j]=(0,r.useState)(null),g=(0,a.useSearchParams)();g.get("viewSpend"),(0,a.useRouter)();let w=g.get("token"),[Z,f]=(0,r.useState)(null),[k,_]=(0,r.useState)([]),[b,v]=(0,r.useState)(n?n[0]:null);if(window.addEventListener("beforeunload",function(){sessionStorage.clear()}),(0,r.useEffect)(()=>{if(w){let e=(0,ed.o)(w);if(e){if(console.log("Decoded token:",e),console.log("Decoded key:",e.key),f(e.key),e.user_role){let t=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";default:return"Unknown Role"}}(e.user_role);console.log("Decoded user_role:",t),i(t)}else console.log("User role not defined");e.user_email?d(e.user_email):console.log("User Email is not set ".concat(e))}}if(t&&Z&&s&&!o&&!p){let e=sessionStorage.getItem("userModels"+t);e?_(JSON.parse(e)):(async()=>{try{let e=await u(Z,t,s);if(console.log("received teams in user dashboard: ".concat(Object.keys(e),"; team values: ").concat(Object.entries(e.teams))),"Admin"==s){let e=await x(Z);j(e),console.log("globalSpend:",e)}else j(e.user_info);m(e.keys),h(e.teams),v(e.teams?e.teams[0]:null),sessionStorage.setItem("userData"+t,JSON.stringify(e.keys)),sessionStorage.setItem("userSpendData"+t,JSON.stringify(e.user_info));let l=(await y(Z,t,s)).data.map(e=>e.id);console.log("available_model_names:",l),_(l),console.log("userModels:",k),sessionStorage.setItem("userModels"+t,JSON.stringify(l))}catch(e){console.error("There was an error fetching the data",e)}})()}},[t,w,Z,o,s]),null==t||null==w){let e="/sso/key/generate";return console.log("Full URL:",e),window.location.href=e,null}if(null==Z)return null;if(null==s&&i("App Owner"),s&&"Admin Viewer"==s){let{Title:e,Paragraph:t}=en.default;return(0,l.jsxs)("div",{children:[(0,l.jsx)(e,{level:1,children:"Access Denied"}),(0,l.jsx)(t,{children:"Ask your proxy admin for access to create keys"})]})}return(0,l.jsx)("div",{children:(0,l.jsx)(O.Z,{numItems:1,className:"gap-0 p-10 h-[75vh] w-full",children:(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(ea,{userID:t,userSpendData:p,userRole:s,accessToken:Z}),(0,l.jsx)(er,{userID:t,accessToken:Z,data:o,setData:m}),(0,l.jsx)(q,{userID:t,teamID:b?b.team_id:null,userRole:s,userModels:k,accessToken:Z,data:o,setData:m}),(0,l.jsx)(ec,{teams:n,setSelectedTeam:v})]})})})},em=s(5);let{Option:eu}=U.default;var ex=e=>{let{userModels:t,accessToken:s,userID:a}=e,[n]=L.Z.useForm(),[i,d]=(0,r.useState)(!1),h=async e=>{try{c.ZP.info("Requesting access");let{selectedModel:t,accessReason:l}=e;await S(s,t,a,l),d(!0)}catch(e){console.error("Error requesting access:",e)}};return(0,l.jsxs)("div",{children:[(0,l.jsx)(o.Z,{size:"xs",onClick:()=>d(!0),children:"Request Access"}),(0,l.jsx)(B.Z,{title:"Request Access",visible:i,width:800,footer:null,onOk:()=>{d(!1),n.resetFields()},onCancel:()=>{d(!1),n.resetFields()},children:(0,l.jsxs)(L.Z,{form:n,onFinish:h,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsx)(L.Z.Item,{label:"Select Model",name:"selectedModel",children:(0,l.jsx)(U.default,{placeholder:"Select model",style:{width:"100%"},children:t.map(e=>(0,l.jsx)(eu,{value:e,children:e},e))})}),(0,l.jsx)(L.Z.Item,{label:"Reason for Access",name:"accessReason",children:(0,l.jsx)(z.Z.TextArea,{rows:4,placeholder:"Enter reason for access"})}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(o.Z,{children:"Request Access"})})]})})]})},ep=e=>{let{accessToken:t,token:s,userRole:a,userID:n}=e,[o,i]=(0,r.useState)({data:[]}),[c,d]=(0,r.useState)([]),[h,m]=(0,r.useState)([]);if((0,r.useEffect)(()=>{if(!t||!s||!a||!n)return;let e=async()=>{try{let e=await p(t,n,a);console.log("Model data response:",e.data),i(e);let s=await j(t,n,a);if(console.log("Model metrics response:",s),d(s),"Admin"===a&&t){let e=await N(t);console.log("Pending Requests:",h),m(e.requests||[])}}catch(e){console.error("There was an error fetching the model data",e)}};t&&s&&a&&n&&e()},[t,s,a,n]),!o||!t||!s||!a||!n)return(0,l.jsx)("div",{children:"Loading..."});let u=[];for(let e=0;e(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{children:(0,l.jsx)(D.Z,{children:e.model_name})}),(0,l.jsx)(Y.Z,{children:e.provider}),"Admin"===a&&(0,l.jsx)(Y.Z,{children:e.api_base}),(0,l.jsx)(Y.Z,{children:e.user_access?(0,l.jsx)(em.Z,{color:"green",children:"Yes"}):(0,l.jsx)(ex,{userModels:u,accessToken:t,userID:n})}),(0,l.jsx)(Y.Z,{children:e.input_cost}),(0,l.jsx)(Y.Z,{children:e.output_cost}),(0,l.jsx)(Y.Z,{children:e.max_tokens})]},e.model_name))})]})}),(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Model Statistics (Number Requests)"}),(0,l.jsx)(et.Z,{data:c,index:"model",categories:["num_requests"],colors:["blue"],yAxisWidth:400,layout:"vertical",tickGap:5})]}),(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Model Statistics (Latency)"}),(0,l.jsx)(et.Z,{data:c,index:"model",categories:["avg_latency_seconds"],colors:["red"],yAxisWidth:400,layout:"vertical",tickGap:5})]})]})})},ej=s(92836),ey=s(26734),eg=s(41608),ew=s(32126),eZ=s(23682);let{Option:ef}=U.default;var ek=e=>{let{userID:t,accessToken:s}=e,[a]=L.Z.useForm(),[n,i]=(0,r.useState)(!1),[d,m]=(0,r.useState)(null),[u,x]=(0,r.useState)([]);(0,r.useEffect)(()=>{(async()=>{try{let e=await y(s,t,"any"),l=[];for(let t=0;t{i(!1),a.resetFields()},j=()=>{i(!1),m(null),a.resetFields()},g=async e=>{try{c.ZP.info("Making API Call"),i(!0),console.log("formValues in create user:",e);let l=await h(s,t,e);console.log("user create Response:",l),m(l.key),c.ZP.success("API user Created"),a.resetFields(),localStorage.removeItem("userData"+t)}catch(e){console.error("Error creating the user:",e)}};return(0,l.jsxs)("div",{children:[(0,l.jsx)(o.Z,{className:"mx-auto",onClick:()=>i(!0),children:"+ Create New User"}),(0,l.jsx)(B.Z,{title:"Create User",visible:n,width:800,footer:null,onOk:p,onCancel:j,children:(0,l.jsxs)(L.Z,{form:a,onFinish:g,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsx)(L.Z.Item,{label:"User ID",name:"user_id",children:(0,l.jsx)(z.Z,{placeholder:"Enter User ID"})}),(0,l.jsx)(L.Z.Item,{label:"Team ID",name:"team_id",children:(0,l.jsx)(z.Z,{placeholder:"ai_team"})}),(0,l.jsx)(L.Z.Item,{label:"Models",name:"models",children:(0,l.jsx)(U.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:u.map(e=>(0,l.jsx)(ef,{value:e,children:e},e))})}),(0,l.jsx)(L.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,l.jsx)(K.Z,{step:.01,precision:2,width:200})}),(0,l.jsx)(L.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})}),(0,l.jsx)(L.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})}),(0,l.jsx)(L.Z.Item,{label:"Duration (eg: 30s, 30h, 30d)",name:"duration",children:(0,l.jsx)(z.Z,{})}),(0,l.jsx)(L.Z.Item,{label:"Metadata",name:"metadata",children:(0,l.jsx)(z.Z.TextArea,{rows:4,placeholder:"Enter metadata as JSON"})}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(W.ZP,{htmlType:"submit",children:"Create User"})})]})}),d&&(0,l.jsxs)(B.Z,{title:"Save Your User",visible:n,onOk:p,onCancel:j,footer:null,children:[(0,l.jsxs)("p",{children:["Please save this secret user somewhere safe and accessible. For security reasons, ",(0,l.jsx)("b",{children:"you will not be able to view it again"})," ","through your LiteLLM account. If you lose this secret user, you will need to generate a new one."]}),(0,l.jsx)("p",{children:null!=d?"API user: ".concat(d):"User being created, this might take 30s"})]})]})},e_=e=>{let{accessToken:t,token:s,keys:a,userRole:n,userID:o,setKeys:i}=e,[c,d]=(0,r.useState)(null),[h,m]=(0,r.useState)(null),[x,p]=(0,r.useState)(1);if((0,r.useEffect)(()=>{if(!t||!s||!n||!o)return;let e=async()=>{try{let e=await u(t,null,n,!0);console.log("user data response:",e),d(e)}catch(e){console.error("There was an error fetching the model data",e)}};t&&s&&n&&o&&!c&&e();let l=async()=>{try{let e=await _(t,null);console.log("user data response:",e),m(e)}catch(e){console.error("There was an error fetching the model data",e)}};n&&("Admin"==n||"Admin Viewer"==n)&&!h&&l()},[t,s,n,o]),!c||!t||!s||!n||!o)return(0,l.jsx)("div",{children:"Loading..."});let j=async e=>{try{let s=await _(t,e);console.log("user data response:",s),m(s)}catch(e){console.error("There was an error fetching the model data",e)}};return(0,l.jsx)("div",{style:{width:"100%"},children:(0,l.jsxs)(O.Z,{className:"gap-2 p-10 h-[75vh] w-full",children:[(0,l.jsx)(ek,{userID:o,accessToken:t}),(0,l.jsx)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh] mb-4",children:(0,l.jsxs)(ey.Z,{children:[(0,l.jsxs)(eg.Z,{variant:"line",defaultValue:"1",children:[(0,l.jsx)(ej.Z,{value:"1",children:"Key Owners"}),(0,l.jsx)(ej.Z,{value:"2",children:"End-Users"})]}),(0,l.jsxs)(eZ.Z,{children:[(0,l.jsx)(ew.Z,{children:(0,l.jsxs)($.Z,{className:"mt-5",children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"User ID"}),(0,l.jsx)(Q.Z,{children:"User Role"}),(0,l.jsx)(Q.Z,{children:"User Models"}),(0,l.jsx)(Q.Z,{children:"User Spend ($ USD)"}),(0,l.jsx)(Q.Z,{children:"User Max Budget ($ USD)"})]})}),(0,l.jsx)(H.Z,{children:c.map(e=>(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{children:e.user_id}),(0,l.jsx)(Y.Z,{children:e.user_role?e.user_role:"app_owner"}),(0,l.jsx)(Y.Z,{children:e.models&&e.models.length>0?e.models:"All Models"}),(0,l.jsx)(Y.Z,{children:e.spend?e.spend:0}),(0,l.jsx)(Y.Z,{children:e.max_budget?e.max_budget:"Unlimited"})]},e.user_id))})]})}),(0,l.jsxs)(ew.Z,{children:[(0,l.jsxs)("div",{className:"flex items-center",children:[(0,l.jsx)("div",{className:"flex-1"}),(0,l.jsxs)("div",{className:"flex-1 flex justify-between items-center",children:[(0,l.jsx)(R.Z,{className:"w-1/4 mr-2 text-right",children:"Key"}),(0,l.jsx)(eo.Z,{defaultValue:"1",className:"w-3/4",children:null==a?void 0:a.map((e,t)=>{if(e&&null!==e.key_name&&e.key_name.length>0)return(0,l.jsx)(ei.Z,{value:String(t),onClick:()=>j(e.token),children:e.key_name},t)})})]})]}),(0,l.jsxs)($.Z,{children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"End User"}),(0,l.jsx)(Q.Z,{children:"Spend"}),(0,l.jsx)(Q.Z,{children:"Total Events"})]})}),(0,l.jsx)(H.Z,{children:null==h?void 0:h.map((e,t)=>(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{children:e.end_user}),(0,l.jsx)(Y.Z,{children:e.total_spend}),(0,l.jsx)(Y.Z,{children:e.total_events})]},t))})]})]})]})]})}),function(){if(!c)return null;let e=Math.ceil(c.length/25),t=Math.min(25*x,c.length);return(0,l.jsxs)("div",{className:"flex justify-between items-center",children:[(0,l.jsxs)("div",{children:["Showing ",(x-1)*25+1," – ",t," of ",c.length]}),(0,l.jsxs)("div",{className:"flex",children:[(0,l.jsx)("button",{className:"bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-l focus:outline-none",disabled:1===x,onClick:()=>p(x-1),children:"← Prev"}),(0,l.jsx)("button",{className:"bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-r focus:outline-none",disabled:x===e,onClick:()=>p(x+1),children:"Next →"})]})]})}()]})})},eb=e=>{let{teams:t,searchParams:s,accessToken:a,setTeams:n,userID:i,userRole:d}=e,[h]=L.Z.useForm(),[m]=L.Z.useForm(),{Title:u,Paragraph:x}=en.default,[p,j]=(0,r.useState)(""),[g,w]=(0,r.useState)(t?t[0]:null),[Z,f]=(0,r.useState)(!1),[k,_]=(0,r.useState)(!1),[b,v]=(0,r.useState)([]);(0,r.useEffect)(()=>{(async()=>{try{if(null===i||null===d)return;if(null!==a){let e=(await y(a,i,d)).data.map(e=>e.id);console.log("available_model_names:",e),v(e)}}catch(e){console.error("Error fetching user models:",e)}})()},[a,i,d]);let S=async e=>{try{if(null!=a){let s=await C(a,e);null!==t?n([...t,s]):n([s]),console.log("response for team create call: ".concat(s)),c.ZP.success("Team created"),f(!1)}}catch(e){console.error("Error creating the key:",e),c.ZP.error("Error creating the team: "+e)}},N=async e=>{try{if(null!=a&&null!=t){c.ZP.info("Making API Call");let s={role:"user",user_email:e.user_email,user_id:e.user_id},l=await T(a,g.team_id,s);console.log("response for team create call: ".concat(l.data));let r=t.findIndex(e=>(console.log("team.team_id=".concat(e.team_id,"; response.data.team_id=").concat(l.data.team_id)),e.team_id===l.data.team_id));if(console.log("foundIndex: ".concat(r)),-1!==r){let e=[...t];e[r]=l.data,n(e),w(l.data)}_(!1)}}catch(e){console.error("Error creating the key:",e)}};return console.log("received teams ".concat(t)),(0,l.jsx)("div",{className:"w-full mx-4",children:(0,l.jsxs)(O.Z,{numItems:1,className:"gap-2 p-2 h-[75vh] w-full",children:[(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(u,{level:4,children:"All Teams"}),(0,l.jsx)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,l.jsxs)($.Z,{children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"Team Name"}),(0,l.jsx)(Q.Z,{children:"Spend (USD)"}),(0,l.jsx)(Q.Z,{children:"Budget (USD)"}),(0,l.jsx)(Q.Z,{children:"Models"}),(0,l.jsx)(Q.Z,{children:"TPM / RPM Limits"})]})}),(0,l.jsx)(H.Z,{children:t&&t.length>0?t.map(e=>(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:e.team_alias}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:e.spend}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:e.max_budget?e.max_budget:"No limit"}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:JSON.stringify(e.models?e.models:[])})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsxs)(R.Z,{children:["TPM Limit:"," ",e.tpm_limit?e.tpm_limit:"Unlimited"," ",(0,l.jsx)("br",{}),"RPM Limit:"," ",e.rpm_limit?e.rpm_limit:"Unlimited"]})})]},e.team_id)):null})]})})]}),(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(o.Z,{className:"mx-auto",onClick:()=>f(!0),children:"+ Create New Team"}),(0,l.jsx)(B.Z,{title:"Create Team",visible:Z,width:800,footer:null,onOk:()=>{f(!1),h.resetFields()},onCancel:()=>{f(!1),h.resetFields()},children:(0,l.jsxs)(L.Z,{form:h,onFinish:S,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(L.Z.Item,{label:"Team Name",name:"team_alias",children:(0,l.jsx)(z.Z,{})}),(0,l.jsx)(L.Z.Item,{label:"Models",name:"models",children:(0,l.jsx)(U.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:b.map(e=>(0,l.jsx)(U.default.Option,{value:e,children:e},e))})}),(0,l.jsx)(L.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,l.jsx)(K.Z,{step:.01,precision:2,width:200})}),(0,l.jsx)(L.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})}),(0,l.jsx)(L.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})})]}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(W.ZP,{htmlType:"submit",children:"Create Team"})})]})})]}),(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(u,{level:4,children:"Team Members"}),(0,l.jsx)(x,{children:"If you belong to multiple teams, this setting controls which teams members you see."}),t&&t.length>0?(0,l.jsx)(eo.Z,{defaultValue:"0",children:t.map((e,t)=>(0,l.jsx)(ei.Z,{value:String(t),onClick:()=>{w(e)},children:e.team_alias},t))}):(0,l.jsxs)(x,{children:["No team created. ",(0,l.jsx)("b",{children:"Defaulting to personal account."})]})]}),(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsx)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,l.jsxs)($.Z,{children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"Member Name"}),(0,l.jsx)(Q.Z,{children:"Role"})]})}),(0,l.jsx)(H.Z,{children:g?g.members_with_roles.map((e,t)=>(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{children:e.user_email?e.user_email:e.user_id?e.user_id:null}),(0,l.jsx)(Y.Z,{children:e.role})]},t)):null})]})})}),(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(o.Z,{className:"mx-auto mb-5",onClick:()=>_(!0),children:"+ Add member"}),(0,l.jsx)(B.Z,{title:"Add member",visible:k,width:800,footer:null,onOk:()=>{_(!1),m.resetFields()},onCancel:()=>{_(!1),m.resetFields()},children:(0,l.jsxs)(L.Z,{form:h,onFinish:N,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(L.Z.Item,{label:"Email",name:"user_email",className:"mb-4",children:(0,l.jsx)(z.Z,{name:"user_email",className:"px-3 py-2 border rounded-md w-full"})}),(0,l.jsx)("div",{className:"text-center mb-4",children:"OR"}),(0,l.jsx)(L.Z.Item,{label:"User ID",name:"user_id",className:"mb-4",children:(0,l.jsx)(z.Z,{name:"user_id",className:"px-3 py-2 border rounded-md w-full"})})]}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(W.ZP,{htmlType:"submit",children:"Add member"})})]})})]})]})})},ev=s(8510),eS=e=>{let{searchParams:t,accessToken:s}=e,[a]=L.Z.useForm(),[n]=L.Z.useForm(),{Title:i,Paragraph:d}=en.default,[h,m]=(0,r.useState)(""),[u,x]=(0,r.useState)(null),[p,j]=(0,r.useState)(!1);(0,r.useEffect)(()=>{(async()=>{if(null!=s){let e=[],t=await A(s,"proxy_admin_viewer");t.forEach(t=>{e.push({user_role:t.user_role,user_id:t.user_id,user_email:t.user_email})}),console.log("proxy viewers: ".concat(t));let l=await A(s,"proxy_admin");l.forEach(t=>{e.push({user_role:t.user_role,user_id:t.user_id,user_email:t.user_email})}),console.log("proxy admins: ".concat(l)),console.log("combinedList: ".concat(e)),x(e)}})()},[s]);let y=async e=>{try{if(null!=s&&null!=u){c.ZP.info("Making API Call"),e.user_email,e.user_id;let t=await I(s,e);console.log("response for team create call: ".concat(t));let l=u.findIndex(e=>(console.log("user.user_id=".concat(e.user_id,"; response.user_id=").concat(t.user_id)),e.user_id===t.user_id));console.log("foundIndex: ".concat(l)),-1==l&&(console.log("updates admin with new user"),u.push(t),x(u)),j(!1)}}catch(e){console.error("Error creating the key:",e)}};return console.log("admins: ".concat(null==u?void 0:u.length)),(0,l.jsxs)("div",{className:"w-full m-2",children:[(0,l.jsx)(i,{level:4,children:"Restricted Access"}),(0,l.jsxs)(d,{children:["Add other people to just view spend. They cannot create keys, teams or grant users access to new models."," ",(0,l.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/ui#restrict-ui-access",children:"Requires SSO Setup"})]}),(0,l.jsxs)(O.Z,{numItems:1,className:"gap-2 p-0 w-full",children:[(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsx)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,l.jsxs)($.Z,{children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"Member Name"}),(0,l.jsx)(Q.Z,{children:"Role"}),(0,l.jsx)(Q.Z,{children:"Action"})]})}),(0,l.jsx)(H.Z,{children:u?u.map((e,t)=>(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{children:e.user_email?e.user_email:e.user_id?e.user_id:null}),(0,l.jsx)(Y.Z,{children:e.user_role}),(0,l.jsx)(Y.Z,{children:(0,l.jsx)(G.Z,{icon:ev.Z,size:"sm"})})]},t)):null})]})})}),(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(o.Z,{className:"mx-auto mb-5",onClick:()=>j(!0),children:"+ Add viewer"}),(0,l.jsx)(B.Z,{title:"Add viewer",visible:p,width:800,footer:null,onOk:()=>{j(!1),n.resetFields()},onCancel:()=>{j(!1),n.resetFields()},children:(0,l.jsxs)(L.Z,{form:a,onFinish:y,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(L.Z.Item,{label:"Email",name:"user_email",className:"mb-4",children:(0,l.jsx)(z.Z,{name:"user_email",className:"px-3 py-2 border rounded-md w-full"})}),(0,l.jsx)("div",{className:"text-center mb-4",children:"OR"}),(0,l.jsx)(L.Z.Item,{label:"User ID",name:"user_id",className:"mb-4",children:(0,l.jsx)(z.Z,{name:"user_id",className:"px-3 py-2 border rounded-md w-full"})})]}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(W.ZP,{htmlType:"submit",children:"Add member"})})]})})]})]})]})},eN=s(12968),eA=s(67951);async function eC(e,t,s,l){console.log("isLocal:",!1);let r=window.location.origin,a=new eN.ZP.OpenAI({apiKey:l,baseURL:r,dangerouslyAllowBrowser:!0});for await(let l of(await a.chat.completions.create({model:s,stream:!0,messages:[{role:"user",content:e}]})))console.log(l),l.choices[0].delta.content&&t(l.choices[0].delta.content)}var eT=e=>{let{accessToken:t,token:s,userRole:a,userID:n}=e,[o,i]=(0,r.useState)(""),[c,d]=(0,r.useState)([]),[h,m]=(0,r.useState)(void 0),[u,x]=(0,r.useState)(null);(0,r.useEffect)(()=>{t&&s&&a&&n&&(async()=>{let e=await y(t,n,a);console.log("model_info:",e),(null==e?void 0:e.data.length)>0&&(x(e.data),m(e.data[0].id))})()},[t,n,a]);let p=(e,t)=>{d(s=>{let l=s[s.length-1];return l&&l.role===e?[...s.slice(0,s.length-1),{role:e,content:l.content+t}]:[...s,{role:e,content:t}]})},j=async()=>{if(""!==o.trim()&&t&&s&&a&&n){d(e=>[...e,{role:"user",content:o}]);try{h&&await eC(o,e=>p("assistant",e),h,t)}catch(e){console.error("Error fetching model response",e),p("assistant","Error fetching model response")}i("")}};if(a&&"Admin Viewer"==a){let{Title:e,Paragraph:t}=en.default;return(0,l.jsxs)("div",{children:[(0,l.jsx)(e,{level:1,children:"Access Denied"}),(0,l.jsx)(t,{children:"Ask your proxy admin for access to test models"})]})}return(0,l.jsx)("div",{style:{width:"100%",position:"relative"},children:(0,l.jsx)(O.Z,{className:"gap-2 p-10 h-[75vh] w-full",children:(0,l.jsx)(M.Z,{children:(0,l.jsxs)(ey.Z,{children:[(0,l.jsxs)(eg.Z,{className:"mt-4",children:[(0,l.jsx)(ej.Z,{children:"Chat"}),(0,l.jsx)(ej.Z,{children:"API Reference"})]}),(0,l.jsxs)(eZ.Z,{children:[(0,l.jsxs)(ew.Z,{children:[(0,l.jsxs)("div",{children:[(0,l.jsx)("label",{children:"Select Model:"}),(0,l.jsx)("select",{value:h||"",onChange:e=>m(e.target.value),children:null==u?void 0:u.map(e=>(0,l.jsx)("option",{value:e.id,children:e.id},e.id))})]}),(0,l.jsxs)($.Z,{className:"mt-5",style:{display:"block",maxHeight:"60vh",overflowY:"auto"},children:[(0,l.jsx)(X.Z,{children:(0,l.jsx)(ee.Z,{children:(0,l.jsx)(Y.Z,{children:(0,l.jsx)(D.Z,{children:"Chat"})})})}),(0,l.jsx)(H.Z,{children:c.map((e,t)=>(0,l.jsx)(ee.Z,{children:(0,l.jsx)(Y.Z,{children:"".concat(e.role,": ").concat(e.content)})},t))})]}),(0,l.jsx)("div",{className:"mt-3",style:{position:"absolute",bottom:5,width:"95%"},children:(0,l.jsxs)("div",{className:"flex",children:[(0,l.jsx)("input",{type:"text",value:o,onChange:e=>i(e.target.value),className:"flex-1 p-2 border rounded-md mr-2",placeholder:"Type your message..."}),(0,l.jsx)("button",{onClick:j,className:"p-2 bg-blue-500 text-white rounded-md",children:"Send"})]})})]}),(0,l.jsx)(ew.Z,{children:(0,l.jsxs)(ey.Z,{children:[(0,l.jsxs)(eg.Z,{children:[(0,l.jsx)(ej.Z,{children:"OpenAI Python SDK"}),(0,l.jsx)(ej.Z,{children:"LlamaIndex"}),(0,l.jsx)(ej.Z,{children:"Langchain Py"})]}),(0,l.jsxs)(eZ.Z,{children:[(0,l.jsx)(ew.Z,{children:(0,l.jsx)(eA.Z,{language:"python",children:'\nimport openai\nclient = openai.OpenAI(\n api_key="your_api_key",\n base_url="http://0.0.0.0:4000" # proxy base url\n)\n\nresponse = client.chat.completions.create(\n model="gpt-3.5-turbo", # model to use from Models Tab\n messages = [\n {\n "role": "user",\n "content": "this is a test request, write a short poem"\n }\n ],\n extra_body={\n "metadata": {\n "generation_name": "ishaan-generation-openai-client",\n "generation_id": "openai-client-gen-id22",\n "trace_id": "openai-client-trace-id22",\n "trace_user_id": "openai-client-user-id2"\n }\n }\n)\n\nprint(response)\n '})}),(0,l.jsx)(ew.Z,{children:(0,l.jsx)(eA.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="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,l.jsx)(ew.Z,{children:(0,l.jsx)(eA.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:8000",\n model = "gpt-3.5-turbo",\n temperature=0.1,\n extra_body={\n "metadata": {\n "generation_name": "ishaan-generation-langchain-client",\n "generation_id": "langchain-client-gen-id22",\n "trace_id": "langchain-client-trace-id22",\n "trace_user_id": "langchain-client-user-id2"\n }\n }\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 '})})]})]})})]})]})})})})},eI=s(33509),eP=s(30569);let{Sider:eE}=eI.default;var eF=e=>{let{setPage:t,userRole:s,defaultSelectedKey:r}=e;return"Admin Viewer"==s?(0,l.jsx)(eI.default,{style:{minHeight:"100vh",maxWidth:"120px"},children:(0,l.jsx)(eE,{width:120,children:(0,l.jsxs)(eP.Z,{mode:"inline",defaultSelectedKeys:r||["4"],style:{height:"100%",borderRight:0},children:[(0,l.jsx)(eP.Z.Item,{onClick:()=>t("api-keys"),children:"API Keys"},"4"),(0,l.jsx)(eP.Z.Item,{onClick:()=>t("models"),children:"Models"},"2"),(0,l.jsx)(eP.Z.Item,{onClick:()=>t("llm-playground"),children:"Chat UI"},"3"),(0,l.jsx)(eP.Z.Item,{onClick:()=>t("usage"),children:"Usage"},"1")]})})}):(0,l.jsx)(eI.default,{style:{minHeight:"100vh",maxWidth:"120px"},children:(0,l.jsx)(eE,{width:120,children:(0,l.jsxs)(eP.Z,{mode:"inline",defaultSelectedKeys:r||["1"],style:{height:"100%",borderRight:0},children:[(0,l.jsx)(eP.Z.Item,{onClick:()=>t("api-keys"),children:"API Keys"},"1"),(0,l.jsx)(eP.Z.Item,{onClick:()=>t("models"),children:"Models"},"2"),(0,l.jsx)(eP.Z.Item,{onClick:()=>t("llm-playground"),children:"Chat UI"},"3"),(0,l.jsx)(eP.Z.Item,{onClick:()=>t("usage"),children:"Usage"},"4"),"Admin"==s?(0,l.jsx)(eP.Z.Item,{onClick:()=>t("users"),children:"Users"},"5"):null,"Admin"==s?(0,l.jsx)(eP.Z.Item,{onClick:()=>t("teams"),children:"Teams"},"6"):null,"Admin"==s?(0,l.jsx)(eP.Z.Item,{onClick:()=>t("admin-panel"),children:"Admin"},"7"):null]})})})},eO=e=>{let{accessToken:t,token:s,userRole:a,userID:n}=e,o=new Date,[i,c]=(0,r.useState)([]),[d,h]=(0,r.useState)([]),[m,u]=(0,r.useState)([]),[x,p]=(0,r.useState)([]),[j,y]=(0,r.useState)([]),[g,_]=(0,r.useState)([]),[S,N]=(0,r.useState)([]),A=new Date(o.getFullYear(),o.getMonth(),1),C=new Date(o.getFullYear(),o.getMonth()+1,0),T=P(A),I=P(C);function P(e){let t=e.getFullYear(),s=e.getMonth()+1,l=e.getDate();return"".concat(t,"-").concat(s<10?"0"+s:s,"-").concat(l<10?"0"+l:l)}return console.log("Start date is ".concat(T)),console.log("End date is ".concat(I)),(0,r.useEffect)(()=>{t&&s&&a&&n&&(async()=>{try{if(console.log("user role: ".concat(a)),"Admin"==a||"Admin Viewer"==a){let e=await f(t);c(e);let s=(await k(t)).map(e=>({key:(e.key_name||e.key_alias||e.api_key).substring(0,7),spend:e.total_spend}));h(s);let l=(await b(t)).map(e=>({key:e.model,spend:e.total_spend}));u(l);let r=await w(t);console.log("teamSpend",r),y(r.daily_spend),_(r.teams),N(r.total_spend_per_team)}else"App Owner"==a&&await Z(t,s,a,n,T,I).then(async e=>{if(console.log("result from spend logs call",e),"daily_spend"in e){let t=e.daily_spend;console.log("daily spend",t),c(t);let s=e.top_api_keys;h(s)}else{let s=(await v(t,function(e){let t=[];e.forEach(e=>{Object.entries(e).forEach(e=>{let[s,l]=e;"spend"!==s&&"startTime"!==s&&"models"!==s&&"users"!==s&&t.push({key:s,spend:l})})}),t.sort((e,t)=>Number(t.spend)-Number(e.spend));let s=t.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||e.token).substring(0,7),spend:e.spend}));h(s),p(function(e){let t={};e.forEach(e=>{Object.entries(e.users).forEach(e=>{let[s,l]=e;""!==s&&null!=s&&"None"!=s&&(t[s]||(t[s]=0),t[s]+=l)})});let s=Object.entries(t).map(e=>{let[t,s]=e;return{user_id:t,spend:s}});s.sort((e,t)=>t.spend-e.spend);let l=s.slice(0,5);return console.log("topKeys: ".concat(Object.values(l[0]))),l}(e)),c(e)}})}catch(e){console.error("There was an error fetching the data",e)}})()},[t,s,a,n,T,I]),(0,l.jsx)("div",{style:{width:"100%"},children:(0,l.jsxs)(ey.Z,{children:[(0,l.jsxs)(eg.Z,{className:"mt-4",children:[(0,l.jsx)(ej.Z,{children:"All Up"}),(0,l.jsx)(ej.Z,{children:"Team Based Usage"})]}),(0,l.jsxs)(eZ.Z,{children:[(0,l.jsx)(ew.Z,{children:(0,l.jsxs)(O.Z,{numItems:2,className:"gap-2 p-10 h-[75vh] w-full",children:[(0,l.jsx)(F.Z,{numColSpan:2,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Monthly Spend"}),(0,l.jsx)(et.Z,{data:i,index:"date",categories:["spend"],colors:["blue"],valueFormatter:e=>"$ ".concat(new Intl.NumberFormat("us").format(e).toString()),yAxisWidth:100,tickGap:5})]})}),(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Top API Keys"}),(0,l.jsx)(et.Z,{className:"mt-4 h-40",data:d,index:"key",categories:["spend"],colors:["blue"],yAxisWidth:80,tickGap:5,layout:"vertical",showXAxis:!1,showLegend:!1})]})}),(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Top Users"}),(0,l.jsx)(et.Z,{className:"mt-4 h-40",data:x,index:"user_id",categories:["spend"],colors:["blue"],yAxisWidth:200,layout:"vertical",showXAxis:!1,showLegend:!1})]})}),(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Top Models"}),(0,l.jsx)(et.Z,{className:"mt-4 h-40",data:m,index:"key",categories:["spend"],colors:["blue"],yAxisWidth:200,layout:"vertical",showXAxis:!1,showLegend:!1})]})})]})}),(0,l.jsx)(ew.Z,{children:(0,l.jsxs)(O.Z,{numItems:2,className:"gap-2 p-10 h-[75vh] w-full",children:[(0,l.jsx)(F.Z,{numColSpan:2,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Daily Spend Per Team"}),(0,l.jsx)(et.Z,{className:"h-72",data:j,index:"date",categories:g,yAxisWidth:30,stack:!0})]})}),(0,l.jsx)(F.Z,{numColSpan:2,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Total Spend Per Team"}),(0,l.jsx)(et.Z,{className:"h-72",data:S,index:"team_id",categories:["total_spend"],yAxisWidth:30})]})})]})})]})]})})},eM=()=>{let{Title:e,Paragraph:t}=en.default,[s,n]=(0,r.useState)(""),[o,c]=(0,r.useState)(null),[d,h]=(0,r.useState)(null),[m,u]=(0,r.useState)(null),[x,p]=(0,r.useState)(!0),j=(0,a.useSearchParams)(),y=j.get("userID"),g=j.get("token"),[w,Z]=(0,r.useState)("api-keys"),[f,k]=(0,r.useState)(null);return(0,r.useEffect)(()=>{if(g){let e=(0,ed.o)(g);if(e){if(console.log("Decoded token:",e),console.log("Decoded key:",e.key),k(e.key),e.user_role){let t=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"app_user":return"App User";default:return"Unknown Role"}}(e.user_role);console.log("Decoded user_role:",t),n(t),"Admin Viewer"==t&&Z("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?p("username_password"==e.login_method):console.log("User Email is not set ".concat(e))}}},[g]),(0,l.jsx)(r.Suspense,{fallback:(0,l.jsx)("div",{children:"Loading..."}),children:(0,l.jsxs)("div",{className:"flex flex-col min-h-screen",children:[(0,l.jsx)(i,{userID:y,userRole:s,userEmail:o,showSSOBanner:x}),(0,l.jsxs)("div",{className:"flex flex-1 overflow-auto",children:[(0,l.jsx)(eF,{setPage:Z,userRole:s,defaultSelectedKey:null}),"api-keys"==w?(0,l.jsx)(eh,{userID:y,userRole:s,teams:d,keys:m,setUserRole:n,userEmail:o,setUserEmail:c,setTeams:h,setKeys:u}):"models"==w?(0,l.jsx)(ep,{userID:y,userRole:s,token:g,accessToken:f}):"llm-playground"==w?(0,l.jsx)(eT,{userID:y,userRole:s,token:g,accessToken:f}):"users"==w?(0,l.jsx)(e_,{userID:y,userRole:s,token:g,keys:m,accessToken:f,setKeys:u}):"teams"==w?(0,l.jsx)(eb,{teams:d,setTeams:h,searchParams:j,accessToken:f,userID:y,userRole:s}):"admin-panel"==w?(0,l.jsx)(eS,{setTeams:h,searchParams:j,accessToken:f}):(0,l.jsx)(eO,{userID:y,userRole:s,token:g,accessToken:f})]})]})})}}},function(e){e.O(0,[730,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/main-app-096338c8e1915716.js b/litellm/proxy/_experimental/out/_next/static/chunks/main-app-9b4fb13a7db53edf.js similarity index 54% rename from litellm/proxy/_experimental/out/_next/static/chunks/main-app-096338c8e1915716.js rename to litellm/proxy/_experimental/out/_next/static/chunks/main-app-9b4fb13a7db53edf.js index 421ae3e2c..440df3cb3 100644 --- a/litellm/proxy/_experimental/out/_next/static/chunks/main-app-096338c8e1915716.js +++ b/litellm/proxy/_experimental/out/_next/static/chunks/main-app-9b4fb13a7db53edf.js @@ -1 +1 @@ -(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[744],{70377:function(e,n,t){Promise.resolve().then(t.t.bind(t,47690,23)),Promise.resolve().then(t.t.bind(t,48955,23)),Promise.resolve().then(t.t.bind(t,5613,23)),Promise.resolve().then(t.t.bind(t,11902,23)),Promise.resolve().then(t.t.bind(t,31778,23)),Promise.resolve().then(t.t.bind(t,77831,23))}},function(e){var n=function(n){return e(e.s=n)};e.O(0,[971,69],function(){return n(35317),n(70377)}),_N_E=e.O()}]); \ No newline at end of file +(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[744],{32028:function(e,n,t){Promise.resolve().then(t.t.bind(t,47690,23)),Promise.resolve().then(t.t.bind(t,48955,23)),Promise.resolve().then(t.t.bind(t,5613,23)),Promise.resolve().then(t.t.bind(t,11902,23)),Promise.resolve().then(t.t.bind(t,31778,23)),Promise.resolve().then(t.t.bind(t,77831,23))}},function(e){var n=function(n){return e(e.s=n)};e.O(0,[971,69],function(){return n(35317),n(32028)}),_N_E=e.O()}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/aIO8mtlEIEUTmgL8cGjve/_buildManifest.js b/litellm/proxy/_experimental/out/_next/static/tpFpoAscsg2XQqXwfShjz/_buildManifest.js similarity index 100% rename from litellm/proxy/_experimental/out/_next/static/aIO8mtlEIEUTmgL8cGjve/_buildManifest.js rename to litellm/proxy/_experimental/out/_next/static/tpFpoAscsg2XQqXwfShjz/_buildManifest.js diff --git a/litellm/proxy/_experimental/out/_next/static/aIO8mtlEIEUTmgL8cGjve/_ssgManifest.js b/litellm/proxy/_experimental/out/_next/static/tpFpoAscsg2XQqXwfShjz/_ssgManifest.js similarity index 100% rename from litellm/proxy/_experimental/out/_next/static/aIO8mtlEIEUTmgL8cGjve/_ssgManifest.js rename to litellm/proxy/_experimental/out/_next/static/tpFpoAscsg2XQqXwfShjz/_ssgManifest.js diff --git a/litellm/proxy/_experimental/out/index.html b/litellm/proxy/_experimental/out/index.html index b138e2de3..92bf64b20 100644 --- a/litellm/proxy/_experimental/out/index.html +++ b/litellm/proxy/_experimental/out/index.html @@ -1 +1 @@ -🚅 LiteLLM \ No newline at end of file +🚅 LiteLLM \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/index.txt b/litellm/proxy/_experimental/out/index.txt index d70e09bac..c68d627f6 100644 --- a/litellm/proxy/_experimental/out/index.txt +++ b/litellm/proxy/_experimental/out/index.txt @@ -1,7 +1,7 @@ 2:I[77831,[],""] -3:I[19914,["730","static/chunks/730-1411b729a1c79695.js","931","static/chunks/app/page-144687b251040a22.js"],""] +3:I[92182,["730","static/chunks/730-1411b729a1c79695.js","931","static/chunks/app/page-2b5b48b67d7eccff.js"],""] 4:I[5613,[],""] 5:I[31778,[],""] -0:["aIO8mtlEIEUTmgL8cGjve",[[["",{"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_c23dc8","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/68a21c6e6697f7ca.css","precedence":"next","crossOrigin":""}]],"$L6"]]]] +0:["tpFpoAscsg2XQqXwfShjz",[[["",{"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_c23dc8","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/68a21c6e6697f7ca.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"}],["$","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 423a55d1f..99d054e9c 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

404

This page could not be found.

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

404

This page could not be found.

\ No newline at end of file diff --git a/ui/litellm-dashboard/out/_next/static/chunks/app/layout-24ae10436e315256.js b/ui/litellm-dashboard/out/_next/static/chunks/app/layout-24ae10436e315256.js new file mode 100644 index 000000000..e261adc05 --- /dev/null +++ b/ui/litellm-dashboard/out/_next/static/chunks/app/layout-24ae10436e315256.js @@ -0,0 +1 @@ +(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[185],{87421:function(n,e,t){Promise.resolve().then(t.t.bind(t,99646,23)),Promise.resolve().then(t.t.bind(t,63385,23))},63385:function(){},99646:function(n){n.exports={style:{fontFamily:"'__Inter_c23dc8', '__Inter_Fallback_c23dc8'",fontStyle:"normal"},className:"__className_c23dc8"}}},function(n){n.O(0,[971,69,744],function(){return n(n.s=87421)}),_N_E=n.O()}]); \ No newline at end of file diff --git a/ui/litellm-dashboard/out/_next/static/chunks/app/page-2b5b48b67d7eccff.js b/ui/litellm-dashboard/out/_next/static/chunks/app/page-2b5b48b67d7eccff.js new file mode 100644 index 000000000..f1848d3af --- /dev/null +++ b/ui/litellm-dashboard/out/_next/static/chunks/app/page-2b5b48b67d7eccff.js @@ -0,0 +1 @@ +(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[931],{20661:function(e,t,s){Promise.resolve().then(s.bind(s,92182))},92182:function(e,t,s){"use strict";s.r(t),s.d(t,{default:function(){return eM}});var l=s(3827),r=s(64090),a=s(47907),n=s(8792),o=s(2179),i=e=>{let{userID:t,userRole:s,userEmail:r,showSSOBanner:a}=e;return console.log("User ID:",t),console.log("userEmail:",r),(0,l.jsxs)("nav",{className:"left-0 right-0 top-0 flex justify-between items-center h-12 mb-4",children:[(0,l.jsx)("div",{className:"text-left my-2 absolute top-0 left-0",children:(0,l.jsx)("div",{className:"flex flex-col items-center",children:(0,l.jsx)(n.default,{href:"/",children:(0,l.jsx)("button",{className:"text-gray-800 text-2xl py-1 rounded text-center",children:(0,l.jsx)("img",{src:"/get_image",width:200,height:200,alt:"LiteLLM Brand",className:"mr-2"})})})})}),(0,l.jsxs)("div",{className:"text-right mx-4 my-2 absolute top-0 right-0 flex items-center justify-end space-x-2",children:[a?(0,l.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/ui#setup-ssoauth-for-ui",target:"_blank",className:"mr-2"}):null,(0,l.jsxs)(o.Z,{variant:"secondary",size:"lg",children:[r,(0,l.jsxs)("p",{children:["Role: ",s]}),(0,l.jsxs)("p",{children:["ID: ",t]})]})]})]})},c=s(80588);let d=async(e,t,s)=>{try{if(console.log("Form Values in keyCreateCall:",s),s.description&&(s.metadata||(s.metadata={}),s.metadata.description=s.description,delete s.description,s.metadata=JSON.stringify(s.metadata)),s.metadata){console.log("formValues.metadata:",s.metadata);try{s.metadata=JSON.parse(s.metadata)}catch(e){throw c.ZP.error("Failed to parse metadata: "+e),Error("Failed to parse metadata: "+e)}}console.log("Form Values after check:",s);let l=await fetch("/key/generate",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({user_id:t,...s})});if(!l.ok){let e=await l.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let r=await l.json();return console.log("API Response:",r),r}catch(e){throw console.error("Failed to create key:",e),e}},h=async(e,t,s)=>{try{if(console.log("Form Values in keyCreateCall:",s),s.description&&(s.metadata||(s.metadata={}),s.metadata.description=s.description,delete s.description,s.metadata=JSON.stringify(s.metadata)),s.metadata){console.log("formValues.metadata:",s.metadata);try{s.metadata=JSON.parse(s.metadata)}catch(e){throw c.ZP.error("Failed to parse metadata: "+e),Error("Failed to parse metadata: "+e)}}console.log("Form Values after check:",s);let l=await fetch("/user/new",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({user_id:t,...s})});if(!l.ok){let e=await l.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let r=await l.json();return console.log("API Response:",r),r}catch(e){throw console.error("Failed to create key:",e),e}},m=async(e,t)=>{try{console.log("in keyDeleteCall:",t);let s=await fetch("/key/delete",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({keys:[t]})});if(!s.ok){let e=await s.text();throw c.ZP.error("Failed to delete key: "+e),Error("Network response was not ok")}let l=await s.json();return console.log(l),l}catch(e){throw console.error("Failed to create key:",e),e}},u=async function(e,t,s){let l=arguments.length>3&&void 0!==arguments[3]&&arguments[3];try{let r="/user/info";"App Owner"==s&&t&&(r="".concat(r,"?user_id=").concat(t)),console.log("in userInfoCall viewAll=",l),l&&(r="".concat(r,"?view_all=true"));let a=await fetch(r,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!a.ok){let e=await a.text();throw c.ZP.error(e),Error("Network response was not ok")}let n=await a.json();return console.log("API Response:",n),n}catch(e){throw console.error("Failed to create key:",e),e}},x=async e=>{try{let t=await fetch("/global/spend",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},p=async(e,t,s)=>{try{let t=await fetch("/v2/model/info",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},j=async(e,t,s)=>{try{let t=await fetch("/model/metrics",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},y=async(e,t,s)=>{try{let t=await fetch("/models",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},g=async(e,t)=>{try{let s="/global/spend/logs";console.log("in keySpendLogsCall:",s);let l=await fetch("".concat(s,"?api_key=").concat(t),{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw c.ZP.error(e),Error("Network response was not ok")}let r=await l.json();return console.log(r),r}catch(e){throw console.error("Failed to create key:",e),e}},w=async e=>{try{let t="/global/spend/teams";console.log("in teamSpendLogsCall:",t);let s=await fetch("".concat(t),{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!s.ok){let e=await s.text();throw c.ZP.error(e),Error("Network response was not ok")}let l=await s.json();return console.log(l),l}catch(e){throw console.error("Failed to create key:",e),e}},Z=async(e,t,s,l,r,a)=>{try{console.log("user role in spend logs call: ".concat(s));let t="/spend/logs";t="App Owner"==s?"".concat(t,"?user_id=").concat(l,"&start_date=").concat(r,"&end_date=").concat(a):"".concat(t,"?start_date=").concat(r,"&end_date=").concat(a);let n=await fetch(t,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!n.ok){let e=await n.text();throw c.ZP.error(e),Error("Network response was not ok")}let o=await n.json();return console.log(o),o}catch(e){throw console.error("Failed to create key:",e),e}},f=async e=>{try{let t=await fetch("/global/spend/logs",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to create key:",e),e}},k=async e=>{try{let t=await fetch("/global/spend/keys?limit=5",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to create key:",e),e}},_=async(e,t)=>{try{t&&JSON.stringify({api_key:t});let s={method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}};t&&(s.body=JSON.stringify({api_key:t}));let l=await fetch("/global/spend/end_users",s);if(!l.ok){let e=await l.text();throw c.ZP.error(e),Error("Network response was not ok")}let r=await l.json();return console.log(r),r}catch(e){throw console.error("Failed to create key:",e),e}},b=async e=>{try{let t=await fetch("/global/spend/models?limit=5",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to create key:",e),e}},v=async(e,t)=>{try{let s=await fetch("/v2/key/info",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({keys:t})});if(!s.ok){let e=await s.text();throw c.ZP.error(e),Error("Network response was not ok")}let l=await s.json();return console.log(l),l}catch(e){throw console.error("Failed to create key:",e),e}},S=async(e,t,s,l)=>{try{let r=await fetch("/user/request_model",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({models:[t],user_id:s,justification:l})});if(!r.ok){let e=await r.text();throw c.ZP.error("Failed to delete key: "+e),Error("Network response was not ok")}let a=await r.json();return console.log(a),a}catch(e){throw console.error("Failed to create key:",e),e}},N=async e=>{try{let t="/user/get_requests";console.log("in userGetRequesedtModelsCall:",t);let s=await fetch(t,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!s.ok){let e=await s.text();throw c.ZP.error("Failed to delete key: "+e),Error("Network response was not ok")}let l=await s.json();return console.log(l),l}catch(e){throw console.error("Failed to get requested models:",e),e}},A=async(e,t)=>{try{let s="/user/get_users?role=".concat(t);console.log("in userGetAllUsersCall:",s);let l=await fetch(s,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw c.ZP.error("Failed to delete key: "+e),Error("Network response was not ok")}let r=await l.json();return console.log(r),r}catch(e){throw console.error("Failed to get requested models:",e),e}},C=async(e,t)=>{try{console.log("Form Values in teamCreateCall:",t);let s=await fetch("/team/new",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...t})});if(!s.ok){let e=await s.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let l=await s.json();return console.log("API Response:",l),l}catch(e){throw console.error("Failed to create key:",e),e}},T=async(e,t,s)=>{try{console.log("Form Values in teamMemberAddCall:",s);let l=await fetch("/team/member_add",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({team_id:t,member:s})});if(!l.ok){let e=await l.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let r=await l.json();return console.log("API Response:",r),r}catch(e){throw console.error("Failed to create key:",e),e}},I=async(e,t)=>{try{console.log("Form Values in userUpdateUserCall:",t);let s=await fetch("/user/update",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({user_role:"proxy_admin_viewer",...t})});if(!s.ok){let e=await s.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let l=await s.json();return console.log("API Response:",l),l}catch(e){throw console.error("Failed to create key:",e),e}},P=async(e,t)=>{try{let s=await fetch("/global/predict/spend/logs",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({data:t})});if(!s.ok){let e=await s.text();throw c.ZP.error(e),Error("Network response was not ok")}let l=await s.json();return console.log(l),l}catch(e){throw console.error("Failed to create key:",e),e}},E=async e=>{try{console.log("Checking Slack Budget Alerts service health");let t=await fetch("/health/services?service=slack_budget_alerts",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error("Failed Slack Alert test: "+e),Error(e)}let s=await t.json();return c.ZP.success("Test Slack Alert worked - check your Slack!"),console.log("Service Health Response:",s),s}catch(e){throw console.error("Failed to perform health check:",e),e}};var F=s(10384),O=s(46453),M=s(13810),R=s(71801),D=s(42440),U=s(17189),L=s(12143),B=s(77171),z=s(42539),K=s(88707),W=s(1861);let{Option:V}=U.default;var q=e=>{let{userID:t,teamID:s,userRole:a,accessToken:n,data:i,userModels:h,setData:m}=e,[u]=L.Z.useForm(),[x,p]=(0,r.useState)(!1),[j,y]=(0,r.useState)(null),[g,w]=(0,r.useState)(null),Z=()=>{p(!1),u.resetFields()},f=()=>{p(!1),y(null),u.resetFields()},k=async e=>{try{c.ZP.info("Making API Call"),p(!0);let s=await d(n,t,e);console.log("key create Response:",s),m(e=>e?[...e,s]:[s]),y(s.key),w(s.soft_budget),c.ZP.success("API Key Created"),u.resetFields(),localStorage.removeItem("userData"+t)}catch(e){console.error("Error creating the key:",e)}},_=async()=>{try{console.log("Sending Slack alert...");let e=await E(n);console.log("slackBudgetAlertsHealthCheck Response:",e),console.log("Testing Slack alert successful")}catch(e){console.error("Error sending Slack alert:",e)}};return(0,l.jsxs)("div",{children:[(0,l.jsx)(o.Z,{className:"mx-auto",onClick:()=>p(!0),children:"+ Create New Key"}),(0,l.jsx)(B.Z,{title:"Create Key",visible:x,width:800,footer:null,onOk:Z,onCancel:f,children:(0,l.jsxs)(L.Z,{form:u,onFinish:k,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:["App Owner"===a||"Admin"===a?(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(L.Z.Item,{label:"Key Name",name:"key_alias",children:(0,l.jsx)(z.Z,{})}),(0,l.jsx)(L.Z.Item,{label:"Team ID",name:"team_id",children:(0,l.jsx)(z.Z,{placeholder:"ai_team",defaultValue:s||""})}),(0,l.jsx)(L.Z.Item,{label:"Models",name:"models",children:(0,l.jsx)(U.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:h.map(e=>(0,l.jsx)(V,{value:e,children:e},e))})}),(0,l.jsx)(L.Z.Item,{label:"Soft Budget (USD) Monthly",name:"soft_budget",initialValue:50,children:(0,l.jsx)(K.Z,{step:.01,precision:2,defaultValue:50,width:200})}),(0,l.jsx)(L.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,l.jsx)(K.Z,{step:.01,precision:2,width:200})}),(0,l.jsx)(L.Z.Item,{label:"Reset Budget",name:"budget_duration",children:(0,l.jsxs)(U.default,{defaultValue:null,placeholder:"n/a",children:[(0,l.jsx)(U.default.Option,{value:"24h",children:"daily"}),(0,l.jsx)(U.default.Option,{value:"30d",children:"monthly"})]})}),(0,l.jsx)(L.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})}),(0,l.jsx)(L.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})}),(0,l.jsx)(L.Z.Item,{label:"Expire Key (eg: 30s, 30h, 30d)",name:"duration",children:(0,l.jsx)(z.Z,{})}),(0,l.jsx)(L.Z.Item,{label:"Metadata",name:"metadata",children:(0,l.jsx)(z.Z.TextArea,{rows:4,placeholder:"Enter metadata as JSON"})})]}):(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(L.Z.Item,{label:"Key Name",name:"key_alias",children:(0,l.jsx)(z.Z,{})}),(0,l.jsx)(L.Z.Item,{label:"Team ID (Contact Group)",name:"team_id",children:(0,l.jsx)(z.Z,{placeholder:"ai_team"})}),(0,l.jsx)(L.Z.Item,{label:"Description",name:"description",children:(0,l.jsx)(z.Z.TextArea,{placeholder:"Enter description",rows:4})})]}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(W.ZP,{htmlType:"submit",children:"Create Key"})})]})}),j&&(0,l.jsx)(B.Z,{visible:x,onOk:Z,onCancel:f,footer:null,children:(0,l.jsx)(O.Z,{numItems:1,className:"gap-2 w-full",children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Save your Key"}),(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsxs)("p",{children:["Please save this secret key somewhere safe and accessible. For security reasons, ",(0,l.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,l.jsx)(F.Z,{numColSpan:1,children:null!=j?(0,l.jsxs)("div",{children:[(0,l.jsxs)(R.Z,{children:["API Key: ",j]}),(0,l.jsx)(D.Z,{className:"mt-6",children:"Budgets"}),(0,l.jsxs)(R.Z,{children:["Soft Limit Budget: $",g]}),(0,l.jsx)(o.Z,{className:"mt-3",onClick:_,children:"Test Slack Alert"}),(0,l.jsxs)(R.Z,{className:"mt-2",children:["(LiteLLM Docs -",(0,l.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/alerting",target:"_blank",className:"text-blue-500",children:"Set Up Slack Alerting)"})]})]}):(0,l.jsx)(R.Z,{children:"Key being created, this might take 30s"})})]})})})]})},J=s(33393),G=s(61244),$=s(10827),H=s(3851),Y=s(2044),X=s(64167),Q=s(74480),ee=s(7178),et=s(9853),es=s(56863),el=e=>{let{token:t,accessToken:s,keySpend:a,keyBudget:n,keyName:i}=e,[c,d]=(0,r.useState)(!1),[h,m]=(0,r.useState)(null),[u,x]=(0,r.useState)(""),[p,j]=(0,r.useState)(null),y=async()=>{try{if(null==s||null==t)return;console.log("accessToken: ".concat(s,"; token: ").concat(t));let e=await g(s,t);console.log("Response:",e),m(e);let l=await P(s,e);console.log("Response2:",l);let r=[...e,...l.response];m(r),x(l.predicted_spend),console.log("Combined Data:",r)}catch(e){console.error("There was an error fetching the data",e)}};return t?(0,l.jsxs)("div",{children:[(0,l.jsx)(o.Z,{size:"xs",onClick:()=>{console.log("Show Modal triggered"),d(!0),y()},variant:"secondary",children:"Spend Report"}),(0,l.jsxs)(B.Z,{visible:c,width:1400,onOk:()=>{d(!1)},onCancel:()=>{d(!1)},footer:null,children:[(0,l.jsxs)(D.Z,{style:{textAlign:"left"},children:["Key Name: ",i]}),(0,l.jsxs)(es.Z,{children:["Monthly Spend $",a]}),(0,l.jsx)(D.Z,{children:u}),(0,l.jsx)(M.Z,{className:"mt-6 mb-6",children:h&&(0,l.jsx)(et.Z,{className:"mt-6",data:h,colors:["blue","amber"],index:"date",categories:["spend","predicted_spend"],yAxisWidth:80})})]})]}):null},er=e=>{let{userID:t,accessToken:s,data:a,setData:n}=e,[i,c]=(0,r.useState)(!1),[d,h]=(0,r.useState)(!1),[u,x]=(0,r.useState)(null),p=async e=>{null!=a&&(x(e),localStorage.removeItem("userData"+t),h(!0))},j=async()=>{if(null!=u&&null!=a){try{await m(s,u);let e=a.filter(e=>e.token!==u);n(e)}catch(e){console.error("Error deleting the key:",e)}h(!1),x(null)}};if(null!=a)return console.log("RERENDER TRIGGERED"),(0,l.jsxs)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh] mb-4",children:[(0,l.jsxs)($.Z,{className:"mt-5",children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"Key Alias"}),(0,l.jsx)(Q.Z,{children:"Secret Key"}),(0,l.jsx)(Q.Z,{children:"Spend (USD)"}),(0,l.jsx)(Q.Z,{children:"Key Budget (USD)"}),(0,l.jsx)(Q.Z,{children:"Spend Report"}),(0,l.jsx)(Q.Z,{children:"Team ID"}),(0,l.jsx)(Q.Z,{children:"Metadata"}),(0,l.jsx)(Q.Z,{children:"Models"}),(0,l.jsx)(Q.Z,{children:"TPM / RPM Limits"}),(0,l.jsx)(Q.Z,{children:"Expires"})]})}),(0,l.jsx)(H.Z,{children:a.map(e=>(console.log(e),"litellm-dashboard"===e.team_id)?null:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",whiteSpace:"pre-wrap",overflow:"hidden"},children:null!=e.key_alias?(0,l.jsx)(R.Z,{children:e.key_alias}):(0,l.jsx)(R.Z,{children:"Not Set"})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:e.key_name})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:(()=>{try{return parseFloat(e.spend).toFixed(4)}catch(t){return e.spend}})()})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",whiteSpace:"pre-wrap",overflow:"hidden"},children:null!=e.max_budget?(0,l.jsx)(R.Z,{children:e.max_budget}):(0,l.jsx)(R.Z,{children:"Unlimited Budget"})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px"},children:(0,l.jsx)(el,{token:e.token,accessToken:s,keySpend:e.spend,keyBudget:e.max_budget,keyName:e.key_name})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:e.team_id})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:JSON.stringify(e.metadata).slice(0,400)})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:JSON.stringify(e.models)})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",overflowWrap:"break-word"},children:(0,l.jsxs)(R.Z,{children:["TPM Limit: ",e.tpm_limit?e.tpm_limit:"Unlimited"," ",(0,l.jsx)("br",{})," RPM Limit:"," ",e.rpm_limit?e.rpm_limit:"Unlimited"]})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",wordWrap:"break-word"},children:null!=e.expires?(0,l.jsx)(R.Z,{children:e.expires}):(0,l.jsx)(R.Z,{children:"Never"})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",wordWrap:"break-word"},children:(0,l.jsx)(G.Z,{onClick:()=>p(e.token),icon:J.Z,size:"sm"})})]},e.token))})]}),d&&(0,l.jsx)("div",{className:"fixed z-10 inset-0 overflow-y-auto",children:(0,l.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,l.jsx)("div",{className:"fixed inset-0 transition-opacity","aria-hidden":"true",children:(0,l.jsx)("div",{className:"absolute inset-0 bg-gray-500 opacity-75"})}),(0,l.jsx)("span",{className:"hidden sm:inline-block sm:align-middle sm:h-screen","aria-hidden":"true",children:"​"}),(0,l.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,l.jsx)("div",{className:"bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4",children:(0,l.jsx)("div",{className:"sm:flex sm:items-start",children:(0,l.jsxs)("div",{className:"mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left",children:[(0,l.jsx)("h3",{className:"text-lg leading-6 font-medium text-gray-900",children:"Delete Key"}),(0,l.jsx)("div",{className:"mt-2",children:(0,l.jsx)("p",{className:"text-sm text-gray-500",children:"Are you sure you want to delete this key ?"})})]})})}),(0,l.jsxs)("div",{className:"bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse",children:[(0,l.jsx)(o.Z,{onClick:j,color:"red",className:"ml-2",children:"Delete"}),(0,l.jsx)(o.Z,{onClick:()=>{h(!1),x(null)},children:"Cancel"})]})]})]})})]})},ea=e=>{let{userID:t,userSpendData:s,userRole:a,accessToken:n}=e,[o,i]=(0,r.useState)(null==s?void 0:s.spend),[c,d]=(0,r.useState)((null==s?void 0:s.max_budget)||null);(0,r.useEffect)(()=>{(async()=>{if("Admin"===a)try{let e=await x(n);i(e.spend),d(e.max_budget||null)}catch(e){console.error("Error fetching global spend data:",e)}})()},[a,n]);let h=void 0!==o?o.toFixed(4):null;return(0,l.jsx)(l.Fragment,{children:(0,l.jsxs)(M.Z,{className:"mx-auto mb-4",children:[(0,l.jsxs)(es.Z,{children:["$",h]}),(0,l.jsxs)(D.Z,{children:["/ ",null!==c?"$".concat(c," limit"):"No limit"]})]})})},en=s(36083),eo=s(68967),ei=s(27166),ec=e=>{let{teams:t,setSelectedTeam:s}=e,{Title:a,Paragraph:n}=en.default,[o,i]=(0,r.useState)("");return(0,l.jsxs)("div",{className:"mt-10",children:[(0,l.jsx)(a,{level:4,children:"Default Team"}),(0,l.jsx)(n,{children:"If you belong to multiple teams, this setting controls which team is used by default when creating new API Keys."}),t&&t.length>0?(0,l.jsx)(eo.Z,{defaultValue:"0",children:t.map((e,t)=>(0,l.jsx)(ei.Z,{value:String(t),onClick:()=>s(e),children:e.team_alias},t))}):(0,l.jsxs)(n,{children:["No team created. ",(0,l.jsx)("b",{children:"Defaulting to personal account."})]})]})},ed=s(37963);console.log("isLocal:",!1);var eh=e=>{let{userID:t,userRole:s,teams:n,keys:o,setUserRole:i,userEmail:c,setUserEmail:d,setTeams:h,setKeys:m}=e,[p,j]=(0,r.useState)(null),g=(0,a.useSearchParams)();g.get("viewSpend"),(0,a.useRouter)();let w=g.get("token"),[Z,f]=(0,r.useState)(null),[k,_]=(0,r.useState)([]),[b,v]=(0,r.useState)(n?n[0]:null);if(window.addEventListener("beforeunload",function(){sessionStorage.clear()}),(0,r.useEffect)(()=>{if(w){let e=(0,ed.o)(w);if(e){if(console.log("Decoded token:",e),console.log("Decoded key:",e.key),f(e.key),e.user_role){let t=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";default:return"Unknown Role"}}(e.user_role);console.log("Decoded user_role:",t),i(t)}else console.log("User role not defined");e.user_email?d(e.user_email):console.log("User Email is not set ".concat(e))}}if(t&&Z&&s&&!o&&!p){let e=sessionStorage.getItem("userModels"+t);e?_(JSON.parse(e)):(async()=>{try{let e=await u(Z,t,s);if(console.log("received teams in user dashboard: ".concat(Object.keys(e),"; team values: ").concat(Object.entries(e.teams))),"Admin"==s){let e=await x(Z);j(e),console.log("globalSpend:",e)}else j(e.user_info);m(e.keys),h(e.teams),v(e.teams?e.teams[0]:null),sessionStorage.setItem("userData"+t,JSON.stringify(e.keys)),sessionStorage.setItem("userSpendData"+t,JSON.stringify(e.user_info));let l=(await y(Z,t,s)).data.map(e=>e.id);console.log("available_model_names:",l),_(l),console.log("userModels:",k),sessionStorage.setItem("userModels"+t,JSON.stringify(l))}catch(e){console.error("There was an error fetching the data",e)}})()}},[t,w,Z,o,s]),null==t||null==w){let e="/sso/key/generate";return console.log("Full URL:",e),window.location.href=e,null}if(null==Z)return null;if(null==s&&i("App Owner"),s&&"Admin Viewer"==s){let{Title:e,Paragraph:t}=en.default;return(0,l.jsxs)("div",{children:[(0,l.jsx)(e,{level:1,children:"Access Denied"}),(0,l.jsx)(t,{children:"Ask your proxy admin for access to create keys"})]})}return(0,l.jsx)("div",{children:(0,l.jsx)(O.Z,{numItems:1,className:"gap-0 p-10 h-[75vh] w-full",children:(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(ea,{userID:t,userSpendData:p,userRole:s,accessToken:Z}),(0,l.jsx)(er,{userID:t,accessToken:Z,data:o,setData:m}),(0,l.jsx)(q,{userID:t,teamID:b?b.team_id:null,userRole:s,userModels:k,accessToken:Z,data:o,setData:m}),(0,l.jsx)(ec,{teams:n,setSelectedTeam:v})]})})})},em=s(5);let{Option:eu}=U.default;var ex=e=>{let{userModels:t,accessToken:s,userID:a}=e,[n]=L.Z.useForm(),[i,d]=(0,r.useState)(!1),h=async e=>{try{c.ZP.info("Requesting access");let{selectedModel:t,accessReason:l}=e;await S(s,t,a,l),d(!0)}catch(e){console.error("Error requesting access:",e)}};return(0,l.jsxs)("div",{children:[(0,l.jsx)(o.Z,{size:"xs",onClick:()=>d(!0),children:"Request Access"}),(0,l.jsx)(B.Z,{title:"Request Access",visible:i,width:800,footer:null,onOk:()=>{d(!1),n.resetFields()},onCancel:()=>{d(!1),n.resetFields()},children:(0,l.jsxs)(L.Z,{form:n,onFinish:h,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsx)(L.Z.Item,{label:"Select Model",name:"selectedModel",children:(0,l.jsx)(U.default,{placeholder:"Select model",style:{width:"100%"},children:t.map(e=>(0,l.jsx)(eu,{value:e,children:e},e))})}),(0,l.jsx)(L.Z.Item,{label:"Reason for Access",name:"accessReason",children:(0,l.jsx)(z.Z.TextArea,{rows:4,placeholder:"Enter reason for access"})}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(o.Z,{children:"Request Access"})})]})})]})},ep=e=>{let{accessToken:t,token:s,userRole:a,userID:n}=e,[o,i]=(0,r.useState)({data:[]}),[c,d]=(0,r.useState)([]),[h,m]=(0,r.useState)([]);if((0,r.useEffect)(()=>{if(!t||!s||!a||!n)return;let e=async()=>{try{let e=await p(t,n,a);console.log("Model data response:",e.data),i(e);let s=await j(t,n,a);if(console.log("Model metrics response:",s),d(s),"Admin"===a&&t){let e=await N(t);console.log("Pending Requests:",h),m(e.requests||[])}}catch(e){console.error("There was an error fetching the model data",e)}};t&&s&&a&&n&&e()},[t,s,a,n]),!o||!t||!s||!a||!n)return(0,l.jsx)("div",{children:"Loading..."});let u=[];for(let e=0;e(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{children:(0,l.jsx)(D.Z,{children:e.model_name})}),(0,l.jsx)(Y.Z,{children:e.provider}),"Admin"===a&&(0,l.jsx)(Y.Z,{children:e.api_base}),(0,l.jsx)(Y.Z,{children:e.user_access?(0,l.jsx)(em.Z,{color:"green",children:"Yes"}):(0,l.jsx)(ex,{userModels:u,accessToken:t,userID:n})}),(0,l.jsx)(Y.Z,{children:e.input_cost}),(0,l.jsx)(Y.Z,{children:e.output_cost}),(0,l.jsx)(Y.Z,{children:e.max_tokens})]},e.model_name))})]})}),(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Model Statistics (Number Requests)"}),(0,l.jsx)(et.Z,{data:c,index:"model",categories:["num_requests"],colors:["blue"],yAxisWidth:400,layout:"vertical",tickGap:5})]}),(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Model Statistics (Latency)"}),(0,l.jsx)(et.Z,{data:c,index:"model",categories:["avg_latency_seconds"],colors:["red"],yAxisWidth:400,layout:"vertical",tickGap:5})]})]})})},ej=s(92836),ey=s(26734),eg=s(41608),ew=s(32126),eZ=s(23682);let{Option:ef}=U.default;var ek=e=>{let{userID:t,accessToken:s}=e,[a]=L.Z.useForm(),[n,i]=(0,r.useState)(!1),[d,m]=(0,r.useState)(null),[u,x]=(0,r.useState)([]);(0,r.useEffect)(()=>{(async()=>{try{let e=await y(s,t,"any"),l=[];for(let t=0;t{i(!1),a.resetFields()},j=()=>{i(!1),m(null),a.resetFields()},g=async e=>{try{c.ZP.info("Making API Call"),i(!0),console.log("formValues in create user:",e);let l=await h(s,t,e);console.log("user create Response:",l),m(l.key),c.ZP.success("API user Created"),a.resetFields(),localStorage.removeItem("userData"+t)}catch(e){console.error("Error creating the user:",e)}};return(0,l.jsxs)("div",{children:[(0,l.jsx)(o.Z,{className:"mx-auto",onClick:()=>i(!0),children:"+ Create New User"}),(0,l.jsx)(B.Z,{title:"Create User",visible:n,width:800,footer:null,onOk:p,onCancel:j,children:(0,l.jsxs)(L.Z,{form:a,onFinish:g,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsx)(L.Z.Item,{label:"User ID",name:"user_id",children:(0,l.jsx)(z.Z,{placeholder:"Enter User ID"})}),(0,l.jsx)(L.Z.Item,{label:"Team ID",name:"team_id",children:(0,l.jsx)(z.Z,{placeholder:"ai_team"})}),(0,l.jsx)(L.Z.Item,{label:"Models",name:"models",children:(0,l.jsx)(U.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:u.map(e=>(0,l.jsx)(ef,{value:e,children:e},e))})}),(0,l.jsx)(L.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,l.jsx)(K.Z,{step:.01,precision:2,width:200})}),(0,l.jsx)(L.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})}),(0,l.jsx)(L.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})}),(0,l.jsx)(L.Z.Item,{label:"Duration (eg: 30s, 30h, 30d)",name:"duration",children:(0,l.jsx)(z.Z,{})}),(0,l.jsx)(L.Z.Item,{label:"Metadata",name:"metadata",children:(0,l.jsx)(z.Z.TextArea,{rows:4,placeholder:"Enter metadata as JSON"})}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(W.ZP,{htmlType:"submit",children:"Create User"})})]})}),d&&(0,l.jsxs)(B.Z,{title:"Save Your User",visible:n,onOk:p,onCancel:j,footer:null,children:[(0,l.jsxs)("p",{children:["Please save this secret user somewhere safe and accessible. For security reasons, ",(0,l.jsx)("b",{children:"you will not be able to view it again"})," ","through your LiteLLM account. If you lose this secret user, you will need to generate a new one."]}),(0,l.jsx)("p",{children:null!=d?"API user: ".concat(d):"User being created, this might take 30s"})]})]})},e_=e=>{let{accessToken:t,token:s,keys:a,userRole:n,userID:o,setKeys:i}=e,[c,d]=(0,r.useState)(null),[h,m]=(0,r.useState)(null),[x,p]=(0,r.useState)(1);if((0,r.useEffect)(()=>{if(!t||!s||!n||!o)return;let e=async()=>{try{let e=await u(t,null,n,!0);console.log("user data response:",e),d(e)}catch(e){console.error("There was an error fetching the model data",e)}};t&&s&&n&&o&&!c&&e();let l=async()=>{try{let e=await _(t,null);console.log("user data response:",e),m(e)}catch(e){console.error("There was an error fetching the model data",e)}};n&&("Admin"==n||"Admin Viewer"==n)&&!h&&l()},[t,s,n,o]),!c||!t||!s||!n||!o)return(0,l.jsx)("div",{children:"Loading..."});let j=async e=>{try{let s=await _(t,e);console.log("user data response:",s),m(s)}catch(e){console.error("There was an error fetching the model data",e)}};return(0,l.jsx)("div",{style:{width:"100%"},children:(0,l.jsxs)(O.Z,{className:"gap-2 p-10 h-[75vh] w-full",children:[(0,l.jsx)(ek,{userID:o,accessToken:t}),(0,l.jsx)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh] mb-4",children:(0,l.jsxs)(ey.Z,{children:[(0,l.jsxs)(eg.Z,{variant:"line",defaultValue:"1",children:[(0,l.jsx)(ej.Z,{value:"1",children:"Key Owners"}),(0,l.jsx)(ej.Z,{value:"2",children:"End-Users"})]}),(0,l.jsxs)(eZ.Z,{children:[(0,l.jsx)(ew.Z,{children:(0,l.jsxs)($.Z,{className:"mt-5",children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"User ID"}),(0,l.jsx)(Q.Z,{children:"User Role"}),(0,l.jsx)(Q.Z,{children:"User Models"}),(0,l.jsx)(Q.Z,{children:"User Spend ($ USD)"}),(0,l.jsx)(Q.Z,{children:"User Max Budget ($ USD)"})]})}),(0,l.jsx)(H.Z,{children:c.map(e=>(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{children:e.user_id}),(0,l.jsx)(Y.Z,{children:e.user_role?e.user_role:"app_owner"}),(0,l.jsx)(Y.Z,{children:e.models&&e.models.length>0?e.models:"All Models"}),(0,l.jsx)(Y.Z,{children:e.spend?e.spend:0}),(0,l.jsx)(Y.Z,{children:e.max_budget?e.max_budget:"Unlimited"})]},e.user_id))})]})}),(0,l.jsxs)(ew.Z,{children:[(0,l.jsxs)("div",{className:"flex items-center",children:[(0,l.jsx)("div",{className:"flex-1"}),(0,l.jsxs)("div",{className:"flex-1 flex justify-between items-center",children:[(0,l.jsx)(R.Z,{className:"w-1/4 mr-2 text-right",children:"Key"}),(0,l.jsx)(eo.Z,{defaultValue:"1",className:"w-3/4",children:null==a?void 0:a.map((e,t)=>{if(e&&null!==e.key_name&&e.key_name.length>0)return(0,l.jsx)(ei.Z,{value:String(t),onClick:()=>j(e.token),children:e.key_name},t)})})]})]}),(0,l.jsxs)($.Z,{children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"End User"}),(0,l.jsx)(Q.Z,{children:"Spend"}),(0,l.jsx)(Q.Z,{children:"Total Events"})]})}),(0,l.jsx)(H.Z,{children:null==h?void 0:h.map((e,t)=>(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{children:e.end_user}),(0,l.jsx)(Y.Z,{children:e.total_spend}),(0,l.jsx)(Y.Z,{children:e.total_events})]},t))})]})]})]})]})}),function(){if(!c)return null;let e=Math.ceil(c.length/25),t=Math.min(25*x,c.length);return(0,l.jsxs)("div",{className:"flex justify-between items-center",children:[(0,l.jsxs)("div",{children:["Showing ",(x-1)*25+1," – ",t," of ",c.length]}),(0,l.jsxs)("div",{className:"flex",children:[(0,l.jsx)("button",{className:"bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-l focus:outline-none",disabled:1===x,onClick:()=>p(x-1),children:"← Prev"}),(0,l.jsx)("button",{className:"bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-r focus:outline-none",disabled:x===e,onClick:()=>p(x+1),children:"Next →"})]})]})}()]})})},eb=e=>{let{teams:t,searchParams:s,accessToken:a,setTeams:n,userID:i,userRole:d}=e,[h]=L.Z.useForm(),[m]=L.Z.useForm(),{Title:u,Paragraph:x}=en.default,[p,j]=(0,r.useState)(""),[g,w]=(0,r.useState)(t?t[0]:null),[Z,f]=(0,r.useState)(!1),[k,_]=(0,r.useState)(!1),[b,v]=(0,r.useState)([]);(0,r.useEffect)(()=>{(async()=>{try{if(null===i||null===d)return;if(null!==a){let e=(await y(a,i,d)).data.map(e=>e.id);console.log("available_model_names:",e),v(e)}}catch(e){console.error("Error fetching user models:",e)}})()},[a,i,d]);let S=async e=>{try{if(null!=a){let s=await C(a,e);null!==t?n([...t,s]):n([s]),console.log("response for team create call: ".concat(s)),c.ZP.success("Team created"),f(!1)}}catch(e){console.error("Error creating the key:",e),c.ZP.error("Error creating the team: "+e)}},N=async e=>{try{if(null!=a&&null!=t){c.ZP.info("Making API Call");let s={role:"user",user_email:e.user_email,user_id:e.user_id},l=await T(a,g.team_id,s);console.log("response for team create call: ".concat(l.data));let r=t.findIndex(e=>(console.log("team.team_id=".concat(e.team_id,"; response.data.team_id=").concat(l.data.team_id)),e.team_id===l.data.team_id));if(console.log("foundIndex: ".concat(r)),-1!==r){let e=[...t];e[r]=l.data,n(e),w(l.data)}_(!1)}}catch(e){console.error("Error creating the key:",e)}};return console.log("received teams ".concat(t)),(0,l.jsx)("div",{className:"w-full mx-4",children:(0,l.jsxs)(O.Z,{numItems:1,className:"gap-2 p-2 h-[75vh] w-full",children:[(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(u,{level:4,children:"All Teams"}),(0,l.jsx)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,l.jsxs)($.Z,{children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"Team Name"}),(0,l.jsx)(Q.Z,{children:"Spend (USD)"}),(0,l.jsx)(Q.Z,{children:"Budget (USD)"}),(0,l.jsx)(Q.Z,{children:"Models"}),(0,l.jsx)(Q.Z,{children:"TPM / RPM Limits"})]})}),(0,l.jsx)(H.Z,{children:t&&t.length>0?t.map(e=>(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:e.team_alias}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:e.spend}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:e.max_budget?e.max_budget:"No limit"}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:JSON.stringify(e.models?e.models:[])})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsxs)(R.Z,{children:["TPM Limit:"," ",e.tpm_limit?e.tpm_limit:"Unlimited"," ",(0,l.jsx)("br",{}),"RPM Limit:"," ",e.rpm_limit?e.rpm_limit:"Unlimited"]})})]},e.team_id)):null})]})})]}),(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(o.Z,{className:"mx-auto",onClick:()=>f(!0),children:"+ Create New Team"}),(0,l.jsx)(B.Z,{title:"Create Team",visible:Z,width:800,footer:null,onOk:()=>{f(!1),h.resetFields()},onCancel:()=>{f(!1),h.resetFields()},children:(0,l.jsxs)(L.Z,{form:h,onFinish:S,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(L.Z.Item,{label:"Team Name",name:"team_alias",children:(0,l.jsx)(z.Z,{})}),(0,l.jsx)(L.Z.Item,{label:"Models",name:"models",children:(0,l.jsx)(U.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:b.map(e=>(0,l.jsx)(U.default.Option,{value:e,children:e},e))})}),(0,l.jsx)(L.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,l.jsx)(K.Z,{step:.01,precision:2,width:200})}),(0,l.jsx)(L.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})}),(0,l.jsx)(L.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})})]}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(W.ZP,{htmlType:"submit",children:"Create Team"})})]})})]}),(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(u,{level:4,children:"Team Members"}),(0,l.jsx)(x,{children:"If you belong to multiple teams, this setting controls which teams members you see."}),t&&t.length>0?(0,l.jsx)(eo.Z,{defaultValue:"0",children:t.map((e,t)=>(0,l.jsx)(ei.Z,{value:String(t),onClick:()=>{w(e)},children:e.team_alias},t))}):(0,l.jsxs)(x,{children:["No team created. ",(0,l.jsx)("b",{children:"Defaulting to personal account."})]})]}),(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsx)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,l.jsxs)($.Z,{children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"Member Name"}),(0,l.jsx)(Q.Z,{children:"Role"})]})}),(0,l.jsx)(H.Z,{children:g?g.members_with_roles.map((e,t)=>(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{children:e.user_email?e.user_email:e.user_id?e.user_id:null}),(0,l.jsx)(Y.Z,{children:e.role})]},t)):null})]})})}),(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(o.Z,{className:"mx-auto mb-5",onClick:()=>_(!0),children:"+ Add member"}),(0,l.jsx)(B.Z,{title:"Add member",visible:k,width:800,footer:null,onOk:()=>{_(!1),m.resetFields()},onCancel:()=>{_(!1),m.resetFields()},children:(0,l.jsxs)(L.Z,{form:h,onFinish:N,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(L.Z.Item,{label:"Email",name:"user_email",className:"mb-4",children:(0,l.jsx)(z.Z,{name:"user_email",className:"px-3 py-2 border rounded-md w-full"})}),(0,l.jsx)("div",{className:"text-center mb-4",children:"OR"}),(0,l.jsx)(L.Z.Item,{label:"User ID",name:"user_id",className:"mb-4",children:(0,l.jsx)(z.Z,{name:"user_id",className:"px-3 py-2 border rounded-md w-full"})})]}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(W.ZP,{htmlType:"submit",children:"Add member"})})]})})]})]})})},ev=s(8510),eS=e=>{let{searchParams:t,accessToken:s}=e,[a]=L.Z.useForm(),[n]=L.Z.useForm(),{Title:i,Paragraph:d}=en.default,[h,m]=(0,r.useState)(""),[u,x]=(0,r.useState)(null),[p,j]=(0,r.useState)(!1);(0,r.useEffect)(()=>{(async()=>{if(null!=s){let e=[],t=await A(s,"proxy_admin_viewer");t.forEach(t=>{e.push({user_role:t.user_role,user_id:t.user_id,user_email:t.user_email})}),console.log("proxy viewers: ".concat(t));let l=await A(s,"proxy_admin");l.forEach(t=>{e.push({user_role:t.user_role,user_id:t.user_id,user_email:t.user_email})}),console.log("proxy admins: ".concat(l)),console.log("combinedList: ".concat(e)),x(e)}})()},[s]);let y=async e=>{try{if(null!=s&&null!=u){c.ZP.info("Making API Call"),e.user_email,e.user_id;let t=await I(s,e);console.log("response for team create call: ".concat(t));let l=u.findIndex(e=>(console.log("user.user_id=".concat(e.user_id,"; response.user_id=").concat(t.user_id)),e.user_id===t.user_id));console.log("foundIndex: ".concat(l)),-1==l&&(console.log("updates admin with new user"),u.push(t),x(u)),j(!1)}}catch(e){console.error("Error creating the key:",e)}};return console.log("admins: ".concat(null==u?void 0:u.length)),(0,l.jsxs)("div",{className:"w-full m-2",children:[(0,l.jsx)(i,{level:4,children:"Restricted Access"}),(0,l.jsxs)(d,{children:["Add other people to just view spend. They cannot create keys, teams or grant users access to new models."," ",(0,l.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/ui#restrict-ui-access",children:"Requires SSO Setup"})]}),(0,l.jsxs)(O.Z,{numItems:1,className:"gap-2 p-0 w-full",children:[(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsx)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,l.jsxs)($.Z,{children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"Member Name"}),(0,l.jsx)(Q.Z,{children:"Role"}),(0,l.jsx)(Q.Z,{children:"Action"})]})}),(0,l.jsx)(H.Z,{children:u?u.map((e,t)=>(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{children:e.user_email?e.user_email:e.user_id?e.user_id:null}),(0,l.jsx)(Y.Z,{children:e.user_role}),(0,l.jsx)(Y.Z,{children:(0,l.jsx)(G.Z,{icon:ev.Z,size:"sm"})})]},t)):null})]})})}),(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(o.Z,{className:"mx-auto mb-5",onClick:()=>j(!0),children:"+ Add viewer"}),(0,l.jsx)(B.Z,{title:"Add viewer",visible:p,width:800,footer:null,onOk:()=>{j(!1),n.resetFields()},onCancel:()=>{j(!1),n.resetFields()},children:(0,l.jsxs)(L.Z,{form:a,onFinish:y,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(L.Z.Item,{label:"Email",name:"user_email",className:"mb-4",children:(0,l.jsx)(z.Z,{name:"user_email",className:"px-3 py-2 border rounded-md w-full"})}),(0,l.jsx)("div",{className:"text-center mb-4",children:"OR"}),(0,l.jsx)(L.Z.Item,{label:"User ID",name:"user_id",className:"mb-4",children:(0,l.jsx)(z.Z,{name:"user_id",className:"px-3 py-2 border rounded-md w-full"})})]}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(W.ZP,{htmlType:"submit",children:"Add member"})})]})})]})]})]})},eN=s(12968),eA=s(67951);async function eC(e,t,s,l){console.log("isLocal:",!1);let r=window.location.origin,a=new eN.ZP.OpenAI({apiKey:l,baseURL:r,dangerouslyAllowBrowser:!0});for await(let l of(await a.chat.completions.create({model:s,stream:!0,messages:[{role:"user",content:e}]})))console.log(l),l.choices[0].delta.content&&t(l.choices[0].delta.content)}var eT=e=>{let{accessToken:t,token:s,userRole:a,userID:n}=e,[o,i]=(0,r.useState)(""),[c,d]=(0,r.useState)([]),[h,m]=(0,r.useState)(void 0),[u,x]=(0,r.useState)(null);(0,r.useEffect)(()=>{t&&s&&a&&n&&(async()=>{let e=await y(t,n,a);console.log("model_info:",e),(null==e?void 0:e.data.length)>0&&(x(e.data),m(e.data[0].id))})()},[t,n,a]);let p=(e,t)=>{d(s=>{let l=s[s.length-1];return l&&l.role===e?[...s.slice(0,s.length-1),{role:e,content:l.content+t}]:[...s,{role:e,content:t}]})},j=async()=>{if(""!==o.trim()&&t&&s&&a&&n){d(e=>[...e,{role:"user",content:o}]);try{h&&await eC(o,e=>p("assistant",e),h,t)}catch(e){console.error("Error fetching model response",e),p("assistant","Error fetching model response")}i("")}};if(a&&"Admin Viewer"==a){let{Title:e,Paragraph:t}=en.default;return(0,l.jsxs)("div",{children:[(0,l.jsx)(e,{level:1,children:"Access Denied"}),(0,l.jsx)(t,{children:"Ask your proxy admin for access to test models"})]})}return(0,l.jsx)("div",{style:{width:"100%",position:"relative"},children:(0,l.jsx)(O.Z,{className:"gap-2 p-10 h-[75vh] w-full",children:(0,l.jsx)(M.Z,{children:(0,l.jsxs)(ey.Z,{children:[(0,l.jsxs)(eg.Z,{className:"mt-4",children:[(0,l.jsx)(ej.Z,{children:"Chat"}),(0,l.jsx)(ej.Z,{children:"API Reference"})]}),(0,l.jsxs)(eZ.Z,{children:[(0,l.jsxs)(ew.Z,{children:[(0,l.jsxs)("div",{children:[(0,l.jsx)("label",{children:"Select Model:"}),(0,l.jsx)("select",{value:h||"",onChange:e=>m(e.target.value),children:null==u?void 0:u.map(e=>(0,l.jsx)("option",{value:e.id,children:e.id},e.id))})]}),(0,l.jsxs)($.Z,{className:"mt-5",style:{display:"block",maxHeight:"60vh",overflowY:"auto"},children:[(0,l.jsx)(X.Z,{children:(0,l.jsx)(ee.Z,{children:(0,l.jsx)(Y.Z,{children:(0,l.jsx)(D.Z,{children:"Chat"})})})}),(0,l.jsx)(H.Z,{children:c.map((e,t)=>(0,l.jsx)(ee.Z,{children:(0,l.jsx)(Y.Z,{children:"".concat(e.role,": ").concat(e.content)})},t))})]}),(0,l.jsx)("div",{className:"mt-3",style:{position:"absolute",bottom:5,width:"95%"},children:(0,l.jsxs)("div",{className:"flex",children:[(0,l.jsx)("input",{type:"text",value:o,onChange:e=>i(e.target.value),className:"flex-1 p-2 border rounded-md mr-2",placeholder:"Type your message..."}),(0,l.jsx)("button",{onClick:j,className:"p-2 bg-blue-500 text-white rounded-md",children:"Send"})]})})]}),(0,l.jsx)(ew.Z,{children:(0,l.jsxs)(ey.Z,{children:[(0,l.jsxs)(eg.Z,{children:[(0,l.jsx)(ej.Z,{children:"OpenAI Python SDK"}),(0,l.jsx)(ej.Z,{children:"LlamaIndex"}),(0,l.jsx)(ej.Z,{children:"Langchain Py"})]}),(0,l.jsxs)(eZ.Z,{children:[(0,l.jsx)(ew.Z,{children:(0,l.jsx)(eA.Z,{language:"python",children:'\nimport openai\nclient = openai.OpenAI(\n api_key="your_api_key",\n base_url="http://0.0.0.0:4000" # proxy base url\n)\n\nresponse = client.chat.completions.create(\n model="gpt-3.5-turbo", # model to use from Models Tab\n messages = [\n {\n "role": "user",\n "content": "this is a test request, write a short poem"\n }\n ],\n extra_body={\n "metadata": {\n "generation_name": "ishaan-generation-openai-client",\n "generation_id": "openai-client-gen-id22",\n "trace_id": "openai-client-trace-id22",\n "trace_user_id": "openai-client-user-id2"\n }\n }\n)\n\nprint(response)\n '})}),(0,l.jsx)(ew.Z,{children:(0,l.jsx)(eA.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="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,l.jsx)(ew.Z,{children:(0,l.jsx)(eA.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:8000",\n model = "gpt-3.5-turbo",\n temperature=0.1,\n extra_body={\n "metadata": {\n "generation_name": "ishaan-generation-langchain-client",\n "generation_id": "langchain-client-gen-id22",\n "trace_id": "langchain-client-trace-id22",\n "trace_user_id": "langchain-client-user-id2"\n }\n }\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 '})})]})]})})]})]})})})})},eI=s(33509),eP=s(30569);let{Sider:eE}=eI.default;var eF=e=>{let{setPage:t,userRole:s,defaultSelectedKey:r}=e;return"Admin Viewer"==s?(0,l.jsx)(eI.default,{style:{minHeight:"100vh",maxWidth:"120px"},children:(0,l.jsx)(eE,{width:120,children:(0,l.jsxs)(eP.Z,{mode:"inline",defaultSelectedKeys:r||["4"],style:{height:"100%",borderRight:0},children:[(0,l.jsx)(eP.Z.Item,{onClick:()=>t("api-keys"),children:"API Keys"},"4"),(0,l.jsx)(eP.Z.Item,{onClick:()=>t("models"),children:"Models"},"2"),(0,l.jsx)(eP.Z.Item,{onClick:()=>t("llm-playground"),children:"Chat UI"},"3"),(0,l.jsx)(eP.Z.Item,{onClick:()=>t("usage"),children:"Usage"},"1")]})})}):(0,l.jsx)(eI.default,{style:{minHeight:"100vh",maxWidth:"120px"},children:(0,l.jsx)(eE,{width:120,children:(0,l.jsxs)(eP.Z,{mode:"inline",defaultSelectedKeys:r||["1"],style:{height:"100%",borderRight:0},children:[(0,l.jsx)(eP.Z.Item,{onClick:()=>t("api-keys"),children:"API Keys"},"1"),(0,l.jsx)(eP.Z.Item,{onClick:()=>t("models"),children:"Models"},"2"),(0,l.jsx)(eP.Z.Item,{onClick:()=>t("llm-playground"),children:"Chat UI"},"3"),(0,l.jsx)(eP.Z.Item,{onClick:()=>t("usage"),children:"Usage"},"4"),"Admin"==s?(0,l.jsx)(eP.Z.Item,{onClick:()=>t("users"),children:"Users"},"5"):null,"Admin"==s?(0,l.jsx)(eP.Z.Item,{onClick:()=>t("teams"),children:"Teams"},"6"):null,"Admin"==s?(0,l.jsx)(eP.Z.Item,{onClick:()=>t("admin-panel"),children:"Admin"},"7"):null]})})})},eO=e=>{let{accessToken:t,token:s,userRole:a,userID:n}=e,o=new Date,[i,c]=(0,r.useState)([]),[d,h]=(0,r.useState)([]),[m,u]=(0,r.useState)([]),[x,p]=(0,r.useState)([]),[j,y]=(0,r.useState)([]),[g,_]=(0,r.useState)([]),[S,N]=(0,r.useState)([]),A=new Date(o.getFullYear(),o.getMonth(),1),C=new Date(o.getFullYear(),o.getMonth()+1,0),T=P(A),I=P(C);function P(e){let t=e.getFullYear(),s=e.getMonth()+1,l=e.getDate();return"".concat(t,"-").concat(s<10?"0"+s:s,"-").concat(l<10?"0"+l:l)}return console.log("Start date is ".concat(T)),console.log("End date is ".concat(I)),(0,r.useEffect)(()=>{t&&s&&a&&n&&(async()=>{try{if(console.log("user role: ".concat(a)),"Admin"==a||"Admin Viewer"==a){let e=await f(t);c(e);let s=(await k(t)).map(e=>({key:(e.key_name||e.key_alias||e.api_key).substring(0,7),spend:e.total_spend}));h(s);let l=(await b(t)).map(e=>({key:e.model,spend:e.total_spend}));u(l);let r=await w(t);console.log("teamSpend",r),y(r.daily_spend),_(r.teams),N(r.total_spend_per_team)}else"App Owner"==a&&await Z(t,s,a,n,T,I).then(async e=>{if(console.log("result from spend logs call",e),"daily_spend"in e){let t=e.daily_spend;console.log("daily spend",t),c(t);let s=e.top_api_keys;h(s)}else{let s=(await v(t,function(e){let t=[];e.forEach(e=>{Object.entries(e).forEach(e=>{let[s,l]=e;"spend"!==s&&"startTime"!==s&&"models"!==s&&"users"!==s&&t.push({key:s,spend:l})})}),t.sort((e,t)=>Number(t.spend)-Number(e.spend));let s=t.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||e.token).substring(0,7),spend:e.spend}));h(s),p(function(e){let t={};e.forEach(e=>{Object.entries(e.users).forEach(e=>{let[s,l]=e;""!==s&&null!=s&&"None"!=s&&(t[s]||(t[s]=0),t[s]+=l)})});let s=Object.entries(t).map(e=>{let[t,s]=e;return{user_id:t,spend:s}});s.sort((e,t)=>t.spend-e.spend);let l=s.slice(0,5);return console.log("topKeys: ".concat(Object.values(l[0]))),l}(e)),c(e)}})}catch(e){console.error("There was an error fetching the data",e)}})()},[t,s,a,n,T,I]),(0,l.jsx)("div",{style:{width:"100%"},children:(0,l.jsxs)(ey.Z,{children:[(0,l.jsxs)(eg.Z,{className:"mt-4",children:[(0,l.jsx)(ej.Z,{children:"All Up"}),(0,l.jsx)(ej.Z,{children:"Team Based Usage"})]}),(0,l.jsxs)(eZ.Z,{children:[(0,l.jsx)(ew.Z,{children:(0,l.jsxs)(O.Z,{numItems:2,className:"gap-2 p-10 h-[75vh] w-full",children:[(0,l.jsx)(F.Z,{numColSpan:2,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Monthly Spend"}),(0,l.jsx)(et.Z,{data:i,index:"date",categories:["spend"],colors:["blue"],valueFormatter:e=>"$ ".concat(new Intl.NumberFormat("us").format(e).toString()),yAxisWidth:100,tickGap:5})]})}),(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Top API Keys"}),(0,l.jsx)(et.Z,{className:"mt-4 h-40",data:d,index:"key",categories:["spend"],colors:["blue"],yAxisWidth:80,tickGap:5,layout:"vertical",showXAxis:!1,showLegend:!1})]})}),(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Top Users"}),(0,l.jsx)(et.Z,{className:"mt-4 h-40",data:x,index:"user_id",categories:["spend"],colors:["blue"],yAxisWidth:200,layout:"vertical",showXAxis:!1,showLegend:!1})]})}),(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Top Models"}),(0,l.jsx)(et.Z,{className:"mt-4 h-40",data:m,index:"key",categories:["spend"],colors:["blue"],yAxisWidth:200,layout:"vertical",showXAxis:!1,showLegend:!1})]})})]})}),(0,l.jsx)(ew.Z,{children:(0,l.jsxs)(O.Z,{numItems:2,className:"gap-2 p-10 h-[75vh] w-full",children:[(0,l.jsx)(F.Z,{numColSpan:2,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Daily Spend Per Team"}),(0,l.jsx)(et.Z,{className:"h-72",data:j,index:"date",categories:g,yAxisWidth:30,stack:!0})]})}),(0,l.jsx)(F.Z,{numColSpan:2,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Total Spend Per Team"}),(0,l.jsx)(et.Z,{className:"h-72",data:S,index:"team_id",categories:["total_spend"],yAxisWidth:30})]})})]})})]})]})})},eM=()=>{let{Title:e,Paragraph:t}=en.default,[s,n]=(0,r.useState)(""),[o,c]=(0,r.useState)(null),[d,h]=(0,r.useState)(null),[m,u]=(0,r.useState)(null),[x,p]=(0,r.useState)(!0),j=(0,a.useSearchParams)(),y=j.get("userID"),g=j.get("token"),[w,Z]=(0,r.useState)("api-keys"),[f,k]=(0,r.useState)(null);return(0,r.useEffect)(()=>{if(g){let e=(0,ed.o)(g);if(e){if(console.log("Decoded token:",e),console.log("Decoded key:",e.key),k(e.key),e.user_role){let t=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"app_user":return"App User";default:return"Unknown Role"}}(e.user_role);console.log("Decoded user_role:",t),n(t),"Admin Viewer"==t&&Z("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?p("username_password"==e.login_method):console.log("User Email is not set ".concat(e))}}},[g]),(0,l.jsx)(r.Suspense,{fallback:(0,l.jsx)("div",{children:"Loading..."}),children:(0,l.jsxs)("div",{className:"flex flex-col min-h-screen",children:[(0,l.jsx)(i,{userID:y,userRole:s,userEmail:o,showSSOBanner:x}),(0,l.jsxs)("div",{className:"flex flex-1 overflow-auto",children:[(0,l.jsx)(eF,{setPage:Z,userRole:s,defaultSelectedKey:null}),"api-keys"==w?(0,l.jsx)(eh,{userID:y,userRole:s,teams:d,keys:m,setUserRole:n,userEmail:o,setUserEmail:c,setTeams:h,setKeys:u}):"models"==w?(0,l.jsx)(ep,{userID:y,userRole:s,token:g,accessToken:f}):"llm-playground"==w?(0,l.jsx)(eT,{userID:y,userRole:s,token:g,accessToken:f}):"users"==w?(0,l.jsx)(e_,{userID:y,userRole:s,token:g,keys:m,accessToken:f,setKeys:u}):"teams"==w?(0,l.jsx)(eb,{teams:d,setTeams:h,searchParams:j,accessToken:f,userID:y,userRole:s}):"admin-panel"==w?(0,l.jsx)(eS,{setTeams:h,searchParams:j,accessToken:f}):(0,l.jsx)(eO,{userID:y,userRole:s,token:g,accessToken:f})]})]})})}}},function(e){e.O(0,[730,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/main-app-9b4fb13a7db53edf.js b/ui/litellm-dashboard/out/_next/static/chunks/main-app-9b4fb13a7db53edf.js new file mode 100644 index 000000000..440df3cb3 --- /dev/null +++ b/ui/litellm-dashboard/out/_next/static/chunks/main-app-9b4fb13a7db53edf.js @@ -0,0 +1 @@ +(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[744],{32028:function(e,n,t){Promise.resolve().then(t.t.bind(t,47690,23)),Promise.resolve().then(t.t.bind(t,48955,23)),Promise.resolve().then(t.t.bind(t,5613,23)),Promise.resolve().then(t.t.bind(t,11902,23)),Promise.resolve().then(t.t.bind(t,31778,23)),Promise.resolve().then(t.t.bind(t,77831,23))}},function(e){var n=function(n){return e(e.s=n)};e.O(0,[971,69],function(){return n(35317),n(32028)}),_N_E=e.O()}]); \ No newline at end of file diff --git a/ui/litellm-dashboard/out/_next/static/tpFpoAscsg2XQqXwfShjz/_buildManifest.js b/ui/litellm-dashboard/out/_next/static/tpFpoAscsg2XQqXwfShjz/_buildManifest.js new file mode 100644 index 000000000..f779caa02 --- /dev/null +++ b/ui/litellm-dashboard/out/_next/static/tpFpoAscsg2XQqXwfShjz/_buildManifest.js @@ -0,0 +1 @@ +self.__BUILD_MANIFEST={__rewrites:{afterFiles:[],beforeFiles:[],fallback:[]},"/_error":["static/chunks/pages/_error-d6107f1aac0c574c.js"],sortedPages:["/_app","/_error"]},self.__BUILD_MANIFEST_CB&&self.__BUILD_MANIFEST_CB(); \ No newline at end of file diff --git a/ui/litellm-dashboard/out/_next/static/tpFpoAscsg2XQqXwfShjz/_ssgManifest.js b/ui/litellm-dashboard/out/_next/static/tpFpoAscsg2XQqXwfShjz/_ssgManifest.js new file mode 100644 index 000000000..5b3ff592f --- /dev/null +++ b/ui/litellm-dashboard/out/_next/static/tpFpoAscsg2XQqXwfShjz/_ssgManifest.js @@ -0,0 +1 @@ +self.__SSG_MANIFEST=new Set([]);self.__SSG_MANIFEST_CB&&self.__SSG_MANIFEST_CB() \ No newline at end of file diff --git a/ui/litellm-dashboard/out/index.html b/ui/litellm-dashboard/out/index.html index b138e2de3..92bf64b20 100644 --- a/ui/litellm-dashboard/out/index.html +++ b/ui/litellm-dashboard/out/index.html @@ -1 +1 @@ -🚅 LiteLLM \ No newline at end of file +🚅 LiteLLM \ No newline at end of file diff --git a/ui/litellm-dashboard/out/index.txt b/ui/litellm-dashboard/out/index.txt index d70e09bac..c68d627f6 100644 --- a/ui/litellm-dashboard/out/index.txt +++ b/ui/litellm-dashboard/out/index.txt @@ -1,7 +1,7 @@ 2:I[77831,[],""] -3:I[19914,["730","static/chunks/730-1411b729a1c79695.js","931","static/chunks/app/page-144687b251040a22.js"],""] +3:I[92182,["730","static/chunks/730-1411b729a1c79695.js","931","static/chunks/app/page-2b5b48b67d7eccff.js"],""] 4:I[5613,[],""] 5:I[31778,[],""] -0:["aIO8mtlEIEUTmgL8cGjve",[[["",{"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_c23dc8","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/68a21c6e6697f7ca.css","precedence":"next","crossOrigin":""}]],"$L6"]]]] +0:["tpFpoAscsg2XQqXwfShjz",[[["",{"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_c23dc8","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/68a21c6e6697f7ca.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"}],["$","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 32a29fce69719c527d31a7acae6050076779a41b Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Thu, 28 Mar 2024 08:14:58 -0700 Subject: [PATCH 27/54] (feat) new ui build --- litellm/proxy/_experimental/out/404.html | 2 +- .../_buildManifest.js | 0 .../_ssgManifest.js | 0 .../{page-2b5b48b67d7eccff.js => page-7811c13c82288ada.js} | 2 +- litellm/proxy/_experimental/out/index.html | 2 +- litellm/proxy/_experimental/out/index.txt | 4 ++-- ui/litellm-dashboard/out/404.html | 2 +- .../_buildManifest.js | 0 .../_ssgManifest.js | 0 .../{page-2b5b48b67d7eccff.js => page-7811c13c82288ada.js} | 2 +- ui/litellm-dashboard/out/index.html | 2 +- ui/litellm-dashboard/out/index.txt | 4 ++-- ui/litellm-dashboard/src/components/teams.tsx | 2 +- 13 files changed, 11 insertions(+), 11 deletions(-) rename litellm/proxy/_experimental/out/_next/static/{tpFpoAscsg2XQqXwfShjz => NOy_Z-02UirnQn7wjpTs0}/_buildManifest.js (100%) rename litellm/proxy/_experimental/out/_next/static/{tpFpoAscsg2XQqXwfShjz => NOy_Z-02UirnQn7wjpTs0}/_ssgManifest.js (100%) rename litellm/proxy/_experimental/out/_next/static/chunks/app/{page-2b5b48b67d7eccff.js => page-7811c13c82288ada.js} (62%) rename ui/litellm-dashboard/out/_next/static/{tpFpoAscsg2XQqXwfShjz => NOy_Z-02UirnQn7wjpTs0}/_buildManifest.js (100%) rename ui/litellm-dashboard/out/_next/static/{tpFpoAscsg2XQqXwfShjz => NOy_Z-02UirnQn7wjpTs0}/_ssgManifest.js (100%) rename ui/litellm-dashboard/out/_next/static/chunks/app/{page-2b5b48b67d7eccff.js => page-7811c13c82288ada.js} (62%) diff --git a/litellm/proxy/_experimental/out/404.html b/litellm/proxy/_experimental/out/404.html index 99d054e9c..a53766463 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

404

This page could not be found.

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

404

This page could not be found.

\ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/tpFpoAscsg2XQqXwfShjz/_buildManifest.js b/litellm/proxy/_experimental/out/_next/static/NOy_Z-02UirnQn7wjpTs0/_buildManifest.js similarity index 100% rename from litellm/proxy/_experimental/out/_next/static/tpFpoAscsg2XQqXwfShjz/_buildManifest.js rename to litellm/proxy/_experimental/out/_next/static/NOy_Z-02UirnQn7wjpTs0/_buildManifest.js diff --git a/litellm/proxy/_experimental/out/_next/static/tpFpoAscsg2XQqXwfShjz/_ssgManifest.js b/litellm/proxy/_experimental/out/_next/static/NOy_Z-02UirnQn7wjpTs0/_ssgManifest.js similarity index 100% rename from litellm/proxy/_experimental/out/_next/static/tpFpoAscsg2XQqXwfShjz/_ssgManifest.js rename to litellm/proxy/_experimental/out/_next/static/NOy_Z-02UirnQn7wjpTs0/_ssgManifest.js diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/app/page-2b5b48b67d7eccff.js b/litellm/proxy/_experimental/out/_next/static/chunks/app/page-7811c13c82288ada.js similarity index 62% rename from litellm/proxy/_experimental/out/_next/static/chunks/app/page-2b5b48b67d7eccff.js rename to litellm/proxy/_experimental/out/_next/static/chunks/app/page-7811c13c82288ada.js index f1848d3af..8aae09847 100644 --- a/litellm/proxy/_experimental/out/_next/static/chunks/app/page-2b5b48b67d7eccff.js +++ b/litellm/proxy/_experimental/out/_next/static/chunks/app/page-7811c13c82288ada.js @@ -1 +1 @@ -(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[931],{20661:function(e,t,s){Promise.resolve().then(s.bind(s,92182))},92182:function(e,t,s){"use strict";s.r(t),s.d(t,{default:function(){return eM}});var l=s(3827),r=s(64090),a=s(47907),n=s(8792),o=s(2179),i=e=>{let{userID:t,userRole:s,userEmail:r,showSSOBanner:a}=e;return console.log("User ID:",t),console.log("userEmail:",r),(0,l.jsxs)("nav",{className:"left-0 right-0 top-0 flex justify-between items-center h-12 mb-4",children:[(0,l.jsx)("div",{className:"text-left my-2 absolute top-0 left-0",children:(0,l.jsx)("div",{className:"flex flex-col items-center",children:(0,l.jsx)(n.default,{href:"/",children:(0,l.jsx)("button",{className:"text-gray-800 text-2xl py-1 rounded text-center",children:(0,l.jsx)("img",{src:"/get_image",width:200,height:200,alt:"LiteLLM Brand",className:"mr-2"})})})})}),(0,l.jsxs)("div",{className:"text-right mx-4 my-2 absolute top-0 right-0 flex items-center justify-end space-x-2",children:[a?(0,l.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/ui#setup-ssoauth-for-ui",target:"_blank",className:"mr-2"}):null,(0,l.jsxs)(o.Z,{variant:"secondary",size:"lg",children:[r,(0,l.jsxs)("p",{children:["Role: ",s]}),(0,l.jsxs)("p",{children:["ID: ",t]})]})]})]})},c=s(80588);let d=async(e,t,s)=>{try{if(console.log("Form Values in keyCreateCall:",s),s.description&&(s.metadata||(s.metadata={}),s.metadata.description=s.description,delete s.description,s.metadata=JSON.stringify(s.metadata)),s.metadata){console.log("formValues.metadata:",s.metadata);try{s.metadata=JSON.parse(s.metadata)}catch(e){throw c.ZP.error("Failed to parse metadata: "+e),Error("Failed to parse metadata: "+e)}}console.log("Form Values after check:",s);let l=await fetch("/key/generate",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({user_id:t,...s})});if(!l.ok){let e=await l.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let r=await l.json();return console.log("API Response:",r),r}catch(e){throw console.error("Failed to create key:",e),e}},h=async(e,t,s)=>{try{if(console.log("Form Values in keyCreateCall:",s),s.description&&(s.metadata||(s.metadata={}),s.metadata.description=s.description,delete s.description,s.metadata=JSON.stringify(s.metadata)),s.metadata){console.log("formValues.metadata:",s.metadata);try{s.metadata=JSON.parse(s.metadata)}catch(e){throw c.ZP.error("Failed to parse metadata: "+e),Error("Failed to parse metadata: "+e)}}console.log("Form Values after check:",s);let l=await fetch("/user/new",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({user_id:t,...s})});if(!l.ok){let e=await l.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let r=await l.json();return console.log("API Response:",r),r}catch(e){throw console.error("Failed to create key:",e),e}},m=async(e,t)=>{try{console.log("in keyDeleteCall:",t);let s=await fetch("/key/delete",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({keys:[t]})});if(!s.ok){let e=await s.text();throw c.ZP.error("Failed to delete key: "+e),Error("Network response was not ok")}let l=await s.json();return console.log(l),l}catch(e){throw console.error("Failed to create key:",e),e}},u=async function(e,t,s){let l=arguments.length>3&&void 0!==arguments[3]&&arguments[3];try{let r="/user/info";"App Owner"==s&&t&&(r="".concat(r,"?user_id=").concat(t)),console.log("in userInfoCall viewAll=",l),l&&(r="".concat(r,"?view_all=true"));let a=await fetch(r,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!a.ok){let e=await a.text();throw c.ZP.error(e),Error("Network response was not ok")}let n=await a.json();return console.log("API Response:",n),n}catch(e){throw console.error("Failed to create key:",e),e}},x=async e=>{try{let t=await fetch("/global/spend",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},p=async(e,t,s)=>{try{let t=await fetch("/v2/model/info",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},j=async(e,t,s)=>{try{let t=await fetch("/model/metrics",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},y=async(e,t,s)=>{try{let t=await fetch("/models",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},g=async(e,t)=>{try{let s="/global/spend/logs";console.log("in keySpendLogsCall:",s);let l=await fetch("".concat(s,"?api_key=").concat(t),{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw c.ZP.error(e),Error("Network response was not ok")}let r=await l.json();return console.log(r),r}catch(e){throw console.error("Failed to create key:",e),e}},w=async e=>{try{let t="/global/spend/teams";console.log("in teamSpendLogsCall:",t);let s=await fetch("".concat(t),{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!s.ok){let e=await s.text();throw c.ZP.error(e),Error("Network response was not ok")}let l=await s.json();return console.log(l),l}catch(e){throw console.error("Failed to create key:",e),e}},Z=async(e,t,s,l,r,a)=>{try{console.log("user role in spend logs call: ".concat(s));let t="/spend/logs";t="App Owner"==s?"".concat(t,"?user_id=").concat(l,"&start_date=").concat(r,"&end_date=").concat(a):"".concat(t,"?start_date=").concat(r,"&end_date=").concat(a);let n=await fetch(t,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!n.ok){let e=await n.text();throw c.ZP.error(e),Error("Network response was not ok")}let o=await n.json();return console.log(o),o}catch(e){throw console.error("Failed to create key:",e),e}},f=async e=>{try{let t=await fetch("/global/spend/logs",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to create key:",e),e}},k=async e=>{try{let t=await fetch("/global/spend/keys?limit=5",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to create key:",e),e}},_=async(e,t)=>{try{t&&JSON.stringify({api_key:t});let s={method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}};t&&(s.body=JSON.stringify({api_key:t}));let l=await fetch("/global/spend/end_users",s);if(!l.ok){let e=await l.text();throw c.ZP.error(e),Error("Network response was not ok")}let r=await l.json();return console.log(r),r}catch(e){throw console.error("Failed to create key:",e),e}},b=async e=>{try{let t=await fetch("/global/spend/models?limit=5",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to create key:",e),e}},v=async(e,t)=>{try{let s=await fetch("/v2/key/info",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({keys:t})});if(!s.ok){let e=await s.text();throw c.ZP.error(e),Error("Network response was not ok")}let l=await s.json();return console.log(l),l}catch(e){throw console.error("Failed to create key:",e),e}},S=async(e,t,s,l)=>{try{let r=await fetch("/user/request_model",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({models:[t],user_id:s,justification:l})});if(!r.ok){let e=await r.text();throw c.ZP.error("Failed to delete key: "+e),Error("Network response was not ok")}let a=await r.json();return console.log(a),a}catch(e){throw console.error("Failed to create key:",e),e}},N=async e=>{try{let t="/user/get_requests";console.log("in userGetRequesedtModelsCall:",t);let s=await fetch(t,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!s.ok){let e=await s.text();throw c.ZP.error("Failed to delete key: "+e),Error("Network response was not ok")}let l=await s.json();return console.log(l),l}catch(e){throw console.error("Failed to get requested models:",e),e}},A=async(e,t)=>{try{let s="/user/get_users?role=".concat(t);console.log("in userGetAllUsersCall:",s);let l=await fetch(s,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw c.ZP.error("Failed to delete key: "+e),Error("Network response was not ok")}let r=await l.json();return console.log(r),r}catch(e){throw console.error("Failed to get requested models:",e),e}},C=async(e,t)=>{try{console.log("Form Values in teamCreateCall:",t);let s=await fetch("/team/new",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...t})});if(!s.ok){let e=await s.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let l=await s.json();return console.log("API Response:",l),l}catch(e){throw console.error("Failed to create key:",e),e}},T=async(e,t,s)=>{try{console.log("Form Values in teamMemberAddCall:",s);let l=await fetch("/team/member_add",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({team_id:t,member:s})});if(!l.ok){let e=await l.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let r=await l.json();return console.log("API Response:",r),r}catch(e){throw console.error("Failed to create key:",e),e}},I=async(e,t)=>{try{console.log("Form Values in userUpdateUserCall:",t);let s=await fetch("/user/update",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({user_role:"proxy_admin_viewer",...t})});if(!s.ok){let e=await s.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let l=await s.json();return console.log("API Response:",l),l}catch(e){throw console.error("Failed to create key:",e),e}},P=async(e,t)=>{try{let s=await fetch("/global/predict/spend/logs",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({data:t})});if(!s.ok){let e=await s.text();throw c.ZP.error(e),Error("Network response was not ok")}let l=await s.json();return console.log(l),l}catch(e){throw console.error("Failed to create key:",e),e}},E=async e=>{try{console.log("Checking Slack Budget Alerts service health");let t=await fetch("/health/services?service=slack_budget_alerts",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error("Failed Slack Alert test: "+e),Error(e)}let s=await t.json();return c.ZP.success("Test Slack Alert worked - check your Slack!"),console.log("Service Health Response:",s),s}catch(e){throw console.error("Failed to perform health check:",e),e}};var F=s(10384),O=s(46453),M=s(13810),R=s(71801),D=s(42440),U=s(17189),L=s(12143),B=s(77171),z=s(42539),K=s(88707),W=s(1861);let{Option:V}=U.default;var q=e=>{let{userID:t,teamID:s,userRole:a,accessToken:n,data:i,userModels:h,setData:m}=e,[u]=L.Z.useForm(),[x,p]=(0,r.useState)(!1),[j,y]=(0,r.useState)(null),[g,w]=(0,r.useState)(null),Z=()=>{p(!1),u.resetFields()},f=()=>{p(!1),y(null),u.resetFields()},k=async e=>{try{c.ZP.info("Making API Call"),p(!0);let s=await d(n,t,e);console.log("key create Response:",s),m(e=>e?[...e,s]:[s]),y(s.key),w(s.soft_budget),c.ZP.success("API Key Created"),u.resetFields(),localStorage.removeItem("userData"+t)}catch(e){console.error("Error creating the key:",e)}},_=async()=>{try{console.log("Sending Slack alert...");let e=await E(n);console.log("slackBudgetAlertsHealthCheck Response:",e),console.log("Testing Slack alert successful")}catch(e){console.error("Error sending Slack alert:",e)}};return(0,l.jsxs)("div",{children:[(0,l.jsx)(o.Z,{className:"mx-auto",onClick:()=>p(!0),children:"+ Create New Key"}),(0,l.jsx)(B.Z,{title:"Create Key",visible:x,width:800,footer:null,onOk:Z,onCancel:f,children:(0,l.jsxs)(L.Z,{form:u,onFinish:k,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:["App Owner"===a||"Admin"===a?(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(L.Z.Item,{label:"Key Name",name:"key_alias",children:(0,l.jsx)(z.Z,{})}),(0,l.jsx)(L.Z.Item,{label:"Team ID",name:"team_id",children:(0,l.jsx)(z.Z,{placeholder:"ai_team",defaultValue:s||""})}),(0,l.jsx)(L.Z.Item,{label:"Models",name:"models",children:(0,l.jsx)(U.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:h.map(e=>(0,l.jsx)(V,{value:e,children:e},e))})}),(0,l.jsx)(L.Z.Item,{label:"Soft Budget (USD) Monthly",name:"soft_budget",initialValue:50,children:(0,l.jsx)(K.Z,{step:.01,precision:2,defaultValue:50,width:200})}),(0,l.jsx)(L.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,l.jsx)(K.Z,{step:.01,precision:2,width:200})}),(0,l.jsx)(L.Z.Item,{label:"Reset Budget",name:"budget_duration",children:(0,l.jsxs)(U.default,{defaultValue:null,placeholder:"n/a",children:[(0,l.jsx)(U.default.Option,{value:"24h",children:"daily"}),(0,l.jsx)(U.default.Option,{value:"30d",children:"monthly"})]})}),(0,l.jsx)(L.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})}),(0,l.jsx)(L.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})}),(0,l.jsx)(L.Z.Item,{label:"Expire Key (eg: 30s, 30h, 30d)",name:"duration",children:(0,l.jsx)(z.Z,{})}),(0,l.jsx)(L.Z.Item,{label:"Metadata",name:"metadata",children:(0,l.jsx)(z.Z.TextArea,{rows:4,placeholder:"Enter metadata as JSON"})})]}):(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(L.Z.Item,{label:"Key Name",name:"key_alias",children:(0,l.jsx)(z.Z,{})}),(0,l.jsx)(L.Z.Item,{label:"Team ID (Contact Group)",name:"team_id",children:(0,l.jsx)(z.Z,{placeholder:"ai_team"})}),(0,l.jsx)(L.Z.Item,{label:"Description",name:"description",children:(0,l.jsx)(z.Z.TextArea,{placeholder:"Enter description",rows:4})})]}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(W.ZP,{htmlType:"submit",children:"Create Key"})})]})}),j&&(0,l.jsx)(B.Z,{visible:x,onOk:Z,onCancel:f,footer:null,children:(0,l.jsx)(O.Z,{numItems:1,className:"gap-2 w-full",children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Save your Key"}),(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsxs)("p",{children:["Please save this secret key somewhere safe and accessible. For security reasons, ",(0,l.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,l.jsx)(F.Z,{numColSpan:1,children:null!=j?(0,l.jsxs)("div",{children:[(0,l.jsxs)(R.Z,{children:["API Key: ",j]}),(0,l.jsx)(D.Z,{className:"mt-6",children:"Budgets"}),(0,l.jsxs)(R.Z,{children:["Soft Limit Budget: $",g]}),(0,l.jsx)(o.Z,{className:"mt-3",onClick:_,children:"Test Slack Alert"}),(0,l.jsxs)(R.Z,{className:"mt-2",children:["(LiteLLM Docs -",(0,l.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/alerting",target:"_blank",className:"text-blue-500",children:"Set Up Slack Alerting)"})]})]}):(0,l.jsx)(R.Z,{children:"Key being created, this might take 30s"})})]})})})]})},J=s(33393),G=s(61244),$=s(10827),H=s(3851),Y=s(2044),X=s(64167),Q=s(74480),ee=s(7178),et=s(9853),es=s(56863),el=e=>{let{token:t,accessToken:s,keySpend:a,keyBudget:n,keyName:i}=e,[c,d]=(0,r.useState)(!1),[h,m]=(0,r.useState)(null),[u,x]=(0,r.useState)(""),[p,j]=(0,r.useState)(null),y=async()=>{try{if(null==s||null==t)return;console.log("accessToken: ".concat(s,"; token: ").concat(t));let e=await g(s,t);console.log("Response:",e),m(e);let l=await P(s,e);console.log("Response2:",l);let r=[...e,...l.response];m(r),x(l.predicted_spend),console.log("Combined Data:",r)}catch(e){console.error("There was an error fetching the data",e)}};return t?(0,l.jsxs)("div",{children:[(0,l.jsx)(o.Z,{size:"xs",onClick:()=>{console.log("Show Modal triggered"),d(!0),y()},variant:"secondary",children:"Spend Report"}),(0,l.jsxs)(B.Z,{visible:c,width:1400,onOk:()=>{d(!1)},onCancel:()=>{d(!1)},footer:null,children:[(0,l.jsxs)(D.Z,{style:{textAlign:"left"},children:["Key Name: ",i]}),(0,l.jsxs)(es.Z,{children:["Monthly Spend $",a]}),(0,l.jsx)(D.Z,{children:u}),(0,l.jsx)(M.Z,{className:"mt-6 mb-6",children:h&&(0,l.jsx)(et.Z,{className:"mt-6",data:h,colors:["blue","amber"],index:"date",categories:["spend","predicted_spend"],yAxisWidth:80})})]})]}):null},er=e=>{let{userID:t,accessToken:s,data:a,setData:n}=e,[i,c]=(0,r.useState)(!1),[d,h]=(0,r.useState)(!1),[u,x]=(0,r.useState)(null),p=async e=>{null!=a&&(x(e),localStorage.removeItem("userData"+t),h(!0))},j=async()=>{if(null!=u&&null!=a){try{await m(s,u);let e=a.filter(e=>e.token!==u);n(e)}catch(e){console.error("Error deleting the key:",e)}h(!1),x(null)}};if(null!=a)return console.log("RERENDER TRIGGERED"),(0,l.jsxs)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh] mb-4",children:[(0,l.jsxs)($.Z,{className:"mt-5",children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"Key Alias"}),(0,l.jsx)(Q.Z,{children:"Secret Key"}),(0,l.jsx)(Q.Z,{children:"Spend (USD)"}),(0,l.jsx)(Q.Z,{children:"Key Budget (USD)"}),(0,l.jsx)(Q.Z,{children:"Spend Report"}),(0,l.jsx)(Q.Z,{children:"Team ID"}),(0,l.jsx)(Q.Z,{children:"Metadata"}),(0,l.jsx)(Q.Z,{children:"Models"}),(0,l.jsx)(Q.Z,{children:"TPM / RPM Limits"}),(0,l.jsx)(Q.Z,{children:"Expires"})]})}),(0,l.jsx)(H.Z,{children:a.map(e=>(console.log(e),"litellm-dashboard"===e.team_id)?null:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",whiteSpace:"pre-wrap",overflow:"hidden"},children:null!=e.key_alias?(0,l.jsx)(R.Z,{children:e.key_alias}):(0,l.jsx)(R.Z,{children:"Not Set"})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:e.key_name})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:(()=>{try{return parseFloat(e.spend).toFixed(4)}catch(t){return e.spend}})()})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",whiteSpace:"pre-wrap",overflow:"hidden"},children:null!=e.max_budget?(0,l.jsx)(R.Z,{children:e.max_budget}):(0,l.jsx)(R.Z,{children:"Unlimited Budget"})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px"},children:(0,l.jsx)(el,{token:e.token,accessToken:s,keySpend:e.spend,keyBudget:e.max_budget,keyName:e.key_name})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:e.team_id})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:JSON.stringify(e.metadata).slice(0,400)})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:JSON.stringify(e.models)})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",overflowWrap:"break-word"},children:(0,l.jsxs)(R.Z,{children:["TPM Limit: ",e.tpm_limit?e.tpm_limit:"Unlimited"," ",(0,l.jsx)("br",{})," RPM Limit:"," ",e.rpm_limit?e.rpm_limit:"Unlimited"]})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",wordWrap:"break-word"},children:null!=e.expires?(0,l.jsx)(R.Z,{children:e.expires}):(0,l.jsx)(R.Z,{children:"Never"})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",wordWrap:"break-word"},children:(0,l.jsx)(G.Z,{onClick:()=>p(e.token),icon:J.Z,size:"sm"})})]},e.token))})]}),d&&(0,l.jsx)("div",{className:"fixed z-10 inset-0 overflow-y-auto",children:(0,l.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,l.jsx)("div",{className:"fixed inset-0 transition-opacity","aria-hidden":"true",children:(0,l.jsx)("div",{className:"absolute inset-0 bg-gray-500 opacity-75"})}),(0,l.jsx)("span",{className:"hidden sm:inline-block sm:align-middle sm:h-screen","aria-hidden":"true",children:"​"}),(0,l.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,l.jsx)("div",{className:"bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4",children:(0,l.jsx)("div",{className:"sm:flex sm:items-start",children:(0,l.jsxs)("div",{className:"mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left",children:[(0,l.jsx)("h3",{className:"text-lg leading-6 font-medium text-gray-900",children:"Delete Key"}),(0,l.jsx)("div",{className:"mt-2",children:(0,l.jsx)("p",{className:"text-sm text-gray-500",children:"Are you sure you want to delete this key ?"})})]})})}),(0,l.jsxs)("div",{className:"bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse",children:[(0,l.jsx)(o.Z,{onClick:j,color:"red",className:"ml-2",children:"Delete"}),(0,l.jsx)(o.Z,{onClick:()=>{h(!1),x(null)},children:"Cancel"})]})]})]})})]})},ea=e=>{let{userID:t,userSpendData:s,userRole:a,accessToken:n}=e,[o,i]=(0,r.useState)(null==s?void 0:s.spend),[c,d]=(0,r.useState)((null==s?void 0:s.max_budget)||null);(0,r.useEffect)(()=>{(async()=>{if("Admin"===a)try{let e=await x(n);i(e.spend),d(e.max_budget||null)}catch(e){console.error("Error fetching global spend data:",e)}})()},[a,n]);let h=void 0!==o?o.toFixed(4):null;return(0,l.jsx)(l.Fragment,{children:(0,l.jsxs)(M.Z,{className:"mx-auto mb-4",children:[(0,l.jsxs)(es.Z,{children:["$",h]}),(0,l.jsxs)(D.Z,{children:["/ ",null!==c?"$".concat(c," limit"):"No limit"]})]})})},en=s(36083),eo=s(68967),ei=s(27166),ec=e=>{let{teams:t,setSelectedTeam:s}=e,{Title:a,Paragraph:n}=en.default,[o,i]=(0,r.useState)("");return(0,l.jsxs)("div",{className:"mt-10",children:[(0,l.jsx)(a,{level:4,children:"Default Team"}),(0,l.jsx)(n,{children:"If you belong to multiple teams, this setting controls which team is used by default when creating new API Keys."}),t&&t.length>0?(0,l.jsx)(eo.Z,{defaultValue:"0",children:t.map((e,t)=>(0,l.jsx)(ei.Z,{value:String(t),onClick:()=>s(e),children:e.team_alias},t))}):(0,l.jsxs)(n,{children:["No team created. ",(0,l.jsx)("b",{children:"Defaulting to personal account."})]})]})},ed=s(37963);console.log("isLocal:",!1);var eh=e=>{let{userID:t,userRole:s,teams:n,keys:o,setUserRole:i,userEmail:c,setUserEmail:d,setTeams:h,setKeys:m}=e,[p,j]=(0,r.useState)(null),g=(0,a.useSearchParams)();g.get("viewSpend"),(0,a.useRouter)();let w=g.get("token"),[Z,f]=(0,r.useState)(null),[k,_]=(0,r.useState)([]),[b,v]=(0,r.useState)(n?n[0]:null);if(window.addEventListener("beforeunload",function(){sessionStorage.clear()}),(0,r.useEffect)(()=>{if(w){let e=(0,ed.o)(w);if(e){if(console.log("Decoded token:",e),console.log("Decoded key:",e.key),f(e.key),e.user_role){let t=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";default:return"Unknown Role"}}(e.user_role);console.log("Decoded user_role:",t),i(t)}else console.log("User role not defined");e.user_email?d(e.user_email):console.log("User Email is not set ".concat(e))}}if(t&&Z&&s&&!o&&!p){let e=sessionStorage.getItem("userModels"+t);e?_(JSON.parse(e)):(async()=>{try{let e=await u(Z,t,s);if(console.log("received teams in user dashboard: ".concat(Object.keys(e),"; team values: ").concat(Object.entries(e.teams))),"Admin"==s){let e=await x(Z);j(e),console.log("globalSpend:",e)}else j(e.user_info);m(e.keys),h(e.teams),v(e.teams?e.teams[0]:null),sessionStorage.setItem("userData"+t,JSON.stringify(e.keys)),sessionStorage.setItem("userSpendData"+t,JSON.stringify(e.user_info));let l=(await y(Z,t,s)).data.map(e=>e.id);console.log("available_model_names:",l),_(l),console.log("userModels:",k),sessionStorage.setItem("userModels"+t,JSON.stringify(l))}catch(e){console.error("There was an error fetching the data",e)}})()}},[t,w,Z,o,s]),null==t||null==w){let e="/sso/key/generate";return console.log("Full URL:",e),window.location.href=e,null}if(null==Z)return null;if(null==s&&i("App Owner"),s&&"Admin Viewer"==s){let{Title:e,Paragraph:t}=en.default;return(0,l.jsxs)("div",{children:[(0,l.jsx)(e,{level:1,children:"Access Denied"}),(0,l.jsx)(t,{children:"Ask your proxy admin for access to create keys"})]})}return(0,l.jsx)("div",{children:(0,l.jsx)(O.Z,{numItems:1,className:"gap-0 p-10 h-[75vh] w-full",children:(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(ea,{userID:t,userSpendData:p,userRole:s,accessToken:Z}),(0,l.jsx)(er,{userID:t,accessToken:Z,data:o,setData:m}),(0,l.jsx)(q,{userID:t,teamID:b?b.team_id:null,userRole:s,userModels:k,accessToken:Z,data:o,setData:m}),(0,l.jsx)(ec,{teams:n,setSelectedTeam:v})]})})})},em=s(5);let{Option:eu}=U.default;var ex=e=>{let{userModels:t,accessToken:s,userID:a}=e,[n]=L.Z.useForm(),[i,d]=(0,r.useState)(!1),h=async e=>{try{c.ZP.info("Requesting access");let{selectedModel:t,accessReason:l}=e;await S(s,t,a,l),d(!0)}catch(e){console.error("Error requesting access:",e)}};return(0,l.jsxs)("div",{children:[(0,l.jsx)(o.Z,{size:"xs",onClick:()=>d(!0),children:"Request Access"}),(0,l.jsx)(B.Z,{title:"Request Access",visible:i,width:800,footer:null,onOk:()=>{d(!1),n.resetFields()},onCancel:()=>{d(!1),n.resetFields()},children:(0,l.jsxs)(L.Z,{form:n,onFinish:h,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsx)(L.Z.Item,{label:"Select Model",name:"selectedModel",children:(0,l.jsx)(U.default,{placeholder:"Select model",style:{width:"100%"},children:t.map(e=>(0,l.jsx)(eu,{value:e,children:e},e))})}),(0,l.jsx)(L.Z.Item,{label:"Reason for Access",name:"accessReason",children:(0,l.jsx)(z.Z.TextArea,{rows:4,placeholder:"Enter reason for access"})}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(o.Z,{children:"Request Access"})})]})})]})},ep=e=>{let{accessToken:t,token:s,userRole:a,userID:n}=e,[o,i]=(0,r.useState)({data:[]}),[c,d]=(0,r.useState)([]),[h,m]=(0,r.useState)([]);if((0,r.useEffect)(()=>{if(!t||!s||!a||!n)return;let e=async()=>{try{let e=await p(t,n,a);console.log("Model data response:",e.data),i(e);let s=await j(t,n,a);if(console.log("Model metrics response:",s),d(s),"Admin"===a&&t){let e=await N(t);console.log("Pending Requests:",h),m(e.requests||[])}}catch(e){console.error("There was an error fetching the model data",e)}};t&&s&&a&&n&&e()},[t,s,a,n]),!o||!t||!s||!a||!n)return(0,l.jsx)("div",{children:"Loading..."});let u=[];for(let e=0;e(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{children:(0,l.jsx)(D.Z,{children:e.model_name})}),(0,l.jsx)(Y.Z,{children:e.provider}),"Admin"===a&&(0,l.jsx)(Y.Z,{children:e.api_base}),(0,l.jsx)(Y.Z,{children:e.user_access?(0,l.jsx)(em.Z,{color:"green",children:"Yes"}):(0,l.jsx)(ex,{userModels:u,accessToken:t,userID:n})}),(0,l.jsx)(Y.Z,{children:e.input_cost}),(0,l.jsx)(Y.Z,{children:e.output_cost}),(0,l.jsx)(Y.Z,{children:e.max_tokens})]},e.model_name))})]})}),(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Model Statistics (Number Requests)"}),(0,l.jsx)(et.Z,{data:c,index:"model",categories:["num_requests"],colors:["blue"],yAxisWidth:400,layout:"vertical",tickGap:5})]}),(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Model Statistics (Latency)"}),(0,l.jsx)(et.Z,{data:c,index:"model",categories:["avg_latency_seconds"],colors:["red"],yAxisWidth:400,layout:"vertical",tickGap:5})]})]})})},ej=s(92836),ey=s(26734),eg=s(41608),ew=s(32126),eZ=s(23682);let{Option:ef}=U.default;var ek=e=>{let{userID:t,accessToken:s}=e,[a]=L.Z.useForm(),[n,i]=(0,r.useState)(!1),[d,m]=(0,r.useState)(null),[u,x]=(0,r.useState)([]);(0,r.useEffect)(()=>{(async()=>{try{let e=await y(s,t,"any"),l=[];for(let t=0;t{i(!1),a.resetFields()},j=()=>{i(!1),m(null),a.resetFields()},g=async e=>{try{c.ZP.info("Making API Call"),i(!0),console.log("formValues in create user:",e);let l=await h(s,t,e);console.log("user create Response:",l),m(l.key),c.ZP.success("API user Created"),a.resetFields(),localStorage.removeItem("userData"+t)}catch(e){console.error("Error creating the user:",e)}};return(0,l.jsxs)("div",{children:[(0,l.jsx)(o.Z,{className:"mx-auto",onClick:()=>i(!0),children:"+ Create New User"}),(0,l.jsx)(B.Z,{title:"Create User",visible:n,width:800,footer:null,onOk:p,onCancel:j,children:(0,l.jsxs)(L.Z,{form:a,onFinish:g,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsx)(L.Z.Item,{label:"User ID",name:"user_id",children:(0,l.jsx)(z.Z,{placeholder:"Enter User ID"})}),(0,l.jsx)(L.Z.Item,{label:"Team ID",name:"team_id",children:(0,l.jsx)(z.Z,{placeholder:"ai_team"})}),(0,l.jsx)(L.Z.Item,{label:"Models",name:"models",children:(0,l.jsx)(U.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:u.map(e=>(0,l.jsx)(ef,{value:e,children:e},e))})}),(0,l.jsx)(L.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,l.jsx)(K.Z,{step:.01,precision:2,width:200})}),(0,l.jsx)(L.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})}),(0,l.jsx)(L.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})}),(0,l.jsx)(L.Z.Item,{label:"Duration (eg: 30s, 30h, 30d)",name:"duration",children:(0,l.jsx)(z.Z,{})}),(0,l.jsx)(L.Z.Item,{label:"Metadata",name:"metadata",children:(0,l.jsx)(z.Z.TextArea,{rows:4,placeholder:"Enter metadata as JSON"})}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(W.ZP,{htmlType:"submit",children:"Create User"})})]})}),d&&(0,l.jsxs)(B.Z,{title:"Save Your User",visible:n,onOk:p,onCancel:j,footer:null,children:[(0,l.jsxs)("p",{children:["Please save this secret user somewhere safe and accessible. For security reasons, ",(0,l.jsx)("b",{children:"you will not be able to view it again"})," ","through your LiteLLM account. If you lose this secret user, you will need to generate a new one."]}),(0,l.jsx)("p",{children:null!=d?"API user: ".concat(d):"User being created, this might take 30s"})]})]})},e_=e=>{let{accessToken:t,token:s,keys:a,userRole:n,userID:o,setKeys:i}=e,[c,d]=(0,r.useState)(null),[h,m]=(0,r.useState)(null),[x,p]=(0,r.useState)(1);if((0,r.useEffect)(()=>{if(!t||!s||!n||!o)return;let e=async()=>{try{let e=await u(t,null,n,!0);console.log("user data response:",e),d(e)}catch(e){console.error("There was an error fetching the model data",e)}};t&&s&&n&&o&&!c&&e();let l=async()=>{try{let e=await _(t,null);console.log("user data response:",e),m(e)}catch(e){console.error("There was an error fetching the model data",e)}};n&&("Admin"==n||"Admin Viewer"==n)&&!h&&l()},[t,s,n,o]),!c||!t||!s||!n||!o)return(0,l.jsx)("div",{children:"Loading..."});let j=async e=>{try{let s=await _(t,e);console.log("user data response:",s),m(s)}catch(e){console.error("There was an error fetching the model data",e)}};return(0,l.jsx)("div",{style:{width:"100%"},children:(0,l.jsxs)(O.Z,{className:"gap-2 p-10 h-[75vh] w-full",children:[(0,l.jsx)(ek,{userID:o,accessToken:t}),(0,l.jsx)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh] mb-4",children:(0,l.jsxs)(ey.Z,{children:[(0,l.jsxs)(eg.Z,{variant:"line",defaultValue:"1",children:[(0,l.jsx)(ej.Z,{value:"1",children:"Key Owners"}),(0,l.jsx)(ej.Z,{value:"2",children:"End-Users"})]}),(0,l.jsxs)(eZ.Z,{children:[(0,l.jsx)(ew.Z,{children:(0,l.jsxs)($.Z,{className:"mt-5",children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"User ID"}),(0,l.jsx)(Q.Z,{children:"User Role"}),(0,l.jsx)(Q.Z,{children:"User Models"}),(0,l.jsx)(Q.Z,{children:"User Spend ($ USD)"}),(0,l.jsx)(Q.Z,{children:"User Max Budget ($ USD)"})]})}),(0,l.jsx)(H.Z,{children:c.map(e=>(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{children:e.user_id}),(0,l.jsx)(Y.Z,{children:e.user_role?e.user_role:"app_owner"}),(0,l.jsx)(Y.Z,{children:e.models&&e.models.length>0?e.models:"All Models"}),(0,l.jsx)(Y.Z,{children:e.spend?e.spend:0}),(0,l.jsx)(Y.Z,{children:e.max_budget?e.max_budget:"Unlimited"})]},e.user_id))})]})}),(0,l.jsxs)(ew.Z,{children:[(0,l.jsxs)("div",{className:"flex items-center",children:[(0,l.jsx)("div",{className:"flex-1"}),(0,l.jsxs)("div",{className:"flex-1 flex justify-between items-center",children:[(0,l.jsx)(R.Z,{className:"w-1/4 mr-2 text-right",children:"Key"}),(0,l.jsx)(eo.Z,{defaultValue:"1",className:"w-3/4",children:null==a?void 0:a.map((e,t)=>{if(e&&null!==e.key_name&&e.key_name.length>0)return(0,l.jsx)(ei.Z,{value:String(t),onClick:()=>j(e.token),children:e.key_name},t)})})]})]}),(0,l.jsxs)($.Z,{children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"End User"}),(0,l.jsx)(Q.Z,{children:"Spend"}),(0,l.jsx)(Q.Z,{children:"Total Events"})]})}),(0,l.jsx)(H.Z,{children:null==h?void 0:h.map((e,t)=>(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{children:e.end_user}),(0,l.jsx)(Y.Z,{children:e.total_spend}),(0,l.jsx)(Y.Z,{children:e.total_events})]},t))})]})]})]})]})}),function(){if(!c)return null;let e=Math.ceil(c.length/25),t=Math.min(25*x,c.length);return(0,l.jsxs)("div",{className:"flex justify-between items-center",children:[(0,l.jsxs)("div",{children:["Showing ",(x-1)*25+1," – ",t," of ",c.length]}),(0,l.jsxs)("div",{className:"flex",children:[(0,l.jsx)("button",{className:"bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-l focus:outline-none",disabled:1===x,onClick:()=>p(x-1),children:"← Prev"}),(0,l.jsx)("button",{className:"bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-r focus:outline-none",disabled:x===e,onClick:()=>p(x+1),children:"Next →"})]})]})}()]})})},eb=e=>{let{teams:t,searchParams:s,accessToken:a,setTeams:n,userID:i,userRole:d}=e,[h]=L.Z.useForm(),[m]=L.Z.useForm(),{Title:u,Paragraph:x}=en.default,[p,j]=(0,r.useState)(""),[g,w]=(0,r.useState)(t?t[0]:null),[Z,f]=(0,r.useState)(!1),[k,_]=(0,r.useState)(!1),[b,v]=(0,r.useState)([]);(0,r.useEffect)(()=>{(async()=>{try{if(null===i||null===d)return;if(null!==a){let e=(await y(a,i,d)).data.map(e=>e.id);console.log("available_model_names:",e),v(e)}}catch(e){console.error("Error fetching user models:",e)}})()},[a,i,d]);let S=async e=>{try{if(null!=a){let s=await C(a,e);null!==t?n([...t,s]):n([s]),console.log("response for team create call: ".concat(s)),c.ZP.success("Team created"),f(!1)}}catch(e){console.error("Error creating the key:",e),c.ZP.error("Error creating the team: "+e)}},N=async e=>{try{if(null!=a&&null!=t){c.ZP.info("Making API Call");let s={role:"user",user_email:e.user_email,user_id:e.user_id},l=await T(a,g.team_id,s);console.log("response for team create call: ".concat(l.data));let r=t.findIndex(e=>(console.log("team.team_id=".concat(e.team_id,"; response.data.team_id=").concat(l.data.team_id)),e.team_id===l.data.team_id));if(console.log("foundIndex: ".concat(r)),-1!==r){let e=[...t];e[r]=l.data,n(e),w(l.data)}_(!1)}}catch(e){console.error("Error creating the key:",e)}};return console.log("received teams ".concat(t)),(0,l.jsx)("div",{className:"w-full mx-4",children:(0,l.jsxs)(O.Z,{numItems:1,className:"gap-2 p-2 h-[75vh] w-full",children:[(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(u,{level:4,children:"All Teams"}),(0,l.jsx)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,l.jsxs)($.Z,{children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"Team Name"}),(0,l.jsx)(Q.Z,{children:"Spend (USD)"}),(0,l.jsx)(Q.Z,{children:"Budget (USD)"}),(0,l.jsx)(Q.Z,{children:"Models"}),(0,l.jsx)(Q.Z,{children:"TPM / RPM Limits"})]})}),(0,l.jsx)(H.Z,{children:t&&t.length>0?t.map(e=>(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:e.team_alias}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:e.spend}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:e.max_budget?e.max_budget:"No limit"}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:JSON.stringify(e.models?e.models:[])})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsxs)(R.Z,{children:["TPM Limit:"," ",e.tpm_limit?e.tpm_limit:"Unlimited"," ",(0,l.jsx)("br",{}),"RPM Limit:"," ",e.rpm_limit?e.rpm_limit:"Unlimited"]})})]},e.team_id)):null})]})})]}),(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(o.Z,{className:"mx-auto",onClick:()=>f(!0),children:"+ Create New Team"}),(0,l.jsx)(B.Z,{title:"Create Team",visible:Z,width:800,footer:null,onOk:()=>{f(!1),h.resetFields()},onCancel:()=>{f(!1),h.resetFields()},children:(0,l.jsxs)(L.Z,{form:h,onFinish:S,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(L.Z.Item,{label:"Team Name",name:"team_alias",children:(0,l.jsx)(z.Z,{})}),(0,l.jsx)(L.Z.Item,{label:"Models",name:"models",children:(0,l.jsx)(U.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:b.map(e=>(0,l.jsx)(U.default.Option,{value:e,children:e},e))})}),(0,l.jsx)(L.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,l.jsx)(K.Z,{step:.01,precision:2,width:200})}),(0,l.jsx)(L.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})}),(0,l.jsx)(L.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})})]}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(W.ZP,{htmlType:"submit",children:"Create Team"})})]})})]}),(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(u,{level:4,children:"Team Members"}),(0,l.jsx)(x,{children:"If you belong to multiple teams, this setting controls which teams members you see."}),t&&t.length>0?(0,l.jsx)(eo.Z,{defaultValue:"0",children:t.map((e,t)=>(0,l.jsx)(ei.Z,{value:String(t),onClick:()=>{w(e)},children:e.team_alias},t))}):(0,l.jsxs)(x,{children:["No team created. ",(0,l.jsx)("b",{children:"Defaulting to personal account."})]})]}),(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsx)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,l.jsxs)($.Z,{children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"Member Name"}),(0,l.jsx)(Q.Z,{children:"Role"})]})}),(0,l.jsx)(H.Z,{children:g?g.members_with_roles.map((e,t)=>(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{children:e.user_email?e.user_email:e.user_id?e.user_id:null}),(0,l.jsx)(Y.Z,{children:e.role})]},t)):null})]})})}),(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(o.Z,{className:"mx-auto mb-5",onClick:()=>_(!0),children:"+ Add member"}),(0,l.jsx)(B.Z,{title:"Add member",visible:k,width:800,footer:null,onOk:()=>{_(!1),m.resetFields()},onCancel:()=>{_(!1),m.resetFields()},children:(0,l.jsxs)(L.Z,{form:h,onFinish:N,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(L.Z.Item,{label:"Email",name:"user_email",className:"mb-4",children:(0,l.jsx)(z.Z,{name:"user_email",className:"px-3 py-2 border rounded-md w-full"})}),(0,l.jsx)("div",{className:"text-center mb-4",children:"OR"}),(0,l.jsx)(L.Z.Item,{label:"User ID",name:"user_id",className:"mb-4",children:(0,l.jsx)(z.Z,{name:"user_id",className:"px-3 py-2 border rounded-md w-full"})})]}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(W.ZP,{htmlType:"submit",children:"Add member"})})]})})]})]})})},ev=s(8510),eS=e=>{let{searchParams:t,accessToken:s}=e,[a]=L.Z.useForm(),[n]=L.Z.useForm(),{Title:i,Paragraph:d}=en.default,[h,m]=(0,r.useState)(""),[u,x]=(0,r.useState)(null),[p,j]=(0,r.useState)(!1);(0,r.useEffect)(()=>{(async()=>{if(null!=s){let e=[],t=await A(s,"proxy_admin_viewer");t.forEach(t=>{e.push({user_role:t.user_role,user_id:t.user_id,user_email:t.user_email})}),console.log("proxy viewers: ".concat(t));let l=await A(s,"proxy_admin");l.forEach(t=>{e.push({user_role:t.user_role,user_id:t.user_id,user_email:t.user_email})}),console.log("proxy admins: ".concat(l)),console.log("combinedList: ".concat(e)),x(e)}})()},[s]);let y=async e=>{try{if(null!=s&&null!=u){c.ZP.info("Making API Call"),e.user_email,e.user_id;let t=await I(s,e);console.log("response for team create call: ".concat(t));let l=u.findIndex(e=>(console.log("user.user_id=".concat(e.user_id,"; response.user_id=").concat(t.user_id)),e.user_id===t.user_id));console.log("foundIndex: ".concat(l)),-1==l&&(console.log("updates admin with new user"),u.push(t),x(u)),j(!1)}}catch(e){console.error("Error creating the key:",e)}};return console.log("admins: ".concat(null==u?void 0:u.length)),(0,l.jsxs)("div",{className:"w-full m-2",children:[(0,l.jsx)(i,{level:4,children:"Restricted Access"}),(0,l.jsxs)(d,{children:["Add other people to just view spend. They cannot create keys, teams or grant users access to new models."," ",(0,l.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/ui#restrict-ui-access",children:"Requires SSO Setup"})]}),(0,l.jsxs)(O.Z,{numItems:1,className:"gap-2 p-0 w-full",children:[(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsx)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,l.jsxs)($.Z,{children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"Member Name"}),(0,l.jsx)(Q.Z,{children:"Role"}),(0,l.jsx)(Q.Z,{children:"Action"})]})}),(0,l.jsx)(H.Z,{children:u?u.map((e,t)=>(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{children:e.user_email?e.user_email:e.user_id?e.user_id:null}),(0,l.jsx)(Y.Z,{children:e.user_role}),(0,l.jsx)(Y.Z,{children:(0,l.jsx)(G.Z,{icon:ev.Z,size:"sm"})})]},t)):null})]})})}),(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(o.Z,{className:"mx-auto mb-5",onClick:()=>j(!0),children:"+ Add viewer"}),(0,l.jsx)(B.Z,{title:"Add viewer",visible:p,width:800,footer:null,onOk:()=>{j(!1),n.resetFields()},onCancel:()=>{j(!1),n.resetFields()},children:(0,l.jsxs)(L.Z,{form:a,onFinish:y,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(L.Z.Item,{label:"Email",name:"user_email",className:"mb-4",children:(0,l.jsx)(z.Z,{name:"user_email",className:"px-3 py-2 border rounded-md w-full"})}),(0,l.jsx)("div",{className:"text-center mb-4",children:"OR"}),(0,l.jsx)(L.Z.Item,{label:"User ID",name:"user_id",className:"mb-4",children:(0,l.jsx)(z.Z,{name:"user_id",className:"px-3 py-2 border rounded-md w-full"})})]}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(W.ZP,{htmlType:"submit",children:"Add member"})})]})})]})]})]})},eN=s(12968),eA=s(67951);async function eC(e,t,s,l){console.log("isLocal:",!1);let r=window.location.origin,a=new eN.ZP.OpenAI({apiKey:l,baseURL:r,dangerouslyAllowBrowser:!0});for await(let l of(await a.chat.completions.create({model:s,stream:!0,messages:[{role:"user",content:e}]})))console.log(l),l.choices[0].delta.content&&t(l.choices[0].delta.content)}var eT=e=>{let{accessToken:t,token:s,userRole:a,userID:n}=e,[o,i]=(0,r.useState)(""),[c,d]=(0,r.useState)([]),[h,m]=(0,r.useState)(void 0),[u,x]=(0,r.useState)(null);(0,r.useEffect)(()=>{t&&s&&a&&n&&(async()=>{let e=await y(t,n,a);console.log("model_info:",e),(null==e?void 0:e.data.length)>0&&(x(e.data),m(e.data[0].id))})()},[t,n,a]);let p=(e,t)=>{d(s=>{let l=s[s.length-1];return l&&l.role===e?[...s.slice(0,s.length-1),{role:e,content:l.content+t}]:[...s,{role:e,content:t}]})},j=async()=>{if(""!==o.trim()&&t&&s&&a&&n){d(e=>[...e,{role:"user",content:o}]);try{h&&await eC(o,e=>p("assistant",e),h,t)}catch(e){console.error("Error fetching model response",e),p("assistant","Error fetching model response")}i("")}};if(a&&"Admin Viewer"==a){let{Title:e,Paragraph:t}=en.default;return(0,l.jsxs)("div",{children:[(0,l.jsx)(e,{level:1,children:"Access Denied"}),(0,l.jsx)(t,{children:"Ask your proxy admin for access to test models"})]})}return(0,l.jsx)("div",{style:{width:"100%",position:"relative"},children:(0,l.jsx)(O.Z,{className:"gap-2 p-10 h-[75vh] w-full",children:(0,l.jsx)(M.Z,{children:(0,l.jsxs)(ey.Z,{children:[(0,l.jsxs)(eg.Z,{className:"mt-4",children:[(0,l.jsx)(ej.Z,{children:"Chat"}),(0,l.jsx)(ej.Z,{children:"API Reference"})]}),(0,l.jsxs)(eZ.Z,{children:[(0,l.jsxs)(ew.Z,{children:[(0,l.jsxs)("div",{children:[(0,l.jsx)("label",{children:"Select Model:"}),(0,l.jsx)("select",{value:h||"",onChange:e=>m(e.target.value),children:null==u?void 0:u.map(e=>(0,l.jsx)("option",{value:e.id,children:e.id},e.id))})]}),(0,l.jsxs)($.Z,{className:"mt-5",style:{display:"block",maxHeight:"60vh",overflowY:"auto"},children:[(0,l.jsx)(X.Z,{children:(0,l.jsx)(ee.Z,{children:(0,l.jsx)(Y.Z,{children:(0,l.jsx)(D.Z,{children:"Chat"})})})}),(0,l.jsx)(H.Z,{children:c.map((e,t)=>(0,l.jsx)(ee.Z,{children:(0,l.jsx)(Y.Z,{children:"".concat(e.role,": ").concat(e.content)})},t))})]}),(0,l.jsx)("div",{className:"mt-3",style:{position:"absolute",bottom:5,width:"95%"},children:(0,l.jsxs)("div",{className:"flex",children:[(0,l.jsx)("input",{type:"text",value:o,onChange:e=>i(e.target.value),className:"flex-1 p-2 border rounded-md mr-2",placeholder:"Type your message..."}),(0,l.jsx)("button",{onClick:j,className:"p-2 bg-blue-500 text-white rounded-md",children:"Send"})]})})]}),(0,l.jsx)(ew.Z,{children:(0,l.jsxs)(ey.Z,{children:[(0,l.jsxs)(eg.Z,{children:[(0,l.jsx)(ej.Z,{children:"OpenAI Python SDK"}),(0,l.jsx)(ej.Z,{children:"LlamaIndex"}),(0,l.jsx)(ej.Z,{children:"Langchain Py"})]}),(0,l.jsxs)(eZ.Z,{children:[(0,l.jsx)(ew.Z,{children:(0,l.jsx)(eA.Z,{language:"python",children:'\nimport openai\nclient = openai.OpenAI(\n api_key="your_api_key",\n base_url="http://0.0.0.0:4000" # proxy base url\n)\n\nresponse = client.chat.completions.create(\n model="gpt-3.5-turbo", # model to use from Models Tab\n messages = [\n {\n "role": "user",\n "content": "this is a test request, write a short poem"\n }\n ],\n extra_body={\n "metadata": {\n "generation_name": "ishaan-generation-openai-client",\n "generation_id": "openai-client-gen-id22",\n "trace_id": "openai-client-trace-id22",\n "trace_user_id": "openai-client-user-id2"\n }\n }\n)\n\nprint(response)\n '})}),(0,l.jsx)(ew.Z,{children:(0,l.jsx)(eA.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="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,l.jsx)(ew.Z,{children:(0,l.jsx)(eA.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:8000",\n model = "gpt-3.5-turbo",\n temperature=0.1,\n extra_body={\n "metadata": {\n "generation_name": "ishaan-generation-langchain-client",\n "generation_id": "langchain-client-gen-id22",\n "trace_id": "langchain-client-trace-id22",\n "trace_user_id": "langchain-client-user-id2"\n }\n }\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 '})})]})]})})]})]})})})})},eI=s(33509),eP=s(30569);let{Sider:eE}=eI.default;var eF=e=>{let{setPage:t,userRole:s,defaultSelectedKey:r}=e;return"Admin Viewer"==s?(0,l.jsx)(eI.default,{style:{minHeight:"100vh",maxWidth:"120px"},children:(0,l.jsx)(eE,{width:120,children:(0,l.jsxs)(eP.Z,{mode:"inline",defaultSelectedKeys:r||["4"],style:{height:"100%",borderRight:0},children:[(0,l.jsx)(eP.Z.Item,{onClick:()=>t("api-keys"),children:"API Keys"},"4"),(0,l.jsx)(eP.Z.Item,{onClick:()=>t("models"),children:"Models"},"2"),(0,l.jsx)(eP.Z.Item,{onClick:()=>t("llm-playground"),children:"Chat UI"},"3"),(0,l.jsx)(eP.Z.Item,{onClick:()=>t("usage"),children:"Usage"},"1")]})})}):(0,l.jsx)(eI.default,{style:{minHeight:"100vh",maxWidth:"120px"},children:(0,l.jsx)(eE,{width:120,children:(0,l.jsxs)(eP.Z,{mode:"inline",defaultSelectedKeys:r||["1"],style:{height:"100%",borderRight:0},children:[(0,l.jsx)(eP.Z.Item,{onClick:()=>t("api-keys"),children:"API Keys"},"1"),(0,l.jsx)(eP.Z.Item,{onClick:()=>t("models"),children:"Models"},"2"),(0,l.jsx)(eP.Z.Item,{onClick:()=>t("llm-playground"),children:"Chat UI"},"3"),(0,l.jsx)(eP.Z.Item,{onClick:()=>t("usage"),children:"Usage"},"4"),"Admin"==s?(0,l.jsx)(eP.Z.Item,{onClick:()=>t("users"),children:"Users"},"5"):null,"Admin"==s?(0,l.jsx)(eP.Z.Item,{onClick:()=>t("teams"),children:"Teams"},"6"):null,"Admin"==s?(0,l.jsx)(eP.Z.Item,{onClick:()=>t("admin-panel"),children:"Admin"},"7"):null]})})})},eO=e=>{let{accessToken:t,token:s,userRole:a,userID:n}=e,o=new Date,[i,c]=(0,r.useState)([]),[d,h]=(0,r.useState)([]),[m,u]=(0,r.useState)([]),[x,p]=(0,r.useState)([]),[j,y]=(0,r.useState)([]),[g,_]=(0,r.useState)([]),[S,N]=(0,r.useState)([]),A=new Date(o.getFullYear(),o.getMonth(),1),C=new Date(o.getFullYear(),o.getMonth()+1,0),T=P(A),I=P(C);function P(e){let t=e.getFullYear(),s=e.getMonth()+1,l=e.getDate();return"".concat(t,"-").concat(s<10?"0"+s:s,"-").concat(l<10?"0"+l:l)}return console.log("Start date is ".concat(T)),console.log("End date is ".concat(I)),(0,r.useEffect)(()=>{t&&s&&a&&n&&(async()=>{try{if(console.log("user role: ".concat(a)),"Admin"==a||"Admin Viewer"==a){let e=await f(t);c(e);let s=(await k(t)).map(e=>({key:(e.key_name||e.key_alias||e.api_key).substring(0,7),spend:e.total_spend}));h(s);let l=(await b(t)).map(e=>({key:e.model,spend:e.total_spend}));u(l);let r=await w(t);console.log("teamSpend",r),y(r.daily_spend),_(r.teams),N(r.total_spend_per_team)}else"App Owner"==a&&await Z(t,s,a,n,T,I).then(async e=>{if(console.log("result from spend logs call",e),"daily_spend"in e){let t=e.daily_spend;console.log("daily spend",t),c(t);let s=e.top_api_keys;h(s)}else{let s=(await v(t,function(e){let t=[];e.forEach(e=>{Object.entries(e).forEach(e=>{let[s,l]=e;"spend"!==s&&"startTime"!==s&&"models"!==s&&"users"!==s&&t.push({key:s,spend:l})})}),t.sort((e,t)=>Number(t.spend)-Number(e.spend));let s=t.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||e.token).substring(0,7),spend:e.spend}));h(s),p(function(e){let t={};e.forEach(e=>{Object.entries(e.users).forEach(e=>{let[s,l]=e;""!==s&&null!=s&&"None"!=s&&(t[s]||(t[s]=0),t[s]+=l)})});let s=Object.entries(t).map(e=>{let[t,s]=e;return{user_id:t,spend:s}});s.sort((e,t)=>t.spend-e.spend);let l=s.slice(0,5);return console.log("topKeys: ".concat(Object.values(l[0]))),l}(e)),c(e)}})}catch(e){console.error("There was an error fetching the data",e)}})()},[t,s,a,n,T,I]),(0,l.jsx)("div",{style:{width:"100%"},children:(0,l.jsxs)(ey.Z,{children:[(0,l.jsxs)(eg.Z,{className:"mt-4",children:[(0,l.jsx)(ej.Z,{children:"All Up"}),(0,l.jsx)(ej.Z,{children:"Team Based Usage"})]}),(0,l.jsxs)(eZ.Z,{children:[(0,l.jsx)(ew.Z,{children:(0,l.jsxs)(O.Z,{numItems:2,className:"gap-2 p-10 h-[75vh] w-full",children:[(0,l.jsx)(F.Z,{numColSpan:2,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Monthly Spend"}),(0,l.jsx)(et.Z,{data:i,index:"date",categories:["spend"],colors:["blue"],valueFormatter:e=>"$ ".concat(new Intl.NumberFormat("us").format(e).toString()),yAxisWidth:100,tickGap:5})]})}),(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Top API Keys"}),(0,l.jsx)(et.Z,{className:"mt-4 h-40",data:d,index:"key",categories:["spend"],colors:["blue"],yAxisWidth:80,tickGap:5,layout:"vertical",showXAxis:!1,showLegend:!1})]})}),(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Top Users"}),(0,l.jsx)(et.Z,{className:"mt-4 h-40",data:x,index:"user_id",categories:["spend"],colors:["blue"],yAxisWidth:200,layout:"vertical",showXAxis:!1,showLegend:!1})]})}),(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Top Models"}),(0,l.jsx)(et.Z,{className:"mt-4 h-40",data:m,index:"key",categories:["spend"],colors:["blue"],yAxisWidth:200,layout:"vertical",showXAxis:!1,showLegend:!1})]})})]})}),(0,l.jsx)(ew.Z,{children:(0,l.jsxs)(O.Z,{numItems:2,className:"gap-2 p-10 h-[75vh] w-full",children:[(0,l.jsx)(F.Z,{numColSpan:2,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Daily Spend Per Team"}),(0,l.jsx)(et.Z,{className:"h-72",data:j,index:"date",categories:g,yAxisWidth:30,stack:!0})]})}),(0,l.jsx)(F.Z,{numColSpan:2,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Total Spend Per Team"}),(0,l.jsx)(et.Z,{className:"h-72",data:S,index:"team_id",categories:["total_spend"],yAxisWidth:30})]})})]})})]})]})})},eM=()=>{let{Title:e,Paragraph:t}=en.default,[s,n]=(0,r.useState)(""),[o,c]=(0,r.useState)(null),[d,h]=(0,r.useState)(null),[m,u]=(0,r.useState)(null),[x,p]=(0,r.useState)(!0),j=(0,a.useSearchParams)(),y=j.get("userID"),g=j.get("token"),[w,Z]=(0,r.useState)("api-keys"),[f,k]=(0,r.useState)(null);return(0,r.useEffect)(()=>{if(g){let e=(0,ed.o)(g);if(e){if(console.log("Decoded token:",e),console.log("Decoded key:",e.key),k(e.key),e.user_role){let t=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"app_user":return"App User";default:return"Unknown Role"}}(e.user_role);console.log("Decoded user_role:",t),n(t),"Admin Viewer"==t&&Z("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?p("username_password"==e.login_method):console.log("User Email is not set ".concat(e))}}},[g]),(0,l.jsx)(r.Suspense,{fallback:(0,l.jsx)("div",{children:"Loading..."}),children:(0,l.jsxs)("div",{className:"flex flex-col min-h-screen",children:[(0,l.jsx)(i,{userID:y,userRole:s,userEmail:o,showSSOBanner:x}),(0,l.jsxs)("div",{className:"flex flex-1 overflow-auto",children:[(0,l.jsx)(eF,{setPage:Z,userRole:s,defaultSelectedKey:null}),"api-keys"==w?(0,l.jsx)(eh,{userID:y,userRole:s,teams:d,keys:m,setUserRole:n,userEmail:o,setUserEmail:c,setTeams:h,setKeys:u}):"models"==w?(0,l.jsx)(ep,{userID:y,userRole:s,token:g,accessToken:f}):"llm-playground"==w?(0,l.jsx)(eT,{userID:y,userRole:s,token:g,accessToken:f}):"users"==w?(0,l.jsx)(e_,{userID:y,userRole:s,token:g,keys:m,accessToken:f,setKeys:u}):"teams"==w?(0,l.jsx)(eb,{teams:d,setTeams:h,searchParams:j,accessToken:f,userID:y,userRole:s}):"admin-panel"==w?(0,l.jsx)(eS,{setTeams:h,searchParams:j,accessToken:f}):(0,l.jsx)(eO,{userID:y,userRole:s,token:g,accessToken:f})]})]})})}}},function(e){e.O(0,[730,971,69,744],function(){return e(e.s=20661)}),_N_E=e.O()}]); \ No newline at end of file +(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[931],{20661:function(e,t,s){Promise.resolve().then(s.bind(s,92182))},92182:function(e,t,s){"use strict";s.r(t),s.d(t,{default:function(){return eM}});var l=s(3827),r=s(64090),a=s(47907),n=s(8792),o=s(2179),i=e=>{let{userID:t,userRole:s,userEmail:r,showSSOBanner:a}=e;return console.log("User ID:",t),console.log("userEmail:",r),(0,l.jsxs)("nav",{className:"left-0 right-0 top-0 flex justify-between items-center h-12 mb-4",children:[(0,l.jsx)("div",{className:"text-left my-2 absolute top-0 left-0",children:(0,l.jsx)("div",{className:"flex flex-col items-center",children:(0,l.jsx)(n.default,{href:"/",children:(0,l.jsx)("button",{className:"text-gray-800 text-2xl py-1 rounded text-center",children:(0,l.jsx)("img",{src:"/get_image",width:200,height:200,alt:"LiteLLM Brand",className:"mr-2"})})})})}),(0,l.jsxs)("div",{className:"text-right mx-4 my-2 absolute top-0 right-0 flex items-center justify-end space-x-2",children:[a?(0,l.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/ui#setup-ssoauth-for-ui",target:"_blank",className:"mr-2"}):null,(0,l.jsxs)(o.Z,{variant:"secondary",size:"lg",children:[r,(0,l.jsxs)("p",{children:["Role: ",s]}),(0,l.jsxs)("p",{children:["ID: ",t]})]})]})]})},c=s(80588);let d=async(e,t,s)=>{try{if(console.log("Form Values in keyCreateCall:",s),s.description&&(s.metadata||(s.metadata={}),s.metadata.description=s.description,delete s.description,s.metadata=JSON.stringify(s.metadata)),s.metadata){console.log("formValues.metadata:",s.metadata);try{s.metadata=JSON.parse(s.metadata)}catch(e){throw c.ZP.error("Failed to parse metadata: "+e),Error("Failed to parse metadata: "+e)}}console.log("Form Values after check:",s);let l=await fetch("/key/generate",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({user_id:t,...s})});if(!l.ok){let e=await l.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let r=await l.json();return console.log("API Response:",r),r}catch(e){throw console.error("Failed to create key:",e),e}},h=async(e,t,s)=>{try{if(console.log("Form Values in keyCreateCall:",s),s.description&&(s.metadata||(s.metadata={}),s.metadata.description=s.description,delete s.description,s.metadata=JSON.stringify(s.metadata)),s.metadata){console.log("formValues.metadata:",s.metadata);try{s.metadata=JSON.parse(s.metadata)}catch(e){throw c.ZP.error("Failed to parse metadata: "+e),Error("Failed to parse metadata: "+e)}}console.log("Form Values after check:",s);let l=await fetch("/user/new",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({user_id:t,...s})});if(!l.ok){let e=await l.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let r=await l.json();return console.log("API Response:",r),r}catch(e){throw console.error("Failed to create key:",e),e}},m=async(e,t)=>{try{console.log("in keyDeleteCall:",t);let s=await fetch("/key/delete",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({keys:[t]})});if(!s.ok){let e=await s.text();throw c.ZP.error("Failed to delete key: "+e),Error("Network response was not ok")}let l=await s.json();return console.log(l),l}catch(e){throw console.error("Failed to create key:",e),e}},u=async function(e,t,s){let l=arguments.length>3&&void 0!==arguments[3]&&arguments[3];try{let r="/user/info";"App Owner"==s&&t&&(r="".concat(r,"?user_id=").concat(t)),console.log("in userInfoCall viewAll=",l),l&&(r="".concat(r,"?view_all=true"));let a=await fetch(r,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!a.ok){let e=await a.text();throw c.ZP.error(e),Error("Network response was not ok")}let n=await a.json();return console.log("API Response:",n),n}catch(e){throw console.error("Failed to create key:",e),e}},x=async e=>{try{let t=await fetch("/global/spend",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},p=async(e,t,s)=>{try{let t=await fetch("/v2/model/info",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},j=async(e,t,s)=>{try{let t=await fetch("/model/metrics",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},y=async(e,t,s)=>{try{let t=await fetch("/models",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},g=async(e,t)=>{try{let s="/global/spend/logs";console.log("in keySpendLogsCall:",s);let l=await fetch("".concat(s,"?api_key=").concat(t),{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw c.ZP.error(e),Error("Network response was not ok")}let r=await l.json();return console.log(r),r}catch(e){throw console.error("Failed to create key:",e),e}},w=async e=>{try{let t="/global/spend/teams";console.log("in teamSpendLogsCall:",t);let s=await fetch("".concat(t),{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!s.ok){let e=await s.text();throw c.ZP.error(e),Error("Network response was not ok")}let l=await s.json();return console.log(l),l}catch(e){throw console.error("Failed to create key:",e),e}},Z=async(e,t,s,l,r,a)=>{try{console.log("user role in spend logs call: ".concat(s));let t="/spend/logs";t="App Owner"==s?"".concat(t,"?user_id=").concat(l,"&start_date=").concat(r,"&end_date=").concat(a):"".concat(t,"?start_date=").concat(r,"&end_date=").concat(a);let n=await fetch(t,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!n.ok){let e=await n.text();throw c.ZP.error(e),Error("Network response was not ok")}let o=await n.json();return console.log(o),o}catch(e){throw console.error("Failed to create key:",e),e}},f=async e=>{try{let t=await fetch("/global/spend/logs",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to create key:",e),e}},k=async e=>{try{let t=await fetch("/global/spend/keys?limit=5",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to create key:",e),e}},_=async(e,t)=>{try{t&&JSON.stringify({api_key:t});let s={method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}};t&&(s.body=JSON.stringify({api_key:t}));let l=await fetch("/global/spend/end_users",s);if(!l.ok){let e=await l.text();throw c.ZP.error(e),Error("Network response was not ok")}let r=await l.json();return console.log(r),r}catch(e){throw console.error("Failed to create key:",e),e}},b=async e=>{try{let t=await fetch("/global/spend/models?limit=5",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to create key:",e),e}},v=async(e,t)=>{try{let s=await fetch("/v2/key/info",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({keys:t})});if(!s.ok){let e=await s.text();throw c.ZP.error(e),Error("Network response was not ok")}let l=await s.json();return console.log(l),l}catch(e){throw console.error("Failed to create key:",e),e}},S=async(e,t,s,l)=>{try{let r=await fetch("/user/request_model",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({models:[t],user_id:s,justification:l})});if(!r.ok){let e=await r.text();throw c.ZP.error("Failed to delete key: "+e),Error("Network response was not ok")}let a=await r.json();return console.log(a),a}catch(e){throw console.error("Failed to create key:",e),e}},N=async e=>{try{let t="/user/get_requests";console.log("in userGetRequesedtModelsCall:",t);let s=await fetch(t,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!s.ok){let e=await s.text();throw c.ZP.error("Failed to delete key: "+e),Error("Network response was not ok")}let l=await s.json();return console.log(l),l}catch(e){throw console.error("Failed to get requested models:",e),e}},A=async(e,t)=>{try{let s="/user/get_users?role=".concat(t);console.log("in userGetAllUsersCall:",s);let l=await fetch(s,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw c.ZP.error("Failed to delete key: "+e),Error("Network response was not ok")}let r=await l.json();return console.log(r),r}catch(e){throw console.error("Failed to get requested models:",e),e}},C=async(e,t)=>{try{console.log("Form Values in teamCreateCall:",t);let s=await fetch("/team/new",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...t})});if(!s.ok){let e=await s.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let l=await s.json();return console.log("API Response:",l),l}catch(e){throw console.error("Failed to create key:",e),e}},T=async(e,t,s)=>{try{console.log("Form Values in teamMemberAddCall:",s);let l=await fetch("/team/member_add",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({team_id:t,member:s})});if(!l.ok){let e=await l.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let r=await l.json();return console.log("API Response:",r),r}catch(e){throw console.error("Failed to create key:",e),e}},I=async(e,t)=>{try{console.log("Form Values in userUpdateUserCall:",t);let s=await fetch("/user/update",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({user_role:"proxy_admin_viewer",...t})});if(!s.ok){let e=await s.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let l=await s.json();return console.log("API Response:",l),l}catch(e){throw console.error("Failed to create key:",e),e}},P=async(e,t)=>{try{let s=await fetch("/global/predict/spend/logs",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({data:t})});if(!s.ok){let e=await s.text();throw c.ZP.error(e),Error("Network response was not ok")}let l=await s.json();return console.log(l),l}catch(e){throw console.error("Failed to create key:",e),e}},E=async e=>{try{console.log("Checking Slack Budget Alerts service health");let t=await fetch("/health/services?service=slack_budget_alerts",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error("Failed Slack Alert test: "+e),Error(e)}let s=await t.json();return c.ZP.success("Test Slack Alert worked - check your Slack!"),console.log("Service Health Response:",s),s}catch(e){throw console.error("Failed to perform health check:",e),e}};var F=s(10384),O=s(46453),M=s(13810),R=s(71801),D=s(42440),U=s(17189),L=s(12143),B=s(77171),z=s(42539),K=s(88707),W=s(1861);let{Option:V}=U.default;var q=e=>{let{userID:t,teamID:s,userRole:a,accessToken:n,data:i,userModels:h,setData:m}=e,[u]=L.Z.useForm(),[x,p]=(0,r.useState)(!1),[j,y]=(0,r.useState)(null),[g,w]=(0,r.useState)(null),Z=()=>{p(!1),u.resetFields()},f=()=>{p(!1),y(null),u.resetFields()},k=async e=>{try{c.ZP.info("Making API Call"),p(!0);let s=await d(n,t,e);console.log("key create Response:",s),m(e=>e?[...e,s]:[s]),y(s.key),w(s.soft_budget),c.ZP.success("API Key Created"),u.resetFields(),localStorage.removeItem("userData"+t)}catch(e){console.error("Error creating the key:",e)}},_=async()=>{try{console.log("Sending Slack alert...");let e=await E(n);console.log("slackBudgetAlertsHealthCheck Response:",e),console.log("Testing Slack alert successful")}catch(e){console.error("Error sending Slack alert:",e)}};return(0,l.jsxs)("div",{children:[(0,l.jsx)(o.Z,{className:"mx-auto",onClick:()=>p(!0),children:"+ Create New Key"}),(0,l.jsx)(B.Z,{title:"Create Key",visible:x,width:800,footer:null,onOk:Z,onCancel:f,children:(0,l.jsxs)(L.Z,{form:u,onFinish:k,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:["App Owner"===a||"Admin"===a?(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(L.Z.Item,{label:"Key Name",name:"key_alias",children:(0,l.jsx)(z.Z,{})}),(0,l.jsx)(L.Z.Item,{label:"Team ID",name:"team_id",children:(0,l.jsx)(z.Z,{placeholder:"ai_team",defaultValue:s||""})}),(0,l.jsx)(L.Z.Item,{label:"Models",name:"models",children:(0,l.jsx)(U.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:h.map(e=>(0,l.jsx)(V,{value:e,children:e},e))})}),(0,l.jsx)(L.Z.Item,{label:"Soft Budget (USD) Monthly",name:"soft_budget",initialValue:50,children:(0,l.jsx)(K.Z,{step:.01,precision:2,defaultValue:50,width:200})}),(0,l.jsx)(L.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,l.jsx)(K.Z,{step:.01,precision:2,width:200})}),(0,l.jsx)(L.Z.Item,{label:"Reset Budget",name:"budget_duration",children:(0,l.jsxs)(U.default,{defaultValue:null,placeholder:"n/a",children:[(0,l.jsx)(U.default.Option,{value:"24h",children:"daily"}),(0,l.jsx)(U.default.Option,{value:"30d",children:"monthly"})]})}),(0,l.jsx)(L.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})}),(0,l.jsx)(L.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})}),(0,l.jsx)(L.Z.Item,{label:"Expire Key (eg: 30s, 30h, 30d)",name:"duration",children:(0,l.jsx)(z.Z,{})}),(0,l.jsx)(L.Z.Item,{label:"Metadata",name:"metadata",children:(0,l.jsx)(z.Z.TextArea,{rows:4,placeholder:"Enter metadata as JSON"})})]}):(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(L.Z.Item,{label:"Key Name",name:"key_alias",children:(0,l.jsx)(z.Z,{})}),(0,l.jsx)(L.Z.Item,{label:"Team ID (Contact Group)",name:"team_id",children:(0,l.jsx)(z.Z,{placeholder:"ai_team"})}),(0,l.jsx)(L.Z.Item,{label:"Description",name:"description",children:(0,l.jsx)(z.Z.TextArea,{placeholder:"Enter description",rows:4})})]}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(W.ZP,{htmlType:"submit",children:"Create Key"})})]})}),j&&(0,l.jsx)(B.Z,{visible:x,onOk:Z,onCancel:f,footer:null,children:(0,l.jsx)(O.Z,{numItems:1,className:"gap-2 w-full",children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Save your Key"}),(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsxs)("p",{children:["Please save this secret key somewhere safe and accessible. For security reasons, ",(0,l.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,l.jsx)(F.Z,{numColSpan:1,children:null!=j?(0,l.jsxs)("div",{children:[(0,l.jsxs)(R.Z,{children:["API Key: ",j]}),(0,l.jsx)(D.Z,{className:"mt-6",children:"Budgets"}),(0,l.jsxs)(R.Z,{children:["Soft Limit Budget: $",g]}),(0,l.jsx)(o.Z,{className:"mt-3",onClick:_,children:"Test Slack Alert"}),(0,l.jsxs)(R.Z,{className:"mt-2",children:["(LiteLLM Docs -",(0,l.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/alerting",target:"_blank",className:"text-blue-500",children:"Set Up Slack Alerting)"})]})]}):(0,l.jsx)(R.Z,{children:"Key being created, this might take 30s"})})]})})})]})},J=s(33393),G=s(61244),$=s(10827),H=s(3851),Y=s(2044),X=s(64167),Q=s(74480),ee=s(7178),et=s(9853),es=s(56863),el=e=>{let{token:t,accessToken:s,keySpend:a,keyBudget:n,keyName:i}=e,[c,d]=(0,r.useState)(!1),[h,m]=(0,r.useState)(null),[u,x]=(0,r.useState)(""),[p,j]=(0,r.useState)(null),y=async()=>{try{if(null==s||null==t)return;console.log("accessToken: ".concat(s,"; token: ").concat(t));let e=await g(s,t);console.log("Response:",e),m(e);let l=await P(s,e);console.log("Response2:",l);let r=[...e,...l.response];m(r),x(l.predicted_spend),console.log("Combined Data:",r)}catch(e){console.error("There was an error fetching the data",e)}};return t?(0,l.jsxs)("div",{children:[(0,l.jsx)(o.Z,{size:"xs",onClick:()=>{console.log("Show Modal triggered"),d(!0),y()},variant:"secondary",children:"Spend Report"}),(0,l.jsxs)(B.Z,{visible:c,width:1400,onOk:()=>{d(!1)},onCancel:()=>{d(!1)},footer:null,children:[(0,l.jsxs)(D.Z,{style:{textAlign:"left"},children:["Key Name: ",i]}),(0,l.jsxs)(es.Z,{children:["Monthly Spend $",a]}),(0,l.jsx)(D.Z,{children:u}),(0,l.jsx)(M.Z,{className:"mt-6 mb-6",children:h&&(0,l.jsx)(et.Z,{className:"mt-6",data:h,colors:["blue","amber"],index:"date",categories:["spend","predicted_spend"],yAxisWidth:80})})]})]}):null},er=e=>{let{userID:t,accessToken:s,data:a,setData:n}=e,[i,c]=(0,r.useState)(!1),[d,h]=(0,r.useState)(!1),[u,x]=(0,r.useState)(null),p=async e=>{null!=a&&(x(e),localStorage.removeItem("userData"+t),h(!0))},j=async()=>{if(null!=u&&null!=a){try{await m(s,u);let e=a.filter(e=>e.token!==u);n(e)}catch(e){console.error("Error deleting the key:",e)}h(!1),x(null)}};if(null!=a)return console.log("RERENDER TRIGGERED"),(0,l.jsxs)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh] mb-4",children:[(0,l.jsxs)($.Z,{className:"mt-5",children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"Key Alias"}),(0,l.jsx)(Q.Z,{children:"Secret Key"}),(0,l.jsx)(Q.Z,{children:"Spend (USD)"}),(0,l.jsx)(Q.Z,{children:"Key Budget (USD)"}),(0,l.jsx)(Q.Z,{children:"Spend Report"}),(0,l.jsx)(Q.Z,{children:"Team ID"}),(0,l.jsx)(Q.Z,{children:"Metadata"}),(0,l.jsx)(Q.Z,{children:"Models"}),(0,l.jsx)(Q.Z,{children:"TPM / RPM Limits"}),(0,l.jsx)(Q.Z,{children:"Expires"})]})}),(0,l.jsx)(H.Z,{children:a.map(e=>(console.log(e),"litellm-dashboard"===e.team_id)?null:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",whiteSpace:"pre-wrap",overflow:"hidden"},children:null!=e.key_alias?(0,l.jsx)(R.Z,{children:e.key_alias}):(0,l.jsx)(R.Z,{children:"Not Set"})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:e.key_name})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:(()=>{try{return parseFloat(e.spend).toFixed(4)}catch(t){return e.spend}})()})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",whiteSpace:"pre-wrap",overflow:"hidden"},children:null!=e.max_budget?(0,l.jsx)(R.Z,{children:e.max_budget}):(0,l.jsx)(R.Z,{children:"Unlimited Budget"})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px"},children:(0,l.jsx)(el,{token:e.token,accessToken:s,keySpend:e.spend,keyBudget:e.max_budget,keyName:e.key_name})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:e.team_id})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:JSON.stringify(e.metadata).slice(0,400)})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:JSON.stringify(e.models)})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",overflowWrap:"break-word"},children:(0,l.jsxs)(R.Z,{children:["TPM Limit: ",e.tpm_limit?e.tpm_limit:"Unlimited"," ",(0,l.jsx)("br",{})," RPM Limit:"," ",e.rpm_limit?e.rpm_limit:"Unlimited"]})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",wordWrap:"break-word"},children:null!=e.expires?(0,l.jsx)(R.Z,{children:e.expires}):(0,l.jsx)(R.Z,{children:"Never"})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",wordWrap:"break-word"},children:(0,l.jsx)(G.Z,{onClick:()=>p(e.token),icon:J.Z,size:"sm"})})]},e.token))})]}),d&&(0,l.jsx)("div",{className:"fixed z-10 inset-0 overflow-y-auto",children:(0,l.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,l.jsx)("div",{className:"fixed inset-0 transition-opacity","aria-hidden":"true",children:(0,l.jsx)("div",{className:"absolute inset-0 bg-gray-500 opacity-75"})}),(0,l.jsx)("span",{className:"hidden sm:inline-block sm:align-middle sm:h-screen","aria-hidden":"true",children:"​"}),(0,l.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,l.jsx)("div",{className:"bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4",children:(0,l.jsx)("div",{className:"sm:flex sm:items-start",children:(0,l.jsxs)("div",{className:"mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left",children:[(0,l.jsx)("h3",{className:"text-lg leading-6 font-medium text-gray-900",children:"Delete Key"}),(0,l.jsx)("div",{className:"mt-2",children:(0,l.jsx)("p",{className:"text-sm text-gray-500",children:"Are you sure you want to delete this key ?"})})]})})}),(0,l.jsxs)("div",{className:"bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse",children:[(0,l.jsx)(o.Z,{onClick:j,color:"red",className:"ml-2",children:"Delete"}),(0,l.jsx)(o.Z,{onClick:()=>{h(!1),x(null)},children:"Cancel"})]})]})]})})]})},ea=e=>{let{userID:t,userSpendData:s,userRole:a,accessToken:n}=e,[o,i]=(0,r.useState)(null==s?void 0:s.spend),[c,d]=(0,r.useState)((null==s?void 0:s.max_budget)||null);(0,r.useEffect)(()=>{(async()=>{if("Admin"===a)try{let e=await x(n);i(e.spend),d(e.max_budget||null)}catch(e){console.error("Error fetching global spend data:",e)}})()},[a,n]);let h=void 0!==o?o.toFixed(4):null;return(0,l.jsx)(l.Fragment,{children:(0,l.jsxs)(M.Z,{className:"mx-auto mb-4",children:[(0,l.jsxs)(es.Z,{children:["$",h]}),(0,l.jsxs)(D.Z,{children:["/ ",null!==c?"$".concat(c," limit"):"No limit"]})]})})},en=s(36083),eo=s(68967),ei=s(27166),ec=e=>{let{teams:t,setSelectedTeam:s}=e,{Title:a,Paragraph:n}=en.default,[o,i]=(0,r.useState)("");return(0,l.jsxs)("div",{className:"mt-10",children:[(0,l.jsx)(a,{level:4,children:"Default Team"}),(0,l.jsx)(n,{children:"If you belong to multiple teams, this setting controls which team is used by default when creating new API Keys."}),t&&t.length>0?(0,l.jsx)(eo.Z,{defaultValue:"0",children:t.map((e,t)=>(0,l.jsx)(ei.Z,{value:String(t),onClick:()=>s(e),children:e.team_alias},t))}):(0,l.jsxs)(n,{children:["No team created. ",(0,l.jsx)("b",{children:"Defaulting to personal account."})]})]})},ed=s(37963);console.log("isLocal:",!1);var eh=e=>{let{userID:t,userRole:s,teams:n,keys:o,setUserRole:i,userEmail:c,setUserEmail:d,setTeams:h,setKeys:m}=e,[p,j]=(0,r.useState)(null),g=(0,a.useSearchParams)();g.get("viewSpend"),(0,a.useRouter)();let w=g.get("token"),[Z,f]=(0,r.useState)(null),[k,_]=(0,r.useState)([]),[b,v]=(0,r.useState)(n?n[0]:null);if(window.addEventListener("beforeunload",function(){sessionStorage.clear()}),(0,r.useEffect)(()=>{if(w){let e=(0,ed.o)(w);if(e){if(console.log("Decoded token:",e),console.log("Decoded key:",e.key),f(e.key),e.user_role){let t=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";default:return"Unknown Role"}}(e.user_role);console.log("Decoded user_role:",t),i(t)}else console.log("User role not defined");e.user_email?d(e.user_email):console.log("User Email is not set ".concat(e))}}if(t&&Z&&s&&!o&&!p){let e=sessionStorage.getItem("userModels"+t);e?_(JSON.parse(e)):(async()=>{try{let e=await u(Z,t,s);if(console.log("received teams in user dashboard: ".concat(Object.keys(e),"; team values: ").concat(Object.entries(e.teams))),"Admin"==s){let e=await x(Z);j(e),console.log("globalSpend:",e)}else j(e.user_info);m(e.keys),h(e.teams),v(e.teams?e.teams[0]:null),sessionStorage.setItem("userData"+t,JSON.stringify(e.keys)),sessionStorage.setItem("userSpendData"+t,JSON.stringify(e.user_info));let l=(await y(Z,t,s)).data.map(e=>e.id);console.log("available_model_names:",l),_(l),console.log("userModels:",k),sessionStorage.setItem("userModels"+t,JSON.stringify(l))}catch(e){console.error("There was an error fetching the data",e)}})()}},[t,w,Z,o,s]),null==t||null==w){let e="/sso/key/generate";return console.log("Full URL:",e),window.location.href=e,null}if(null==Z)return null;if(null==s&&i("App Owner"),s&&"Admin Viewer"==s){let{Title:e,Paragraph:t}=en.default;return(0,l.jsxs)("div",{children:[(0,l.jsx)(e,{level:1,children:"Access Denied"}),(0,l.jsx)(t,{children:"Ask your proxy admin for access to create keys"})]})}return(0,l.jsx)("div",{children:(0,l.jsx)(O.Z,{numItems:1,className:"gap-0 p-10 h-[75vh] w-full",children:(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(ea,{userID:t,userSpendData:p,userRole:s,accessToken:Z}),(0,l.jsx)(er,{userID:t,accessToken:Z,data:o,setData:m}),(0,l.jsx)(q,{userID:t,teamID:b?b.team_id:null,userRole:s,userModels:k,accessToken:Z,data:o,setData:m}),(0,l.jsx)(ec,{teams:n,setSelectedTeam:v})]})})})},em=s(5);let{Option:eu}=U.default;var ex=e=>{let{userModels:t,accessToken:s,userID:a}=e,[n]=L.Z.useForm(),[i,d]=(0,r.useState)(!1),h=async e=>{try{c.ZP.info("Requesting access");let{selectedModel:t,accessReason:l}=e;await S(s,t,a,l),d(!0)}catch(e){console.error("Error requesting access:",e)}};return(0,l.jsxs)("div",{children:[(0,l.jsx)(o.Z,{size:"xs",onClick:()=>d(!0),children:"Request Access"}),(0,l.jsx)(B.Z,{title:"Request Access",visible:i,width:800,footer:null,onOk:()=>{d(!1),n.resetFields()},onCancel:()=>{d(!1),n.resetFields()},children:(0,l.jsxs)(L.Z,{form:n,onFinish:h,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsx)(L.Z.Item,{label:"Select Model",name:"selectedModel",children:(0,l.jsx)(U.default,{placeholder:"Select model",style:{width:"100%"},children:t.map(e=>(0,l.jsx)(eu,{value:e,children:e},e))})}),(0,l.jsx)(L.Z.Item,{label:"Reason for Access",name:"accessReason",children:(0,l.jsx)(z.Z.TextArea,{rows:4,placeholder:"Enter reason for access"})}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(o.Z,{children:"Request Access"})})]})})]})},ep=e=>{let{accessToken:t,token:s,userRole:a,userID:n}=e,[o,i]=(0,r.useState)({data:[]}),[c,d]=(0,r.useState)([]),[h,m]=(0,r.useState)([]);if((0,r.useEffect)(()=>{if(!t||!s||!a||!n)return;let e=async()=>{try{let e=await p(t,n,a);console.log("Model data response:",e.data),i(e);let s=await j(t,n,a);if(console.log("Model metrics response:",s),d(s),"Admin"===a&&t){let e=await N(t);console.log("Pending Requests:",h),m(e.requests||[])}}catch(e){console.error("There was an error fetching the model data",e)}};t&&s&&a&&n&&e()},[t,s,a,n]),!o||!t||!s||!a||!n)return(0,l.jsx)("div",{children:"Loading..."});let u=[];for(let e=0;e(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{children:(0,l.jsx)(D.Z,{children:e.model_name})}),(0,l.jsx)(Y.Z,{children:e.provider}),"Admin"===a&&(0,l.jsx)(Y.Z,{children:e.api_base}),(0,l.jsx)(Y.Z,{children:e.user_access?(0,l.jsx)(em.Z,{color:"green",children:"Yes"}):(0,l.jsx)(ex,{userModels:u,accessToken:t,userID:n})}),(0,l.jsx)(Y.Z,{children:e.input_cost}),(0,l.jsx)(Y.Z,{children:e.output_cost}),(0,l.jsx)(Y.Z,{children:e.max_tokens})]},e.model_name))})]})}),(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Model Statistics (Number Requests)"}),(0,l.jsx)(et.Z,{data:c,index:"model",categories:["num_requests"],colors:["blue"],yAxisWidth:400,layout:"vertical",tickGap:5})]}),(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Model Statistics (Latency)"}),(0,l.jsx)(et.Z,{data:c,index:"model",categories:["avg_latency_seconds"],colors:["red"],yAxisWidth:400,layout:"vertical",tickGap:5})]})]})})},ej=s(92836),ey=s(26734),eg=s(41608),ew=s(32126),eZ=s(23682);let{Option:ef}=U.default;var ek=e=>{let{userID:t,accessToken:s}=e,[a]=L.Z.useForm(),[n,i]=(0,r.useState)(!1),[d,m]=(0,r.useState)(null),[u,x]=(0,r.useState)([]);(0,r.useEffect)(()=>{(async()=>{try{let e=await y(s,t,"any"),l=[];for(let t=0;t{i(!1),a.resetFields()},j=()=>{i(!1),m(null),a.resetFields()},g=async e=>{try{c.ZP.info("Making API Call"),i(!0),console.log("formValues in create user:",e);let l=await h(s,t,e);console.log("user create Response:",l),m(l.key),c.ZP.success("API user Created"),a.resetFields(),localStorage.removeItem("userData"+t)}catch(e){console.error("Error creating the user:",e)}};return(0,l.jsxs)("div",{children:[(0,l.jsx)(o.Z,{className:"mx-auto",onClick:()=>i(!0),children:"+ Create New User"}),(0,l.jsx)(B.Z,{title:"Create User",visible:n,width:800,footer:null,onOk:p,onCancel:j,children:(0,l.jsxs)(L.Z,{form:a,onFinish:g,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsx)(L.Z.Item,{label:"User ID",name:"user_id",children:(0,l.jsx)(z.Z,{placeholder:"Enter User ID"})}),(0,l.jsx)(L.Z.Item,{label:"Team ID",name:"team_id",children:(0,l.jsx)(z.Z,{placeholder:"ai_team"})}),(0,l.jsx)(L.Z.Item,{label:"Models",name:"models",children:(0,l.jsx)(U.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:u.map(e=>(0,l.jsx)(ef,{value:e,children:e},e))})}),(0,l.jsx)(L.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,l.jsx)(K.Z,{step:.01,precision:2,width:200})}),(0,l.jsx)(L.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})}),(0,l.jsx)(L.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})}),(0,l.jsx)(L.Z.Item,{label:"Duration (eg: 30s, 30h, 30d)",name:"duration",children:(0,l.jsx)(z.Z,{})}),(0,l.jsx)(L.Z.Item,{label:"Metadata",name:"metadata",children:(0,l.jsx)(z.Z.TextArea,{rows:4,placeholder:"Enter metadata as JSON"})}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(W.ZP,{htmlType:"submit",children:"Create User"})})]})}),d&&(0,l.jsxs)(B.Z,{title:"Save Your User",visible:n,onOk:p,onCancel:j,footer:null,children:[(0,l.jsxs)("p",{children:["Please save this secret user somewhere safe and accessible. For security reasons, ",(0,l.jsx)("b",{children:"you will not be able to view it again"})," ","through your LiteLLM account. If you lose this secret user, you will need to generate a new one."]}),(0,l.jsx)("p",{children:null!=d?"API user: ".concat(d):"User being created, this might take 30s"})]})]})},e_=e=>{let{accessToken:t,token:s,keys:a,userRole:n,userID:o,setKeys:i}=e,[c,d]=(0,r.useState)(null),[h,m]=(0,r.useState)(null),[x,p]=(0,r.useState)(1);if((0,r.useEffect)(()=>{if(!t||!s||!n||!o)return;let e=async()=>{try{let e=await u(t,null,n,!0);console.log("user data response:",e),d(e)}catch(e){console.error("There was an error fetching the model data",e)}};t&&s&&n&&o&&!c&&e();let l=async()=>{try{let e=await _(t,null);console.log("user data response:",e),m(e)}catch(e){console.error("There was an error fetching the model data",e)}};n&&("Admin"==n||"Admin Viewer"==n)&&!h&&l()},[t,s,n,o]),!c||!t||!s||!n||!o)return(0,l.jsx)("div",{children:"Loading..."});let j=async e=>{try{let s=await _(t,e);console.log("user data response:",s),m(s)}catch(e){console.error("There was an error fetching the model data",e)}};return(0,l.jsx)("div",{style:{width:"100%"},children:(0,l.jsxs)(O.Z,{className:"gap-2 p-10 h-[75vh] w-full",children:[(0,l.jsx)(ek,{userID:o,accessToken:t}),(0,l.jsx)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh] mb-4",children:(0,l.jsxs)(ey.Z,{children:[(0,l.jsxs)(eg.Z,{variant:"line",defaultValue:"1",children:[(0,l.jsx)(ej.Z,{value:"1",children:"Key Owners"}),(0,l.jsx)(ej.Z,{value:"2",children:"End-Users"})]}),(0,l.jsxs)(eZ.Z,{children:[(0,l.jsx)(ew.Z,{children:(0,l.jsxs)($.Z,{className:"mt-5",children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"User ID"}),(0,l.jsx)(Q.Z,{children:"User Role"}),(0,l.jsx)(Q.Z,{children:"User Models"}),(0,l.jsx)(Q.Z,{children:"User Spend ($ USD)"}),(0,l.jsx)(Q.Z,{children:"User Max Budget ($ USD)"})]})}),(0,l.jsx)(H.Z,{children:c.map(e=>(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{children:e.user_id}),(0,l.jsx)(Y.Z,{children:e.user_role?e.user_role:"app_owner"}),(0,l.jsx)(Y.Z,{children:e.models&&e.models.length>0?e.models:"All Models"}),(0,l.jsx)(Y.Z,{children:e.spend?e.spend:0}),(0,l.jsx)(Y.Z,{children:e.max_budget?e.max_budget:"Unlimited"})]},e.user_id))})]})}),(0,l.jsxs)(ew.Z,{children:[(0,l.jsxs)("div",{className:"flex items-center",children:[(0,l.jsx)("div",{className:"flex-1"}),(0,l.jsxs)("div",{className:"flex-1 flex justify-between items-center",children:[(0,l.jsx)(R.Z,{className:"w-1/4 mr-2 text-right",children:"Key"}),(0,l.jsx)(eo.Z,{defaultValue:"1",className:"w-3/4",children:null==a?void 0:a.map((e,t)=>{if(e&&null!==e.key_name&&e.key_name.length>0)return(0,l.jsx)(ei.Z,{value:String(t),onClick:()=>j(e.token),children:e.key_name},t)})})]})]}),(0,l.jsxs)($.Z,{children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"End User"}),(0,l.jsx)(Q.Z,{children:"Spend"}),(0,l.jsx)(Q.Z,{children:"Total Events"})]})}),(0,l.jsx)(H.Z,{children:null==h?void 0:h.map((e,t)=>(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{children:e.end_user}),(0,l.jsx)(Y.Z,{children:e.total_spend}),(0,l.jsx)(Y.Z,{children:e.total_events})]},t))})]})]})]})]})}),function(){if(!c)return null;let e=Math.ceil(c.length/25),t=Math.min(25*x,c.length);return(0,l.jsxs)("div",{className:"flex justify-between items-center",children:[(0,l.jsxs)("div",{children:["Showing ",(x-1)*25+1," – ",t," of ",c.length]}),(0,l.jsxs)("div",{className:"flex",children:[(0,l.jsx)("button",{className:"bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-l focus:outline-none",disabled:1===x,onClick:()=>p(x-1),children:"← Prev"}),(0,l.jsx)("button",{className:"bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-r focus:outline-none",disabled:x===e,onClick:()=>p(x+1),children:"Next →"})]})]})}()]})})},eb=e=>{let{teams:t,searchParams:s,accessToken:a,setTeams:n,userID:i,userRole:d}=e,[h]=L.Z.useForm(),[m]=L.Z.useForm(),{Title:u,Paragraph:x}=en.default,[p,j]=(0,r.useState)(""),[g,w]=(0,r.useState)(t?t[0]:null),[Z,f]=(0,r.useState)(!1),[k,_]=(0,r.useState)(!1),[b,v]=(0,r.useState)([]);(0,r.useEffect)(()=>{(async()=>{try{if(null===i||null===d)return;if(null!==a){let e=(await y(a,i,d)).data.map(e=>e.id);console.log("available_model_names:",e),v(e)}}catch(e){console.error("Error fetching user models:",e)}})()},[a,i,d]);let S=async e=>{try{if(null!=a){c.ZP.info("Creating Team");let s=await C(a,e);null!==t?n([...t,s]):n([s]),console.log("response for team create call: ".concat(s)),c.ZP.success("Team created"),f(!1)}}catch(e){console.error("Error creating the key:",e),c.ZP.error("Error creating the team: "+e)}},N=async e=>{try{if(null!=a&&null!=t){c.ZP.info("Making API Call");let s={role:"user",user_email:e.user_email,user_id:e.user_id},l=await T(a,g.team_id,s);console.log("response for team create call: ".concat(l.data));let r=t.findIndex(e=>(console.log("team.team_id=".concat(e.team_id,"; response.data.team_id=").concat(l.data.team_id)),e.team_id===l.data.team_id));if(console.log("foundIndex: ".concat(r)),-1!==r){let e=[...t];e[r]=l.data,n(e),w(l.data)}_(!1)}}catch(e){console.error("Error creating the key:",e)}};return console.log("received teams ".concat(t)),(0,l.jsx)("div",{className:"w-full mx-4",children:(0,l.jsxs)(O.Z,{numItems:1,className:"gap-2 p-2 h-[75vh] w-full",children:[(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(u,{level:4,children:"All Teams"}),(0,l.jsx)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,l.jsxs)($.Z,{children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"Team Name"}),(0,l.jsx)(Q.Z,{children:"Spend (USD)"}),(0,l.jsx)(Q.Z,{children:"Budget (USD)"}),(0,l.jsx)(Q.Z,{children:"Models"}),(0,l.jsx)(Q.Z,{children:"TPM / RPM Limits"})]})}),(0,l.jsx)(H.Z,{children:t&&t.length>0?t.map(e=>(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:e.team_alias}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:e.spend}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:e.max_budget?e.max_budget:"No limit"}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:JSON.stringify(e.models?e.models:[])})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsxs)(R.Z,{children:["TPM Limit:"," ",e.tpm_limit?e.tpm_limit:"Unlimited"," ",(0,l.jsx)("br",{}),"RPM Limit:"," ",e.rpm_limit?e.rpm_limit:"Unlimited"]})})]},e.team_id)):null})]})})]}),(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(o.Z,{className:"mx-auto",onClick:()=>f(!0),children:"+ Create New Team"}),(0,l.jsx)(B.Z,{title:"Create Team",visible:Z,width:800,footer:null,onOk:()=>{f(!1),h.resetFields()},onCancel:()=>{f(!1),h.resetFields()},children:(0,l.jsxs)(L.Z,{form:h,onFinish:S,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(L.Z.Item,{label:"Team Name",name:"team_alias",children:(0,l.jsx)(z.Z,{})}),(0,l.jsx)(L.Z.Item,{label:"Models",name:"models",children:(0,l.jsx)(U.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:b.map(e=>(0,l.jsx)(U.default.Option,{value:e,children:e},e))})}),(0,l.jsx)(L.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,l.jsx)(K.Z,{step:.01,precision:2,width:200})}),(0,l.jsx)(L.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})}),(0,l.jsx)(L.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})})]}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(W.ZP,{htmlType:"submit",children:"Create Team"})})]})})]}),(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(u,{level:4,children:"Team Members"}),(0,l.jsx)(x,{children:"If you belong to multiple teams, this setting controls which teams members you see."}),t&&t.length>0?(0,l.jsx)(eo.Z,{defaultValue:"0",children:t.map((e,t)=>(0,l.jsx)(ei.Z,{value:String(t),onClick:()=>{w(e)},children:e.team_alias},t))}):(0,l.jsxs)(x,{children:["No team created. ",(0,l.jsx)("b",{children:"Defaulting to personal account."})]})]}),(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsx)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,l.jsxs)($.Z,{children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"Member Name"}),(0,l.jsx)(Q.Z,{children:"Role"})]})}),(0,l.jsx)(H.Z,{children:g?g.members_with_roles.map((e,t)=>(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{children:e.user_email?e.user_email:e.user_id?e.user_id:null}),(0,l.jsx)(Y.Z,{children:e.role})]},t)):null})]})})}),(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(o.Z,{className:"mx-auto mb-5",onClick:()=>_(!0),children:"+ Add member"}),(0,l.jsx)(B.Z,{title:"Add member",visible:k,width:800,footer:null,onOk:()=>{_(!1),m.resetFields()},onCancel:()=>{_(!1),m.resetFields()},children:(0,l.jsxs)(L.Z,{form:h,onFinish:N,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(L.Z.Item,{label:"Email",name:"user_email",className:"mb-4",children:(0,l.jsx)(z.Z,{name:"user_email",className:"px-3 py-2 border rounded-md w-full"})}),(0,l.jsx)("div",{className:"text-center mb-4",children:"OR"}),(0,l.jsx)(L.Z.Item,{label:"User ID",name:"user_id",className:"mb-4",children:(0,l.jsx)(z.Z,{name:"user_id",className:"px-3 py-2 border rounded-md w-full"})})]}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(W.ZP,{htmlType:"submit",children:"Add member"})})]})})]})]})})},ev=s(8510),eS=e=>{let{searchParams:t,accessToken:s}=e,[a]=L.Z.useForm(),[n]=L.Z.useForm(),{Title:i,Paragraph:d}=en.default,[h,m]=(0,r.useState)(""),[u,x]=(0,r.useState)(null),[p,j]=(0,r.useState)(!1);(0,r.useEffect)(()=>{(async()=>{if(null!=s){let e=[],t=await A(s,"proxy_admin_viewer");t.forEach(t=>{e.push({user_role:t.user_role,user_id:t.user_id,user_email:t.user_email})}),console.log("proxy viewers: ".concat(t));let l=await A(s,"proxy_admin");l.forEach(t=>{e.push({user_role:t.user_role,user_id:t.user_id,user_email:t.user_email})}),console.log("proxy admins: ".concat(l)),console.log("combinedList: ".concat(e)),x(e)}})()},[s]);let y=async e=>{try{if(null!=s&&null!=u){c.ZP.info("Making API Call"),e.user_email,e.user_id;let t=await I(s,e);console.log("response for team create call: ".concat(t));let l=u.findIndex(e=>(console.log("user.user_id=".concat(e.user_id,"; response.user_id=").concat(t.user_id)),e.user_id===t.user_id));console.log("foundIndex: ".concat(l)),-1==l&&(console.log("updates admin with new user"),u.push(t),x(u)),j(!1)}}catch(e){console.error("Error creating the key:",e)}};return console.log("admins: ".concat(null==u?void 0:u.length)),(0,l.jsxs)("div",{className:"w-full m-2",children:[(0,l.jsx)(i,{level:4,children:"Restricted Access"}),(0,l.jsxs)(d,{children:["Add other people to just view spend. They cannot create keys, teams or grant users access to new models."," ",(0,l.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/ui#restrict-ui-access",children:"Requires SSO Setup"})]}),(0,l.jsxs)(O.Z,{numItems:1,className:"gap-2 p-0 w-full",children:[(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsx)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,l.jsxs)($.Z,{children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"Member Name"}),(0,l.jsx)(Q.Z,{children:"Role"}),(0,l.jsx)(Q.Z,{children:"Action"})]})}),(0,l.jsx)(H.Z,{children:u?u.map((e,t)=>(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{children:e.user_email?e.user_email:e.user_id?e.user_id:null}),(0,l.jsx)(Y.Z,{children:e.user_role}),(0,l.jsx)(Y.Z,{children:(0,l.jsx)(G.Z,{icon:ev.Z,size:"sm"})})]},t)):null})]})})}),(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(o.Z,{className:"mx-auto mb-5",onClick:()=>j(!0),children:"+ Add viewer"}),(0,l.jsx)(B.Z,{title:"Add viewer",visible:p,width:800,footer:null,onOk:()=>{j(!1),n.resetFields()},onCancel:()=>{j(!1),n.resetFields()},children:(0,l.jsxs)(L.Z,{form:a,onFinish:y,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(L.Z.Item,{label:"Email",name:"user_email",className:"mb-4",children:(0,l.jsx)(z.Z,{name:"user_email",className:"px-3 py-2 border rounded-md w-full"})}),(0,l.jsx)("div",{className:"text-center mb-4",children:"OR"}),(0,l.jsx)(L.Z.Item,{label:"User ID",name:"user_id",className:"mb-4",children:(0,l.jsx)(z.Z,{name:"user_id",className:"px-3 py-2 border rounded-md w-full"})})]}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(W.ZP,{htmlType:"submit",children:"Add member"})})]})})]})]})]})},eN=s(12968),eA=s(67951);async function eC(e,t,s,l){console.log("isLocal:",!1);let r=window.location.origin,a=new eN.ZP.OpenAI({apiKey:l,baseURL:r,dangerouslyAllowBrowser:!0});for await(let l of(await a.chat.completions.create({model:s,stream:!0,messages:[{role:"user",content:e}]})))console.log(l),l.choices[0].delta.content&&t(l.choices[0].delta.content)}var eT=e=>{let{accessToken:t,token:s,userRole:a,userID:n}=e,[o,i]=(0,r.useState)(""),[c,d]=(0,r.useState)([]),[h,m]=(0,r.useState)(void 0),[u,x]=(0,r.useState)(null);(0,r.useEffect)(()=>{t&&s&&a&&n&&(async()=>{let e=await y(t,n,a);console.log("model_info:",e),(null==e?void 0:e.data.length)>0&&(x(e.data),m(e.data[0].id))})()},[t,n,a]);let p=(e,t)=>{d(s=>{let l=s[s.length-1];return l&&l.role===e?[...s.slice(0,s.length-1),{role:e,content:l.content+t}]:[...s,{role:e,content:t}]})},j=async()=>{if(""!==o.trim()&&t&&s&&a&&n){d(e=>[...e,{role:"user",content:o}]);try{h&&await eC(o,e=>p("assistant",e),h,t)}catch(e){console.error("Error fetching model response",e),p("assistant","Error fetching model response")}i("")}};if(a&&"Admin Viewer"==a){let{Title:e,Paragraph:t}=en.default;return(0,l.jsxs)("div",{children:[(0,l.jsx)(e,{level:1,children:"Access Denied"}),(0,l.jsx)(t,{children:"Ask your proxy admin for access to test models"})]})}return(0,l.jsx)("div",{style:{width:"100%",position:"relative"},children:(0,l.jsx)(O.Z,{className:"gap-2 p-10 h-[75vh] w-full",children:(0,l.jsx)(M.Z,{children:(0,l.jsxs)(ey.Z,{children:[(0,l.jsxs)(eg.Z,{className:"mt-4",children:[(0,l.jsx)(ej.Z,{children:"Chat"}),(0,l.jsx)(ej.Z,{children:"API Reference"})]}),(0,l.jsxs)(eZ.Z,{children:[(0,l.jsxs)(ew.Z,{children:[(0,l.jsxs)("div",{children:[(0,l.jsx)("label",{children:"Select Model:"}),(0,l.jsx)("select",{value:h||"",onChange:e=>m(e.target.value),children:null==u?void 0:u.map(e=>(0,l.jsx)("option",{value:e.id,children:e.id},e.id))})]}),(0,l.jsxs)($.Z,{className:"mt-5",style:{display:"block",maxHeight:"60vh",overflowY:"auto"},children:[(0,l.jsx)(X.Z,{children:(0,l.jsx)(ee.Z,{children:(0,l.jsx)(Y.Z,{children:(0,l.jsx)(D.Z,{children:"Chat"})})})}),(0,l.jsx)(H.Z,{children:c.map((e,t)=>(0,l.jsx)(ee.Z,{children:(0,l.jsx)(Y.Z,{children:"".concat(e.role,": ").concat(e.content)})},t))})]}),(0,l.jsx)("div",{className:"mt-3",style:{position:"absolute",bottom:5,width:"95%"},children:(0,l.jsxs)("div",{className:"flex",children:[(0,l.jsx)("input",{type:"text",value:o,onChange:e=>i(e.target.value),className:"flex-1 p-2 border rounded-md mr-2",placeholder:"Type your message..."}),(0,l.jsx)("button",{onClick:j,className:"p-2 bg-blue-500 text-white rounded-md",children:"Send"})]})})]}),(0,l.jsx)(ew.Z,{children:(0,l.jsxs)(ey.Z,{children:[(0,l.jsxs)(eg.Z,{children:[(0,l.jsx)(ej.Z,{children:"OpenAI Python SDK"}),(0,l.jsx)(ej.Z,{children:"LlamaIndex"}),(0,l.jsx)(ej.Z,{children:"Langchain Py"})]}),(0,l.jsxs)(eZ.Z,{children:[(0,l.jsx)(ew.Z,{children:(0,l.jsx)(eA.Z,{language:"python",children:'\nimport openai\nclient = openai.OpenAI(\n api_key="your_api_key",\n base_url="http://0.0.0.0:4000" # proxy base url\n)\n\nresponse = client.chat.completions.create(\n model="gpt-3.5-turbo", # model to use from Models Tab\n messages = [\n {\n "role": "user",\n "content": "this is a test request, write a short poem"\n }\n ],\n extra_body={\n "metadata": {\n "generation_name": "ishaan-generation-openai-client",\n "generation_id": "openai-client-gen-id22",\n "trace_id": "openai-client-trace-id22",\n "trace_user_id": "openai-client-user-id2"\n }\n }\n)\n\nprint(response)\n '})}),(0,l.jsx)(ew.Z,{children:(0,l.jsx)(eA.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="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,l.jsx)(ew.Z,{children:(0,l.jsx)(eA.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:8000",\n model = "gpt-3.5-turbo",\n temperature=0.1,\n extra_body={\n "metadata": {\n "generation_name": "ishaan-generation-langchain-client",\n "generation_id": "langchain-client-gen-id22",\n "trace_id": "langchain-client-trace-id22",\n "trace_user_id": "langchain-client-user-id2"\n }\n }\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 '})})]})]})})]})]})})})})},eI=s(33509),eP=s(30569);let{Sider:eE}=eI.default;var eF=e=>{let{setPage:t,userRole:s,defaultSelectedKey:r}=e;return"Admin Viewer"==s?(0,l.jsx)(eI.default,{style:{minHeight:"100vh",maxWidth:"120px"},children:(0,l.jsx)(eE,{width:120,children:(0,l.jsxs)(eP.Z,{mode:"inline",defaultSelectedKeys:r||["4"],style:{height:"100%",borderRight:0},children:[(0,l.jsx)(eP.Z.Item,{onClick:()=>t("api-keys"),children:"API Keys"},"4"),(0,l.jsx)(eP.Z.Item,{onClick:()=>t("models"),children:"Models"},"2"),(0,l.jsx)(eP.Z.Item,{onClick:()=>t("llm-playground"),children:"Chat UI"},"3"),(0,l.jsx)(eP.Z.Item,{onClick:()=>t("usage"),children:"Usage"},"1")]})})}):(0,l.jsx)(eI.default,{style:{minHeight:"100vh",maxWidth:"120px"},children:(0,l.jsx)(eE,{width:120,children:(0,l.jsxs)(eP.Z,{mode:"inline",defaultSelectedKeys:r||["1"],style:{height:"100%",borderRight:0},children:[(0,l.jsx)(eP.Z.Item,{onClick:()=>t("api-keys"),children:"API Keys"},"1"),(0,l.jsx)(eP.Z.Item,{onClick:()=>t("models"),children:"Models"},"2"),(0,l.jsx)(eP.Z.Item,{onClick:()=>t("llm-playground"),children:"Chat UI"},"3"),(0,l.jsx)(eP.Z.Item,{onClick:()=>t("usage"),children:"Usage"},"4"),"Admin"==s?(0,l.jsx)(eP.Z.Item,{onClick:()=>t("users"),children:"Users"},"5"):null,"Admin"==s?(0,l.jsx)(eP.Z.Item,{onClick:()=>t("teams"),children:"Teams"},"6"):null,"Admin"==s?(0,l.jsx)(eP.Z.Item,{onClick:()=>t("admin-panel"),children:"Admin"},"7"):null]})})})},eO=e=>{let{accessToken:t,token:s,userRole:a,userID:n}=e,o=new Date,[i,c]=(0,r.useState)([]),[d,h]=(0,r.useState)([]),[m,u]=(0,r.useState)([]),[x,p]=(0,r.useState)([]),[j,y]=(0,r.useState)([]),[g,_]=(0,r.useState)([]),[S,N]=(0,r.useState)([]),A=new Date(o.getFullYear(),o.getMonth(),1),C=new Date(o.getFullYear(),o.getMonth()+1,0),T=P(A),I=P(C);function P(e){let t=e.getFullYear(),s=e.getMonth()+1,l=e.getDate();return"".concat(t,"-").concat(s<10?"0"+s:s,"-").concat(l<10?"0"+l:l)}return console.log("Start date is ".concat(T)),console.log("End date is ".concat(I)),(0,r.useEffect)(()=>{t&&s&&a&&n&&(async()=>{try{if(console.log("user role: ".concat(a)),"Admin"==a||"Admin Viewer"==a){let e=await f(t);c(e);let s=(await k(t)).map(e=>({key:(e.key_name||e.key_alias||e.api_key).substring(0,7),spend:e.total_spend}));h(s);let l=(await b(t)).map(e=>({key:e.model,spend:e.total_spend}));u(l);let r=await w(t);console.log("teamSpend",r),y(r.daily_spend),_(r.teams),N(r.total_spend_per_team)}else"App Owner"==a&&await Z(t,s,a,n,T,I).then(async e=>{if(console.log("result from spend logs call",e),"daily_spend"in e){let t=e.daily_spend;console.log("daily spend",t),c(t);let s=e.top_api_keys;h(s)}else{let s=(await v(t,function(e){let t=[];e.forEach(e=>{Object.entries(e).forEach(e=>{let[s,l]=e;"spend"!==s&&"startTime"!==s&&"models"!==s&&"users"!==s&&t.push({key:s,spend:l})})}),t.sort((e,t)=>Number(t.spend)-Number(e.spend));let s=t.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||e.token).substring(0,7),spend:e.spend}));h(s),p(function(e){let t={};e.forEach(e=>{Object.entries(e.users).forEach(e=>{let[s,l]=e;""!==s&&null!=s&&"None"!=s&&(t[s]||(t[s]=0),t[s]+=l)})});let s=Object.entries(t).map(e=>{let[t,s]=e;return{user_id:t,spend:s}});s.sort((e,t)=>t.spend-e.spend);let l=s.slice(0,5);return console.log("topKeys: ".concat(Object.values(l[0]))),l}(e)),c(e)}})}catch(e){console.error("There was an error fetching the data",e)}})()},[t,s,a,n,T,I]),(0,l.jsx)("div",{style:{width:"100%"},children:(0,l.jsxs)(ey.Z,{children:[(0,l.jsxs)(eg.Z,{className:"mt-4",children:[(0,l.jsx)(ej.Z,{children:"All Up"}),(0,l.jsx)(ej.Z,{children:"Team Based Usage"})]}),(0,l.jsxs)(eZ.Z,{children:[(0,l.jsx)(ew.Z,{children:(0,l.jsxs)(O.Z,{numItems:2,className:"gap-2 p-10 h-[75vh] w-full",children:[(0,l.jsx)(F.Z,{numColSpan:2,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Monthly Spend"}),(0,l.jsx)(et.Z,{data:i,index:"date",categories:["spend"],colors:["blue"],valueFormatter:e=>"$ ".concat(new Intl.NumberFormat("us").format(e).toString()),yAxisWidth:100,tickGap:5})]})}),(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Top API Keys"}),(0,l.jsx)(et.Z,{className:"mt-4 h-40",data:d,index:"key",categories:["spend"],colors:["blue"],yAxisWidth:80,tickGap:5,layout:"vertical",showXAxis:!1,showLegend:!1})]})}),(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Top Users"}),(0,l.jsx)(et.Z,{className:"mt-4 h-40",data:x,index:"user_id",categories:["spend"],colors:["blue"],yAxisWidth:200,layout:"vertical",showXAxis:!1,showLegend:!1})]})}),(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Top Models"}),(0,l.jsx)(et.Z,{className:"mt-4 h-40",data:m,index:"key",categories:["spend"],colors:["blue"],yAxisWidth:200,layout:"vertical",showXAxis:!1,showLegend:!1})]})})]})}),(0,l.jsx)(ew.Z,{children:(0,l.jsxs)(O.Z,{numItems:2,className:"gap-2 p-10 h-[75vh] w-full",children:[(0,l.jsx)(F.Z,{numColSpan:2,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Daily Spend Per Team"}),(0,l.jsx)(et.Z,{className:"h-72",data:j,index:"date",categories:g,yAxisWidth:30,stack:!0})]})}),(0,l.jsx)(F.Z,{numColSpan:2,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Total Spend Per Team"}),(0,l.jsx)(et.Z,{className:"h-72",data:S,index:"team_id",categories:["total_spend"],yAxisWidth:30})]})})]})})]})]})})},eM=()=>{let{Title:e,Paragraph:t}=en.default,[s,n]=(0,r.useState)(""),[o,c]=(0,r.useState)(null),[d,h]=(0,r.useState)(null),[m,u]=(0,r.useState)(null),[x,p]=(0,r.useState)(!0),j=(0,a.useSearchParams)(),y=j.get("userID"),g=j.get("token"),[w,Z]=(0,r.useState)("api-keys"),[f,k]=(0,r.useState)(null);return(0,r.useEffect)(()=>{if(g){let e=(0,ed.o)(g);if(e){if(console.log("Decoded token:",e),console.log("Decoded key:",e.key),k(e.key),e.user_role){let t=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"app_user":return"App User";default:return"Unknown Role"}}(e.user_role);console.log("Decoded user_role:",t),n(t),"Admin Viewer"==t&&Z("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?p("username_password"==e.login_method):console.log("User Email is not set ".concat(e))}}},[g]),(0,l.jsx)(r.Suspense,{fallback:(0,l.jsx)("div",{children:"Loading..."}),children:(0,l.jsxs)("div",{className:"flex flex-col min-h-screen",children:[(0,l.jsx)(i,{userID:y,userRole:s,userEmail:o,showSSOBanner:x}),(0,l.jsxs)("div",{className:"flex flex-1 overflow-auto",children:[(0,l.jsx)(eF,{setPage:Z,userRole:s,defaultSelectedKey:null}),"api-keys"==w?(0,l.jsx)(eh,{userID:y,userRole:s,teams:d,keys:m,setUserRole:n,userEmail:o,setUserEmail:c,setTeams:h,setKeys:u}):"models"==w?(0,l.jsx)(ep,{userID:y,userRole:s,token:g,accessToken:f}):"llm-playground"==w?(0,l.jsx)(eT,{userID:y,userRole:s,token:g,accessToken:f}):"users"==w?(0,l.jsx)(e_,{userID:y,userRole:s,token:g,keys:m,accessToken:f,setKeys:u}):"teams"==w?(0,l.jsx)(eb,{teams:d,setTeams:h,searchParams:j,accessToken:f,userID:y,userRole:s}):"admin-panel"==w?(0,l.jsx)(eS,{setTeams:h,searchParams:j,accessToken:f}):(0,l.jsx)(eO,{userID:y,userRole:s,token:g,accessToken:f})]})]})})}}},function(e){e.O(0,[730,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 92bf64b20..c7e3747d6 100644 --- a/litellm/proxy/_experimental/out/index.html +++ b/litellm/proxy/_experimental/out/index.html @@ -1 +1 @@ -🚅 LiteLLM \ No newline at end of file +🚅 LiteLLM \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/index.txt b/litellm/proxy/_experimental/out/index.txt index c68d627f6..2c6c4f5bb 100644 --- a/litellm/proxy/_experimental/out/index.txt +++ b/litellm/proxy/_experimental/out/index.txt @@ -1,7 +1,7 @@ 2:I[77831,[],""] -3:I[92182,["730","static/chunks/730-1411b729a1c79695.js","931","static/chunks/app/page-2b5b48b67d7eccff.js"],""] +3:I[92182,["730","static/chunks/730-1411b729a1c79695.js","931","static/chunks/app/page-7811c13c82288ada.js"],""] 4:I[5613,[],""] 5:I[31778,[],""] -0:["tpFpoAscsg2XQqXwfShjz",[[["",{"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_c23dc8","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/68a21c6e6697f7ca.css","precedence":"next","crossOrigin":""}]],"$L6"]]]] +0:["NOy_Z-02UirnQn7wjpTs0",[[["",{"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_c23dc8","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/68a21c6e6697f7ca.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"}],["$","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 99d054e9c..a53766463 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

404

This page could not be found.

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

404

This page could not be found.

\ No newline at end of file diff --git a/ui/litellm-dashboard/out/_next/static/tpFpoAscsg2XQqXwfShjz/_buildManifest.js b/ui/litellm-dashboard/out/_next/static/NOy_Z-02UirnQn7wjpTs0/_buildManifest.js similarity index 100% rename from ui/litellm-dashboard/out/_next/static/tpFpoAscsg2XQqXwfShjz/_buildManifest.js rename to ui/litellm-dashboard/out/_next/static/NOy_Z-02UirnQn7wjpTs0/_buildManifest.js diff --git a/ui/litellm-dashboard/out/_next/static/tpFpoAscsg2XQqXwfShjz/_ssgManifest.js b/ui/litellm-dashboard/out/_next/static/NOy_Z-02UirnQn7wjpTs0/_ssgManifest.js similarity index 100% rename from ui/litellm-dashboard/out/_next/static/tpFpoAscsg2XQqXwfShjz/_ssgManifest.js rename to ui/litellm-dashboard/out/_next/static/NOy_Z-02UirnQn7wjpTs0/_ssgManifest.js diff --git a/ui/litellm-dashboard/out/_next/static/chunks/app/page-2b5b48b67d7eccff.js b/ui/litellm-dashboard/out/_next/static/chunks/app/page-7811c13c82288ada.js similarity index 62% rename from ui/litellm-dashboard/out/_next/static/chunks/app/page-2b5b48b67d7eccff.js rename to ui/litellm-dashboard/out/_next/static/chunks/app/page-7811c13c82288ada.js index f1848d3af..8aae09847 100644 --- a/ui/litellm-dashboard/out/_next/static/chunks/app/page-2b5b48b67d7eccff.js +++ b/ui/litellm-dashboard/out/_next/static/chunks/app/page-7811c13c82288ada.js @@ -1 +1 @@ -(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[931],{20661:function(e,t,s){Promise.resolve().then(s.bind(s,92182))},92182:function(e,t,s){"use strict";s.r(t),s.d(t,{default:function(){return eM}});var l=s(3827),r=s(64090),a=s(47907),n=s(8792),o=s(2179),i=e=>{let{userID:t,userRole:s,userEmail:r,showSSOBanner:a}=e;return console.log("User ID:",t),console.log("userEmail:",r),(0,l.jsxs)("nav",{className:"left-0 right-0 top-0 flex justify-between items-center h-12 mb-4",children:[(0,l.jsx)("div",{className:"text-left my-2 absolute top-0 left-0",children:(0,l.jsx)("div",{className:"flex flex-col items-center",children:(0,l.jsx)(n.default,{href:"/",children:(0,l.jsx)("button",{className:"text-gray-800 text-2xl py-1 rounded text-center",children:(0,l.jsx)("img",{src:"/get_image",width:200,height:200,alt:"LiteLLM Brand",className:"mr-2"})})})})}),(0,l.jsxs)("div",{className:"text-right mx-4 my-2 absolute top-0 right-0 flex items-center justify-end space-x-2",children:[a?(0,l.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/ui#setup-ssoauth-for-ui",target:"_blank",className:"mr-2"}):null,(0,l.jsxs)(o.Z,{variant:"secondary",size:"lg",children:[r,(0,l.jsxs)("p",{children:["Role: ",s]}),(0,l.jsxs)("p",{children:["ID: ",t]})]})]})]})},c=s(80588);let d=async(e,t,s)=>{try{if(console.log("Form Values in keyCreateCall:",s),s.description&&(s.metadata||(s.metadata={}),s.metadata.description=s.description,delete s.description,s.metadata=JSON.stringify(s.metadata)),s.metadata){console.log("formValues.metadata:",s.metadata);try{s.metadata=JSON.parse(s.metadata)}catch(e){throw c.ZP.error("Failed to parse metadata: "+e),Error("Failed to parse metadata: "+e)}}console.log("Form Values after check:",s);let l=await fetch("/key/generate",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({user_id:t,...s})});if(!l.ok){let e=await l.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let r=await l.json();return console.log("API Response:",r),r}catch(e){throw console.error("Failed to create key:",e),e}},h=async(e,t,s)=>{try{if(console.log("Form Values in keyCreateCall:",s),s.description&&(s.metadata||(s.metadata={}),s.metadata.description=s.description,delete s.description,s.metadata=JSON.stringify(s.metadata)),s.metadata){console.log("formValues.metadata:",s.metadata);try{s.metadata=JSON.parse(s.metadata)}catch(e){throw c.ZP.error("Failed to parse metadata: "+e),Error("Failed to parse metadata: "+e)}}console.log("Form Values after check:",s);let l=await fetch("/user/new",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({user_id:t,...s})});if(!l.ok){let e=await l.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let r=await l.json();return console.log("API Response:",r),r}catch(e){throw console.error("Failed to create key:",e),e}},m=async(e,t)=>{try{console.log("in keyDeleteCall:",t);let s=await fetch("/key/delete",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({keys:[t]})});if(!s.ok){let e=await s.text();throw c.ZP.error("Failed to delete key: "+e),Error("Network response was not ok")}let l=await s.json();return console.log(l),l}catch(e){throw console.error("Failed to create key:",e),e}},u=async function(e,t,s){let l=arguments.length>3&&void 0!==arguments[3]&&arguments[3];try{let r="/user/info";"App Owner"==s&&t&&(r="".concat(r,"?user_id=").concat(t)),console.log("in userInfoCall viewAll=",l),l&&(r="".concat(r,"?view_all=true"));let a=await fetch(r,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!a.ok){let e=await a.text();throw c.ZP.error(e),Error("Network response was not ok")}let n=await a.json();return console.log("API Response:",n),n}catch(e){throw console.error("Failed to create key:",e),e}},x=async e=>{try{let t=await fetch("/global/spend",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},p=async(e,t,s)=>{try{let t=await fetch("/v2/model/info",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},j=async(e,t,s)=>{try{let t=await fetch("/model/metrics",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},y=async(e,t,s)=>{try{let t=await fetch("/models",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},g=async(e,t)=>{try{let s="/global/spend/logs";console.log("in keySpendLogsCall:",s);let l=await fetch("".concat(s,"?api_key=").concat(t),{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw c.ZP.error(e),Error("Network response was not ok")}let r=await l.json();return console.log(r),r}catch(e){throw console.error("Failed to create key:",e),e}},w=async e=>{try{let t="/global/spend/teams";console.log("in teamSpendLogsCall:",t);let s=await fetch("".concat(t),{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!s.ok){let e=await s.text();throw c.ZP.error(e),Error("Network response was not ok")}let l=await s.json();return console.log(l),l}catch(e){throw console.error("Failed to create key:",e),e}},Z=async(e,t,s,l,r,a)=>{try{console.log("user role in spend logs call: ".concat(s));let t="/spend/logs";t="App Owner"==s?"".concat(t,"?user_id=").concat(l,"&start_date=").concat(r,"&end_date=").concat(a):"".concat(t,"?start_date=").concat(r,"&end_date=").concat(a);let n=await fetch(t,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!n.ok){let e=await n.text();throw c.ZP.error(e),Error("Network response was not ok")}let o=await n.json();return console.log(o),o}catch(e){throw console.error("Failed to create key:",e),e}},f=async e=>{try{let t=await fetch("/global/spend/logs",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to create key:",e),e}},k=async e=>{try{let t=await fetch("/global/spend/keys?limit=5",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to create key:",e),e}},_=async(e,t)=>{try{t&&JSON.stringify({api_key:t});let s={method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}};t&&(s.body=JSON.stringify({api_key:t}));let l=await fetch("/global/spend/end_users",s);if(!l.ok){let e=await l.text();throw c.ZP.error(e),Error("Network response was not ok")}let r=await l.json();return console.log(r),r}catch(e){throw console.error("Failed to create key:",e),e}},b=async e=>{try{let t=await fetch("/global/spend/models?limit=5",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to create key:",e),e}},v=async(e,t)=>{try{let s=await fetch("/v2/key/info",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({keys:t})});if(!s.ok){let e=await s.text();throw c.ZP.error(e),Error("Network response was not ok")}let l=await s.json();return console.log(l),l}catch(e){throw console.error("Failed to create key:",e),e}},S=async(e,t,s,l)=>{try{let r=await fetch("/user/request_model",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({models:[t],user_id:s,justification:l})});if(!r.ok){let e=await r.text();throw c.ZP.error("Failed to delete key: "+e),Error("Network response was not ok")}let a=await r.json();return console.log(a),a}catch(e){throw console.error("Failed to create key:",e),e}},N=async e=>{try{let t="/user/get_requests";console.log("in userGetRequesedtModelsCall:",t);let s=await fetch(t,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!s.ok){let e=await s.text();throw c.ZP.error("Failed to delete key: "+e),Error("Network response was not ok")}let l=await s.json();return console.log(l),l}catch(e){throw console.error("Failed to get requested models:",e),e}},A=async(e,t)=>{try{let s="/user/get_users?role=".concat(t);console.log("in userGetAllUsersCall:",s);let l=await fetch(s,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw c.ZP.error("Failed to delete key: "+e),Error("Network response was not ok")}let r=await l.json();return console.log(r),r}catch(e){throw console.error("Failed to get requested models:",e),e}},C=async(e,t)=>{try{console.log("Form Values in teamCreateCall:",t);let s=await fetch("/team/new",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...t})});if(!s.ok){let e=await s.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let l=await s.json();return console.log("API Response:",l),l}catch(e){throw console.error("Failed to create key:",e),e}},T=async(e,t,s)=>{try{console.log("Form Values in teamMemberAddCall:",s);let l=await fetch("/team/member_add",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({team_id:t,member:s})});if(!l.ok){let e=await l.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let r=await l.json();return console.log("API Response:",r),r}catch(e){throw console.error("Failed to create key:",e),e}},I=async(e,t)=>{try{console.log("Form Values in userUpdateUserCall:",t);let s=await fetch("/user/update",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({user_role:"proxy_admin_viewer",...t})});if(!s.ok){let e=await s.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let l=await s.json();return console.log("API Response:",l),l}catch(e){throw console.error("Failed to create key:",e),e}},P=async(e,t)=>{try{let s=await fetch("/global/predict/spend/logs",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({data:t})});if(!s.ok){let e=await s.text();throw c.ZP.error(e),Error("Network response was not ok")}let l=await s.json();return console.log(l),l}catch(e){throw console.error("Failed to create key:",e),e}},E=async e=>{try{console.log("Checking Slack Budget Alerts service health");let t=await fetch("/health/services?service=slack_budget_alerts",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error("Failed Slack Alert test: "+e),Error(e)}let s=await t.json();return c.ZP.success("Test Slack Alert worked - check your Slack!"),console.log("Service Health Response:",s),s}catch(e){throw console.error("Failed to perform health check:",e),e}};var F=s(10384),O=s(46453),M=s(13810),R=s(71801),D=s(42440),U=s(17189),L=s(12143),B=s(77171),z=s(42539),K=s(88707),W=s(1861);let{Option:V}=U.default;var q=e=>{let{userID:t,teamID:s,userRole:a,accessToken:n,data:i,userModels:h,setData:m}=e,[u]=L.Z.useForm(),[x,p]=(0,r.useState)(!1),[j,y]=(0,r.useState)(null),[g,w]=(0,r.useState)(null),Z=()=>{p(!1),u.resetFields()},f=()=>{p(!1),y(null),u.resetFields()},k=async e=>{try{c.ZP.info("Making API Call"),p(!0);let s=await d(n,t,e);console.log("key create Response:",s),m(e=>e?[...e,s]:[s]),y(s.key),w(s.soft_budget),c.ZP.success("API Key Created"),u.resetFields(),localStorage.removeItem("userData"+t)}catch(e){console.error("Error creating the key:",e)}},_=async()=>{try{console.log("Sending Slack alert...");let e=await E(n);console.log("slackBudgetAlertsHealthCheck Response:",e),console.log("Testing Slack alert successful")}catch(e){console.error("Error sending Slack alert:",e)}};return(0,l.jsxs)("div",{children:[(0,l.jsx)(o.Z,{className:"mx-auto",onClick:()=>p(!0),children:"+ Create New Key"}),(0,l.jsx)(B.Z,{title:"Create Key",visible:x,width:800,footer:null,onOk:Z,onCancel:f,children:(0,l.jsxs)(L.Z,{form:u,onFinish:k,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:["App Owner"===a||"Admin"===a?(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(L.Z.Item,{label:"Key Name",name:"key_alias",children:(0,l.jsx)(z.Z,{})}),(0,l.jsx)(L.Z.Item,{label:"Team ID",name:"team_id",children:(0,l.jsx)(z.Z,{placeholder:"ai_team",defaultValue:s||""})}),(0,l.jsx)(L.Z.Item,{label:"Models",name:"models",children:(0,l.jsx)(U.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:h.map(e=>(0,l.jsx)(V,{value:e,children:e},e))})}),(0,l.jsx)(L.Z.Item,{label:"Soft Budget (USD) Monthly",name:"soft_budget",initialValue:50,children:(0,l.jsx)(K.Z,{step:.01,precision:2,defaultValue:50,width:200})}),(0,l.jsx)(L.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,l.jsx)(K.Z,{step:.01,precision:2,width:200})}),(0,l.jsx)(L.Z.Item,{label:"Reset Budget",name:"budget_duration",children:(0,l.jsxs)(U.default,{defaultValue:null,placeholder:"n/a",children:[(0,l.jsx)(U.default.Option,{value:"24h",children:"daily"}),(0,l.jsx)(U.default.Option,{value:"30d",children:"monthly"})]})}),(0,l.jsx)(L.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})}),(0,l.jsx)(L.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})}),(0,l.jsx)(L.Z.Item,{label:"Expire Key (eg: 30s, 30h, 30d)",name:"duration",children:(0,l.jsx)(z.Z,{})}),(0,l.jsx)(L.Z.Item,{label:"Metadata",name:"metadata",children:(0,l.jsx)(z.Z.TextArea,{rows:4,placeholder:"Enter metadata as JSON"})})]}):(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(L.Z.Item,{label:"Key Name",name:"key_alias",children:(0,l.jsx)(z.Z,{})}),(0,l.jsx)(L.Z.Item,{label:"Team ID (Contact Group)",name:"team_id",children:(0,l.jsx)(z.Z,{placeholder:"ai_team"})}),(0,l.jsx)(L.Z.Item,{label:"Description",name:"description",children:(0,l.jsx)(z.Z.TextArea,{placeholder:"Enter description",rows:4})})]}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(W.ZP,{htmlType:"submit",children:"Create Key"})})]})}),j&&(0,l.jsx)(B.Z,{visible:x,onOk:Z,onCancel:f,footer:null,children:(0,l.jsx)(O.Z,{numItems:1,className:"gap-2 w-full",children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Save your Key"}),(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsxs)("p",{children:["Please save this secret key somewhere safe and accessible. For security reasons, ",(0,l.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,l.jsx)(F.Z,{numColSpan:1,children:null!=j?(0,l.jsxs)("div",{children:[(0,l.jsxs)(R.Z,{children:["API Key: ",j]}),(0,l.jsx)(D.Z,{className:"mt-6",children:"Budgets"}),(0,l.jsxs)(R.Z,{children:["Soft Limit Budget: $",g]}),(0,l.jsx)(o.Z,{className:"mt-3",onClick:_,children:"Test Slack Alert"}),(0,l.jsxs)(R.Z,{className:"mt-2",children:["(LiteLLM Docs -",(0,l.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/alerting",target:"_blank",className:"text-blue-500",children:"Set Up Slack Alerting)"})]})]}):(0,l.jsx)(R.Z,{children:"Key being created, this might take 30s"})})]})})})]})},J=s(33393),G=s(61244),$=s(10827),H=s(3851),Y=s(2044),X=s(64167),Q=s(74480),ee=s(7178),et=s(9853),es=s(56863),el=e=>{let{token:t,accessToken:s,keySpend:a,keyBudget:n,keyName:i}=e,[c,d]=(0,r.useState)(!1),[h,m]=(0,r.useState)(null),[u,x]=(0,r.useState)(""),[p,j]=(0,r.useState)(null),y=async()=>{try{if(null==s||null==t)return;console.log("accessToken: ".concat(s,"; token: ").concat(t));let e=await g(s,t);console.log("Response:",e),m(e);let l=await P(s,e);console.log("Response2:",l);let r=[...e,...l.response];m(r),x(l.predicted_spend),console.log("Combined Data:",r)}catch(e){console.error("There was an error fetching the data",e)}};return t?(0,l.jsxs)("div",{children:[(0,l.jsx)(o.Z,{size:"xs",onClick:()=>{console.log("Show Modal triggered"),d(!0),y()},variant:"secondary",children:"Spend Report"}),(0,l.jsxs)(B.Z,{visible:c,width:1400,onOk:()=>{d(!1)},onCancel:()=>{d(!1)},footer:null,children:[(0,l.jsxs)(D.Z,{style:{textAlign:"left"},children:["Key Name: ",i]}),(0,l.jsxs)(es.Z,{children:["Monthly Spend $",a]}),(0,l.jsx)(D.Z,{children:u}),(0,l.jsx)(M.Z,{className:"mt-6 mb-6",children:h&&(0,l.jsx)(et.Z,{className:"mt-6",data:h,colors:["blue","amber"],index:"date",categories:["spend","predicted_spend"],yAxisWidth:80})})]})]}):null},er=e=>{let{userID:t,accessToken:s,data:a,setData:n}=e,[i,c]=(0,r.useState)(!1),[d,h]=(0,r.useState)(!1),[u,x]=(0,r.useState)(null),p=async e=>{null!=a&&(x(e),localStorage.removeItem("userData"+t),h(!0))},j=async()=>{if(null!=u&&null!=a){try{await m(s,u);let e=a.filter(e=>e.token!==u);n(e)}catch(e){console.error("Error deleting the key:",e)}h(!1),x(null)}};if(null!=a)return console.log("RERENDER TRIGGERED"),(0,l.jsxs)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh] mb-4",children:[(0,l.jsxs)($.Z,{className:"mt-5",children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"Key Alias"}),(0,l.jsx)(Q.Z,{children:"Secret Key"}),(0,l.jsx)(Q.Z,{children:"Spend (USD)"}),(0,l.jsx)(Q.Z,{children:"Key Budget (USD)"}),(0,l.jsx)(Q.Z,{children:"Spend Report"}),(0,l.jsx)(Q.Z,{children:"Team ID"}),(0,l.jsx)(Q.Z,{children:"Metadata"}),(0,l.jsx)(Q.Z,{children:"Models"}),(0,l.jsx)(Q.Z,{children:"TPM / RPM Limits"}),(0,l.jsx)(Q.Z,{children:"Expires"})]})}),(0,l.jsx)(H.Z,{children:a.map(e=>(console.log(e),"litellm-dashboard"===e.team_id)?null:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",whiteSpace:"pre-wrap",overflow:"hidden"},children:null!=e.key_alias?(0,l.jsx)(R.Z,{children:e.key_alias}):(0,l.jsx)(R.Z,{children:"Not Set"})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:e.key_name})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:(()=>{try{return parseFloat(e.spend).toFixed(4)}catch(t){return e.spend}})()})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",whiteSpace:"pre-wrap",overflow:"hidden"},children:null!=e.max_budget?(0,l.jsx)(R.Z,{children:e.max_budget}):(0,l.jsx)(R.Z,{children:"Unlimited Budget"})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px"},children:(0,l.jsx)(el,{token:e.token,accessToken:s,keySpend:e.spend,keyBudget:e.max_budget,keyName:e.key_name})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:e.team_id})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:JSON.stringify(e.metadata).slice(0,400)})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:JSON.stringify(e.models)})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",overflowWrap:"break-word"},children:(0,l.jsxs)(R.Z,{children:["TPM Limit: ",e.tpm_limit?e.tpm_limit:"Unlimited"," ",(0,l.jsx)("br",{})," RPM Limit:"," ",e.rpm_limit?e.rpm_limit:"Unlimited"]})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",wordWrap:"break-word"},children:null!=e.expires?(0,l.jsx)(R.Z,{children:e.expires}):(0,l.jsx)(R.Z,{children:"Never"})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",wordWrap:"break-word"},children:(0,l.jsx)(G.Z,{onClick:()=>p(e.token),icon:J.Z,size:"sm"})})]},e.token))})]}),d&&(0,l.jsx)("div",{className:"fixed z-10 inset-0 overflow-y-auto",children:(0,l.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,l.jsx)("div",{className:"fixed inset-0 transition-opacity","aria-hidden":"true",children:(0,l.jsx)("div",{className:"absolute inset-0 bg-gray-500 opacity-75"})}),(0,l.jsx)("span",{className:"hidden sm:inline-block sm:align-middle sm:h-screen","aria-hidden":"true",children:"​"}),(0,l.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,l.jsx)("div",{className:"bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4",children:(0,l.jsx)("div",{className:"sm:flex sm:items-start",children:(0,l.jsxs)("div",{className:"mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left",children:[(0,l.jsx)("h3",{className:"text-lg leading-6 font-medium text-gray-900",children:"Delete Key"}),(0,l.jsx)("div",{className:"mt-2",children:(0,l.jsx)("p",{className:"text-sm text-gray-500",children:"Are you sure you want to delete this key ?"})})]})})}),(0,l.jsxs)("div",{className:"bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse",children:[(0,l.jsx)(o.Z,{onClick:j,color:"red",className:"ml-2",children:"Delete"}),(0,l.jsx)(o.Z,{onClick:()=>{h(!1),x(null)},children:"Cancel"})]})]})]})})]})},ea=e=>{let{userID:t,userSpendData:s,userRole:a,accessToken:n}=e,[o,i]=(0,r.useState)(null==s?void 0:s.spend),[c,d]=(0,r.useState)((null==s?void 0:s.max_budget)||null);(0,r.useEffect)(()=>{(async()=>{if("Admin"===a)try{let e=await x(n);i(e.spend),d(e.max_budget||null)}catch(e){console.error("Error fetching global spend data:",e)}})()},[a,n]);let h=void 0!==o?o.toFixed(4):null;return(0,l.jsx)(l.Fragment,{children:(0,l.jsxs)(M.Z,{className:"mx-auto mb-4",children:[(0,l.jsxs)(es.Z,{children:["$",h]}),(0,l.jsxs)(D.Z,{children:["/ ",null!==c?"$".concat(c," limit"):"No limit"]})]})})},en=s(36083),eo=s(68967),ei=s(27166),ec=e=>{let{teams:t,setSelectedTeam:s}=e,{Title:a,Paragraph:n}=en.default,[o,i]=(0,r.useState)("");return(0,l.jsxs)("div",{className:"mt-10",children:[(0,l.jsx)(a,{level:4,children:"Default Team"}),(0,l.jsx)(n,{children:"If you belong to multiple teams, this setting controls which team is used by default when creating new API Keys."}),t&&t.length>0?(0,l.jsx)(eo.Z,{defaultValue:"0",children:t.map((e,t)=>(0,l.jsx)(ei.Z,{value:String(t),onClick:()=>s(e),children:e.team_alias},t))}):(0,l.jsxs)(n,{children:["No team created. ",(0,l.jsx)("b",{children:"Defaulting to personal account."})]})]})},ed=s(37963);console.log("isLocal:",!1);var eh=e=>{let{userID:t,userRole:s,teams:n,keys:o,setUserRole:i,userEmail:c,setUserEmail:d,setTeams:h,setKeys:m}=e,[p,j]=(0,r.useState)(null),g=(0,a.useSearchParams)();g.get("viewSpend"),(0,a.useRouter)();let w=g.get("token"),[Z,f]=(0,r.useState)(null),[k,_]=(0,r.useState)([]),[b,v]=(0,r.useState)(n?n[0]:null);if(window.addEventListener("beforeunload",function(){sessionStorage.clear()}),(0,r.useEffect)(()=>{if(w){let e=(0,ed.o)(w);if(e){if(console.log("Decoded token:",e),console.log("Decoded key:",e.key),f(e.key),e.user_role){let t=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";default:return"Unknown Role"}}(e.user_role);console.log("Decoded user_role:",t),i(t)}else console.log("User role not defined");e.user_email?d(e.user_email):console.log("User Email is not set ".concat(e))}}if(t&&Z&&s&&!o&&!p){let e=sessionStorage.getItem("userModels"+t);e?_(JSON.parse(e)):(async()=>{try{let e=await u(Z,t,s);if(console.log("received teams in user dashboard: ".concat(Object.keys(e),"; team values: ").concat(Object.entries(e.teams))),"Admin"==s){let e=await x(Z);j(e),console.log("globalSpend:",e)}else j(e.user_info);m(e.keys),h(e.teams),v(e.teams?e.teams[0]:null),sessionStorage.setItem("userData"+t,JSON.stringify(e.keys)),sessionStorage.setItem("userSpendData"+t,JSON.stringify(e.user_info));let l=(await y(Z,t,s)).data.map(e=>e.id);console.log("available_model_names:",l),_(l),console.log("userModels:",k),sessionStorage.setItem("userModels"+t,JSON.stringify(l))}catch(e){console.error("There was an error fetching the data",e)}})()}},[t,w,Z,o,s]),null==t||null==w){let e="/sso/key/generate";return console.log("Full URL:",e),window.location.href=e,null}if(null==Z)return null;if(null==s&&i("App Owner"),s&&"Admin Viewer"==s){let{Title:e,Paragraph:t}=en.default;return(0,l.jsxs)("div",{children:[(0,l.jsx)(e,{level:1,children:"Access Denied"}),(0,l.jsx)(t,{children:"Ask your proxy admin for access to create keys"})]})}return(0,l.jsx)("div",{children:(0,l.jsx)(O.Z,{numItems:1,className:"gap-0 p-10 h-[75vh] w-full",children:(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(ea,{userID:t,userSpendData:p,userRole:s,accessToken:Z}),(0,l.jsx)(er,{userID:t,accessToken:Z,data:o,setData:m}),(0,l.jsx)(q,{userID:t,teamID:b?b.team_id:null,userRole:s,userModels:k,accessToken:Z,data:o,setData:m}),(0,l.jsx)(ec,{teams:n,setSelectedTeam:v})]})})})},em=s(5);let{Option:eu}=U.default;var ex=e=>{let{userModels:t,accessToken:s,userID:a}=e,[n]=L.Z.useForm(),[i,d]=(0,r.useState)(!1),h=async e=>{try{c.ZP.info("Requesting access");let{selectedModel:t,accessReason:l}=e;await S(s,t,a,l),d(!0)}catch(e){console.error("Error requesting access:",e)}};return(0,l.jsxs)("div",{children:[(0,l.jsx)(o.Z,{size:"xs",onClick:()=>d(!0),children:"Request Access"}),(0,l.jsx)(B.Z,{title:"Request Access",visible:i,width:800,footer:null,onOk:()=>{d(!1),n.resetFields()},onCancel:()=>{d(!1),n.resetFields()},children:(0,l.jsxs)(L.Z,{form:n,onFinish:h,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsx)(L.Z.Item,{label:"Select Model",name:"selectedModel",children:(0,l.jsx)(U.default,{placeholder:"Select model",style:{width:"100%"},children:t.map(e=>(0,l.jsx)(eu,{value:e,children:e},e))})}),(0,l.jsx)(L.Z.Item,{label:"Reason for Access",name:"accessReason",children:(0,l.jsx)(z.Z.TextArea,{rows:4,placeholder:"Enter reason for access"})}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(o.Z,{children:"Request Access"})})]})})]})},ep=e=>{let{accessToken:t,token:s,userRole:a,userID:n}=e,[o,i]=(0,r.useState)({data:[]}),[c,d]=(0,r.useState)([]),[h,m]=(0,r.useState)([]);if((0,r.useEffect)(()=>{if(!t||!s||!a||!n)return;let e=async()=>{try{let e=await p(t,n,a);console.log("Model data response:",e.data),i(e);let s=await j(t,n,a);if(console.log("Model metrics response:",s),d(s),"Admin"===a&&t){let e=await N(t);console.log("Pending Requests:",h),m(e.requests||[])}}catch(e){console.error("There was an error fetching the model data",e)}};t&&s&&a&&n&&e()},[t,s,a,n]),!o||!t||!s||!a||!n)return(0,l.jsx)("div",{children:"Loading..."});let u=[];for(let e=0;e(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{children:(0,l.jsx)(D.Z,{children:e.model_name})}),(0,l.jsx)(Y.Z,{children:e.provider}),"Admin"===a&&(0,l.jsx)(Y.Z,{children:e.api_base}),(0,l.jsx)(Y.Z,{children:e.user_access?(0,l.jsx)(em.Z,{color:"green",children:"Yes"}):(0,l.jsx)(ex,{userModels:u,accessToken:t,userID:n})}),(0,l.jsx)(Y.Z,{children:e.input_cost}),(0,l.jsx)(Y.Z,{children:e.output_cost}),(0,l.jsx)(Y.Z,{children:e.max_tokens})]},e.model_name))})]})}),(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Model Statistics (Number Requests)"}),(0,l.jsx)(et.Z,{data:c,index:"model",categories:["num_requests"],colors:["blue"],yAxisWidth:400,layout:"vertical",tickGap:5})]}),(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Model Statistics (Latency)"}),(0,l.jsx)(et.Z,{data:c,index:"model",categories:["avg_latency_seconds"],colors:["red"],yAxisWidth:400,layout:"vertical",tickGap:5})]})]})})},ej=s(92836),ey=s(26734),eg=s(41608),ew=s(32126),eZ=s(23682);let{Option:ef}=U.default;var ek=e=>{let{userID:t,accessToken:s}=e,[a]=L.Z.useForm(),[n,i]=(0,r.useState)(!1),[d,m]=(0,r.useState)(null),[u,x]=(0,r.useState)([]);(0,r.useEffect)(()=>{(async()=>{try{let e=await y(s,t,"any"),l=[];for(let t=0;t{i(!1),a.resetFields()},j=()=>{i(!1),m(null),a.resetFields()},g=async e=>{try{c.ZP.info("Making API Call"),i(!0),console.log("formValues in create user:",e);let l=await h(s,t,e);console.log("user create Response:",l),m(l.key),c.ZP.success("API user Created"),a.resetFields(),localStorage.removeItem("userData"+t)}catch(e){console.error("Error creating the user:",e)}};return(0,l.jsxs)("div",{children:[(0,l.jsx)(o.Z,{className:"mx-auto",onClick:()=>i(!0),children:"+ Create New User"}),(0,l.jsx)(B.Z,{title:"Create User",visible:n,width:800,footer:null,onOk:p,onCancel:j,children:(0,l.jsxs)(L.Z,{form:a,onFinish:g,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsx)(L.Z.Item,{label:"User ID",name:"user_id",children:(0,l.jsx)(z.Z,{placeholder:"Enter User ID"})}),(0,l.jsx)(L.Z.Item,{label:"Team ID",name:"team_id",children:(0,l.jsx)(z.Z,{placeholder:"ai_team"})}),(0,l.jsx)(L.Z.Item,{label:"Models",name:"models",children:(0,l.jsx)(U.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:u.map(e=>(0,l.jsx)(ef,{value:e,children:e},e))})}),(0,l.jsx)(L.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,l.jsx)(K.Z,{step:.01,precision:2,width:200})}),(0,l.jsx)(L.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})}),(0,l.jsx)(L.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})}),(0,l.jsx)(L.Z.Item,{label:"Duration (eg: 30s, 30h, 30d)",name:"duration",children:(0,l.jsx)(z.Z,{})}),(0,l.jsx)(L.Z.Item,{label:"Metadata",name:"metadata",children:(0,l.jsx)(z.Z.TextArea,{rows:4,placeholder:"Enter metadata as JSON"})}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(W.ZP,{htmlType:"submit",children:"Create User"})})]})}),d&&(0,l.jsxs)(B.Z,{title:"Save Your User",visible:n,onOk:p,onCancel:j,footer:null,children:[(0,l.jsxs)("p",{children:["Please save this secret user somewhere safe and accessible. For security reasons, ",(0,l.jsx)("b",{children:"you will not be able to view it again"})," ","through your LiteLLM account. If you lose this secret user, you will need to generate a new one."]}),(0,l.jsx)("p",{children:null!=d?"API user: ".concat(d):"User being created, this might take 30s"})]})]})},e_=e=>{let{accessToken:t,token:s,keys:a,userRole:n,userID:o,setKeys:i}=e,[c,d]=(0,r.useState)(null),[h,m]=(0,r.useState)(null),[x,p]=(0,r.useState)(1);if((0,r.useEffect)(()=>{if(!t||!s||!n||!o)return;let e=async()=>{try{let e=await u(t,null,n,!0);console.log("user data response:",e),d(e)}catch(e){console.error("There was an error fetching the model data",e)}};t&&s&&n&&o&&!c&&e();let l=async()=>{try{let e=await _(t,null);console.log("user data response:",e),m(e)}catch(e){console.error("There was an error fetching the model data",e)}};n&&("Admin"==n||"Admin Viewer"==n)&&!h&&l()},[t,s,n,o]),!c||!t||!s||!n||!o)return(0,l.jsx)("div",{children:"Loading..."});let j=async e=>{try{let s=await _(t,e);console.log("user data response:",s),m(s)}catch(e){console.error("There was an error fetching the model data",e)}};return(0,l.jsx)("div",{style:{width:"100%"},children:(0,l.jsxs)(O.Z,{className:"gap-2 p-10 h-[75vh] w-full",children:[(0,l.jsx)(ek,{userID:o,accessToken:t}),(0,l.jsx)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh] mb-4",children:(0,l.jsxs)(ey.Z,{children:[(0,l.jsxs)(eg.Z,{variant:"line",defaultValue:"1",children:[(0,l.jsx)(ej.Z,{value:"1",children:"Key Owners"}),(0,l.jsx)(ej.Z,{value:"2",children:"End-Users"})]}),(0,l.jsxs)(eZ.Z,{children:[(0,l.jsx)(ew.Z,{children:(0,l.jsxs)($.Z,{className:"mt-5",children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"User ID"}),(0,l.jsx)(Q.Z,{children:"User Role"}),(0,l.jsx)(Q.Z,{children:"User Models"}),(0,l.jsx)(Q.Z,{children:"User Spend ($ USD)"}),(0,l.jsx)(Q.Z,{children:"User Max Budget ($ USD)"})]})}),(0,l.jsx)(H.Z,{children:c.map(e=>(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{children:e.user_id}),(0,l.jsx)(Y.Z,{children:e.user_role?e.user_role:"app_owner"}),(0,l.jsx)(Y.Z,{children:e.models&&e.models.length>0?e.models:"All Models"}),(0,l.jsx)(Y.Z,{children:e.spend?e.spend:0}),(0,l.jsx)(Y.Z,{children:e.max_budget?e.max_budget:"Unlimited"})]},e.user_id))})]})}),(0,l.jsxs)(ew.Z,{children:[(0,l.jsxs)("div",{className:"flex items-center",children:[(0,l.jsx)("div",{className:"flex-1"}),(0,l.jsxs)("div",{className:"flex-1 flex justify-between items-center",children:[(0,l.jsx)(R.Z,{className:"w-1/4 mr-2 text-right",children:"Key"}),(0,l.jsx)(eo.Z,{defaultValue:"1",className:"w-3/4",children:null==a?void 0:a.map((e,t)=>{if(e&&null!==e.key_name&&e.key_name.length>0)return(0,l.jsx)(ei.Z,{value:String(t),onClick:()=>j(e.token),children:e.key_name},t)})})]})]}),(0,l.jsxs)($.Z,{children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"End User"}),(0,l.jsx)(Q.Z,{children:"Spend"}),(0,l.jsx)(Q.Z,{children:"Total Events"})]})}),(0,l.jsx)(H.Z,{children:null==h?void 0:h.map((e,t)=>(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{children:e.end_user}),(0,l.jsx)(Y.Z,{children:e.total_spend}),(0,l.jsx)(Y.Z,{children:e.total_events})]},t))})]})]})]})]})}),function(){if(!c)return null;let e=Math.ceil(c.length/25),t=Math.min(25*x,c.length);return(0,l.jsxs)("div",{className:"flex justify-between items-center",children:[(0,l.jsxs)("div",{children:["Showing ",(x-1)*25+1," – ",t," of ",c.length]}),(0,l.jsxs)("div",{className:"flex",children:[(0,l.jsx)("button",{className:"bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-l focus:outline-none",disabled:1===x,onClick:()=>p(x-1),children:"← Prev"}),(0,l.jsx)("button",{className:"bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-r focus:outline-none",disabled:x===e,onClick:()=>p(x+1),children:"Next →"})]})]})}()]})})},eb=e=>{let{teams:t,searchParams:s,accessToken:a,setTeams:n,userID:i,userRole:d}=e,[h]=L.Z.useForm(),[m]=L.Z.useForm(),{Title:u,Paragraph:x}=en.default,[p,j]=(0,r.useState)(""),[g,w]=(0,r.useState)(t?t[0]:null),[Z,f]=(0,r.useState)(!1),[k,_]=(0,r.useState)(!1),[b,v]=(0,r.useState)([]);(0,r.useEffect)(()=>{(async()=>{try{if(null===i||null===d)return;if(null!==a){let e=(await y(a,i,d)).data.map(e=>e.id);console.log("available_model_names:",e),v(e)}}catch(e){console.error("Error fetching user models:",e)}})()},[a,i,d]);let S=async e=>{try{if(null!=a){let s=await C(a,e);null!==t?n([...t,s]):n([s]),console.log("response for team create call: ".concat(s)),c.ZP.success("Team created"),f(!1)}}catch(e){console.error("Error creating the key:",e),c.ZP.error("Error creating the team: "+e)}},N=async e=>{try{if(null!=a&&null!=t){c.ZP.info("Making API Call");let s={role:"user",user_email:e.user_email,user_id:e.user_id},l=await T(a,g.team_id,s);console.log("response for team create call: ".concat(l.data));let r=t.findIndex(e=>(console.log("team.team_id=".concat(e.team_id,"; response.data.team_id=").concat(l.data.team_id)),e.team_id===l.data.team_id));if(console.log("foundIndex: ".concat(r)),-1!==r){let e=[...t];e[r]=l.data,n(e),w(l.data)}_(!1)}}catch(e){console.error("Error creating the key:",e)}};return console.log("received teams ".concat(t)),(0,l.jsx)("div",{className:"w-full mx-4",children:(0,l.jsxs)(O.Z,{numItems:1,className:"gap-2 p-2 h-[75vh] w-full",children:[(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(u,{level:4,children:"All Teams"}),(0,l.jsx)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,l.jsxs)($.Z,{children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"Team Name"}),(0,l.jsx)(Q.Z,{children:"Spend (USD)"}),(0,l.jsx)(Q.Z,{children:"Budget (USD)"}),(0,l.jsx)(Q.Z,{children:"Models"}),(0,l.jsx)(Q.Z,{children:"TPM / RPM Limits"})]})}),(0,l.jsx)(H.Z,{children:t&&t.length>0?t.map(e=>(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:e.team_alias}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:e.spend}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:e.max_budget?e.max_budget:"No limit"}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:JSON.stringify(e.models?e.models:[])})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsxs)(R.Z,{children:["TPM Limit:"," ",e.tpm_limit?e.tpm_limit:"Unlimited"," ",(0,l.jsx)("br",{}),"RPM Limit:"," ",e.rpm_limit?e.rpm_limit:"Unlimited"]})})]},e.team_id)):null})]})})]}),(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(o.Z,{className:"mx-auto",onClick:()=>f(!0),children:"+ Create New Team"}),(0,l.jsx)(B.Z,{title:"Create Team",visible:Z,width:800,footer:null,onOk:()=>{f(!1),h.resetFields()},onCancel:()=>{f(!1),h.resetFields()},children:(0,l.jsxs)(L.Z,{form:h,onFinish:S,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(L.Z.Item,{label:"Team Name",name:"team_alias",children:(0,l.jsx)(z.Z,{})}),(0,l.jsx)(L.Z.Item,{label:"Models",name:"models",children:(0,l.jsx)(U.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:b.map(e=>(0,l.jsx)(U.default.Option,{value:e,children:e},e))})}),(0,l.jsx)(L.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,l.jsx)(K.Z,{step:.01,precision:2,width:200})}),(0,l.jsx)(L.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})}),(0,l.jsx)(L.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})})]}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(W.ZP,{htmlType:"submit",children:"Create Team"})})]})})]}),(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(u,{level:4,children:"Team Members"}),(0,l.jsx)(x,{children:"If you belong to multiple teams, this setting controls which teams members you see."}),t&&t.length>0?(0,l.jsx)(eo.Z,{defaultValue:"0",children:t.map((e,t)=>(0,l.jsx)(ei.Z,{value:String(t),onClick:()=>{w(e)},children:e.team_alias},t))}):(0,l.jsxs)(x,{children:["No team created. ",(0,l.jsx)("b",{children:"Defaulting to personal account."})]})]}),(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsx)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,l.jsxs)($.Z,{children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"Member Name"}),(0,l.jsx)(Q.Z,{children:"Role"})]})}),(0,l.jsx)(H.Z,{children:g?g.members_with_roles.map((e,t)=>(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{children:e.user_email?e.user_email:e.user_id?e.user_id:null}),(0,l.jsx)(Y.Z,{children:e.role})]},t)):null})]})})}),(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(o.Z,{className:"mx-auto mb-5",onClick:()=>_(!0),children:"+ Add member"}),(0,l.jsx)(B.Z,{title:"Add member",visible:k,width:800,footer:null,onOk:()=>{_(!1),m.resetFields()},onCancel:()=>{_(!1),m.resetFields()},children:(0,l.jsxs)(L.Z,{form:h,onFinish:N,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(L.Z.Item,{label:"Email",name:"user_email",className:"mb-4",children:(0,l.jsx)(z.Z,{name:"user_email",className:"px-3 py-2 border rounded-md w-full"})}),(0,l.jsx)("div",{className:"text-center mb-4",children:"OR"}),(0,l.jsx)(L.Z.Item,{label:"User ID",name:"user_id",className:"mb-4",children:(0,l.jsx)(z.Z,{name:"user_id",className:"px-3 py-2 border rounded-md w-full"})})]}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(W.ZP,{htmlType:"submit",children:"Add member"})})]})})]})]})})},ev=s(8510),eS=e=>{let{searchParams:t,accessToken:s}=e,[a]=L.Z.useForm(),[n]=L.Z.useForm(),{Title:i,Paragraph:d}=en.default,[h,m]=(0,r.useState)(""),[u,x]=(0,r.useState)(null),[p,j]=(0,r.useState)(!1);(0,r.useEffect)(()=>{(async()=>{if(null!=s){let e=[],t=await A(s,"proxy_admin_viewer");t.forEach(t=>{e.push({user_role:t.user_role,user_id:t.user_id,user_email:t.user_email})}),console.log("proxy viewers: ".concat(t));let l=await A(s,"proxy_admin");l.forEach(t=>{e.push({user_role:t.user_role,user_id:t.user_id,user_email:t.user_email})}),console.log("proxy admins: ".concat(l)),console.log("combinedList: ".concat(e)),x(e)}})()},[s]);let y=async e=>{try{if(null!=s&&null!=u){c.ZP.info("Making API Call"),e.user_email,e.user_id;let t=await I(s,e);console.log("response for team create call: ".concat(t));let l=u.findIndex(e=>(console.log("user.user_id=".concat(e.user_id,"; response.user_id=").concat(t.user_id)),e.user_id===t.user_id));console.log("foundIndex: ".concat(l)),-1==l&&(console.log("updates admin with new user"),u.push(t),x(u)),j(!1)}}catch(e){console.error("Error creating the key:",e)}};return console.log("admins: ".concat(null==u?void 0:u.length)),(0,l.jsxs)("div",{className:"w-full m-2",children:[(0,l.jsx)(i,{level:4,children:"Restricted Access"}),(0,l.jsxs)(d,{children:["Add other people to just view spend. They cannot create keys, teams or grant users access to new models."," ",(0,l.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/ui#restrict-ui-access",children:"Requires SSO Setup"})]}),(0,l.jsxs)(O.Z,{numItems:1,className:"gap-2 p-0 w-full",children:[(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsx)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,l.jsxs)($.Z,{children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"Member Name"}),(0,l.jsx)(Q.Z,{children:"Role"}),(0,l.jsx)(Q.Z,{children:"Action"})]})}),(0,l.jsx)(H.Z,{children:u?u.map((e,t)=>(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{children:e.user_email?e.user_email:e.user_id?e.user_id:null}),(0,l.jsx)(Y.Z,{children:e.user_role}),(0,l.jsx)(Y.Z,{children:(0,l.jsx)(G.Z,{icon:ev.Z,size:"sm"})})]},t)):null})]})})}),(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(o.Z,{className:"mx-auto mb-5",onClick:()=>j(!0),children:"+ Add viewer"}),(0,l.jsx)(B.Z,{title:"Add viewer",visible:p,width:800,footer:null,onOk:()=>{j(!1),n.resetFields()},onCancel:()=>{j(!1),n.resetFields()},children:(0,l.jsxs)(L.Z,{form:a,onFinish:y,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(L.Z.Item,{label:"Email",name:"user_email",className:"mb-4",children:(0,l.jsx)(z.Z,{name:"user_email",className:"px-3 py-2 border rounded-md w-full"})}),(0,l.jsx)("div",{className:"text-center mb-4",children:"OR"}),(0,l.jsx)(L.Z.Item,{label:"User ID",name:"user_id",className:"mb-4",children:(0,l.jsx)(z.Z,{name:"user_id",className:"px-3 py-2 border rounded-md w-full"})})]}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(W.ZP,{htmlType:"submit",children:"Add member"})})]})})]})]})]})},eN=s(12968),eA=s(67951);async function eC(e,t,s,l){console.log("isLocal:",!1);let r=window.location.origin,a=new eN.ZP.OpenAI({apiKey:l,baseURL:r,dangerouslyAllowBrowser:!0});for await(let l of(await a.chat.completions.create({model:s,stream:!0,messages:[{role:"user",content:e}]})))console.log(l),l.choices[0].delta.content&&t(l.choices[0].delta.content)}var eT=e=>{let{accessToken:t,token:s,userRole:a,userID:n}=e,[o,i]=(0,r.useState)(""),[c,d]=(0,r.useState)([]),[h,m]=(0,r.useState)(void 0),[u,x]=(0,r.useState)(null);(0,r.useEffect)(()=>{t&&s&&a&&n&&(async()=>{let e=await y(t,n,a);console.log("model_info:",e),(null==e?void 0:e.data.length)>0&&(x(e.data),m(e.data[0].id))})()},[t,n,a]);let p=(e,t)=>{d(s=>{let l=s[s.length-1];return l&&l.role===e?[...s.slice(0,s.length-1),{role:e,content:l.content+t}]:[...s,{role:e,content:t}]})},j=async()=>{if(""!==o.trim()&&t&&s&&a&&n){d(e=>[...e,{role:"user",content:o}]);try{h&&await eC(o,e=>p("assistant",e),h,t)}catch(e){console.error("Error fetching model response",e),p("assistant","Error fetching model response")}i("")}};if(a&&"Admin Viewer"==a){let{Title:e,Paragraph:t}=en.default;return(0,l.jsxs)("div",{children:[(0,l.jsx)(e,{level:1,children:"Access Denied"}),(0,l.jsx)(t,{children:"Ask your proxy admin for access to test models"})]})}return(0,l.jsx)("div",{style:{width:"100%",position:"relative"},children:(0,l.jsx)(O.Z,{className:"gap-2 p-10 h-[75vh] w-full",children:(0,l.jsx)(M.Z,{children:(0,l.jsxs)(ey.Z,{children:[(0,l.jsxs)(eg.Z,{className:"mt-4",children:[(0,l.jsx)(ej.Z,{children:"Chat"}),(0,l.jsx)(ej.Z,{children:"API Reference"})]}),(0,l.jsxs)(eZ.Z,{children:[(0,l.jsxs)(ew.Z,{children:[(0,l.jsxs)("div",{children:[(0,l.jsx)("label",{children:"Select Model:"}),(0,l.jsx)("select",{value:h||"",onChange:e=>m(e.target.value),children:null==u?void 0:u.map(e=>(0,l.jsx)("option",{value:e.id,children:e.id},e.id))})]}),(0,l.jsxs)($.Z,{className:"mt-5",style:{display:"block",maxHeight:"60vh",overflowY:"auto"},children:[(0,l.jsx)(X.Z,{children:(0,l.jsx)(ee.Z,{children:(0,l.jsx)(Y.Z,{children:(0,l.jsx)(D.Z,{children:"Chat"})})})}),(0,l.jsx)(H.Z,{children:c.map((e,t)=>(0,l.jsx)(ee.Z,{children:(0,l.jsx)(Y.Z,{children:"".concat(e.role,": ").concat(e.content)})},t))})]}),(0,l.jsx)("div",{className:"mt-3",style:{position:"absolute",bottom:5,width:"95%"},children:(0,l.jsxs)("div",{className:"flex",children:[(0,l.jsx)("input",{type:"text",value:o,onChange:e=>i(e.target.value),className:"flex-1 p-2 border rounded-md mr-2",placeholder:"Type your message..."}),(0,l.jsx)("button",{onClick:j,className:"p-2 bg-blue-500 text-white rounded-md",children:"Send"})]})})]}),(0,l.jsx)(ew.Z,{children:(0,l.jsxs)(ey.Z,{children:[(0,l.jsxs)(eg.Z,{children:[(0,l.jsx)(ej.Z,{children:"OpenAI Python SDK"}),(0,l.jsx)(ej.Z,{children:"LlamaIndex"}),(0,l.jsx)(ej.Z,{children:"Langchain Py"})]}),(0,l.jsxs)(eZ.Z,{children:[(0,l.jsx)(ew.Z,{children:(0,l.jsx)(eA.Z,{language:"python",children:'\nimport openai\nclient = openai.OpenAI(\n api_key="your_api_key",\n base_url="http://0.0.0.0:4000" # proxy base url\n)\n\nresponse = client.chat.completions.create(\n model="gpt-3.5-turbo", # model to use from Models Tab\n messages = [\n {\n "role": "user",\n "content": "this is a test request, write a short poem"\n }\n ],\n extra_body={\n "metadata": {\n "generation_name": "ishaan-generation-openai-client",\n "generation_id": "openai-client-gen-id22",\n "trace_id": "openai-client-trace-id22",\n "trace_user_id": "openai-client-user-id2"\n }\n }\n)\n\nprint(response)\n '})}),(0,l.jsx)(ew.Z,{children:(0,l.jsx)(eA.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="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,l.jsx)(ew.Z,{children:(0,l.jsx)(eA.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:8000",\n model = "gpt-3.5-turbo",\n temperature=0.1,\n extra_body={\n "metadata": {\n "generation_name": "ishaan-generation-langchain-client",\n "generation_id": "langchain-client-gen-id22",\n "trace_id": "langchain-client-trace-id22",\n "trace_user_id": "langchain-client-user-id2"\n }\n }\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 '})})]})]})})]})]})})})})},eI=s(33509),eP=s(30569);let{Sider:eE}=eI.default;var eF=e=>{let{setPage:t,userRole:s,defaultSelectedKey:r}=e;return"Admin Viewer"==s?(0,l.jsx)(eI.default,{style:{minHeight:"100vh",maxWidth:"120px"},children:(0,l.jsx)(eE,{width:120,children:(0,l.jsxs)(eP.Z,{mode:"inline",defaultSelectedKeys:r||["4"],style:{height:"100%",borderRight:0},children:[(0,l.jsx)(eP.Z.Item,{onClick:()=>t("api-keys"),children:"API Keys"},"4"),(0,l.jsx)(eP.Z.Item,{onClick:()=>t("models"),children:"Models"},"2"),(0,l.jsx)(eP.Z.Item,{onClick:()=>t("llm-playground"),children:"Chat UI"},"3"),(0,l.jsx)(eP.Z.Item,{onClick:()=>t("usage"),children:"Usage"},"1")]})})}):(0,l.jsx)(eI.default,{style:{minHeight:"100vh",maxWidth:"120px"},children:(0,l.jsx)(eE,{width:120,children:(0,l.jsxs)(eP.Z,{mode:"inline",defaultSelectedKeys:r||["1"],style:{height:"100%",borderRight:0},children:[(0,l.jsx)(eP.Z.Item,{onClick:()=>t("api-keys"),children:"API Keys"},"1"),(0,l.jsx)(eP.Z.Item,{onClick:()=>t("models"),children:"Models"},"2"),(0,l.jsx)(eP.Z.Item,{onClick:()=>t("llm-playground"),children:"Chat UI"},"3"),(0,l.jsx)(eP.Z.Item,{onClick:()=>t("usage"),children:"Usage"},"4"),"Admin"==s?(0,l.jsx)(eP.Z.Item,{onClick:()=>t("users"),children:"Users"},"5"):null,"Admin"==s?(0,l.jsx)(eP.Z.Item,{onClick:()=>t("teams"),children:"Teams"},"6"):null,"Admin"==s?(0,l.jsx)(eP.Z.Item,{onClick:()=>t("admin-panel"),children:"Admin"},"7"):null]})})})},eO=e=>{let{accessToken:t,token:s,userRole:a,userID:n}=e,o=new Date,[i,c]=(0,r.useState)([]),[d,h]=(0,r.useState)([]),[m,u]=(0,r.useState)([]),[x,p]=(0,r.useState)([]),[j,y]=(0,r.useState)([]),[g,_]=(0,r.useState)([]),[S,N]=(0,r.useState)([]),A=new Date(o.getFullYear(),o.getMonth(),1),C=new Date(o.getFullYear(),o.getMonth()+1,0),T=P(A),I=P(C);function P(e){let t=e.getFullYear(),s=e.getMonth()+1,l=e.getDate();return"".concat(t,"-").concat(s<10?"0"+s:s,"-").concat(l<10?"0"+l:l)}return console.log("Start date is ".concat(T)),console.log("End date is ".concat(I)),(0,r.useEffect)(()=>{t&&s&&a&&n&&(async()=>{try{if(console.log("user role: ".concat(a)),"Admin"==a||"Admin Viewer"==a){let e=await f(t);c(e);let s=(await k(t)).map(e=>({key:(e.key_name||e.key_alias||e.api_key).substring(0,7),spend:e.total_spend}));h(s);let l=(await b(t)).map(e=>({key:e.model,spend:e.total_spend}));u(l);let r=await w(t);console.log("teamSpend",r),y(r.daily_spend),_(r.teams),N(r.total_spend_per_team)}else"App Owner"==a&&await Z(t,s,a,n,T,I).then(async e=>{if(console.log("result from spend logs call",e),"daily_spend"in e){let t=e.daily_spend;console.log("daily spend",t),c(t);let s=e.top_api_keys;h(s)}else{let s=(await v(t,function(e){let t=[];e.forEach(e=>{Object.entries(e).forEach(e=>{let[s,l]=e;"spend"!==s&&"startTime"!==s&&"models"!==s&&"users"!==s&&t.push({key:s,spend:l})})}),t.sort((e,t)=>Number(t.spend)-Number(e.spend));let s=t.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||e.token).substring(0,7),spend:e.spend}));h(s),p(function(e){let t={};e.forEach(e=>{Object.entries(e.users).forEach(e=>{let[s,l]=e;""!==s&&null!=s&&"None"!=s&&(t[s]||(t[s]=0),t[s]+=l)})});let s=Object.entries(t).map(e=>{let[t,s]=e;return{user_id:t,spend:s}});s.sort((e,t)=>t.spend-e.spend);let l=s.slice(0,5);return console.log("topKeys: ".concat(Object.values(l[0]))),l}(e)),c(e)}})}catch(e){console.error("There was an error fetching the data",e)}})()},[t,s,a,n,T,I]),(0,l.jsx)("div",{style:{width:"100%"},children:(0,l.jsxs)(ey.Z,{children:[(0,l.jsxs)(eg.Z,{className:"mt-4",children:[(0,l.jsx)(ej.Z,{children:"All Up"}),(0,l.jsx)(ej.Z,{children:"Team Based Usage"})]}),(0,l.jsxs)(eZ.Z,{children:[(0,l.jsx)(ew.Z,{children:(0,l.jsxs)(O.Z,{numItems:2,className:"gap-2 p-10 h-[75vh] w-full",children:[(0,l.jsx)(F.Z,{numColSpan:2,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Monthly Spend"}),(0,l.jsx)(et.Z,{data:i,index:"date",categories:["spend"],colors:["blue"],valueFormatter:e=>"$ ".concat(new Intl.NumberFormat("us").format(e).toString()),yAxisWidth:100,tickGap:5})]})}),(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Top API Keys"}),(0,l.jsx)(et.Z,{className:"mt-4 h-40",data:d,index:"key",categories:["spend"],colors:["blue"],yAxisWidth:80,tickGap:5,layout:"vertical",showXAxis:!1,showLegend:!1})]})}),(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Top Users"}),(0,l.jsx)(et.Z,{className:"mt-4 h-40",data:x,index:"user_id",categories:["spend"],colors:["blue"],yAxisWidth:200,layout:"vertical",showXAxis:!1,showLegend:!1})]})}),(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Top Models"}),(0,l.jsx)(et.Z,{className:"mt-4 h-40",data:m,index:"key",categories:["spend"],colors:["blue"],yAxisWidth:200,layout:"vertical",showXAxis:!1,showLegend:!1})]})})]})}),(0,l.jsx)(ew.Z,{children:(0,l.jsxs)(O.Z,{numItems:2,className:"gap-2 p-10 h-[75vh] w-full",children:[(0,l.jsx)(F.Z,{numColSpan:2,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Daily Spend Per Team"}),(0,l.jsx)(et.Z,{className:"h-72",data:j,index:"date",categories:g,yAxisWidth:30,stack:!0})]})}),(0,l.jsx)(F.Z,{numColSpan:2,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Total Spend Per Team"}),(0,l.jsx)(et.Z,{className:"h-72",data:S,index:"team_id",categories:["total_spend"],yAxisWidth:30})]})})]})})]})]})})},eM=()=>{let{Title:e,Paragraph:t}=en.default,[s,n]=(0,r.useState)(""),[o,c]=(0,r.useState)(null),[d,h]=(0,r.useState)(null),[m,u]=(0,r.useState)(null),[x,p]=(0,r.useState)(!0),j=(0,a.useSearchParams)(),y=j.get("userID"),g=j.get("token"),[w,Z]=(0,r.useState)("api-keys"),[f,k]=(0,r.useState)(null);return(0,r.useEffect)(()=>{if(g){let e=(0,ed.o)(g);if(e){if(console.log("Decoded token:",e),console.log("Decoded key:",e.key),k(e.key),e.user_role){let t=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"app_user":return"App User";default:return"Unknown Role"}}(e.user_role);console.log("Decoded user_role:",t),n(t),"Admin Viewer"==t&&Z("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?p("username_password"==e.login_method):console.log("User Email is not set ".concat(e))}}},[g]),(0,l.jsx)(r.Suspense,{fallback:(0,l.jsx)("div",{children:"Loading..."}),children:(0,l.jsxs)("div",{className:"flex flex-col min-h-screen",children:[(0,l.jsx)(i,{userID:y,userRole:s,userEmail:o,showSSOBanner:x}),(0,l.jsxs)("div",{className:"flex flex-1 overflow-auto",children:[(0,l.jsx)(eF,{setPage:Z,userRole:s,defaultSelectedKey:null}),"api-keys"==w?(0,l.jsx)(eh,{userID:y,userRole:s,teams:d,keys:m,setUserRole:n,userEmail:o,setUserEmail:c,setTeams:h,setKeys:u}):"models"==w?(0,l.jsx)(ep,{userID:y,userRole:s,token:g,accessToken:f}):"llm-playground"==w?(0,l.jsx)(eT,{userID:y,userRole:s,token:g,accessToken:f}):"users"==w?(0,l.jsx)(e_,{userID:y,userRole:s,token:g,keys:m,accessToken:f,setKeys:u}):"teams"==w?(0,l.jsx)(eb,{teams:d,setTeams:h,searchParams:j,accessToken:f,userID:y,userRole:s}):"admin-panel"==w?(0,l.jsx)(eS,{setTeams:h,searchParams:j,accessToken:f}):(0,l.jsx)(eO,{userID:y,userRole:s,token:g,accessToken:f})]})]})})}}},function(e){e.O(0,[730,971,69,744],function(){return e(e.s=20661)}),_N_E=e.O()}]); \ No newline at end of file +(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[931],{20661:function(e,t,s){Promise.resolve().then(s.bind(s,92182))},92182:function(e,t,s){"use strict";s.r(t),s.d(t,{default:function(){return eM}});var l=s(3827),r=s(64090),a=s(47907),n=s(8792),o=s(2179),i=e=>{let{userID:t,userRole:s,userEmail:r,showSSOBanner:a}=e;return console.log("User ID:",t),console.log("userEmail:",r),(0,l.jsxs)("nav",{className:"left-0 right-0 top-0 flex justify-between items-center h-12 mb-4",children:[(0,l.jsx)("div",{className:"text-left my-2 absolute top-0 left-0",children:(0,l.jsx)("div",{className:"flex flex-col items-center",children:(0,l.jsx)(n.default,{href:"/",children:(0,l.jsx)("button",{className:"text-gray-800 text-2xl py-1 rounded text-center",children:(0,l.jsx)("img",{src:"/get_image",width:200,height:200,alt:"LiteLLM Brand",className:"mr-2"})})})})}),(0,l.jsxs)("div",{className:"text-right mx-4 my-2 absolute top-0 right-0 flex items-center justify-end space-x-2",children:[a?(0,l.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/ui#setup-ssoauth-for-ui",target:"_blank",className:"mr-2"}):null,(0,l.jsxs)(o.Z,{variant:"secondary",size:"lg",children:[r,(0,l.jsxs)("p",{children:["Role: ",s]}),(0,l.jsxs)("p",{children:["ID: ",t]})]})]})]})},c=s(80588);let d=async(e,t,s)=>{try{if(console.log("Form Values in keyCreateCall:",s),s.description&&(s.metadata||(s.metadata={}),s.metadata.description=s.description,delete s.description,s.metadata=JSON.stringify(s.metadata)),s.metadata){console.log("formValues.metadata:",s.metadata);try{s.metadata=JSON.parse(s.metadata)}catch(e){throw c.ZP.error("Failed to parse metadata: "+e),Error("Failed to parse metadata: "+e)}}console.log("Form Values after check:",s);let l=await fetch("/key/generate",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({user_id:t,...s})});if(!l.ok){let e=await l.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let r=await l.json();return console.log("API Response:",r),r}catch(e){throw console.error("Failed to create key:",e),e}},h=async(e,t,s)=>{try{if(console.log("Form Values in keyCreateCall:",s),s.description&&(s.metadata||(s.metadata={}),s.metadata.description=s.description,delete s.description,s.metadata=JSON.stringify(s.metadata)),s.metadata){console.log("formValues.metadata:",s.metadata);try{s.metadata=JSON.parse(s.metadata)}catch(e){throw c.ZP.error("Failed to parse metadata: "+e),Error("Failed to parse metadata: "+e)}}console.log("Form Values after check:",s);let l=await fetch("/user/new",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({user_id:t,...s})});if(!l.ok){let e=await l.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let r=await l.json();return console.log("API Response:",r),r}catch(e){throw console.error("Failed to create key:",e),e}},m=async(e,t)=>{try{console.log("in keyDeleteCall:",t);let s=await fetch("/key/delete",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({keys:[t]})});if(!s.ok){let e=await s.text();throw c.ZP.error("Failed to delete key: "+e),Error("Network response was not ok")}let l=await s.json();return console.log(l),l}catch(e){throw console.error("Failed to create key:",e),e}},u=async function(e,t,s){let l=arguments.length>3&&void 0!==arguments[3]&&arguments[3];try{let r="/user/info";"App Owner"==s&&t&&(r="".concat(r,"?user_id=").concat(t)),console.log("in userInfoCall viewAll=",l),l&&(r="".concat(r,"?view_all=true"));let a=await fetch(r,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!a.ok){let e=await a.text();throw c.ZP.error(e),Error("Network response was not ok")}let n=await a.json();return console.log("API Response:",n),n}catch(e){throw console.error("Failed to create key:",e),e}},x=async e=>{try{let t=await fetch("/global/spend",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},p=async(e,t,s)=>{try{let t=await fetch("/v2/model/info",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},j=async(e,t,s)=>{try{let t=await fetch("/model/metrics",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},y=async(e,t,s)=>{try{let t=await fetch("/models",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},g=async(e,t)=>{try{let s="/global/spend/logs";console.log("in keySpendLogsCall:",s);let l=await fetch("".concat(s,"?api_key=").concat(t),{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw c.ZP.error(e),Error("Network response was not ok")}let r=await l.json();return console.log(r),r}catch(e){throw console.error("Failed to create key:",e),e}},w=async e=>{try{let t="/global/spend/teams";console.log("in teamSpendLogsCall:",t);let s=await fetch("".concat(t),{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!s.ok){let e=await s.text();throw c.ZP.error(e),Error("Network response was not ok")}let l=await s.json();return console.log(l),l}catch(e){throw console.error("Failed to create key:",e),e}},Z=async(e,t,s,l,r,a)=>{try{console.log("user role in spend logs call: ".concat(s));let t="/spend/logs";t="App Owner"==s?"".concat(t,"?user_id=").concat(l,"&start_date=").concat(r,"&end_date=").concat(a):"".concat(t,"?start_date=").concat(r,"&end_date=").concat(a);let n=await fetch(t,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!n.ok){let e=await n.text();throw c.ZP.error(e),Error("Network response was not ok")}let o=await n.json();return console.log(o),o}catch(e){throw console.error("Failed to create key:",e),e}},f=async e=>{try{let t=await fetch("/global/spend/logs",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to create key:",e),e}},k=async e=>{try{let t=await fetch("/global/spend/keys?limit=5",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to create key:",e),e}},_=async(e,t)=>{try{t&&JSON.stringify({api_key:t});let s={method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}};t&&(s.body=JSON.stringify({api_key:t}));let l=await fetch("/global/spend/end_users",s);if(!l.ok){let e=await l.text();throw c.ZP.error(e),Error("Network response was not ok")}let r=await l.json();return console.log(r),r}catch(e){throw console.error("Failed to create key:",e),e}},b=async e=>{try{let t=await fetch("/global/spend/models?limit=5",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to create key:",e),e}},v=async(e,t)=>{try{let s=await fetch("/v2/key/info",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({keys:t})});if(!s.ok){let e=await s.text();throw c.ZP.error(e),Error("Network response was not ok")}let l=await s.json();return console.log(l),l}catch(e){throw console.error("Failed to create key:",e),e}},S=async(e,t,s,l)=>{try{let r=await fetch("/user/request_model",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({models:[t],user_id:s,justification:l})});if(!r.ok){let e=await r.text();throw c.ZP.error("Failed to delete key: "+e),Error("Network response was not ok")}let a=await r.json();return console.log(a),a}catch(e){throw console.error("Failed to create key:",e),e}},N=async e=>{try{let t="/user/get_requests";console.log("in userGetRequesedtModelsCall:",t);let s=await fetch(t,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!s.ok){let e=await s.text();throw c.ZP.error("Failed to delete key: "+e),Error("Network response was not ok")}let l=await s.json();return console.log(l),l}catch(e){throw console.error("Failed to get requested models:",e),e}},A=async(e,t)=>{try{let s="/user/get_users?role=".concat(t);console.log("in userGetAllUsersCall:",s);let l=await fetch(s,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw c.ZP.error("Failed to delete key: "+e),Error("Network response was not ok")}let r=await l.json();return console.log(r),r}catch(e){throw console.error("Failed to get requested models:",e),e}},C=async(e,t)=>{try{console.log("Form Values in teamCreateCall:",t);let s=await fetch("/team/new",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...t})});if(!s.ok){let e=await s.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let l=await s.json();return console.log("API Response:",l),l}catch(e){throw console.error("Failed to create key:",e),e}},T=async(e,t,s)=>{try{console.log("Form Values in teamMemberAddCall:",s);let l=await fetch("/team/member_add",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({team_id:t,member:s})});if(!l.ok){let e=await l.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let r=await l.json();return console.log("API Response:",r),r}catch(e){throw console.error("Failed to create key:",e),e}},I=async(e,t)=>{try{console.log("Form Values in userUpdateUserCall:",t);let s=await fetch("/user/update",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({user_role:"proxy_admin_viewer",...t})});if(!s.ok){let e=await s.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let l=await s.json();return console.log("API Response:",l),l}catch(e){throw console.error("Failed to create key:",e),e}},P=async(e,t)=>{try{let s=await fetch("/global/predict/spend/logs",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({data:t})});if(!s.ok){let e=await s.text();throw c.ZP.error(e),Error("Network response was not ok")}let l=await s.json();return console.log(l),l}catch(e){throw console.error("Failed to create key:",e),e}},E=async e=>{try{console.log("Checking Slack Budget Alerts service health");let t=await fetch("/health/services?service=slack_budget_alerts",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error("Failed Slack Alert test: "+e),Error(e)}let s=await t.json();return c.ZP.success("Test Slack Alert worked - check your Slack!"),console.log("Service Health Response:",s),s}catch(e){throw console.error("Failed to perform health check:",e),e}};var F=s(10384),O=s(46453),M=s(13810),R=s(71801),D=s(42440),U=s(17189),L=s(12143),B=s(77171),z=s(42539),K=s(88707),W=s(1861);let{Option:V}=U.default;var q=e=>{let{userID:t,teamID:s,userRole:a,accessToken:n,data:i,userModels:h,setData:m}=e,[u]=L.Z.useForm(),[x,p]=(0,r.useState)(!1),[j,y]=(0,r.useState)(null),[g,w]=(0,r.useState)(null),Z=()=>{p(!1),u.resetFields()},f=()=>{p(!1),y(null),u.resetFields()},k=async e=>{try{c.ZP.info("Making API Call"),p(!0);let s=await d(n,t,e);console.log("key create Response:",s),m(e=>e?[...e,s]:[s]),y(s.key),w(s.soft_budget),c.ZP.success("API Key Created"),u.resetFields(),localStorage.removeItem("userData"+t)}catch(e){console.error("Error creating the key:",e)}},_=async()=>{try{console.log("Sending Slack alert...");let e=await E(n);console.log("slackBudgetAlertsHealthCheck Response:",e),console.log("Testing Slack alert successful")}catch(e){console.error("Error sending Slack alert:",e)}};return(0,l.jsxs)("div",{children:[(0,l.jsx)(o.Z,{className:"mx-auto",onClick:()=>p(!0),children:"+ Create New Key"}),(0,l.jsx)(B.Z,{title:"Create Key",visible:x,width:800,footer:null,onOk:Z,onCancel:f,children:(0,l.jsxs)(L.Z,{form:u,onFinish:k,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:["App Owner"===a||"Admin"===a?(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(L.Z.Item,{label:"Key Name",name:"key_alias",children:(0,l.jsx)(z.Z,{})}),(0,l.jsx)(L.Z.Item,{label:"Team ID",name:"team_id",children:(0,l.jsx)(z.Z,{placeholder:"ai_team",defaultValue:s||""})}),(0,l.jsx)(L.Z.Item,{label:"Models",name:"models",children:(0,l.jsx)(U.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:h.map(e=>(0,l.jsx)(V,{value:e,children:e},e))})}),(0,l.jsx)(L.Z.Item,{label:"Soft Budget (USD) Monthly",name:"soft_budget",initialValue:50,children:(0,l.jsx)(K.Z,{step:.01,precision:2,defaultValue:50,width:200})}),(0,l.jsx)(L.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,l.jsx)(K.Z,{step:.01,precision:2,width:200})}),(0,l.jsx)(L.Z.Item,{label:"Reset Budget",name:"budget_duration",children:(0,l.jsxs)(U.default,{defaultValue:null,placeholder:"n/a",children:[(0,l.jsx)(U.default.Option,{value:"24h",children:"daily"}),(0,l.jsx)(U.default.Option,{value:"30d",children:"monthly"})]})}),(0,l.jsx)(L.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})}),(0,l.jsx)(L.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})}),(0,l.jsx)(L.Z.Item,{label:"Expire Key (eg: 30s, 30h, 30d)",name:"duration",children:(0,l.jsx)(z.Z,{})}),(0,l.jsx)(L.Z.Item,{label:"Metadata",name:"metadata",children:(0,l.jsx)(z.Z.TextArea,{rows:4,placeholder:"Enter metadata as JSON"})})]}):(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(L.Z.Item,{label:"Key Name",name:"key_alias",children:(0,l.jsx)(z.Z,{})}),(0,l.jsx)(L.Z.Item,{label:"Team ID (Contact Group)",name:"team_id",children:(0,l.jsx)(z.Z,{placeholder:"ai_team"})}),(0,l.jsx)(L.Z.Item,{label:"Description",name:"description",children:(0,l.jsx)(z.Z.TextArea,{placeholder:"Enter description",rows:4})})]}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(W.ZP,{htmlType:"submit",children:"Create Key"})})]})}),j&&(0,l.jsx)(B.Z,{visible:x,onOk:Z,onCancel:f,footer:null,children:(0,l.jsx)(O.Z,{numItems:1,className:"gap-2 w-full",children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Save your Key"}),(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsxs)("p",{children:["Please save this secret key somewhere safe and accessible. For security reasons, ",(0,l.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,l.jsx)(F.Z,{numColSpan:1,children:null!=j?(0,l.jsxs)("div",{children:[(0,l.jsxs)(R.Z,{children:["API Key: ",j]}),(0,l.jsx)(D.Z,{className:"mt-6",children:"Budgets"}),(0,l.jsxs)(R.Z,{children:["Soft Limit Budget: $",g]}),(0,l.jsx)(o.Z,{className:"mt-3",onClick:_,children:"Test Slack Alert"}),(0,l.jsxs)(R.Z,{className:"mt-2",children:["(LiteLLM Docs -",(0,l.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/alerting",target:"_blank",className:"text-blue-500",children:"Set Up Slack Alerting)"})]})]}):(0,l.jsx)(R.Z,{children:"Key being created, this might take 30s"})})]})})})]})},J=s(33393),G=s(61244),$=s(10827),H=s(3851),Y=s(2044),X=s(64167),Q=s(74480),ee=s(7178),et=s(9853),es=s(56863),el=e=>{let{token:t,accessToken:s,keySpend:a,keyBudget:n,keyName:i}=e,[c,d]=(0,r.useState)(!1),[h,m]=(0,r.useState)(null),[u,x]=(0,r.useState)(""),[p,j]=(0,r.useState)(null),y=async()=>{try{if(null==s||null==t)return;console.log("accessToken: ".concat(s,"; token: ").concat(t));let e=await g(s,t);console.log("Response:",e),m(e);let l=await P(s,e);console.log("Response2:",l);let r=[...e,...l.response];m(r),x(l.predicted_spend),console.log("Combined Data:",r)}catch(e){console.error("There was an error fetching the data",e)}};return t?(0,l.jsxs)("div",{children:[(0,l.jsx)(o.Z,{size:"xs",onClick:()=>{console.log("Show Modal triggered"),d(!0),y()},variant:"secondary",children:"Spend Report"}),(0,l.jsxs)(B.Z,{visible:c,width:1400,onOk:()=>{d(!1)},onCancel:()=>{d(!1)},footer:null,children:[(0,l.jsxs)(D.Z,{style:{textAlign:"left"},children:["Key Name: ",i]}),(0,l.jsxs)(es.Z,{children:["Monthly Spend $",a]}),(0,l.jsx)(D.Z,{children:u}),(0,l.jsx)(M.Z,{className:"mt-6 mb-6",children:h&&(0,l.jsx)(et.Z,{className:"mt-6",data:h,colors:["blue","amber"],index:"date",categories:["spend","predicted_spend"],yAxisWidth:80})})]})]}):null},er=e=>{let{userID:t,accessToken:s,data:a,setData:n}=e,[i,c]=(0,r.useState)(!1),[d,h]=(0,r.useState)(!1),[u,x]=(0,r.useState)(null),p=async e=>{null!=a&&(x(e),localStorage.removeItem("userData"+t),h(!0))},j=async()=>{if(null!=u&&null!=a){try{await m(s,u);let e=a.filter(e=>e.token!==u);n(e)}catch(e){console.error("Error deleting the key:",e)}h(!1),x(null)}};if(null!=a)return console.log("RERENDER TRIGGERED"),(0,l.jsxs)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh] mb-4",children:[(0,l.jsxs)($.Z,{className:"mt-5",children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"Key Alias"}),(0,l.jsx)(Q.Z,{children:"Secret Key"}),(0,l.jsx)(Q.Z,{children:"Spend (USD)"}),(0,l.jsx)(Q.Z,{children:"Key Budget (USD)"}),(0,l.jsx)(Q.Z,{children:"Spend Report"}),(0,l.jsx)(Q.Z,{children:"Team ID"}),(0,l.jsx)(Q.Z,{children:"Metadata"}),(0,l.jsx)(Q.Z,{children:"Models"}),(0,l.jsx)(Q.Z,{children:"TPM / RPM Limits"}),(0,l.jsx)(Q.Z,{children:"Expires"})]})}),(0,l.jsx)(H.Z,{children:a.map(e=>(console.log(e),"litellm-dashboard"===e.team_id)?null:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",whiteSpace:"pre-wrap",overflow:"hidden"},children:null!=e.key_alias?(0,l.jsx)(R.Z,{children:e.key_alias}):(0,l.jsx)(R.Z,{children:"Not Set"})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:e.key_name})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:(()=>{try{return parseFloat(e.spend).toFixed(4)}catch(t){return e.spend}})()})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",whiteSpace:"pre-wrap",overflow:"hidden"},children:null!=e.max_budget?(0,l.jsx)(R.Z,{children:e.max_budget}):(0,l.jsx)(R.Z,{children:"Unlimited Budget"})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px"},children:(0,l.jsx)(el,{token:e.token,accessToken:s,keySpend:e.spend,keyBudget:e.max_budget,keyName:e.key_name})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:e.team_id})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:JSON.stringify(e.metadata).slice(0,400)})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:JSON.stringify(e.models)})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",overflowWrap:"break-word"},children:(0,l.jsxs)(R.Z,{children:["TPM Limit: ",e.tpm_limit?e.tpm_limit:"Unlimited"," ",(0,l.jsx)("br",{})," RPM Limit:"," ",e.rpm_limit?e.rpm_limit:"Unlimited"]})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",wordWrap:"break-word"},children:null!=e.expires?(0,l.jsx)(R.Z,{children:e.expires}):(0,l.jsx)(R.Z,{children:"Never"})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",wordWrap:"break-word"},children:(0,l.jsx)(G.Z,{onClick:()=>p(e.token),icon:J.Z,size:"sm"})})]},e.token))})]}),d&&(0,l.jsx)("div",{className:"fixed z-10 inset-0 overflow-y-auto",children:(0,l.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,l.jsx)("div",{className:"fixed inset-0 transition-opacity","aria-hidden":"true",children:(0,l.jsx)("div",{className:"absolute inset-0 bg-gray-500 opacity-75"})}),(0,l.jsx)("span",{className:"hidden sm:inline-block sm:align-middle sm:h-screen","aria-hidden":"true",children:"​"}),(0,l.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,l.jsx)("div",{className:"bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4",children:(0,l.jsx)("div",{className:"sm:flex sm:items-start",children:(0,l.jsxs)("div",{className:"mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left",children:[(0,l.jsx)("h3",{className:"text-lg leading-6 font-medium text-gray-900",children:"Delete Key"}),(0,l.jsx)("div",{className:"mt-2",children:(0,l.jsx)("p",{className:"text-sm text-gray-500",children:"Are you sure you want to delete this key ?"})})]})})}),(0,l.jsxs)("div",{className:"bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse",children:[(0,l.jsx)(o.Z,{onClick:j,color:"red",className:"ml-2",children:"Delete"}),(0,l.jsx)(o.Z,{onClick:()=>{h(!1),x(null)},children:"Cancel"})]})]})]})})]})},ea=e=>{let{userID:t,userSpendData:s,userRole:a,accessToken:n}=e,[o,i]=(0,r.useState)(null==s?void 0:s.spend),[c,d]=(0,r.useState)((null==s?void 0:s.max_budget)||null);(0,r.useEffect)(()=>{(async()=>{if("Admin"===a)try{let e=await x(n);i(e.spend),d(e.max_budget||null)}catch(e){console.error("Error fetching global spend data:",e)}})()},[a,n]);let h=void 0!==o?o.toFixed(4):null;return(0,l.jsx)(l.Fragment,{children:(0,l.jsxs)(M.Z,{className:"mx-auto mb-4",children:[(0,l.jsxs)(es.Z,{children:["$",h]}),(0,l.jsxs)(D.Z,{children:["/ ",null!==c?"$".concat(c," limit"):"No limit"]})]})})},en=s(36083),eo=s(68967),ei=s(27166),ec=e=>{let{teams:t,setSelectedTeam:s}=e,{Title:a,Paragraph:n}=en.default,[o,i]=(0,r.useState)("");return(0,l.jsxs)("div",{className:"mt-10",children:[(0,l.jsx)(a,{level:4,children:"Default Team"}),(0,l.jsx)(n,{children:"If you belong to multiple teams, this setting controls which team is used by default when creating new API Keys."}),t&&t.length>0?(0,l.jsx)(eo.Z,{defaultValue:"0",children:t.map((e,t)=>(0,l.jsx)(ei.Z,{value:String(t),onClick:()=>s(e),children:e.team_alias},t))}):(0,l.jsxs)(n,{children:["No team created. ",(0,l.jsx)("b",{children:"Defaulting to personal account."})]})]})},ed=s(37963);console.log("isLocal:",!1);var eh=e=>{let{userID:t,userRole:s,teams:n,keys:o,setUserRole:i,userEmail:c,setUserEmail:d,setTeams:h,setKeys:m}=e,[p,j]=(0,r.useState)(null),g=(0,a.useSearchParams)();g.get("viewSpend"),(0,a.useRouter)();let w=g.get("token"),[Z,f]=(0,r.useState)(null),[k,_]=(0,r.useState)([]),[b,v]=(0,r.useState)(n?n[0]:null);if(window.addEventListener("beforeunload",function(){sessionStorage.clear()}),(0,r.useEffect)(()=>{if(w){let e=(0,ed.o)(w);if(e){if(console.log("Decoded token:",e),console.log("Decoded key:",e.key),f(e.key),e.user_role){let t=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";default:return"Unknown Role"}}(e.user_role);console.log("Decoded user_role:",t),i(t)}else console.log("User role not defined");e.user_email?d(e.user_email):console.log("User Email is not set ".concat(e))}}if(t&&Z&&s&&!o&&!p){let e=sessionStorage.getItem("userModels"+t);e?_(JSON.parse(e)):(async()=>{try{let e=await u(Z,t,s);if(console.log("received teams in user dashboard: ".concat(Object.keys(e),"; team values: ").concat(Object.entries(e.teams))),"Admin"==s){let e=await x(Z);j(e),console.log("globalSpend:",e)}else j(e.user_info);m(e.keys),h(e.teams),v(e.teams?e.teams[0]:null),sessionStorage.setItem("userData"+t,JSON.stringify(e.keys)),sessionStorage.setItem("userSpendData"+t,JSON.stringify(e.user_info));let l=(await y(Z,t,s)).data.map(e=>e.id);console.log("available_model_names:",l),_(l),console.log("userModels:",k),sessionStorage.setItem("userModels"+t,JSON.stringify(l))}catch(e){console.error("There was an error fetching the data",e)}})()}},[t,w,Z,o,s]),null==t||null==w){let e="/sso/key/generate";return console.log("Full URL:",e),window.location.href=e,null}if(null==Z)return null;if(null==s&&i("App Owner"),s&&"Admin Viewer"==s){let{Title:e,Paragraph:t}=en.default;return(0,l.jsxs)("div",{children:[(0,l.jsx)(e,{level:1,children:"Access Denied"}),(0,l.jsx)(t,{children:"Ask your proxy admin for access to create keys"})]})}return(0,l.jsx)("div",{children:(0,l.jsx)(O.Z,{numItems:1,className:"gap-0 p-10 h-[75vh] w-full",children:(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(ea,{userID:t,userSpendData:p,userRole:s,accessToken:Z}),(0,l.jsx)(er,{userID:t,accessToken:Z,data:o,setData:m}),(0,l.jsx)(q,{userID:t,teamID:b?b.team_id:null,userRole:s,userModels:k,accessToken:Z,data:o,setData:m}),(0,l.jsx)(ec,{teams:n,setSelectedTeam:v})]})})})},em=s(5);let{Option:eu}=U.default;var ex=e=>{let{userModels:t,accessToken:s,userID:a}=e,[n]=L.Z.useForm(),[i,d]=(0,r.useState)(!1),h=async e=>{try{c.ZP.info("Requesting access");let{selectedModel:t,accessReason:l}=e;await S(s,t,a,l),d(!0)}catch(e){console.error("Error requesting access:",e)}};return(0,l.jsxs)("div",{children:[(0,l.jsx)(o.Z,{size:"xs",onClick:()=>d(!0),children:"Request Access"}),(0,l.jsx)(B.Z,{title:"Request Access",visible:i,width:800,footer:null,onOk:()=>{d(!1),n.resetFields()},onCancel:()=>{d(!1),n.resetFields()},children:(0,l.jsxs)(L.Z,{form:n,onFinish:h,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsx)(L.Z.Item,{label:"Select Model",name:"selectedModel",children:(0,l.jsx)(U.default,{placeholder:"Select model",style:{width:"100%"},children:t.map(e=>(0,l.jsx)(eu,{value:e,children:e},e))})}),(0,l.jsx)(L.Z.Item,{label:"Reason for Access",name:"accessReason",children:(0,l.jsx)(z.Z.TextArea,{rows:4,placeholder:"Enter reason for access"})}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(o.Z,{children:"Request Access"})})]})})]})},ep=e=>{let{accessToken:t,token:s,userRole:a,userID:n}=e,[o,i]=(0,r.useState)({data:[]}),[c,d]=(0,r.useState)([]),[h,m]=(0,r.useState)([]);if((0,r.useEffect)(()=>{if(!t||!s||!a||!n)return;let e=async()=>{try{let e=await p(t,n,a);console.log("Model data response:",e.data),i(e);let s=await j(t,n,a);if(console.log("Model metrics response:",s),d(s),"Admin"===a&&t){let e=await N(t);console.log("Pending Requests:",h),m(e.requests||[])}}catch(e){console.error("There was an error fetching the model data",e)}};t&&s&&a&&n&&e()},[t,s,a,n]),!o||!t||!s||!a||!n)return(0,l.jsx)("div",{children:"Loading..."});let u=[];for(let e=0;e(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{children:(0,l.jsx)(D.Z,{children:e.model_name})}),(0,l.jsx)(Y.Z,{children:e.provider}),"Admin"===a&&(0,l.jsx)(Y.Z,{children:e.api_base}),(0,l.jsx)(Y.Z,{children:e.user_access?(0,l.jsx)(em.Z,{color:"green",children:"Yes"}):(0,l.jsx)(ex,{userModels:u,accessToken:t,userID:n})}),(0,l.jsx)(Y.Z,{children:e.input_cost}),(0,l.jsx)(Y.Z,{children:e.output_cost}),(0,l.jsx)(Y.Z,{children:e.max_tokens})]},e.model_name))})]})}),(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Model Statistics (Number Requests)"}),(0,l.jsx)(et.Z,{data:c,index:"model",categories:["num_requests"],colors:["blue"],yAxisWidth:400,layout:"vertical",tickGap:5})]}),(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Model Statistics (Latency)"}),(0,l.jsx)(et.Z,{data:c,index:"model",categories:["avg_latency_seconds"],colors:["red"],yAxisWidth:400,layout:"vertical",tickGap:5})]})]})})},ej=s(92836),ey=s(26734),eg=s(41608),ew=s(32126),eZ=s(23682);let{Option:ef}=U.default;var ek=e=>{let{userID:t,accessToken:s}=e,[a]=L.Z.useForm(),[n,i]=(0,r.useState)(!1),[d,m]=(0,r.useState)(null),[u,x]=(0,r.useState)([]);(0,r.useEffect)(()=>{(async()=>{try{let e=await y(s,t,"any"),l=[];for(let t=0;t{i(!1),a.resetFields()},j=()=>{i(!1),m(null),a.resetFields()},g=async e=>{try{c.ZP.info("Making API Call"),i(!0),console.log("formValues in create user:",e);let l=await h(s,t,e);console.log("user create Response:",l),m(l.key),c.ZP.success("API user Created"),a.resetFields(),localStorage.removeItem("userData"+t)}catch(e){console.error("Error creating the user:",e)}};return(0,l.jsxs)("div",{children:[(0,l.jsx)(o.Z,{className:"mx-auto",onClick:()=>i(!0),children:"+ Create New User"}),(0,l.jsx)(B.Z,{title:"Create User",visible:n,width:800,footer:null,onOk:p,onCancel:j,children:(0,l.jsxs)(L.Z,{form:a,onFinish:g,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsx)(L.Z.Item,{label:"User ID",name:"user_id",children:(0,l.jsx)(z.Z,{placeholder:"Enter User ID"})}),(0,l.jsx)(L.Z.Item,{label:"Team ID",name:"team_id",children:(0,l.jsx)(z.Z,{placeholder:"ai_team"})}),(0,l.jsx)(L.Z.Item,{label:"Models",name:"models",children:(0,l.jsx)(U.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:u.map(e=>(0,l.jsx)(ef,{value:e,children:e},e))})}),(0,l.jsx)(L.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,l.jsx)(K.Z,{step:.01,precision:2,width:200})}),(0,l.jsx)(L.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})}),(0,l.jsx)(L.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})}),(0,l.jsx)(L.Z.Item,{label:"Duration (eg: 30s, 30h, 30d)",name:"duration",children:(0,l.jsx)(z.Z,{})}),(0,l.jsx)(L.Z.Item,{label:"Metadata",name:"metadata",children:(0,l.jsx)(z.Z.TextArea,{rows:4,placeholder:"Enter metadata as JSON"})}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(W.ZP,{htmlType:"submit",children:"Create User"})})]})}),d&&(0,l.jsxs)(B.Z,{title:"Save Your User",visible:n,onOk:p,onCancel:j,footer:null,children:[(0,l.jsxs)("p",{children:["Please save this secret user somewhere safe and accessible. For security reasons, ",(0,l.jsx)("b",{children:"you will not be able to view it again"})," ","through your LiteLLM account. If you lose this secret user, you will need to generate a new one."]}),(0,l.jsx)("p",{children:null!=d?"API user: ".concat(d):"User being created, this might take 30s"})]})]})},e_=e=>{let{accessToken:t,token:s,keys:a,userRole:n,userID:o,setKeys:i}=e,[c,d]=(0,r.useState)(null),[h,m]=(0,r.useState)(null),[x,p]=(0,r.useState)(1);if((0,r.useEffect)(()=>{if(!t||!s||!n||!o)return;let e=async()=>{try{let e=await u(t,null,n,!0);console.log("user data response:",e),d(e)}catch(e){console.error("There was an error fetching the model data",e)}};t&&s&&n&&o&&!c&&e();let l=async()=>{try{let e=await _(t,null);console.log("user data response:",e),m(e)}catch(e){console.error("There was an error fetching the model data",e)}};n&&("Admin"==n||"Admin Viewer"==n)&&!h&&l()},[t,s,n,o]),!c||!t||!s||!n||!o)return(0,l.jsx)("div",{children:"Loading..."});let j=async e=>{try{let s=await _(t,e);console.log("user data response:",s),m(s)}catch(e){console.error("There was an error fetching the model data",e)}};return(0,l.jsx)("div",{style:{width:"100%"},children:(0,l.jsxs)(O.Z,{className:"gap-2 p-10 h-[75vh] w-full",children:[(0,l.jsx)(ek,{userID:o,accessToken:t}),(0,l.jsx)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh] mb-4",children:(0,l.jsxs)(ey.Z,{children:[(0,l.jsxs)(eg.Z,{variant:"line",defaultValue:"1",children:[(0,l.jsx)(ej.Z,{value:"1",children:"Key Owners"}),(0,l.jsx)(ej.Z,{value:"2",children:"End-Users"})]}),(0,l.jsxs)(eZ.Z,{children:[(0,l.jsx)(ew.Z,{children:(0,l.jsxs)($.Z,{className:"mt-5",children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"User ID"}),(0,l.jsx)(Q.Z,{children:"User Role"}),(0,l.jsx)(Q.Z,{children:"User Models"}),(0,l.jsx)(Q.Z,{children:"User Spend ($ USD)"}),(0,l.jsx)(Q.Z,{children:"User Max Budget ($ USD)"})]})}),(0,l.jsx)(H.Z,{children:c.map(e=>(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{children:e.user_id}),(0,l.jsx)(Y.Z,{children:e.user_role?e.user_role:"app_owner"}),(0,l.jsx)(Y.Z,{children:e.models&&e.models.length>0?e.models:"All Models"}),(0,l.jsx)(Y.Z,{children:e.spend?e.spend:0}),(0,l.jsx)(Y.Z,{children:e.max_budget?e.max_budget:"Unlimited"})]},e.user_id))})]})}),(0,l.jsxs)(ew.Z,{children:[(0,l.jsxs)("div",{className:"flex items-center",children:[(0,l.jsx)("div",{className:"flex-1"}),(0,l.jsxs)("div",{className:"flex-1 flex justify-between items-center",children:[(0,l.jsx)(R.Z,{className:"w-1/4 mr-2 text-right",children:"Key"}),(0,l.jsx)(eo.Z,{defaultValue:"1",className:"w-3/4",children:null==a?void 0:a.map((e,t)=>{if(e&&null!==e.key_name&&e.key_name.length>0)return(0,l.jsx)(ei.Z,{value:String(t),onClick:()=>j(e.token),children:e.key_name},t)})})]})]}),(0,l.jsxs)($.Z,{children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"End User"}),(0,l.jsx)(Q.Z,{children:"Spend"}),(0,l.jsx)(Q.Z,{children:"Total Events"})]})}),(0,l.jsx)(H.Z,{children:null==h?void 0:h.map((e,t)=>(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{children:e.end_user}),(0,l.jsx)(Y.Z,{children:e.total_spend}),(0,l.jsx)(Y.Z,{children:e.total_events})]},t))})]})]})]})]})}),function(){if(!c)return null;let e=Math.ceil(c.length/25),t=Math.min(25*x,c.length);return(0,l.jsxs)("div",{className:"flex justify-between items-center",children:[(0,l.jsxs)("div",{children:["Showing ",(x-1)*25+1," – ",t," of ",c.length]}),(0,l.jsxs)("div",{className:"flex",children:[(0,l.jsx)("button",{className:"bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-l focus:outline-none",disabled:1===x,onClick:()=>p(x-1),children:"← Prev"}),(0,l.jsx)("button",{className:"bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-r focus:outline-none",disabled:x===e,onClick:()=>p(x+1),children:"Next →"})]})]})}()]})})},eb=e=>{let{teams:t,searchParams:s,accessToken:a,setTeams:n,userID:i,userRole:d}=e,[h]=L.Z.useForm(),[m]=L.Z.useForm(),{Title:u,Paragraph:x}=en.default,[p,j]=(0,r.useState)(""),[g,w]=(0,r.useState)(t?t[0]:null),[Z,f]=(0,r.useState)(!1),[k,_]=(0,r.useState)(!1),[b,v]=(0,r.useState)([]);(0,r.useEffect)(()=>{(async()=>{try{if(null===i||null===d)return;if(null!==a){let e=(await y(a,i,d)).data.map(e=>e.id);console.log("available_model_names:",e),v(e)}}catch(e){console.error("Error fetching user models:",e)}})()},[a,i,d]);let S=async e=>{try{if(null!=a){c.ZP.info("Creating Team");let s=await C(a,e);null!==t?n([...t,s]):n([s]),console.log("response for team create call: ".concat(s)),c.ZP.success("Team created"),f(!1)}}catch(e){console.error("Error creating the key:",e),c.ZP.error("Error creating the team: "+e)}},N=async e=>{try{if(null!=a&&null!=t){c.ZP.info("Making API Call");let s={role:"user",user_email:e.user_email,user_id:e.user_id},l=await T(a,g.team_id,s);console.log("response for team create call: ".concat(l.data));let r=t.findIndex(e=>(console.log("team.team_id=".concat(e.team_id,"; response.data.team_id=").concat(l.data.team_id)),e.team_id===l.data.team_id));if(console.log("foundIndex: ".concat(r)),-1!==r){let e=[...t];e[r]=l.data,n(e),w(l.data)}_(!1)}}catch(e){console.error("Error creating the key:",e)}};return console.log("received teams ".concat(t)),(0,l.jsx)("div",{className:"w-full mx-4",children:(0,l.jsxs)(O.Z,{numItems:1,className:"gap-2 p-2 h-[75vh] w-full",children:[(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(u,{level:4,children:"All Teams"}),(0,l.jsx)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,l.jsxs)($.Z,{children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"Team Name"}),(0,l.jsx)(Q.Z,{children:"Spend (USD)"}),(0,l.jsx)(Q.Z,{children:"Budget (USD)"}),(0,l.jsx)(Q.Z,{children:"Models"}),(0,l.jsx)(Q.Z,{children:"TPM / RPM Limits"})]})}),(0,l.jsx)(H.Z,{children:t&&t.length>0?t.map(e=>(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:e.team_alias}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:e.spend}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:e.max_budget?e.max_budget:"No limit"}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:JSON.stringify(e.models?e.models:[])})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsxs)(R.Z,{children:["TPM Limit:"," ",e.tpm_limit?e.tpm_limit:"Unlimited"," ",(0,l.jsx)("br",{}),"RPM Limit:"," ",e.rpm_limit?e.rpm_limit:"Unlimited"]})})]},e.team_id)):null})]})})]}),(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(o.Z,{className:"mx-auto",onClick:()=>f(!0),children:"+ Create New Team"}),(0,l.jsx)(B.Z,{title:"Create Team",visible:Z,width:800,footer:null,onOk:()=>{f(!1),h.resetFields()},onCancel:()=>{f(!1),h.resetFields()},children:(0,l.jsxs)(L.Z,{form:h,onFinish:S,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(L.Z.Item,{label:"Team Name",name:"team_alias",children:(0,l.jsx)(z.Z,{})}),(0,l.jsx)(L.Z.Item,{label:"Models",name:"models",children:(0,l.jsx)(U.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:b.map(e=>(0,l.jsx)(U.default.Option,{value:e,children:e},e))})}),(0,l.jsx)(L.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,l.jsx)(K.Z,{step:.01,precision:2,width:200})}),(0,l.jsx)(L.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})}),(0,l.jsx)(L.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})})]}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(W.ZP,{htmlType:"submit",children:"Create Team"})})]})})]}),(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(u,{level:4,children:"Team Members"}),(0,l.jsx)(x,{children:"If you belong to multiple teams, this setting controls which teams members you see."}),t&&t.length>0?(0,l.jsx)(eo.Z,{defaultValue:"0",children:t.map((e,t)=>(0,l.jsx)(ei.Z,{value:String(t),onClick:()=>{w(e)},children:e.team_alias},t))}):(0,l.jsxs)(x,{children:["No team created. ",(0,l.jsx)("b",{children:"Defaulting to personal account."})]})]}),(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsx)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,l.jsxs)($.Z,{children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"Member Name"}),(0,l.jsx)(Q.Z,{children:"Role"})]})}),(0,l.jsx)(H.Z,{children:g?g.members_with_roles.map((e,t)=>(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{children:e.user_email?e.user_email:e.user_id?e.user_id:null}),(0,l.jsx)(Y.Z,{children:e.role})]},t)):null})]})})}),(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(o.Z,{className:"mx-auto mb-5",onClick:()=>_(!0),children:"+ Add member"}),(0,l.jsx)(B.Z,{title:"Add member",visible:k,width:800,footer:null,onOk:()=>{_(!1),m.resetFields()},onCancel:()=>{_(!1),m.resetFields()},children:(0,l.jsxs)(L.Z,{form:h,onFinish:N,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(L.Z.Item,{label:"Email",name:"user_email",className:"mb-4",children:(0,l.jsx)(z.Z,{name:"user_email",className:"px-3 py-2 border rounded-md w-full"})}),(0,l.jsx)("div",{className:"text-center mb-4",children:"OR"}),(0,l.jsx)(L.Z.Item,{label:"User ID",name:"user_id",className:"mb-4",children:(0,l.jsx)(z.Z,{name:"user_id",className:"px-3 py-2 border rounded-md w-full"})})]}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(W.ZP,{htmlType:"submit",children:"Add member"})})]})})]})]})})},ev=s(8510),eS=e=>{let{searchParams:t,accessToken:s}=e,[a]=L.Z.useForm(),[n]=L.Z.useForm(),{Title:i,Paragraph:d}=en.default,[h,m]=(0,r.useState)(""),[u,x]=(0,r.useState)(null),[p,j]=(0,r.useState)(!1);(0,r.useEffect)(()=>{(async()=>{if(null!=s){let e=[],t=await A(s,"proxy_admin_viewer");t.forEach(t=>{e.push({user_role:t.user_role,user_id:t.user_id,user_email:t.user_email})}),console.log("proxy viewers: ".concat(t));let l=await A(s,"proxy_admin");l.forEach(t=>{e.push({user_role:t.user_role,user_id:t.user_id,user_email:t.user_email})}),console.log("proxy admins: ".concat(l)),console.log("combinedList: ".concat(e)),x(e)}})()},[s]);let y=async e=>{try{if(null!=s&&null!=u){c.ZP.info("Making API Call"),e.user_email,e.user_id;let t=await I(s,e);console.log("response for team create call: ".concat(t));let l=u.findIndex(e=>(console.log("user.user_id=".concat(e.user_id,"; response.user_id=").concat(t.user_id)),e.user_id===t.user_id));console.log("foundIndex: ".concat(l)),-1==l&&(console.log("updates admin with new user"),u.push(t),x(u)),j(!1)}}catch(e){console.error("Error creating the key:",e)}};return console.log("admins: ".concat(null==u?void 0:u.length)),(0,l.jsxs)("div",{className:"w-full m-2",children:[(0,l.jsx)(i,{level:4,children:"Restricted Access"}),(0,l.jsxs)(d,{children:["Add other people to just view spend. They cannot create keys, teams or grant users access to new models."," ",(0,l.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/ui#restrict-ui-access",children:"Requires SSO Setup"})]}),(0,l.jsxs)(O.Z,{numItems:1,className:"gap-2 p-0 w-full",children:[(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsx)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,l.jsxs)($.Z,{children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"Member Name"}),(0,l.jsx)(Q.Z,{children:"Role"}),(0,l.jsx)(Q.Z,{children:"Action"})]})}),(0,l.jsx)(H.Z,{children:u?u.map((e,t)=>(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{children:e.user_email?e.user_email:e.user_id?e.user_id:null}),(0,l.jsx)(Y.Z,{children:e.user_role}),(0,l.jsx)(Y.Z,{children:(0,l.jsx)(G.Z,{icon:ev.Z,size:"sm"})})]},t)):null})]})})}),(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(o.Z,{className:"mx-auto mb-5",onClick:()=>j(!0),children:"+ Add viewer"}),(0,l.jsx)(B.Z,{title:"Add viewer",visible:p,width:800,footer:null,onOk:()=>{j(!1),n.resetFields()},onCancel:()=>{j(!1),n.resetFields()},children:(0,l.jsxs)(L.Z,{form:a,onFinish:y,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(L.Z.Item,{label:"Email",name:"user_email",className:"mb-4",children:(0,l.jsx)(z.Z,{name:"user_email",className:"px-3 py-2 border rounded-md w-full"})}),(0,l.jsx)("div",{className:"text-center mb-4",children:"OR"}),(0,l.jsx)(L.Z.Item,{label:"User ID",name:"user_id",className:"mb-4",children:(0,l.jsx)(z.Z,{name:"user_id",className:"px-3 py-2 border rounded-md w-full"})})]}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(W.ZP,{htmlType:"submit",children:"Add member"})})]})})]})]})]})},eN=s(12968),eA=s(67951);async function eC(e,t,s,l){console.log("isLocal:",!1);let r=window.location.origin,a=new eN.ZP.OpenAI({apiKey:l,baseURL:r,dangerouslyAllowBrowser:!0});for await(let l of(await a.chat.completions.create({model:s,stream:!0,messages:[{role:"user",content:e}]})))console.log(l),l.choices[0].delta.content&&t(l.choices[0].delta.content)}var eT=e=>{let{accessToken:t,token:s,userRole:a,userID:n}=e,[o,i]=(0,r.useState)(""),[c,d]=(0,r.useState)([]),[h,m]=(0,r.useState)(void 0),[u,x]=(0,r.useState)(null);(0,r.useEffect)(()=>{t&&s&&a&&n&&(async()=>{let e=await y(t,n,a);console.log("model_info:",e),(null==e?void 0:e.data.length)>0&&(x(e.data),m(e.data[0].id))})()},[t,n,a]);let p=(e,t)=>{d(s=>{let l=s[s.length-1];return l&&l.role===e?[...s.slice(0,s.length-1),{role:e,content:l.content+t}]:[...s,{role:e,content:t}]})},j=async()=>{if(""!==o.trim()&&t&&s&&a&&n){d(e=>[...e,{role:"user",content:o}]);try{h&&await eC(o,e=>p("assistant",e),h,t)}catch(e){console.error("Error fetching model response",e),p("assistant","Error fetching model response")}i("")}};if(a&&"Admin Viewer"==a){let{Title:e,Paragraph:t}=en.default;return(0,l.jsxs)("div",{children:[(0,l.jsx)(e,{level:1,children:"Access Denied"}),(0,l.jsx)(t,{children:"Ask your proxy admin for access to test models"})]})}return(0,l.jsx)("div",{style:{width:"100%",position:"relative"},children:(0,l.jsx)(O.Z,{className:"gap-2 p-10 h-[75vh] w-full",children:(0,l.jsx)(M.Z,{children:(0,l.jsxs)(ey.Z,{children:[(0,l.jsxs)(eg.Z,{className:"mt-4",children:[(0,l.jsx)(ej.Z,{children:"Chat"}),(0,l.jsx)(ej.Z,{children:"API Reference"})]}),(0,l.jsxs)(eZ.Z,{children:[(0,l.jsxs)(ew.Z,{children:[(0,l.jsxs)("div",{children:[(0,l.jsx)("label",{children:"Select Model:"}),(0,l.jsx)("select",{value:h||"",onChange:e=>m(e.target.value),children:null==u?void 0:u.map(e=>(0,l.jsx)("option",{value:e.id,children:e.id},e.id))})]}),(0,l.jsxs)($.Z,{className:"mt-5",style:{display:"block",maxHeight:"60vh",overflowY:"auto"},children:[(0,l.jsx)(X.Z,{children:(0,l.jsx)(ee.Z,{children:(0,l.jsx)(Y.Z,{children:(0,l.jsx)(D.Z,{children:"Chat"})})})}),(0,l.jsx)(H.Z,{children:c.map((e,t)=>(0,l.jsx)(ee.Z,{children:(0,l.jsx)(Y.Z,{children:"".concat(e.role,": ").concat(e.content)})},t))})]}),(0,l.jsx)("div",{className:"mt-3",style:{position:"absolute",bottom:5,width:"95%"},children:(0,l.jsxs)("div",{className:"flex",children:[(0,l.jsx)("input",{type:"text",value:o,onChange:e=>i(e.target.value),className:"flex-1 p-2 border rounded-md mr-2",placeholder:"Type your message..."}),(0,l.jsx)("button",{onClick:j,className:"p-2 bg-blue-500 text-white rounded-md",children:"Send"})]})})]}),(0,l.jsx)(ew.Z,{children:(0,l.jsxs)(ey.Z,{children:[(0,l.jsxs)(eg.Z,{children:[(0,l.jsx)(ej.Z,{children:"OpenAI Python SDK"}),(0,l.jsx)(ej.Z,{children:"LlamaIndex"}),(0,l.jsx)(ej.Z,{children:"Langchain Py"})]}),(0,l.jsxs)(eZ.Z,{children:[(0,l.jsx)(ew.Z,{children:(0,l.jsx)(eA.Z,{language:"python",children:'\nimport openai\nclient = openai.OpenAI(\n api_key="your_api_key",\n base_url="http://0.0.0.0:4000" # proxy base url\n)\n\nresponse = client.chat.completions.create(\n model="gpt-3.5-turbo", # model to use from Models Tab\n messages = [\n {\n "role": "user",\n "content": "this is a test request, write a short poem"\n }\n ],\n extra_body={\n "metadata": {\n "generation_name": "ishaan-generation-openai-client",\n "generation_id": "openai-client-gen-id22",\n "trace_id": "openai-client-trace-id22",\n "trace_user_id": "openai-client-user-id2"\n }\n }\n)\n\nprint(response)\n '})}),(0,l.jsx)(ew.Z,{children:(0,l.jsx)(eA.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="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,l.jsx)(ew.Z,{children:(0,l.jsx)(eA.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:8000",\n model = "gpt-3.5-turbo",\n temperature=0.1,\n extra_body={\n "metadata": {\n "generation_name": "ishaan-generation-langchain-client",\n "generation_id": "langchain-client-gen-id22",\n "trace_id": "langchain-client-trace-id22",\n "trace_user_id": "langchain-client-user-id2"\n }\n }\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 '})})]})]})})]})]})})})})},eI=s(33509),eP=s(30569);let{Sider:eE}=eI.default;var eF=e=>{let{setPage:t,userRole:s,defaultSelectedKey:r}=e;return"Admin Viewer"==s?(0,l.jsx)(eI.default,{style:{minHeight:"100vh",maxWidth:"120px"},children:(0,l.jsx)(eE,{width:120,children:(0,l.jsxs)(eP.Z,{mode:"inline",defaultSelectedKeys:r||["4"],style:{height:"100%",borderRight:0},children:[(0,l.jsx)(eP.Z.Item,{onClick:()=>t("api-keys"),children:"API Keys"},"4"),(0,l.jsx)(eP.Z.Item,{onClick:()=>t("models"),children:"Models"},"2"),(0,l.jsx)(eP.Z.Item,{onClick:()=>t("llm-playground"),children:"Chat UI"},"3"),(0,l.jsx)(eP.Z.Item,{onClick:()=>t("usage"),children:"Usage"},"1")]})})}):(0,l.jsx)(eI.default,{style:{minHeight:"100vh",maxWidth:"120px"},children:(0,l.jsx)(eE,{width:120,children:(0,l.jsxs)(eP.Z,{mode:"inline",defaultSelectedKeys:r||["1"],style:{height:"100%",borderRight:0},children:[(0,l.jsx)(eP.Z.Item,{onClick:()=>t("api-keys"),children:"API Keys"},"1"),(0,l.jsx)(eP.Z.Item,{onClick:()=>t("models"),children:"Models"},"2"),(0,l.jsx)(eP.Z.Item,{onClick:()=>t("llm-playground"),children:"Chat UI"},"3"),(0,l.jsx)(eP.Z.Item,{onClick:()=>t("usage"),children:"Usage"},"4"),"Admin"==s?(0,l.jsx)(eP.Z.Item,{onClick:()=>t("users"),children:"Users"},"5"):null,"Admin"==s?(0,l.jsx)(eP.Z.Item,{onClick:()=>t("teams"),children:"Teams"},"6"):null,"Admin"==s?(0,l.jsx)(eP.Z.Item,{onClick:()=>t("admin-panel"),children:"Admin"},"7"):null]})})})},eO=e=>{let{accessToken:t,token:s,userRole:a,userID:n}=e,o=new Date,[i,c]=(0,r.useState)([]),[d,h]=(0,r.useState)([]),[m,u]=(0,r.useState)([]),[x,p]=(0,r.useState)([]),[j,y]=(0,r.useState)([]),[g,_]=(0,r.useState)([]),[S,N]=(0,r.useState)([]),A=new Date(o.getFullYear(),o.getMonth(),1),C=new Date(o.getFullYear(),o.getMonth()+1,0),T=P(A),I=P(C);function P(e){let t=e.getFullYear(),s=e.getMonth()+1,l=e.getDate();return"".concat(t,"-").concat(s<10?"0"+s:s,"-").concat(l<10?"0"+l:l)}return console.log("Start date is ".concat(T)),console.log("End date is ".concat(I)),(0,r.useEffect)(()=>{t&&s&&a&&n&&(async()=>{try{if(console.log("user role: ".concat(a)),"Admin"==a||"Admin Viewer"==a){let e=await f(t);c(e);let s=(await k(t)).map(e=>({key:(e.key_name||e.key_alias||e.api_key).substring(0,7),spend:e.total_spend}));h(s);let l=(await b(t)).map(e=>({key:e.model,spend:e.total_spend}));u(l);let r=await w(t);console.log("teamSpend",r),y(r.daily_spend),_(r.teams),N(r.total_spend_per_team)}else"App Owner"==a&&await Z(t,s,a,n,T,I).then(async e=>{if(console.log("result from spend logs call",e),"daily_spend"in e){let t=e.daily_spend;console.log("daily spend",t),c(t);let s=e.top_api_keys;h(s)}else{let s=(await v(t,function(e){let t=[];e.forEach(e=>{Object.entries(e).forEach(e=>{let[s,l]=e;"spend"!==s&&"startTime"!==s&&"models"!==s&&"users"!==s&&t.push({key:s,spend:l})})}),t.sort((e,t)=>Number(t.spend)-Number(e.spend));let s=t.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||e.token).substring(0,7),spend:e.spend}));h(s),p(function(e){let t={};e.forEach(e=>{Object.entries(e.users).forEach(e=>{let[s,l]=e;""!==s&&null!=s&&"None"!=s&&(t[s]||(t[s]=0),t[s]+=l)})});let s=Object.entries(t).map(e=>{let[t,s]=e;return{user_id:t,spend:s}});s.sort((e,t)=>t.spend-e.spend);let l=s.slice(0,5);return console.log("topKeys: ".concat(Object.values(l[0]))),l}(e)),c(e)}})}catch(e){console.error("There was an error fetching the data",e)}})()},[t,s,a,n,T,I]),(0,l.jsx)("div",{style:{width:"100%"},children:(0,l.jsxs)(ey.Z,{children:[(0,l.jsxs)(eg.Z,{className:"mt-4",children:[(0,l.jsx)(ej.Z,{children:"All Up"}),(0,l.jsx)(ej.Z,{children:"Team Based Usage"})]}),(0,l.jsxs)(eZ.Z,{children:[(0,l.jsx)(ew.Z,{children:(0,l.jsxs)(O.Z,{numItems:2,className:"gap-2 p-10 h-[75vh] w-full",children:[(0,l.jsx)(F.Z,{numColSpan:2,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Monthly Spend"}),(0,l.jsx)(et.Z,{data:i,index:"date",categories:["spend"],colors:["blue"],valueFormatter:e=>"$ ".concat(new Intl.NumberFormat("us").format(e).toString()),yAxisWidth:100,tickGap:5})]})}),(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Top API Keys"}),(0,l.jsx)(et.Z,{className:"mt-4 h-40",data:d,index:"key",categories:["spend"],colors:["blue"],yAxisWidth:80,tickGap:5,layout:"vertical",showXAxis:!1,showLegend:!1})]})}),(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Top Users"}),(0,l.jsx)(et.Z,{className:"mt-4 h-40",data:x,index:"user_id",categories:["spend"],colors:["blue"],yAxisWidth:200,layout:"vertical",showXAxis:!1,showLegend:!1})]})}),(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Top Models"}),(0,l.jsx)(et.Z,{className:"mt-4 h-40",data:m,index:"key",categories:["spend"],colors:["blue"],yAxisWidth:200,layout:"vertical",showXAxis:!1,showLegend:!1})]})})]})}),(0,l.jsx)(ew.Z,{children:(0,l.jsxs)(O.Z,{numItems:2,className:"gap-2 p-10 h-[75vh] w-full",children:[(0,l.jsx)(F.Z,{numColSpan:2,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Daily Spend Per Team"}),(0,l.jsx)(et.Z,{className:"h-72",data:j,index:"date",categories:g,yAxisWidth:30,stack:!0})]})}),(0,l.jsx)(F.Z,{numColSpan:2,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Total Spend Per Team"}),(0,l.jsx)(et.Z,{className:"h-72",data:S,index:"team_id",categories:["total_spend"],yAxisWidth:30})]})})]})})]})]})})},eM=()=>{let{Title:e,Paragraph:t}=en.default,[s,n]=(0,r.useState)(""),[o,c]=(0,r.useState)(null),[d,h]=(0,r.useState)(null),[m,u]=(0,r.useState)(null),[x,p]=(0,r.useState)(!0),j=(0,a.useSearchParams)(),y=j.get("userID"),g=j.get("token"),[w,Z]=(0,r.useState)("api-keys"),[f,k]=(0,r.useState)(null);return(0,r.useEffect)(()=>{if(g){let e=(0,ed.o)(g);if(e){if(console.log("Decoded token:",e),console.log("Decoded key:",e.key),k(e.key),e.user_role){let t=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"app_user":return"App User";default:return"Unknown Role"}}(e.user_role);console.log("Decoded user_role:",t),n(t),"Admin Viewer"==t&&Z("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?p("username_password"==e.login_method):console.log("User Email is not set ".concat(e))}}},[g]),(0,l.jsx)(r.Suspense,{fallback:(0,l.jsx)("div",{children:"Loading..."}),children:(0,l.jsxs)("div",{className:"flex flex-col min-h-screen",children:[(0,l.jsx)(i,{userID:y,userRole:s,userEmail:o,showSSOBanner:x}),(0,l.jsxs)("div",{className:"flex flex-1 overflow-auto",children:[(0,l.jsx)(eF,{setPage:Z,userRole:s,defaultSelectedKey:null}),"api-keys"==w?(0,l.jsx)(eh,{userID:y,userRole:s,teams:d,keys:m,setUserRole:n,userEmail:o,setUserEmail:c,setTeams:h,setKeys:u}):"models"==w?(0,l.jsx)(ep,{userID:y,userRole:s,token:g,accessToken:f}):"llm-playground"==w?(0,l.jsx)(eT,{userID:y,userRole:s,token:g,accessToken:f}):"users"==w?(0,l.jsx)(e_,{userID:y,userRole:s,token:g,keys:m,accessToken:f,setKeys:u}):"teams"==w?(0,l.jsx)(eb,{teams:d,setTeams:h,searchParams:j,accessToken:f,userID:y,userRole:s}):"admin-panel"==w?(0,l.jsx)(eS,{setTeams:h,searchParams:j,accessToken:f}):(0,l.jsx)(eO,{userID:y,userRole:s,token:g,accessToken:f})]})]})})}}},function(e){e.O(0,[730,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 92bf64b20..c7e3747d6 100644 --- a/ui/litellm-dashboard/out/index.html +++ b/ui/litellm-dashboard/out/index.html @@ -1 +1 @@ -🚅 LiteLLM \ No newline at end of file +🚅 LiteLLM \ No newline at end of file diff --git a/ui/litellm-dashboard/out/index.txt b/ui/litellm-dashboard/out/index.txt index c68d627f6..2c6c4f5bb 100644 --- a/ui/litellm-dashboard/out/index.txt +++ b/ui/litellm-dashboard/out/index.txt @@ -1,7 +1,7 @@ 2:I[77831,[],""] -3:I[92182,["730","static/chunks/730-1411b729a1c79695.js","931","static/chunks/app/page-2b5b48b67d7eccff.js"],""] +3:I[92182,["730","static/chunks/730-1411b729a1c79695.js","931","static/chunks/app/page-7811c13c82288ada.js"],""] 4:I[5613,[],""] 5:I[31778,[],""] -0:["tpFpoAscsg2XQqXwfShjz",[[["",{"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_c23dc8","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/68a21c6e6697f7ca.css","precedence":"next","crossOrigin":""}]],"$L6"]]]] +0:["NOy_Z-02UirnQn7wjpTs0",[[["",{"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_c23dc8","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/68a21c6e6697f7ca.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"}],["$","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/src/components/teams.tsx b/ui/litellm-dashboard/src/components/teams.tsx index 80993c891..d3e00772e 100644 --- a/ui/litellm-dashboard/src/components/teams.tsx +++ b/ui/litellm-dashboard/src/components/teams.tsx @@ -102,7 +102,7 @@ const Team: React.FC = ({ const handleCreate = async (formValues: Record) => { try { if (accessToken != null) { - //message.info("Making API Call"); + message.info("Creating Team"); const response: any = await teamCreateCall(accessToken, formValues); if (teams !== null) { setTeams([...teams, response]); From 1e8749dfe021af5fba9d6f7d4639df0e6a185423 Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Thu, 28 Mar 2024 08:18:36 -0700 Subject: [PATCH 28/54] (feat) new ui build --- litellm/proxy/_experimental/out/404.html | 2 +- .../_buildManifest.js | 0 .../_ssgManifest.js | 0 .../{page-7811c13c82288ada.js => page-a94f48a4c941dbe4.js} | 2 +- litellm/proxy/_experimental/out/index.html | 2 +- litellm/proxy/_experimental/out/index.txt | 4 ++-- ui/litellm-dashboard/out/404.html | 2 +- .../_buildManifest.js | 0 .../_ssgManifest.js | 0 .../{page-7811c13c82288ada.js => page-a94f48a4c941dbe4.js} | 2 +- ui/litellm-dashboard/out/index.html | 2 +- ui/litellm-dashboard/out/index.txt | 4 ++-- ui/litellm-dashboard/src/components/teams.tsx | 2 +- 13 files changed, 11 insertions(+), 11 deletions(-) rename litellm/proxy/_experimental/out/_next/static/{NOy_Z-02UirnQn7wjpTs0 => IXxGmLpL0ryrAsqCmdljD}/_buildManifest.js (100%) rename litellm/proxy/_experimental/out/_next/static/{NOy_Z-02UirnQn7wjpTs0 => IXxGmLpL0ryrAsqCmdljD}/_ssgManifest.js (100%) rename litellm/proxy/_experimental/out/_next/static/chunks/app/{page-7811c13c82288ada.js => page-a94f48a4c941dbe4.js} (54%) rename ui/litellm-dashboard/out/_next/static/{NOy_Z-02UirnQn7wjpTs0 => IXxGmLpL0ryrAsqCmdljD}/_buildManifest.js (100%) rename ui/litellm-dashboard/out/_next/static/{NOy_Z-02UirnQn7wjpTs0 => IXxGmLpL0ryrAsqCmdljD}/_ssgManifest.js (100%) rename ui/litellm-dashboard/out/_next/static/chunks/app/{page-7811c13c82288ada.js => page-a94f48a4c941dbe4.js} (54%) diff --git a/litellm/proxy/_experimental/out/404.html b/litellm/proxy/_experimental/out/404.html index a53766463..3e5ac000f 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

404

This page could not be found.

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

404

This page could not be found.

\ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/NOy_Z-02UirnQn7wjpTs0/_buildManifest.js b/litellm/proxy/_experimental/out/_next/static/IXxGmLpL0ryrAsqCmdljD/_buildManifest.js similarity index 100% rename from litellm/proxy/_experimental/out/_next/static/NOy_Z-02UirnQn7wjpTs0/_buildManifest.js rename to litellm/proxy/_experimental/out/_next/static/IXxGmLpL0ryrAsqCmdljD/_buildManifest.js diff --git a/litellm/proxy/_experimental/out/_next/static/NOy_Z-02UirnQn7wjpTs0/_ssgManifest.js b/litellm/proxy/_experimental/out/_next/static/IXxGmLpL0ryrAsqCmdljD/_ssgManifest.js similarity index 100% rename from litellm/proxy/_experimental/out/_next/static/NOy_Z-02UirnQn7wjpTs0/_ssgManifest.js rename to litellm/proxy/_experimental/out/_next/static/IXxGmLpL0ryrAsqCmdljD/_ssgManifest.js diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/app/page-7811c13c82288ada.js b/litellm/proxy/_experimental/out/_next/static/chunks/app/page-a94f48a4c941dbe4.js similarity index 54% rename from litellm/proxy/_experimental/out/_next/static/chunks/app/page-7811c13c82288ada.js rename to litellm/proxy/_experimental/out/_next/static/chunks/app/page-a94f48a4c941dbe4.js index 8aae09847..755ccbe7e 100644 --- a/litellm/proxy/_experimental/out/_next/static/chunks/app/page-7811c13c82288ada.js +++ b/litellm/proxy/_experimental/out/_next/static/chunks/app/page-a94f48a4c941dbe4.js @@ -1 +1 @@ -(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[931],{20661:function(e,t,s){Promise.resolve().then(s.bind(s,92182))},92182:function(e,t,s){"use strict";s.r(t),s.d(t,{default:function(){return eM}});var l=s(3827),r=s(64090),a=s(47907),n=s(8792),o=s(2179),i=e=>{let{userID:t,userRole:s,userEmail:r,showSSOBanner:a}=e;return console.log("User ID:",t),console.log("userEmail:",r),(0,l.jsxs)("nav",{className:"left-0 right-0 top-0 flex justify-between items-center h-12 mb-4",children:[(0,l.jsx)("div",{className:"text-left my-2 absolute top-0 left-0",children:(0,l.jsx)("div",{className:"flex flex-col items-center",children:(0,l.jsx)(n.default,{href:"/",children:(0,l.jsx)("button",{className:"text-gray-800 text-2xl py-1 rounded text-center",children:(0,l.jsx)("img",{src:"/get_image",width:200,height:200,alt:"LiteLLM Brand",className:"mr-2"})})})})}),(0,l.jsxs)("div",{className:"text-right mx-4 my-2 absolute top-0 right-0 flex items-center justify-end space-x-2",children:[a?(0,l.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/ui#setup-ssoauth-for-ui",target:"_blank",className:"mr-2"}):null,(0,l.jsxs)(o.Z,{variant:"secondary",size:"lg",children:[r,(0,l.jsxs)("p",{children:["Role: ",s]}),(0,l.jsxs)("p",{children:["ID: ",t]})]})]})]})},c=s(80588);let d=async(e,t,s)=>{try{if(console.log("Form Values in keyCreateCall:",s),s.description&&(s.metadata||(s.metadata={}),s.metadata.description=s.description,delete s.description,s.metadata=JSON.stringify(s.metadata)),s.metadata){console.log("formValues.metadata:",s.metadata);try{s.metadata=JSON.parse(s.metadata)}catch(e){throw c.ZP.error("Failed to parse metadata: "+e),Error("Failed to parse metadata: "+e)}}console.log("Form Values after check:",s);let l=await fetch("/key/generate",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({user_id:t,...s})});if(!l.ok){let e=await l.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let r=await l.json();return console.log("API Response:",r),r}catch(e){throw console.error("Failed to create key:",e),e}},h=async(e,t,s)=>{try{if(console.log("Form Values in keyCreateCall:",s),s.description&&(s.metadata||(s.metadata={}),s.metadata.description=s.description,delete s.description,s.metadata=JSON.stringify(s.metadata)),s.metadata){console.log("formValues.metadata:",s.metadata);try{s.metadata=JSON.parse(s.metadata)}catch(e){throw c.ZP.error("Failed to parse metadata: "+e),Error("Failed to parse metadata: "+e)}}console.log("Form Values after check:",s);let l=await fetch("/user/new",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({user_id:t,...s})});if(!l.ok){let e=await l.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let r=await l.json();return console.log("API Response:",r),r}catch(e){throw console.error("Failed to create key:",e),e}},m=async(e,t)=>{try{console.log("in keyDeleteCall:",t);let s=await fetch("/key/delete",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({keys:[t]})});if(!s.ok){let e=await s.text();throw c.ZP.error("Failed to delete key: "+e),Error("Network response was not ok")}let l=await s.json();return console.log(l),l}catch(e){throw console.error("Failed to create key:",e),e}},u=async function(e,t,s){let l=arguments.length>3&&void 0!==arguments[3]&&arguments[3];try{let r="/user/info";"App Owner"==s&&t&&(r="".concat(r,"?user_id=").concat(t)),console.log("in userInfoCall viewAll=",l),l&&(r="".concat(r,"?view_all=true"));let a=await fetch(r,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!a.ok){let e=await a.text();throw c.ZP.error(e),Error("Network response was not ok")}let n=await a.json();return console.log("API Response:",n),n}catch(e){throw console.error("Failed to create key:",e),e}},x=async e=>{try{let t=await fetch("/global/spend",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},p=async(e,t,s)=>{try{let t=await fetch("/v2/model/info",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},j=async(e,t,s)=>{try{let t=await fetch("/model/metrics",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},y=async(e,t,s)=>{try{let t=await fetch("/models",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},g=async(e,t)=>{try{let s="/global/spend/logs";console.log("in keySpendLogsCall:",s);let l=await fetch("".concat(s,"?api_key=").concat(t),{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw c.ZP.error(e),Error("Network response was not ok")}let r=await l.json();return console.log(r),r}catch(e){throw console.error("Failed to create key:",e),e}},w=async e=>{try{let t="/global/spend/teams";console.log("in teamSpendLogsCall:",t);let s=await fetch("".concat(t),{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!s.ok){let e=await s.text();throw c.ZP.error(e),Error("Network response was not ok")}let l=await s.json();return console.log(l),l}catch(e){throw console.error("Failed to create key:",e),e}},Z=async(e,t,s,l,r,a)=>{try{console.log("user role in spend logs call: ".concat(s));let t="/spend/logs";t="App Owner"==s?"".concat(t,"?user_id=").concat(l,"&start_date=").concat(r,"&end_date=").concat(a):"".concat(t,"?start_date=").concat(r,"&end_date=").concat(a);let n=await fetch(t,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!n.ok){let e=await n.text();throw c.ZP.error(e),Error("Network response was not ok")}let o=await n.json();return console.log(o),o}catch(e){throw console.error("Failed to create key:",e),e}},f=async e=>{try{let t=await fetch("/global/spend/logs",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to create key:",e),e}},k=async e=>{try{let t=await fetch("/global/spend/keys?limit=5",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to create key:",e),e}},_=async(e,t)=>{try{t&&JSON.stringify({api_key:t});let s={method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}};t&&(s.body=JSON.stringify({api_key:t}));let l=await fetch("/global/spend/end_users",s);if(!l.ok){let e=await l.text();throw c.ZP.error(e),Error("Network response was not ok")}let r=await l.json();return console.log(r),r}catch(e){throw console.error("Failed to create key:",e),e}},b=async e=>{try{let t=await fetch("/global/spend/models?limit=5",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to create key:",e),e}},v=async(e,t)=>{try{let s=await fetch("/v2/key/info",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({keys:t})});if(!s.ok){let e=await s.text();throw c.ZP.error(e),Error("Network response was not ok")}let l=await s.json();return console.log(l),l}catch(e){throw console.error("Failed to create key:",e),e}},S=async(e,t,s,l)=>{try{let r=await fetch("/user/request_model",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({models:[t],user_id:s,justification:l})});if(!r.ok){let e=await r.text();throw c.ZP.error("Failed to delete key: "+e),Error("Network response was not ok")}let a=await r.json();return console.log(a),a}catch(e){throw console.error("Failed to create key:",e),e}},N=async e=>{try{let t="/user/get_requests";console.log("in userGetRequesedtModelsCall:",t);let s=await fetch(t,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!s.ok){let e=await s.text();throw c.ZP.error("Failed to delete key: "+e),Error("Network response was not ok")}let l=await s.json();return console.log(l),l}catch(e){throw console.error("Failed to get requested models:",e),e}},A=async(e,t)=>{try{let s="/user/get_users?role=".concat(t);console.log("in userGetAllUsersCall:",s);let l=await fetch(s,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw c.ZP.error("Failed to delete key: "+e),Error("Network response was not ok")}let r=await l.json();return console.log(r),r}catch(e){throw console.error("Failed to get requested models:",e),e}},C=async(e,t)=>{try{console.log("Form Values in teamCreateCall:",t);let s=await fetch("/team/new",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...t})});if(!s.ok){let e=await s.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let l=await s.json();return console.log("API Response:",l),l}catch(e){throw console.error("Failed to create key:",e),e}},T=async(e,t,s)=>{try{console.log("Form Values in teamMemberAddCall:",s);let l=await fetch("/team/member_add",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({team_id:t,member:s})});if(!l.ok){let e=await l.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let r=await l.json();return console.log("API Response:",r),r}catch(e){throw console.error("Failed to create key:",e),e}},I=async(e,t)=>{try{console.log("Form Values in userUpdateUserCall:",t);let s=await fetch("/user/update",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({user_role:"proxy_admin_viewer",...t})});if(!s.ok){let e=await s.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let l=await s.json();return console.log("API Response:",l),l}catch(e){throw console.error("Failed to create key:",e),e}},P=async(e,t)=>{try{let s=await fetch("/global/predict/spend/logs",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({data:t})});if(!s.ok){let e=await s.text();throw c.ZP.error(e),Error("Network response was not ok")}let l=await s.json();return console.log(l),l}catch(e){throw console.error("Failed to create key:",e),e}},E=async e=>{try{console.log("Checking Slack Budget Alerts service health");let t=await fetch("/health/services?service=slack_budget_alerts",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error("Failed Slack Alert test: "+e),Error(e)}let s=await t.json();return c.ZP.success("Test Slack Alert worked - check your Slack!"),console.log("Service Health Response:",s),s}catch(e){throw console.error("Failed to perform health check:",e),e}};var F=s(10384),O=s(46453),M=s(13810),R=s(71801),D=s(42440),U=s(17189),L=s(12143),B=s(77171),z=s(42539),K=s(88707),W=s(1861);let{Option:V}=U.default;var q=e=>{let{userID:t,teamID:s,userRole:a,accessToken:n,data:i,userModels:h,setData:m}=e,[u]=L.Z.useForm(),[x,p]=(0,r.useState)(!1),[j,y]=(0,r.useState)(null),[g,w]=(0,r.useState)(null),Z=()=>{p(!1),u.resetFields()},f=()=>{p(!1),y(null),u.resetFields()},k=async e=>{try{c.ZP.info("Making API Call"),p(!0);let s=await d(n,t,e);console.log("key create Response:",s),m(e=>e?[...e,s]:[s]),y(s.key),w(s.soft_budget),c.ZP.success("API Key Created"),u.resetFields(),localStorage.removeItem("userData"+t)}catch(e){console.error("Error creating the key:",e)}},_=async()=>{try{console.log("Sending Slack alert...");let e=await E(n);console.log("slackBudgetAlertsHealthCheck Response:",e),console.log("Testing Slack alert successful")}catch(e){console.error("Error sending Slack alert:",e)}};return(0,l.jsxs)("div",{children:[(0,l.jsx)(o.Z,{className:"mx-auto",onClick:()=>p(!0),children:"+ Create New Key"}),(0,l.jsx)(B.Z,{title:"Create Key",visible:x,width:800,footer:null,onOk:Z,onCancel:f,children:(0,l.jsxs)(L.Z,{form:u,onFinish:k,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:["App Owner"===a||"Admin"===a?(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(L.Z.Item,{label:"Key Name",name:"key_alias",children:(0,l.jsx)(z.Z,{})}),(0,l.jsx)(L.Z.Item,{label:"Team ID",name:"team_id",children:(0,l.jsx)(z.Z,{placeholder:"ai_team",defaultValue:s||""})}),(0,l.jsx)(L.Z.Item,{label:"Models",name:"models",children:(0,l.jsx)(U.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:h.map(e=>(0,l.jsx)(V,{value:e,children:e},e))})}),(0,l.jsx)(L.Z.Item,{label:"Soft Budget (USD) Monthly",name:"soft_budget",initialValue:50,children:(0,l.jsx)(K.Z,{step:.01,precision:2,defaultValue:50,width:200})}),(0,l.jsx)(L.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,l.jsx)(K.Z,{step:.01,precision:2,width:200})}),(0,l.jsx)(L.Z.Item,{label:"Reset Budget",name:"budget_duration",children:(0,l.jsxs)(U.default,{defaultValue:null,placeholder:"n/a",children:[(0,l.jsx)(U.default.Option,{value:"24h",children:"daily"}),(0,l.jsx)(U.default.Option,{value:"30d",children:"monthly"})]})}),(0,l.jsx)(L.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})}),(0,l.jsx)(L.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})}),(0,l.jsx)(L.Z.Item,{label:"Expire Key (eg: 30s, 30h, 30d)",name:"duration",children:(0,l.jsx)(z.Z,{})}),(0,l.jsx)(L.Z.Item,{label:"Metadata",name:"metadata",children:(0,l.jsx)(z.Z.TextArea,{rows:4,placeholder:"Enter metadata as JSON"})})]}):(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(L.Z.Item,{label:"Key Name",name:"key_alias",children:(0,l.jsx)(z.Z,{})}),(0,l.jsx)(L.Z.Item,{label:"Team ID (Contact Group)",name:"team_id",children:(0,l.jsx)(z.Z,{placeholder:"ai_team"})}),(0,l.jsx)(L.Z.Item,{label:"Description",name:"description",children:(0,l.jsx)(z.Z.TextArea,{placeholder:"Enter description",rows:4})})]}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(W.ZP,{htmlType:"submit",children:"Create Key"})})]})}),j&&(0,l.jsx)(B.Z,{visible:x,onOk:Z,onCancel:f,footer:null,children:(0,l.jsx)(O.Z,{numItems:1,className:"gap-2 w-full",children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Save your Key"}),(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsxs)("p",{children:["Please save this secret key somewhere safe and accessible. For security reasons, ",(0,l.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,l.jsx)(F.Z,{numColSpan:1,children:null!=j?(0,l.jsxs)("div",{children:[(0,l.jsxs)(R.Z,{children:["API Key: ",j]}),(0,l.jsx)(D.Z,{className:"mt-6",children:"Budgets"}),(0,l.jsxs)(R.Z,{children:["Soft Limit Budget: $",g]}),(0,l.jsx)(o.Z,{className:"mt-3",onClick:_,children:"Test Slack Alert"}),(0,l.jsxs)(R.Z,{className:"mt-2",children:["(LiteLLM Docs -",(0,l.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/alerting",target:"_blank",className:"text-blue-500",children:"Set Up Slack Alerting)"})]})]}):(0,l.jsx)(R.Z,{children:"Key being created, this might take 30s"})})]})})})]})},J=s(33393),G=s(61244),$=s(10827),H=s(3851),Y=s(2044),X=s(64167),Q=s(74480),ee=s(7178),et=s(9853),es=s(56863),el=e=>{let{token:t,accessToken:s,keySpend:a,keyBudget:n,keyName:i}=e,[c,d]=(0,r.useState)(!1),[h,m]=(0,r.useState)(null),[u,x]=(0,r.useState)(""),[p,j]=(0,r.useState)(null),y=async()=>{try{if(null==s||null==t)return;console.log("accessToken: ".concat(s,"; token: ").concat(t));let e=await g(s,t);console.log("Response:",e),m(e);let l=await P(s,e);console.log("Response2:",l);let r=[...e,...l.response];m(r),x(l.predicted_spend),console.log("Combined Data:",r)}catch(e){console.error("There was an error fetching the data",e)}};return t?(0,l.jsxs)("div",{children:[(0,l.jsx)(o.Z,{size:"xs",onClick:()=>{console.log("Show Modal triggered"),d(!0),y()},variant:"secondary",children:"Spend Report"}),(0,l.jsxs)(B.Z,{visible:c,width:1400,onOk:()=>{d(!1)},onCancel:()=>{d(!1)},footer:null,children:[(0,l.jsxs)(D.Z,{style:{textAlign:"left"},children:["Key Name: ",i]}),(0,l.jsxs)(es.Z,{children:["Monthly Spend $",a]}),(0,l.jsx)(D.Z,{children:u}),(0,l.jsx)(M.Z,{className:"mt-6 mb-6",children:h&&(0,l.jsx)(et.Z,{className:"mt-6",data:h,colors:["blue","amber"],index:"date",categories:["spend","predicted_spend"],yAxisWidth:80})})]})]}):null},er=e=>{let{userID:t,accessToken:s,data:a,setData:n}=e,[i,c]=(0,r.useState)(!1),[d,h]=(0,r.useState)(!1),[u,x]=(0,r.useState)(null),p=async e=>{null!=a&&(x(e),localStorage.removeItem("userData"+t),h(!0))},j=async()=>{if(null!=u&&null!=a){try{await m(s,u);let e=a.filter(e=>e.token!==u);n(e)}catch(e){console.error("Error deleting the key:",e)}h(!1),x(null)}};if(null!=a)return console.log("RERENDER TRIGGERED"),(0,l.jsxs)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh] mb-4",children:[(0,l.jsxs)($.Z,{className:"mt-5",children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"Key Alias"}),(0,l.jsx)(Q.Z,{children:"Secret Key"}),(0,l.jsx)(Q.Z,{children:"Spend (USD)"}),(0,l.jsx)(Q.Z,{children:"Key Budget (USD)"}),(0,l.jsx)(Q.Z,{children:"Spend Report"}),(0,l.jsx)(Q.Z,{children:"Team ID"}),(0,l.jsx)(Q.Z,{children:"Metadata"}),(0,l.jsx)(Q.Z,{children:"Models"}),(0,l.jsx)(Q.Z,{children:"TPM / RPM Limits"}),(0,l.jsx)(Q.Z,{children:"Expires"})]})}),(0,l.jsx)(H.Z,{children:a.map(e=>(console.log(e),"litellm-dashboard"===e.team_id)?null:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",whiteSpace:"pre-wrap",overflow:"hidden"},children:null!=e.key_alias?(0,l.jsx)(R.Z,{children:e.key_alias}):(0,l.jsx)(R.Z,{children:"Not Set"})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:e.key_name})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:(()=>{try{return parseFloat(e.spend).toFixed(4)}catch(t){return e.spend}})()})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",whiteSpace:"pre-wrap",overflow:"hidden"},children:null!=e.max_budget?(0,l.jsx)(R.Z,{children:e.max_budget}):(0,l.jsx)(R.Z,{children:"Unlimited Budget"})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px"},children:(0,l.jsx)(el,{token:e.token,accessToken:s,keySpend:e.spend,keyBudget:e.max_budget,keyName:e.key_name})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:e.team_id})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:JSON.stringify(e.metadata).slice(0,400)})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:JSON.stringify(e.models)})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",overflowWrap:"break-word"},children:(0,l.jsxs)(R.Z,{children:["TPM Limit: ",e.tpm_limit?e.tpm_limit:"Unlimited"," ",(0,l.jsx)("br",{})," RPM Limit:"," ",e.rpm_limit?e.rpm_limit:"Unlimited"]})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",wordWrap:"break-word"},children:null!=e.expires?(0,l.jsx)(R.Z,{children:e.expires}):(0,l.jsx)(R.Z,{children:"Never"})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",wordWrap:"break-word"},children:(0,l.jsx)(G.Z,{onClick:()=>p(e.token),icon:J.Z,size:"sm"})})]},e.token))})]}),d&&(0,l.jsx)("div",{className:"fixed z-10 inset-0 overflow-y-auto",children:(0,l.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,l.jsx)("div",{className:"fixed inset-0 transition-opacity","aria-hidden":"true",children:(0,l.jsx)("div",{className:"absolute inset-0 bg-gray-500 opacity-75"})}),(0,l.jsx)("span",{className:"hidden sm:inline-block sm:align-middle sm:h-screen","aria-hidden":"true",children:"​"}),(0,l.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,l.jsx)("div",{className:"bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4",children:(0,l.jsx)("div",{className:"sm:flex sm:items-start",children:(0,l.jsxs)("div",{className:"mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left",children:[(0,l.jsx)("h3",{className:"text-lg leading-6 font-medium text-gray-900",children:"Delete Key"}),(0,l.jsx)("div",{className:"mt-2",children:(0,l.jsx)("p",{className:"text-sm text-gray-500",children:"Are you sure you want to delete this key ?"})})]})})}),(0,l.jsxs)("div",{className:"bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse",children:[(0,l.jsx)(o.Z,{onClick:j,color:"red",className:"ml-2",children:"Delete"}),(0,l.jsx)(o.Z,{onClick:()=>{h(!1),x(null)},children:"Cancel"})]})]})]})})]})},ea=e=>{let{userID:t,userSpendData:s,userRole:a,accessToken:n}=e,[o,i]=(0,r.useState)(null==s?void 0:s.spend),[c,d]=(0,r.useState)((null==s?void 0:s.max_budget)||null);(0,r.useEffect)(()=>{(async()=>{if("Admin"===a)try{let e=await x(n);i(e.spend),d(e.max_budget||null)}catch(e){console.error("Error fetching global spend data:",e)}})()},[a,n]);let h=void 0!==o?o.toFixed(4):null;return(0,l.jsx)(l.Fragment,{children:(0,l.jsxs)(M.Z,{className:"mx-auto mb-4",children:[(0,l.jsxs)(es.Z,{children:["$",h]}),(0,l.jsxs)(D.Z,{children:["/ ",null!==c?"$".concat(c," limit"):"No limit"]})]})})},en=s(36083),eo=s(68967),ei=s(27166),ec=e=>{let{teams:t,setSelectedTeam:s}=e,{Title:a,Paragraph:n}=en.default,[o,i]=(0,r.useState)("");return(0,l.jsxs)("div",{className:"mt-10",children:[(0,l.jsx)(a,{level:4,children:"Default Team"}),(0,l.jsx)(n,{children:"If you belong to multiple teams, this setting controls which team is used by default when creating new API Keys."}),t&&t.length>0?(0,l.jsx)(eo.Z,{defaultValue:"0",children:t.map((e,t)=>(0,l.jsx)(ei.Z,{value:String(t),onClick:()=>s(e),children:e.team_alias},t))}):(0,l.jsxs)(n,{children:["No team created. ",(0,l.jsx)("b",{children:"Defaulting to personal account."})]})]})},ed=s(37963);console.log("isLocal:",!1);var eh=e=>{let{userID:t,userRole:s,teams:n,keys:o,setUserRole:i,userEmail:c,setUserEmail:d,setTeams:h,setKeys:m}=e,[p,j]=(0,r.useState)(null),g=(0,a.useSearchParams)();g.get("viewSpend"),(0,a.useRouter)();let w=g.get("token"),[Z,f]=(0,r.useState)(null),[k,_]=(0,r.useState)([]),[b,v]=(0,r.useState)(n?n[0]:null);if(window.addEventListener("beforeunload",function(){sessionStorage.clear()}),(0,r.useEffect)(()=>{if(w){let e=(0,ed.o)(w);if(e){if(console.log("Decoded token:",e),console.log("Decoded key:",e.key),f(e.key),e.user_role){let t=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";default:return"Unknown Role"}}(e.user_role);console.log("Decoded user_role:",t),i(t)}else console.log("User role not defined");e.user_email?d(e.user_email):console.log("User Email is not set ".concat(e))}}if(t&&Z&&s&&!o&&!p){let e=sessionStorage.getItem("userModels"+t);e?_(JSON.parse(e)):(async()=>{try{let e=await u(Z,t,s);if(console.log("received teams in user dashboard: ".concat(Object.keys(e),"; team values: ").concat(Object.entries(e.teams))),"Admin"==s){let e=await x(Z);j(e),console.log("globalSpend:",e)}else j(e.user_info);m(e.keys),h(e.teams),v(e.teams?e.teams[0]:null),sessionStorage.setItem("userData"+t,JSON.stringify(e.keys)),sessionStorage.setItem("userSpendData"+t,JSON.stringify(e.user_info));let l=(await y(Z,t,s)).data.map(e=>e.id);console.log("available_model_names:",l),_(l),console.log("userModels:",k),sessionStorage.setItem("userModels"+t,JSON.stringify(l))}catch(e){console.error("There was an error fetching the data",e)}})()}},[t,w,Z,o,s]),null==t||null==w){let e="/sso/key/generate";return console.log("Full URL:",e),window.location.href=e,null}if(null==Z)return null;if(null==s&&i("App Owner"),s&&"Admin Viewer"==s){let{Title:e,Paragraph:t}=en.default;return(0,l.jsxs)("div",{children:[(0,l.jsx)(e,{level:1,children:"Access Denied"}),(0,l.jsx)(t,{children:"Ask your proxy admin for access to create keys"})]})}return(0,l.jsx)("div",{children:(0,l.jsx)(O.Z,{numItems:1,className:"gap-0 p-10 h-[75vh] w-full",children:(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(ea,{userID:t,userSpendData:p,userRole:s,accessToken:Z}),(0,l.jsx)(er,{userID:t,accessToken:Z,data:o,setData:m}),(0,l.jsx)(q,{userID:t,teamID:b?b.team_id:null,userRole:s,userModels:k,accessToken:Z,data:o,setData:m}),(0,l.jsx)(ec,{teams:n,setSelectedTeam:v})]})})})},em=s(5);let{Option:eu}=U.default;var ex=e=>{let{userModels:t,accessToken:s,userID:a}=e,[n]=L.Z.useForm(),[i,d]=(0,r.useState)(!1),h=async e=>{try{c.ZP.info("Requesting access");let{selectedModel:t,accessReason:l}=e;await S(s,t,a,l),d(!0)}catch(e){console.error("Error requesting access:",e)}};return(0,l.jsxs)("div",{children:[(0,l.jsx)(o.Z,{size:"xs",onClick:()=>d(!0),children:"Request Access"}),(0,l.jsx)(B.Z,{title:"Request Access",visible:i,width:800,footer:null,onOk:()=>{d(!1),n.resetFields()},onCancel:()=>{d(!1),n.resetFields()},children:(0,l.jsxs)(L.Z,{form:n,onFinish:h,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsx)(L.Z.Item,{label:"Select Model",name:"selectedModel",children:(0,l.jsx)(U.default,{placeholder:"Select model",style:{width:"100%"},children:t.map(e=>(0,l.jsx)(eu,{value:e,children:e},e))})}),(0,l.jsx)(L.Z.Item,{label:"Reason for Access",name:"accessReason",children:(0,l.jsx)(z.Z.TextArea,{rows:4,placeholder:"Enter reason for access"})}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(o.Z,{children:"Request Access"})})]})})]})},ep=e=>{let{accessToken:t,token:s,userRole:a,userID:n}=e,[o,i]=(0,r.useState)({data:[]}),[c,d]=(0,r.useState)([]),[h,m]=(0,r.useState)([]);if((0,r.useEffect)(()=>{if(!t||!s||!a||!n)return;let e=async()=>{try{let e=await p(t,n,a);console.log("Model data response:",e.data),i(e);let s=await j(t,n,a);if(console.log("Model metrics response:",s),d(s),"Admin"===a&&t){let e=await N(t);console.log("Pending Requests:",h),m(e.requests||[])}}catch(e){console.error("There was an error fetching the model data",e)}};t&&s&&a&&n&&e()},[t,s,a,n]),!o||!t||!s||!a||!n)return(0,l.jsx)("div",{children:"Loading..."});let u=[];for(let e=0;e(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{children:(0,l.jsx)(D.Z,{children:e.model_name})}),(0,l.jsx)(Y.Z,{children:e.provider}),"Admin"===a&&(0,l.jsx)(Y.Z,{children:e.api_base}),(0,l.jsx)(Y.Z,{children:e.user_access?(0,l.jsx)(em.Z,{color:"green",children:"Yes"}):(0,l.jsx)(ex,{userModels:u,accessToken:t,userID:n})}),(0,l.jsx)(Y.Z,{children:e.input_cost}),(0,l.jsx)(Y.Z,{children:e.output_cost}),(0,l.jsx)(Y.Z,{children:e.max_tokens})]},e.model_name))})]})}),(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Model Statistics (Number Requests)"}),(0,l.jsx)(et.Z,{data:c,index:"model",categories:["num_requests"],colors:["blue"],yAxisWidth:400,layout:"vertical",tickGap:5})]}),(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Model Statistics (Latency)"}),(0,l.jsx)(et.Z,{data:c,index:"model",categories:["avg_latency_seconds"],colors:["red"],yAxisWidth:400,layout:"vertical",tickGap:5})]})]})})},ej=s(92836),ey=s(26734),eg=s(41608),ew=s(32126),eZ=s(23682);let{Option:ef}=U.default;var ek=e=>{let{userID:t,accessToken:s}=e,[a]=L.Z.useForm(),[n,i]=(0,r.useState)(!1),[d,m]=(0,r.useState)(null),[u,x]=(0,r.useState)([]);(0,r.useEffect)(()=>{(async()=>{try{let e=await y(s,t,"any"),l=[];for(let t=0;t{i(!1),a.resetFields()},j=()=>{i(!1),m(null),a.resetFields()},g=async e=>{try{c.ZP.info("Making API Call"),i(!0),console.log("formValues in create user:",e);let l=await h(s,t,e);console.log("user create Response:",l),m(l.key),c.ZP.success("API user Created"),a.resetFields(),localStorage.removeItem("userData"+t)}catch(e){console.error("Error creating the user:",e)}};return(0,l.jsxs)("div",{children:[(0,l.jsx)(o.Z,{className:"mx-auto",onClick:()=>i(!0),children:"+ Create New User"}),(0,l.jsx)(B.Z,{title:"Create User",visible:n,width:800,footer:null,onOk:p,onCancel:j,children:(0,l.jsxs)(L.Z,{form:a,onFinish:g,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsx)(L.Z.Item,{label:"User ID",name:"user_id",children:(0,l.jsx)(z.Z,{placeholder:"Enter User ID"})}),(0,l.jsx)(L.Z.Item,{label:"Team ID",name:"team_id",children:(0,l.jsx)(z.Z,{placeholder:"ai_team"})}),(0,l.jsx)(L.Z.Item,{label:"Models",name:"models",children:(0,l.jsx)(U.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:u.map(e=>(0,l.jsx)(ef,{value:e,children:e},e))})}),(0,l.jsx)(L.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,l.jsx)(K.Z,{step:.01,precision:2,width:200})}),(0,l.jsx)(L.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})}),(0,l.jsx)(L.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})}),(0,l.jsx)(L.Z.Item,{label:"Duration (eg: 30s, 30h, 30d)",name:"duration",children:(0,l.jsx)(z.Z,{})}),(0,l.jsx)(L.Z.Item,{label:"Metadata",name:"metadata",children:(0,l.jsx)(z.Z.TextArea,{rows:4,placeholder:"Enter metadata as JSON"})}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(W.ZP,{htmlType:"submit",children:"Create User"})})]})}),d&&(0,l.jsxs)(B.Z,{title:"Save Your User",visible:n,onOk:p,onCancel:j,footer:null,children:[(0,l.jsxs)("p",{children:["Please save this secret user somewhere safe and accessible. For security reasons, ",(0,l.jsx)("b",{children:"you will not be able to view it again"})," ","through your LiteLLM account. If you lose this secret user, you will need to generate a new one."]}),(0,l.jsx)("p",{children:null!=d?"API user: ".concat(d):"User being created, this might take 30s"})]})]})},e_=e=>{let{accessToken:t,token:s,keys:a,userRole:n,userID:o,setKeys:i}=e,[c,d]=(0,r.useState)(null),[h,m]=(0,r.useState)(null),[x,p]=(0,r.useState)(1);if((0,r.useEffect)(()=>{if(!t||!s||!n||!o)return;let e=async()=>{try{let e=await u(t,null,n,!0);console.log("user data response:",e),d(e)}catch(e){console.error("There was an error fetching the model data",e)}};t&&s&&n&&o&&!c&&e();let l=async()=>{try{let e=await _(t,null);console.log("user data response:",e),m(e)}catch(e){console.error("There was an error fetching the model data",e)}};n&&("Admin"==n||"Admin Viewer"==n)&&!h&&l()},[t,s,n,o]),!c||!t||!s||!n||!o)return(0,l.jsx)("div",{children:"Loading..."});let j=async e=>{try{let s=await _(t,e);console.log("user data response:",s),m(s)}catch(e){console.error("There was an error fetching the model data",e)}};return(0,l.jsx)("div",{style:{width:"100%"},children:(0,l.jsxs)(O.Z,{className:"gap-2 p-10 h-[75vh] w-full",children:[(0,l.jsx)(ek,{userID:o,accessToken:t}),(0,l.jsx)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh] mb-4",children:(0,l.jsxs)(ey.Z,{children:[(0,l.jsxs)(eg.Z,{variant:"line",defaultValue:"1",children:[(0,l.jsx)(ej.Z,{value:"1",children:"Key Owners"}),(0,l.jsx)(ej.Z,{value:"2",children:"End-Users"})]}),(0,l.jsxs)(eZ.Z,{children:[(0,l.jsx)(ew.Z,{children:(0,l.jsxs)($.Z,{className:"mt-5",children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"User ID"}),(0,l.jsx)(Q.Z,{children:"User Role"}),(0,l.jsx)(Q.Z,{children:"User Models"}),(0,l.jsx)(Q.Z,{children:"User Spend ($ USD)"}),(0,l.jsx)(Q.Z,{children:"User Max Budget ($ USD)"})]})}),(0,l.jsx)(H.Z,{children:c.map(e=>(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{children:e.user_id}),(0,l.jsx)(Y.Z,{children:e.user_role?e.user_role:"app_owner"}),(0,l.jsx)(Y.Z,{children:e.models&&e.models.length>0?e.models:"All Models"}),(0,l.jsx)(Y.Z,{children:e.spend?e.spend:0}),(0,l.jsx)(Y.Z,{children:e.max_budget?e.max_budget:"Unlimited"})]},e.user_id))})]})}),(0,l.jsxs)(ew.Z,{children:[(0,l.jsxs)("div",{className:"flex items-center",children:[(0,l.jsx)("div",{className:"flex-1"}),(0,l.jsxs)("div",{className:"flex-1 flex justify-between items-center",children:[(0,l.jsx)(R.Z,{className:"w-1/4 mr-2 text-right",children:"Key"}),(0,l.jsx)(eo.Z,{defaultValue:"1",className:"w-3/4",children:null==a?void 0:a.map((e,t)=>{if(e&&null!==e.key_name&&e.key_name.length>0)return(0,l.jsx)(ei.Z,{value:String(t),onClick:()=>j(e.token),children:e.key_name},t)})})]})]}),(0,l.jsxs)($.Z,{children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"End User"}),(0,l.jsx)(Q.Z,{children:"Spend"}),(0,l.jsx)(Q.Z,{children:"Total Events"})]})}),(0,l.jsx)(H.Z,{children:null==h?void 0:h.map((e,t)=>(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{children:e.end_user}),(0,l.jsx)(Y.Z,{children:e.total_spend}),(0,l.jsx)(Y.Z,{children:e.total_events})]},t))})]})]})]})]})}),function(){if(!c)return null;let e=Math.ceil(c.length/25),t=Math.min(25*x,c.length);return(0,l.jsxs)("div",{className:"flex justify-between items-center",children:[(0,l.jsxs)("div",{children:["Showing ",(x-1)*25+1," – ",t," of ",c.length]}),(0,l.jsxs)("div",{className:"flex",children:[(0,l.jsx)("button",{className:"bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-l focus:outline-none",disabled:1===x,onClick:()=>p(x-1),children:"← Prev"}),(0,l.jsx)("button",{className:"bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-r focus:outline-none",disabled:x===e,onClick:()=>p(x+1),children:"Next →"})]})]})}()]})})},eb=e=>{let{teams:t,searchParams:s,accessToken:a,setTeams:n,userID:i,userRole:d}=e,[h]=L.Z.useForm(),[m]=L.Z.useForm(),{Title:u,Paragraph:x}=en.default,[p,j]=(0,r.useState)(""),[g,w]=(0,r.useState)(t?t[0]:null),[Z,f]=(0,r.useState)(!1),[k,_]=(0,r.useState)(!1),[b,v]=(0,r.useState)([]);(0,r.useEffect)(()=>{(async()=>{try{if(null===i||null===d)return;if(null!==a){let e=(await y(a,i,d)).data.map(e=>e.id);console.log("available_model_names:",e),v(e)}}catch(e){console.error("Error fetching user models:",e)}})()},[a,i,d]);let S=async e=>{try{if(null!=a){c.ZP.info("Creating Team");let s=await C(a,e);null!==t?n([...t,s]):n([s]),console.log("response for team create call: ".concat(s)),c.ZP.success("Team created"),f(!1)}}catch(e){console.error("Error creating the key:",e),c.ZP.error("Error creating the team: "+e)}},N=async e=>{try{if(null!=a&&null!=t){c.ZP.info("Making API Call");let s={role:"user",user_email:e.user_email,user_id:e.user_id},l=await T(a,g.team_id,s);console.log("response for team create call: ".concat(l.data));let r=t.findIndex(e=>(console.log("team.team_id=".concat(e.team_id,"; response.data.team_id=").concat(l.data.team_id)),e.team_id===l.data.team_id));if(console.log("foundIndex: ".concat(r)),-1!==r){let e=[...t];e[r]=l.data,n(e),w(l.data)}_(!1)}}catch(e){console.error("Error creating the key:",e)}};return console.log("received teams ".concat(t)),(0,l.jsx)("div",{className:"w-full mx-4",children:(0,l.jsxs)(O.Z,{numItems:1,className:"gap-2 p-2 h-[75vh] w-full",children:[(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(u,{level:4,children:"All Teams"}),(0,l.jsx)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,l.jsxs)($.Z,{children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"Team Name"}),(0,l.jsx)(Q.Z,{children:"Spend (USD)"}),(0,l.jsx)(Q.Z,{children:"Budget (USD)"}),(0,l.jsx)(Q.Z,{children:"Models"}),(0,l.jsx)(Q.Z,{children:"TPM / RPM Limits"})]})}),(0,l.jsx)(H.Z,{children:t&&t.length>0?t.map(e=>(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:e.team_alias}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:e.spend}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:e.max_budget?e.max_budget:"No limit"}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:JSON.stringify(e.models?e.models:[])})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsxs)(R.Z,{children:["TPM Limit:"," ",e.tpm_limit?e.tpm_limit:"Unlimited"," ",(0,l.jsx)("br",{}),"RPM Limit:"," ",e.rpm_limit?e.rpm_limit:"Unlimited"]})})]},e.team_id)):null})]})})]}),(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(o.Z,{className:"mx-auto",onClick:()=>f(!0),children:"+ Create New Team"}),(0,l.jsx)(B.Z,{title:"Create Team",visible:Z,width:800,footer:null,onOk:()=>{f(!1),h.resetFields()},onCancel:()=>{f(!1),h.resetFields()},children:(0,l.jsxs)(L.Z,{form:h,onFinish:S,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(L.Z.Item,{label:"Team Name",name:"team_alias",children:(0,l.jsx)(z.Z,{})}),(0,l.jsx)(L.Z.Item,{label:"Models",name:"models",children:(0,l.jsx)(U.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:b.map(e=>(0,l.jsx)(U.default.Option,{value:e,children:e},e))})}),(0,l.jsx)(L.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,l.jsx)(K.Z,{step:.01,precision:2,width:200})}),(0,l.jsx)(L.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})}),(0,l.jsx)(L.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})})]}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(W.ZP,{htmlType:"submit",children:"Create Team"})})]})})]}),(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(u,{level:4,children:"Team Members"}),(0,l.jsx)(x,{children:"If you belong to multiple teams, this setting controls which teams members you see."}),t&&t.length>0?(0,l.jsx)(eo.Z,{defaultValue:"0",children:t.map((e,t)=>(0,l.jsx)(ei.Z,{value:String(t),onClick:()=>{w(e)},children:e.team_alias},t))}):(0,l.jsxs)(x,{children:["No team created. ",(0,l.jsx)("b",{children:"Defaulting to personal account."})]})]}),(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsx)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,l.jsxs)($.Z,{children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"Member Name"}),(0,l.jsx)(Q.Z,{children:"Role"})]})}),(0,l.jsx)(H.Z,{children:g?g.members_with_roles.map((e,t)=>(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{children:e.user_email?e.user_email:e.user_id?e.user_id:null}),(0,l.jsx)(Y.Z,{children:e.role})]},t)):null})]})})}),(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(o.Z,{className:"mx-auto mb-5",onClick:()=>_(!0),children:"+ Add member"}),(0,l.jsx)(B.Z,{title:"Add member",visible:k,width:800,footer:null,onOk:()=>{_(!1),m.resetFields()},onCancel:()=>{_(!1),m.resetFields()},children:(0,l.jsxs)(L.Z,{form:h,onFinish:N,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(L.Z.Item,{label:"Email",name:"user_email",className:"mb-4",children:(0,l.jsx)(z.Z,{name:"user_email",className:"px-3 py-2 border rounded-md w-full"})}),(0,l.jsx)("div",{className:"text-center mb-4",children:"OR"}),(0,l.jsx)(L.Z.Item,{label:"User ID",name:"user_id",className:"mb-4",children:(0,l.jsx)(z.Z,{name:"user_id",className:"px-3 py-2 border rounded-md w-full"})})]}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(W.ZP,{htmlType:"submit",children:"Add member"})})]})})]})]})})},ev=s(8510),eS=e=>{let{searchParams:t,accessToken:s}=e,[a]=L.Z.useForm(),[n]=L.Z.useForm(),{Title:i,Paragraph:d}=en.default,[h,m]=(0,r.useState)(""),[u,x]=(0,r.useState)(null),[p,j]=(0,r.useState)(!1);(0,r.useEffect)(()=>{(async()=>{if(null!=s){let e=[],t=await A(s,"proxy_admin_viewer");t.forEach(t=>{e.push({user_role:t.user_role,user_id:t.user_id,user_email:t.user_email})}),console.log("proxy viewers: ".concat(t));let l=await A(s,"proxy_admin");l.forEach(t=>{e.push({user_role:t.user_role,user_id:t.user_id,user_email:t.user_email})}),console.log("proxy admins: ".concat(l)),console.log("combinedList: ".concat(e)),x(e)}})()},[s]);let y=async e=>{try{if(null!=s&&null!=u){c.ZP.info("Making API Call"),e.user_email,e.user_id;let t=await I(s,e);console.log("response for team create call: ".concat(t));let l=u.findIndex(e=>(console.log("user.user_id=".concat(e.user_id,"; response.user_id=").concat(t.user_id)),e.user_id===t.user_id));console.log("foundIndex: ".concat(l)),-1==l&&(console.log("updates admin with new user"),u.push(t),x(u)),j(!1)}}catch(e){console.error("Error creating the key:",e)}};return console.log("admins: ".concat(null==u?void 0:u.length)),(0,l.jsxs)("div",{className:"w-full m-2",children:[(0,l.jsx)(i,{level:4,children:"Restricted Access"}),(0,l.jsxs)(d,{children:["Add other people to just view spend. They cannot create keys, teams or grant users access to new models."," ",(0,l.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/ui#restrict-ui-access",children:"Requires SSO Setup"})]}),(0,l.jsxs)(O.Z,{numItems:1,className:"gap-2 p-0 w-full",children:[(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsx)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,l.jsxs)($.Z,{children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"Member Name"}),(0,l.jsx)(Q.Z,{children:"Role"}),(0,l.jsx)(Q.Z,{children:"Action"})]})}),(0,l.jsx)(H.Z,{children:u?u.map((e,t)=>(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{children:e.user_email?e.user_email:e.user_id?e.user_id:null}),(0,l.jsx)(Y.Z,{children:e.user_role}),(0,l.jsx)(Y.Z,{children:(0,l.jsx)(G.Z,{icon:ev.Z,size:"sm"})})]},t)):null})]})})}),(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(o.Z,{className:"mx-auto mb-5",onClick:()=>j(!0),children:"+ Add viewer"}),(0,l.jsx)(B.Z,{title:"Add viewer",visible:p,width:800,footer:null,onOk:()=>{j(!1),n.resetFields()},onCancel:()=>{j(!1),n.resetFields()},children:(0,l.jsxs)(L.Z,{form:a,onFinish:y,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(L.Z.Item,{label:"Email",name:"user_email",className:"mb-4",children:(0,l.jsx)(z.Z,{name:"user_email",className:"px-3 py-2 border rounded-md w-full"})}),(0,l.jsx)("div",{className:"text-center mb-4",children:"OR"}),(0,l.jsx)(L.Z.Item,{label:"User ID",name:"user_id",className:"mb-4",children:(0,l.jsx)(z.Z,{name:"user_id",className:"px-3 py-2 border rounded-md w-full"})})]}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(W.ZP,{htmlType:"submit",children:"Add member"})})]})})]})]})]})},eN=s(12968),eA=s(67951);async function eC(e,t,s,l){console.log("isLocal:",!1);let r=window.location.origin,a=new eN.ZP.OpenAI({apiKey:l,baseURL:r,dangerouslyAllowBrowser:!0});for await(let l of(await a.chat.completions.create({model:s,stream:!0,messages:[{role:"user",content:e}]})))console.log(l),l.choices[0].delta.content&&t(l.choices[0].delta.content)}var eT=e=>{let{accessToken:t,token:s,userRole:a,userID:n}=e,[o,i]=(0,r.useState)(""),[c,d]=(0,r.useState)([]),[h,m]=(0,r.useState)(void 0),[u,x]=(0,r.useState)(null);(0,r.useEffect)(()=>{t&&s&&a&&n&&(async()=>{let e=await y(t,n,a);console.log("model_info:",e),(null==e?void 0:e.data.length)>0&&(x(e.data),m(e.data[0].id))})()},[t,n,a]);let p=(e,t)=>{d(s=>{let l=s[s.length-1];return l&&l.role===e?[...s.slice(0,s.length-1),{role:e,content:l.content+t}]:[...s,{role:e,content:t}]})},j=async()=>{if(""!==o.trim()&&t&&s&&a&&n){d(e=>[...e,{role:"user",content:o}]);try{h&&await eC(o,e=>p("assistant",e),h,t)}catch(e){console.error("Error fetching model response",e),p("assistant","Error fetching model response")}i("")}};if(a&&"Admin Viewer"==a){let{Title:e,Paragraph:t}=en.default;return(0,l.jsxs)("div",{children:[(0,l.jsx)(e,{level:1,children:"Access Denied"}),(0,l.jsx)(t,{children:"Ask your proxy admin for access to test models"})]})}return(0,l.jsx)("div",{style:{width:"100%",position:"relative"},children:(0,l.jsx)(O.Z,{className:"gap-2 p-10 h-[75vh] w-full",children:(0,l.jsx)(M.Z,{children:(0,l.jsxs)(ey.Z,{children:[(0,l.jsxs)(eg.Z,{className:"mt-4",children:[(0,l.jsx)(ej.Z,{children:"Chat"}),(0,l.jsx)(ej.Z,{children:"API Reference"})]}),(0,l.jsxs)(eZ.Z,{children:[(0,l.jsxs)(ew.Z,{children:[(0,l.jsxs)("div",{children:[(0,l.jsx)("label",{children:"Select Model:"}),(0,l.jsx)("select",{value:h||"",onChange:e=>m(e.target.value),children:null==u?void 0:u.map(e=>(0,l.jsx)("option",{value:e.id,children:e.id},e.id))})]}),(0,l.jsxs)($.Z,{className:"mt-5",style:{display:"block",maxHeight:"60vh",overflowY:"auto"},children:[(0,l.jsx)(X.Z,{children:(0,l.jsx)(ee.Z,{children:(0,l.jsx)(Y.Z,{children:(0,l.jsx)(D.Z,{children:"Chat"})})})}),(0,l.jsx)(H.Z,{children:c.map((e,t)=>(0,l.jsx)(ee.Z,{children:(0,l.jsx)(Y.Z,{children:"".concat(e.role,": ").concat(e.content)})},t))})]}),(0,l.jsx)("div",{className:"mt-3",style:{position:"absolute",bottom:5,width:"95%"},children:(0,l.jsxs)("div",{className:"flex",children:[(0,l.jsx)("input",{type:"text",value:o,onChange:e=>i(e.target.value),className:"flex-1 p-2 border rounded-md mr-2",placeholder:"Type your message..."}),(0,l.jsx)("button",{onClick:j,className:"p-2 bg-blue-500 text-white rounded-md",children:"Send"})]})})]}),(0,l.jsx)(ew.Z,{children:(0,l.jsxs)(ey.Z,{children:[(0,l.jsxs)(eg.Z,{children:[(0,l.jsx)(ej.Z,{children:"OpenAI Python SDK"}),(0,l.jsx)(ej.Z,{children:"LlamaIndex"}),(0,l.jsx)(ej.Z,{children:"Langchain Py"})]}),(0,l.jsxs)(eZ.Z,{children:[(0,l.jsx)(ew.Z,{children:(0,l.jsx)(eA.Z,{language:"python",children:'\nimport openai\nclient = openai.OpenAI(\n api_key="your_api_key",\n base_url="http://0.0.0.0:4000" # proxy base url\n)\n\nresponse = client.chat.completions.create(\n model="gpt-3.5-turbo", # model to use from Models Tab\n messages = [\n {\n "role": "user",\n "content": "this is a test request, write a short poem"\n }\n ],\n extra_body={\n "metadata": {\n "generation_name": "ishaan-generation-openai-client",\n "generation_id": "openai-client-gen-id22",\n "trace_id": "openai-client-trace-id22",\n "trace_user_id": "openai-client-user-id2"\n }\n }\n)\n\nprint(response)\n '})}),(0,l.jsx)(ew.Z,{children:(0,l.jsx)(eA.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="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,l.jsx)(ew.Z,{children:(0,l.jsx)(eA.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:8000",\n model = "gpt-3.5-turbo",\n temperature=0.1,\n extra_body={\n "metadata": {\n "generation_name": "ishaan-generation-langchain-client",\n "generation_id": "langchain-client-gen-id22",\n "trace_id": "langchain-client-trace-id22",\n "trace_user_id": "langchain-client-user-id2"\n }\n }\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 '})})]})]})})]})]})})})})},eI=s(33509),eP=s(30569);let{Sider:eE}=eI.default;var eF=e=>{let{setPage:t,userRole:s,defaultSelectedKey:r}=e;return"Admin Viewer"==s?(0,l.jsx)(eI.default,{style:{minHeight:"100vh",maxWidth:"120px"},children:(0,l.jsx)(eE,{width:120,children:(0,l.jsxs)(eP.Z,{mode:"inline",defaultSelectedKeys:r||["4"],style:{height:"100%",borderRight:0},children:[(0,l.jsx)(eP.Z.Item,{onClick:()=>t("api-keys"),children:"API Keys"},"4"),(0,l.jsx)(eP.Z.Item,{onClick:()=>t("models"),children:"Models"},"2"),(0,l.jsx)(eP.Z.Item,{onClick:()=>t("llm-playground"),children:"Chat UI"},"3"),(0,l.jsx)(eP.Z.Item,{onClick:()=>t("usage"),children:"Usage"},"1")]})})}):(0,l.jsx)(eI.default,{style:{minHeight:"100vh",maxWidth:"120px"},children:(0,l.jsx)(eE,{width:120,children:(0,l.jsxs)(eP.Z,{mode:"inline",defaultSelectedKeys:r||["1"],style:{height:"100%",borderRight:0},children:[(0,l.jsx)(eP.Z.Item,{onClick:()=>t("api-keys"),children:"API Keys"},"1"),(0,l.jsx)(eP.Z.Item,{onClick:()=>t("models"),children:"Models"},"2"),(0,l.jsx)(eP.Z.Item,{onClick:()=>t("llm-playground"),children:"Chat UI"},"3"),(0,l.jsx)(eP.Z.Item,{onClick:()=>t("usage"),children:"Usage"},"4"),"Admin"==s?(0,l.jsx)(eP.Z.Item,{onClick:()=>t("users"),children:"Users"},"5"):null,"Admin"==s?(0,l.jsx)(eP.Z.Item,{onClick:()=>t("teams"),children:"Teams"},"6"):null,"Admin"==s?(0,l.jsx)(eP.Z.Item,{onClick:()=>t("admin-panel"),children:"Admin"},"7"):null]})})})},eO=e=>{let{accessToken:t,token:s,userRole:a,userID:n}=e,o=new Date,[i,c]=(0,r.useState)([]),[d,h]=(0,r.useState)([]),[m,u]=(0,r.useState)([]),[x,p]=(0,r.useState)([]),[j,y]=(0,r.useState)([]),[g,_]=(0,r.useState)([]),[S,N]=(0,r.useState)([]),A=new Date(o.getFullYear(),o.getMonth(),1),C=new Date(o.getFullYear(),o.getMonth()+1,0),T=P(A),I=P(C);function P(e){let t=e.getFullYear(),s=e.getMonth()+1,l=e.getDate();return"".concat(t,"-").concat(s<10?"0"+s:s,"-").concat(l<10?"0"+l:l)}return console.log("Start date is ".concat(T)),console.log("End date is ".concat(I)),(0,r.useEffect)(()=>{t&&s&&a&&n&&(async()=>{try{if(console.log("user role: ".concat(a)),"Admin"==a||"Admin Viewer"==a){let e=await f(t);c(e);let s=(await k(t)).map(e=>({key:(e.key_name||e.key_alias||e.api_key).substring(0,7),spend:e.total_spend}));h(s);let l=(await b(t)).map(e=>({key:e.model,spend:e.total_spend}));u(l);let r=await w(t);console.log("teamSpend",r),y(r.daily_spend),_(r.teams),N(r.total_spend_per_team)}else"App Owner"==a&&await Z(t,s,a,n,T,I).then(async e=>{if(console.log("result from spend logs call",e),"daily_spend"in e){let t=e.daily_spend;console.log("daily spend",t),c(t);let s=e.top_api_keys;h(s)}else{let s=(await v(t,function(e){let t=[];e.forEach(e=>{Object.entries(e).forEach(e=>{let[s,l]=e;"spend"!==s&&"startTime"!==s&&"models"!==s&&"users"!==s&&t.push({key:s,spend:l})})}),t.sort((e,t)=>Number(t.spend)-Number(e.spend));let s=t.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||e.token).substring(0,7),spend:e.spend}));h(s),p(function(e){let t={};e.forEach(e=>{Object.entries(e.users).forEach(e=>{let[s,l]=e;""!==s&&null!=s&&"None"!=s&&(t[s]||(t[s]=0),t[s]+=l)})});let s=Object.entries(t).map(e=>{let[t,s]=e;return{user_id:t,spend:s}});s.sort((e,t)=>t.spend-e.spend);let l=s.slice(0,5);return console.log("topKeys: ".concat(Object.values(l[0]))),l}(e)),c(e)}})}catch(e){console.error("There was an error fetching the data",e)}})()},[t,s,a,n,T,I]),(0,l.jsx)("div",{style:{width:"100%"},children:(0,l.jsxs)(ey.Z,{children:[(0,l.jsxs)(eg.Z,{className:"mt-4",children:[(0,l.jsx)(ej.Z,{children:"All Up"}),(0,l.jsx)(ej.Z,{children:"Team Based Usage"})]}),(0,l.jsxs)(eZ.Z,{children:[(0,l.jsx)(ew.Z,{children:(0,l.jsxs)(O.Z,{numItems:2,className:"gap-2 p-10 h-[75vh] w-full",children:[(0,l.jsx)(F.Z,{numColSpan:2,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Monthly Spend"}),(0,l.jsx)(et.Z,{data:i,index:"date",categories:["spend"],colors:["blue"],valueFormatter:e=>"$ ".concat(new Intl.NumberFormat("us").format(e).toString()),yAxisWidth:100,tickGap:5})]})}),(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Top API Keys"}),(0,l.jsx)(et.Z,{className:"mt-4 h-40",data:d,index:"key",categories:["spend"],colors:["blue"],yAxisWidth:80,tickGap:5,layout:"vertical",showXAxis:!1,showLegend:!1})]})}),(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Top Users"}),(0,l.jsx)(et.Z,{className:"mt-4 h-40",data:x,index:"user_id",categories:["spend"],colors:["blue"],yAxisWidth:200,layout:"vertical",showXAxis:!1,showLegend:!1})]})}),(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Top Models"}),(0,l.jsx)(et.Z,{className:"mt-4 h-40",data:m,index:"key",categories:["spend"],colors:["blue"],yAxisWidth:200,layout:"vertical",showXAxis:!1,showLegend:!1})]})})]})}),(0,l.jsx)(ew.Z,{children:(0,l.jsxs)(O.Z,{numItems:2,className:"gap-2 p-10 h-[75vh] w-full",children:[(0,l.jsx)(F.Z,{numColSpan:2,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Daily Spend Per Team"}),(0,l.jsx)(et.Z,{className:"h-72",data:j,index:"date",categories:g,yAxisWidth:30,stack:!0})]})}),(0,l.jsx)(F.Z,{numColSpan:2,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Total Spend Per Team"}),(0,l.jsx)(et.Z,{className:"h-72",data:S,index:"team_id",categories:["total_spend"],yAxisWidth:30})]})})]})})]})]})})},eM=()=>{let{Title:e,Paragraph:t}=en.default,[s,n]=(0,r.useState)(""),[o,c]=(0,r.useState)(null),[d,h]=(0,r.useState)(null),[m,u]=(0,r.useState)(null),[x,p]=(0,r.useState)(!0),j=(0,a.useSearchParams)(),y=j.get("userID"),g=j.get("token"),[w,Z]=(0,r.useState)("api-keys"),[f,k]=(0,r.useState)(null);return(0,r.useEffect)(()=>{if(g){let e=(0,ed.o)(g);if(e){if(console.log("Decoded token:",e),console.log("Decoded key:",e.key),k(e.key),e.user_role){let t=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"app_user":return"App User";default:return"Unknown Role"}}(e.user_role);console.log("Decoded user_role:",t),n(t),"Admin Viewer"==t&&Z("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?p("username_password"==e.login_method):console.log("User Email is not set ".concat(e))}}},[g]),(0,l.jsx)(r.Suspense,{fallback:(0,l.jsx)("div",{children:"Loading..."}),children:(0,l.jsxs)("div",{className:"flex flex-col min-h-screen",children:[(0,l.jsx)(i,{userID:y,userRole:s,userEmail:o,showSSOBanner:x}),(0,l.jsxs)("div",{className:"flex flex-1 overflow-auto",children:[(0,l.jsx)(eF,{setPage:Z,userRole:s,defaultSelectedKey:null}),"api-keys"==w?(0,l.jsx)(eh,{userID:y,userRole:s,teams:d,keys:m,setUserRole:n,userEmail:o,setUserEmail:c,setTeams:h,setKeys:u}):"models"==w?(0,l.jsx)(ep,{userID:y,userRole:s,token:g,accessToken:f}):"llm-playground"==w?(0,l.jsx)(eT,{userID:y,userRole:s,token:g,accessToken:f}):"users"==w?(0,l.jsx)(e_,{userID:y,userRole:s,token:g,keys:m,accessToken:f,setKeys:u}):"teams"==w?(0,l.jsx)(eb,{teams:d,setTeams:h,searchParams:j,accessToken:f,userID:y,userRole:s}):"admin-panel"==w?(0,l.jsx)(eS,{setTeams:h,searchParams:j,accessToken:f}):(0,l.jsx)(eO,{userID:y,userRole:s,token:g,accessToken:f})]})]})})}}},function(e){e.O(0,[730,971,69,744],function(){return e(e.s=20661)}),_N_E=e.O()}]); \ No newline at end of file +(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[931],{20661:function(e,t,s){Promise.resolve().then(s.bind(s,92182))},92182:function(e,t,s){"use strict";s.r(t),s.d(t,{default:function(){return eM}});var l=s(3827),r=s(64090),n=s(47907),a=s(8792),o=s(2179),i=e=>{let{userID:t,userRole:s,userEmail:r,showSSOBanner:n}=e;return console.log("User ID:",t),console.log("userEmail:",r),(0,l.jsxs)("nav",{className:"left-0 right-0 top-0 flex justify-between items-center h-12 mb-4",children:[(0,l.jsx)("div",{className:"text-left my-2 absolute top-0 left-0",children:(0,l.jsx)("div",{className:"flex flex-col items-center",children:(0,l.jsx)(a.default,{href:"/",children:(0,l.jsx)("button",{className:"text-gray-800 text-2xl py-1 rounded text-center",children:(0,l.jsx)("img",{src:"/get_image",width:200,height:200,alt:"LiteLLM Brand",className:"mr-2"})})})})}),(0,l.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,l.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/ui#setup-ssoauth-for-ui",target:"_blank",className:"mr-2"}):null,(0,l.jsxs)(o.Z,{variant:"secondary",size:"lg",children:[r,(0,l.jsxs)("p",{children:["Role: ",s]}),(0,l.jsxs)("p",{children:["ID: ",t]})]})]})]})},c=s(80588);let d=async(e,t,s)=>{try{if(console.log("Form Values in keyCreateCall:",s),s.description&&(s.metadata||(s.metadata={}),s.metadata.description=s.description,delete s.description,s.metadata=JSON.stringify(s.metadata)),s.metadata){console.log("formValues.metadata:",s.metadata);try{s.metadata=JSON.parse(s.metadata)}catch(e){throw c.ZP.error("Failed to parse metadata: "+e),Error("Failed to parse metadata: "+e)}}console.log("Form Values after check:",s);let l=await fetch("/key/generate",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({user_id:t,...s})});if(!l.ok){let e=await l.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let r=await l.json();return console.log("API Response:",r),r}catch(e){throw console.error("Failed to create key:",e),e}},h=async(e,t,s)=>{try{if(console.log("Form Values in keyCreateCall:",s),s.description&&(s.metadata||(s.metadata={}),s.metadata.description=s.description,delete s.description,s.metadata=JSON.stringify(s.metadata)),s.metadata){console.log("formValues.metadata:",s.metadata);try{s.metadata=JSON.parse(s.metadata)}catch(e){throw c.ZP.error("Failed to parse metadata: "+e),Error("Failed to parse metadata: "+e)}}console.log("Form Values after check:",s);let l=await fetch("/user/new",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({user_id:t,...s})});if(!l.ok){let e=await l.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let r=await l.json();return console.log("API Response:",r),r}catch(e){throw console.error("Failed to create key:",e),e}},m=async(e,t)=>{try{console.log("in keyDeleteCall:",t);let s=await fetch("/key/delete",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({keys:[t]})});if(!s.ok){let e=await s.text();throw c.ZP.error("Failed to delete key: "+e),Error("Network response was not ok")}let l=await s.json();return console.log(l),l}catch(e){throw console.error("Failed to create key:",e),e}},u=async function(e,t,s){let l=arguments.length>3&&void 0!==arguments[3]&&arguments[3];try{let r="/user/info";"App Owner"==s&&t&&(r="".concat(r,"?user_id=").concat(t)),console.log("in userInfoCall viewAll=",l),l&&(r="".concat(r,"?view_all=true"));let n=await fetch(r,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!n.ok){let e=await n.text();throw c.ZP.error(e),Error("Network response was not ok")}let a=await n.json();return console.log("API Response:",a),a}catch(e){throw console.error("Failed to create key:",e),e}},x=async e=>{try{let t=await fetch("/global/spend",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},p=async(e,t,s)=>{try{let t=await fetch("/v2/model/info",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},j=async(e,t,s)=>{try{let t=await fetch("/model/metrics",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},y=async(e,t,s)=>{try{let t=await fetch("/models",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},g=async(e,t)=>{try{let s="/global/spend/logs";console.log("in keySpendLogsCall:",s);let l=await fetch("".concat(s,"?api_key=").concat(t),{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw c.ZP.error(e),Error("Network response was not ok")}let r=await l.json();return console.log(r),r}catch(e){throw console.error("Failed to create key:",e),e}},w=async e=>{try{let t="/global/spend/teams";console.log("in teamSpendLogsCall:",t);let s=await fetch("".concat(t),{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!s.ok){let e=await s.text();throw c.ZP.error(e),Error("Network response was not ok")}let l=await s.json();return console.log(l),l}catch(e){throw console.error("Failed to create key:",e),e}},Z=async(e,t,s,l,r,n)=>{try{console.log("user role in spend logs call: ".concat(s));let t="/spend/logs";t="App Owner"==s?"".concat(t,"?user_id=").concat(l,"&start_date=").concat(r,"&end_date=").concat(n):"".concat(t,"?start_date=").concat(r,"&end_date=").concat(n);let a=await fetch(t,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!a.ok){let e=await a.text();throw c.ZP.error(e),Error("Network response was not ok")}let o=await a.json();return console.log(o),o}catch(e){throw console.error("Failed to create key:",e),e}},f=async e=>{try{let t=await fetch("/global/spend/logs",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to create key:",e),e}},k=async e=>{try{let t=await fetch("/global/spend/keys?limit=5",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to create key:",e),e}},_=async(e,t)=>{try{t&&JSON.stringify({api_key:t});let s={method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}};t&&(s.body=JSON.stringify({api_key:t}));let l=await fetch("/global/spend/end_users",s);if(!l.ok){let e=await l.text();throw c.ZP.error(e),Error("Network response was not ok")}let r=await l.json();return console.log(r),r}catch(e){throw console.error("Failed to create key:",e),e}},b=async e=>{try{let t=await fetch("/global/spend/models?limit=5",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to create key:",e),e}},v=async(e,t)=>{try{let s=await fetch("/v2/key/info",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({keys:t})});if(!s.ok){let e=await s.text();throw c.ZP.error(e),Error("Network response was not ok")}let l=await s.json();return console.log(l),l}catch(e){throw console.error("Failed to create key:",e),e}},S=async(e,t,s,l)=>{try{let r=await fetch("/user/request_model",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({models:[t],user_id:s,justification:l})});if(!r.ok){let e=await r.text();throw c.ZP.error("Failed to delete key: "+e),Error("Network response was not ok")}let n=await r.json();return console.log(n),n}catch(e){throw console.error("Failed to create key:",e),e}},N=async e=>{try{let t="/user/get_requests";console.log("in userGetRequesedtModelsCall:",t);let s=await fetch(t,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!s.ok){let e=await s.text();throw c.ZP.error("Failed to delete key: "+e),Error("Network response was not ok")}let l=await s.json();return console.log(l),l}catch(e){throw console.error("Failed to get requested models:",e),e}},A=async(e,t)=>{try{let s="/user/get_users?role=".concat(t);console.log("in userGetAllUsersCall:",s);let l=await fetch(s,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw c.ZP.error("Failed to delete key: "+e),Error("Network response was not ok")}let r=await l.json();return console.log(r),r}catch(e){throw console.error("Failed to get requested models:",e),e}},C=async(e,t)=>{try{console.log("Form Values in teamCreateCall:",t);let s=await fetch("/team/new",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...t})});if(!s.ok){let e=await s.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let l=await s.json();return console.log("API Response:",l),l}catch(e){throw console.error("Failed to create key:",e),e}},T=async(e,t,s)=>{try{console.log("Form Values in teamMemberAddCall:",s);let l=await fetch("/team/member_add",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({team_id:t,member:s})});if(!l.ok){let e=await l.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let r=await l.json();return console.log("API Response:",r),r}catch(e){throw console.error("Failed to create key:",e),e}},I=async(e,t)=>{try{console.log("Form Values in userUpdateUserCall:",t);let s=await fetch("/user/update",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({user_role:"proxy_admin_viewer",...t})});if(!s.ok){let e=await s.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let l=await s.json();return console.log("API Response:",l),l}catch(e){throw console.error("Failed to create key:",e),e}},P=async(e,t)=>{try{let s=await fetch("/global/predict/spend/logs",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({data:t})});if(!s.ok){let e=await s.text();throw c.ZP.error(e),Error("Network response was not ok")}let l=await s.json();return console.log(l),l}catch(e){throw console.error("Failed to create key:",e),e}},E=async e=>{try{console.log("Checking Slack Budget Alerts service health");let t=await fetch("/health/services?service=slack_budget_alerts",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error("Failed Slack Alert test: "+e),Error(e)}let s=await t.json();return c.ZP.success("Test Slack Alert worked - check your Slack!"),console.log("Service Health Response:",s),s}catch(e){throw console.error("Failed to perform health check:",e),e}};var F=s(10384),O=s(46453),M=s(13810),R=s(71801),D=s(42440),U=s(17189),L=s(12143),B=s(77171),z=s(42539),K=s(88707),W=s(1861);let{Option:V}=U.default;var q=e=>{let{userID:t,teamID:s,userRole:n,accessToken:a,data:i,userModels:h,setData:m}=e,[u]=L.Z.useForm(),[x,p]=(0,r.useState)(!1),[j,y]=(0,r.useState)(null),[g,w]=(0,r.useState)(null),Z=()=>{p(!1),u.resetFields()},f=()=>{p(!1),y(null),u.resetFields()},k=async e=>{try{c.ZP.info("Making API Call"),p(!0);let s=await d(a,t,e);console.log("key create Response:",s),m(e=>e?[...e,s]:[s]),y(s.key),w(s.soft_budget),c.ZP.success("API Key Created"),u.resetFields(),localStorage.removeItem("userData"+t)}catch(e){console.error("Error creating the key:",e)}},_=async()=>{try{console.log("Sending Slack alert...");let e=await E(a);console.log("slackBudgetAlertsHealthCheck Response:",e),console.log("Testing Slack alert successful")}catch(e){console.error("Error sending Slack alert:",e)}};return(0,l.jsxs)("div",{children:[(0,l.jsx)(o.Z,{className:"mx-auto",onClick:()=>p(!0),children:"+ Create New Key"}),(0,l.jsx)(B.Z,{title:"Create Key",visible:x,width:800,footer:null,onOk:Z,onCancel:f,children:(0,l.jsxs)(L.Z,{form:u,onFinish:k,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:["App Owner"===n||"Admin"===n?(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(L.Z.Item,{label:"Key Name",name:"key_alias",children:(0,l.jsx)(z.Z,{})}),(0,l.jsx)(L.Z.Item,{label:"Team ID",name:"team_id",children:(0,l.jsx)(z.Z,{placeholder:"ai_team",defaultValue:s||""})}),(0,l.jsx)(L.Z.Item,{label:"Models",name:"models",children:(0,l.jsx)(U.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:h.map(e=>(0,l.jsx)(V,{value:e,children:e},e))})}),(0,l.jsx)(L.Z.Item,{label:"Soft Budget (USD) Monthly",name:"soft_budget",initialValue:50,children:(0,l.jsx)(K.Z,{step:.01,precision:2,defaultValue:50,width:200})}),(0,l.jsx)(L.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,l.jsx)(K.Z,{step:.01,precision:2,width:200})}),(0,l.jsx)(L.Z.Item,{label:"Reset Budget",name:"budget_duration",children:(0,l.jsxs)(U.default,{defaultValue:null,placeholder:"n/a",children:[(0,l.jsx)(U.default.Option,{value:"24h",children:"daily"}),(0,l.jsx)(U.default.Option,{value:"30d",children:"monthly"})]})}),(0,l.jsx)(L.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})}),(0,l.jsx)(L.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})}),(0,l.jsx)(L.Z.Item,{label:"Expire Key (eg: 30s, 30h, 30d)",name:"duration",children:(0,l.jsx)(z.Z,{})}),(0,l.jsx)(L.Z.Item,{label:"Metadata",name:"metadata",children:(0,l.jsx)(z.Z.TextArea,{rows:4,placeholder:"Enter metadata as JSON"})})]}):(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(L.Z.Item,{label:"Key Name",name:"key_alias",children:(0,l.jsx)(z.Z,{})}),(0,l.jsx)(L.Z.Item,{label:"Team ID (Contact Group)",name:"team_id",children:(0,l.jsx)(z.Z,{placeholder:"ai_team"})}),(0,l.jsx)(L.Z.Item,{label:"Description",name:"description",children:(0,l.jsx)(z.Z.TextArea,{placeholder:"Enter description",rows:4})})]}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(W.ZP,{htmlType:"submit",children:"Create Key"})})]})}),j&&(0,l.jsx)(B.Z,{visible:x,onOk:Z,onCancel:f,footer:null,children:(0,l.jsx)(O.Z,{numItems:1,className:"gap-2 w-full",children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Save your Key"}),(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsxs)("p",{children:["Please save this secret key somewhere safe and accessible. For security reasons, ",(0,l.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,l.jsx)(F.Z,{numColSpan:1,children:null!=j?(0,l.jsxs)("div",{children:[(0,l.jsxs)(R.Z,{children:["API Key: ",j]}),(0,l.jsx)(D.Z,{className:"mt-6",children:"Budgets"}),(0,l.jsxs)(R.Z,{children:["Soft Limit Budget: $",g]}),(0,l.jsx)(o.Z,{className:"mt-3",onClick:_,children:"Test Slack Alert"}),(0,l.jsxs)(R.Z,{className:"mt-2",children:["(LiteLLM Docs -",(0,l.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/alerting",target:"_blank",className:"text-blue-500",children:"Set Up Slack Alerting)"})]})]}):(0,l.jsx)(R.Z,{children:"Key being created, this might take 30s"})})]})})})]})},J=s(33393),G=s(61244),$=s(10827),H=s(3851),Y=s(2044),X=s(64167),Q=s(74480),ee=s(7178),et=s(9853),es=s(56863),el=e=>{let{token:t,accessToken:s,keySpend:n,keyBudget:a,keyName:i}=e,[c,d]=(0,r.useState)(!1),[h,m]=(0,r.useState)(null),[u,x]=(0,r.useState)(""),[p,j]=(0,r.useState)(null),y=async()=>{try{if(null==s||null==t)return;console.log("accessToken: ".concat(s,"; token: ").concat(t));let e=await g(s,t);console.log("Response:",e),m(e);let l=await P(s,e);console.log("Response2:",l);let r=[...e,...l.response];m(r),x(l.predicted_spend),console.log("Combined Data:",r)}catch(e){console.error("There was an error fetching the data",e)}};return t?(0,l.jsxs)("div",{children:[(0,l.jsx)(o.Z,{size:"xs",onClick:()=>{console.log("Show Modal triggered"),d(!0),y()},variant:"secondary",children:"Spend Report"}),(0,l.jsxs)(B.Z,{visible:c,width:1400,onOk:()=>{d(!1)},onCancel:()=>{d(!1)},footer:null,children:[(0,l.jsxs)(D.Z,{style:{textAlign:"left"},children:["Key Name: ",i]}),(0,l.jsxs)(es.Z,{children:["Monthly Spend $",n]}),(0,l.jsx)(D.Z,{children:u}),(0,l.jsx)(M.Z,{className:"mt-6 mb-6",children:h&&(0,l.jsx)(et.Z,{className:"mt-6",data:h,colors:["blue","amber"],index:"date",categories:["spend","predicted_spend"],yAxisWidth:80})})]})]}):null},er=e=>{let{userID:t,accessToken:s,data:n,setData:a}=e,[i,c]=(0,r.useState)(!1),[d,h]=(0,r.useState)(!1),[u,x]=(0,r.useState)(null),p=async e=>{null!=n&&(x(e),localStorage.removeItem("userData"+t),h(!0))},j=async()=>{if(null!=u&&null!=n){try{await m(s,u);let e=n.filter(e=>e.token!==u);a(e)}catch(e){console.error("Error deleting the key:",e)}h(!1),x(null)}};if(null!=n)return console.log("RERENDER TRIGGERED"),(0,l.jsxs)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh] mb-4",children:[(0,l.jsxs)($.Z,{className:"mt-5",children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"Key Alias"}),(0,l.jsx)(Q.Z,{children:"Secret Key"}),(0,l.jsx)(Q.Z,{children:"Spend (USD)"}),(0,l.jsx)(Q.Z,{children:"Key Budget (USD)"}),(0,l.jsx)(Q.Z,{children:"Spend Report"}),(0,l.jsx)(Q.Z,{children:"Team ID"}),(0,l.jsx)(Q.Z,{children:"Metadata"}),(0,l.jsx)(Q.Z,{children:"Models"}),(0,l.jsx)(Q.Z,{children:"TPM / RPM Limits"}),(0,l.jsx)(Q.Z,{children:"Expires"})]})}),(0,l.jsx)(H.Z,{children:n.map(e=>(console.log(e),"litellm-dashboard"===e.team_id)?null:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",whiteSpace:"pre-wrap",overflow:"hidden"},children:null!=e.key_alias?(0,l.jsx)(R.Z,{children:e.key_alias}):(0,l.jsx)(R.Z,{children:"Not Set"})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:e.key_name})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:(()=>{try{return parseFloat(e.spend).toFixed(4)}catch(t){return e.spend}})()})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",whiteSpace:"pre-wrap",overflow:"hidden"},children:null!=e.max_budget?(0,l.jsx)(R.Z,{children:e.max_budget}):(0,l.jsx)(R.Z,{children:"Unlimited Budget"})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px"},children:(0,l.jsx)(el,{token:e.token,accessToken:s,keySpend:e.spend,keyBudget:e.max_budget,keyName:e.key_name})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:e.team_id})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:JSON.stringify(e.metadata).slice(0,400)})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:JSON.stringify(e.models)})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",overflowWrap:"break-word"},children:(0,l.jsxs)(R.Z,{children:["TPM Limit: ",e.tpm_limit?e.tpm_limit:"Unlimited"," ",(0,l.jsx)("br",{})," RPM Limit:"," ",e.rpm_limit?e.rpm_limit:"Unlimited"]})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",wordWrap:"break-word"},children:null!=e.expires?(0,l.jsx)(R.Z,{children:e.expires}):(0,l.jsx)(R.Z,{children:"Never"})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",wordWrap:"break-word"},children:(0,l.jsx)(G.Z,{onClick:()=>p(e.token),icon:J.Z,size:"sm"})})]},e.token))})]}),d&&(0,l.jsx)("div",{className:"fixed z-10 inset-0 overflow-y-auto",children:(0,l.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,l.jsx)("div",{className:"fixed inset-0 transition-opacity","aria-hidden":"true",children:(0,l.jsx)("div",{className:"absolute inset-0 bg-gray-500 opacity-75"})}),(0,l.jsx)("span",{className:"hidden sm:inline-block sm:align-middle sm:h-screen","aria-hidden":"true",children:"​"}),(0,l.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,l.jsx)("div",{className:"bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4",children:(0,l.jsx)("div",{className:"sm:flex sm:items-start",children:(0,l.jsxs)("div",{className:"mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left",children:[(0,l.jsx)("h3",{className:"text-lg leading-6 font-medium text-gray-900",children:"Delete Key"}),(0,l.jsx)("div",{className:"mt-2",children:(0,l.jsx)("p",{className:"text-sm text-gray-500",children:"Are you sure you want to delete this key ?"})})]})})}),(0,l.jsxs)("div",{className:"bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse",children:[(0,l.jsx)(o.Z,{onClick:j,color:"red",className:"ml-2",children:"Delete"}),(0,l.jsx)(o.Z,{onClick:()=>{h(!1),x(null)},children:"Cancel"})]})]})]})})]})},en=e=>{let{userID:t,userSpendData:s,userRole:n,accessToken:a}=e,[o,i]=(0,r.useState)(null==s?void 0:s.spend),[c,d]=(0,r.useState)((null==s?void 0:s.max_budget)||null);(0,r.useEffect)(()=>{(async()=>{if("Admin"===n)try{let e=await x(a);i(e.spend),d(e.max_budget||null)}catch(e){console.error("Error fetching global spend data:",e)}})()},[n,a]);let h=void 0!==o?o.toFixed(4):null;return(0,l.jsx)(l.Fragment,{children:(0,l.jsxs)(M.Z,{className:"mx-auto mb-4",children:[(0,l.jsxs)(es.Z,{children:["$",h]}),(0,l.jsxs)(D.Z,{children:["/ ",null!==c?"$".concat(c," limit"):"No limit"]})]})})},ea=s(36083),eo=s(68967),ei=s(27166),ec=e=>{let{teams:t,setSelectedTeam:s}=e,{Title:n,Paragraph:a}=ea.default,[o,i]=(0,r.useState)("");return(0,l.jsxs)("div",{className:"mt-10",children:[(0,l.jsx)(n,{level:4,children:"Default Team"}),(0,l.jsx)(a,{children:"If you belong to multiple teams, this setting controls which team is used by default when creating new API Keys."}),t&&t.length>0?(0,l.jsx)(eo.Z,{defaultValue:"0",children:t.map((e,t)=>(0,l.jsx)(ei.Z,{value:String(t),onClick:()=>s(e),children:e.team_alias},t))}):(0,l.jsxs)(a,{children:["No team created. ",(0,l.jsx)("b",{children:"Defaulting to personal account."})]})]})},ed=s(37963);console.log("isLocal:",!1);var eh=e=>{let{userID:t,userRole:s,teams:a,keys:o,setUserRole:i,userEmail:c,setUserEmail:d,setTeams:h,setKeys:m}=e,[p,j]=(0,r.useState)(null),g=(0,n.useSearchParams)();g.get("viewSpend"),(0,n.useRouter)();let w=g.get("token"),[Z,f]=(0,r.useState)(null),[k,_]=(0,r.useState)([]),[b,v]=(0,r.useState)(a?a[0]:null);if(window.addEventListener("beforeunload",function(){sessionStorage.clear()}),(0,r.useEffect)(()=>{if(w){let e=(0,ed.o)(w);if(e){if(console.log("Decoded token:",e),console.log("Decoded key:",e.key),f(e.key),e.user_role){let t=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";default:return"Unknown Role"}}(e.user_role);console.log("Decoded user_role:",t),i(t)}else console.log("User role not defined");e.user_email?d(e.user_email):console.log("User Email is not set ".concat(e))}}if(t&&Z&&s&&!o&&!p){let e=sessionStorage.getItem("userModels"+t);e?_(JSON.parse(e)):(async()=>{try{let e=await u(Z,t,s);if(console.log("received teams in user dashboard: ".concat(Object.keys(e),"; team values: ").concat(Object.entries(e.teams))),"Admin"==s){let e=await x(Z);j(e),console.log("globalSpend:",e)}else j(e.user_info);m(e.keys),h(e.teams),v(e.teams?e.teams[0]:null),sessionStorage.setItem("userData"+t,JSON.stringify(e.keys)),sessionStorage.setItem("userSpendData"+t,JSON.stringify(e.user_info));let l=(await y(Z,t,s)).data.map(e=>e.id);console.log("available_model_names:",l),_(l),console.log("userModels:",k),sessionStorage.setItem("userModels"+t,JSON.stringify(l))}catch(e){console.error("There was an error fetching the data",e)}})()}},[t,w,Z,o,s]),null==t||null==w){let e="/sso/key/generate";return console.log("Full URL:",e),window.location.href=e,null}if(null==Z)return null;if(null==s&&i("App Owner"),s&&"Admin Viewer"==s){let{Title:e,Paragraph:t}=ea.default;return(0,l.jsxs)("div",{children:[(0,l.jsx)(e,{level:1,children:"Access Denied"}),(0,l.jsx)(t,{children:"Ask your proxy admin for access to create keys"})]})}return(0,l.jsx)("div",{children:(0,l.jsx)(O.Z,{numItems:1,className:"gap-0 p-10 h-[75vh] w-full",children:(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(en,{userID:t,userSpendData:p,userRole:s,accessToken:Z}),(0,l.jsx)(er,{userID:t,accessToken:Z,data:o,setData:m}),(0,l.jsx)(q,{userID:t,teamID:b?b.team_id:null,userRole:s,userModels:k,accessToken:Z,data:o,setData:m}),(0,l.jsx)(ec,{teams:a,setSelectedTeam:v})]})})})},em=s(5);let{Option:eu}=U.default;var ex=e=>{let{userModels:t,accessToken:s,userID:n}=e,[a]=L.Z.useForm(),[i,d]=(0,r.useState)(!1),h=async e=>{try{c.ZP.info("Requesting access");let{selectedModel:t,accessReason:l}=e;await S(s,t,n,l),d(!0)}catch(e){console.error("Error requesting access:",e)}};return(0,l.jsxs)("div",{children:[(0,l.jsx)(o.Z,{size:"xs",onClick:()=>d(!0),children:"Request Access"}),(0,l.jsx)(B.Z,{title:"Request Access",visible:i,width:800,footer:null,onOk:()=>{d(!1),a.resetFields()},onCancel:()=>{d(!1),a.resetFields()},children:(0,l.jsxs)(L.Z,{form:a,onFinish:h,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsx)(L.Z.Item,{label:"Select Model",name:"selectedModel",children:(0,l.jsx)(U.default,{placeholder:"Select model",style:{width:"100%"},children:t.map(e=>(0,l.jsx)(eu,{value:e,children:e},e))})}),(0,l.jsx)(L.Z.Item,{label:"Reason for Access",name:"accessReason",children:(0,l.jsx)(z.Z.TextArea,{rows:4,placeholder:"Enter reason for access"})}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(o.Z,{children:"Request Access"})})]})})]})},ep=e=>{let{accessToken:t,token:s,userRole:n,userID:a}=e,[o,i]=(0,r.useState)({data:[]}),[c,d]=(0,r.useState)([]),[h,m]=(0,r.useState)([]);if((0,r.useEffect)(()=>{if(!t||!s||!n||!a)return;let e=async()=>{try{let e=await p(t,a,n);console.log("Model data response:",e.data),i(e);let s=await j(t,a,n);if(console.log("Model metrics response:",s),d(s),"Admin"===n&&t){let e=await N(t);console.log("Pending Requests:",h),m(e.requests||[])}}catch(e){console.error("There was an error fetching the model data",e)}};t&&s&&n&&a&&e()},[t,s,n,a]),!o||!t||!s||!n||!a)return(0,l.jsx)("div",{children:"Loading..."});let u=[];for(let e=0;e(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{children:(0,l.jsx)(D.Z,{children:e.model_name})}),(0,l.jsx)(Y.Z,{children:e.provider}),"Admin"===n&&(0,l.jsx)(Y.Z,{children:e.api_base}),(0,l.jsx)(Y.Z,{children:e.user_access?(0,l.jsx)(em.Z,{color:"green",children:"Yes"}):(0,l.jsx)(ex,{userModels:u,accessToken:t,userID:a})}),(0,l.jsx)(Y.Z,{children:e.input_cost}),(0,l.jsx)(Y.Z,{children:e.output_cost}),(0,l.jsx)(Y.Z,{children:e.max_tokens})]},e.model_name))})]})}),(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Model Statistics (Number Requests)"}),(0,l.jsx)(et.Z,{data:c,index:"model",categories:["num_requests"],colors:["blue"],yAxisWidth:400,layout:"vertical",tickGap:5})]}),(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Model Statistics (Latency)"}),(0,l.jsx)(et.Z,{data:c,index:"model",categories:["avg_latency_seconds"],colors:["red"],yAxisWidth:400,layout:"vertical",tickGap:5})]})]})})},ej=s(92836),ey=s(26734),eg=s(41608),ew=s(32126),eZ=s(23682);let{Option:ef}=U.default;var ek=e=>{let{userID:t,accessToken:s}=e,[n]=L.Z.useForm(),[a,i]=(0,r.useState)(!1),[d,m]=(0,r.useState)(null),[u,x]=(0,r.useState)([]);(0,r.useEffect)(()=>{(async()=>{try{let e=await y(s,t,"any"),l=[];for(let t=0;t{i(!1),n.resetFields()},j=()=>{i(!1),m(null),n.resetFields()},g=async e=>{try{c.ZP.info("Making API Call"),i(!0),console.log("formValues in create user:",e);let l=await h(s,t,e);console.log("user create Response:",l),m(l.key),c.ZP.success("API user Created"),n.resetFields(),localStorage.removeItem("userData"+t)}catch(e){console.error("Error creating the user:",e)}};return(0,l.jsxs)("div",{children:[(0,l.jsx)(o.Z,{className:"mx-auto",onClick:()=>i(!0),children:"+ Create New User"}),(0,l.jsx)(B.Z,{title:"Create User",visible:a,width:800,footer:null,onOk:p,onCancel:j,children:(0,l.jsxs)(L.Z,{form:n,onFinish:g,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsx)(L.Z.Item,{label:"User ID",name:"user_id",children:(0,l.jsx)(z.Z,{placeholder:"Enter User ID"})}),(0,l.jsx)(L.Z.Item,{label:"Team ID",name:"team_id",children:(0,l.jsx)(z.Z,{placeholder:"ai_team"})}),(0,l.jsx)(L.Z.Item,{label:"Models",name:"models",children:(0,l.jsx)(U.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:u.map(e=>(0,l.jsx)(ef,{value:e,children:e},e))})}),(0,l.jsx)(L.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,l.jsx)(K.Z,{step:.01,precision:2,width:200})}),(0,l.jsx)(L.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})}),(0,l.jsx)(L.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})}),(0,l.jsx)(L.Z.Item,{label:"Duration (eg: 30s, 30h, 30d)",name:"duration",children:(0,l.jsx)(z.Z,{})}),(0,l.jsx)(L.Z.Item,{label:"Metadata",name:"metadata",children:(0,l.jsx)(z.Z.TextArea,{rows:4,placeholder:"Enter metadata as JSON"})}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(W.ZP,{htmlType:"submit",children:"Create User"})})]})}),d&&(0,l.jsxs)(B.Z,{title:"Save Your User",visible:a,onOk:p,onCancel:j,footer:null,children:[(0,l.jsxs)("p",{children:["Please save this secret user somewhere safe and accessible. For security reasons, ",(0,l.jsx)("b",{children:"you will not be able to view it again"})," ","through your LiteLLM account. If you lose this secret user, you will need to generate a new one."]}),(0,l.jsx)("p",{children:null!=d?"API user: ".concat(d):"User being created, this might take 30s"})]})]})},e_=e=>{let{accessToken:t,token:s,keys:n,userRole:a,userID:o,setKeys:i}=e,[c,d]=(0,r.useState)(null),[h,m]=(0,r.useState)(null),[x,p]=(0,r.useState)(1);if((0,r.useEffect)(()=>{if(!t||!s||!a||!o)return;let e=async()=>{try{let e=await u(t,null,a,!0);console.log("user data response:",e),d(e)}catch(e){console.error("There was an error fetching the model data",e)}};t&&s&&a&&o&&!c&&e();let l=async()=>{try{let e=await _(t,null);console.log("user data response:",e),m(e)}catch(e){console.error("There was an error fetching the model data",e)}};a&&("Admin"==a||"Admin Viewer"==a)&&!h&&l()},[t,s,a,o]),!c||!t||!s||!a||!o)return(0,l.jsx)("div",{children:"Loading..."});let j=async e=>{try{let s=await _(t,e);console.log("user data response:",s),m(s)}catch(e){console.error("There was an error fetching the model data",e)}};return(0,l.jsx)("div",{style:{width:"100%"},children:(0,l.jsxs)(O.Z,{className:"gap-2 p-10 h-[75vh] w-full",children:[(0,l.jsx)(ek,{userID:o,accessToken:t}),(0,l.jsx)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh] mb-4",children:(0,l.jsxs)(ey.Z,{children:[(0,l.jsxs)(eg.Z,{variant:"line",defaultValue:"1",children:[(0,l.jsx)(ej.Z,{value:"1",children:"Key Owners"}),(0,l.jsx)(ej.Z,{value:"2",children:"End-Users"})]}),(0,l.jsxs)(eZ.Z,{children:[(0,l.jsx)(ew.Z,{children:(0,l.jsxs)($.Z,{className:"mt-5",children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"User ID"}),(0,l.jsx)(Q.Z,{children:"User Role"}),(0,l.jsx)(Q.Z,{children:"User Models"}),(0,l.jsx)(Q.Z,{children:"User Spend ($ USD)"}),(0,l.jsx)(Q.Z,{children:"User Max Budget ($ USD)"})]})}),(0,l.jsx)(H.Z,{children:c.map(e=>(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{children:e.user_id}),(0,l.jsx)(Y.Z,{children:e.user_role?e.user_role:"app_owner"}),(0,l.jsx)(Y.Z,{children:e.models&&e.models.length>0?e.models:"All Models"}),(0,l.jsx)(Y.Z,{children:e.spend?e.spend:0}),(0,l.jsx)(Y.Z,{children:e.max_budget?e.max_budget:"Unlimited"})]},e.user_id))})]})}),(0,l.jsxs)(ew.Z,{children:[(0,l.jsxs)("div",{className:"flex items-center",children:[(0,l.jsx)("div",{className:"flex-1"}),(0,l.jsxs)("div",{className:"flex-1 flex justify-between items-center",children:[(0,l.jsx)(R.Z,{className:"w-1/4 mr-2 text-right",children:"Key"}),(0,l.jsx)(eo.Z,{defaultValue:"1",className:"w-3/4",children:null==n?void 0:n.map((e,t)=>{if(e&&null!==e.key_name&&e.key_name.length>0)return(0,l.jsx)(ei.Z,{value:String(t),onClick:()=>j(e.token),children:e.key_name},t)})})]})]}),(0,l.jsxs)($.Z,{children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"End User"}),(0,l.jsx)(Q.Z,{children:"Spend"}),(0,l.jsx)(Q.Z,{children:"Total Events"})]})}),(0,l.jsx)(H.Z,{children:null==h?void 0:h.map((e,t)=>(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{children:e.end_user}),(0,l.jsx)(Y.Z,{children:e.total_spend}),(0,l.jsx)(Y.Z,{children:e.total_events})]},t))})]})]})]})]})}),function(){if(!c)return null;let e=Math.ceil(c.length/25),t=Math.min(25*x,c.length);return(0,l.jsxs)("div",{className:"flex justify-between items-center",children:[(0,l.jsxs)("div",{children:["Showing ",(x-1)*25+1," – ",t," of ",c.length]}),(0,l.jsxs)("div",{className:"flex",children:[(0,l.jsx)("button",{className:"bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-l focus:outline-none",disabled:1===x,onClick:()=>p(x-1),children:"← Prev"}),(0,l.jsx)("button",{className:"bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-r focus:outline-none",disabled:x===e,onClick:()=>p(x+1),children:"Next →"})]})]})}()]})})},eb=e=>{let{teams:t,searchParams:s,accessToken:n,setTeams:a,userID:i,userRole:d}=e,[h]=L.Z.useForm(),[m]=L.Z.useForm(),{Title:u,Paragraph:x}=ea.default,[p,j]=(0,r.useState)(""),[g,w]=(0,r.useState)(t?t[0]:null),[Z,f]=(0,r.useState)(!1),[k,_]=(0,r.useState)(!1),[b,v]=(0,r.useState)([]);(0,r.useEffect)(()=>{(async()=>{try{if(null===i||null===d)return;if(null!==n){let e=(await y(n,i,d)).data.map(e=>e.id);console.log("available_model_names:",e),v(e)}}catch(e){console.error("Error fetching user models:",e)}})()},[n,i,d]);let S=async e=>{try{if(null!=n){c.ZP.info("Creating Team");let s=await C(n,e);null!==t?a([...t,s]):a([s]),console.log("response for team create call: ".concat(s)),c.ZP.success("Team created"),f(!1)}}catch(e){console.error("Error creating the key:",e),c.ZP.error("Error creating the team: "+e)}},N=async e=>{try{if(null!=n&&null!=t){c.ZP.info("Adding Member");let s={role:"user",user_email:e.user_email,user_id:e.user_id},l=await T(n,g.team_id,s);console.log("response for team create call: ".concat(l.data));let r=t.findIndex(e=>(console.log("team.team_id=".concat(e.team_id,"; response.data.team_id=").concat(l.data.team_id)),e.team_id===l.data.team_id));if(console.log("foundIndex: ".concat(r)),-1!==r){let e=[...t];e[r]=l.data,a(e),w(l.data)}_(!1)}}catch(e){console.error("Error creating the key:",e)}};return console.log("received teams ".concat(t)),(0,l.jsx)("div",{className:"w-full mx-4",children:(0,l.jsxs)(O.Z,{numItems:1,className:"gap-2 p-2 h-[75vh] w-full",children:[(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(u,{level:4,children:"All Teams"}),(0,l.jsx)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,l.jsxs)($.Z,{children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"Team Name"}),(0,l.jsx)(Q.Z,{children:"Spend (USD)"}),(0,l.jsx)(Q.Z,{children:"Budget (USD)"}),(0,l.jsx)(Q.Z,{children:"Models"}),(0,l.jsx)(Q.Z,{children:"TPM / RPM Limits"})]})}),(0,l.jsx)(H.Z,{children:t&&t.length>0?t.map(e=>(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:e.team_alias}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:e.spend}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:e.max_budget?e.max_budget:"No limit"}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:JSON.stringify(e.models?e.models:[])})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsxs)(R.Z,{children:["TPM Limit:"," ",e.tpm_limit?e.tpm_limit:"Unlimited"," ",(0,l.jsx)("br",{}),"RPM Limit:"," ",e.rpm_limit?e.rpm_limit:"Unlimited"]})})]},e.team_id)):null})]})})]}),(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(o.Z,{className:"mx-auto",onClick:()=>f(!0),children:"+ Create New Team"}),(0,l.jsx)(B.Z,{title:"Create Team",visible:Z,width:800,footer:null,onOk:()=>{f(!1),h.resetFields()},onCancel:()=>{f(!1),h.resetFields()},children:(0,l.jsxs)(L.Z,{form:h,onFinish:S,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(L.Z.Item,{label:"Team Name",name:"team_alias",children:(0,l.jsx)(z.Z,{})}),(0,l.jsx)(L.Z.Item,{label:"Models",name:"models",children:(0,l.jsx)(U.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:b.map(e=>(0,l.jsx)(U.default.Option,{value:e,children:e},e))})}),(0,l.jsx)(L.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,l.jsx)(K.Z,{step:.01,precision:2,width:200})}),(0,l.jsx)(L.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})}),(0,l.jsx)(L.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})})]}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(W.ZP,{htmlType:"submit",children:"Create Team"})})]})})]}),(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(u,{level:4,children:"Team Members"}),(0,l.jsx)(x,{children:"If you belong to multiple teams, this setting controls which teams members you see."}),t&&t.length>0?(0,l.jsx)(eo.Z,{defaultValue:"0",children:t.map((e,t)=>(0,l.jsx)(ei.Z,{value:String(t),onClick:()=>{w(e)},children:e.team_alias},t))}):(0,l.jsxs)(x,{children:["No team created. ",(0,l.jsx)("b",{children:"Defaulting to personal account."})]})]}),(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsx)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,l.jsxs)($.Z,{children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"Member Name"}),(0,l.jsx)(Q.Z,{children:"Role"})]})}),(0,l.jsx)(H.Z,{children:g?g.members_with_roles.map((e,t)=>(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{children:e.user_email?e.user_email:e.user_id?e.user_id:null}),(0,l.jsx)(Y.Z,{children:e.role})]},t)):null})]})})}),(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(o.Z,{className:"mx-auto mb-5",onClick:()=>_(!0),children:"+ Add member"}),(0,l.jsx)(B.Z,{title:"Add member",visible:k,width:800,footer:null,onOk:()=>{_(!1),m.resetFields()},onCancel:()=>{_(!1),m.resetFields()},children:(0,l.jsxs)(L.Z,{form:h,onFinish:N,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(L.Z.Item,{label:"Email",name:"user_email",className:"mb-4",children:(0,l.jsx)(z.Z,{name:"user_email",className:"px-3 py-2 border rounded-md w-full"})}),(0,l.jsx)("div",{className:"text-center mb-4",children:"OR"}),(0,l.jsx)(L.Z.Item,{label:"User ID",name:"user_id",className:"mb-4",children:(0,l.jsx)(z.Z,{name:"user_id",className:"px-3 py-2 border rounded-md w-full"})})]}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(W.ZP,{htmlType:"submit",children:"Add member"})})]})})]})]})})},ev=s(8510),eS=e=>{let{searchParams:t,accessToken:s}=e,[n]=L.Z.useForm(),[a]=L.Z.useForm(),{Title:i,Paragraph:d}=ea.default,[h,m]=(0,r.useState)(""),[u,x]=(0,r.useState)(null),[p,j]=(0,r.useState)(!1);(0,r.useEffect)(()=>{(async()=>{if(null!=s){let e=[],t=await A(s,"proxy_admin_viewer");t.forEach(t=>{e.push({user_role:t.user_role,user_id:t.user_id,user_email:t.user_email})}),console.log("proxy viewers: ".concat(t));let l=await A(s,"proxy_admin");l.forEach(t=>{e.push({user_role:t.user_role,user_id:t.user_id,user_email:t.user_email})}),console.log("proxy admins: ".concat(l)),console.log("combinedList: ".concat(e)),x(e)}})()},[s]);let y=async e=>{try{if(null!=s&&null!=u){c.ZP.info("Making API Call"),e.user_email,e.user_id;let t=await I(s,e);console.log("response for team create call: ".concat(t));let l=u.findIndex(e=>(console.log("user.user_id=".concat(e.user_id,"; response.user_id=").concat(t.user_id)),e.user_id===t.user_id));console.log("foundIndex: ".concat(l)),-1==l&&(console.log("updates admin with new user"),u.push(t),x(u)),j(!1)}}catch(e){console.error("Error creating the key:",e)}};return console.log("admins: ".concat(null==u?void 0:u.length)),(0,l.jsxs)("div",{className:"w-full m-2",children:[(0,l.jsx)(i,{level:4,children:"Restricted Access"}),(0,l.jsxs)(d,{children:["Add other people to just view spend. They cannot create keys, teams or grant users access to new models."," ",(0,l.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/ui#restrict-ui-access",children:"Requires SSO Setup"})]}),(0,l.jsxs)(O.Z,{numItems:1,className:"gap-2 p-0 w-full",children:[(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsx)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,l.jsxs)($.Z,{children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"Member Name"}),(0,l.jsx)(Q.Z,{children:"Role"}),(0,l.jsx)(Q.Z,{children:"Action"})]})}),(0,l.jsx)(H.Z,{children:u?u.map((e,t)=>(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{children:e.user_email?e.user_email:e.user_id?e.user_id:null}),(0,l.jsx)(Y.Z,{children:e.user_role}),(0,l.jsx)(Y.Z,{children:(0,l.jsx)(G.Z,{icon:ev.Z,size:"sm"})})]},t)):null})]})})}),(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(o.Z,{className:"mx-auto mb-5",onClick:()=>j(!0),children:"+ Add viewer"}),(0,l.jsx)(B.Z,{title:"Add viewer",visible:p,width:800,footer:null,onOk:()=>{j(!1),a.resetFields()},onCancel:()=>{j(!1),a.resetFields()},children:(0,l.jsxs)(L.Z,{form:n,onFinish:y,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(L.Z.Item,{label:"Email",name:"user_email",className:"mb-4",children:(0,l.jsx)(z.Z,{name:"user_email",className:"px-3 py-2 border rounded-md w-full"})}),(0,l.jsx)("div",{className:"text-center mb-4",children:"OR"}),(0,l.jsx)(L.Z.Item,{label:"User ID",name:"user_id",className:"mb-4",children:(0,l.jsx)(z.Z,{name:"user_id",className:"px-3 py-2 border rounded-md w-full"})})]}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(W.ZP,{htmlType:"submit",children:"Add member"})})]})})]})]})]})},eN=s(12968),eA=s(67951);async function eC(e,t,s,l){console.log("isLocal:",!1);let r=window.location.origin,n=new eN.ZP.OpenAI({apiKey:l,baseURL:r,dangerouslyAllowBrowser:!0});for await(let l of(await n.chat.completions.create({model:s,stream:!0,messages:[{role:"user",content:e}]})))console.log(l),l.choices[0].delta.content&&t(l.choices[0].delta.content)}var eT=e=>{let{accessToken:t,token:s,userRole:n,userID:a}=e,[o,i]=(0,r.useState)(""),[c,d]=(0,r.useState)([]),[h,m]=(0,r.useState)(void 0),[u,x]=(0,r.useState)(null);(0,r.useEffect)(()=>{t&&s&&n&&a&&(async()=>{let e=await y(t,a,n);console.log("model_info:",e),(null==e?void 0:e.data.length)>0&&(x(e.data),m(e.data[0].id))})()},[t,a,n]);let p=(e,t)=>{d(s=>{let l=s[s.length-1];return l&&l.role===e?[...s.slice(0,s.length-1),{role:e,content:l.content+t}]:[...s,{role:e,content:t}]})},j=async()=>{if(""!==o.trim()&&t&&s&&n&&a){d(e=>[...e,{role:"user",content:o}]);try{h&&await eC(o,e=>p("assistant",e),h,t)}catch(e){console.error("Error fetching model response",e),p("assistant","Error fetching model response")}i("")}};if(n&&"Admin Viewer"==n){let{Title:e,Paragraph:t}=ea.default;return(0,l.jsxs)("div",{children:[(0,l.jsx)(e,{level:1,children:"Access Denied"}),(0,l.jsx)(t,{children:"Ask your proxy admin for access to test models"})]})}return(0,l.jsx)("div",{style:{width:"100%",position:"relative"},children:(0,l.jsx)(O.Z,{className:"gap-2 p-10 h-[75vh] w-full",children:(0,l.jsx)(M.Z,{children:(0,l.jsxs)(ey.Z,{children:[(0,l.jsxs)(eg.Z,{className:"mt-4",children:[(0,l.jsx)(ej.Z,{children:"Chat"}),(0,l.jsx)(ej.Z,{children:"API Reference"})]}),(0,l.jsxs)(eZ.Z,{children:[(0,l.jsxs)(ew.Z,{children:[(0,l.jsxs)("div",{children:[(0,l.jsx)("label",{children:"Select Model:"}),(0,l.jsx)("select",{value:h||"",onChange:e=>m(e.target.value),children:null==u?void 0:u.map(e=>(0,l.jsx)("option",{value:e.id,children:e.id},e.id))})]}),(0,l.jsxs)($.Z,{className:"mt-5",style:{display:"block",maxHeight:"60vh",overflowY:"auto"},children:[(0,l.jsx)(X.Z,{children:(0,l.jsx)(ee.Z,{children:(0,l.jsx)(Y.Z,{children:(0,l.jsx)(D.Z,{children:"Chat"})})})}),(0,l.jsx)(H.Z,{children:c.map((e,t)=>(0,l.jsx)(ee.Z,{children:(0,l.jsx)(Y.Z,{children:"".concat(e.role,": ").concat(e.content)})},t))})]}),(0,l.jsx)("div",{className:"mt-3",style:{position:"absolute",bottom:5,width:"95%"},children:(0,l.jsxs)("div",{className:"flex",children:[(0,l.jsx)("input",{type:"text",value:o,onChange:e=>i(e.target.value),className:"flex-1 p-2 border rounded-md mr-2",placeholder:"Type your message..."}),(0,l.jsx)("button",{onClick:j,className:"p-2 bg-blue-500 text-white rounded-md",children:"Send"})]})})]}),(0,l.jsx)(ew.Z,{children:(0,l.jsxs)(ey.Z,{children:[(0,l.jsxs)(eg.Z,{children:[(0,l.jsx)(ej.Z,{children:"OpenAI Python SDK"}),(0,l.jsx)(ej.Z,{children:"LlamaIndex"}),(0,l.jsx)(ej.Z,{children:"Langchain Py"})]}),(0,l.jsxs)(eZ.Z,{children:[(0,l.jsx)(ew.Z,{children:(0,l.jsx)(eA.Z,{language:"python",children:'\nimport openai\nclient = openai.OpenAI(\n api_key="your_api_key",\n base_url="http://0.0.0.0:4000" # proxy base url\n)\n\nresponse = client.chat.completions.create(\n model="gpt-3.5-turbo", # model to use from Models Tab\n messages = [\n {\n "role": "user",\n "content": "this is a test request, write a short poem"\n }\n ],\n extra_body={\n "metadata": {\n "generation_name": "ishaan-generation-openai-client",\n "generation_id": "openai-client-gen-id22",\n "trace_id": "openai-client-trace-id22",\n "trace_user_id": "openai-client-user-id2"\n }\n }\n)\n\nprint(response)\n '})}),(0,l.jsx)(ew.Z,{children:(0,l.jsx)(eA.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="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,l.jsx)(ew.Z,{children:(0,l.jsx)(eA.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:8000",\n model = "gpt-3.5-turbo",\n temperature=0.1,\n extra_body={\n "metadata": {\n "generation_name": "ishaan-generation-langchain-client",\n "generation_id": "langchain-client-gen-id22",\n "trace_id": "langchain-client-trace-id22",\n "trace_user_id": "langchain-client-user-id2"\n }\n }\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 '})})]})]})})]})]})})})})},eI=s(33509),eP=s(30569);let{Sider:eE}=eI.default;var eF=e=>{let{setPage:t,userRole:s,defaultSelectedKey:r}=e;return"Admin Viewer"==s?(0,l.jsx)(eI.default,{style:{minHeight:"100vh",maxWidth:"120px"},children:(0,l.jsx)(eE,{width:120,children:(0,l.jsxs)(eP.Z,{mode:"inline",defaultSelectedKeys:r||["4"],style:{height:"100%",borderRight:0},children:[(0,l.jsx)(eP.Z.Item,{onClick:()=>t("api-keys"),children:"API Keys"},"4"),(0,l.jsx)(eP.Z.Item,{onClick:()=>t("models"),children:"Models"},"2"),(0,l.jsx)(eP.Z.Item,{onClick:()=>t("llm-playground"),children:"Chat UI"},"3"),(0,l.jsx)(eP.Z.Item,{onClick:()=>t("usage"),children:"Usage"},"1")]})})}):(0,l.jsx)(eI.default,{style:{minHeight:"100vh",maxWidth:"120px"},children:(0,l.jsx)(eE,{width:120,children:(0,l.jsxs)(eP.Z,{mode:"inline",defaultSelectedKeys:r||["1"],style:{height:"100%",borderRight:0},children:[(0,l.jsx)(eP.Z.Item,{onClick:()=>t("api-keys"),children:"API Keys"},"1"),(0,l.jsx)(eP.Z.Item,{onClick:()=>t("models"),children:"Models"},"2"),(0,l.jsx)(eP.Z.Item,{onClick:()=>t("llm-playground"),children:"Chat UI"},"3"),(0,l.jsx)(eP.Z.Item,{onClick:()=>t("usage"),children:"Usage"},"4"),"Admin"==s?(0,l.jsx)(eP.Z.Item,{onClick:()=>t("users"),children:"Users"},"5"):null,"Admin"==s?(0,l.jsx)(eP.Z.Item,{onClick:()=>t("teams"),children:"Teams"},"6"):null,"Admin"==s?(0,l.jsx)(eP.Z.Item,{onClick:()=>t("admin-panel"),children:"Admin"},"7"):null]})})})},eO=e=>{let{accessToken:t,token:s,userRole:n,userID:a}=e,o=new Date,[i,c]=(0,r.useState)([]),[d,h]=(0,r.useState)([]),[m,u]=(0,r.useState)([]),[x,p]=(0,r.useState)([]),[j,y]=(0,r.useState)([]),[g,_]=(0,r.useState)([]),[S,N]=(0,r.useState)([]),A=new Date(o.getFullYear(),o.getMonth(),1),C=new Date(o.getFullYear(),o.getMonth()+1,0),T=P(A),I=P(C);function P(e){let t=e.getFullYear(),s=e.getMonth()+1,l=e.getDate();return"".concat(t,"-").concat(s<10?"0"+s:s,"-").concat(l<10?"0"+l:l)}return console.log("Start date is ".concat(T)),console.log("End date is ".concat(I)),(0,r.useEffect)(()=>{t&&s&&n&&a&&(async()=>{try{if(console.log("user role: ".concat(n)),"Admin"==n||"Admin Viewer"==n){let e=await f(t);c(e);let s=(await k(t)).map(e=>({key:(e.key_name||e.key_alias||e.api_key).substring(0,7),spend:e.total_spend}));h(s);let l=(await b(t)).map(e=>({key:e.model,spend:e.total_spend}));u(l);let r=await w(t);console.log("teamSpend",r),y(r.daily_spend),_(r.teams),N(r.total_spend_per_team)}else"App Owner"==n&&await Z(t,s,n,a,T,I).then(async e=>{if(console.log("result from spend logs call",e),"daily_spend"in e){let t=e.daily_spend;console.log("daily spend",t),c(t);let s=e.top_api_keys;h(s)}else{let s=(await v(t,function(e){let t=[];e.forEach(e=>{Object.entries(e).forEach(e=>{let[s,l]=e;"spend"!==s&&"startTime"!==s&&"models"!==s&&"users"!==s&&t.push({key:s,spend:l})})}),t.sort((e,t)=>Number(t.spend)-Number(e.spend));let s=t.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||e.token).substring(0,7),spend:e.spend}));h(s),p(function(e){let t={};e.forEach(e=>{Object.entries(e.users).forEach(e=>{let[s,l]=e;""!==s&&null!=s&&"None"!=s&&(t[s]||(t[s]=0),t[s]+=l)})});let s=Object.entries(t).map(e=>{let[t,s]=e;return{user_id:t,spend:s}});s.sort((e,t)=>t.spend-e.spend);let l=s.slice(0,5);return console.log("topKeys: ".concat(Object.values(l[0]))),l}(e)),c(e)}})}catch(e){console.error("There was an error fetching the data",e)}})()},[t,s,n,a,T,I]),(0,l.jsx)("div",{style:{width:"100%"},children:(0,l.jsxs)(ey.Z,{children:[(0,l.jsxs)(eg.Z,{className:"mt-4",children:[(0,l.jsx)(ej.Z,{children:"All Up"}),(0,l.jsx)(ej.Z,{children:"Team Based Usage"})]}),(0,l.jsxs)(eZ.Z,{children:[(0,l.jsx)(ew.Z,{children:(0,l.jsxs)(O.Z,{numItems:2,className:"gap-2 p-10 h-[75vh] w-full",children:[(0,l.jsx)(F.Z,{numColSpan:2,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Monthly Spend"}),(0,l.jsx)(et.Z,{data:i,index:"date",categories:["spend"],colors:["blue"],valueFormatter:e=>"$ ".concat(new Intl.NumberFormat("us").format(e).toString()),yAxisWidth:100,tickGap:5})]})}),(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Top API Keys"}),(0,l.jsx)(et.Z,{className:"mt-4 h-40",data:d,index:"key",categories:["spend"],colors:["blue"],yAxisWidth:80,tickGap:5,layout:"vertical",showXAxis:!1,showLegend:!1})]})}),(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Top Users"}),(0,l.jsx)(et.Z,{className:"mt-4 h-40",data:x,index:"user_id",categories:["spend"],colors:["blue"],yAxisWidth:200,layout:"vertical",showXAxis:!1,showLegend:!1})]})}),(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Top Models"}),(0,l.jsx)(et.Z,{className:"mt-4 h-40",data:m,index:"key",categories:["spend"],colors:["blue"],yAxisWidth:200,layout:"vertical",showXAxis:!1,showLegend:!1})]})})]})}),(0,l.jsx)(ew.Z,{children:(0,l.jsxs)(O.Z,{numItems:2,className:"gap-2 p-10 h-[75vh] w-full",children:[(0,l.jsx)(F.Z,{numColSpan:2,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Daily Spend Per Team"}),(0,l.jsx)(et.Z,{className:"h-72",data:j,index:"date",categories:g,yAxisWidth:30,stack:!0})]})}),(0,l.jsx)(F.Z,{numColSpan:2,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Total Spend Per Team"}),(0,l.jsx)(et.Z,{className:"h-72",data:S,index:"team_id",categories:["total_spend"],yAxisWidth:30})]})})]})})]})]})})},eM=()=>{let{Title:e,Paragraph:t}=ea.default,[s,a]=(0,r.useState)(""),[o,c]=(0,r.useState)(null),[d,h]=(0,r.useState)(null),[m,u]=(0,r.useState)(null),[x,p]=(0,r.useState)(!0),j=(0,n.useSearchParams)(),y=j.get("userID"),g=j.get("token"),[w,Z]=(0,r.useState)("api-keys"),[f,k]=(0,r.useState)(null);return(0,r.useEffect)(()=>{if(g){let e=(0,ed.o)(g);if(e){if(console.log("Decoded token:",e),console.log("Decoded key:",e.key),k(e.key),e.user_role){let t=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"app_user":return"App User";default:return"Unknown Role"}}(e.user_role);console.log("Decoded user_role:",t),a(t),"Admin Viewer"==t&&Z("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?p("username_password"==e.login_method):console.log("User Email is not set ".concat(e))}}},[g]),(0,l.jsx)(r.Suspense,{fallback:(0,l.jsx)("div",{children:"Loading..."}),children:(0,l.jsxs)("div",{className:"flex flex-col min-h-screen",children:[(0,l.jsx)(i,{userID:y,userRole:s,userEmail:o,showSSOBanner:x}),(0,l.jsxs)("div",{className:"flex flex-1 overflow-auto",children:[(0,l.jsx)(eF,{setPage:Z,userRole:s,defaultSelectedKey:null}),"api-keys"==w?(0,l.jsx)(eh,{userID:y,userRole:s,teams:d,keys:m,setUserRole:a,userEmail:o,setUserEmail:c,setTeams:h,setKeys:u}):"models"==w?(0,l.jsx)(ep,{userID:y,userRole:s,token:g,accessToken:f}):"llm-playground"==w?(0,l.jsx)(eT,{userID:y,userRole:s,token:g,accessToken:f}):"users"==w?(0,l.jsx)(e_,{userID:y,userRole:s,token:g,keys:m,accessToken:f,setKeys:u}):"teams"==w?(0,l.jsx)(eb,{teams:d,setTeams:h,searchParams:j,accessToken:f,userID:y,userRole:s}):"admin-panel"==w?(0,l.jsx)(eS,{setTeams:h,searchParams:j,accessToken:f}):(0,l.jsx)(eO,{userID:y,userRole:s,token:g,accessToken:f})]})]})})}}},function(e){e.O(0,[730,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 c7e3747d6..c3784800b 100644 --- a/litellm/proxy/_experimental/out/index.html +++ b/litellm/proxy/_experimental/out/index.html @@ -1 +1 @@ -🚅 LiteLLM \ No newline at end of file +🚅 LiteLLM \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/index.txt b/litellm/proxy/_experimental/out/index.txt index 2c6c4f5bb..c63474e28 100644 --- a/litellm/proxy/_experimental/out/index.txt +++ b/litellm/proxy/_experimental/out/index.txt @@ -1,7 +1,7 @@ 2:I[77831,[],""] -3:I[92182,["730","static/chunks/730-1411b729a1c79695.js","931","static/chunks/app/page-7811c13c82288ada.js"],""] +3:I[92182,["730","static/chunks/730-1411b729a1c79695.js","931","static/chunks/app/page-a94f48a4c941dbe4.js"],""] 4:I[5613,[],""] 5:I[31778,[],""] -0:["NOy_Z-02UirnQn7wjpTs0",[[["",{"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_c23dc8","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/68a21c6e6697f7ca.css","precedence":"next","crossOrigin":""}]],"$L6"]]]] +0:["IXxGmLpL0ryrAsqCmdljD",[[["",{"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_c23dc8","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/68a21c6e6697f7ca.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"}],["$","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 a53766463..3e5ac000f 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

404

This page could not be found.

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

404

This page could not be found.

\ No newline at end of file diff --git a/ui/litellm-dashboard/out/_next/static/NOy_Z-02UirnQn7wjpTs0/_buildManifest.js b/ui/litellm-dashboard/out/_next/static/IXxGmLpL0ryrAsqCmdljD/_buildManifest.js similarity index 100% rename from ui/litellm-dashboard/out/_next/static/NOy_Z-02UirnQn7wjpTs0/_buildManifest.js rename to ui/litellm-dashboard/out/_next/static/IXxGmLpL0ryrAsqCmdljD/_buildManifest.js diff --git a/ui/litellm-dashboard/out/_next/static/NOy_Z-02UirnQn7wjpTs0/_ssgManifest.js b/ui/litellm-dashboard/out/_next/static/IXxGmLpL0ryrAsqCmdljD/_ssgManifest.js similarity index 100% rename from ui/litellm-dashboard/out/_next/static/NOy_Z-02UirnQn7wjpTs0/_ssgManifest.js rename to ui/litellm-dashboard/out/_next/static/IXxGmLpL0ryrAsqCmdljD/_ssgManifest.js diff --git a/ui/litellm-dashboard/out/_next/static/chunks/app/page-7811c13c82288ada.js b/ui/litellm-dashboard/out/_next/static/chunks/app/page-a94f48a4c941dbe4.js similarity index 54% rename from ui/litellm-dashboard/out/_next/static/chunks/app/page-7811c13c82288ada.js rename to ui/litellm-dashboard/out/_next/static/chunks/app/page-a94f48a4c941dbe4.js index 8aae09847..755ccbe7e 100644 --- a/ui/litellm-dashboard/out/_next/static/chunks/app/page-7811c13c82288ada.js +++ b/ui/litellm-dashboard/out/_next/static/chunks/app/page-a94f48a4c941dbe4.js @@ -1 +1 @@ -(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[931],{20661:function(e,t,s){Promise.resolve().then(s.bind(s,92182))},92182:function(e,t,s){"use strict";s.r(t),s.d(t,{default:function(){return eM}});var l=s(3827),r=s(64090),a=s(47907),n=s(8792),o=s(2179),i=e=>{let{userID:t,userRole:s,userEmail:r,showSSOBanner:a}=e;return console.log("User ID:",t),console.log("userEmail:",r),(0,l.jsxs)("nav",{className:"left-0 right-0 top-0 flex justify-between items-center h-12 mb-4",children:[(0,l.jsx)("div",{className:"text-left my-2 absolute top-0 left-0",children:(0,l.jsx)("div",{className:"flex flex-col items-center",children:(0,l.jsx)(n.default,{href:"/",children:(0,l.jsx)("button",{className:"text-gray-800 text-2xl py-1 rounded text-center",children:(0,l.jsx)("img",{src:"/get_image",width:200,height:200,alt:"LiteLLM Brand",className:"mr-2"})})})})}),(0,l.jsxs)("div",{className:"text-right mx-4 my-2 absolute top-0 right-0 flex items-center justify-end space-x-2",children:[a?(0,l.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/ui#setup-ssoauth-for-ui",target:"_blank",className:"mr-2"}):null,(0,l.jsxs)(o.Z,{variant:"secondary",size:"lg",children:[r,(0,l.jsxs)("p",{children:["Role: ",s]}),(0,l.jsxs)("p",{children:["ID: ",t]})]})]})]})},c=s(80588);let d=async(e,t,s)=>{try{if(console.log("Form Values in keyCreateCall:",s),s.description&&(s.metadata||(s.metadata={}),s.metadata.description=s.description,delete s.description,s.metadata=JSON.stringify(s.metadata)),s.metadata){console.log("formValues.metadata:",s.metadata);try{s.metadata=JSON.parse(s.metadata)}catch(e){throw c.ZP.error("Failed to parse metadata: "+e),Error("Failed to parse metadata: "+e)}}console.log("Form Values after check:",s);let l=await fetch("/key/generate",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({user_id:t,...s})});if(!l.ok){let e=await l.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let r=await l.json();return console.log("API Response:",r),r}catch(e){throw console.error("Failed to create key:",e),e}},h=async(e,t,s)=>{try{if(console.log("Form Values in keyCreateCall:",s),s.description&&(s.metadata||(s.metadata={}),s.metadata.description=s.description,delete s.description,s.metadata=JSON.stringify(s.metadata)),s.metadata){console.log("formValues.metadata:",s.metadata);try{s.metadata=JSON.parse(s.metadata)}catch(e){throw c.ZP.error("Failed to parse metadata: "+e),Error("Failed to parse metadata: "+e)}}console.log("Form Values after check:",s);let l=await fetch("/user/new",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({user_id:t,...s})});if(!l.ok){let e=await l.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let r=await l.json();return console.log("API Response:",r),r}catch(e){throw console.error("Failed to create key:",e),e}},m=async(e,t)=>{try{console.log("in keyDeleteCall:",t);let s=await fetch("/key/delete",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({keys:[t]})});if(!s.ok){let e=await s.text();throw c.ZP.error("Failed to delete key: "+e),Error("Network response was not ok")}let l=await s.json();return console.log(l),l}catch(e){throw console.error("Failed to create key:",e),e}},u=async function(e,t,s){let l=arguments.length>3&&void 0!==arguments[3]&&arguments[3];try{let r="/user/info";"App Owner"==s&&t&&(r="".concat(r,"?user_id=").concat(t)),console.log("in userInfoCall viewAll=",l),l&&(r="".concat(r,"?view_all=true"));let a=await fetch(r,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!a.ok){let e=await a.text();throw c.ZP.error(e),Error("Network response was not ok")}let n=await a.json();return console.log("API Response:",n),n}catch(e){throw console.error("Failed to create key:",e),e}},x=async e=>{try{let t=await fetch("/global/spend",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},p=async(e,t,s)=>{try{let t=await fetch("/v2/model/info",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},j=async(e,t,s)=>{try{let t=await fetch("/model/metrics",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},y=async(e,t,s)=>{try{let t=await fetch("/models",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},g=async(e,t)=>{try{let s="/global/spend/logs";console.log("in keySpendLogsCall:",s);let l=await fetch("".concat(s,"?api_key=").concat(t),{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw c.ZP.error(e),Error("Network response was not ok")}let r=await l.json();return console.log(r),r}catch(e){throw console.error("Failed to create key:",e),e}},w=async e=>{try{let t="/global/spend/teams";console.log("in teamSpendLogsCall:",t);let s=await fetch("".concat(t),{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!s.ok){let e=await s.text();throw c.ZP.error(e),Error("Network response was not ok")}let l=await s.json();return console.log(l),l}catch(e){throw console.error("Failed to create key:",e),e}},Z=async(e,t,s,l,r,a)=>{try{console.log("user role in spend logs call: ".concat(s));let t="/spend/logs";t="App Owner"==s?"".concat(t,"?user_id=").concat(l,"&start_date=").concat(r,"&end_date=").concat(a):"".concat(t,"?start_date=").concat(r,"&end_date=").concat(a);let n=await fetch(t,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!n.ok){let e=await n.text();throw c.ZP.error(e),Error("Network response was not ok")}let o=await n.json();return console.log(o),o}catch(e){throw console.error("Failed to create key:",e),e}},f=async e=>{try{let t=await fetch("/global/spend/logs",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to create key:",e),e}},k=async e=>{try{let t=await fetch("/global/spend/keys?limit=5",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to create key:",e),e}},_=async(e,t)=>{try{t&&JSON.stringify({api_key:t});let s={method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}};t&&(s.body=JSON.stringify({api_key:t}));let l=await fetch("/global/spend/end_users",s);if(!l.ok){let e=await l.text();throw c.ZP.error(e),Error("Network response was not ok")}let r=await l.json();return console.log(r),r}catch(e){throw console.error("Failed to create key:",e),e}},b=async e=>{try{let t=await fetch("/global/spend/models?limit=5",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to create key:",e),e}},v=async(e,t)=>{try{let s=await fetch("/v2/key/info",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({keys:t})});if(!s.ok){let e=await s.text();throw c.ZP.error(e),Error("Network response was not ok")}let l=await s.json();return console.log(l),l}catch(e){throw console.error("Failed to create key:",e),e}},S=async(e,t,s,l)=>{try{let r=await fetch("/user/request_model",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({models:[t],user_id:s,justification:l})});if(!r.ok){let e=await r.text();throw c.ZP.error("Failed to delete key: "+e),Error("Network response was not ok")}let a=await r.json();return console.log(a),a}catch(e){throw console.error("Failed to create key:",e),e}},N=async e=>{try{let t="/user/get_requests";console.log("in userGetRequesedtModelsCall:",t);let s=await fetch(t,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!s.ok){let e=await s.text();throw c.ZP.error("Failed to delete key: "+e),Error("Network response was not ok")}let l=await s.json();return console.log(l),l}catch(e){throw console.error("Failed to get requested models:",e),e}},A=async(e,t)=>{try{let s="/user/get_users?role=".concat(t);console.log("in userGetAllUsersCall:",s);let l=await fetch(s,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw c.ZP.error("Failed to delete key: "+e),Error("Network response was not ok")}let r=await l.json();return console.log(r),r}catch(e){throw console.error("Failed to get requested models:",e),e}},C=async(e,t)=>{try{console.log("Form Values in teamCreateCall:",t);let s=await fetch("/team/new",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...t})});if(!s.ok){let e=await s.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let l=await s.json();return console.log("API Response:",l),l}catch(e){throw console.error("Failed to create key:",e),e}},T=async(e,t,s)=>{try{console.log("Form Values in teamMemberAddCall:",s);let l=await fetch("/team/member_add",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({team_id:t,member:s})});if(!l.ok){let e=await l.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let r=await l.json();return console.log("API Response:",r),r}catch(e){throw console.error("Failed to create key:",e),e}},I=async(e,t)=>{try{console.log("Form Values in userUpdateUserCall:",t);let s=await fetch("/user/update",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({user_role:"proxy_admin_viewer",...t})});if(!s.ok){let e=await s.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let l=await s.json();return console.log("API Response:",l),l}catch(e){throw console.error("Failed to create key:",e),e}},P=async(e,t)=>{try{let s=await fetch("/global/predict/spend/logs",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({data:t})});if(!s.ok){let e=await s.text();throw c.ZP.error(e),Error("Network response was not ok")}let l=await s.json();return console.log(l),l}catch(e){throw console.error("Failed to create key:",e),e}},E=async e=>{try{console.log("Checking Slack Budget Alerts service health");let t=await fetch("/health/services?service=slack_budget_alerts",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error("Failed Slack Alert test: "+e),Error(e)}let s=await t.json();return c.ZP.success("Test Slack Alert worked - check your Slack!"),console.log("Service Health Response:",s),s}catch(e){throw console.error("Failed to perform health check:",e),e}};var F=s(10384),O=s(46453),M=s(13810),R=s(71801),D=s(42440),U=s(17189),L=s(12143),B=s(77171),z=s(42539),K=s(88707),W=s(1861);let{Option:V}=U.default;var q=e=>{let{userID:t,teamID:s,userRole:a,accessToken:n,data:i,userModels:h,setData:m}=e,[u]=L.Z.useForm(),[x,p]=(0,r.useState)(!1),[j,y]=(0,r.useState)(null),[g,w]=(0,r.useState)(null),Z=()=>{p(!1),u.resetFields()},f=()=>{p(!1),y(null),u.resetFields()},k=async e=>{try{c.ZP.info("Making API Call"),p(!0);let s=await d(n,t,e);console.log("key create Response:",s),m(e=>e?[...e,s]:[s]),y(s.key),w(s.soft_budget),c.ZP.success("API Key Created"),u.resetFields(),localStorage.removeItem("userData"+t)}catch(e){console.error("Error creating the key:",e)}},_=async()=>{try{console.log("Sending Slack alert...");let e=await E(n);console.log("slackBudgetAlertsHealthCheck Response:",e),console.log("Testing Slack alert successful")}catch(e){console.error("Error sending Slack alert:",e)}};return(0,l.jsxs)("div",{children:[(0,l.jsx)(o.Z,{className:"mx-auto",onClick:()=>p(!0),children:"+ Create New Key"}),(0,l.jsx)(B.Z,{title:"Create Key",visible:x,width:800,footer:null,onOk:Z,onCancel:f,children:(0,l.jsxs)(L.Z,{form:u,onFinish:k,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:["App Owner"===a||"Admin"===a?(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(L.Z.Item,{label:"Key Name",name:"key_alias",children:(0,l.jsx)(z.Z,{})}),(0,l.jsx)(L.Z.Item,{label:"Team ID",name:"team_id",children:(0,l.jsx)(z.Z,{placeholder:"ai_team",defaultValue:s||""})}),(0,l.jsx)(L.Z.Item,{label:"Models",name:"models",children:(0,l.jsx)(U.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:h.map(e=>(0,l.jsx)(V,{value:e,children:e},e))})}),(0,l.jsx)(L.Z.Item,{label:"Soft Budget (USD) Monthly",name:"soft_budget",initialValue:50,children:(0,l.jsx)(K.Z,{step:.01,precision:2,defaultValue:50,width:200})}),(0,l.jsx)(L.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,l.jsx)(K.Z,{step:.01,precision:2,width:200})}),(0,l.jsx)(L.Z.Item,{label:"Reset Budget",name:"budget_duration",children:(0,l.jsxs)(U.default,{defaultValue:null,placeholder:"n/a",children:[(0,l.jsx)(U.default.Option,{value:"24h",children:"daily"}),(0,l.jsx)(U.default.Option,{value:"30d",children:"monthly"})]})}),(0,l.jsx)(L.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})}),(0,l.jsx)(L.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})}),(0,l.jsx)(L.Z.Item,{label:"Expire Key (eg: 30s, 30h, 30d)",name:"duration",children:(0,l.jsx)(z.Z,{})}),(0,l.jsx)(L.Z.Item,{label:"Metadata",name:"metadata",children:(0,l.jsx)(z.Z.TextArea,{rows:4,placeholder:"Enter metadata as JSON"})})]}):(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(L.Z.Item,{label:"Key Name",name:"key_alias",children:(0,l.jsx)(z.Z,{})}),(0,l.jsx)(L.Z.Item,{label:"Team ID (Contact Group)",name:"team_id",children:(0,l.jsx)(z.Z,{placeholder:"ai_team"})}),(0,l.jsx)(L.Z.Item,{label:"Description",name:"description",children:(0,l.jsx)(z.Z.TextArea,{placeholder:"Enter description",rows:4})})]}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(W.ZP,{htmlType:"submit",children:"Create Key"})})]})}),j&&(0,l.jsx)(B.Z,{visible:x,onOk:Z,onCancel:f,footer:null,children:(0,l.jsx)(O.Z,{numItems:1,className:"gap-2 w-full",children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Save your Key"}),(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsxs)("p",{children:["Please save this secret key somewhere safe and accessible. For security reasons, ",(0,l.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,l.jsx)(F.Z,{numColSpan:1,children:null!=j?(0,l.jsxs)("div",{children:[(0,l.jsxs)(R.Z,{children:["API Key: ",j]}),(0,l.jsx)(D.Z,{className:"mt-6",children:"Budgets"}),(0,l.jsxs)(R.Z,{children:["Soft Limit Budget: $",g]}),(0,l.jsx)(o.Z,{className:"mt-3",onClick:_,children:"Test Slack Alert"}),(0,l.jsxs)(R.Z,{className:"mt-2",children:["(LiteLLM Docs -",(0,l.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/alerting",target:"_blank",className:"text-blue-500",children:"Set Up Slack Alerting)"})]})]}):(0,l.jsx)(R.Z,{children:"Key being created, this might take 30s"})})]})})})]})},J=s(33393),G=s(61244),$=s(10827),H=s(3851),Y=s(2044),X=s(64167),Q=s(74480),ee=s(7178),et=s(9853),es=s(56863),el=e=>{let{token:t,accessToken:s,keySpend:a,keyBudget:n,keyName:i}=e,[c,d]=(0,r.useState)(!1),[h,m]=(0,r.useState)(null),[u,x]=(0,r.useState)(""),[p,j]=(0,r.useState)(null),y=async()=>{try{if(null==s||null==t)return;console.log("accessToken: ".concat(s,"; token: ").concat(t));let e=await g(s,t);console.log("Response:",e),m(e);let l=await P(s,e);console.log("Response2:",l);let r=[...e,...l.response];m(r),x(l.predicted_spend),console.log("Combined Data:",r)}catch(e){console.error("There was an error fetching the data",e)}};return t?(0,l.jsxs)("div",{children:[(0,l.jsx)(o.Z,{size:"xs",onClick:()=>{console.log("Show Modal triggered"),d(!0),y()},variant:"secondary",children:"Spend Report"}),(0,l.jsxs)(B.Z,{visible:c,width:1400,onOk:()=>{d(!1)},onCancel:()=>{d(!1)},footer:null,children:[(0,l.jsxs)(D.Z,{style:{textAlign:"left"},children:["Key Name: ",i]}),(0,l.jsxs)(es.Z,{children:["Monthly Spend $",a]}),(0,l.jsx)(D.Z,{children:u}),(0,l.jsx)(M.Z,{className:"mt-6 mb-6",children:h&&(0,l.jsx)(et.Z,{className:"mt-6",data:h,colors:["blue","amber"],index:"date",categories:["spend","predicted_spend"],yAxisWidth:80})})]})]}):null},er=e=>{let{userID:t,accessToken:s,data:a,setData:n}=e,[i,c]=(0,r.useState)(!1),[d,h]=(0,r.useState)(!1),[u,x]=(0,r.useState)(null),p=async e=>{null!=a&&(x(e),localStorage.removeItem("userData"+t),h(!0))},j=async()=>{if(null!=u&&null!=a){try{await m(s,u);let e=a.filter(e=>e.token!==u);n(e)}catch(e){console.error("Error deleting the key:",e)}h(!1),x(null)}};if(null!=a)return console.log("RERENDER TRIGGERED"),(0,l.jsxs)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh] mb-4",children:[(0,l.jsxs)($.Z,{className:"mt-5",children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"Key Alias"}),(0,l.jsx)(Q.Z,{children:"Secret Key"}),(0,l.jsx)(Q.Z,{children:"Spend (USD)"}),(0,l.jsx)(Q.Z,{children:"Key Budget (USD)"}),(0,l.jsx)(Q.Z,{children:"Spend Report"}),(0,l.jsx)(Q.Z,{children:"Team ID"}),(0,l.jsx)(Q.Z,{children:"Metadata"}),(0,l.jsx)(Q.Z,{children:"Models"}),(0,l.jsx)(Q.Z,{children:"TPM / RPM Limits"}),(0,l.jsx)(Q.Z,{children:"Expires"})]})}),(0,l.jsx)(H.Z,{children:a.map(e=>(console.log(e),"litellm-dashboard"===e.team_id)?null:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",whiteSpace:"pre-wrap",overflow:"hidden"},children:null!=e.key_alias?(0,l.jsx)(R.Z,{children:e.key_alias}):(0,l.jsx)(R.Z,{children:"Not Set"})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:e.key_name})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:(()=>{try{return parseFloat(e.spend).toFixed(4)}catch(t){return e.spend}})()})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",whiteSpace:"pre-wrap",overflow:"hidden"},children:null!=e.max_budget?(0,l.jsx)(R.Z,{children:e.max_budget}):(0,l.jsx)(R.Z,{children:"Unlimited Budget"})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px"},children:(0,l.jsx)(el,{token:e.token,accessToken:s,keySpend:e.spend,keyBudget:e.max_budget,keyName:e.key_name})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:e.team_id})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:JSON.stringify(e.metadata).slice(0,400)})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:JSON.stringify(e.models)})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",overflowWrap:"break-word"},children:(0,l.jsxs)(R.Z,{children:["TPM Limit: ",e.tpm_limit?e.tpm_limit:"Unlimited"," ",(0,l.jsx)("br",{})," RPM Limit:"," ",e.rpm_limit?e.rpm_limit:"Unlimited"]})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",wordWrap:"break-word"},children:null!=e.expires?(0,l.jsx)(R.Z,{children:e.expires}):(0,l.jsx)(R.Z,{children:"Never"})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",wordWrap:"break-word"},children:(0,l.jsx)(G.Z,{onClick:()=>p(e.token),icon:J.Z,size:"sm"})})]},e.token))})]}),d&&(0,l.jsx)("div",{className:"fixed z-10 inset-0 overflow-y-auto",children:(0,l.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,l.jsx)("div",{className:"fixed inset-0 transition-opacity","aria-hidden":"true",children:(0,l.jsx)("div",{className:"absolute inset-0 bg-gray-500 opacity-75"})}),(0,l.jsx)("span",{className:"hidden sm:inline-block sm:align-middle sm:h-screen","aria-hidden":"true",children:"​"}),(0,l.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,l.jsx)("div",{className:"bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4",children:(0,l.jsx)("div",{className:"sm:flex sm:items-start",children:(0,l.jsxs)("div",{className:"mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left",children:[(0,l.jsx)("h3",{className:"text-lg leading-6 font-medium text-gray-900",children:"Delete Key"}),(0,l.jsx)("div",{className:"mt-2",children:(0,l.jsx)("p",{className:"text-sm text-gray-500",children:"Are you sure you want to delete this key ?"})})]})})}),(0,l.jsxs)("div",{className:"bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse",children:[(0,l.jsx)(o.Z,{onClick:j,color:"red",className:"ml-2",children:"Delete"}),(0,l.jsx)(o.Z,{onClick:()=>{h(!1),x(null)},children:"Cancel"})]})]})]})})]})},ea=e=>{let{userID:t,userSpendData:s,userRole:a,accessToken:n}=e,[o,i]=(0,r.useState)(null==s?void 0:s.spend),[c,d]=(0,r.useState)((null==s?void 0:s.max_budget)||null);(0,r.useEffect)(()=>{(async()=>{if("Admin"===a)try{let e=await x(n);i(e.spend),d(e.max_budget||null)}catch(e){console.error("Error fetching global spend data:",e)}})()},[a,n]);let h=void 0!==o?o.toFixed(4):null;return(0,l.jsx)(l.Fragment,{children:(0,l.jsxs)(M.Z,{className:"mx-auto mb-4",children:[(0,l.jsxs)(es.Z,{children:["$",h]}),(0,l.jsxs)(D.Z,{children:["/ ",null!==c?"$".concat(c," limit"):"No limit"]})]})})},en=s(36083),eo=s(68967),ei=s(27166),ec=e=>{let{teams:t,setSelectedTeam:s}=e,{Title:a,Paragraph:n}=en.default,[o,i]=(0,r.useState)("");return(0,l.jsxs)("div",{className:"mt-10",children:[(0,l.jsx)(a,{level:4,children:"Default Team"}),(0,l.jsx)(n,{children:"If you belong to multiple teams, this setting controls which team is used by default when creating new API Keys."}),t&&t.length>0?(0,l.jsx)(eo.Z,{defaultValue:"0",children:t.map((e,t)=>(0,l.jsx)(ei.Z,{value:String(t),onClick:()=>s(e),children:e.team_alias},t))}):(0,l.jsxs)(n,{children:["No team created. ",(0,l.jsx)("b",{children:"Defaulting to personal account."})]})]})},ed=s(37963);console.log("isLocal:",!1);var eh=e=>{let{userID:t,userRole:s,teams:n,keys:o,setUserRole:i,userEmail:c,setUserEmail:d,setTeams:h,setKeys:m}=e,[p,j]=(0,r.useState)(null),g=(0,a.useSearchParams)();g.get("viewSpend"),(0,a.useRouter)();let w=g.get("token"),[Z,f]=(0,r.useState)(null),[k,_]=(0,r.useState)([]),[b,v]=(0,r.useState)(n?n[0]:null);if(window.addEventListener("beforeunload",function(){sessionStorage.clear()}),(0,r.useEffect)(()=>{if(w){let e=(0,ed.o)(w);if(e){if(console.log("Decoded token:",e),console.log("Decoded key:",e.key),f(e.key),e.user_role){let t=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";default:return"Unknown Role"}}(e.user_role);console.log("Decoded user_role:",t),i(t)}else console.log("User role not defined");e.user_email?d(e.user_email):console.log("User Email is not set ".concat(e))}}if(t&&Z&&s&&!o&&!p){let e=sessionStorage.getItem("userModels"+t);e?_(JSON.parse(e)):(async()=>{try{let e=await u(Z,t,s);if(console.log("received teams in user dashboard: ".concat(Object.keys(e),"; team values: ").concat(Object.entries(e.teams))),"Admin"==s){let e=await x(Z);j(e),console.log("globalSpend:",e)}else j(e.user_info);m(e.keys),h(e.teams),v(e.teams?e.teams[0]:null),sessionStorage.setItem("userData"+t,JSON.stringify(e.keys)),sessionStorage.setItem("userSpendData"+t,JSON.stringify(e.user_info));let l=(await y(Z,t,s)).data.map(e=>e.id);console.log("available_model_names:",l),_(l),console.log("userModels:",k),sessionStorage.setItem("userModels"+t,JSON.stringify(l))}catch(e){console.error("There was an error fetching the data",e)}})()}},[t,w,Z,o,s]),null==t||null==w){let e="/sso/key/generate";return console.log("Full URL:",e),window.location.href=e,null}if(null==Z)return null;if(null==s&&i("App Owner"),s&&"Admin Viewer"==s){let{Title:e,Paragraph:t}=en.default;return(0,l.jsxs)("div",{children:[(0,l.jsx)(e,{level:1,children:"Access Denied"}),(0,l.jsx)(t,{children:"Ask your proxy admin for access to create keys"})]})}return(0,l.jsx)("div",{children:(0,l.jsx)(O.Z,{numItems:1,className:"gap-0 p-10 h-[75vh] w-full",children:(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(ea,{userID:t,userSpendData:p,userRole:s,accessToken:Z}),(0,l.jsx)(er,{userID:t,accessToken:Z,data:o,setData:m}),(0,l.jsx)(q,{userID:t,teamID:b?b.team_id:null,userRole:s,userModels:k,accessToken:Z,data:o,setData:m}),(0,l.jsx)(ec,{teams:n,setSelectedTeam:v})]})})})},em=s(5);let{Option:eu}=U.default;var ex=e=>{let{userModels:t,accessToken:s,userID:a}=e,[n]=L.Z.useForm(),[i,d]=(0,r.useState)(!1),h=async e=>{try{c.ZP.info("Requesting access");let{selectedModel:t,accessReason:l}=e;await S(s,t,a,l),d(!0)}catch(e){console.error("Error requesting access:",e)}};return(0,l.jsxs)("div",{children:[(0,l.jsx)(o.Z,{size:"xs",onClick:()=>d(!0),children:"Request Access"}),(0,l.jsx)(B.Z,{title:"Request Access",visible:i,width:800,footer:null,onOk:()=>{d(!1),n.resetFields()},onCancel:()=>{d(!1),n.resetFields()},children:(0,l.jsxs)(L.Z,{form:n,onFinish:h,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsx)(L.Z.Item,{label:"Select Model",name:"selectedModel",children:(0,l.jsx)(U.default,{placeholder:"Select model",style:{width:"100%"},children:t.map(e=>(0,l.jsx)(eu,{value:e,children:e},e))})}),(0,l.jsx)(L.Z.Item,{label:"Reason for Access",name:"accessReason",children:(0,l.jsx)(z.Z.TextArea,{rows:4,placeholder:"Enter reason for access"})}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(o.Z,{children:"Request Access"})})]})})]})},ep=e=>{let{accessToken:t,token:s,userRole:a,userID:n}=e,[o,i]=(0,r.useState)({data:[]}),[c,d]=(0,r.useState)([]),[h,m]=(0,r.useState)([]);if((0,r.useEffect)(()=>{if(!t||!s||!a||!n)return;let e=async()=>{try{let e=await p(t,n,a);console.log("Model data response:",e.data),i(e);let s=await j(t,n,a);if(console.log("Model metrics response:",s),d(s),"Admin"===a&&t){let e=await N(t);console.log("Pending Requests:",h),m(e.requests||[])}}catch(e){console.error("There was an error fetching the model data",e)}};t&&s&&a&&n&&e()},[t,s,a,n]),!o||!t||!s||!a||!n)return(0,l.jsx)("div",{children:"Loading..."});let u=[];for(let e=0;e(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{children:(0,l.jsx)(D.Z,{children:e.model_name})}),(0,l.jsx)(Y.Z,{children:e.provider}),"Admin"===a&&(0,l.jsx)(Y.Z,{children:e.api_base}),(0,l.jsx)(Y.Z,{children:e.user_access?(0,l.jsx)(em.Z,{color:"green",children:"Yes"}):(0,l.jsx)(ex,{userModels:u,accessToken:t,userID:n})}),(0,l.jsx)(Y.Z,{children:e.input_cost}),(0,l.jsx)(Y.Z,{children:e.output_cost}),(0,l.jsx)(Y.Z,{children:e.max_tokens})]},e.model_name))})]})}),(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Model Statistics (Number Requests)"}),(0,l.jsx)(et.Z,{data:c,index:"model",categories:["num_requests"],colors:["blue"],yAxisWidth:400,layout:"vertical",tickGap:5})]}),(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Model Statistics (Latency)"}),(0,l.jsx)(et.Z,{data:c,index:"model",categories:["avg_latency_seconds"],colors:["red"],yAxisWidth:400,layout:"vertical",tickGap:5})]})]})})},ej=s(92836),ey=s(26734),eg=s(41608),ew=s(32126),eZ=s(23682);let{Option:ef}=U.default;var ek=e=>{let{userID:t,accessToken:s}=e,[a]=L.Z.useForm(),[n,i]=(0,r.useState)(!1),[d,m]=(0,r.useState)(null),[u,x]=(0,r.useState)([]);(0,r.useEffect)(()=>{(async()=>{try{let e=await y(s,t,"any"),l=[];for(let t=0;t{i(!1),a.resetFields()},j=()=>{i(!1),m(null),a.resetFields()},g=async e=>{try{c.ZP.info("Making API Call"),i(!0),console.log("formValues in create user:",e);let l=await h(s,t,e);console.log("user create Response:",l),m(l.key),c.ZP.success("API user Created"),a.resetFields(),localStorage.removeItem("userData"+t)}catch(e){console.error("Error creating the user:",e)}};return(0,l.jsxs)("div",{children:[(0,l.jsx)(o.Z,{className:"mx-auto",onClick:()=>i(!0),children:"+ Create New User"}),(0,l.jsx)(B.Z,{title:"Create User",visible:n,width:800,footer:null,onOk:p,onCancel:j,children:(0,l.jsxs)(L.Z,{form:a,onFinish:g,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsx)(L.Z.Item,{label:"User ID",name:"user_id",children:(0,l.jsx)(z.Z,{placeholder:"Enter User ID"})}),(0,l.jsx)(L.Z.Item,{label:"Team ID",name:"team_id",children:(0,l.jsx)(z.Z,{placeholder:"ai_team"})}),(0,l.jsx)(L.Z.Item,{label:"Models",name:"models",children:(0,l.jsx)(U.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:u.map(e=>(0,l.jsx)(ef,{value:e,children:e},e))})}),(0,l.jsx)(L.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,l.jsx)(K.Z,{step:.01,precision:2,width:200})}),(0,l.jsx)(L.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})}),(0,l.jsx)(L.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})}),(0,l.jsx)(L.Z.Item,{label:"Duration (eg: 30s, 30h, 30d)",name:"duration",children:(0,l.jsx)(z.Z,{})}),(0,l.jsx)(L.Z.Item,{label:"Metadata",name:"metadata",children:(0,l.jsx)(z.Z.TextArea,{rows:4,placeholder:"Enter metadata as JSON"})}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(W.ZP,{htmlType:"submit",children:"Create User"})})]})}),d&&(0,l.jsxs)(B.Z,{title:"Save Your User",visible:n,onOk:p,onCancel:j,footer:null,children:[(0,l.jsxs)("p",{children:["Please save this secret user somewhere safe and accessible. For security reasons, ",(0,l.jsx)("b",{children:"you will not be able to view it again"})," ","through your LiteLLM account. If you lose this secret user, you will need to generate a new one."]}),(0,l.jsx)("p",{children:null!=d?"API user: ".concat(d):"User being created, this might take 30s"})]})]})},e_=e=>{let{accessToken:t,token:s,keys:a,userRole:n,userID:o,setKeys:i}=e,[c,d]=(0,r.useState)(null),[h,m]=(0,r.useState)(null),[x,p]=(0,r.useState)(1);if((0,r.useEffect)(()=>{if(!t||!s||!n||!o)return;let e=async()=>{try{let e=await u(t,null,n,!0);console.log("user data response:",e),d(e)}catch(e){console.error("There was an error fetching the model data",e)}};t&&s&&n&&o&&!c&&e();let l=async()=>{try{let e=await _(t,null);console.log("user data response:",e),m(e)}catch(e){console.error("There was an error fetching the model data",e)}};n&&("Admin"==n||"Admin Viewer"==n)&&!h&&l()},[t,s,n,o]),!c||!t||!s||!n||!o)return(0,l.jsx)("div",{children:"Loading..."});let j=async e=>{try{let s=await _(t,e);console.log("user data response:",s),m(s)}catch(e){console.error("There was an error fetching the model data",e)}};return(0,l.jsx)("div",{style:{width:"100%"},children:(0,l.jsxs)(O.Z,{className:"gap-2 p-10 h-[75vh] w-full",children:[(0,l.jsx)(ek,{userID:o,accessToken:t}),(0,l.jsx)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh] mb-4",children:(0,l.jsxs)(ey.Z,{children:[(0,l.jsxs)(eg.Z,{variant:"line",defaultValue:"1",children:[(0,l.jsx)(ej.Z,{value:"1",children:"Key Owners"}),(0,l.jsx)(ej.Z,{value:"2",children:"End-Users"})]}),(0,l.jsxs)(eZ.Z,{children:[(0,l.jsx)(ew.Z,{children:(0,l.jsxs)($.Z,{className:"mt-5",children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"User ID"}),(0,l.jsx)(Q.Z,{children:"User Role"}),(0,l.jsx)(Q.Z,{children:"User Models"}),(0,l.jsx)(Q.Z,{children:"User Spend ($ USD)"}),(0,l.jsx)(Q.Z,{children:"User Max Budget ($ USD)"})]})}),(0,l.jsx)(H.Z,{children:c.map(e=>(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{children:e.user_id}),(0,l.jsx)(Y.Z,{children:e.user_role?e.user_role:"app_owner"}),(0,l.jsx)(Y.Z,{children:e.models&&e.models.length>0?e.models:"All Models"}),(0,l.jsx)(Y.Z,{children:e.spend?e.spend:0}),(0,l.jsx)(Y.Z,{children:e.max_budget?e.max_budget:"Unlimited"})]},e.user_id))})]})}),(0,l.jsxs)(ew.Z,{children:[(0,l.jsxs)("div",{className:"flex items-center",children:[(0,l.jsx)("div",{className:"flex-1"}),(0,l.jsxs)("div",{className:"flex-1 flex justify-between items-center",children:[(0,l.jsx)(R.Z,{className:"w-1/4 mr-2 text-right",children:"Key"}),(0,l.jsx)(eo.Z,{defaultValue:"1",className:"w-3/4",children:null==a?void 0:a.map((e,t)=>{if(e&&null!==e.key_name&&e.key_name.length>0)return(0,l.jsx)(ei.Z,{value:String(t),onClick:()=>j(e.token),children:e.key_name},t)})})]})]}),(0,l.jsxs)($.Z,{children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"End User"}),(0,l.jsx)(Q.Z,{children:"Spend"}),(0,l.jsx)(Q.Z,{children:"Total Events"})]})}),(0,l.jsx)(H.Z,{children:null==h?void 0:h.map((e,t)=>(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{children:e.end_user}),(0,l.jsx)(Y.Z,{children:e.total_spend}),(0,l.jsx)(Y.Z,{children:e.total_events})]},t))})]})]})]})]})}),function(){if(!c)return null;let e=Math.ceil(c.length/25),t=Math.min(25*x,c.length);return(0,l.jsxs)("div",{className:"flex justify-between items-center",children:[(0,l.jsxs)("div",{children:["Showing ",(x-1)*25+1," – ",t," of ",c.length]}),(0,l.jsxs)("div",{className:"flex",children:[(0,l.jsx)("button",{className:"bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-l focus:outline-none",disabled:1===x,onClick:()=>p(x-1),children:"← Prev"}),(0,l.jsx)("button",{className:"bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-r focus:outline-none",disabled:x===e,onClick:()=>p(x+1),children:"Next →"})]})]})}()]})})},eb=e=>{let{teams:t,searchParams:s,accessToken:a,setTeams:n,userID:i,userRole:d}=e,[h]=L.Z.useForm(),[m]=L.Z.useForm(),{Title:u,Paragraph:x}=en.default,[p,j]=(0,r.useState)(""),[g,w]=(0,r.useState)(t?t[0]:null),[Z,f]=(0,r.useState)(!1),[k,_]=(0,r.useState)(!1),[b,v]=(0,r.useState)([]);(0,r.useEffect)(()=>{(async()=>{try{if(null===i||null===d)return;if(null!==a){let e=(await y(a,i,d)).data.map(e=>e.id);console.log("available_model_names:",e),v(e)}}catch(e){console.error("Error fetching user models:",e)}})()},[a,i,d]);let S=async e=>{try{if(null!=a){c.ZP.info("Creating Team");let s=await C(a,e);null!==t?n([...t,s]):n([s]),console.log("response for team create call: ".concat(s)),c.ZP.success("Team created"),f(!1)}}catch(e){console.error("Error creating the key:",e),c.ZP.error("Error creating the team: "+e)}},N=async e=>{try{if(null!=a&&null!=t){c.ZP.info("Making API Call");let s={role:"user",user_email:e.user_email,user_id:e.user_id},l=await T(a,g.team_id,s);console.log("response for team create call: ".concat(l.data));let r=t.findIndex(e=>(console.log("team.team_id=".concat(e.team_id,"; response.data.team_id=").concat(l.data.team_id)),e.team_id===l.data.team_id));if(console.log("foundIndex: ".concat(r)),-1!==r){let e=[...t];e[r]=l.data,n(e),w(l.data)}_(!1)}}catch(e){console.error("Error creating the key:",e)}};return console.log("received teams ".concat(t)),(0,l.jsx)("div",{className:"w-full mx-4",children:(0,l.jsxs)(O.Z,{numItems:1,className:"gap-2 p-2 h-[75vh] w-full",children:[(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(u,{level:4,children:"All Teams"}),(0,l.jsx)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,l.jsxs)($.Z,{children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"Team Name"}),(0,l.jsx)(Q.Z,{children:"Spend (USD)"}),(0,l.jsx)(Q.Z,{children:"Budget (USD)"}),(0,l.jsx)(Q.Z,{children:"Models"}),(0,l.jsx)(Q.Z,{children:"TPM / RPM Limits"})]})}),(0,l.jsx)(H.Z,{children:t&&t.length>0?t.map(e=>(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:e.team_alias}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:e.spend}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:e.max_budget?e.max_budget:"No limit"}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:JSON.stringify(e.models?e.models:[])})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsxs)(R.Z,{children:["TPM Limit:"," ",e.tpm_limit?e.tpm_limit:"Unlimited"," ",(0,l.jsx)("br",{}),"RPM Limit:"," ",e.rpm_limit?e.rpm_limit:"Unlimited"]})})]},e.team_id)):null})]})})]}),(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(o.Z,{className:"mx-auto",onClick:()=>f(!0),children:"+ Create New Team"}),(0,l.jsx)(B.Z,{title:"Create Team",visible:Z,width:800,footer:null,onOk:()=>{f(!1),h.resetFields()},onCancel:()=>{f(!1),h.resetFields()},children:(0,l.jsxs)(L.Z,{form:h,onFinish:S,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(L.Z.Item,{label:"Team Name",name:"team_alias",children:(0,l.jsx)(z.Z,{})}),(0,l.jsx)(L.Z.Item,{label:"Models",name:"models",children:(0,l.jsx)(U.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:b.map(e=>(0,l.jsx)(U.default.Option,{value:e,children:e},e))})}),(0,l.jsx)(L.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,l.jsx)(K.Z,{step:.01,precision:2,width:200})}),(0,l.jsx)(L.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})}),(0,l.jsx)(L.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})})]}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(W.ZP,{htmlType:"submit",children:"Create Team"})})]})})]}),(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(u,{level:4,children:"Team Members"}),(0,l.jsx)(x,{children:"If you belong to multiple teams, this setting controls which teams members you see."}),t&&t.length>0?(0,l.jsx)(eo.Z,{defaultValue:"0",children:t.map((e,t)=>(0,l.jsx)(ei.Z,{value:String(t),onClick:()=>{w(e)},children:e.team_alias},t))}):(0,l.jsxs)(x,{children:["No team created. ",(0,l.jsx)("b",{children:"Defaulting to personal account."})]})]}),(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsx)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,l.jsxs)($.Z,{children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"Member Name"}),(0,l.jsx)(Q.Z,{children:"Role"})]})}),(0,l.jsx)(H.Z,{children:g?g.members_with_roles.map((e,t)=>(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{children:e.user_email?e.user_email:e.user_id?e.user_id:null}),(0,l.jsx)(Y.Z,{children:e.role})]},t)):null})]})})}),(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(o.Z,{className:"mx-auto mb-5",onClick:()=>_(!0),children:"+ Add member"}),(0,l.jsx)(B.Z,{title:"Add member",visible:k,width:800,footer:null,onOk:()=>{_(!1),m.resetFields()},onCancel:()=>{_(!1),m.resetFields()},children:(0,l.jsxs)(L.Z,{form:h,onFinish:N,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(L.Z.Item,{label:"Email",name:"user_email",className:"mb-4",children:(0,l.jsx)(z.Z,{name:"user_email",className:"px-3 py-2 border rounded-md w-full"})}),(0,l.jsx)("div",{className:"text-center mb-4",children:"OR"}),(0,l.jsx)(L.Z.Item,{label:"User ID",name:"user_id",className:"mb-4",children:(0,l.jsx)(z.Z,{name:"user_id",className:"px-3 py-2 border rounded-md w-full"})})]}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(W.ZP,{htmlType:"submit",children:"Add member"})})]})})]})]})})},ev=s(8510),eS=e=>{let{searchParams:t,accessToken:s}=e,[a]=L.Z.useForm(),[n]=L.Z.useForm(),{Title:i,Paragraph:d}=en.default,[h,m]=(0,r.useState)(""),[u,x]=(0,r.useState)(null),[p,j]=(0,r.useState)(!1);(0,r.useEffect)(()=>{(async()=>{if(null!=s){let e=[],t=await A(s,"proxy_admin_viewer");t.forEach(t=>{e.push({user_role:t.user_role,user_id:t.user_id,user_email:t.user_email})}),console.log("proxy viewers: ".concat(t));let l=await A(s,"proxy_admin");l.forEach(t=>{e.push({user_role:t.user_role,user_id:t.user_id,user_email:t.user_email})}),console.log("proxy admins: ".concat(l)),console.log("combinedList: ".concat(e)),x(e)}})()},[s]);let y=async e=>{try{if(null!=s&&null!=u){c.ZP.info("Making API Call"),e.user_email,e.user_id;let t=await I(s,e);console.log("response for team create call: ".concat(t));let l=u.findIndex(e=>(console.log("user.user_id=".concat(e.user_id,"; response.user_id=").concat(t.user_id)),e.user_id===t.user_id));console.log("foundIndex: ".concat(l)),-1==l&&(console.log("updates admin with new user"),u.push(t),x(u)),j(!1)}}catch(e){console.error("Error creating the key:",e)}};return console.log("admins: ".concat(null==u?void 0:u.length)),(0,l.jsxs)("div",{className:"w-full m-2",children:[(0,l.jsx)(i,{level:4,children:"Restricted Access"}),(0,l.jsxs)(d,{children:["Add other people to just view spend. They cannot create keys, teams or grant users access to new models."," ",(0,l.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/ui#restrict-ui-access",children:"Requires SSO Setup"})]}),(0,l.jsxs)(O.Z,{numItems:1,className:"gap-2 p-0 w-full",children:[(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsx)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,l.jsxs)($.Z,{children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"Member Name"}),(0,l.jsx)(Q.Z,{children:"Role"}),(0,l.jsx)(Q.Z,{children:"Action"})]})}),(0,l.jsx)(H.Z,{children:u?u.map((e,t)=>(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{children:e.user_email?e.user_email:e.user_id?e.user_id:null}),(0,l.jsx)(Y.Z,{children:e.user_role}),(0,l.jsx)(Y.Z,{children:(0,l.jsx)(G.Z,{icon:ev.Z,size:"sm"})})]},t)):null})]})})}),(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(o.Z,{className:"mx-auto mb-5",onClick:()=>j(!0),children:"+ Add viewer"}),(0,l.jsx)(B.Z,{title:"Add viewer",visible:p,width:800,footer:null,onOk:()=>{j(!1),n.resetFields()},onCancel:()=>{j(!1),n.resetFields()},children:(0,l.jsxs)(L.Z,{form:a,onFinish:y,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(L.Z.Item,{label:"Email",name:"user_email",className:"mb-4",children:(0,l.jsx)(z.Z,{name:"user_email",className:"px-3 py-2 border rounded-md w-full"})}),(0,l.jsx)("div",{className:"text-center mb-4",children:"OR"}),(0,l.jsx)(L.Z.Item,{label:"User ID",name:"user_id",className:"mb-4",children:(0,l.jsx)(z.Z,{name:"user_id",className:"px-3 py-2 border rounded-md w-full"})})]}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(W.ZP,{htmlType:"submit",children:"Add member"})})]})})]})]})]})},eN=s(12968),eA=s(67951);async function eC(e,t,s,l){console.log("isLocal:",!1);let r=window.location.origin,a=new eN.ZP.OpenAI({apiKey:l,baseURL:r,dangerouslyAllowBrowser:!0});for await(let l of(await a.chat.completions.create({model:s,stream:!0,messages:[{role:"user",content:e}]})))console.log(l),l.choices[0].delta.content&&t(l.choices[0].delta.content)}var eT=e=>{let{accessToken:t,token:s,userRole:a,userID:n}=e,[o,i]=(0,r.useState)(""),[c,d]=(0,r.useState)([]),[h,m]=(0,r.useState)(void 0),[u,x]=(0,r.useState)(null);(0,r.useEffect)(()=>{t&&s&&a&&n&&(async()=>{let e=await y(t,n,a);console.log("model_info:",e),(null==e?void 0:e.data.length)>0&&(x(e.data),m(e.data[0].id))})()},[t,n,a]);let p=(e,t)=>{d(s=>{let l=s[s.length-1];return l&&l.role===e?[...s.slice(0,s.length-1),{role:e,content:l.content+t}]:[...s,{role:e,content:t}]})},j=async()=>{if(""!==o.trim()&&t&&s&&a&&n){d(e=>[...e,{role:"user",content:o}]);try{h&&await eC(o,e=>p("assistant",e),h,t)}catch(e){console.error("Error fetching model response",e),p("assistant","Error fetching model response")}i("")}};if(a&&"Admin Viewer"==a){let{Title:e,Paragraph:t}=en.default;return(0,l.jsxs)("div",{children:[(0,l.jsx)(e,{level:1,children:"Access Denied"}),(0,l.jsx)(t,{children:"Ask your proxy admin for access to test models"})]})}return(0,l.jsx)("div",{style:{width:"100%",position:"relative"},children:(0,l.jsx)(O.Z,{className:"gap-2 p-10 h-[75vh] w-full",children:(0,l.jsx)(M.Z,{children:(0,l.jsxs)(ey.Z,{children:[(0,l.jsxs)(eg.Z,{className:"mt-4",children:[(0,l.jsx)(ej.Z,{children:"Chat"}),(0,l.jsx)(ej.Z,{children:"API Reference"})]}),(0,l.jsxs)(eZ.Z,{children:[(0,l.jsxs)(ew.Z,{children:[(0,l.jsxs)("div",{children:[(0,l.jsx)("label",{children:"Select Model:"}),(0,l.jsx)("select",{value:h||"",onChange:e=>m(e.target.value),children:null==u?void 0:u.map(e=>(0,l.jsx)("option",{value:e.id,children:e.id},e.id))})]}),(0,l.jsxs)($.Z,{className:"mt-5",style:{display:"block",maxHeight:"60vh",overflowY:"auto"},children:[(0,l.jsx)(X.Z,{children:(0,l.jsx)(ee.Z,{children:(0,l.jsx)(Y.Z,{children:(0,l.jsx)(D.Z,{children:"Chat"})})})}),(0,l.jsx)(H.Z,{children:c.map((e,t)=>(0,l.jsx)(ee.Z,{children:(0,l.jsx)(Y.Z,{children:"".concat(e.role,": ").concat(e.content)})},t))})]}),(0,l.jsx)("div",{className:"mt-3",style:{position:"absolute",bottom:5,width:"95%"},children:(0,l.jsxs)("div",{className:"flex",children:[(0,l.jsx)("input",{type:"text",value:o,onChange:e=>i(e.target.value),className:"flex-1 p-2 border rounded-md mr-2",placeholder:"Type your message..."}),(0,l.jsx)("button",{onClick:j,className:"p-2 bg-blue-500 text-white rounded-md",children:"Send"})]})})]}),(0,l.jsx)(ew.Z,{children:(0,l.jsxs)(ey.Z,{children:[(0,l.jsxs)(eg.Z,{children:[(0,l.jsx)(ej.Z,{children:"OpenAI Python SDK"}),(0,l.jsx)(ej.Z,{children:"LlamaIndex"}),(0,l.jsx)(ej.Z,{children:"Langchain Py"})]}),(0,l.jsxs)(eZ.Z,{children:[(0,l.jsx)(ew.Z,{children:(0,l.jsx)(eA.Z,{language:"python",children:'\nimport openai\nclient = openai.OpenAI(\n api_key="your_api_key",\n base_url="http://0.0.0.0:4000" # proxy base url\n)\n\nresponse = client.chat.completions.create(\n model="gpt-3.5-turbo", # model to use from Models Tab\n messages = [\n {\n "role": "user",\n "content": "this is a test request, write a short poem"\n }\n ],\n extra_body={\n "metadata": {\n "generation_name": "ishaan-generation-openai-client",\n "generation_id": "openai-client-gen-id22",\n "trace_id": "openai-client-trace-id22",\n "trace_user_id": "openai-client-user-id2"\n }\n }\n)\n\nprint(response)\n '})}),(0,l.jsx)(ew.Z,{children:(0,l.jsx)(eA.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="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,l.jsx)(ew.Z,{children:(0,l.jsx)(eA.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:8000",\n model = "gpt-3.5-turbo",\n temperature=0.1,\n extra_body={\n "metadata": {\n "generation_name": "ishaan-generation-langchain-client",\n "generation_id": "langchain-client-gen-id22",\n "trace_id": "langchain-client-trace-id22",\n "trace_user_id": "langchain-client-user-id2"\n }\n }\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 '})})]})]})})]})]})})})})},eI=s(33509),eP=s(30569);let{Sider:eE}=eI.default;var eF=e=>{let{setPage:t,userRole:s,defaultSelectedKey:r}=e;return"Admin Viewer"==s?(0,l.jsx)(eI.default,{style:{minHeight:"100vh",maxWidth:"120px"},children:(0,l.jsx)(eE,{width:120,children:(0,l.jsxs)(eP.Z,{mode:"inline",defaultSelectedKeys:r||["4"],style:{height:"100%",borderRight:0},children:[(0,l.jsx)(eP.Z.Item,{onClick:()=>t("api-keys"),children:"API Keys"},"4"),(0,l.jsx)(eP.Z.Item,{onClick:()=>t("models"),children:"Models"},"2"),(0,l.jsx)(eP.Z.Item,{onClick:()=>t("llm-playground"),children:"Chat UI"},"3"),(0,l.jsx)(eP.Z.Item,{onClick:()=>t("usage"),children:"Usage"},"1")]})})}):(0,l.jsx)(eI.default,{style:{minHeight:"100vh",maxWidth:"120px"},children:(0,l.jsx)(eE,{width:120,children:(0,l.jsxs)(eP.Z,{mode:"inline",defaultSelectedKeys:r||["1"],style:{height:"100%",borderRight:0},children:[(0,l.jsx)(eP.Z.Item,{onClick:()=>t("api-keys"),children:"API Keys"},"1"),(0,l.jsx)(eP.Z.Item,{onClick:()=>t("models"),children:"Models"},"2"),(0,l.jsx)(eP.Z.Item,{onClick:()=>t("llm-playground"),children:"Chat UI"},"3"),(0,l.jsx)(eP.Z.Item,{onClick:()=>t("usage"),children:"Usage"},"4"),"Admin"==s?(0,l.jsx)(eP.Z.Item,{onClick:()=>t("users"),children:"Users"},"5"):null,"Admin"==s?(0,l.jsx)(eP.Z.Item,{onClick:()=>t("teams"),children:"Teams"},"6"):null,"Admin"==s?(0,l.jsx)(eP.Z.Item,{onClick:()=>t("admin-panel"),children:"Admin"},"7"):null]})})})},eO=e=>{let{accessToken:t,token:s,userRole:a,userID:n}=e,o=new Date,[i,c]=(0,r.useState)([]),[d,h]=(0,r.useState)([]),[m,u]=(0,r.useState)([]),[x,p]=(0,r.useState)([]),[j,y]=(0,r.useState)([]),[g,_]=(0,r.useState)([]),[S,N]=(0,r.useState)([]),A=new Date(o.getFullYear(),o.getMonth(),1),C=new Date(o.getFullYear(),o.getMonth()+1,0),T=P(A),I=P(C);function P(e){let t=e.getFullYear(),s=e.getMonth()+1,l=e.getDate();return"".concat(t,"-").concat(s<10?"0"+s:s,"-").concat(l<10?"0"+l:l)}return console.log("Start date is ".concat(T)),console.log("End date is ".concat(I)),(0,r.useEffect)(()=>{t&&s&&a&&n&&(async()=>{try{if(console.log("user role: ".concat(a)),"Admin"==a||"Admin Viewer"==a){let e=await f(t);c(e);let s=(await k(t)).map(e=>({key:(e.key_name||e.key_alias||e.api_key).substring(0,7),spend:e.total_spend}));h(s);let l=(await b(t)).map(e=>({key:e.model,spend:e.total_spend}));u(l);let r=await w(t);console.log("teamSpend",r),y(r.daily_spend),_(r.teams),N(r.total_spend_per_team)}else"App Owner"==a&&await Z(t,s,a,n,T,I).then(async e=>{if(console.log("result from spend logs call",e),"daily_spend"in e){let t=e.daily_spend;console.log("daily spend",t),c(t);let s=e.top_api_keys;h(s)}else{let s=(await v(t,function(e){let t=[];e.forEach(e=>{Object.entries(e).forEach(e=>{let[s,l]=e;"spend"!==s&&"startTime"!==s&&"models"!==s&&"users"!==s&&t.push({key:s,spend:l})})}),t.sort((e,t)=>Number(t.spend)-Number(e.spend));let s=t.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||e.token).substring(0,7),spend:e.spend}));h(s),p(function(e){let t={};e.forEach(e=>{Object.entries(e.users).forEach(e=>{let[s,l]=e;""!==s&&null!=s&&"None"!=s&&(t[s]||(t[s]=0),t[s]+=l)})});let s=Object.entries(t).map(e=>{let[t,s]=e;return{user_id:t,spend:s}});s.sort((e,t)=>t.spend-e.spend);let l=s.slice(0,5);return console.log("topKeys: ".concat(Object.values(l[0]))),l}(e)),c(e)}})}catch(e){console.error("There was an error fetching the data",e)}})()},[t,s,a,n,T,I]),(0,l.jsx)("div",{style:{width:"100%"},children:(0,l.jsxs)(ey.Z,{children:[(0,l.jsxs)(eg.Z,{className:"mt-4",children:[(0,l.jsx)(ej.Z,{children:"All Up"}),(0,l.jsx)(ej.Z,{children:"Team Based Usage"})]}),(0,l.jsxs)(eZ.Z,{children:[(0,l.jsx)(ew.Z,{children:(0,l.jsxs)(O.Z,{numItems:2,className:"gap-2 p-10 h-[75vh] w-full",children:[(0,l.jsx)(F.Z,{numColSpan:2,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Monthly Spend"}),(0,l.jsx)(et.Z,{data:i,index:"date",categories:["spend"],colors:["blue"],valueFormatter:e=>"$ ".concat(new Intl.NumberFormat("us").format(e).toString()),yAxisWidth:100,tickGap:5})]})}),(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Top API Keys"}),(0,l.jsx)(et.Z,{className:"mt-4 h-40",data:d,index:"key",categories:["spend"],colors:["blue"],yAxisWidth:80,tickGap:5,layout:"vertical",showXAxis:!1,showLegend:!1})]})}),(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Top Users"}),(0,l.jsx)(et.Z,{className:"mt-4 h-40",data:x,index:"user_id",categories:["spend"],colors:["blue"],yAxisWidth:200,layout:"vertical",showXAxis:!1,showLegend:!1})]})}),(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Top Models"}),(0,l.jsx)(et.Z,{className:"mt-4 h-40",data:m,index:"key",categories:["spend"],colors:["blue"],yAxisWidth:200,layout:"vertical",showXAxis:!1,showLegend:!1})]})})]})}),(0,l.jsx)(ew.Z,{children:(0,l.jsxs)(O.Z,{numItems:2,className:"gap-2 p-10 h-[75vh] w-full",children:[(0,l.jsx)(F.Z,{numColSpan:2,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Daily Spend Per Team"}),(0,l.jsx)(et.Z,{className:"h-72",data:j,index:"date",categories:g,yAxisWidth:30,stack:!0})]})}),(0,l.jsx)(F.Z,{numColSpan:2,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Total Spend Per Team"}),(0,l.jsx)(et.Z,{className:"h-72",data:S,index:"team_id",categories:["total_spend"],yAxisWidth:30})]})})]})})]})]})})},eM=()=>{let{Title:e,Paragraph:t}=en.default,[s,n]=(0,r.useState)(""),[o,c]=(0,r.useState)(null),[d,h]=(0,r.useState)(null),[m,u]=(0,r.useState)(null),[x,p]=(0,r.useState)(!0),j=(0,a.useSearchParams)(),y=j.get("userID"),g=j.get("token"),[w,Z]=(0,r.useState)("api-keys"),[f,k]=(0,r.useState)(null);return(0,r.useEffect)(()=>{if(g){let e=(0,ed.o)(g);if(e){if(console.log("Decoded token:",e),console.log("Decoded key:",e.key),k(e.key),e.user_role){let t=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"app_user":return"App User";default:return"Unknown Role"}}(e.user_role);console.log("Decoded user_role:",t),n(t),"Admin Viewer"==t&&Z("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?p("username_password"==e.login_method):console.log("User Email is not set ".concat(e))}}},[g]),(0,l.jsx)(r.Suspense,{fallback:(0,l.jsx)("div",{children:"Loading..."}),children:(0,l.jsxs)("div",{className:"flex flex-col min-h-screen",children:[(0,l.jsx)(i,{userID:y,userRole:s,userEmail:o,showSSOBanner:x}),(0,l.jsxs)("div",{className:"flex flex-1 overflow-auto",children:[(0,l.jsx)(eF,{setPage:Z,userRole:s,defaultSelectedKey:null}),"api-keys"==w?(0,l.jsx)(eh,{userID:y,userRole:s,teams:d,keys:m,setUserRole:n,userEmail:o,setUserEmail:c,setTeams:h,setKeys:u}):"models"==w?(0,l.jsx)(ep,{userID:y,userRole:s,token:g,accessToken:f}):"llm-playground"==w?(0,l.jsx)(eT,{userID:y,userRole:s,token:g,accessToken:f}):"users"==w?(0,l.jsx)(e_,{userID:y,userRole:s,token:g,keys:m,accessToken:f,setKeys:u}):"teams"==w?(0,l.jsx)(eb,{teams:d,setTeams:h,searchParams:j,accessToken:f,userID:y,userRole:s}):"admin-panel"==w?(0,l.jsx)(eS,{setTeams:h,searchParams:j,accessToken:f}):(0,l.jsx)(eO,{userID:y,userRole:s,token:g,accessToken:f})]})]})})}}},function(e){e.O(0,[730,971,69,744],function(){return e(e.s=20661)}),_N_E=e.O()}]); \ No newline at end of file +(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[931],{20661:function(e,t,s){Promise.resolve().then(s.bind(s,92182))},92182:function(e,t,s){"use strict";s.r(t),s.d(t,{default:function(){return eM}});var l=s(3827),r=s(64090),n=s(47907),a=s(8792),o=s(2179),i=e=>{let{userID:t,userRole:s,userEmail:r,showSSOBanner:n}=e;return console.log("User ID:",t),console.log("userEmail:",r),(0,l.jsxs)("nav",{className:"left-0 right-0 top-0 flex justify-between items-center h-12 mb-4",children:[(0,l.jsx)("div",{className:"text-left my-2 absolute top-0 left-0",children:(0,l.jsx)("div",{className:"flex flex-col items-center",children:(0,l.jsx)(a.default,{href:"/",children:(0,l.jsx)("button",{className:"text-gray-800 text-2xl py-1 rounded text-center",children:(0,l.jsx)("img",{src:"/get_image",width:200,height:200,alt:"LiteLLM Brand",className:"mr-2"})})})})}),(0,l.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,l.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/ui#setup-ssoauth-for-ui",target:"_blank",className:"mr-2"}):null,(0,l.jsxs)(o.Z,{variant:"secondary",size:"lg",children:[r,(0,l.jsxs)("p",{children:["Role: ",s]}),(0,l.jsxs)("p",{children:["ID: ",t]})]})]})]})},c=s(80588);let d=async(e,t,s)=>{try{if(console.log("Form Values in keyCreateCall:",s),s.description&&(s.metadata||(s.metadata={}),s.metadata.description=s.description,delete s.description,s.metadata=JSON.stringify(s.metadata)),s.metadata){console.log("formValues.metadata:",s.metadata);try{s.metadata=JSON.parse(s.metadata)}catch(e){throw c.ZP.error("Failed to parse metadata: "+e),Error("Failed to parse metadata: "+e)}}console.log("Form Values after check:",s);let l=await fetch("/key/generate",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({user_id:t,...s})});if(!l.ok){let e=await l.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let r=await l.json();return console.log("API Response:",r),r}catch(e){throw console.error("Failed to create key:",e),e}},h=async(e,t,s)=>{try{if(console.log("Form Values in keyCreateCall:",s),s.description&&(s.metadata||(s.metadata={}),s.metadata.description=s.description,delete s.description,s.metadata=JSON.stringify(s.metadata)),s.metadata){console.log("formValues.metadata:",s.metadata);try{s.metadata=JSON.parse(s.metadata)}catch(e){throw c.ZP.error("Failed to parse metadata: "+e),Error("Failed to parse metadata: "+e)}}console.log("Form Values after check:",s);let l=await fetch("/user/new",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({user_id:t,...s})});if(!l.ok){let e=await l.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let r=await l.json();return console.log("API Response:",r),r}catch(e){throw console.error("Failed to create key:",e),e}},m=async(e,t)=>{try{console.log("in keyDeleteCall:",t);let s=await fetch("/key/delete",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({keys:[t]})});if(!s.ok){let e=await s.text();throw c.ZP.error("Failed to delete key: "+e),Error("Network response was not ok")}let l=await s.json();return console.log(l),l}catch(e){throw console.error("Failed to create key:",e),e}},u=async function(e,t,s){let l=arguments.length>3&&void 0!==arguments[3]&&arguments[3];try{let r="/user/info";"App Owner"==s&&t&&(r="".concat(r,"?user_id=").concat(t)),console.log("in userInfoCall viewAll=",l),l&&(r="".concat(r,"?view_all=true"));let n=await fetch(r,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!n.ok){let e=await n.text();throw c.ZP.error(e),Error("Network response was not ok")}let a=await n.json();return console.log("API Response:",a),a}catch(e){throw console.error("Failed to create key:",e),e}},x=async e=>{try{let t=await fetch("/global/spend",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},p=async(e,t,s)=>{try{let t=await fetch("/v2/model/info",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},j=async(e,t,s)=>{try{let t=await fetch("/model/metrics",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},y=async(e,t,s)=>{try{let t=await fetch("/models",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},g=async(e,t)=>{try{let s="/global/spend/logs";console.log("in keySpendLogsCall:",s);let l=await fetch("".concat(s,"?api_key=").concat(t),{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw c.ZP.error(e),Error("Network response was not ok")}let r=await l.json();return console.log(r),r}catch(e){throw console.error("Failed to create key:",e),e}},w=async e=>{try{let t="/global/spend/teams";console.log("in teamSpendLogsCall:",t);let s=await fetch("".concat(t),{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!s.ok){let e=await s.text();throw c.ZP.error(e),Error("Network response was not ok")}let l=await s.json();return console.log(l),l}catch(e){throw console.error("Failed to create key:",e),e}},Z=async(e,t,s,l,r,n)=>{try{console.log("user role in spend logs call: ".concat(s));let t="/spend/logs";t="App Owner"==s?"".concat(t,"?user_id=").concat(l,"&start_date=").concat(r,"&end_date=").concat(n):"".concat(t,"?start_date=").concat(r,"&end_date=").concat(n);let a=await fetch(t,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!a.ok){let e=await a.text();throw c.ZP.error(e),Error("Network response was not ok")}let o=await a.json();return console.log(o),o}catch(e){throw console.error("Failed to create key:",e),e}},f=async e=>{try{let t=await fetch("/global/spend/logs",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to create key:",e),e}},k=async e=>{try{let t=await fetch("/global/spend/keys?limit=5",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to create key:",e),e}},_=async(e,t)=>{try{t&&JSON.stringify({api_key:t});let s={method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}};t&&(s.body=JSON.stringify({api_key:t}));let l=await fetch("/global/spend/end_users",s);if(!l.ok){let e=await l.text();throw c.ZP.error(e),Error("Network response was not ok")}let r=await l.json();return console.log(r),r}catch(e){throw console.error("Failed to create key:",e),e}},b=async e=>{try{let t=await fetch("/global/spend/models?limit=5",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to create key:",e),e}},v=async(e,t)=>{try{let s=await fetch("/v2/key/info",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({keys:t})});if(!s.ok){let e=await s.text();throw c.ZP.error(e),Error("Network response was not ok")}let l=await s.json();return console.log(l),l}catch(e){throw console.error("Failed to create key:",e),e}},S=async(e,t,s,l)=>{try{let r=await fetch("/user/request_model",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({models:[t],user_id:s,justification:l})});if(!r.ok){let e=await r.text();throw c.ZP.error("Failed to delete key: "+e),Error("Network response was not ok")}let n=await r.json();return console.log(n),n}catch(e){throw console.error("Failed to create key:",e),e}},N=async e=>{try{let t="/user/get_requests";console.log("in userGetRequesedtModelsCall:",t);let s=await fetch(t,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!s.ok){let e=await s.text();throw c.ZP.error("Failed to delete key: "+e),Error("Network response was not ok")}let l=await s.json();return console.log(l),l}catch(e){throw console.error("Failed to get requested models:",e),e}},A=async(e,t)=>{try{let s="/user/get_users?role=".concat(t);console.log("in userGetAllUsersCall:",s);let l=await fetch(s,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw c.ZP.error("Failed to delete key: "+e),Error("Network response was not ok")}let r=await l.json();return console.log(r),r}catch(e){throw console.error("Failed to get requested models:",e),e}},C=async(e,t)=>{try{console.log("Form Values in teamCreateCall:",t);let s=await fetch("/team/new",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...t})});if(!s.ok){let e=await s.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let l=await s.json();return console.log("API Response:",l),l}catch(e){throw console.error("Failed to create key:",e),e}},T=async(e,t,s)=>{try{console.log("Form Values in teamMemberAddCall:",s);let l=await fetch("/team/member_add",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({team_id:t,member:s})});if(!l.ok){let e=await l.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let r=await l.json();return console.log("API Response:",r),r}catch(e){throw console.error("Failed to create key:",e),e}},I=async(e,t)=>{try{console.log("Form Values in userUpdateUserCall:",t);let s=await fetch("/user/update",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({user_role:"proxy_admin_viewer",...t})});if(!s.ok){let e=await s.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let l=await s.json();return console.log("API Response:",l),l}catch(e){throw console.error("Failed to create key:",e),e}},P=async(e,t)=>{try{let s=await fetch("/global/predict/spend/logs",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({data:t})});if(!s.ok){let e=await s.text();throw c.ZP.error(e),Error("Network response was not ok")}let l=await s.json();return console.log(l),l}catch(e){throw console.error("Failed to create key:",e),e}},E=async e=>{try{console.log("Checking Slack Budget Alerts service health");let t=await fetch("/health/services?service=slack_budget_alerts",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error("Failed Slack Alert test: "+e),Error(e)}let s=await t.json();return c.ZP.success("Test Slack Alert worked - check your Slack!"),console.log("Service Health Response:",s),s}catch(e){throw console.error("Failed to perform health check:",e),e}};var F=s(10384),O=s(46453),M=s(13810),R=s(71801),D=s(42440),U=s(17189),L=s(12143),B=s(77171),z=s(42539),K=s(88707),W=s(1861);let{Option:V}=U.default;var q=e=>{let{userID:t,teamID:s,userRole:n,accessToken:a,data:i,userModels:h,setData:m}=e,[u]=L.Z.useForm(),[x,p]=(0,r.useState)(!1),[j,y]=(0,r.useState)(null),[g,w]=(0,r.useState)(null),Z=()=>{p(!1),u.resetFields()},f=()=>{p(!1),y(null),u.resetFields()},k=async e=>{try{c.ZP.info("Making API Call"),p(!0);let s=await d(a,t,e);console.log("key create Response:",s),m(e=>e?[...e,s]:[s]),y(s.key),w(s.soft_budget),c.ZP.success("API Key Created"),u.resetFields(),localStorage.removeItem("userData"+t)}catch(e){console.error("Error creating the key:",e)}},_=async()=>{try{console.log("Sending Slack alert...");let e=await E(a);console.log("slackBudgetAlertsHealthCheck Response:",e),console.log("Testing Slack alert successful")}catch(e){console.error("Error sending Slack alert:",e)}};return(0,l.jsxs)("div",{children:[(0,l.jsx)(o.Z,{className:"mx-auto",onClick:()=>p(!0),children:"+ Create New Key"}),(0,l.jsx)(B.Z,{title:"Create Key",visible:x,width:800,footer:null,onOk:Z,onCancel:f,children:(0,l.jsxs)(L.Z,{form:u,onFinish:k,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:["App Owner"===n||"Admin"===n?(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(L.Z.Item,{label:"Key Name",name:"key_alias",children:(0,l.jsx)(z.Z,{})}),(0,l.jsx)(L.Z.Item,{label:"Team ID",name:"team_id",children:(0,l.jsx)(z.Z,{placeholder:"ai_team",defaultValue:s||""})}),(0,l.jsx)(L.Z.Item,{label:"Models",name:"models",children:(0,l.jsx)(U.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:h.map(e=>(0,l.jsx)(V,{value:e,children:e},e))})}),(0,l.jsx)(L.Z.Item,{label:"Soft Budget (USD) Monthly",name:"soft_budget",initialValue:50,children:(0,l.jsx)(K.Z,{step:.01,precision:2,defaultValue:50,width:200})}),(0,l.jsx)(L.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,l.jsx)(K.Z,{step:.01,precision:2,width:200})}),(0,l.jsx)(L.Z.Item,{label:"Reset Budget",name:"budget_duration",children:(0,l.jsxs)(U.default,{defaultValue:null,placeholder:"n/a",children:[(0,l.jsx)(U.default.Option,{value:"24h",children:"daily"}),(0,l.jsx)(U.default.Option,{value:"30d",children:"monthly"})]})}),(0,l.jsx)(L.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})}),(0,l.jsx)(L.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})}),(0,l.jsx)(L.Z.Item,{label:"Expire Key (eg: 30s, 30h, 30d)",name:"duration",children:(0,l.jsx)(z.Z,{})}),(0,l.jsx)(L.Z.Item,{label:"Metadata",name:"metadata",children:(0,l.jsx)(z.Z.TextArea,{rows:4,placeholder:"Enter metadata as JSON"})})]}):(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(L.Z.Item,{label:"Key Name",name:"key_alias",children:(0,l.jsx)(z.Z,{})}),(0,l.jsx)(L.Z.Item,{label:"Team ID (Contact Group)",name:"team_id",children:(0,l.jsx)(z.Z,{placeholder:"ai_team"})}),(0,l.jsx)(L.Z.Item,{label:"Description",name:"description",children:(0,l.jsx)(z.Z.TextArea,{placeholder:"Enter description",rows:4})})]}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(W.ZP,{htmlType:"submit",children:"Create Key"})})]})}),j&&(0,l.jsx)(B.Z,{visible:x,onOk:Z,onCancel:f,footer:null,children:(0,l.jsx)(O.Z,{numItems:1,className:"gap-2 w-full",children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Save your Key"}),(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsxs)("p",{children:["Please save this secret key somewhere safe and accessible. For security reasons, ",(0,l.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,l.jsx)(F.Z,{numColSpan:1,children:null!=j?(0,l.jsxs)("div",{children:[(0,l.jsxs)(R.Z,{children:["API Key: ",j]}),(0,l.jsx)(D.Z,{className:"mt-6",children:"Budgets"}),(0,l.jsxs)(R.Z,{children:["Soft Limit Budget: $",g]}),(0,l.jsx)(o.Z,{className:"mt-3",onClick:_,children:"Test Slack Alert"}),(0,l.jsxs)(R.Z,{className:"mt-2",children:["(LiteLLM Docs -",(0,l.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/alerting",target:"_blank",className:"text-blue-500",children:"Set Up Slack Alerting)"})]})]}):(0,l.jsx)(R.Z,{children:"Key being created, this might take 30s"})})]})})})]})},J=s(33393),G=s(61244),$=s(10827),H=s(3851),Y=s(2044),X=s(64167),Q=s(74480),ee=s(7178),et=s(9853),es=s(56863),el=e=>{let{token:t,accessToken:s,keySpend:n,keyBudget:a,keyName:i}=e,[c,d]=(0,r.useState)(!1),[h,m]=(0,r.useState)(null),[u,x]=(0,r.useState)(""),[p,j]=(0,r.useState)(null),y=async()=>{try{if(null==s||null==t)return;console.log("accessToken: ".concat(s,"; token: ").concat(t));let e=await g(s,t);console.log("Response:",e),m(e);let l=await P(s,e);console.log("Response2:",l);let r=[...e,...l.response];m(r),x(l.predicted_spend),console.log("Combined Data:",r)}catch(e){console.error("There was an error fetching the data",e)}};return t?(0,l.jsxs)("div",{children:[(0,l.jsx)(o.Z,{size:"xs",onClick:()=>{console.log("Show Modal triggered"),d(!0),y()},variant:"secondary",children:"Spend Report"}),(0,l.jsxs)(B.Z,{visible:c,width:1400,onOk:()=>{d(!1)},onCancel:()=>{d(!1)},footer:null,children:[(0,l.jsxs)(D.Z,{style:{textAlign:"left"},children:["Key Name: ",i]}),(0,l.jsxs)(es.Z,{children:["Monthly Spend $",n]}),(0,l.jsx)(D.Z,{children:u}),(0,l.jsx)(M.Z,{className:"mt-6 mb-6",children:h&&(0,l.jsx)(et.Z,{className:"mt-6",data:h,colors:["blue","amber"],index:"date",categories:["spend","predicted_spend"],yAxisWidth:80})})]})]}):null},er=e=>{let{userID:t,accessToken:s,data:n,setData:a}=e,[i,c]=(0,r.useState)(!1),[d,h]=(0,r.useState)(!1),[u,x]=(0,r.useState)(null),p=async e=>{null!=n&&(x(e),localStorage.removeItem("userData"+t),h(!0))},j=async()=>{if(null!=u&&null!=n){try{await m(s,u);let e=n.filter(e=>e.token!==u);a(e)}catch(e){console.error("Error deleting the key:",e)}h(!1),x(null)}};if(null!=n)return console.log("RERENDER TRIGGERED"),(0,l.jsxs)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh] mb-4",children:[(0,l.jsxs)($.Z,{className:"mt-5",children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"Key Alias"}),(0,l.jsx)(Q.Z,{children:"Secret Key"}),(0,l.jsx)(Q.Z,{children:"Spend (USD)"}),(0,l.jsx)(Q.Z,{children:"Key Budget (USD)"}),(0,l.jsx)(Q.Z,{children:"Spend Report"}),(0,l.jsx)(Q.Z,{children:"Team ID"}),(0,l.jsx)(Q.Z,{children:"Metadata"}),(0,l.jsx)(Q.Z,{children:"Models"}),(0,l.jsx)(Q.Z,{children:"TPM / RPM Limits"}),(0,l.jsx)(Q.Z,{children:"Expires"})]})}),(0,l.jsx)(H.Z,{children:n.map(e=>(console.log(e),"litellm-dashboard"===e.team_id)?null:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",whiteSpace:"pre-wrap",overflow:"hidden"},children:null!=e.key_alias?(0,l.jsx)(R.Z,{children:e.key_alias}):(0,l.jsx)(R.Z,{children:"Not Set"})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:e.key_name})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:(()=>{try{return parseFloat(e.spend).toFixed(4)}catch(t){return e.spend}})()})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",whiteSpace:"pre-wrap",overflow:"hidden"},children:null!=e.max_budget?(0,l.jsx)(R.Z,{children:e.max_budget}):(0,l.jsx)(R.Z,{children:"Unlimited Budget"})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px"},children:(0,l.jsx)(el,{token:e.token,accessToken:s,keySpend:e.spend,keyBudget:e.max_budget,keyName:e.key_name})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:e.team_id})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:JSON.stringify(e.metadata).slice(0,400)})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:JSON.stringify(e.models)})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",overflowWrap:"break-word"},children:(0,l.jsxs)(R.Z,{children:["TPM Limit: ",e.tpm_limit?e.tpm_limit:"Unlimited"," ",(0,l.jsx)("br",{})," RPM Limit:"," ",e.rpm_limit?e.rpm_limit:"Unlimited"]})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",wordWrap:"break-word"},children:null!=e.expires?(0,l.jsx)(R.Z,{children:e.expires}):(0,l.jsx)(R.Z,{children:"Never"})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",wordWrap:"break-word"},children:(0,l.jsx)(G.Z,{onClick:()=>p(e.token),icon:J.Z,size:"sm"})})]},e.token))})]}),d&&(0,l.jsx)("div",{className:"fixed z-10 inset-0 overflow-y-auto",children:(0,l.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,l.jsx)("div",{className:"fixed inset-0 transition-opacity","aria-hidden":"true",children:(0,l.jsx)("div",{className:"absolute inset-0 bg-gray-500 opacity-75"})}),(0,l.jsx)("span",{className:"hidden sm:inline-block sm:align-middle sm:h-screen","aria-hidden":"true",children:"​"}),(0,l.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,l.jsx)("div",{className:"bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4",children:(0,l.jsx)("div",{className:"sm:flex sm:items-start",children:(0,l.jsxs)("div",{className:"mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left",children:[(0,l.jsx)("h3",{className:"text-lg leading-6 font-medium text-gray-900",children:"Delete Key"}),(0,l.jsx)("div",{className:"mt-2",children:(0,l.jsx)("p",{className:"text-sm text-gray-500",children:"Are you sure you want to delete this key ?"})})]})})}),(0,l.jsxs)("div",{className:"bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse",children:[(0,l.jsx)(o.Z,{onClick:j,color:"red",className:"ml-2",children:"Delete"}),(0,l.jsx)(o.Z,{onClick:()=>{h(!1),x(null)},children:"Cancel"})]})]})]})})]})},en=e=>{let{userID:t,userSpendData:s,userRole:n,accessToken:a}=e,[o,i]=(0,r.useState)(null==s?void 0:s.spend),[c,d]=(0,r.useState)((null==s?void 0:s.max_budget)||null);(0,r.useEffect)(()=>{(async()=>{if("Admin"===n)try{let e=await x(a);i(e.spend),d(e.max_budget||null)}catch(e){console.error("Error fetching global spend data:",e)}})()},[n,a]);let h=void 0!==o?o.toFixed(4):null;return(0,l.jsx)(l.Fragment,{children:(0,l.jsxs)(M.Z,{className:"mx-auto mb-4",children:[(0,l.jsxs)(es.Z,{children:["$",h]}),(0,l.jsxs)(D.Z,{children:["/ ",null!==c?"$".concat(c," limit"):"No limit"]})]})})},ea=s(36083),eo=s(68967),ei=s(27166),ec=e=>{let{teams:t,setSelectedTeam:s}=e,{Title:n,Paragraph:a}=ea.default,[o,i]=(0,r.useState)("");return(0,l.jsxs)("div",{className:"mt-10",children:[(0,l.jsx)(n,{level:4,children:"Default Team"}),(0,l.jsx)(a,{children:"If you belong to multiple teams, this setting controls which team is used by default when creating new API Keys."}),t&&t.length>0?(0,l.jsx)(eo.Z,{defaultValue:"0",children:t.map((e,t)=>(0,l.jsx)(ei.Z,{value:String(t),onClick:()=>s(e),children:e.team_alias},t))}):(0,l.jsxs)(a,{children:["No team created. ",(0,l.jsx)("b",{children:"Defaulting to personal account."})]})]})},ed=s(37963);console.log("isLocal:",!1);var eh=e=>{let{userID:t,userRole:s,teams:a,keys:o,setUserRole:i,userEmail:c,setUserEmail:d,setTeams:h,setKeys:m}=e,[p,j]=(0,r.useState)(null),g=(0,n.useSearchParams)();g.get("viewSpend"),(0,n.useRouter)();let w=g.get("token"),[Z,f]=(0,r.useState)(null),[k,_]=(0,r.useState)([]),[b,v]=(0,r.useState)(a?a[0]:null);if(window.addEventListener("beforeunload",function(){sessionStorage.clear()}),(0,r.useEffect)(()=>{if(w){let e=(0,ed.o)(w);if(e){if(console.log("Decoded token:",e),console.log("Decoded key:",e.key),f(e.key),e.user_role){let t=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";default:return"Unknown Role"}}(e.user_role);console.log("Decoded user_role:",t),i(t)}else console.log("User role not defined");e.user_email?d(e.user_email):console.log("User Email is not set ".concat(e))}}if(t&&Z&&s&&!o&&!p){let e=sessionStorage.getItem("userModels"+t);e?_(JSON.parse(e)):(async()=>{try{let e=await u(Z,t,s);if(console.log("received teams in user dashboard: ".concat(Object.keys(e),"; team values: ").concat(Object.entries(e.teams))),"Admin"==s){let e=await x(Z);j(e),console.log("globalSpend:",e)}else j(e.user_info);m(e.keys),h(e.teams),v(e.teams?e.teams[0]:null),sessionStorage.setItem("userData"+t,JSON.stringify(e.keys)),sessionStorage.setItem("userSpendData"+t,JSON.stringify(e.user_info));let l=(await y(Z,t,s)).data.map(e=>e.id);console.log("available_model_names:",l),_(l),console.log("userModels:",k),sessionStorage.setItem("userModels"+t,JSON.stringify(l))}catch(e){console.error("There was an error fetching the data",e)}})()}},[t,w,Z,o,s]),null==t||null==w){let e="/sso/key/generate";return console.log("Full URL:",e),window.location.href=e,null}if(null==Z)return null;if(null==s&&i("App Owner"),s&&"Admin Viewer"==s){let{Title:e,Paragraph:t}=ea.default;return(0,l.jsxs)("div",{children:[(0,l.jsx)(e,{level:1,children:"Access Denied"}),(0,l.jsx)(t,{children:"Ask your proxy admin for access to create keys"})]})}return(0,l.jsx)("div",{children:(0,l.jsx)(O.Z,{numItems:1,className:"gap-0 p-10 h-[75vh] w-full",children:(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(en,{userID:t,userSpendData:p,userRole:s,accessToken:Z}),(0,l.jsx)(er,{userID:t,accessToken:Z,data:o,setData:m}),(0,l.jsx)(q,{userID:t,teamID:b?b.team_id:null,userRole:s,userModels:k,accessToken:Z,data:o,setData:m}),(0,l.jsx)(ec,{teams:a,setSelectedTeam:v})]})})})},em=s(5);let{Option:eu}=U.default;var ex=e=>{let{userModels:t,accessToken:s,userID:n}=e,[a]=L.Z.useForm(),[i,d]=(0,r.useState)(!1),h=async e=>{try{c.ZP.info("Requesting access");let{selectedModel:t,accessReason:l}=e;await S(s,t,n,l),d(!0)}catch(e){console.error("Error requesting access:",e)}};return(0,l.jsxs)("div",{children:[(0,l.jsx)(o.Z,{size:"xs",onClick:()=>d(!0),children:"Request Access"}),(0,l.jsx)(B.Z,{title:"Request Access",visible:i,width:800,footer:null,onOk:()=>{d(!1),a.resetFields()},onCancel:()=>{d(!1),a.resetFields()},children:(0,l.jsxs)(L.Z,{form:a,onFinish:h,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsx)(L.Z.Item,{label:"Select Model",name:"selectedModel",children:(0,l.jsx)(U.default,{placeholder:"Select model",style:{width:"100%"},children:t.map(e=>(0,l.jsx)(eu,{value:e,children:e},e))})}),(0,l.jsx)(L.Z.Item,{label:"Reason for Access",name:"accessReason",children:(0,l.jsx)(z.Z.TextArea,{rows:4,placeholder:"Enter reason for access"})}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(o.Z,{children:"Request Access"})})]})})]})},ep=e=>{let{accessToken:t,token:s,userRole:n,userID:a}=e,[o,i]=(0,r.useState)({data:[]}),[c,d]=(0,r.useState)([]),[h,m]=(0,r.useState)([]);if((0,r.useEffect)(()=>{if(!t||!s||!n||!a)return;let e=async()=>{try{let e=await p(t,a,n);console.log("Model data response:",e.data),i(e);let s=await j(t,a,n);if(console.log("Model metrics response:",s),d(s),"Admin"===n&&t){let e=await N(t);console.log("Pending Requests:",h),m(e.requests||[])}}catch(e){console.error("There was an error fetching the model data",e)}};t&&s&&n&&a&&e()},[t,s,n,a]),!o||!t||!s||!n||!a)return(0,l.jsx)("div",{children:"Loading..."});let u=[];for(let e=0;e(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{children:(0,l.jsx)(D.Z,{children:e.model_name})}),(0,l.jsx)(Y.Z,{children:e.provider}),"Admin"===n&&(0,l.jsx)(Y.Z,{children:e.api_base}),(0,l.jsx)(Y.Z,{children:e.user_access?(0,l.jsx)(em.Z,{color:"green",children:"Yes"}):(0,l.jsx)(ex,{userModels:u,accessToken:t,userID:a})}),(0,l.jsx)(Y.Z,{children:e.input_cost}),(0,l.jsx)(Y.Z,{children:e.output_cost}),(0,l.jsx)(Y.Z,{children:e.max_tokens})]},e.model_name))})]})}),(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Model Statistics (Number Requests)"}),(0,l.jsx)(et.Z,{data:c,index:"model",categories:["num_requests"],colors:["blue"],yAxisWidth:400,layout:"vertical",tickGap:5})]}),(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Model Statistics (Latency)"}),(0,l.jsx)(et.Z,{data:c,index:"model",categories:["avg_latency_seconds"],colors:["red"],yAxisWidth:400,layout:"vertical",tickGap:5})]})]})})},ej=s(92836),ey=s(26734),eg=s(41608),ew=s(32126),eZ=s(23682);let{Option:ef}=U.default;var ek=e=>{let{userID:t,accessToken:s}=e,[n]=L.Z.useForm(),[a,i]=(0,r.useState)(!1),[d,m]=(0,r.useState)(null),[u,x]=(0,r.useState)([]);(0,r.useEffect)(()=>{(async()=>{try{let e=await y(s,t,"any"),l=[];for(let t=0;t{i(!1),n.resetFields()},j=()=>{i(!1),m(null),n.resetFields()},g=async e=>{try{c.ZP.info("Making API Call"),i(!0),console.log("formValues in create user:",e);let l=await h(s,t,e);console.log("user create Response:",l),m(l.key),c.ZP.success("API user Created"),n.resetFields(),localStorage.removeItem("userData"+t)}catch(e){console.error("Error creating the user:",e)}};return(0,l.jsxs)("div",{children:[(0,l.jsx)(o.Z,{className:"mx-auto",onClick:()=>i(!0),children:"+ Create New User"}),(0,l.jsx)(B.Z,{title:"Create User",visible:a,width:800,footer:null,onOk:p,onCancel:j,children:(0,l.jsxs)(L.Z,{form:n,onFinish:g,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsx)(L.Z.Item,{label:"User ID",name:"user_id",children:(0,l.jsx)(z.Z,{placeholder:"Enter User ID"})}),(0,l.jsx)(L.Z.Item,{label:"Team ID",name:"team_id",children:(0,l.jsx)(z.Z,{placeholder:"ai_team"})}),(0,l.jsx)(L.Z.Item,{label:"Models",name:"models",children:(0,l.jsx)(U.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:u.map(e=>(0,l.jsx)(ef,{value:e,children:e},e))})}),(0,l.jsx)(L.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,l.jsx)(K.Z,{step:.01,precision:2,width:200})}),(0,l.jsx)(L.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})}),(0,l.jsx)(L.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})}),(0,l.jsx)(L.Z.Item,{label:"Duration (eg: 30s, 30h, 30d)",name:"duration",children:(0,l.jsx)(z.Z,{})}),(0,l.jsx)(L.Z.Item,{label:"Metadata",name:"metadata",children:(0,l.jsx)(z.Z.TextArea,{rows:4,placeholder:"Enter metadata as JSON"})}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(W.ZP,{htmlType:"submit",children:"Create User"})})]})}),d&&(0,l.jsxs)(B.Z,{title:"Save Your User",visible:a,onOk:p,onCancel:j,footer:null,children:[(0,l.jsxs)("p",{children:["Please save this secret user somewhere safe and accessible. For security reasons, ",(0,l.jsx)("b",{children:"you will not be able to view it again"})," ","through your LiteLLM account. If you lose this secret user, you will need to generate a new one."]}),(0,l.jsx)("p",{children:null!=d?"API user: ".concat(d):"User being created, this might take 30s"})]})]})},e_=e=>{let{accessToken:t,token:s,keys:n,userRole:a,userID:o,setKeys:i}=e,[c,d]=(0,r.useState)(null),[h,m]=(0,r.useState)(null),[x,p]=(0,r.useState)(1);if((0,r.useEffect)(()=>{if(!t||!s||!a||!o)return;let e=async()=>{try{let e=await u(t,null,a,!0);console.log("user data response:",e),d(e)}catch(e){console.error("There was an error fetching the model data",e)}};t&&s&&a&&o&&!c&&e();let l=async()=>{try{let e=await _(t,null);console.log("user data response:",e),m(e)}catch(e){console.error("There was an error fetching the model data",e)}};a&&("Admin"==a||"Admin Viewer"==a)&&!h&&l()},[t,s,a,o]),!c||!t||!s||!a||!o)return(0,l.jsx)("div",{children:"Loading..."});let j=async e=>{try{let s=await _(t,e);console.log("user data response:",s),m(s)}catch(e){console.error("There was an error fetching the model data",e)}};return(0,l.jsx)("div",{style:{width:"100%"},children:(0,l.jsxs)(O.Z,{className:"gap-2 p-10 h-[75vh] w-full",children:[(0,l.jsx)(ek,{userID:o,accessToken:t}),(0,l.jsx)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh] mb-4",children:(0,l.jsxs)(ey.Z,{children:[(0,l.jsxs)(eg.Z,{variant:"line",defaultValue:"1",children:[(0,l.jsx)(ej.Z,{value:"1",children:"Key Owners"}),(0,l.jsx)(ej.Z,{value:"2",children:"End-Users"})]}),(0,l.jsxs)(eZ.Z,{children:[(0,l.jsx)(ew.Z,{children:(0,l.jsxs)($.Z,{className:"mt-5",children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"User ID"}),(0,l.jsx)(Q.Z,{children:"User Role"}),(0,l.jsx)(Q.Z,{children:"User Models"}),(0,l.jsx)(Q.Z,{children:"User Spend ($ USD)"}),(0,l.jsx)(Q.Z,{children:"User Max Budget ($ USD)"})]})}),(0,l.jsx)(H.Z,{children:c.map(e=>(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{children:e.user_id}),(0,l.jsx)(Y.Z,{children:e.user_role?e.user_role:"app_owner"}),(0,l.jsx)(Y.Z,{children:e.models&&e.models.length>0?e.models:"All Models"}),(0,l.jsx)(Y.Z,{children:e.spend?e.spend:0}),(0,l.jsx)(Y.Z,{children:e.max_budget?e.max_budget:"Unlimited"})]},e.user_id))})]})}),(0,l.jsxs)(ew.Z,{children:[(0,l.jsxs)("div",{className:"flex items-center",children:[(0,l.jsx)("div",{className:"flex-1"}),(0,l.jsxs)("div",{className:"flex-1 flex justify-between items-center",children:[(0,l.jsx)(R.Z,{className:"w-1/4 mr-2 text-right",children:"Key"}),(0,l.jsx)(eo.Z,{defaultValue:"1",className:"w-3/4",children:null==n?void 0:n.map((e,t)=>{if(e&&null!==e.key_name&&e.key_name.length>0)return(0,l.jsx)(ei.Z,{value:String(t),onClick:()=>j(e.token),children:e.key_name},t)})})]})]}),(0,l.jsxs)($.Z,{children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"End User"}),(0,l.jsx)(Q.Z,{children:"Spend"}),(0,l.jsx)(Q.Z,{children:"Total Events"})]})}),(0,l.jsx)(H.Z,{children:null==h?void 0:h.map((e,t)=>(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{children:e.end_user}),(0,l.jsx)(Y.Z,{children:e.total_spend}),(0,l.jsx)(Y.Z,{children:e.total_events})]},t))})]})]})]})]})}),function(){if(!c)return null;let e=Math.ceil(c.length/25),t=Math.min(25*x,c.length);return(0,l.jsxs)("div",{className:"flex justify-between items-center",children:[(0,l.jsxs)("div",{children:["Showing ",(x-1)*25+1," – ",t," of ",c.length]}),(0,l.jsxs)("div",{className:"flex",children:[(0,l.jsx)("button",{className:"bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-l focus:outline-none",disabled:1===x,onClick:()=>p(x-1),children:"← Prev"}),(0,l.jsx)("button",{className:"bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-r focus:outline-none",disabled:x===e,onClick:()=>p(x+1),children:"Next →"})]})]})}()]})})},eb=e=>{let{teams:t,searchParams:s,accessToken:n,setTeams:a,userID:i,userRole:d}=e,[h]=L.Z.useForm(),[m]=L.Z.useForm(),{Title:u,Paragraph:x}=ea.default,[p,j]=(0,r.useState)(""),[g,w]=(0,r.useState)(t?t[0]:null),[Z,f]=(0,r.useState)(!1),[k,_]=(0,r.useState)(!1),[b,v]=(0,r.useState)([]);(0,r.useEffect)(()=>{(async()=>{try{if(null===i||null===d)return;if(null!==n){let e=(await y(n,i,d)).data.map(e=>e.id);console.log("available_model_names:",e),v(e)}}catch(e){console.error("Error fetching user models:",e)}})()},[n,i,d]);let S=async e=>{try{if(null!=n){c.ZP.info("Creating Team");let s=await C(n,e);null!==t?a([...t,s]):a([s]),console.log("response for team create call: ".concat(s)),c.ZP.success("Team created"),f(!1)}}catch(e){console.error("Error creating the key:",e),c.ZP.error("Error creating the team: "+e)}},N=async e=>{try{if(null!=n&&null!=t){c.ZP.info("Adding Member");let s={role:"user",user_email:e.user_email,user_id:e.user_id},l=await T(n,g.team_id,s);console.log("response for team create call: ".concat(l.data));let r=t.findIndex(e=>(console.log("team.team_id=".concat(e.team_id,"; response.data.team_id=").concat(l.data.team_id)),e.team_id===l.data.team_id));if(console.log("foundIndex: ".concat(r)),-1!==r){let e=[...t];e[r]=l.data,a(e),w(l.data)}_(!1)}}catch(e){console.error("Error creating the key:",e)}};return console.log("received teams ".concat(t)),(0,l.jsx)("div",{className:"w-full mx-4",children:(0,l.jsxs)(O.Z,{numItems:1,className:"gap-2 p-2 h-[75vh] w-full",children:[(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(u,{level:4,children:"All Teams"}),(0,l.jsx)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,l.jsxs)($.Z,{children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"Team Name"}),(0,l.jsx)(Q.Z,{children:"Spend (USD)"}),(0,l.jsx)(Q.Z,{children:"Budget (USD)"}),(0,l.jsx)(Q.Z,{children:"Models"}),(0,l.jsx)(Q.Z,{children:"TPM / RPM Limits"})]})}),(0,l.jsx)(H.Z,{children:t&&t.length>0?t.map(e=>(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:e.team_alias}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:e.spend}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:e.max_budget?e.max_budget:"No limit"}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:JSON.stringify(e.models?e.models:[])})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsxs)(R.Z,{children:["TPM Limit:"," ",e.tpm_limit?e.tpm_limit:"Unlimited"," ",(0,l.jsx)("br",{}),"RPM Limit:"," ",e.rpm_limit?e.rpm_limit:"Unlimited"]})})]},e.team_id)):null})]})})]}),(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(o.Z,{className:"mx-auto",onClick:()=>f(!0),children:"+ Create New Team"}),(0,l.jsx)(B.Z,{title:"Create Team",visible:Z,width:800,footer:null,onOk:()=>{f(!1),h.resetFields()},onCancel:()=>{f(!1),h.resetFields()},children:(0,l.jsxs)(L.Z,{form:h,onFinish:S,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(L.Z.Item,{label:"Team Name",name:"team_alias",children:(0,l.jsx)(z.Z,{})}),(0,l.jsx)(L.Z.Item,{label:"Models",name:"models",children:(0,l.jsx)(U.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:b.map(e=>(0,l.jsx)(U.default.Option,{value:e,children:e},e))})}),(0,l.jsx)(L.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,l.jsx)(K.Z,{step:.01,precision:2,width:200})}),(0,l.jsx)(L.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})}),(0,l.jsx)(L.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})})]}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(W.ZP,{htmlType:"submit",children:"Create Team"})})]})})]}),(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(u,{level:4,children:"Team Members"}),(0,l.jsx)(x,{children:"If you belong to multiple teams, this setting controls which teams members you see."}),t&&t.length>0?(0,l.jsx)(eo.Z,{defaultValue:"0",children:t.map((e,t)=>(0,l.jsx)(ei.Z,{value:String(t),onClick:()=>{w(e)},children:e.team_alias},t))}):(0,l.jsxs)(x,{children:["No team created. ",(0,l.jsx)("b",{children:"Defaulting to personal account."})]})]}),(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsx)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,l.jsxs)($.Z,{children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"Member Name"}),(0,l.jsx)(Q.Z,{children:"Role"})]})}),(0,l.jsx)(H.Z,{children:g?g.members_with_roles.map((e,t)=>(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{children:e.user_email?e.user_email:e.user_id?e.user_id:null}),(0,l.jsx)(Y.Z,{children:e.role})]},t)):null})]})})}),(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(o.Z,{className:"mx-auto mb-5",onClick:()=>_(!0),children:"+ Add member"}),(0,l.jsx)(B.Z,{title:"Add member",visible:k,width:800,footer:null,onOk:()=>{_(!1),m.resetFields()},onCancel:()=>{_(!1),m.resetFields()},children:(0,l.jsxs)(L.Z,{form:h,onFinish:N,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(L.Z.Item,{label:"Email",name:"user_email",className:"mb-4",children:(0,l.jsx)(z.Z,{name:"user_email",className:"px-3 py-2 border rounded-md w-full"})}),(0,l.jsx)("div",{className:"text-center mb-4",children:"OR"}),(0,l.jsx)(L.Z.Item,{label:"User ID",name:"user_id",className:"mb-4",children:(0,l.jsx)(z.Z,{name:"user_id",className:"px-3 py-2 border rounded-md w-full"})})]}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(W.ZP,{htmlType:"submit",children:"Add member"})})]})})]})]})})},ev=s(8510),eS=e=>{let{searchParams:t,accessToken:s}=e,[n]=L.Z.useForm(),[a]=L.Z.useForm(),{Title:i,Paragraph:d}=ea.default,[h,m]=(0,r.useState)(""),[u,x]=(0,r.useState)(null),[p,j]=(0,r.useState)(!1);(0,r.useEffect)(()=>{(async()=>{if(null!=s){let e=[],t=await A(s,"proxy_admin_viewer");t.forEach(t=>{e.push({user_role:t.user_role,user_id:t.user_id,user_email:t.user_email})}),console.log("proxy viewers: ".concat(t));let l=await A(s,"proxy_admin");l.forEach(t=>{e.push({user_role:t.user_role,user_id:t.user_id,user_email:t.user_email})}),console.log("proxy admins: ".concat(l)),console.log("combinedList: ".concat(e)),x(e)}})()},[s]);let y=async e=>{try{if(null!=s&&null!=u){c.ZP.info("Making API Call"),e.user_email,e.user_id;let t=await I(s,e);console.log("response for team create call: ".concat(t));let l=u.findIndex(e=>(console.log("user.user_id=".concat(e.user_id,"; response.user_id=").concat(t.user_id)),e.user_id===t.user_id));console.log("foundIndex: ".concat(l)),-1==l&&(console.log("updates admin with new user"),u.push(t),x(u)),j(!1)}}catch(e){console.error("Error creating the key:",e)}};return console.log("admins: ".concat(null==u?void 0:u.length)),(0,l.jsxs)("div",{className:"w-full m-2",children:[(0,l.jsx)(i,{level:4,children:"Restricted Access"}),(0,l.jsxs)(d,{children:["Add other people to just view spend. They cannot create keys, teams or grant users access to new models."," ",(0,l.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/ui#restrict-ui-access",children:"Requires SSO Setup"})]}),(0,l.jsxs)(O.Z,{numItems:1,className:"gap-2 p-0 w-full",children:[(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsx)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,l.jsxs)($.Z,{children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"Member Name"}),(0,l.jsx)(Q.Z,{children:"Role"}),(0,l.jsx)(Q.Z,{children:"Action"})]})}),(0,l.jsx)(H.Z,{children:u?u.map((e,t)=>(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{children:e.user_email?e.user_email:e.user_id?e.user_id:null}),(0,l.jsx)(Y.Z,{children:e.user_role}),(0,l.jsx)(Y.Z,{children:(0,l.jsx)(G.Z,{icon:ev.Z,size:"sm"})})]},t)):null})]})})}),(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(o.Z,{className:"mx-auto mb-5",onClick:()=>j(!0),children:"+ Add viewer"}),(0,l.jsx)(B.Z,{title:"Add viewer",visible:p,width:800,footer:null,onOk:()=>{j(!1),a.resetFields()},onCancel:()=>{j(!1),a.resetFields()},children:(0,l.jsxs)(L.Z,{form:n,onFinish:y,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(L.Z.Item,{label:"Email",name:"user_email",className:"mb-4",children:(0,l.jsx)(z.Z,{name:"user_email",className:"px-3 py-2 border rounded-md w-full"})}),(0,l.jsx)("div",{className:"text-center mb-4",children:"OR"}),(0,l.jsx)(L.Z.Item,{label:"User ID",name:"user_id",className:"mb-4",children:(0,l.jsx)(z.Z,{name:"user_id",className:"px-3 py-2 border rounded-md w-full"})})]}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(W.ZP,{htmlType:"submit",children:"Add member"})})]})})]})]})]})},eN=s(12968),eA=s(67951);async function eC(e,t,s,l){console.log("isLocal:",!1);let r=window.location.origin,n=new eN.ZP.OpenAI({apiKey:l,baseURL:r,dangerouslyAllowBrowser:!0});for await(let l of(await n.chat.completions.create({model:s,stream:!0,messages:[{role:"user",content:e}]})))console.log(l),l.choices[0].delta.content&&t(l.choices[0].delta.content)}var eT=e=>{let{accessToken:t,token:s,userRole:n,userID:a}=e,[o,i]=(0,r.useState)(""),[c,d]=(0,r.useState)([]),[h,m]=(0,r.useState)(void 0),[u,x]=(0,r.useState)(null);(0,r.useEffect)(()=>{t&&s&&n&&a&&(async()=>{let e=await y(t,a,n);console.log("model_info:",e),(null==e?void 0:e.data.length)>0&&(x(e.data),m(e.data[0].id))})()},[t,a,n]);let p=(e,t)=>{d(s=>{let l=s[s.length-1];return l&&l.role===e?[...s.slice(0,s.length-1),{role:e,content:l.content+t}]:[...s,{role:e,content:t}]})},j=async()=>{if(""!==o.trim()&&t&&s&&n&&a){d(e=>[...e,{role:"user",content:o}]);try{h&&await eC(o,e=>p("assistant",e),h,t)}catch(e){console.error("Error fetching model response",e),p("assistant","Error fetching model response")}i("")}};if(n&&"Admin Viewer"==n){let{Title:e,Paragraph:t}=ea.default;return(0,l.jsxs)("div",{children:[(0,l.jsx)(e,{level:1,children:"Access Denied"}),(0,l.jsx)(t,{children:"Ask your proxy admin for access to test models"})]})}return(0,l.jsx)("div",{style:{width:"100%",position:"relative"},children:(0,l.jsx)(O.Z,{className:"gap-2 p-10 h-[75vh] w-full",children:(0,l.jsx)(M.Z,{children:(0,l.jsxs)(ey.Z,{children:[(0,l.jsxs)(eg.Z,{className:"mt-4",children:[(0,l.jsx)(ej.Z,{children:"Chat"}),(0,l.jsx)(ej.Z,{children:"API Reference"})]}),(0,l.jsxs)(eZ.Z,{children:[(0,l.jsxs)(ew.Z,{children:[(0,l.jsxs)("div",{children:[(0,l.jsx)("label",{children:"Select Model:"}),(0,l.jsx)("select",{value:h||"",onChange:e=>m(e.target.value),children:null==u?void 0:u.map(e=>(0,l.jsx)("option",{value:e.id,children:e.id},e.id))})]}),(0,l.jsxs)($.Z,{className:"mt-5",style:{display:"block",maxHeight:"60vh",overflowY:"auto"},children:[(0,l.jsx)(X.Z,{children:(0,l.jsx)(ee.Z,{children:(0,l.jsx)(Y.Z,{children:(0,l.jsx)(D.Z,{children:"Chat"})})})}),(0,l.jsx)(H.Z,{children:c.map((e,t)=>(0,l.jsx)(ee.Z,{children:(0,l.jsx)(Y.Z,{children:"".concat(e.role,": ").concat(e.content)})},t))})]}),(0,l.jsx)("div",{className:"mt-3",style:{position:"absolute",bottom:5,width:"95%"},children:(0,l.jsxs)("div",{className:"flex",children:[(0,l.jsx)("input",{type:"text",value:o,onChange:e=>i(e.target.value),className:"flex-1 p-2 border rounded-md mr-2",placeholder:"Type your message..."}),(0,l.jsx)("button",{onClick:j,className:"p-2 bg-blue-500 text-white rounded-md",children:"Send"})]})})]}),(0,l.jsx)(ew.Z,{children:(0,l.jsxs)(ey.Z,{children:[(0,l.jsxs)(eg.Z,{children:[(0,l.jsx)(ej.Z,{children:"OpenAI Python SDK"}),(0,l.jsx)(ej.Z,{children:"LlamaIndex"}),(0,l.jsx)(ej.Z,{children:"Langchain Py"})]}),(0,l.jsxs)(eZ.Z,{children:[(0,l.jsx)(ew.Z,{children:(0,l.jsx)(eA.Z,{language:"python",children:'\nimport openai\nclient = openai.OpenAI(\n api_key="your_api_key",\n base_url="http://0.0.0.0:4000" # proxy base url\n)\n\nresponse = client.chat.completions.create(\n model="gpt-3.5-turbo", # model to use from Models Tab\n messages = [\n {\n "role": "user",\n "content": "this is a test request, write a short poem"\n }\n ],\n extra_body={\n "metadata": {\n "generation_name": "ishaan-generation-openai-client",\n "generation_id": "openai-client-gen-id22",\n "trace_id": "openai-client-trace-id22",\n "trace_user_id": "openai-client-user-id2"\n }\n }\n)\n\nprint(response)\n '})}),(0,l.jsx)(ew.Z,{children:(0,l.jsx)(eA.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="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,l.jsx)(ew.Z,{children:(0,l.jsx)(eA.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:8000",\n model = "gpt-3.5-turbo",\n temperature=0.1,\n extra_body={\n "metadata": {\n "generation_name": "ishaan-generation-langchain-client",\n "generation_id": "langchain-client-gen-id22",\n "trace_id": "langchain-client-trace-id22",\n "trace_user_id": "langchain-client-user-id2"\n }\n }\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 '})})]})]})})]})]})})})})},eI=s(33509),eP=s(30569);let{Sider:eE}=eI.default;var eF=e=>{let{setPage:t,userRole:s,defaultSelectedKey:r}=e;return"Admin Viewer"==s?(0,l.jsx)(eI.default,{style:{minHeight:"100vh",maxWidth:"120px"},children:(0,l.jsx)(eE,{width:120,children:(0,l.jsxs)(eP.Z,{mode:"inline",defaultSelectedKeys:r||["4"],style:{height:"100%",borderRight:0},children:[(0,l.jsx)(eP.Z.Item,{onClick:()=>t("api-keys"),children:"API Keys"},"4"),(0,l.jsx)(eP.Z.Item,{onClick:()=>t("models"),children:"Models"},"2"),(0,l.jsx)(eP.Z.Item,{onClick:()=>t("llm-playground"),children:"Chat UI"},"3"),(0,l.jsx)(eP.Z.Item,{onClick:()=>t("usage"),children:"Usage"},"1")]})})}):(0,l.jsx)(eI.default,{style:{minHeight:"100vh",maxWidth:"120px"},children:(0,l.jsx)(eE,{width:120,children:(0,l.jsxs)(eP.Z,{mode:"inline",defaultSelectedKeys:r||["1"],style:{height:"100%",borderRight:0},children:[(0,l.jsx)(eP.Z.Item,{onClick:()=>t("api-keys"),children:"API Keys"},"1"),(0,l.jsx)(eP.Z.Item,{onClick:()=>t("models"),children:"Models"},"2"),(0,l.jsx)(eP.Z.Item,{onClick:()=>t("llm-playground"),children:"Chat UI"},"3"),(0,l.jsx)(eP.Z.Item,{onClick:()=>t("usage"),children:"Usage"},"4"),"Admin"==s?(0,l.jsx)(eP.Z.Item,{onClick:()=>t("users"),children:"Users"},"5"):null,"Admin"==s?(0,l.jsx)(eP.Z.Item,{onClick:()=>t("teams"),children:"Teams"},"6"):null,"Admin"==s?(0,l.jsx)(eP.Z.Item,{onClick:()=>t("admin-panel"),children:"Admin"},"7"):null]})})})},eO=e=>{let{accessToken:t,token:s,userRole:n,userID:a}=e,o=new Date,[i,c]=(0,r.useState)([]),[d,h]=(0,r.useState)([]),[m,u]=(0,r.useState)([]),[x,p]=(0,r.useState)([]),[j,y]=(0,r.useState)([]),[g,_]=(0,r.useState)([]),[S,N]=(0,r.useState)([]),A=new Date(o.getFullYear(),o.getMonth(),1),C=new Date(o.getFullYear(),o.getMonth()+1,0),T=P(A),I=P(C);function P(e){let t=e.getFullYear(),s=e.getMonth()+1,l=e.getDate();return"".concat(t,"-").concat(s<10?"0"+s:s,"-").concat(l<10?"0"+l:l)}return console.log("Start date is ".concat(T)),console.log("End date is ".concat(I)),(0,r.useEffect)(()=>{t&&s&&n&&a&&(async()=>{try{if(console.log("user role: ".concat(n)),"Admin"==n||"Admin Viewer"==n){let e=await f(t);c(e);let s=(await k(t)).map(e=>({key:(e.key_name||e.key_alias||e.api_key).substring(0,7),spend:e.total_spend}));h(s);let l=(await b(t)).map(e=>({key:e.model,spend:e.total_spend}));u(l);let r=await w(t);console.log("teamSpend",r),y(r.daily_spend),_(r.teams),N(r.total_spend_per_team)}else"App Owner"==n&&await Z(t,s,n,a,T,I).then(async e=>{if(console.log("result from spend logs call",e),"daily_spend"in e){let t=e.daily_spend;console.log("daily spend",t),c(t);let s=e.top_api_keys;h(s)}else{let s=(await v(t,function(e){let t=[];e.forEach(e=>{Object.entries(e).forEach(e=>{let[s,l]=e;"spend"!==s&&"startTime"!==s&&"models"!==s&&"users"!==s&&t.push({key:s,spend:l})})}),t.sort((e,t)=>Number(t.spend)-Number(e.spend));let s=t.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||e.token).substring(0,7),spend:e.spend}));h(s),p(function(e){let t={};e.forEach(e=>{Object.entries(e.users).forEach(e=>{let[s,l]=e;""!==s&&null!=s&&"None"!=s&&(t[s]||(t[s]=0),t[s]+=l)})});let s=Object.entries(t).map(e=>{let[t,s]=e;return{user_id:t,spend:s}});s.sort((e,t)=>t.spend-e.spend);let l=s.slice(0,5);return console.log("topKeys: ".concat(Object.values(l[0]))),l}(e)),c(e)}})}catch(e){console.error("There was an error fetching the data",e)}})()},[t,s,n,a,T,I]),(0,l.jsx)("div",{style:{width:"100%"},children:(0,l.jsxs)(ey.Z,{children:[(0,l.jsxs)(eg.Z,{className:"mt-4",children:[(0,l.jsx)(ej.Z,{children:"All Up"}),(0,l.jsx)(ej.Z,{children:"Team Based Usage"})]}),(0,l.jsxs)(eZ.Z,{children:[(0,l.jsx)(ew.Z,{children:(0,l.jsxs)(O.Z,{numItems:2,className:"gap-2 p-10 h-[75vh] w-full",children:[(0,l.jsx)(F.Z,{numColSpan:2,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Monthly Spend"}),(0,l.jsx)(et.Z,{data:i,index:"date",categories:["spend"],colors:["blue"],valueFormatter:e=>"$ ".concat(new Intl.NumberFormat("us").format(e).toString()),yAxisWidth:100,tickGap:5})]})}),(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Top API Keys"}),(0,l.jsx)(et.Z,{className:"mt-4 h-40",data:d,index:"key",categories:["spend"],colors:["blue"],yAxisWidth:80,tickGap:5,layout:"vertical",showXAxis:!1,showLegend:!1})]})}),(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Top Users"}),(0,l.jsx)(et.Z,{className:"mt-4 h-40",data:x,index:"user_id",categories:["spend"],colors:["blue"],yAxisWidth:200,layout:"vertical",showXAxis:!1,showLegend:!1})]})}),(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Top Models"}),(0,l.jsx)(et.Z,{className:"mt-4 h-40",data:m,index:"key",categories:["spend"],colors:["blue"],yAxisWidth:200,layout:"vertical",showXAxis:!1,showLegend:!1})]})})]})}),(0,l.jsx)(ew.Z,{children:(0,l.jsxs)(O.Z,{numItems:2,className:"gap-2 p-10 h-[75vh] w-full",children:[(0,l.jsx)(F.Z,{numColSpan:2,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Daily Spend Per Team"}),(0,l.jsx)(et.Z,{className:"h-72",data:j,index:"date",categories:g,yAxisWidth:30,stack:!0})]})}),(0,l.jsx)(F.Z,{numColSpan:2,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Total Spend Per Team"}),(0,l.jsx)(et.Z,{className:"h-72",data:S,index:"team_id",categories:["total_spend"],yAxisWidth:30})]})})]})})]})]})})},eM=()=>{let{Title:e,Paragraph:t}=ea.default,[s,a]=(0,r.useState)(""),[o,c]=(0,r.useState)(null),[d,h]=(0,r.useState)(null),[m,u]=(0,r.useState)(null),[x,p]=(0,r.useState)(!0),j=(0,n.useSearchParams)(),y=j.get("userID"),g=j.get("token"),[w,Z]=(0,r.useState)("api-keys"),[f,k]=(0,r.useState)(null);return(0,r.useEffect)(()=>{if(g){let e=(0,ed.o)(g);if(e){if(console.log("Decoded token:",e),console.log("Decoded key:",e.key),k(e.key),e.user_role){let t=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"app_user":return"App User";default:return"Unknown Role"}}(e.user_role);console.log("Decoded user_role:",t),a(t),"Admin Viewer"==t&&Z("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?p("username_password"==e.login_method):console.log("User Email is not set ".concat(e))}}},[g]),(0,l.jsx)(r.Suspense,{fallback:(0,l.jsx)("div",{children:"Loading..."}),children:(0,l.jsxs)("div",{className:"flex flex-col min-h-screen",children:[(0,l.jsx)(i,{userID:y,userRole:s,userEmail:o,showSSOBanner:x}),(0,l.jsxs)("div",{className:"flex flex-1 overflow-auto",children:[(0,l.jsx)(eF,{setPage:Z,userRole:s,defaultSelectedKey:null}),"api-keys"==w?(0,l.jsx)(eh,{userID:y,userRole:s,teams:d,keys:m,setUserRole:a,userEmail:o,setUserEmail:c,setTeams:h,setKeys:u}):"models"==w?(0,l.jsx)(ep,{userID:y,userRole:s,token:g,accessToken:f}):"llm-playground"==w?(0,l.jsx)(eT,{userID:y,userRole:s,token:g,accessToken:f}):"users"==w?(0,l.jsx)(e_,{userID:y,userRole:s,token:g,keys:m,accessToken:f,setKeys:u}):"teams"==w?(0,l.jsx)(eb,{teams:d,setTeams:h,searchParams:j,accessToken:f,userID:y,userRole:s}):"admin-panel"==w?(0,l.jsx)(eS,{setTeams:h,searchParams:j,accessToken:f}):(0,l.jsx)(eO,{userID:y,userRole:s,token:g,accessToken:f})]})]})})}}},function(e){e.O(0,[730,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 c7e3747d6..c3784800b 100644 --- a/ui/litellm-dashboard/out/index.html +++ b/ui/litellm-dashboard/out/index.html @@ -1 +1 @@ -🚅 LiteLLM \ No newline at end of file +🚅 LiteLLM \ No newline at end of file diff --git a/ui/litellm-dashboard/out/index.txt b/ui/litellm-dashboard/out/index.txt index 2c6c4f5bb..c63474e28 100644 --- a/ui/litellm-dashboard/out/index.txt +++ b/ui/litellm-dashboard/out/index.txt @@ -1,7 +1,7 @@ 2:I[77831,[],""] -3:I[92182,["730","static/chunks/730-1411b729a1c79695.js","931","static/chunks/app/page-7811c13c82288ada.js"],""] +3:I[92182,["730","static/chunks/730-1411b729a1c79695.js","931","static/chunks/app/page-a94f48a4c941dbe4.js"],""] 4:I[5613,[],""] 5:I[31778,[],""] -0:["NOy_Z-02UirnQn7wjpTs0",[[["",{"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_c23dc8","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/68a21c6e6697f7ca.css","precedence":"next","crossOrigin":""}]],"$L6"]]]] +0:["IXxGmLpL0ryrAsqCmdljD",[[["",{"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_c23dc8","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/68a21c6e6697f7ca.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"}],["$","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/src/components/teams.tsx b/ui/litellm-dashboard/src/components/teams.tsx index d3e00772e..f1d5d6555 100644 --- a/ui/litellm-dashboard/src/components/teams.tsx +++ b/ui/litellm-dashboard/src/components/teams.tsx @@ -122,7 +122,7 @@ const Team: React.FC = ({ const handleMemberCreate = async (formValues: Record) => { try { if (accessToken != null && teams != null) { - message.info("Making API Call"); + message.info("Adding Member"); const user_role: Member = { role: "user", user_email: formValues.user_email, From 046571ebea462da0e7b23997b1d5f83cd7006600 Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Thu, 28 Mar 2024 08:30:43 -0700 Subject: [PATCH 29/54] (fix) show user models when creating a key --- .../src/components/create_key_button.tsx | 28 +++++++++++++++++-- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/ui/litellm-dashboard/src/components/create_key_button.tsx b/ui/litellm-dashboard/src/components/create_key_button.tsx index fa80556b5..3f2d8e7b5 100644 --- a/ui/litellm-dashboard/src/components/create_key_button.tsx +++ b/ui/litellm-dashboard/src/components/create_key_button.tsx @@ -12,7 +12,7 @@ import { Select, message, } from "antd"; -import { keyCreateCall, slackBudgetAlertsHealthCheck } from "./networking"; +import { keyCreateCall, slackBudgetAlertsHealthCheck, modelAvailableCall } from "./networking"; const { Option } = Select; @@ -22,7 +22,6 @@ interface CreateKeyProps { userRole: string | null; accessToken: string; data: any[] | null; - userModels: string[]; setData: React.Dispatch>; } @@ -32,13 +31,13 @@ const CreateKey: React.FC = ({ userRole, accessToken, data, - userModels, setData, }) => { const [form] = Form.useForm(); const [isModalVisible, setIsModalVisible] = useState(false); const [apiKey, setApiKey] = useState(null); const [softBudget, setSoftBudget] = useState(null); + const [userModels, setUserModels] = useState([]); const handleOk = () => { setIsModalVisible(false); form.resetFields(); @@ -50,6 +49,29 @@ const CreateKey: React.FC = ({ form.resetFields(); }; + useEffect(() => { + const fetchUserModels = async () => { + try { + if (userID === null || userRole === null) { + return; + } + + if (accessToken !== null) { + const model_available = await modelAvailableCall(accessToken, userID, userRole); + let available_model_names = model_available["data"].map( + (element: { id: string }) => element.id + ); + console.log("available_model_names:", available_model_names); + setUserModels(available_model_names); + } + } catch (error) { + console.error("Error fetching user models:", error); + } + }; + + fetchUserModels(); + }, [accessToken, userID, userRole]); + const handleCreate = async (formValues: Record) => { try { message.info("Making API Call"); From 37db367ba62aee809a6c817dff00cc06681f8091 Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Thu, 28 Mar 2024 09:07:10 -0700 Subject: [PATCH 30/54] (fix) creating key for a team --- ui/litellm-dashboard/src/components/create_key_button.tsx | 7 ++++--- ui/litellm-dashboard/src/components/user_dashboard.tsx | 5 ++++- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/ui/litellm-dashboard/src/components/create_key_button.tsx b/ui/litellm-dashboard/src/components/create_key_button.tsx index 3f2d8e7b5..7ce84b1f5 100644 --- a/ui/litellm-dashboard/src/components/create_key_button.tsx +++ b/ui/litellm-dashboard/src/components/create_key_button.tsx @@ -18,7 +18,7 @@ const { Option } = Select; interface CreateKeyProps { userID: string; - teamID: string | null; + team: any | null; userRole: string | null; accessToken: string; data: any[] | null; @@ -27,7 +27,7 @@ interface CreateKeyProps { const CreateKey: React.FC = ({ userID, - teamID, + team, userRole, accessToken, data, @@ -130,7 +130,8 @@ const CreateKey: React.FC = ({ diff --git a/ui/litellm-dashboard/src/components/user_dashboard.tsx b/ui/litellm-dashboard/src/components/user_dashboard.tsx index d164a35a1..ecbd0f6f9 100644 --- a/ui/litellm-dashboard/src/components/user_dashboard.tsx +++ b/ui/litellm-dashboard/src/components/user_dashboard.tsx @@ -203,6 +203,8 @@ const UserDashboard: React.FC = ({ ); } + console.log("inside user dashboard, selected team", selectedTeam); + return (
@@ -220,8 +222,9 @@ const UserDashboard: React.FC = ({ setData={setKeys} /> Date: Thu, 28 Mar 2024 09:11:41 -0700 Subject: [PATCH 31/54] (feat) new ui build --- litellm/proxy/_experimental/out/404.html | 2 +- .../_buildManifest.js | 0 .../_ssgManifest.js | 0 .../out/_next/static/chunks/app/page-07e952a07a29317d.js | 1 + .../out/_next/static/chunks/app/page-a94f48a4c941dbe4.js | 1 - litellm/proxy/_experimental/out/index.html | 2 +- litellm/proxy/_experimental/out/index.txt | 4 ++-- ui/litellm-dashboard/out/404.html | 2 +- .../_buildManifest.js | 0 .../_ssgManifest.js | 0 .../out/_next/static/chunks/app/page-07e952a07a29317d.js | 1 + .../out/_next/static/chunks/app/page-a94f48a4c941dbe4.js | 1 - ui/litellm-dashboard/out/index.html | 2 +- ui/litellm-dashboard/out/index.txt | 4 ++-- ui/litellm-dashboard/src/components/user_dashboard.tsx | 1 - 15 files changed, 10 insertions(+), 11 deletions(-) rename litellm/proxy/_experimental/out/_next/static/{IXxGmLpL0ryrAsqCmdljD => 1uJOwOGpazhj7AOlXoDnP}/_buildManifest.js (100%) rename litellm/proxy/_experimental/out/_next/static/{IXxGmLpL0ryrAsqCmdljD => 1uJOwOGpazhj7AOlXoDnP}/_ssgManifest.js (100%) create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/app/page-07e952a07a29317d.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/app/page-a94f48a4c941dbe4.js rename ui/litellm-dashboard/out/_next/static/{IXxGmLpL0ryrAsqCmdljD => 1uJOwOGpazhj7AOlXoDnP}/_buildManifest.js (100%) rename ui/litellm-dashboard/out/_next/static/{IXxGmLpL0ryrAsqCmdljD => 1uJOwOGpazhj7AOlXoDnP}/_ssgManifest.js (100%) create mode 100644 ui/litellm-dashboard/out/_next/static/chunks/app/page-07e952a07a29317d.js delete mode 100644 ui/litellm-dashboard/out/_next/static/chunks/app/page-a94f48a4c941dbe4.js diff --git a/litellm/proxy/_experimental/out/404.html b/litellm/proxy/_experimental/out/404.html index 3e5ac000f..b2750f037 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

404

This page could not be found.

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

404

This page could not be found.

\ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/IXxGmLpL0ryrAsqCmdljD/_buildManifest.js b/litellm/proxy/_experimental/out/_next/static/1uJOwOGpazhj7AOlXoDnP/_buildManifest.js similarity index 100% rename from litellm/proxy/_experimental/out/_next/static/IXxGmLpL0ryrAsqCmdljD/_buildManifest.js rename to litellm/proxy/_experimental/out/_next/static/1uJOwOGpazhj7AOlXoDnP/_buildManifest.js diff --git a/litellm/proxy/_experimental/out/_next/static/IXxGmLpL0ryrAsqCmdljD/_ssgManifest.js b/litellm/proxy/_experimental/out/_next/static/1uJOwOGpazhj7AOlXoDnP/_ssgManifest.js similarity index 100% rename from litellm/proxy/_experimental/out/_next/static/IXxGmLpL0ryrAsqCmdljD/_ssgManifest.js rename to litellm/proxy/_experimental/out/_next/static/1uJOwOGpazhj7AOlXoDnP/_ssgManifest.js diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/app/page-07e952a07a29317d.js b/litellm/proxy/_experimental/out/_next/static/chunks/app/page-07e952a07a29317d.js new file mode 100644 index 000000000..3baff4770 --- /dev/null +++ b/litellm/proxy/_experimental/out/_next/static/chunks/app/page-07e952a07a29317d.js @@ -0,0 +1 @@ +(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[931],{20661:function(e,t,s){Promise.resolve().then(s.bind(s,92182))},92182:function(e,t,s){"use strict";s.r(t),s.d(t,{default:function(){return eM}});var l=s(3827),r=s(64090),a=s(47907),n=s(8792),o=s(2179),i=e=>{let{userID:t,userRole:s,userEmail:r,showSSOBanner:a}=e;return console.log("User ID:",t),console.log("userEmail:",r),(0,l.jsxs)("nav",{className:"left-0 right-0 top-0 flex justify-between items-center h-12 mb-4",children:[(0,l.jsx)("div",{className:"text-left my-2 absolute top-0 left-0",children:(0,l.jsx)("div",{className:"flex flex-col items-center",children:(0,l.jsx)(n.default,{href:"/",children:(0,l.jsx)("button",{className:"text-gray-800 text-2xl py-1 rounded text-center",children:(0,l.jsx)("img",{src:"/get_image",width:200,height:200,alt:"LiteLLM Brand",className:"mr-2"})})})})}),(0,l.jsxs)("div",{className:"text-right mx-4 my-2 absolute top-0 right-0 flex items-center justify-end space-x-2",children:[a?(0,l.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/ui#setup-ssoauth-for-ui",target:"_blank",className:"mr-2"}):null,(0,l.jsxs)(o.Z,{variant:"secondary",size:"lg",children:[r,(0,l.jsxs)("p",{children:["Role: ",s]}),(0,l.jsxs)("p",{children:["ID: ",t]})]})]})]})},c=s(80588);let d=async(e,t,s)=>{try{if(console.log("Form Values in keyCreateCall:",s),s.description&&(s.metadata||(s.metadata={}),s.metadata.description=s.description,delete s.description,s.metadata=JSON.stringify(s.metadata)),s.metadata){console.log("formValues.metadata:",s.metadata);try{s.metadata=JSON.parse(s.metadata)}catch(e){throw c.ZP.error("Failed to parse metadata: "+e),Error("Failed to parse metadata: "+e)}}console.log("Form Values after check:",s);let l=await fetch("/key/generate",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({user_id:t,...s})});if(!l.ok){let e=await l.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let r=await l.json();return console.log("API Response:",r),r}catch(e){throw console.error("Failed to create key:",e),e}},h=async(e,t,s)=>{try{if(console.log("Form Values in keyCreateCall:",s),s.description&&(s.metadata||(s.metadata={}),s.metadata.description=s.description,delete s.description,s.metadata=JSON.stringify(s.metadata)),s.metadata){console.log("formValues.metadata:",s.metadata);try{s.metadata=JSON.parse(s.metadata)}catch(e){throw c.ZP.error("Failed to parse metadata: "+e),Error("Failed to parse metadata: "+e)}}console.log("Form Values after check:",s);let l=await fetch("/user/new",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({user_id:t,...s})});if(!l.ok){let e=await l.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let r=await l.json();return console.log("API Response:",r),r}catch(e){throw console.error("Failed to create key:",e),e}},m=async(e,t)=>{try{console.log("in keyDeleteCall:",t);let s=await fetch("/key/delete",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({keys:[t]})});if(!s.ok){let e=await s.text();throw c.ZP.error("Failed to delete key: "+e),Error("Network response was not ok")}let l=await s.json();return console.log(l),l}catch(e){throw console.error("Failed to create key:",e),e}},u=async function(e,t,s){let l=arguments.length>3&&void 0!==arguments[3]&&arguments[3];try{let r="/user/info";"App Owner"==s&&t&&(r="".concat(r,"?user_id=").concat(t)),console.log("in userInfoCall viewAll=",l),l&&(r="".concat(r,"?view_all=true"));let a=await fetch(r,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!a.ok){let e=await a.text();throw c.ZP.error(e),Error("Network response was not ok")}let n=await a.json();return console.log("API Response:",n),n}catch(e){throw console.error("Failed to create key:",e),e}},x=async e=>{try{let t=await fetch("/global/spend",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},p=async(e,t,s)=>{try{let t=await fetch("/v2/model/info",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},j=async(e,t,s)=>{try{let t=await fetch("/model/metrics",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},y=async(e,t,s)=>{try{let t=await fetch("/models",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},g=async(e,t)=>{try{let s="/global/spend/logs";console.log("in keySpendLogsCall:",s);let l=await fetch("".concat(s,"?api_key=").concat(t),{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw c.ZP.error(e),Error("Network response was not ok")}let r=await l.json();return console.log(r),r}catch(e){throw console.error("Failed to create key:",e),e}},w=async e=>{try{let t="/global/spend/teams";console.log("in teamSpendLogsCall:",t);let s=await fetch("".concat(t),{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!s.ok){let e=await s.text();throw c.ZP.error(e),Error("Network response was not ok")}let l=await s.json();return console.log(l),l}catch(e){throw console.error("Failed to create key:",e),e}},Z=async(e,t,s,l,r,a)=>{try{console.log("user role in spend logs call: ".concat(s));let t="/spend/logs";t="App Owner"==s?"".concat(t,"?user_id=").concat(l,"&start_date=").concat(r,"&end_date=").concat(a):"".concat(t,"?start_date=").concat(r,"&end_date=").concat(a);let n=await fetch(t,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!n.ok){let e=await n.text();throw c.ZP.error(e),Error("Network response was not ok")}let o=await n.json();return console.log(o),o}catch(e){throw console.error("Failed to create key:",e),e}},f=async e=>{try{let t=await fetch("/global/spend/logs",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to create key:",e),e}},k=async e=>{try{let t=await fetch("/global/spend/keys?limit=5",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to create key:",e),e}},_=async(e,t)=>{try{t&&JSON.stringify({api_key:t});let s={method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}};t&&(s.body=JSON.stringify({api_key:t}));let l=await fetch("/global/spend/end_users",s);if(!l.ok){let e=await l.text();throw c.ZP.error(e),Error("Network response was not ok")}let r=await l.json();return console.log(r),r}catch(e){throw console.error("Failed to create key:",e),e}},b=async e=>{try{let t=await fetch("/global/spend/models?limit=5",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to create key:",e),e}},v=async(e,t)=>{try{let s=await fetch("/v2/key/info",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({keys:t})});if(!s.ok){let e=await s.text();throw c.ZP.error(e),Error("Network response was not ok")}let l=await s.json();return console.log(l),l}catch(e){throw console.error("Failed to create key:",e),e}},S=async(e,t,s,l)=>{try{let r=await fetch("/user/request_model",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({models:[t],user_id:s,justification:l})});if(!r.ok){let e=await r.text();throw c.ZP.error("Failed to delete key: "+e),Error("Network response was not ok")}let a=await r.json();return console.log(a),a}catch(e){throw console.error("Failed to create key:",e),e}},N=async e=>{try{let t="/user/get_requests";console.log("in userGetRequesedtModelsCall:",t);let s=await fetch(t,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!s.ok){let e=await s.text();throw c.ZP.error("Failed to delete key: "+e),Error("Network response was not ok")}let l=await s.json();return console.log(l),l}catch(e){throw console.error("Failed to get requested models:",e),e}},A=async(e,t)=>{try{let s="/user/get_users?role=".concat(t);console.log("in userGetAllUsersCall:",s);let l=await fetch(s,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw c.ZP.error("Failed to delete key: "+e),Error("Network response was not ok")}let r=await l.json();return console.log(r),r}catch(e){throw console.error("Failed to get requested models:",e),e}},C=async(e,t)=>{try{console.log("Form Values in teamCreateCall:",t);let s=await fetch("/team/new",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...t})});if(!s.ok){let e=await s.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let l=await s.json();return console.log("API Response:",l),l}catch(e){throw console.error("Failed to create key:",e),e}},T=async(e,t,s)=>{try{console.log("Form Values in teamMemberAddCall:",s);let l=await fetch("/team/member_add",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({team_id:t,member:s})});if(!l.ok){let e=await l.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let r=await l.json();return console.log("API Response:",r),r}catch(e){throw console.error("Failed to create key:",e),e}},I=async(e,t)=>{try{console.log("Form Values in userUpdateUserCall:",t);let s=await fetch("/user/update",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({user_role:"proxy_admin_viewer",...t})});if(!s.ok){let e=await s.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let l=await s.json();return console.log("API Response:",l),l}catch(e){throw console.error("Failed to create key:",e),e}},E=async(e,t)=>{try{let s=await fetch("/global/predict/spend/logs",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({data:t})});if(!s.ok){let e=await s.text();throw c.ZP.error(e),Error("Network response was not ok")}let l=await s.json();return console.log(l),l}catch(e){throw console.error("Failed to create key:",e),e}},P=async e=>{try{console.log("Checking Slack Budget Alerts service health");let t=await fetch("/health/services?service=slack_budget_alerts",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error("Failed Slack Alert test: "+e),Error(e)}let s=await t.json();return c.ZP.success("Test Slack Alert worked - check your Slack!"),console.log("Service Health Response:",s),s}catch(e){throw console.error("Failed to perform health check:",e),e}};var F=s(10384),O=s(46453),M=s(13810),R=s(71801),D=s(42440),U=s(17189),L=s(12143),B=s(77171),z=s(42539),K=s(88707),W=s(1861);let{Option:V}=U.default;var q=e=>{let{userID:t,team:s,userRole:a,accessToken:n,data:i,setData:h}=e,[m]=L.Z.useForm(),[u,x]=(0,r.useState)(!1),[p,j]=(0,r.useState)(null),[g,w]=(0,r.useState)(null),[Z,f]=(0,r.useState)([]),k=()=>{x(!1),m.resetFields()},_=()=>{x(!1),j(null),m.resetFields()};(0,r.useEffect)(()=>{(async()=>{try{if(null===t||null===a)return;if(null!==n){let e=(await y(n,t,a)).data.map(e=>e.id);console.log("available_model_names:",e),f(e)}}catch(e){console.error("Error fetching user models:",e)}})()},[n,t,a]);let b=async e=>{try{c.ZP.info("Making API Call"),x(!0);let s=await d(n,t,e);console.log("key create Response:",s),h(e=>e?[...e,s]:[s]),j(s.key),w(s.soft_budget),c.ZP.success("API Key Created"),m.resetFields(),localStorage.removeItem("userData"+t)}catch(e){console.error("Error creating the key:",e)}},v=async()=>{try{console.log("Sending Slack alert...");let e=await P(n);console.log("slackBudgetAlertsHealthCheck Response:",e),console.log("Testing Slack alert successful")}catch(e){console.error("Error sending Slack alert:",e)}};return(0,l.jsxs)("div",{children:[(0,l.jsx)(o.Z,{className:"mx-auto",onClick:()=>x(!0),children:"+ Create New Key"}),(0,l.jsx)(B.Z,{title:"Create Key",visible:u,width:800,footer:null,onOk:k,onCancel:_,children:(0,l.jsxs)(L.Z,{form:m,onFinish:b,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:["App Owner"===a||"Admin"===a?(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(L.Z.Item,{label:"Key Name",name:"key_alias",children:(0,l.jsx)(z.Z,{})}),(0,l.jsx)(L.Z.Item,{label:"Team ID",name:"team_id",children:(0,l.jsx)(z.Z,{placeholder:"ai_team",defaultValue:s&&s.team_alias?s.team_alias:"",disabled:!0})}),(0,l.jsx)(L.Z.Item,{label:"Models",name:"models",children:(0,l.jsx)(U.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:Z.map(e=>(0,l.jsx)(V,{value:e,children:e},e))})}),(0,l.jsx)(L.Z.Item,{label:"Soft Budget (USD) Monthly",name:"soft_budget",initialValue:50,children:(0,l.jsx)(K.Z,{step:.01,precision:2,defaultValue:50,width:200})}),(0,l.jsx)(L.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,l.jsx)(K.Z,{step:.01,precision:2,width:200})}),(0,l.jsx)(L.Z.Item,{label:"Reset Budget",name:"budget_duration",children:(0,l.jsxs)(U.default,{defaultValue:null,placeholder:"n/a",children:[(0,l.jsx)(U.default.Option,{value:"24h",children:"daily"}),(0,l.jsx)(U.default.Option,{value:"30d",children:"monthly"})]})}),(0,l.jsx)(L.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})}),(0,l.jsx)(L.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})}),(0,l.jsx)(L.Z.Item,{label:"Expire Key (eg: 30s, 30h, 30d)",name:"duration",children:(0,l.jsx)(z.Z,{})}),(0,l.jsx)(L.Z.Item,{label:"Metadata",name:"metadata",children:(0,l.jsx)(z.Z.TextArea,{rows:4,placeholder:"Enter metadata as JSON"})})]}):(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(L.Z.Item,{label:"Key Name",name:"key_alias",children:(0,l.jsx)(z.Z,{})}),(0,l.jsx)(L.Z.Item,{label:"Team ID (Contact Group)",name:"team_id",children:(0,l.jsx)(z.Z,{placeholder:"ai_team"})}),(0,l.jsx)(L.Z.Item,{label:"Description",name:"description",children:(0,l.jsx)(z.Z.TextArea,{placeholder:"Enter description",rows:4})})]}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(W.ZP,{htmlType:"submit",children:"Create Key"})})]})}),p&&(0,l.jsx)(B.Z,{visible:u,onOk:k,onCancel:_,footer:null,children:(0,l.jsx)(O.Z,{numItems:1,className:"gap-2 w-full",children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Save your Key"}),(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsxs)("p",{children:["Please save this secret key somewhere safe and accessible. For security reasons, ",(0,l.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,l.jsx)(F.Z,{numColSpan:1,children:null!=p?(0,l.jsxs)("div",{children:[(0,l.jsxs)(R.Z,{children:["API Key: ",p]}),(0,l.jsx)(D.Z,{className:"mt-6",children:"Budgets"}),(0,l.jsxs)(R.Z,{children:["Soft Limit Budget: $",g]}),(0,l.jsx)(o.Z,{className:"mt-3",onClick:v,children:"Test Slack Alert"}),(0,l.jsxs)(R.Z,{className:"mt-2",children:["(LiteLLM Docs -",(0,l.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/alerting",target:"_blank",className:"text-blue-500",children:"Set Up Slack Alerting)"})]})]}):(0,l.jsx)(R.Z,{children:"Key being created, this might take 30s"})})]})})})]})},J=s(33393),G=s(61244),$=s(10827),H=s(3851),Y=s(2044),X=s(64167),Q=s(74480),ee=s(7178),et=s(9853),es=s(56863),el=e=>{let{token:t,accessToken:s,keySpend:a,keyBudget:n,keyName:i}=e,[c,d]=(0,r.useState)(!1),[h,m]=(0,r.useState)(null),[u,x]=(0,r.useState)(""),[p,j]=(0,r.useState)(null),y=async()=>{try{if(null==s||null==t)return;console.log("accessToken: ".concat(s,"; token: ").concat(t));let e=await g(s,t);console.log("Response:",e),m(e);let l=await E(s,e);console.log("Response2:",l);let r=[...e,...l.response];m(r),x(l.predicted_spend),console.log("Combined Data:",r)}catch(e){console.error("There was an error fetching the data",e)}};return t?(0,l.jsxs)("div",{children:[(0,l.jsx)(o.Z,{size:"xs",onClick:()=>{console.log("Show Modal triggered"),d(!0),y()},variant:"secondary",children:"Spend Report"}),(0,l.jsxs)(B.Z,{visible:c,width:1400,onOk:()=>{d(!1)},onCancel:()=>{d(!1)},footer:null,children:[(0,l.jsxs)(D.Z,{style:{textAlign:"left"},children:["Key Name: ",i]}),(0,l.jsxs)(es.Z,{children:["Monthly Spend $",a]}),(0,l.jsx)(D.Z,{children:u}),(0,l.jsx)(M.Z,{className:"mt-6 mb-6",children:h&&(0,l.jsx)(et.Z,{className:"mt-6",data:h,colors:["blue","amber"],index:"date",categories:["spend","predicted_spend"],yAxisWidth:80})})]})]}):null},er=e=>{let{userID:t,accessToken:s,data:a,setData:n}=e,[i,c]=(0,r.useState)(!1),[d,h]=(0,r.useState)(!1),[u,x]=(0,r.useState)(null),p=async e=>{null!=a&&(x(e),localStorage.removeItem("userData"+t),h(!0))},j=async()=>{if(null!=u&&null!=a){try{await m(s,u);let e=a.filter(e=>e.token!==u);n(e)}catch(e){console.error("Error deleting the key:",e)}h(!1),x(null)}};if(null!=a)return console.log("RERENDER TRIGGERED"),(0,l.jsxs)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh] mb-4",children:[(0,l.jsxs)($.Z,{className:"mt-5",children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"Key Alias"}),(0,l.jsx)(Q.Z,{children:"Secret Key"}),(0,l.jsx)(Q.Z,{children:"Spend (USD)"}),(0,l.jsx)(Q.Z,{children:"Key Budget (USD)"}),(0,l.jsx)(Q.Z,{children:"Spend Report"}),(0,l.jsx)(Q.Z,{children:"Team ID"}),(0,l.jsx)(Q.Z,{children:"Metadata"}),(0,l.jsx)(Q.Z,{children:"Models"}),(0,l.jsx)(Q.Z,{children:"TPM / RPM Limits"}),(0,l.jsx)(Q.Z,{children:"Expires"})]})}),(0,l.jsx)(H.Z,{children:a.map(e=>(console.log(e),"litellm-dashboard"===e.team_id)?null:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",whiteSpace:"pre-wrap",overflow:"hidden"},children:null!=e.key_alias?(0,l.jsx)(R.Z,{children:e.key_alias}):(0,l.jsx)(R.Z,{children:"Not Set"})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:e.key_name})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:(()=>{try{return parseFloat(e.spend).toFixed(4)}catch(t){return e.spend}})()})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",whiteSpace:"pre-wrap",overflow:"hidden"},children:null!=e.max_budget?(0,l.jsx)(R.Z,{children:e.max_budget}):(0,l.jsx)(R.Z,{children:"Unlimited Budget"})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px"},children:(0,l.jsx)(el,{token:e.token,accessToken:s,keySpend:e.spend,keyBudget:e.max_budget,keyName:e.key_name})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:e.team_id})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:JSON.stringify(e.metadata).slice(0,400)})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:JSON.stringify(e.models)})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",overflowWrap:"break-word"},children:(0,l.jsxs)(R.Z,{children:["TPM Limit: ",e.tpm_limit?e.tpm_limit:"Unlimited"," ",(0,l.jsx)("br",{})," RPM Limit:"," ",e.rpm_limit?e.rpm_limit:"Unlimited"]})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",wordWrap:"break-word"},children:null!=e.expires?(0,l.jsx)(R.Z,{children:e.expires}):(0,l.jsx)(R.Z,{children:"Never"})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",wordWrap:"break-word"},children:(0,l.jsx)(G.Z,{onClick:()=>p(e.token),icon:J.Z,size:"sm"})})]},e.token))})]}),d&&(0,l.jsx)("div",{className:"fixed z-10 inset-0 overflow-y-auto",children:(0,l.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,l.jsx)("div",{className:"fixed inset-0 transition-opacity","aria-hidden":"true",children:(0,l.jsx)("div",{className:"absolute inset-0 bg-gray-500 opacity-75"})}),(0,l.jsx)("span",{className:"hidden sm:inline-block sm:align-middle sm:h-screen","aria-hidden":"true",children:"​"}),(0,l.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,l.jsx)("div",{className:"bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4",children:(0,l.jsx)("div",{className:"sm:flex sm:items-start",children:(0,l.jsxs)("div",{className:"mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left",children:[(0,l.jsx)("h3",{className:"text-lg leading-6 font-medium text-gray-900",children:"Delete Key"}),(0,l.jsx)("div",{className:"mt-2",children:(0,l.jsx)("p",{className:"text-sm text-gray-500",children:"Are you sure you want to delete this key ?"})})]})})}),(0,l.jsxs)("div",{className:"bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse",children:[(0,l.jsx)(o.Z,{onClick:j,color:"red",className:"ml-2",children:"Delete"}),(0,l.jsx)(o.Z,{onClick:()=>{h(!1),x(null)},children:"Cancel"})]})]})]})})]})},ea=e=>{let{userID:t,userSpendData:s,userRole:a,accessToken:n}=e,[o,i]=(0,r.useState)(null==s?void 0:s.spend),[c,d]=(0,r.useState)((null==s?void 0:s.max_budget)||null);(0,r.useEffect)(()=>{(async()=>{if("Admin"===a)try{let e=await x(n);i(e.spend),d(e.max_budget||null)}catch(e){console.error("Error fetching global spend data:",e)}})()},[a,n]);let h=void 0!==o?o.toFixed(4):null;return(0,l.jsx)(l.Fragment,{children:(0,l.jsxs)(M.Z,{className:"mx-auto mb-4",children:[(0,l.jsxs)(es.Z,{children:["$",h]}),(0,l.jsxs)(D.Z,{children:["/ ",null!==c?"$".concat(c," limit"):"No limit"]})]})})},en=s(36083),eo=s(68967),ei=s(27166),ec=e=>{let{teams:t,setSelectedTeam:s}=e,{Title:a,Paragraph:n}=en.default,[o,i]=(0,r.useState)("");return(0,l.jsxs)("div",{className:"mt-10",children:[(0,l.jsx)(a,{level:4,children:"Default Team"}),(0,l.jsx)(n,{children:"If you belong to multiple teams, this setting controls which team is used by default when creating new API Keys."}),t&&t.length>0?(0,l.jsx)(eo.Z,{defaultValue:"0",children:t.map((e,t)=>(0,l.jsx)(ei.Z,{value:String(t),onClick:()=>s(e),children:e.team_alias},t))}):(0,l.jsxs)(n,{children:["No team created. ",(0,l.jsx)("b",{children:"Defaulting to personal account."})]})]})},ed=s(37963);console.log("isLocal:",!1);var eh=e=>{let{userID:t,userRole:s,teams:n,keys:o,setUserRole:i,userEmail:c,setUserEmail:d,setTeams:h,setKeys:m}=e,[p,j]=(0,r.useState)(null),g=(0,a.useSearchParams)();g.get("viewSpend"),(0,a.useRouter)();let w=g.get("token"),[Z,f]=(0,r.useState)(null),[k,_]=(0,r.useState)([]),[b,v]=(0,r.useState)(n?n[0]:null);if(window.addEventListener("beforeunload",function(){sessionStorage.clear()}),(0,r.useEffect)(()=>{if(w){let e=(0,ed.o)(w);if(e){if(console.log("Decoded token:",e),console.log("Decoded key:",e.key),f(e.key),e.user_role){let t=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";default:return"Unknown Role"}}(e.user_role);console.log("Decoded user_role:",t),i(t)}else console.log("User role not defined");e.user_email?d(e.user_email):console.log("User Email is not set ".concat(e))}}if(t&&Z&&s&&!o&&!p){let e=sessionStorage.getItem("userModels"+t);e?_(JSON.parse(e)):(async()=>{try{let e=await u(Z,t,s);if(console.log("received teams in user dashboard: ".concat(Object.keys(e),"; team values: ").concat(Object.entries(e.teams))),"Admin"==s){let e=await x(Z);j(e),console.log("globalSpend:",e)}else j(e.user_info);m(e.keys),h(e.teams),v(e.teams?e.teams[0]:null),sessionStorage.setItem("userData"+t,JSON.stringify(e.keys)),sessionStorage.setItem("userSpendData"+t,JSON.stringify(e.user_info));let l=(await y(Z,t,s)).data.map(e=>e.id);console.log("available_model_names:",l),_(l),console.log("userModels:",k),sessionStorage.setItem("userModels"+t,JSON.stringify(l))}catch(e){console.error("There was an error fetching the data",e)}})()}},[t,w,Z,o,s]),null==t||null==w){let e="/sso/key/generate";return console.log("Full URL:",e),window.location.href=e,null}if(null==Z)return null;if(null==s&&i("App Owner"),s&&"Admin Viewer"==s){let{Title:e,Paragraph:t}=en.default;return(0,l.jsxs)("div",{children:[(0,l.jsx)(e,{level:1,children:"Access Denied"}),(0,l.jsx)(t,{children:"Ask your proxy admin for access to create keys"})]})}return console.log("inside user dashboard, selected team",b),(0,l.jsx)("div",{children:(0,l.jsx)(O.Z,{numItems:1,className:"gap-0 p-10 h-[75vh] w-full",children:(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(ea,{userID:t,userSpendData:p,userRole:s,accessToken:Z}),(0,l.jsx)(er,{userID:t,accessToken:Z,data:o,setData:m}),(0,l.jsx)(q,{userID:t,team:b||null,userRole:s,accessToken:Z,data:o,setData:m},b?b.team_id:null),(0,l.jsx)(ec,{teams:n,setSelectedTeam:v})]})})})},em=s(5);let{Option:eu}=U.default;var ex=e=>{let{userModels:t,accessToken:s,userID:a}=e,[n]=L.Z.useForm(),[i,d]=(0,r.useState)(!1),h=async e=>{try{c.ZP.info("Requesting access");let{selectedModel:t,accessReason:l}=e;await S(s,t,a,l),d(!0)}catch(e){console.error("Error requesting access:",e)}};return(0,l.jsxs)("div",{children:[(0,l.jsx)(o.Z,{size:"xs",onClick:()=>d(!0),children:"Request Access"}),(0,l.jsx)(B.Z,{title:"Request Access",visible:i,width:800,footer:null,onOk:()=>{d(!1),n.resetFields()},onCancel:()=>{d(!1),n.resetFields()},children:(0,l.jsxs)(L.Z,{form:n,onFinish:h,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsx)(L.Z.Item,{label:"Select Model",name:"selectedModel",children:(0,l.jsx)(U.default,{placeholder:"Select model",style:{width:"100%"},children:t.map(e=>(0,l.jsx)(eu,{value:e,children:e},e))})}),(0,l.jsx)(L.Z.Item,{label:"Reason for Access",name:"accessReason",children:(0,l.jsx)(z.Z.TextArea,{rows:4,placeholder:"Enter reason for access"})}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(o.Z,{children:"Request Access"})})]})})]})},ep=e=>{let{accessToken:t,token:s,userRole:a,userID:n}=e,[o,i]=(0,r.useState)({data:[]}),[c,d]=(0,r.useState)([]),[h,m]=(0,r.useState)([]);if((0,r.useEffect)(()=>{if(!t||!s||!a||!n)return;let e=async()=>{try{let e=await p(t,n,a);console.log("Model data response:",e.data),i(e);let s=await j(t,n,a);if(console.log("Model metrics response:",s),d(s),"Admin"===a&&t){let e=await N(t);console.log("Pending Requests:",h),m(e.requests||[])}}catch(e){console.error("There was an error fetching the model data",e)}};t&&s&&a&&n&&e()},[t,s,a,n]),!o||!t||!s||!a||!n)return(0,l.jsx)("div",{children:"Loading..."});let u=[];for(let e=0;e(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{children:(0,l.jsx)(D.Z,{children:e.model_name})}),(0,l.jsx)(Y.Z,{children:e.provider}),"Admin"===a&&(0,l.jsx)(Y.Z,{children:e.api_base}),(0,l.jsx)(Y.Z,{children:e.user_access?(0,l.jsx)(em.Z,{color:"green",children:"Yes"}):(0,l.jsx)(ex,{userModels:u,accessToken:t,userID:n})}),(0,l.jsx)(Y.Z,{children:e.input_cost}),(0,l.jsx)(Y.Z,{children:e.output_cost}),(0,l.jsx)(Y.Z,{children:e.max_tokens})]},e.model_name))})]})}),(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Model Statistics (Number Requests)"}),(0,l.jsx)(et.Z,{data:c,index:"model",categories:["num_requests"],colors:["blue"],yAxisWidth:400,layout:"vertical",tickGap:5})]}),(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Model Statistics (Latency)"}),(0,l.jsx)(et.Z,{data:c,index:"model",categories:["avg_latency_seconds"],colors:["red"],yAxisWidth:400,layout:"vertical",tickGap:5})]})]})})},ej=s(92836),ey=s(26734),eg=s(41608),ew=s(32126),eZ=s(23682);let{Option:ef}=U.default;var ek=e=>{let{userID:t,accessToken:s}=e,[a]=L.Z.useForm(),[n,i]=(0,r.useState)(!1),[d,m]=(0,r.useState)(null),[u,x]=(0,r.useState)([]);(0,r.useEffect)(()=>{(async()=>{try{let e=await y(s,t,"any"),l=[];for(let t=0;t{i(!1),a.resetFields()},j=()=>{i(!1),m(null),a.resetFields()},g=async e=>{try{c.ZP.info("Making API Call"),i(!0),console.log("formValues in create user:",e);let l=await h(s,t,e);console.log("user create Response:",l),m(l.key),c.ZP.success("API user Created"),a.resetFields(),localStorage.removeItem("userData"+t)}catch(e){console.error("Error creating the user:",e)}};return(0,l.jsxs)("div",{children:[(0,l.jsx)(o.Z,{className:"mx-auto",onClick:()=>i(!0),children:"+ Create New User"}),(0,l.jsx)(B.Z,{title:"Create User",visible:n,width:800,footer:null,onOk:p,onCancel:j,children:(0,l.jsxs)(L.Z,{form:a,onFinish:g,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsx)(L.Z.Item,{label:"User ID",name:"user_id",children:(0,l.jsx)(z.Z,{placeholder:"Enter User ID"})}),(0,l.jsx)(L.Z.Item,{label:"Team ID",name:"team_id",children:(0,l.jsx)(z.Z,{placeholder:"ai_team"})}),(0,l.jsx)(L.Z.Item,{label:"Models",name:"models",children:(0,l.jsx)(U.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:u.map(e=>(0,l.jsx)(ef,{value:e,children:e},e))})}),(0,l.jsx)(L.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,l.jsx)(K.Z,{step:.01,precision:2,width:200})}),(0,l.jsx)(L.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})}),(0,l.jsx)(L.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})}),(0,l.jsx)(L.Z.Item,{label:"Duration (eg: 30s, 30h, 30d)",name:"duration",children:(0,l.jsx)(z.Z,{})}),(0,l.jsx)(L.Z.Item,{label:"Metadata",name:"metadata",children:(0,l.jsx)(z.Z.TextArea,{rows:4,placeholder:"Enter metadata as JSON"})}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(W.ZP,{htmlType:"submit",children:"Create User"})})]})}),d&&(0,l.jsxs)(B.Z,{title:"Save Your User",visible:n,onOk:p,onCancel:j,footer:null,children:[(0,l.jsxs)("p",{children:["Please save this secret user somewhere safe and accessible. For security reasons, ",(0,l.jsx)("b",{children:"you will not be able to view it again"})," ","through your LiteLLM account. If you lose this secret user, you will need to generate a new one."]}),(0,l.jsx)("p",{children:null!=d?"API user: ".concat(d):"User being created, this might take 30s"})]})]})},e_=e=>{let{accessToken:t,token:s,keys:a,userRole:n,userID:o,setKeys:i}=e,[c,d]=(0,r.useState)(null),[h,m]=(0,r.useState)(null),[x,p]=(0,r.useState)(1);if((0,r.useEffect)(()=>{if(!t||!s||!n||!o)return;let e=async()=>{try{let e=await u(t,null,n,!0);console.log("user data response:",e),d(e)}catch(e){console.error("There was an error fetching the model data",e)}};t&&s&&n&&o&&!c&&e();let l=async()=>{try{let e=await _(t,null);console.log("user data response:",e),m(e)}catch(e){console.error("There was an error fetching the model data",e)}};n&&("Admin"==n||"Admin Viewer"==n)&&!h&&l()},[t,s,n,o]),!c||!t||!s||!n||!o)return(0,l.jsx)("div",{children:"Loading..."});let j=async e=>{try{let s=await _(t,e);console.log("user data response:",s),m(s)}catch(e){console.error("There was an error fetching the model data",e)}};return(0,l.jsx)("div",{style:{width:"100%"},children:(0,l.jsxs)(O.Z,{className:"gap-2 p-10 h-[75vh] w-full",children:[(0,l.jsx)(ek,{userID:o,accessToken:t}),(0,l.jsx)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh] mb-4",children:(0,l.jsxs)(ey.Z,{children:[(0,l.jsxs)(eg.Z,{variant:"line",defaultValue:"1",children:[(0,l.jsx)(ej.Z,{value:"1",children:"Key Owners"}),(0,l.jsx)(ej.Z,{value:"2",children:"End-Users"})]}),(0,l.jsxs)(eZ.Z,{children:[(0,l.jsx)(ew.Z,{children:(0,l.jsxs)($.Z,{className:"mt-5",children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"User ID"}),(0,l.jsx)(Q.Z,{children:"User Role"}),(0,l.jsx)(Q.Z,{children:"User Models"}),(0,l.jsx)(Q.Z,{children:"User Spend ($ USD)"}),(0,l.jsx)(Q.Z,{children:"User Max Budget ($ USD)"})]})}),(0,l.jsx)(H.Z,{children:c.map(e=>(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{children:e.user_id}),(0,l.jsx)(Y.Z,{children:e.user_role?e.user_role:"app_owner"}),(0,l.jsx)(Y.Z,{children:e.models&&e.models.length>0?e.models:"All Models"}),(0,l.jsx)(Y.Z,{children:e.spend?e.spend:0}),(0,l.jsx)(Y.Z,{children:e.max_budget?e.max_budget:"Unlimited"})]},e.user_id))})]})}),(0,l.jsxs)(ew.Z,{children:[(0,l.jsxs)("div",{className:"flex items-center",children:[(0,l.jsx)("div",{className:"flex-1"}),(0,l.jsxs)("div",{className:"flex-1 flex justify-between items-center",children:[(0,l.jsx)(R.Z,{className:"w-1/4 mr-2 text-right",children:"Key"}),(0,l.jsx)(eo.Z,{defaultValue:"1",className:"w-3/4",children:null==a?void 0:a.map((e,t)=>{if(e&&null!==e.key_name&&e.key_name.length>0)return(0,l.jsx)(ei.Z,{value:String(t),onClick:()=>j(e.token),children:e.key_name},t)})})]})]}),(0,l.jsxs)($.Z,{children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"End User"}),(0,l.jsx)(Q.Z,{children:"Spend"}),(0,l.jsx)(Q.Z,{children:"Total Events"})]})}),(0,l.jsx)(H.Z,{children:null==h?void 0:h.map((e,t)=>(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{children:e.end_user}),(0,l.jsx)(Y.Z,{children:e.total_spend}),(0,l.jsx)(Y.Z,{children:e.total_events})]},t))})]})]})]})]})}),function(){if(!c)return null;let e=Math.ceil(c.length/25),t=Math.min(25*x,c.length);return(0,l.jsxs)("div",{className:"flex justify-between items-center",children:[(0,l.jsxs)("div",{children:["Showing ",(x-1)*25+1," – ",t," of ",c.length]}),(0,l.jsxs)("div",{className:"flex",children:[(0,l.jsx)("button",{className:"bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-l focus:outline-none",disabled:1===x,onClick:()=>p(x-1),children:"← Prev"}),(0,l.jsx)("button",{className:"bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-r focus:outline-none",disabled:x===e,onClick:()=>p(x+1),children:"Next →"})]})]})}()]})})},eb=e=>{let{teams:t,searchParams:s,accessToken:a,setTeams:n,userID:i,userRole:d}=e,[h]=L.Z.useForm(),[m]=L.Z.useForm(),{Title:u,Paragraph:x}=en.default,[p,j]=(0,r.useState)(""),[g,w]=(0,r.useState)(t?t[0]:null),[Z,f]=(0,r.useState)(!1),[k,_]=(0,r.useState)(!1),[b,v]=(0,r.useState)([]);(0,r.useEffect)(()=>{(async()=>{try{if(null===i||null===d)return;if(null!==a){let e=(await y(a,i,d)).data.map(e=>e.id);console.log("available_model_names:",e),v(e)}}catch(e){console.error("Error fetching user models:",e)}})()},[a,i,d]);let S=async e=>{try{if(null!=a){c.ZP.info("Creating Team");let s=await C(a,e);null!==t?n([...t,s]):n([s]),console.log("response for team create call: ".concat(s)),c.ZP.success("Team created"),f(!1)}}catch(e){console.error("Error creating the key:",e),c.ZP.error("Error creating the team: "+e)}},N=async e=>{try{if(null!=a&&null!=t){c.ZP.info("Adding Member");let s={role:"user",user_email:e.user_email,user_id:e.user_id},l=await T(a,g.team_id,s);console.log("response for team create call: ".concat(l.data));let r=t.findIndex(e=>(console.log("team.team_id=".concat(e.team_id,"; response.data.team_id=").concat(l.data.team_id)),e.team_id===l.data.team_id));if(console.log("foundIndex: ".concat(r)),-1!==r){let e=[...t];e[r]=l.data,n(e),w(l.data)}_(!1)}}catch(e){console.error("Error creating the key:",e)}};return console.log("received teams ".concat(t)),(0,l.jsx)("div",{className:"w-full mx-4",children:(0,l.jsxs)(O.Z,{numItems:1,className:"gap-2 p-2 h-[75vh] w-full",children:[(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(u,{level:4,children:"All Teams"}),(0,l.jsx)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,l.jsxs)($.Z,{children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"Team Name"}),(0,l.jsx)(Q.Z,{children:"Spend (USD)"}),(0,l.jsx)(Q.Z,{children:"Budget (USD)"}),(0,l.jsx)(Q.Z,{children:"Models"}),(0,l.jsx)(Q.Z,{children:"TPM / RPM Limits"})]})}),(0,l.jsx)(H.Z,{children:t&&t.length>0?t.map(e=>(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:e.team_alias}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:e.spend}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:e.max_budget?e.max_budget:"No limit"}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:JSON.stringify(e.models?e.models:[])})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsxs)(R.Z,{children:["TPM Limit:"," ",e.tpm_limit?e.tpm_limit:"Unlimited"," ",(0,l.jsx)("br",{}),"RPM Limit:"," ",e.rpm_limit?e.rpm_limit:"Unlimited"]})})]},e.team_id)):null})]})})]}),(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(o.Z,{className:"mx-auto",onClick:()=>f(!0),children:"+ Create New Team"}),(0,l.jsx)(B.Z,{title:"Create Team",visible:Z,width:800,footer:null,onOk:()=>{f(!1),h.resetFields()},onCancel:()=>{f(!1),h.resetFields()},children:(0,l.jsxs)(L.Z,{form:h,onFinish:S,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(L.Z.Item,{label:"Team Name",name:"team_alias",children:(0,l.jsx)(z.Z,{})}),(0,l.jsx)(L.Z.Item,{label:"Models",name:"models",children:(0,l.jsx)(U.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:b.map(e=>(0,l.jsx)(U.default.Option,{value:e,children:e},e))})}),(0,l.jsx)(L.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,l.jsx)(K.Z,{step:.01,precision:2,width:200})}),(0,l.jsx)(L.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})}),(0,l.jsx)(L.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})})]}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(W.ZP,{htmlType:"submit",children:"Create Team"})})]})})]}),(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(u,{level:4,children:"Team Members"}),(0,l.jsx)(x,{children:"If you belong to multiple teams, this setting controls which teams members you see."}),t&&t.length>0?(0,l.jsx)(eo.Z,{defaultValue:"0",children:t.map((e,t)=>(0,l.jsx)(ei.Z,{value:String(t),onClick:()=>{w(e)},children:e.team_alias},t))}):(0,l.jsxs)(x,{children:["No team created. ",(0,l.jsx)("b",{children:"Defaulting to personal account."})]})]}),(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsx)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,l.jsxs)($.Z,{children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"Member Name"}),(0,l.jsx)(Q.Z,{children:"Role"})]})}),(0,l.jsx)(H.Z,{children:g?g.members_with_roles.map((e,t)=>(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{children:e.user_email?e.user_email:e.user_id?e.user_id:null}),(0,l.jsx)(Y.Z,{children:e.role})]},t)):null})]})})}),(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(o.Z,{className:"mx-auto mb-5",onClick:()=>_(!0),children:"+ Add member"}),(0,l.jsx)(B.Z,{title:"Add member",visible:k,width:800,footer:null,onOk:()=>{_(!1),m.resetFields()},onCancel:()=>{_(!1),m.resetFields()},children:(0,l.jsxs)(L.Z,{form:h,onFinish:N,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(L.Z.Item,{label:"Email",name:"user_email",className:"mb-4",children:(0,l.jsx)(z.Z,{name:"user_email",className:"px-3 py-2 border rounded-md w-full"})}),(0,l.jsx)("div",{className:"text-center mb-4",children:"OR"}),(0,l.jsx)(L.Z.Item,{label:"User ID",name:"user_id",className:"mb-4",children:(0,l.jsx)(z.Z,{name:"user_id",className:"px-3 py-2 border rounded-md w-full"})})]}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(W.ZP,{htmlType:"submit",children:"Add member"})})]})})]})]})})},ev=s(8510),eS=e=>{let{searchParams:t,accessToken:s}=e,[a]=L.Z.useForm(),[n]=L.Z.useForm(),{Title:i,Paragraph:d}=en.default,[h,m]=(0,r.useState)(""),[u,x]=(0,r.useState)(null),[p,j]=(0,r.useState)(!1);(0,r.useEffect)(()=>{(async()=>{if(null!=s){let e=[],t=await A(s,"proxy_admin_viewer");t.forEach(t=>{e.push({user_role:t.user_role,user_id:t.user_id,user_email:t.user_email})}),console.log("proxy viewers: ".concat(t));let l=await A(s,"proxy_admin");l.forEach(t=>{e.push({user_role:t.user_role,user_id:t.user_id,user_email:t.user_email})}),console.log("proxy admins: ".concat(l)),console.log("combinedList: ".concat(e)),x(e)}})()},[s]);let y=async e=>{try{if(null!=s&&null!=u){c.ZP.info("Making API Call"),e.user_email,e.user_id;let t=await I(s,e);console.log("response for team create call: ".concat(t));let l=u.findIndex(e=>(console.log("user.user_id=".concat(e.user_id,"; response.user_id=").concat(t.user_id)),e.user_id===t.user_id));console.log("foundIndex: ".concat(l)),-1==l&&(console.log("updates admin with new user"),u.push(t),x(u)),j(!1)}}catch(e){console.error("Error creating the key:",e)}};return console.log("admins: ".concat(null==u?void 0:u.length)),(0,l.jsxs)("div",{className:"w-full m-2",children:[(0,l.jsx)(i,{level:4,children:"Restricted Access"}),(0,l.jsxs)(d,{children:["Add other people to just view spend. They cannot create keys, teams or grant users access to new models."," ",(0,l.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/ui#restrict-ui-access",children:"Requires SSO Setup"})]}),(0,l.jsxs)(O.Z,{numItems:1,className:"gap-2 p-0 w-full",children:[(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsx)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,l.jsxs)($.Z,{children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"Member Name"}),(0,l.jsx)(Q.Z,{children:"Role"}),(0,l.jsx)(Q.Z,{children:"Action"})]})}),(0,l.jsx)(H.Z,{children:u?u.map((e,t)=>(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{children:e.user_email?e.user_email:e.user_id?e.user_id:null}),(0,l.jsx)(Y.Z,{children:e.user_role}),(0,l.jsx)(Y.Z,{children:(0,l.jsx)(G.Z,{icon:ev.Z,size:"sm"})})]},t)):null})]})})}),(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(o.Z,{className:"mx-auto mb-5",onClick:()=>j(!0),children:"+ Add viewer"}),(0,l.jsx)(B.Z,{title:"Add viewer",visible:p,width:800,footer:null,onOk:()=>{j(!1),n.resetFields()},onCancel:()=>{j(!1),n.resetFields()},children:(0,l.jsxs)(L.Z,{form:a,onFinish:y,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(L.Z.Item,{label:"Email",name:"user_email",className:"mb-4",children:(0,l.jsx)(z.Z,{name:"user_email",className:"px-3 py-2 border rounded-md w-full"})}),(0,l.jsx)("div",{className:"text-center mb-4",children:"OR"}),(0,l.jsx)(L.Z.Item,{label:"User ID",name:"user_id",className:"mb-4",children:(0,l.jsx)(z.Z,{name:"user_id",className:"px-3 py-2 border rounded-md w-full"})})]}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(W.ZP,{htmlType:"submit",children:"Add member"})})]})})]})]})]})},eN=s(12968),eA=s(67951);async function eC(e,t,s,l){console.log("isLocal:",!1);let r=window.location.origin,a=new eN.ZP.OpenAI({apiKey:l,baseURL:r,dangerouslyAllowBrowser:!0});for await(let l of(await a.chat.completions.create({model:s,stream:!0,messages:[{role:"user",content:e}]})))console.log(l),l.choices[0].delta.content&&t(l.choices[0].delta.content)}var eT=e=>{let{accessToken:t,token:s,userRole:a,userID:n}=e,[o,i]=(0,r.useState)(""),[c,d]=(0,r.useState)([]),[h,m]=(0,r.useState)(void 0),[u,x]=(0,r.useState)(null);(0,r.useEffect)(()=>{t&&s&&a&&n&&(async()=>{let e=await y(t,n,a);console.log("model_info:",e),(null==e?void 0:e.data.length)>0&&(x(e.data),m(e.data[0].id))})()},[t,n,a]);let p=(e,t)=>{d(s=>{let l=s[s.length-1];return l&&l.role===e?[...s.slice(0,s.length-1),{role:e,content:l.content+t}]:[...s,{role:e,content:t}]})},j=async()=>{if(""!==o.trim()&&t&&s&&a&&n){d(e=>[...e,{role:"user",content:o}]);try{h&&await eC(o,e=>p("assistant",e),h,t)}catch(e){console.error("Error fetching model response",e),p("assistant","Error fetching model response")}i("")}};if(a&&"Admin Viewer"==a){let{Title:e,Paragraph:t}=en.default;return(0,l.jsxs)("div",{children:[(0,l.jsx)(e,{level:1,children:"Access Denied"}),(0,l.jsx)(t,{children:"Ask your proxy admin for access to test models"})]})}return(0,l.jsx)("div",{style:{width:"100%",position:"relative"},children:(0,l.jsx)(O.Z,{className:"gap-2 p-10 h-[75vh] w-full",children:(0,l.jsx)(M.Z,{children:(0,l.jsxs)(ey.Z,{children:[(0,l.jsxs)(eg.Z,{className:"mt-4",children:[(0,l.jsx)(ej.Z,{children:"Chat"}),(0,l.jsx)(ej.Z,{children:"API Reference"})]}),(0,l.jsxs)(eZ.Z,{children:[(0,l.jsxs)(ew.Z,{children:[(0,l.jsxs)("div",{children:[(0,l.jsx)("label",{children:"Select Model:"}),(0,l.jsx)("select",{value:h||"",onChange:e=>m(e.target.value),children:null==u?void 0:u.map(e=>(0,l.jsx)("option",{value:e.id,children:e.id},e.id))})]}),(0,l.jsxs)($.Z,{className:"mt-5",style:{display:"block",maxHeight:"60vh",overflowY:"auto"},children:[(0,l.jsx)(X.Z,{children:(0,l.jsx)(ee.Z,{children:(0,l.jsx)(Y.Z,{children:(0,l.jsx)(D.Z,{children:"Chat"})})})}),(0,l.jsx)(H.Z,{children:c.map((e,t)=>(0,l.jsx)(ee.Z,{children:(0,l.jsx)(Y.Z,{children:"".concat(e.role,": ").concat(e.content)})},t))})]}),(0,l.jsx)("div",{className:"mt-3",style:{position:"absolute",bottom:5,width:"95%"},children:(0,l.jsxs)("div",{className:"flex",children:[(0,l.jsx)("input",{type:"text",value:o,onChange:e=>i(e.target.value),className:"flex-1 p-2 border rounded-md mr-2",placeholder:"Type your message..."}),(0,l.jsx)("button",{onClick:j,className:"p-2 bg-blue-500 text-white rounded-md",children:"Send"})]})})]}),(0,l.jsx)(ew.Z,{children:(0,l.jsxs)(ey.Z,{children:[(0,l.jsxs)(eg.Z,{children:[(0,l.jsx)(ej.Z,{children:"OpenAI Python SDK"}),(0,l.jsx)(ej.Z,{children:"LlamaIndex"}),(0,l.jsx)(ej.Z,{children:"Langchain Py"})]}),(0,l.jsxs)(eZ.Z,{children:[(0,l.jsx)(ew.Z,{children:(0,l.jsx)(eA.Z,{language:"python",children:'\nimport openai\nclient = openai.OpenAI(\n api_key="your_api_key",\n base_url="http://0.0.0.0:4000" # proxy base url\n)\n\nresponse = client.chat.completions.create(\n model="gpt-3.5-turbo", # model to use from Models Tab\n messages = [\n {\n "role": "user",\n "content": "this is a test request, write a short poem"\n }\n ],\n extra_body={\n "metadata": {\n "generation_name": "ishaan-generation-openai-client",\n "generation_id": "openai-client-gen-id22",\n "trace_id": "openai-client-trace-id22",\n "trace_user_id": "openai-client-user-id2"\n }\n }\n)\n\nprint(response)\n '})}),(0,l.jsx)(ew.Z,{children:(0,l.jsx)(eA.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="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,l.jsx)(ew.Z,{children:(0,l.jsx)(eA.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:8000",\n model = "gpt-3.5-turbo",\n temperature=0.1,\n extra_body={\n "metadata": {\n "generation_name": "ishaan-generation-langchain-client",\n "generation_id": "langchain-client-gen-id22",\n "trace_id": "langchain-client-trace-id22",\n "trace_user_id": "langchain-client-user-id2"\n }\n }\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 '})})]})]})})]})]})})})})},eI=s(33509),eE=s(30569);let{Sider:eP}=eI.default;var eF=e=>{let{setPage:t,userRole:s,defaultSelectedKey:r}=e;return"Admin Viewer"==s?(0,l.jsx)(eI.default,{style:{minHeight:"100vh",maxWidth:"120px"},children:(0,l.jsx)(eP,{width:120,children:(0,l.jsxs)(eE.Z,{mode:"inline",defaultSelectedKeys:r||["4"],style:{height:"100%",borderRight:0},children:[(0,l.jsx)(eE.Z.Item,{onClick:()=>t("api-keys"),children:"API Keys"},"4"),(0,l.jsx)(eE.Z.Item,{onClick:()=>t("models"),children:"Models"},"2"),(0,l.jsx)(eE.Z.Item,{onClick:()=>t("llm-playground"),children:"Chat UI"},"3"),(0,l.jsx)(eE.Z.Item,{onClick:()=>t("usage"),children:"Usage"},"1")]})})}):(0,l.jsx)(eI.default,{style:{minHeight:"100vh",maxWidth:"120px"},children:(0,l.jsx)(eP,{width:120,children:(0,l.jsxs)(eE.Z,{mode:"inline",defaultSelectedKeys:r||["1"],style:{height:"100%",borderRight:0},children:[(0,l.jsx)(eE.Z.Item,{onClick:()=>t("api-keys"),children:"API Keys"},"1"),(0,l.jsx)(eE.Z.Item,{onClick:()=>t("models"),children:"Models"},"2"),(0,l.jsx)(eE.Z.Item,{onClick:()=>t("llm-playground"),children:"Chat UI"},"3"),(0,l.jsx)(eE.Z.Item,{onClick:()=>t("usage"),children:"Usage"},"4"),"Admin"==s?(0,l.jsx)(eE.Z.Item,{onClick:()=>t("users"),children:"Users"},"5"):null,"Admin"==s?(0,l.jsx)(eE.Z.Item,{onClick:()=>t("teams"),children:"Teams"},"6"):null,"Admin"==s?(0,l.jsx)(eE.Z.Item,{onClick:()=>t("admin-panel"),children:"Admin"},"7"):null]})})})},eO=e=>{let{accessToken:t,token:s,userRole:a,userID:n}=e,o=new Date,[i,c]=(0,r.useState)([]),[d,h]=(0,r.useState)([]),[m,u]=(0,r.useState)([]),[x,p]=(0,r.useState)([]),[j,y]=(0,r.useState)([]),[g,_]=(0,r.useState)([]),[S,N]=(0,r.useState)([]),A=new Date(o.getFullYear(),o.getMonth(),1),C=new Date(o.getFullYear(),o.getMonth()+1,0),T=E(A),I=E(C);function E(e){let t=e.getFullYear(),s=e.getMonth()+1,l=e.getDate();return"".concat(t,"-").concat(s<10?"0"+s:s,"-").concat(l<10?"0"+l:l)}return console.log("Start date is ".concat(T)),console.log("End date is ".concat(I)),(0,r.useEffect)(()=>{t&&s&&a&&n&&(async()=>{try{if(console.log("user role: ".concat(a)),"Admin"==a||"Admin Viewer"==a){let e=await f(t);c(e);let s=(await k(t)).map(e=>({key:(e.key_name||e.key_alias||e.api_key).substring(0,7),spend:e.total_spend}));h(s);let l=(await b(t)).map(e=>({key:e.model,spend:e.total_spend}));u(l);let r=await w(t);console.log("teamSpend",r),y(r.daily_spend),_(r.teams),N(r.total_spend_per_team)}else"App Owner"==a&&await Z(t,s,a,n,T,I).then(async e=>{if(console.log("result from spend logs call",e),"daily_spend"in e){let t=e.daily_spend;console.log("daily spend",t),c(t);let s=e.top_api_keys;h(s)}else{let s=(await v(t,function(e){let t=[];e.forEach(e=>{Object.entries(e).forEach(e=>{let[s,l]=e;"spend"!==s&&"startTime"!==s&&"models"!==s&&"users"!==s&&t.push({key:s,spend:l})})}),t.sort((e,t)=>Number(t.spend)-Number(e.spend));let s=t.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||e.token).substring(0,7),spend:e.spend}));h(s),p(function(e){let t={};e.forEach(e=>{Object.entries(e.users).forEach(e=>{let[s,l]=e;""!==s&&null!=s&&"None"!=s&&(t[s]||(t[s]=0),t[s]+=l)})});let s=Object.entries(t).map(e=>{let[t,s]=e;return{user_id:t,spend:s}});s.sort((e,t)=>t.spend-e.spend);let l=s.slice(0,5);return console.log("topKeys: ".concat(Object.values(l[0]))),l}(e)),c(e)}})}catch(e){console.error("There was an error fetching the data",e)}})()},[t,s,a,n,T,I]),(0,l.jsx)("div",{style:{width:"100%"},children:(0,l.jsxs)(ey.Z,{children:[(0,l.jsxs)(eg.Z,{className:"mt-4",children:[(0,l.jsx)(ej.Z,{children:"All Up"}),(0,l.jsx)(ej.Z,{children:"Team Based Usage"})]}),(0,l.jsxs)(eZ.Z,{children:[(0,l.jsx)(ew.Z,{children:(0,l.jsxs)(O.Z,{numItems:2,className:"gap-2 p-10 h-[75vh] w-full",children:[(0,l.jsx)(F.Z,{numColSpan:2,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Monthly Spend"}),(0,l.jsx)(et.Z,{data:i,index:"date",categories:["spend"],colors:["blue"],valueFormatter:e=>"$ ".concat(new Intl.NumberFormat("us").format(e).toString()),yAxisWidth:100,tickGap:5})]})}),(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Top API Keys"}),(0,l.jsx)(et.Z,{className:"mt-4 h-40",data:d,index:"key",categories:["spend"],colors:["blue"],yAxisWidth:80,tickGap:5,layout:"vertical",showXAxis:!1,showLegend:!1})]})}),(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Top Users"}),(0,l.jsx)(et.Z,{className:"mt-4 h-40",data:x,index:"user_id",categories:["spend"],colors:["blue"],yAxisWidth:200,layout:"vertical",showXAxis:!1,showLegend:!1})]})}),(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Top Models"}),(0,l.jsx)(et.Z,{className:"mt-4 h-40",data:m,index:"key",categories:["spend"],colors:["blue"],yAxisWidth:200,layout:"vertical",showXAxis:!1,showLegend:!1})]})})]})}),(0,l.jsx)(ew.Z,{children:(0,l.jsxs)(O.Z,{numItems:2,className:"gap-2 p-10 h-[75vh] w-full",children:[(0,l.jsx)(F.Z,{numColSpan:2,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Daily Spend Per Team"}),(0,l.jsx)(et.Z,{className:"h-72",data:j,index:"date",categories:g,yAxisWidth:30,stack:!0})]})}),(0,l.jsx)(F.Z,{numColSpan:2,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Total Spend Per Team"}),(0,l.jsx)(et.Z,{className:"h-72",data:S,index:"team_id",categories:["total_spend"],yAxisWidth:30})]})})]})})]})]})})},eM=()=>{let{Title:e,Paragraph:t}=en.default,[s,n]=(0,r.useState)(""),[o,c]=(0,r.useState)(null),[d,h]=(0,r.useState)(null),[m,u]=(0,r.useState)(null),[x,p]=(0,r.useState)(!0),j=(0,a.useSearchParams)(),y=j.get("userID"),g=j.get("token"),[w,Z]=(0,r.useState)("api-keys"),[f,k]=(0,r.useState)(null);return(0,r.useEffect)(()=>{if(g){let e=(0,ed.o)(g);if(e){if(console.log("Decoded token:",e),console.log("Decoded key:",e.key),k(e.key),e.user_role){let t=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"app_user":return"App User";default:return"Unknown Role"}}(e.user_role);console.log("Decoded user_role:",t),n(t),"Admin Viewer"==t&&Z("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?p("username_password"==e.login_method):console.log("User Email is not set ".concat(e))}}},[g]),(0,l.jsx)(r.Suspense,{fallback:(0,l.jsx)("div",{children:"Loading..."}),children:(0,l.jsxs)("div",{className:"flex flex-col min-h-screen",children:[(0,l.jsx)(i,{userID:y,userRole:s,userEmail:o,showSSOBanner:x}),(0,l.jsxs)("div",{className:"flex flex-1 overflow-auto",children:[(0,l.jsx)(eF,{setPage:Z,userRole:s,defaultSelectedKey:null}),"api-keys"==w?(0,l.jsx)(eh,{userID:y,userRole:s,teams:d,keys:m,setUserRole:n,userEmail:o,setUserEmail:c,setTeams:h,setKeys:u}):"models"==w?(0,l.jsx)(ep,{userID:y,userRole:s,token:g,accessToken:f}):"llm-playground"==w?(0,l.jsx)(eT,{userID:y,userRole:s,token:g,accessToken:f}):"users"==w?(0,l.jsx)(e_,{userID:y,userRole:s,token:g,keys:m,accessToken:f,setKeys:u}):"teams"==w?(0,l.jsx)(eb,{teams:d,setTeams:h,searchParams:j,accessToken:f,userID:y,userRole:s}):"admin-panel"==w?(0,l.jsx)(eS,{setTeams:h,searchParams:j,accessToken:f}):(0,l.jsx)(eO,{userID:y,userRole:s,token:g,accessToken:f})]})]})})}}},function(e){e.O(0,[730,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-a94f48a4c941dbe4.js b/litellm/proxy/_experimental/out/_next/static/chunks/app/page-a94f48a4c941dbe4.js deleted file mode 100644 index 755ccbe7e..000000000 --- a/litellm/proxy/_experimental/out/_next/static/chunks/app/page-a94f48a4c941dbe4.js +++ /dev/null @@ -1 +0,0 @@ -(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[931],{20661:function(e,t,s){Promise.resolve().then(s.bind(s,92182))},92182:function(e,t,s){"use strict";s.r(t),s.d(t,{default:function(){return eM}});var l=s(3827),r=s(64090),n=s(47907),a=s(8792),o=s(2179),i=e=>{let{userID:t,userRole:s,userEmail:r,showSSOBanner:n}=e;return console.log("User ID:",t),console.log("userEmail:",r),(0,l.jsxs)("nav",{className:"left-0 right-0 top-0 flex justify-between items-center h-12 mb-4",children:[(0,l.jsx)("div",{className:"text-left my-2 absolute top-0 left-0",children:(0,l.jsx)("div",{className:"flex flex-col items-center",children:(0,l.jsx)(a.default,{href:"/",children:(0,l.jsx)("button",{className:"text-gray-800 text-2xl py-1 rounded text-center",children:(0,l.jsx)("img",{src:"/get_image",width:200,height:200,alt:"LiteLLM Brand",className:"mr-2"})})})})}),(0,l.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,l.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/ui#setup-ssoauth-for-ui",target:"_blank",className:"mr-2"}):null,(0,l.jsxs)(o.Z,{variant:"secondary",size:"lg",children:[r,(0,l.jsxs)("p",{children:["Role: ",s]}),(0,l.jsxs)("p",{children:["ID: ",t]})]})]})]})},c=s(80588);let d=async(e,t,s)=>{try{if(console.log("Form Values in keyCreateCall:",s),s.description&&(s.metadata||(s.metadata={}),s.metadata.description=s.description,delete s.description,s.metadata=JSON.stringify(s.metadata)),s.metadata){console.log("formValues.metadata:",s.metadata);try{s.metadata=JSON.parse(s.metadata)}catch(e){throw c.ZP.error("Failed to parse metadata: "+e),Error("Failed to parse metadata: "+e)}}console.log("Form Values after check:",s);let l=await fetch("/key/generate",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({user_id:t,...s})});if(!l.ok){let e=await l.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let r=await l.json();return console.log("API Response:",r),r}catch(e){throw console.error("Failed to create key:",e),e}},h=async(e,t,s)=>{try{if(console.log("Form Values in keyCreateCall:",s),s.description&&(s.metadata||(s.metadata={}),s.metadata.description=s.description,delete s.description,s.metadata=JSON.stringify(s.metadata)),s.metadata){console.log("formValues.metadata:",s.metadata);try{s.metadata=JSON.parse(s.metadata)}catch(e){throw c.ZP.error("Failed to parse metadata: "+e),Error("Failed to parse metadata: "+e)}}console.log("Form Values after check:",s);let l=await fetch("/user/new",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({user_id:t,...s})});if(!l.ok){let e=await l.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let r=await l.json();return console.log("API Response:",r),r}catch(e){throw console.error("Failed to create key:",e),e}},m=async(e,t)=>{try{console.log("in keyDeleteCall:",t);let s=await fetch("/key/delete",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({keys:[t]})});if(!s.ok){let e=await s.text();throw c.ZP.error("Failed to delete key: "+e),Error("Network response was not ok")}let l=await s.json();return console.log(l),l}catch(e){throw console.error("Failed to create key:",e),e}},u=async function(e,t,s){let l=arguments.length>3&&void 0!==arguments[3]&&arguments[3];try{let r="/user/info";"App Owner"==s&&t&&(r="".concat(r,"?user_id=").concat(t)),console.log("in userInfoCall viewAll=",l),l&&(r="".concat(r,"?view_all=true"));let n=await fetch(r,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!n.ok){let e=await n.text();throw c.ZP.error(e),Error("Network response was not ok")}let a=await n.json();return console.log("API Response:",a),a}catch(e){throw console.error("Failed to create key:",e),e}},x=async e=>{try{let t=await fetch("/global/spend",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},p=async(e,t,s)=>{try{let t=await fetch("/v2/model/info",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},j=async(e,t,s)=>{try{let t=await fetch("/model/metrics",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},y=async(e,t,s)=>{try{let t=await fetch("/models",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},g=async(e,t)=>{try{let s="/global/spend/logs";console.log("in keySpendLogsCall:",s);let l=await fetch("".concat(s,"?api_key=").concat(t),{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw c.ZP.error(e),Error("Network response was not ok")}let r=await l.json();return console.log(r),r}catch(e){throw console.error("Failed to create key:",e),e}},w=async e=>{try{let t="/global/spend/teams";console.log("in teamSpendLogsCall:",t);let s=await fetch("".concat(t),{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!s.ok){let e=await s.text();throw c.ZP.error(e),Error("Network response was not ok")}let l=await s.json();return console.log(l),l}catch(e){throw console.error("Failed to create key:",e),e}},Z=async(e,t,s,l,r,n)=>{try{console.log("user role in spend logs call: ".concat(s));let t="/spend/logs";t="App Owner"==s?"".concat(t,"?user_id=").concat(l,"&start_date=").concat(r,"&end_date=").concat(n):"".concat(t,"?start_date=").concat(r,"&end_date=").concat(n);let a=await fetch(t,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!a.ok){let e=await a.text();throw c.ZP.error(e),Error("Network response was not ok")}let o=await a.json();return console.log(o),o}catch(e){throw console.error("Failed to create key:",e),e}},f=async e=>{try{let t=await fetch("/global/spend/logs",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to create key:",e),e}},k=async e=>{try{let t=await fetch("/global/spend/keys?limit=5",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to create key:",e),e}},_=async(e,t)=>{try{t&&JSON.stringify({api_key:t});let s={method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}};t&&(s.body=JSON.stringify({api_key:t}));let l=await fetch("/global/spend/end_users",s);if(!l.ok){let e=await l.text();throw c.ZP.error(e),Error("Network response was not ok")}let r=await l.json();return console.log(r),r}catch(e){throw console.error("Failed to create key:",e),e}},b=async e=>{try{let t=await fetch("/global/spend/models?limit=5",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to create key:",e),e}},v=async(e,t)=>{try{let s=await fetch("/v2/key/info",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({keys:t})});if(!s.ok){let e=await s.text();throw c.ZP.error(e),Error("Network response was not ok")}let l=await s.json();return console.log(l),l}catch(e){throw console.error("Failed to create key:",e),e}},S=async(e,t,s,l)=>{try{let r=await fetch("/user/request_model",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({models:[t],user_id:s,justification:l})});if(!r.ok){let e=await r.text();throw c.ZP.error("Failed to delete key: "+e),Error("Network response was not ok")}let n=await r.json();return console.log(n),n}catch(e){throw console.error("Failed to create key:",e),e}},N=async e=>{try{let t="/user/get_requests";console.log("in userGetRequesedtModelsCall:",t);let s=await fetch(t,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!s.ok){let e=await s.text();throw c.ZP.error("Failed to delete key: "+e),Error("Network response was not ok")}let l=await s.json();return console.log(l),l}catch(e){throw console.error("Failed to get requested models:",e),e}},A=async(e,t)=>{try{let s="/user/get_users?role=".concat(t);console.log("in userGetAllUsersCall:",s);let l=await fetch(s,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw c.ZP.error("Failed to delete key: "+e),Error("Network response was not ok")}let r=await l.json();return console.log(r),r}catch(e){throw console.error("Failed to get requested models:",e),e}},C=async(e,t)=>{try{console.log("Form Values in teamCreateCall:",t);let s=await fetch("/team/new",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...t})});if(!s.ok){let e=await s.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let l=await s.json();return console.log("API Response:",l),l}catch(e){throw console.error("Failed to create key:",e),e}},T=async(e,t,s)=>{try{console.log("Form Values in teamMemberAddCall:",s);let l=await fetch("/team/member_add",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({team_id:t,member:s})});if(!l.ok){let e=await l.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let r=await l.json();return console.log("API Response:",r),r}catch(e){throw console.error("Failed to create key:",e),e}},I=async(e,t)=>{try{console.log("Form Values in userUpdateUserCall:",t);let s=await fetch("/user/update",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({user_role:"proxy_admin_viewer",...t})});if(!s.ok){let e=await s.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let l=await s.json();return console.log("API Response:",l),l}catch(e){throw console.error("Failed to create key:",e),e}},P=async(e,t)=>{try{let s=await fetch("/global/predict/spend/logs",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({data:t})});if(!s.ok){let e=await s.text();throw c.ZP.error(e),Error("Network response was not ok")}let l=await s.json();return console.log(l),l}catch(e){throw console.error("Failed to create key:",e),e}},E=async e=>{try{console.log("Checking Slack Budget Alerts service health");let t=await fetch("/health/services?service=slack_budget_alerts",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error("Failed Slack Alert test: "+e),Error(e)}let s=await t.json();return c.ZP.success("Test Slack Alert worked - check your Slack!"),console.log("Service Health Response:",s),s}catch(e){throw console.error("Failed to perform health check:",e),e}};var F=s(10384),O=s(46453),M=s(13810),R=s(71801),D=s(42440),U=s(17189),L=s(12143),B=s(77171),z=s(42539),K=s(88707),W=s(1861);let{Option:V}=U.default;var q=e=>{let{userID:t,teamID:s,userRole:n,accessToken:a,data:i,userModels:h,setData:m}=e,[u]=L.Z.useForm(),[x,p]=(0,r.useState)(!1),[j,y]=(0,r.useState)(null),[g,w]=(0,r.useState)(null),Z=()=>{p(!1),u.resetFields()},f=()=>{p(!1),y(null),u.resetFields()},k=async e=>{try{c.ZP.info("Making API Call"),p(!0);let s=await d(a,t,e);console.log("key create Response:",s),m(e=>e?[...e,s]:[s]),y(s.key),w(s.soft_budget),c.ZP.success("API Key Created"),u.resetFields(),localStorage.removeItem("userData"+t)}catch(e){console.error("Error creating the key:",e)}},_=async()=>{try{console.log("Sending Slack alert...");let e=await E(a);console.log("slackBudgetAlertsHealthCheck Response:",e),console.log("Testing Slack alert successful")}catch(e){console.error("Error sending Slack alert:",e)}};return(0,l.jsxs)("div",{children:[(0,l.jsx)(o.Z,{className:"mx-auto",onClick:()=>p(!0),children:"+ Create New Key"}),(0,l.jsx)(B.Z,{title:"Create Key",visible:x,width:800,footer:null,onOk:Z,onCancel:f,children:(0,l.jsxs)(L.Z,{form:u,onFinish:k,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:["App Owner"===n||"Admin"===n?(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(L.Z.Item,{label:"Key Name",name:"key_alias",children:(0,l.jsx)(z.Z,{})}),(0,l.jsx)(L.Z.Item,{label:"Team ID",name:"team_id",children:(0,l.jsx)(z.Z,{placeholder:"ai_team",defaultValue:s||""})}),(0,l.jsx)(L.Z.Item,{label:"Models",name:"models",children:(0,l.jsx)(U.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:h.map(e=>(0,l.jsx)(V,{value:e,children:e},e))})}),(0,l.jsx)(L.Z.Item,{label:"Soft Budget (USD) Monthly",name:"soft_budget",initialValue:50,children:(0,l.jsx)(K.Z,{step:.01,precision:2,defaultValue:50,width:200})}),(0,l.jsx)(L.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,l.jsx)(K.Z,{step:.01,precision:2,width:200})}),(0,l.jsx)(L.Z.Item,{label:"Reset Budget",name:"budget_duration",children:(0,l.jsxs)(U.default,{defaultValue:null,placeholder:"n/a",children:[(0,l.jsx)(U.default.Option,{value:"24h",children:"daily"}),(0,l.jsx)(U.default.Option,{value:"30d",children:"monthly"})]})}),(0,l.jsx)(L.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})}),(0,l.jsx)(L.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})}),(0,l.jsx)(L.Z.Item,{label:"Expire Key (eg: 30s, 30h, 30d)",name:"duration",children:(0,l.jsx)(z.Z,{})}),(0,l.jsx)(L.Z.Item,{label:"Metadata",name:"metadata",children:(0,l.jsx)(z.Z.TextArea,{rows:4,placeholder:"Enter metadata as JSON"})})]}):(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(L.Z.Item,{label:"Key Name",name:"key_alias",children:(0,l.jsx)(z.Z,{})}),(0,l.jsx)(L.Z.Item,{label:"Team ID (Contact Group)",name:"team_id",children:(0,l.jsx)(z.Z,{placeholder:"ai_team"})}),(0,l.jsx)(L.Z.Item,{label:"Description",name:"description",children:(0,l.jsx)(z.Z.TextArea,{placeholder:"Enter description",rows:4})})]}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(W.ZP,{htmlType:"submit",children:"Create Key"})})]})}),j&&(0,l.jsx)(B.Z,{visible:x,onOk:Z,onCancel:f,footer:null,children:(0,l.jsx)(O.Z,{numItems:1,className:"gap-2 w-full",children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Save your Key"}),(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsxs)("p",{children:["Please save this secret key somewhere safe and accessible. For security reasons, ",(0,l.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,l.jsx)(F.Z,{numColSpan:1,children:null!=j?(0,l.jsxs)("div",{children:[(0,l.jsxs)(R.Z,{children:["API Key: ",j]}),(0,l.jsx)(D.Z,{className:"mt-6",children:"Budgets"}),(0,l.jsxs)(R.Z,{children:["Soft Limit Budget: $",g]}),(0,l.jsx)(o.Z,{className:"mt-3",onClick:_,children:"Test Slack Alert"}),(0,l.jsxs)(R.Z,{className:"mt-2",children:["(LiteLLM Docs -",(0,l.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/alerting",target:"_blank",className:"text-blue-500",children:"Set Up Slack Alerting)"})]})]}):(0,l.jsx)(R.Z,{children:"Key being created, this might take 30s"})})]})})})]})},J=s(33393),G=s(61244),$=s(10827),H=s(3851),Y=s(2044),X=s(64167),Q=s(74480),ee=s(7178),et=s(9853),es=s(56863),el=e=>{let{token:t,accessToken:s,keySpend:n,keyBudget:a,keyName:i}=e,[c,d]=(0,r.useState)(!1),[h,m]=(0,r.useState)(null),[u,x]=(0,r.useState)(""),[p,j]=(0,r.useState)(null),y=async()=>{try{if(null==s||null==t)return;console.log("accessToken: ".concat(s,"; token: ").concat(t));let e=await g(s,t);console.log("Response:",e),m(e);let l=await P(s,e);console.log("Response2:",l);let r=[...e,...l.response];m(r),x(l.predicted_spend),console.log("Combined Data:",r)}catch(e){console.error("There was an error fetching the data",e)}};return t?(0,l.jsxs)("div",{children:[(0,l.jsx)(o.Z,{size:"xs",onClick:()=>{console.log("Show Modal triggered"),d(!0),y()},variant:"secondary",children:"Spend Report"}),(0,l.jsxs)(B.Z,{visible:c,width:1400,onOk:()=>{d(!1)},onCancel:()=>{d(!1)},footer:null,children:[(0,l.jsxs)(D.Z,{style:{textAlign:"left"},children:["Key Name: ",i]}),(0,l.jsxs)(es.Z,{children:["Monthly Spend $",n]}),(0,l.jsx)(D.Z,{children:u}),(0,l.jsx)(M.Z,{className:"mt-6 mb-6",children:h&&(0,l.jsx)(et.Z,{className:"mt-6",data:h,colors:["blue","amber"],index:"date",categories:["spend","predicted_spend"],yAxisWidth:80})})]})]}):null},er=e=>{let{userID:t,accessToken:s,data:n,setData:a}=e,[i,c]=(0,r.useState)(!1),[d,h]=(0,r.useState)(!1),[u,x]=(0,r.useState)(null),p=async e=>{null!=n&&(x(e),localStorage.removeItem("userData"+t),h(!0))},j=async()=>{if(null!=u&&null!=n){try{await m(s,u);let e=n.filter(e=>e.token!==u);a(e)}catch(e){console.error("Error deleting the key:",e)}h(!1),x(null)}};if(null!=n)return console.log("RERENDER TRIGGERED"),(0,l.jsxs)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh] mb-4",children:[(0,l.jsxs)($.Z,{className:"mt-5",children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"Key Alias"}),(0,l.jsx)(Q.Z,{children:"Secret Key"}),(0,l.jsx)(Q.Z,{children:"Spend (USD)"}),(0,l.jsx)(Q.Z,{children:"Key Budget (USD)"}),(0,l.jsx)(Q.Z,{children:"Spend Report"}),(0,l.jsx)(Q.Z,{children:"Team ID"}),(0,l.jsx)(Q.Z,{children:"Metadata"}),(0,l.jsx)(Q.Z,{children:"Models"}),(0,l.jsx)(Q.Z,{children:"TPM / RPM Limits"}),(0,l.jsx)(Q.Z,{children:"Expires"})]})}),(0,l.jsx)(H.Z,{children:n.map(e=>(console.log(e),"litellm-dashboard"===e.team_id)?null:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",whiteSpace:"pre-wrap",overflow:"hidden"},children:null!=e.key_alias?(0,l.jsx)(R.Z,{children:e.key_alias}):(0,l.jsx)(R.Z,{children:"Not Set"})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:e.key_name})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:(()=>{try{return parseFloat(e.spend).toFixed(4)}catch(t){return e.spend}})()})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",whiteSpace:"pre-wrap",overflow:"hidden"},children:null!=e.max_budget?(0,l.jsx)(R.Z,{children:e.max_budget}):(0,l.jsx)(R.Z,{children:"Unlimited Budget"})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px"},children:(0,l.jsx)(el,{token:e.token,accessToken:s,keySpend:e.spend,keyBudget:e.max_budget,keyName:e.key_name})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:e.team_id})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:JSON.stringify(e.metadata).slice(0,400)})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:JSON.stringify(e.models)})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",overflowWrap:"break-word"},children:(0,l.jsxs)(R.Z,{children:["TPM Limit: ",e.tpm_limit?e.tpm_limit:"Unlimited"," ",(0,l.jsx)("br",{})," RPM Limit:"," ",e.rpm_limit?e.rpm_limit:"Unlimited"]})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",wordWrap:"break-word"},children:null!=e.expires?(0,l.jsx)(R.Z,{children:e.expires}):(0,l.jsx)(R.Z,{children:"Never"})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",wordWrap:"break-word"},children:(0,l.jsx)(G.Z,{onClick:()=>p(e.token),icon:J.Z,size:"sm"})})]},e.token))})]}),d&&(0,l.jsx)("div",{className:"fixed z-10 inset-0 overflow-y-auto",children:(0,l.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,l.jsx)("div",{className:"fixed inset-0 transition-opacity","aria-hidden":"true",children:(0,l.jsx)("div",{className:"absolute inset-0 bg-gray-500 opacity-75"})}),(0,l.jsx)("span",{className:"hidden sm:inline-block sm:align-middle sm:h-screen","aria-hidden":"true",children:"​"}),(0,l.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,l.jsx)("div",{className:"bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4",children:(0,l.jsx)("div",{className:"sm:flex sm:items-start",children:(0,l.jsxs)("div",{className:"mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left",children:[(0,l.jsx)("h3",{className:"text-lg leading-6 font-medium text-gray-900",children:"Delete Key"}),(0,l.jsx)("div",{className:"mt-2",children:(0,l.jsx)("p",{className:"text-sm text-gray-500",children:"Are you sure you want to delete this key ?"})})]})})}),(0,l.jsxs)("div",{className:"bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse",children:[(0,l.jsx)(o.Z,{onClick:j,color:"red",className:"ml-2",children:"Delete"}),(0,l.jsx)(o.Z,{onClick:()=>{h(!1),x(null)},children:"Cancel"})]})]})]})})]})},en=e=>{let{userID:t,userSpendData:s,userRole:n,accessToken:a}=e,[o,i]=(0,r.useState)(null==s?void 0:s.spend),[c,d]=(0,r.useState)((null==s?void 0:s.max_budget)||null);(0,r.useEffect)(()=>{(async()=>{if("Admin"===n)try{let e=await x(a);i(e.spend),d(e.max_budget||null)}catch(e){console.error("Error fetching global spend data:",e)}})()},[n,a]);let h=void 0!==o?o.toFixed(4):null;return(0,l.jsx)(l.Fragment,{children:(0,l.jsxs)(M.Z,{className:"mx-auto mb-4",children:[(0,l.jsxs)(es.Z,{children:["$",h]}),(0,l.jsxs)(D.Z,{children:["/ ",null!==c?"$".concat(c," limit"):"No limit"]})]})})},ea=s(36083),eo=s(68967),ei=s(27166),ec=e=>{let{teams:t,setSelectedTeam:s}=e,{Title:n,Paragraph:a}=ea.default,[o,i]=(0,r.useState)("");return(0,l.jsxs)("div",{className:"mt-10",children:[(0,l.jsx)(n,{level:4,children:"Default Team"}),(0,l.jsx)(a,{children:"If you belong to multiple teams, this setting controls which team is used by default when creating new API Keys."}),t&&t.length>0?(0,l.jsx)(eo.Z,{defaultValue:"0",children:t.map((e,t)=>(0,l.jsx)(ei.Z,{value:String(t),onClick:()=>s(e),children:e.team_alias},t))}):(0,l.jsxs)(a,{children:["No team created. ",(0,l.jsx)("b",{children:"Defaulting to personal account."})]})]})},ed=s(37963);console.log("isLocal:",!1);var eh=e=>{let{userID:t,userRole:s,teams:a,keys:o,setUserRole:i,userEmail:c,setUserEmail:d,setTeams:h,setKeys:m}=e,[p,j]=(0,r.useState)(null),g=(0,n.useSearchParams)();g.get("viewSpend"),(0,n.useRouter)();let w=g.get("token"),[Z,f]=(0,r.useState)(null),[k,_]=(0,r.useState)([]),[b,v]=(0,r.useState)(a?a[0]:null);if(window.addEventListener("beforeunload",function(){sessionStorage.clear()}),(0,r.useEffect)(()=>{if(w){let e=(0,ed.o)(w);if(e){if(console.log("Decoded token:",e),console.log("Decoded key:",e.key),f(e.key),e.user_role){let t=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";default:return"Unknown Role"}}(e.user_role);console.log("Decoded user_role:",t),i(t)}else console.log("User role not defined");e.user_email?d(e.user_email):console.log("User Email is not set ".concat(e))}}if(t&&Z&&s&&!o&&!p){let e=sessionStorage.getItem("userModels"+t);e?_(JSON.parse(e)):(async()=>{try{let e=await u(Z,t,s);if(console.log("received teams in user dashboard: ".concat(Object.keys(e),"; team values: ").concat(Object.entries(e.teams))),"Admin"==s){let e=await x(Z);j(e),console.log("globalSpend:",e)}else j(e.user_info);m(e.keys),h(e.teams),v(e.teams?e.teams[0]:null),sessionStorage.setItem("userData"+t,JSON.stringify(e.keys)),sessionStorage.setItem("userSpendData"+t,JSON.stringify(e.user_info));let l=(await y(Z,t,s)).data.map(e=>e.id);console.log("available_model_names:",l),_(l),console.log("userModels:",k),sessionStorage.setItem("userModels"+t,JSON.stringify(l))}catch(e){console.error("There was an error fetching the data",e)}})()}},[t,w,Z,o,s]),null==t||null==w){let e="/sso/key/generate";return console.log("Full URL:",e),window.location.href=e,null}if(null==Z)return null;if(null==s&&i("App Owner"),s&&"Admin Viewer"==s){let{Title:e,Paragraph:t}=ea.default;return(0,l.jsxs)("div",{children:[(0,l.jsx)(e,{level:1,children:"Access Denied"}),(0,l.jsx)(t,{children:"Ask your proxy admin for access to create keys"})]})}return(0,l.jsx)("div",{children:(0,l.jsx)(O.Z,{numItems:1,className:"gap-0 p-10 h-[75vh] w-full",children:(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(en,{userID:t,userSpendData:p,userRole:s,accessToken:Z}),(0,l.jsx)(er,{userID:t,accessToken:Z,data:o,setData:m}),(0,l.jsx)(q,{userID:t,teamID:b?b.team_id:null,userRole:s,userModels:k,accessToken:Z,data:o,setData:m}),(0,l.jsx)(ec,{teams:a,setSelectedTeam:v})]})})})},em=s(5);let{Option:eu}=U.default;var ex=e=>{let{userModels:t,accessToken:s,userID:n}=e,[a]=L.Z.useForm(),[i,d]=(0,r.useState)(!1),h=async e=>{try{c.ZP.info("Requesting access");let{selectedModel:t,accessReason:l}=e;await S(s,t,n,l),d(!0)}catch(e){console.error("Error requesting access:",e)}};return(0,l.jsxs)("div",{children:[(0,l.jsx)(o.Z,{size:"xs",onClick:()=>d(!0),children:"Request Access"}),(0,l.jsx)(B.Z,{title:"Request Access",visible:i,width:800,footer:null,onOk:()=>{d(!1),a.resetFields()},onCancel:()=>{d(!1),a.resetFields()},children:(0,l.jsxs)(L.Z,{form:a,onFinish:h,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsx)(L.Z.Item,{label:"Select Model",name:"selectedModel",children:(0,l.jsx)(U.default,{placeholder:"Select model",style:{width:"100%"},children:t.map(e=>(0,l.jsx)(eu,{value:e,children:e},e))})}),(0,l.jsx)(L.Z.Item,{label:"Reason for Access",name:"accessReason",children:(0,l.jsx)(z.Z.TextArea,{rows:4,placeholder:"Enter reason for access"})}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(o.Z,{children:"Request Access"})})]})})]})},ep=e=>{let{accessToken:t,token:s,userRole:n,userID:a}=e,[o,i]=(0,r.useState)({data:[]}),[c,d]=(0,r.useState)([]),[h,m]=(0,r.useState)([]);if((0,r.useEffect)(()=>{if(!t||!s||!n||!a)return;let e=async()=>{try{let e=await p(t,a,n);console.log("Model data response:",e.data),i(e);let s=await j(t,a,n);if(console.log("Model metrics response:",s),d(s),"Admin"===n&&t){let e=await N(t);console.log("Pending Requests:",h),m(e.requests||[])}}catch(e){console.error("There was an error fetching the model data",e)}};t&&s&&n&&a&&e()},[t,s,n,a]),!o||!t||!s||!n||!a)return(0,l.jsx)("div",{children:"Loading..."});let u=[];for(let e=0;e(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{children:(0,l.jsx)(D.Z,{children:e.model_name})}),(0,l.jsx)(Y.Z,{children:e.provider}),"Admin"===n&&(0,l.jsx)(Y.Z,{children:e.api_base}),(0,l.jsx)(Y.Z,{children:e.user_access?(0,l.jsx)(em.Z,{color:"green",children:"Yes"}):(0,l.jsx)(ex,{userModels:u,accessToken:t,userID:a})}),(0,l.jsx)(Y.Z,{children:e.input_cost}),(0,l.jsx)(Y.Z,{children:e.output_cost}),(0,l.jsx)(Y.Z,{children:e.max_tokens})]},e.model_name))})]})}),(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Model Statistics (Number Requests)"}),(0,l.jsx)(et.Z,{data:c,index:"model",categories:["num_requests"],colors:["blue"],yAxisWidth:400,layout:"vertical",tickGap:5})]}),(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Model Statistics (Latency)"}),(0,l.jsx)(et.Z,{data:c,index:"model",categories:["avg_latency_seconds"],colors:["red"],yAxisWidth:400,layout:"vertical",tickGap:5})]})]})})},ej=s(92836),ey=s(26734),eg=s(41608),ew=s(32126),eZ=s(23682);let{Option:ef}=U.default;var ek=e=>{let{userID:t,accessToken:s}=e,[n]=L.Z.useForm(),[a,i]=(0,r.useState)(!1),[d,m]=(0,r.useState)(null),[u,x]=(0,r.useState)([]);(0,r.useEffect)(()=>{(async()=>{try{let e=await y(s,t,"any"),l=[];for(let t=0;t{i(!1),n.resetFields()},j=()=>{i(!1),m(null),n.resetFields()},g=async e=>{try{c.ZP.info("Making API Call"),i(!0),console.log("formValues in create user:",e);let l=await h(s,t,e);console.log("user create Response:",l),m(l.key),c.ZP.success("API user Created"),n.resetFields(),localStorage.removeItem("userData"+t)}catch(e){console.error("Error creating the user:",e)}};return(0,l.jsxs)("div",{children:[(0,l.jsx)(o.Z,{className:"mx-auto",onClick:()=>i(!0),children:"+ Create New User"}),(0,l.jsx)(B.Z,{title:"Create User",visible:a,width:800,footer:null,onOk:p,onCancel:j,children:(0,l.jsxs)(L.Z,{form:n,onFinish:g,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsx)(L.Z.Item,{label:"User ID",name:"user_id",children:(0,l.jsx)(z.Z,{placeholder:"Enter User ID"})}),(0,l.jsx)(L.Z.Item,{label:"Team ID",name:"team_id",children:(0,l.jsx)(z.Z,{placeholder:"ai_team"})}),(0,l.jsx)(L.Z.Item,{label:"Models",name:"models",children:(0,l.jsx)(U.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:u.map(e=>(0,l.jsx)(ef,{value:e,children:e},e))})}),(0,l.jsx)(L.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,l.jsx)(K.Z,{step:.01,precision:2,width:200})}),(0,l.jsx)(L.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})}),(0,l.jsx)(L.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})}),(0,l.jsx)(L.Z.Item,{label:"Duration (eg: 30s, 30h, 30d)",name:"duration",children:(0,l.jsx)(z.Z,{})}),(0,l.jsx)(L.Z.Item,{label:"Metadata",name:"metadata",children:(0,l.jsx)(z.Z.TextArea,{rows:4,placeholder:"Enter metadata as JSON"})}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(W.ZP,{htmlType:"submit",children:"Create User"})})]})}),d&&(0,l.jsxs)(B.Z,{title:"Save Your User",visible:a,onOk:p,onCancel:j,footer:null,children:[(0,l.jsxs)("p",{children:["Please save this secret user somewhere safe and accessible. For security reasons, ",(0,l.jsx)("b",{children:"you will not be able to view it again"})," ","through your LiteLLM account. If you lose this secret user, you will need to generate a new one."]}),(0,l.jsx)("p",{children:null!=d?"API user: ".concat(d):"User being created, this might take 30s"})]})]})},e_=e=>{let{accessToken:t,token:s,keys:n,userRole:a,userID:o,setKeys:i}=e,[c,d]=(0,r.useState)(null),[h,m]=(0,r.useState)(null),[x,p]=(0,r.useState)(1);if((0,r.useEffect)(()=>{if(!t||!s||!a||!o)return;let e=async()=>{try{let e=await u(t,null,a,!0);console.log("user data response:",e),d(e)}catch(e){console.error("There was an error fetching the model data",e)}};t&&s&&a&&o&&!c&&e();let l=async()=>{try{let e=await _(t,null);console.log("user data response:",e),m(e)}catch(e){console.error("There was an error fetching the model data",e)}};a&&("Admin"==a||"Admin Viewer"==a)&&!h&&l()},[t,s,a,o]),!c||!t||!s||!a||!o)return(0,l.jsx)("div",{children:"Loading..."});let j=async e=>{try{let s=await _(t,e);console.log("user data response:",s),m(s)}catch(e){console.error("There was an error fetching the model data",e)}};return(0,l.jsx)("div",{style:{width:"100%"},children:(0,l.jsxs)(O.Z,{className:"gap-2 p-10 h-[75vh] w-full",children:[(0,l.jsx)(ek,{userID:o,accessToken:t}),(0,l.jsx)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh] mb-4",children:(0,l.jsxs)(ey.Z,{children:[(0,l.jsxs)(eg.Z,{variant:"line",defaultValue:"1",children:[(0,l.jsx)(ej.Z,{value:"1",children:"Key Owners"}),(0,l.jsx)(ej.Z,{value:"2",children:"End-Users"})]}),(0,l.jsxs)(eZ.Z,{children:[(0,l.jsx)(ew.Z,{children:(0,l.jsxs)($.Z,{className:"mt-5",children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"User ID"}),(0,l.jsx)(Q.Z,{children:"User Role"}),(0,l.jsx)(Q.Z,{children:"User Models"}),(0,l.jsx)(Q.Z,{children:"User Spend ($ USD)"}),(0,l.jsx)(Q.Z,{children:"User Max Budget ($ USD)"})]})}),(0,l.jsx)(H.Z,{children:c.map(e=>(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{children:e.user_id}),(0,l.jsx)(Y.Z,{children:e.user_role?e.user_role:"app_owner"}),(0,l.jsx)(Y.Z,{children:e.models&&e.models.length>0?e.models:"All Models"}),(0,l.jsx)(Y.Z,{children:e.spend?e.spend:0}),(0,l.jsx)(Y.Z,{children:e.max_budget?e.max_budget:"Unlimited"})]},e.user_id))})]})}),(0,l.jsxs)(ew.Z,{children:[(0,l.jsxs)("div",{className:"flex items-center",children:[(0,l.jsx)("div",{className:"flex-1"}),(0,l.jsxs)("div",{className:"flex-1 flex justify-between items-center",children:[(0,l.jsx)(R.Z,{className:"w-1/4 mr-2 text-right",children:"Key"}),(0,l.jsx)(eo.Z,{defaultValue:"1",className:"w-3/4",children:null==n?void 0:n.map((e,t)=>{if(e&&null!==e.key_name&&e.key_name.length>0)return(0,l.jsx)(ei.Z,{value:String(t),onClick:()=>j(e.token),children:e.key_name},t)})})]})]}),(0,l.jsxs)($.Z,{children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"End User"}),(0,l.jsx)(Q.Z,{children:"Spend"}),(0,l.jsx)(Q.Z,{children:"Total Events"})]})}),(0,l.jsx)(H.Z,{children:null==h?void 0:h.map((e,t)=>(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{children:e.end_user}),(0,l.jsx)(Y.Z,{children:e.total_spend}),(0,l.jsx)(Y.Z,{children:e.total_events})]},t))})]})]})]})]})}),function(){if(!c)return null;let e=Math.ceil(c.length/25),t=Math.min(25*x,c.length);return(0,l.jsxs)("div",{className:"flex justify-between items-center",children:[(0,l.jsxs)("div",{children:["Showing ",(x-1)*25+1," – ",t," of ",c.length]}),(0,l.jsxs)("div",{className:"flex",children:[(0,l.jsx)("button",{className:"bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-l focus:outline-none",disabled:1===x,onClick:()=>p(x-1),children:"← Prev"}),(0,l.jsx)("button",{className:"bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-r focus:outline-none",disabled:x===e,onClick:()=>p(x+1),children:"Next →"})]})]})}()]})})},eb=e=>{let{teams:t,searchParams:s,accessToken:n,setTeams:a,userID:i,userRole:d}=e,[h]=L.Z.useForm(),[m]=L.Z.useForm(),{Title:u,Paragraph:x}=ea.default,[p,j]=(0,r.useState)(""),[g,w]=(0,r.useState)(t?t[0]:null),[Z,f]=(0,r.useState)(!1),[k,_]=(0,r.useState)(!1),[b,v]=(0,r.useState)([]);(0,r.useEffect)(()=>{(async()=>{try{if(null===i||null===d)return;if(null!==n){let e=(await y(n,i,d)).data.map(e=>e.id);console.log("available_model_names:",e),v(e)}}catch(e){console.error("Error fetching user models:",e)}})()},[n,i,d]);let S=async e=>{try{if(null!=n){c.ZP.info("Creating Team");let s=await C(n,e);null!==t?a([...t,s]):a([s]),console.log("response for team create call: ".concat(s)),c.ZP.success("Team created"),f(!1)}}catch(e){console.error("Error creating the key:",e),c.ZP.error("Error creating the team: "+e)}},N=async e=>{try{if(null!=n&&null!=t){c.ZP.info("Adding Member");let s={role:"user",user_email:e.user_email,user_id:e.user_id},l=await T(n,g.team_id,s);console.log("response for team create call: ".concat(l.data));let r=t.findIndex(e=>(console.log("team.team_id=".concat(e.team_id,"; response.data.team_id=").concat(l.data.team_id)),e.team_id===l.data.team_id));if(console.log("foundIndex: ".concat(r)),-1!==r){let e=[...t];e[r]=l.data,a(e),w(l.data)}_(!1)}}catch(e){console.error("Error creating the key:",e)}};return console.log("received teams ".concat(t)),(0,l.jsx)("div",{className:"w-full mx-4",children:(0,l.jsxs)(O.Z,{numItems:1,className:"gap-2 p-2 h-[75vh] w-full",children:[(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(u,{level:4,children:"All Teams"}),(0,l.jsx)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,l.jsxs)($.Z,{children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"Team Name"}),(0,l.jsx)(Q.Z,{children:"Spend (USD)"}),(0,l.jsx)(Q.Z,{children:"Budget (USD)"}),(0,l.jsx)(Q.Z,{children:"Models"}),(0,l.jsx)(Q.Z,{children:"TPM / RPM Limits"})]})}),(0,l.jsx)(H.Z,{children:t&&t.length>0?t.map(e=>(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:e.team_alias}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:e.spend}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:e.max_budget?e.max_budget:"No limit"}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:JSON.stringify(e.models?e.models:[])})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsxs)(R.Z,{children:["TPM Limit:"," ",e.tpm_limit?e.tpm_limit:"Unlimited"," ",(0,l.jsx)("br",{}),"RPM Limit:"," ",e.rpm_limit?e.rpm_limit:"Unlimited"]})})]},e.team_id)):null})]})})]}),(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(o.Z,{className:"mx-auto",onClick:()=>f(!0),children:"+ Create New Team"}),(0,l.jsx)(B.Z,{title:"Create Team",visible:Z,width:800,footer:null,onOk:()=>{f(!1),h.resetFields()},onCancel:()=>{f(!1),h.resetFields()},children:(0,l.jsxs)(L.Z,{form:h,onFinish:S,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(L.Z.Item,{label:"Team Name",name:"team_alias",children:(0,l.jsx)(z.Z,{})}),(0,l.jsx)(L.Z.Item,{label:"Models",name:"models",children:(0,l.jsx)(U.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:b.map(e=>(0,l.jsx)(U.default.Option,{value:e,children:e},e))})}),(0,l.jsx)(L.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,l.jsx)(K.Z,{step:.01,precision:2,width:200})}),(0,l.jsx)(L.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})}),(0,l.jsx)(L.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})})]}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(W.ZP,{htmlType:"submit",children:"Create Team"})})]})})]}),(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(u,{level:4,children:"Team Members"}),(0,l.jsx)(x,{children:"If you belong to multiple teams, this setting controls which teams members you see."}),t&&t.length>0?(0,l.jsx)(eo.Z,{defaultValue:"0",children:t.map((e,t)=>(0,l.jsx)(ei.Z,{value:String(t),onClick:()=>{w(e)},children:e.team_alias},t))}):(0,l.jsxs)(x,{children:["No team created. ",(0,l.jsx)("b",{children:"Defaulting to personal account."})]})]}),(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsx)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,l.jsxs)($.Z,{children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"Member Name"}),(0,l.jsx)(Q.Z,{children:"Role"})]})}),(0,l.jsx)(H.Z,{children:g?g.members_with_roles.map((e,t)=>(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{children:e.user_email?e.user_email:e.user_id?e.user_id:null}),(0,l.jsx)(Y.Z,{children:e.role})]},t)):null})]})})}),(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(o.Z,{className:"mx-auto mb-5",onClick:()=>_(!0),children:"+ Add member"}),(0,l.jsx)(B.Z,{title:"Add member",visible:k,width:800,footer:null,onOk:()=>{_(!1),m.resetFields()},onCancel:()=>{_(!1),m.resetFields()},children:(0,l.jsxs)(L.Z,{form:h,onFinish:N,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(L.Z.Item,{label:"Email",name:"user_email",className:"mb-4",children:(0,l.jsx)(z.Z,{name:"user_email",className:"px-3 py-2 border rounded-md w-full"})}),(0,l.jsx)("div",{className:"text-center mb-4",children:"OR"}),(0,l.jsx)(L.Z.Item,{label:"User ID",name:"user_id",className:"mb-4",children:(0,l.jsx)(z.Z,{name:"user_id",className:"px-3 py-2 border rounded-md w-full"})})]}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(W.ZP,{htmlType:"submit",children:"Add member"})})]})})]})]})})},ev=s(8510),eS=e=>{let{searchParams:t,accessToken:s}=e,[n]=L.Z.useForm(),[a]=L.Z.useForm(),{Title:i,Paragraph:d}=ea.default,[h,m]=(0,r.useState)(""),[u,x]=(0,r.useState)(null),[p,j]=(0,r.useState)(!1);(0,r.useEffect)(()=>{(async()=>{if(null!=s){let e=[],t=await A(s,"proxy_admin_viewer");t.forEach(t=>{e.push({user_role:t.user_role,user_id:t.user_id,user_email:t.user_email})}),console.log("proxy viewers: ".concat(t));let l=await A(s,"proxy_admin");l.forEach(t=>{e.push({user_role:t.user_role,user_id:t.user_id,user_email:t.user_email})}),console.log("proxy admins: ".concat(l)),console.log("combinedList: ".concat(e)),x(e)}})()},[s]);let y=async e=>{try{if(null!=s&&null!=u){c.ZP.info("Making API Call"),e.user_email,e.user_id;let t=await I(s,e);console.log("response for team create call: ".concat(t));let l=u.findIndex(e=>(console.log("user.user_id=".concat(e.user_id,"; response.user_id=").concat(t.user_id)),e.user_id===t.user_id));console.log("foundIndex: ".concat(l)),-1==l&&(console.log("updates admin with new user"),u.push(t),x(u)),j(!1)}}catch(e){console.error("Error creating the key:",e)}};return console.log("admins: ".concat(null==u?void 0:u.length)),(0,l.jsxs)("div",{className:"w-full m-2",children:[(0,l.jsx)(i,{level:4,children:"Restricted Access"}),(0,l.jsxs)(d,{children:["Add other people to just view spend. They cannot create keys, teams or grant users access to new models."," ",(0,l.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/ui#restrict-ui-access",children:"Requires SSO Setup"})]}),(0,l.jsxs)(O.Z,{numItems:1,className:"gap-2 p-0 w-full",children:[(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsx)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,l.jsxs)($.Z,{children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"Member Name"}),(0,l.jsx)(Q.Z,{children:"Role"}),(0,l.jsx)(Q.Z,{children:"Action"})]})}),(0,l.jsx)(H.Z,{children:u?u.map((e,t)=>(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{children:e.user_email?e.user_email:e.user_id?e.user_id:null}),(0,l.jsx)(Y.Z,{children:e.user_role}),(0,l.jsx)(Y.Z,{children:(0,l.jsx)(G.Z,{icon:ev.Z,size:"sm"})})]},t)):null})]})})}),(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(o.Z,{className:"mx-auto mb-5",onClick:()=>j(!0),children:"+ Add viewer"}),(0,l.jsx)(B.Z,{title:"Add viewer",visible:p,width:800,footer:null,onOk:()=>{j(!1),a.resetFields()},onCancel:()=>{j(!1),a.resetFields()},children:(0,l.jsxs)(L.Z,{form:n,onFinish:y,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(L.Z.Item,{label:"Email",name:"user_email",className:"mb-4",children:(0,l.jsx)(z.Z,{name:"user_email",className:"px-3 py-2 border rounded-md w-full"})}),(0,l.jsx)("div",{className:"text-center mb-4",children:"OR"}),(0,l.jsx)(L.Z.Item,{label:"User ID",name:"user_id",className:"mb-4",children:(0,l.jsx)(z.Z,{name:"user_id",className:"px-3 py-2 border rounded-md w-full"})})]}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(W.ZP,{htmlType:"submit",children:"Add member"})})]})})]})]})]})},eN=s(12968),eA=s(67951);async function eC(e,t,s,l){console.log("isLocal:",!1);let r=window.location.origin,n=new eN.ZP.OpenAI({apiKey:l,baseURL:r,dangerouslyAllowBrowser:!0});for await(let l of(await n.chat.completions.create({model:s,stream:!0,messages:[{role:"user",content:e}]})))console.log(l),l.choices[0].delta.content&&t(l.choices[0].delta.content)}var eT=e=>{let{accessToken:t,token:s,userRole:n,userID:a}=e,[o,i]=(0,r.useState)(""),[c,d]=(0,r.useState)([]),[h,m]=(0,r.useState)(void 0),[u,x]=(0,r.useState)(null);(0,r.useEffect)(()=>{t&&s&&n&&a&&(async()=>{let e=await y(t,a,n);console.log("model_info:",e),(null==e?void 0:e.data.length)>0&&(x(e.data),m(e.data[0].id))})()},[t,a,n]);let p=(e,t)=>{d(s=>{let l=s[s.length-1];return l&&l.role===e?[...s.slice(0,s.length-1),{role:e,content:l.content+t}]:[...s,{role:e,content:t}]})},j=async()=>{if(""!==o.trim()&&t&&s&&n&&a){d(e=>[...e,{role:"user",content:o}]);try{h&&await eC(o,e=>p("assistant",e),h,t)}catch(e){console.error("Error fetching model response",e),p("assistant","Error fetching model response")}i("")}};if(n&&"Admin Viewer"==n){let{Title:e,Paragraph:t}=ea.default;return(0,l.jsxs)("div",{children:[(0,l.jsx)(e,{level:1,children:"Access Denied"}),(0,l.jsx)(t,{children:"Ask your proxy admin for access to test models"})]})}return(0,l.jsx)("div",{style:{width:"100%",position:"relative"},children:(0,l.jsx)(O.Z,{className:"gap-2 p-10 h-[75vh] w-full",children:(0,l.jsx)(M.Z,{children:(0,l.jsxs)(ey.Z,{children:[(0,l.jsxs)(eg.Z,{className:"mt-4",children:[(0,l.jsx)(ej.Z,{children:"Chat"}),(0,l.jsx)(ej.Z,{children:"API Reference"})]}),(0,l.jsxs)(eZ.Z,{children:[(0,l.jsxs)(ew.Z,{children:[(0,l.jsxs)("div",{children:[(0,l.jsx)("label",{children:"Select Model:"}),(0,l.jsx)("select",{value:h||"",onChange:e=>m(e.target.value),children:null==u?void 0:u.map(e=>(0,l.jsx)("option",{value:e.id,children:e.id},e.id))})]}),(0,l.jsxs)($.Z,{className:"mt-5",style:{display:"block",maxHeight:"60vh",overflowY:"auto"},children:[(0,l.jsx)(X.Z,{children:(0,l.jsx)(ee.Z,{children:(0,l.jsx)(Y.Z,{children:(0,l.jsx)(D.Z,{children:"Chat"})})})}),(0,l.jsx)(H.Z,{children:c.map((e,t)=>(0,l.jsx)(ee.Z,{children:(0,l.jsx)(Y.Z,{children:"".concat(e.role,": ").concat(e.content)})},t))})]}),(0,l.jsx)("div",{className:"mt-3",style:{position:"absolute",bottom:5,width:"95%"},children:(0,l.jsxs)("div",{className:"flex",children:[(0,l.jsx)("input",{type:"text",value:o,onChange:e=>i(e.target.value),className:"flex-1 p-2 border rounded-md mr-2",placeholder:"Type your message..."}),(0,l.jsx)("button",{onClick:j,className:"p-2 bg-blue-500 text-white rounded-md",children:"Send"})]})})]}),(0,l.jsx)(ew.Z,{children:(0,l.jsxs)(ey.Z,{children:[(0,l.jsxs)(eg.Z,{children:[(0,l.jsx)(ej.Z,{children:"OpenAI Python SDK"}),(0,l.jsx)(ej.Z,{children:"LlamaIndex"}),(0,l.jsx)(ej.Z,{children:"Langchain Py"})]}),(0,l.jsxs)(eZ.Z,{children:[(0,l.jsx)(ew.Z,{children:(0,l.jsx)(eA.Z,{language:"python",children:'\nimport openai\nclient = openai.OpenAI(\n api_key="your_api_key",\n base_url="http://0.0.0.0:4000" # proxy base url\n)\n\nresponse = client.chat.completions.create(\n model="gpt-3.5-turbo", # model to use from Models Tab\n messages = [\n {\n "role": "user",\n "content": "this is a test request, write a short poem"\n }\n ],\n extra_body={\n "metadata": {\n "generation_name": "ishaan-generation-openai-client",\n "generation_id": "openai-client-gen-id22",\n "trace_id": "openai-client-trace-id22",\n "trace_user_id": "openai-client-user-id2"\n }\n }\n)\n\nprint(response)\n '})}),(0,l.jsx)(ew.Z,{children:(0,l.jsx)(eA.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="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,l.jsx)(ew.Z,{children:(0,l.jsx)(eA.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:8000",\n model = "gpt-3.5-turbo",\n temperature=0.1,\n extra_body={\n "metadata": {\n "generation_name": "ishaan-generation-langchain-client",\n "generation_id": "langchain-client-gen-id22",\n "trace_id": "langchain-client-trace-id22",\n "trace_user_id": "langchain-client-user-id2"\n }\n }\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 '})})]})]})})]})]})})})})},eI=s(33509),eP=s(30569);let{Sider:eE}=eI.default;var eF=e=>{let{setPage:t,userRole:s,defaultSelectedKey:r}=e;return"Admin Viewer"==s?(0,l.jsx)(eI.default,{style:{minHeight:"100vh",maxWidth:"120px"},children:(0,l.jsx)(eE,{width:120,children:(0,l.jsxs)(eP.Z,{mode:"inline",defaultSelectedKeys:r||["4"],style:{height:"100%",borderRight:0},children:[(0,l.jsx)(eP.Z.Item,{onClick:()=>t("api-keys"),children:"API Keys"},"4"),(0,l.jsx)(eP.Z.Item,{onClick:()=>t("models"),children:"Models"},"2"),(0,l.jsx)(eP.Z.Item,{onClick:()=>t("llm-playground"),children:"Chat UI"},"3"),(0,l.jsx)(eP.Z.Item,{onClick:()=>t("usage"),children:"Usage"},"1")]})})}):(0,l.jsx)(eI.default,{style:{minHeight:"100vh",maxWidth:"120px"},children:(0,l.jsx)(eE,{width:120,children:(0,l.jsxs)(eP.Z,{mode:"inline",defaultSelectedKeys:r||["1"],style:{height:"100%",borderRight:0},children:[(0,l.jsx)(eP.Z.Item,{onClick:()=>t("api-keys"),children:"API Keys"},"1"),(0,l.jsx)(eP.Z.Item,{onClick:()=>t("models"),children:"Models"},"2"),(0,l.jsx)(eP.Z.Item,{onClick:()=>t("llm-playground"),children:"Chat UI"},"3"),(0,l.jsx)(eP.Z.Item,{onClick:()=>t("usage"),children:"Usage"},"4"),"Admin"==s?(0,l.jsx)(eP.Z.Item,{onClick:()=>t("users"),children:"Users"},"5"):null,"Admin"==s?(0,l.jsx)(eP.Z.Item,{onClick:()=>t("teams"),children:"Teams"},"6"):null,"Admin"==s?(0,l.jsx)(eP.Z.Item,{onClick:()=>t("admin-panel"),children:"Admin"},"7"):null]})})})},eO=e=>{let{accessToken:t,token:s,userRole:n,userID:a}=e,o=new Date,[i,c]=(0,r.useState)([]),[d,h]=(0,r.useState)([]),[m,u]=(0,r.useState)([]),[x,p]=(0,r.useState)([]),[j,y]=(0,r.useState)([]),[g,_]=(0,r.useState)([]),[S,N]=(0,r.useState)([]),A=new Date(o.getFullYear(),o.getMonth(),1),C=new Date(o.getFullYear(),o.getMonth()+1,0),T=P(A),I=P(C);function P(e){let t=e.getFullYear(),s=e.getMonth()+1,l=e.getDate();return"".concat(t,"-").concat(s<10?"0"+s:s,"-").concat(l<10?"0"+l:l)}return console.log("Start date is ".concat(T)),console.log("End date is ".concat(I)),(0,r.useEffect)(()=>{t&&s&&n&&a&&(async()=>{try{if(console.log("user role: ".concat(n)),"Admin"==n||"Admin Viewer"==n){let e=await f(t);c(e);let s=(await k(t)).map(e=>({key:(e.key_name||e.key_alias||e.api_key).substring(0,7),spend:e.total_spend}));h(s);let l=(await b(t)).map(e=>({key:e.model,spend:e.total_spend}));u(l);let r=await w(t);console.log("teamSpend",r),y(r.daily_spend),_(r.teams),N(r.total_spend_per_team)}else"App Owner"==n&&await Z(t,s,n,a,T,I).then(async e=>{if(console.log("result from spend logs call",e),"daily_spend"in e){let t=e.daily_spend;console.log("daily spend",t),c(t);let s=e.top_api_keys;h(s)}else{let s=(await v(t,function(e){let t=[];e.forEach(e=>{Object.entries(e).forEach(e=>{let[s,l]=e;"spend"!==s&&"startTime"!==s&&"models"!==s&&"users"!==s&&t.push({key:s,spend:l})})}),t.sort((e,t)=>Number(t.spend)-Number(e.spend));let s=t.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||e.token).substring(0,7),spend:e.spend}));h(s),p(function(e){let t={};e.forEach(e=>{Object.entries(e.users).forEach(e=>{let[s,l]=e;""!==s&&null!=s&&"None"!=s&&(t[s]||(t[s]=0),t[s]+=l)})});let s=Object.entries(t).map(e=>{let[t,s]=e;return{user_id:t,spend:s}});s.sort((e,t)=>t.spend-e.spend);let l=s.slice(0,5);return console.log("topKeys: ".concat(Object.values(l[0]))),l}(e)),c(e)}})}catch(e){console.error("There was an error fetching the data",e)}})()},[t,s,n,a,T,I]),(0,l.jsx)("div",{style:{width:"100%"},children:(0,l.jsxs)(ey.Z,{children:[(0,l.jsxs)(eg.Z,{className:"mt-4",children:[(0,l.jsx)(ej.Z,{children:"All Up"}),(0,l.jsx)(ej.Z,{children:"Team Based Usage"})]}),(0,l.jsxs)(eZ.Z,{children:[(0,l.jsx)(ew.Z,{children:(0,l.jsxs)(O.Z,{numItems:2,className:"gap-2 p-10 h-[75vh] w-full",children:[(0,l.jsx)(F.Z,{numColSpan:2,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Monthly Spend"}),(0,l.jsx)(et.Z,{data:i,index:"date",categories:["spend"],colors:["blue"],valueFormatter:e=>"$ ".concat(new Intl.NumberFormat("us").format(e).toString()),yAxisWidth:100,tickGap:5})]})}),(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Top API Keys"}),(0,l.jsx)(et.Z,{className:"mt-4 h-40",data:d,index:"key",categories:["spend"],colors:["blue"],yAxisWidth:80,tickGap:5,layout:"vertical",showXAxis:!1,showLegend:!1})]})}),(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Top Users"}),(0,l.jsx)(et.Z,{className:"mt-4 h-40",data:x,index:"user_id",categories:["spend"],colors:["blue"],yAxisWidth:200,layout:"vertical",showXAxis:!1,showLegend:!1})]})}),(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Top Models"}),(0,l.jsx)(et.Z,{className:"mt-4 h-40",data:m,index:"key",categories:["spend"],colors:["blue"],yAxisWidth:200,layout:"vertical",showXAxis:!1,showLegend:!1})]})})]})}),(0,l.jsx)(ew.Z,{children:(0,l.jsxs)(O.Z,{numItems:2,className:"gap-2 p-10 h-[75vh] w-full",children:[(0,l.jsx)(F.Z,{numColSpan:2,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Daily Spend Per Team"}),(0,l.jsx)(et.Z,{className:"h-72",data:j,index:"date",categories:g,yAxisWidth:30,stack:!0})]})}),(0,l.jsx)(F.Z,{numColSpan:2,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Total Spend Per Team"}),(0,l.jsx)(et.Z,{className:"h-72",data:S,index:"team_id",categories:["total_spend"],yAxisWidth:30})]})})]})})]})]})})},eM=()=>{let{Title:e,Paragraph:t}=ea.default,[s,a]=(0,r.useState)(""),[o,c]=(0,r.useState)(null),[d,h]=(0,r.useState)(null),[m,u]=(0,r.useState)(null),[x,p]=(0,r.useState)(!0),j=(0,n.useSearchParams)(),y=j.get("userID"),g=j.get("token"),[w,Z]=(0,r.useState)("api-keys"),[f,k]=(0,r.useState)(null);return(0,r.useEffect)(()=>{if(g){let e=(0,ed.o)(g);if(e){if(console.log("Decoded token:",e),console.log("Decoded key:",e.key),k(e.key),e.user_role){let t=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"app_user":return"App User";default:return"Unknown Role"}}(e.user_role);console.log("Decoded user_role:",t),a(t),"Admin Viewer"==t&&Z("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?p("username_password"==e.login_method):console.log("User Email is not set ".concat(e))}}},[g]),(0,l.jsx)(r.Suspense,{fallback:(0,l.jsx)("div",{children:"Loading..."}),children:(0,l.jsxs)("div",{className:"flex flex-col min-h-screen",children:[(0,l.jsx)(i,{userID:y,userRole:s,userEmail:o,showSSOBanner:x}),(0,l.jsxs)("div",{className:"flex flex-1 overflow-auto",children:[(0,l.jsx)(eF,{setPage:Z,userRole:s,defaultSelectedKey:null}),"api-keys"==w?(0,l.jsx)(eh,{userID:y,userRole:s,teams:d,keys:m,setUserRole:a,userEmail:o,setUserEmail:c,setTeams:h,setKeys:u}):"models"==w?(0,l.jsx)(ep,{userID:y,userRole:s,token:g,accessToken:f}):"llm-playground"==w?(0,l.jsx)(eT,{userID:y,userRole:s,token:g,accessToken:f}):"users"==w?(0,l.jsx)(e_,{userID:y,userRole:s,token:g,keys:m,accessToken:f,setKeys:u}):"teams"==w?(0,l.jsx)(eb,{teams:d,setTeams:h,searchParams:j,accessToken:f,userID:y,userRole:s}):"admin-panel"==w?(0,l.jsx)(eS,{setTeams:h,searchParams:j,accessToken:f}):(0,l.jsx)(eO,{userID:y,userRole:s,token:g,accessToken:f})]})]})})}}},function(e){e.O(0,[730,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 c3784800b..acaf479cc 100644 --- a/litellm/proxy/_experimental/out/index.html +++ b/litellm/proxy/_experimental/out/index.html @@ -1 +1 @@ -🚅 LiteLLM \ No newline at end of file +🚅 LiteLLM \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/index.txt b/litellm/proxy/_experimental/out/index.txt index c63474e28..90aef107e 100644 --- a/litellm/proxy/_experimental/out/index.txt +++ b/litellm/proxy/_experimental/out/index.txt @@ -1,7 +1,7 @@ 2:I[77831,[],""] -3:I[92182,["730","static/chunks/730-1411b729a1c79695.js","931","static/chunks/app/page-a94f48a4c941dbe4.js"],""] +3:I[92182,["730","static/chunks/730-1411b729a1c79695.js","931","static/chunks/app/page-07e952a07a29317d.js"],""] 4:I[5613,[],""] 5:I[31778,[],""] -0:["IXxGmLpL0ryrAsqCmdljD",[[["",{"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_c23dc8","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/68a21c6e6697f7ca.css","precedence":"next","crossOrigin":""}]],"$L6"]]]] +0:["1uJOwOGpazhj7AOlXoDnP",[[["",{"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_c23dc8","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/68a21c6e6697f7ca.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"}],["$","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 3e5ac000f..b2750f037 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

404

This page could not be found.

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

404

This page could not be found.

\ No newline at end of file diff --git a/ui/litellm-dashboard/out/_next/static/IXxGmLpL0ryrAsqCmdljD/_buildManifest.js b/ui/litellm-dashboard/out/_next/static/1uJOwOGpazhj7AOlXoDnP/_buildManifest.js similarity index 100% rename from ui/litellm-dashboard/out/_next/static/IXxGmLpL0ryrAsqCmdljD/_buildManifest.js rename to ui/litellm-dashboard/out/_next/static/1uJOwOGpazhj7AOlXoDnP/_buildManifest.js diff --git a/ui/litellm-dashboard/out/_next/static/IXxGmLpL0ryrAsqCmdljD/_ssgManifest.js b/ui/litellm-dashboard/out/_next/static/1uJOwOGpazhj7AOlXoDnP/_ssgManifest.js similarity index 100% rename from ui/litellm-dashboard/out/_next/static/IXxGmLpL0ryrAsqCmdljD/_ssgManifest.js rename to ui/litellm-dashboard/out/_next/static/1uJOwOGpazhj7AOlXoDnP/_ssgManifest.js diff --git a/ui/litellm-dashboard/out/_next/static/chunks/app/page-07e952a07a29317d.js b/ui/litellm-dashboard/out/_next/static/chunks/app/page-07e952a07a29317d.js new file mode 100644 index 000000000..3baff4770 --- /dev/null +++ b/ui/litellm-dashboard/out/_next/static/chunks/app/page-07e952a07a29317d.js @@ -0,0 +1 @@ +(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[931],{20661:function(e,t,s){Promise.resolve().then(s.bind(s,92182))},92182:function(e,t,s){"use strict";s.r(t),s.d(t,{default:function(){return eM}});var l=s(3827),r=s(64090),a=s(47907),n=s(8792),o=s(2179),i=e=>{let{userID:t,userRole:s,userEmail:r,showSSOBanner:a}=e;return console.log("User ID:",t),console.log("userEmail:",r),(0,l.jsxs)("nav",{className:"left-0 right-0 top-0 flex justify-between items-center h-12 mb-4",children:[(0,l.jsx)("div",{className:"text-left my-2 absolute top-0 left-0",children:(0,l.jsx)("div",{className:"flex flex-col items-center",children:(0,l.jsx)(n.default,{href:"/",children:(0,l.jsx)("button",{className:"text-gray-800 text-2xl py-1 rounded text-center",children:(0,l.jsx)("img",{src:"/get_image",width:200,height:200,alt:"LiteLLM Brand",className:"mr-2"})})})})}),(0,l.jsxs)("div",{className:"text-right mx-4 my-2 absolute top-0 right-0 flex items-center justify-end space-x-2",children:[a?(0,l.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/ui#setup-ssoauth-for-ui",target:"_blank",className:"mr-2"}):null,(0,l.jsxs)(o.Z,{variant:"secondary",size:"lg",children:[r,(0,l.jsxs)("p",{children:["Role: ",s]}),(0,l.jsxs)("p",{children:["ID: ",t]})]})]})]})},c=s(80588);let d=async(e,t,s)=>{try{if(console.log("Form Values in keyCreateCall:",s),s.description&&(s.metadata||(s.metadata={}),s.metadata.description=s.description,delete s.description,s.metadata=JSON.stringify(s.metadata)),s.metadata){console.log("formValues.metadata:",s.metadata);try{s.metadata=JSON.parse(s.metadata)}catch(e){throw c.ZP.error("Failed to parse metadata: "+e),Error("Failed to parse metadata: "+e)}}console.log("Form Values after check:",s);let l=await fetch("/key/generate",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({user_id:t,...s})});if(!l.ok){let e=await l.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let r=await l.json();return console.log("API Response:",r),r}catch(e){throw console.error("Failed to create key:",e),e}},h=async(e,t,s)=>{try{if(console.log("Form Values in keyCreateCall:",s),s.description&&(s.metadata||(s.metadata={}),s.metadata.description=s.description,delete s.description,s.metadata=JSON.stringify(s.metadata)),s.metadata){console.log("formValues.metadata:",s.metadata);try{s.metadata=JSON.parse(s.metadata)}catch(e){throw c.ZP.error("Failed to parse metadata: "+e),Error("Failed to parse metadata: "+e)}}console.log("Form Values after check:",s);let l=await fetch("/user/new",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({user_id:t,...s})});if(!l.ok){let e=await l.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let r=await l.json();return console.log("API Response:",r),r}catch(e){throw console.error("Failed to create key:",e),e}},m=async(e,t)=>{try{console.log("in keyDeleteCall:",t);let s=await fetch("/key/delete",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({keys:[t]})});if(!s.ok){let e=await s.text();throw c.ZP.error("Failed to delete key: "+e),Error("Network response was not ok")}let l=await s.json();return console.log(l),l}catch(e){throw console.error("Failed to create key:",e),e}},u=async function(e,t,s){let l=arguments.length>3&&void 0!==arguments[3]&&arguments[3];try{let r="/user/info";"App Owner"==s&&t&&(r="".concat(r,"?user_id=").concat(t)),console.log("in userInfoCall viewAll=",l),l&&(r="".concat(r,"?view_all=true"));let a=await fetch(r,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!a.ok){let e=await a.text();throw c.ZP.error(e),Error("Network response was not ok")}let n=await a.json();return console.log("API Response:",n),n}catch(e){throw console.error("Failed to create key:",e),e}},x=async e=>{try{let t=await fetch("/global/spend",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},p=async(e,t,s)=>{try{let t=await fetch("/v2/model/info",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},j=async(e,t,s)=>{try{let t=await fetch("/model/metrics",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},y=async(e,t,s)=>{try{let t=await fetch("/models",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},g=async(e,t)=>{try{let s="/global/spend/logs";console.log("in keySpendLogsCall:",s);let l=await fetch("".concat(s,"?api_key=").concat(t),{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw c.ZP.error(e),Error("Network response was not ok")}let r=await l.json();return console.log(r),r}catch(e){throw console.error("Failed to create key:",e),e}},w=async e=>{try{let t="/global/spend/teams";console.log("in teamSpendLogsCall:",t);let s=await fetch("".concat(t),{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!s.ok){let e=await s.text();throw c.ZP.error(e),Error("Network response was not ok")}let l=await s.json();return console.log(l),l}catch(e){throw console.error("Failed to create key:",e),e}},Z=async(e,t,s,l,r,a)=>{try{console.log("user role in spend logs call: ".concat(s));let t="/spend/logs";t="App Owner"==s?"".concat(t,"?user_id=").concat(l,"&start_date=").concat(r,"&end_date=").concat(a):"".concat(t,"?start_date=").concat(r,"&end_date=").concat(a);let n=await fetch(t,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!n.ok){let e=await n.text();throw c.ZP.error(e),Error("Network response was not ok")}let o=await n.json();return console.log(o),o}catch(e){throw console.error("Failed to create key:",e),e}},f=async e=>{try{let t=await fetch("/global/spend/logs",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to create key:",e),e}},k=async e=>{try{let t=await fetch("/global/spend/keys?limit=5",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to create key:",e),e}},_=async(e,t)=>{try{t&&JSON.stringify({api_key:t});let s={method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}};t&&(s.body=JSON.stringify({api_key:t}));let l=await fetch("/global/spend/end_users",s);if(!l.ok){let e=await l.text();throw c.ZP.error(e),Error("Network response was not ok")}let r=await l.json();return console.log(r),r}catch(e){throw console.error("Failed to create key:",e),e}},b=async e=>{try{let t=await fetch("/global/spend/models?limit=5",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to create key:",e),e}},v=async(e,t)=>{try{let s=await fetch("/v2/key/info",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({keys:t})});if(!s.ok){let e=await s.text();throw c.ZP.error(e),Error("Network response was not ok")}let l=await s.json();return console.log(l),l}catch(e){throw console.error("Failed to create key:",e),e}},S=async(e,t,s,l)=>{try{let r=await fetch("/user/request_model",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({models:[t],user_id:s,justification:l})});if(!r.ok){let e=await r.text();throw c.ZP.error("Failed to delete key: "+e),Error("Network response was not ok")}let a=await r.json();return console.log(a),a}catch(e){throw console.error("Failed to create key:",e),e}},N=async e=>{try{let t="/user/get_requests";console.log("in userGetRequesedtModelsCall:",t);let s=await fetch(t,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!s.ok){let e=await s.text();throw c.ZP.error("Failed to delete key: "+e),Error("Network response was not ok")}let l=await s.json();return console.log(l),l}catch(e){throw console.error("Failed to get requested models:",e),e}},A=async(e,t)=>{try{let s="/user/get_users?role=".concat(t);console.log("in userGetAllUsersCall:",s);let l=await fetch(s,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw c.ZP.error("Failed to delete key: "+e),Error("Network response was not ok")}let r=await l.json();return console.log(r),r}catch(e){throw console.error("Failed to get requested models:",e),e}},C=async(e,t)=>{try{console.log("Form Values in teamCreateCall:",t);let s=await fetch("/team/new",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...t})});if(!s.ok){let e=await s.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let l=await s.json();return console.log("API Response:",l),l}catch(e){throw console.error("Failed to create key:",e),e}},T=async(e,t,s)=>{try{console.log("Form Values in teamMemberAddCall:",s);let l=await fetch("/team/member_add",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({team_id:t,member:s})});if(!l.ok){let e=await l.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let r=await l.json();return console.log("API Response:",r),r}catch(e){throw console.error("Failed to create key:",e),e}},I=async(e,t)=>{try{console.log("Form Values in userUpdateUserCall:",t);let s=await fetch("/user/update",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({user_role:"proxy_admin_viewer",...t})});if(!s.ok){let e=await s.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let l=await s.json();return console.log("API Response:",l),l}catch(e){throw console.error("Failed to create key:",e),e}},E=async(e,t)=>{try{let s=await fetch("/global/predict/spend/logs",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({data:t})});if(!s.ok){let e=await s.text();throw c.ZP.error(e),Error("Network response was not ok")}let l=await s.json();return console.log(l),l}catch(e){throw console.error("Failed to create key:",e),e}},P=async e=>{try{console.log("Checking Slack Budget Alerts service health");let t=await fetch("/health/services?service=slack_budget_alerts",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error("Failed Slack Alert test: "+e),Error(e)}let s=await t.json();return c.ZP.success("Test Slack Alert worked - check your Slack!"),console.log("Service Health Response:",s),s}catch(e){throw console.error("Failed to perform health check:",e),e}};var F=s(10384),O=s(46453),M=s(13810),R=s(71801),D=s(42440),U=s(17189),L=s(12143),B=s(77171),z=s(42539),K=s(88707),W=s(1861);let{Option:V}=U.default;var q=e=>{let{userID:t,team:s,userRole:a,accessToken:n,data:i,setData:h}=e,[m]=L.Z.useForm(),[u,x]=(0,r.useState)(!1),[p,j]=(0,r.useState)(null),[g,w]=(0,r.useState)(null),[Z,f]=(0,r.useState)([]),k=()=>{x(!1),m.resetFields()},_=()=>{x(!1),j(null),m.resetFields()};(0,r.useEffect)(()=>{(async()=>{try{if(null===t||null===a)return;if(null!==n){let e=(await y(n,t,a)).data.map(e=>e.id);console.log("available_model_names:",e),f(e)}}catch(e){console.error("Error fetching user models:",e)}})()},[n,t,a]);let b=async e=>{try{c.ZP.info("Making API Call"),x(!0);let s=await d(n,t,e);console.log("key create Response:",s),h(e=>e?[...e,s]:[s]),j(s.key),w(s.soft_budget),c.ZP.success("API Key Created"),m.resetFields(),localStorage.removeItem("userData"+t)}catch(e){console.error("Error creating the key:",e)}},v=async()=>{try{console.log("Sending Slack alert...");let e=await P(n);console.log("slackBudgetAlertsHealthCheck Response:",e),console.log("Testing Slack alert successful")}catch(e){console.error("Error sending Slack alert:",e)}};return(0,l.jsxs)("div",{children:[(0,l.jsx)(o.Z,{className:"mx-auto",onClick:()=>x(!0),children:"+ Create New Key"}),(0,l.jsx)(B.Z,{title:"Create Key",visible:u,width:800,footer:null,onOk:k,onCancel:_,children:(0,l.jsxs)(L.Z,{form:m,onFinish:b,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:["App Owner"===a||"Admin"===a?(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(L.Z.Item,{label:"Key Name",name:"key_alias",children:(0,l.jsx)(z.Z,{})}),(0,l.jsx)(L.Z.Item,{label:"Team ID",name:"team_id",children:(0,l.jsx)(z.Z,{placeholder:"ai_team",defaultValue:s&&s.team_alias?s.team_alias:"",disabled:!0})}),(0,l.jsx)(L.Z.Item,{label:"Models",name:"models",children:(0,l.jsx)(U.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:Z.map(e=>(0,l.jsx)(V,{value:e,children:e},e))})}),(0,l.jsx)(L.Z.Item,{label:"Soft Budget (USD) Monthly",name:"soft_budget",initialValue:50,children:(0,l.jsx)(K.Z,{step:.01,precision:2,defaultValue:50,width:200})}),(0,l.jsx)(L.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,l.jsx)(K.Z,{step:.01,precision:2,width:200})}),(0,l.jsx)(L.Z.Item,{label:"Reset Budget",name:"budget_duration",children:(0,l.jsxs)(U.default,{defaultValue:null,placeholder:"n/a",children:[(0,l.jsx)(U.default.Option,{value:"24h",children:"daily"}),(0,l.jsx)(U.default.Option,{value:"30d",children:"monthly"})]})}),(0,l.jsx)(L.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})}),(0,l.jsx)(L.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})}),(0,l.jsx)(L.Z.Item,{label:"Expire Key (eg: 30s, 30h, 30d)",name:"duration",children:(0,l.jsx)(z.Z,{})}),(0,l.jsx)(L.Z.Item,{label:"Metadata",name:"metadata",children:(0,l.jsx)(z.Z.TextArea,{rows:4,placeholder:"Enter metadata as JSON"})})]}):(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(L.Z.Item,{label:"Key Name",name:"key_alias",children:(0,l.jsx)(z.Z,{})}),(0,l.jsx)(L.Z.Item,{label:"Team ID (Contact Group)",name:"team_id",children:(0,l.jsx)(z.Z,{placeholder:"ai_team"})}),(0,l.jsx)(L.Z.Item,{label:"Description",name:"description",children:(0,l.jsx)(z.Z.TextArea,{placeholder:"Enter description",rows:4})})]}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(W.ZP,{htmlType:"submit",children:"Create Key"})})]})}),p&&(0,l.jsx)(B.Z,{visible:u,onOk:k,onCancel:_,footer:null,children:(0,l.jsx)(O.Z,{numItems:1,className:"gap-2 w-full",children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Save your Key"}),(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsxs)("p",{children:["Please save this secret key somewhere safe and accessible. For security reasons, ",(0,l.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,l.jsx)(F.Z,{numColSpan:1,children:null!=p?(0,l.jsxs)("div",{children:[(0,l.jsxs)(R.Z,{children:["API Key: ",p]}),(0,l.jsx)(D.Z,{className:"mt-6",children:"Budgets"}),(0,l.jsxs)(R.Z,{children:["Soft Limit Budget: $",g]}),(0,l.jsx)(o.Z,{className:"mt-3",onClick:v,children:"Test Slack Alert"}),(0,l.jsxs)(R.Z,{className:"mt-2",children:["(LiteLLM Docs -",(0,l.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/alerting",target:"_blank",className:"text-blue-500",children:"Set Up Slack Alerting)"})]})]}):(0,l.jsx)(R.Z,{children:"Key being created, this might take 30s"})})]})})})]})},J=s(33393),G=s(61244),$=s(10827),H=s(3851),Y=s(2044),X=s(64167),Q=s(74480),ee=s(7178),et=s(9853),es=s(56863),el=e=>{let{token:t,accessToken:s,keySpend:a,keyBudget:n,keyName:i}=e,[c,d]=(0,r.useState)(!1),[h,m]=(0,r.useState)(null),[u,x]=(0,r.useState)(""),[p,j]=(0,r.useState)(null),y=async()=>{try{if(null==s||null==t)return;console.log("accessToken: ".concat(s,"; token: ").concat(t));let e=await g(s,t);console.log("Response:",e),m(e);let l=await E(s,e);console.log("Response2:",l);let r=[...e,...l.response];m(r),x(l.predicted_spend),console.log("Combined Data:",r)}catch(e){console.error("There was an error fetching the data",e)}};return t?(0,l.jsxs)("div",{children:[(0,l.jsx)(o.Z,{size:"xs",onClick:()=>{console.log("Show Modal triggered"),d(!0),y()},variant:"secondary",children:"Spend Report"}),(0,l.jsxs)(B.Z,{visible:c,width:1400,onOk:()=>{d(!1)},onCancel:()=>{d(!1)},footer:null,children:[(0,l.jsxs)(D.Z,{style:{textAlign:"left"},children:["Key Name: ",i]}),(0,l.jsxs)(es.Z,{children:["Monthly Spend $",a]}),(0,l.jsx)(D.Z,{children:u}),(0,l.jsx)(M.Z,{className:"mt-6 mb-6",children:h&&(0,l.jsx)(et.Z,{className:"mt-6",data:h,colors:["blue","amber"],index:"date",categories:["spend","predicted_spend"],yAxisWidth:80})})]})]}):null},er=e=>{let{userID:t,accessToken:s,data:a,setData:n}=e,[i,c]=(0,r.useState)(!1),[d,h]=(0,r.useState)(!1),[u,x]=(0,r.useState)(null),p=async e=>{null!=a&&(x(e),localStorage.removeItem("userData"+t),h(!0))},j=async()=>{if(null!=u&&null!=a){try{await m(s,u);let e=a.filter(e=>e.token!==u);n(e)}catch(e){console.error("Error deleting the key:",e)}h(!1),x(null)}};if(null!=a)return console.log("RERENDER TRIGGERED"),(0,l.jsxs)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh] mb-4",children:[(0,l.jsxs)($.Z,{className:"mt-5",children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"Key Alias"}),(0,l.jsx)(Q.Z,{children:"Secret Key"}),(0,l.jsx)(Q.Z,{children:"Spend (USD)"}),(0,l.jsx)(Q.Z,{children:"Key Budget (USD)"}),(0,l.jsx)(Q.Z,{children:"Spend Report"}),(0,l.jsx)(Q.Z,{children:"Team ID"}),(0,l.jsx)(Q.Z,{children:"Metadata"}),(0,l.jsx)(Q.Z,{children:"Models"}),(0,l.jsx)(Q.Z,{children:"TPM / RPM Limits"}),(0,l.jsx)(Q.Z,{children:"Expires"})]})}),(0,l.jsx)(H.Z,{children:a.map(e=>(console.log(e),"litellm-dashboard"===e.team_id)?null:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",whiteSpace:"pre-wrap",overflow:"hidden"},children:null!=e.key_alias?(0,l.jsx)(R.Z,{children:e.key_alias}):(0,l.jsx)(R.Z,{children:"Not Set"})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:e.key_name})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:(()=>{try{return parseFloat(e.spend).toFixed(4)}catch(t){return e.spend}})()})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",whiteSpace:"pre-wrap",overflow:"hidden"},children:null!=e.max_budget?(0,l.jsx)(R.Z,{children:e.max_budget}):(0,l.jsx)(R.Z,{children:"Unlimited Budget"})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px"},children:(0,l.jsx)(el,{token:e.token,accessToken:s,keySpend:e.spend,keyBudget:e.max_budget,keyName:e.key_name})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:e.team_id})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:JSON.stringify(e.metadata).slice(0,400)})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:JSON.stringify(e.models)})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",overflowWrap:"break-word"},children:(0,l.jsxs)(R.Z,{children:["TPM Limit: ",e.tpm_limit?e.tpm_limit:"Unlimited"," ",(0,l.jsx)("br",{})," RPM Limit:"," ",e.rpm_limit?e.rpm_limit:"Unlimited"]})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",wordWrap:"break-word"},children:null!=e.expires?(0,l.jsx)(R.Z,{children:e.expires}):(0,l.jsx)(R.Z,{children:"Never"})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",wordWrap:"break-word"},children:(0,l.jsx)(G.Z,{onClick:()=>p(e.token),icon:J.Z,size:"sm"})})]},e.token))})]}),d&&(0,l.jsx)("div",{className:"fixed z-10 inset-0 overflow-y-auto",children:(0,l.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,l.jsx)("div",{className:"fixed inset-0 transition-opacity","aria-hidden":"true",children:(0,l.jsx)("div",{className:"absolute inset-0 bg-gray-500 opacity-75"})}),(0,l.jsx)("span",{className:"hidden sm:inline-block sm:align-middle sm:h-screen","aria-hidden":"true",children:"​"}),(0,l.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,l.jsx)("div",{className:"bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4",children:(0,l.jsx)("div",{className:"sm:flex sm:items-start",children:(0,l.jsxs)("div",{className:"mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left",children:[(0,l.jsx)("h3",{className:"text-lg leading-6 font-medium text-gray-900",children:"Delete Key"}),(0,l.jsx)("div",{className:"mt-2",children:(0,l.jsx)("p",{className:"text-sm text-gray-500",children:"Are you sure you want to delete this key ?"})})]})})}),(0,l.jsxs)("div",{className:"bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse",children:[(0,l.jsx)(o.Z,{onClick:j,color:"red",className:"ml-2",children:"Delete"}),(0,l.jsx)(o.Z,{onClick:()=>{h(!1),x(null)},children:"Cancel"})]})]})]})})]})},ea=e=>{let{userID:t,userSpendData:s,userRole:a,accessToken:n}=e,[o,i]=(0,r.useState)(null==s?void 0:s.spend),[c,d]=(0,r.useState)((null==s?void 0:s.max_budget)||null);(0,r.useEffect)(()=>{(async()=>{if("Admin"===a)try{let e=await x(n);i(e.spend),d(e.max_budget||null)}catch(e){console.error("Error fetching global spend data:",e)}})()},[a,n]);let h=void 0!==o?o.toFixed(4):null;return(0,l.jsx)(l.Fragment,{children:(0,l.jsxs)(M.Z,{className:"mx-auto mb-4",children:[(0,l.jsxs)(es.Z,{children:["$",h]}),(0,l.jsxs)(D.Z,{children:["/ ",null!==c?"$".concat(c," limit"):"No limit"]})]})})},en=s(36083),eo=s(68967),ei=s(27166),ec=e=>{let{teams:t,setSelectedTeam:s}=e,{Title:a,Paragraph:n}=en.default,[o,i]=(0,r.useState)("");return(0,l.jsxs)("div",{className:"mt-10",children:[(0,l.jsx)(a,{level:4,children:"Default Team"}),(0,l.jsx)(n,{children:"If you belong to multiple teams, this setting controls which team is used by default when creating new API Keys."}),t&&t.length>0?(0,l.jsx)(eo.Z,{defaultValue:"0",children:t.map((e,t)=>(0,l.jsx)(ei.Z,{value:String(t),onClick:()=>s(e),children:e.team_alias},t))}):(0,l.jsxs)(n,{children:["No team created. ",(0,l.jsx)("b",{children:"Defaulting to personal account."})]})]})},ed=s(37963);console.log("isLocal:",!1);var eh=e=>{let{userID:t,userRole:s,teams:n,keys:o,setUserRole:i,userEmail:c,setUserEmail:d,setTeams:h,setKeys:m}=e,[p,j]=(0,r.useState)(null),g=(0,a.useSearchParams)();g.get("viewSpend"),(0,a.useRouter)();let w=g.get("token"),[Z,f]=(0,r.useState)(null),[k,_]=(0,r.useState)([]),[b,v]=(0,r.useState)(n?n[0]:null);if(window.addEventListener("beforeunload",function(){sessionStorage.clear()}),(0,r.useEffect)(()=>{if(w){let e=(0,ed.o)(w);if(e){if(console.log("Decoded token:",e),console.log("Decoded key:",e.key),f(e.key),e.user_role){let t=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";default:return"Unknown Role"}}(e.user_role);console.log("Decoded user_role:",t),i(t)}else console.log("User role not defined");e.user_email?d(e.user_email):console.log("User Email is not set ".concat(e))}}if(t&&Z&&s&&!o&&!p){let e=sessionStorage.getItem("userModels"+t);e?_(JSON.parse(e)):(async()=>{try{let e=await u(Z,t,s);if(console.log("received teams in user dashboard: ".concat(Object.keys(e),"; team values: ").concat(Object.entries(e.teams))),"Admin"==s){let e=await x(Z);j(e),console.log("globalSpend:",e)}else j(e.user_info);m(e.keys),h(e.teams),v(e.teams?e.teams[0]:null),sessionStorage.setItem("userData"+t,JSON.stringify(e.keys)),sessionStorage.setItem("userSpendData"+t,JSON.stringify(e.user_info));let l=(await y(Z,t,s)).data.map(e=>e.id);console.log("available_model_names:",l),_(l),console.log("userModels:",k),sessionStorage.setItem("userModels"+t,JSON.stringify(l))}catch(e){console.error("There was an error fetching the data",e)}})()}},[t,w,Z,o,s]),null==t||null==w){let e="/sso/key/generate";return console.log("Full URL:",e),window.location.href=e,null}if(null==Z)return null;if(null==s&&i("App Owner"),s&&"Admin Viewer"==s){let{Title:e,Paragraph:t}=en.default;return(0,l.jsxs)("div",{children:[(0,l.jsx)(e,{level:1,children:"Access Denied"}),(0,l.jsx)(t,{children:"Ask your proxy admin for access to create keys"})]})}return console.log("inside user dashboard, selected team",b),(0,l.jsx)("div",{children:(0,l.jsx)(O.Z,{numItems:1,className:"gap-0 p-10 h-[75vh] w-full",children:(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(ea,{userID:t,userSpendData:p,userRole:s,accessToken:Z}),(0,l.jsx)(er,{userID:t,accessToken:Z,data:o,setData:m}),(0,l.jsx)(q,{userID:t,team:b||null,userRole:s,accessToken:Z,data:o,setData:m},b?b.team_id:null),(0,l.jsx)(ec,{teams:n,setSelectedTeam:v})]})})})},em=s(5);let{Option:eu}=U.default;var ex=e=>{let{userModels:t,accessToken:s,userID:a}=e,[n]=L.Z.useForm(),[i,d]=(0,r.useState)(!1),h=async e=>{try{c.ZP.info("Requesting access");let{selectedModel:t,accessReason:l}=e;await S(s,t,a,l),d(!0)}catch(e){console.error("Error requesting access:",e)}};return(0,l.jsxs)("div",{children:[(0,l.jsx)(o.Z,{size:"xs",onClick:()=>d(!0),children:"Request Access"}),(0,l.jsx)(B.Z,{title:"Request Access",visible:i,width:800,footer:null,onOk:()=>{d(!1),n.resetFields()},onCancel:()=>{d(!1),n.resetFields()},children:(0,l.jsxs)(L.Z,{form:n,onFinish:h,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsx)(L.Z.Item,{label:"Select Model",name:"selectedModel",children:(0,l.jsx)(U.default,{placeholder:"Select model",style:{width:"100%"},children:t.map(e=>(0,l.jsx)(eu,{value:e,children:e},e))})}),(0,l.jsx)(L.Z.Item,{label:"Reason for Access",name:"accessReason",children:(0,l.jsx)(z.Z.TextArea,{rows:4,placeholder:"Enter reason for access"})}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(o.Z,{children:"Request Access"})})]})})]})},ep=e=>{let{accessToken:t,token:s,userRole:a,userID:n}=e,[o,i]=(0,r.useState)({data:[]}),[c,d]=(0,r.useState)([]),[h,m]=(0,r.useState)([]);if((0,r.useEffect)(()=>{if(!t||!s||!a||!n)return;let e=async()=>{try{let e=await p(t,n,a);console.log("Model data response:",e.data),i(e);let s=await j(t,n,a);if(console.log("Model metrics response:",s),d(s),"Admin"===a&&t){let e=await N(t);console.log("Pending Requests:",h),m(e.requests||[])}}catch(e){console.error("There was an error fetching the model data",e)}};t&&s&&a&&n&&e()},[t,s,a,n]),!o||!t||!s||!a||!n)return(0,l.jsx)("div",{children:"Loading..."});let u=[];for(let e=0;e(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{children:(0,l.jsx)(D.Z,{children:e.model_name})}),(0,l.jsx)(Y.Z,{children:e.provider}),"Admin"===a&&(0,l.jsx)(Y.Z,{children:e.api_base}),(0,l.jsx)(Y.Z,{children:e.user_access?(0,l.jsx)(em.Z,{color:"green",children:"Yes"}):(0,l.jsx)(ex,{userModels:u,accessToken:t,userID:n})}),(0,l.jsx)(Y.Z,{children:e.input_cost}),(0,l.jsx)(Y.Z,{children:e.output_cost}),(0,l.jsx)(Y.Z,{children:e.max_tokens})]},e.model_name))})]})}),(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Model Statistics (Number Requests)"}),(0,l.jsx)(et.Z,{data:c,index:"model",categories:["num_requests"],colors:["blue"],yAxisWidth:400,layout:"vertical",tickGap:5})]}),(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Model Statistics (Latency)"}),(0,l.jsx)(et.Z,{data:c,index:"model",categories:["avg_latency_seconds"],colors:["red"],yAxisWidth:400,layout:"vertical",tickGap:5})]})]})})},ej=s(92836),ey=s(26734),eg=s(41608),ew=s(32126),eZ=s(23682);let{Option:ef}=U.default;var ek=e=>{let{userID:t,accessToken:s}=e,[a]=L.Z.useForm(),[n,i]=(0,r.useState)(!1),[d,m]=(0,r.useState)(null),[u,x]=(0,r.useState)([]);(0,r.useEffect)(()=>{(async()=>{try{let e=await y(s,t,"any"),l=[];for(let t=0;t{i(!1),a.resetFields()},j=()=>{i(!1),m(null),a.resetFields()},g=async e=>{try{c.ZP.info("Making API Call"),i(!0),console.log("formValues in create user:",e);let l=await h(s,t,e);console.log("user create Response:",l),m(l.key),c.ZP.success("API user Created"),a.resetFields(),localStorage.removeItem("userData"+t)}catch(e){console.error("Error creating the user:",e)}};return(0,l.jsxs)("div",{children:[(0,l.jsx)(o.Z,{className:"mx-auto",onClick:()=>i(!0),children:"+ Create New User"}),(0,l.jsx)(B.Z,{title:"Create User",visible:n,width:800,footer:null,onOk:p,onCancel:j,children:(0,l.jsxs)(L.Z,{form:a,onFinish:g,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsx)(L.Z.Item,{label:"User ID",name:"user_id",children:(0,l.jsx)(z.Z,{placeholder:"Enter User ID"})}),(0,l.jsx)(L.Z.Item,{label:"Team ID",name:"team_id",children:(0,l.jsx)(z.Z,{placeholder:"ai_team"})}),(0,l.jsx)(L.Z.Item,{label:"Models",name:"models",children:(0,l.jsx)(U.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:u.map(e=>(0,l.jsx)(ef,{value:e,children:e},e))})}),(0,l.jsx)(L.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,l.jsx)(K.Z,{step:.01,precision:2,width:200})}),(0,l.jsx)(L.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})}),(0,l.jsx)(L.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})}),(0,l.jsx)(L.Z.Item,{label:"Duration (eg: 30s, 30h, 30d)",name:"duration",children:(0,l.jsx)(z.Z,{})}),(0,l.jsx)(L.Z.Item,{label:"Metadata",name:"metadata",children:(0,l.jsx)(z.Z.TextArea,{rows:4,placeholder:"Enter metadata as JSON"})}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(W.ZP,{htmlType:"submit",children:"Create User"})})]})}),d&&(0,l.jsxs)(B.Z,{title:"Save Your User",visible:n,onOk:p,onCancel:j,footer:null,children:[(0,l.jsxs)("p",{children:["Please save this secret user somewhere safe and accessible. For security reasons, ",(0,l.jsx)("b",{children:"you will not be able to view it again"})," ","through your LiteLLM account. If you lose this secret user, you will need to generate a new one."]}),(0,l.jsx)("p",{children:null!=d?"API user: ".concat(d):"User being created, this might take 30s"})]})]})},e_=e=>{let{accessToken:t,token:s,keys:a,userRole:n,userID:o,setKeys:i}=e,[c,d]=(0,r.useState)(null),[h,m]=(0,r.useState)(null),[x,p]=(0,r.useState)(1);if((0,r.useEffect)(()=>{if(!t||!s||!n||!o)return;let e=async()=>{try{let e=await u(t,null,n,!0);console.log("user data response:",e),d(e)}catch(e){console.error("There was an error fetching the model data",e)}};t&&s&&n&&o&&!c&&e();let l=async()=>{try{let e=await _(t,null);console.log("user data response:",e),m(e)}catch(e){console.error("There was an error fetching the model data",e)}};n&&("Admin"==n||"Admin Viewer"==n)&&!h&&l()},[t,s,n,o]),!c||!t||!s||!n||!o)return(0,l.jsx)("div",{children:"Loading..."});let j=async e=>{try{let s=await _(t,e);console.log("user data response:",s),m(s)}catch(e){console.error("There was an error fetching the model data",e)}};return(0,l.jsx)("div",{style:{width:"100%"},children:(0,l.jsxs)(O.Z,{className:"gap-2 p-10 h-[75vh] w-full",children:[(0,l.jsx)(ek,{userID:o,accessToken:t}),(0,l.jsx)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh] mb-4",children:(0,l.jsxs)(ey.Z,{children:[(0,l.jsxs)(eg.Z,{variant:"line",defaultValue:"1",children:[(0,l.jsx)(ej.Z,{value:"1",children:"Key Owners"}),(0,l.jsx)(ej.Z,{value:"2",children:"End-Users"})]}),(0,l.jsxs)(eZ.Z,{children:[(0,l.jsx)(ew.Z,{children:(0,l.jsxs)($.Z,{className:"mt-5",children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"User ID"}),(0,l.jsx)(Q.Z,{children:"User Role"}),(0,l.jsx)(Q.Z,{children:"User Models"}),(0,l.jsx)(Q.Z,{children:"User Spend ($ USD)"}),(0,l.jsx)(Q.Z,{children:"User Max Budget ($ USD)"})]})}),(0,l.jsx)(H.Z,{children:c.map(e=>(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{children:e.user_id}),(0,l.jsx)(Y.Z,{children:e.user_role?e.user_role:"app_owner"}),(0,l.jsx)(Y.Z,{children:e.models&&e.models.length>0?e.models:"All Models"}),(0,l.jsx)(Y.Z,{children:e.spend?e.spend:0}),(0,l.jsx)(Y.Z,{children:e.max_budget?e.max_budget:"Unlimited"})]},e.user_id))})]})}),(0,l.jsxs)(ew.Z,{children:[(0,l.jsxs)("div",{className:"flex items-center",children:[(0,l.jsx)("div",{className:"flex-1"}),(0,l.jsxs)("div",{className:"flex-1 flex justify-between items-center",children:[(0,l.jsx)(R.Z,{className:"w-1/4 mr-2 text-right",children:"Key"}),(0,l.jsx)(eo.Z,{defaultValue:"1",className:"w-3/4",children:null==a?void 0:a.map((e,t)=>{if(e&&null!==e.key_name&&e.key_name.length>0)return(0,l.jsx)(ei.Z,{value:String(t),onClick:()=>j(e.token),children:e.key_name},t)})})]})]}),(0,l.jsxs)($.Z,{children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"End User"}),(0,l.jsx)(Q.Z,{children:"Spend"}),(0,l.jsx)(Q.Z,{children:"Total Events"})]})}),(0,l.jsx)(H.Z,{children:null==h?void 0:h.map((e,t)=>(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{children:e.end_user}),(0,l.jsx)(Y.Z,{children:e.total_spend}),(0,l.jsx)(Y.Z,{children:e.total_events})]},t))})]})]})]})]})}),function(){if(!c)return null;let e=Math.ceil(c.length/25),t=Math.min(25*x,c.length);return(0,l.jsxs)("div",{className:"flex justify-between items-center",children:[(0,l.jsxs)("div",{children:["Showing ",(x-1)*25+1," – ",t," of ",c.length]}),(0,l.jsxs)("div",{className:"flex",children:[(0,l.jsx)("button",{className:"bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-l focus:outline-none",disabled:1===x,onClick:()=>p(x-1),children:"← Prev"}),(0,l.jsx)("button",{className:"bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-r focus:outline-none",disabled:x===e,onClick:()=>p(x+1),children:"Next →"})]})]})}()]})})},eb=e=>{let{teams:t,searchParams:s,accessToken:a,setTeams:n,userID:i,userRole:d}=e,[h]=L.Z.useForm(),[m]=L.Z.useForm(),{Title:u,Paragraph:x}=en.default,[p,j]=(0,r.useState)(""),[g,w]=(0,r.useState)(t?t[0]:null),[Z,f]=(0,r.useState)(!1),[k,_]=(0,r.useState)(!1),[b,v]=(0,r.useState)([]);(0,r.useEffect)(()=>{(async()=>{try{if(null===i||null===d)return;if(null!==a){let e=(await y(a,i,d)).data.map(e=>e.id);console.log("available_model_names:",e),v(e)}}catch(e){console.error("Error fetching user models:",e)}})()},[a,i,d]);let S=async e=>{try{if(null!=a){c.ZP.info("Creating Team");let s=await C(a,e);null!==t?n([...t,s]):n([s]),console.log("response for team create call: ".concat(s)),c.ZP.success("Team created"),f(!1)}}catch(e){console.error("Error creating the key:",e),c.ZP.error("Error creating the team: "+e)}},N=async e=>{try{if(null!=a&&null!=t){c.ZP.info("Adding Member");let s={role:"user",user_email:e.user_email,user_id:e.user_id},l=await T(a,g.team_id,s);console.log("response for team create call: ".concat(l.data));let r=t.findIndex(e=>(console.log("team.team_id=".concat(e.team_id,"; response.data.team_id=").concat(l.data.team_id)),e.team_id===l.data.team_id));if(console.log("foundIndex: ".concat(r)),-1!==r){let e=[...t];e[r]=l.data,n(e),w(l.data)}_(!1)}}catch(e){console.error("Error creating the key:",e)}};return console.log("received teams ".concat(t)),(0,l.jsx)("div",{className:"w-full mx-4",children:(0,l.jsxs)(O.Z,{numItems:1,className:"gap-2 p-2 h-[75vh] w-full",children:[(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(u,{level:4,children:"All Teams"}),(0,l.jsx)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,l.jsxs)($.Z,{children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"Team Name"}),(0,l.jsx)(Q.Z,{children:"Spend (USD)"}),(0,l.jsx)(Q.Z,{children:"Budget (USD)"}),(0,l.jsx)(Q.Z,{children:"Models"}),(0,l.jsx)(Q.Z,{children:"TPM / RPM Limits"})]})}),(0,l.jsx)(H.Z,{children:t&&t.length>0?t.map(e=>(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:e.team_alias}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:e.spend}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:e.max_budget?e.max_budget:"No limit"}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:JSON.stringify(e.models?e.models:[])})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsxs)(R.Z,{children:["TPM Limit:"," ",e.tpm_limit?e.tpm_limit:"Unlimited"," ",(0,l.jsx)("br",{}),"RPM Limit:"," ",e.rpm_limit?e.rpm_limit:"Unlimited"]})})]},e.team_id)):null})]})})]}),(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(o.Z,{className:"mx-auto",onClick:()=>f(!0),children:"+ Create New Team"}),(0,l.jsx)(B.Z,{title:"Create Team",visible:Z,width:800,footer:null,onOk:()=>{f(!1),h.resetFields()},onCancel:()=>{f(!1),h.resetFields()},children:(0,l.jsxs)(L.Z,{form:h,onFinish:S,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(L.Z.Item,{label:"Team Name",name:"team_alias",children:(0,l.jsx)(z.Z,{})}),(0,l.jsx)(L.Z.Item,{label:"Models",name:"models",children:(0,l.jsx)(U.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:b.map(e=>(0,l.jsx)(U.default.Option,{value:e,children:e},e))})}),(0,l.jsx)(L.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,l.jsx)(K.Z,{step:.01,precision:2,width:200})}),(0,l.jsx)(L.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})}),(0,l.jsx)(L.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})})]}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(W.ZP,{htmlType:"submit",children:"Create Team"})})]})})]}),(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(u,{level:4,children:"Team Members"}),(0,l.jsx)(x,{children:"If you belong to multiple teams, this setting controls which teams members you see."}),t&&t.length>0?(0,l.jsx)(eo.Z,{defaultValue:"0",children:t.map((e,t)=>(0,l.jsx)(ei.Z,{value:String(t),onClick:()=>{w(e)},children:e.team_alias},t))}):(0,l.jsxs)(x,{children:["No team created. ",(0,l.jsx)("b",{children:"Defaulting to personal account."})]})]}),(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsx)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,l.jsxs)($.Z,{children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"Member Name"}),(0,l.jsx)(Q.Z,{children:"Role"})]})}),(0,l.jsx)(H.Z,{children:g?g.members_with_roles.map((e,t)=>(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{children:e.user_email?e.user_email:e.user_id?e.user_id:null}),(0,l.jsx)(Y.Z,{children:e.role})]},t)):null})]})})}),(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(o.Z,{className:"mx-auto mb-5",onClick:()=>_(!0),children:"+ Add member"}),(0,l.jsx)(B.Z,{title:"Add member",visible:k,width:800,footer:null,onOk:()=>{_(!1),m.resetFields()},onCancel:()=>{_(!1),m.resetFields()},children:(0,l.jsxs)(L.Z,{form:h,onFinish:N,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(L.Z.Item,{label:"Email",name:"user_email",className:"mb-4",children:(0,l.jsx)(z.Z,{name:"user_email",className:"px-3 py-2 border rounded-md w-full"})}),(0,l.jsx)("div",{className:"text-center mb-4",children:"OR"}),(0,l.jsx)(L.Z.Item,{label:"User ID",name:"user_id",className:"mb-4",children:(0,l.jsx)(z.Z,{name:"user_id",className:"px-3 py-2 border rounded-md w-full"})})]}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(W.ZP,{htmlType:"submit",children:"Add member"})})]})})]})]})})},ev=s(8510),eS=e=>{let{searchParams:t,accessToken:s}=e,[a]=L.Z.useForm(),[n]=L.Z.useForm(),{Title:i,Paragraph:d}=en.default,[h,m]=(0,r.useState)(""),[u,x]=(0,r.useState)(null),[p,j]=(0,r.useState)(!1);(0,r.useEffect)(()=>{(async()=>{if(null!=s){let e=[],t=await A(s,"proxy_admin_viewer");t.forEach(t=>{e.push({user_role:t.user_role,user_id:t.user_id,user_email:t.user_email})}),console.log("proxy viewers: ".concat(t));let l=await A(s,"proxy_admin");l.forEach(t=>{e.push({user_role:t.user_role,user_id:t.user_id,user_email:t.user_email})}),console.log("proxy admins: ".concat(l)),console.log("combinedList: ".concat(e)),x(e)}})()},[s]);let y=async e=>{try{if(null!=s&&null!=u){c.ZP.info("Making API Call"),e.user_email,e.user_id;let t=await I(s,e);console.log("response for team create call: ".concat(t));let l=u.findIndex(e=>(console.log("user.user_id=".concat(e.user_id,"; response.user_id=").concat(t.user_id)),e.user_id===t.user_id));console.log("foundIndex: ".concat(l)),-1==l&&(console.log("updates admin with new user"),u.push(t),x(u)),j(!1)}}catch(e){console.error("Error creating the key:",e)}};return console.log("admins: ".concat(null==u?void 0:u.length)),(0,l.jsxs)("div",{className:"w-full m-2",children:[(0,l.jsx)(i,{level:4,children:"Restricted Access"}),(0,l.jsxs)(d,{children:["Add other people to just view spend. They cannot create keys, teams or grant users access to new models."," ",(0,l.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/ui#restrict-ui-access",children:"Requires SSO Setup"})]}),(0,l.jsxs)(O.Z,{numItems:1,className:"gap-2 p-0 w-full",children:[(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsx)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,l.jsxs)($.Z,{children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"Member Name"}),(0,l.jsx)(Q.Z,{children:"Role"}),(0,l.jsx)(Q.Z,{children:"Action"})]})}),(0,l.jsx)(H.Z,{children:u?u.map((e,t)=>(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{children:e.user_email?e.user_email:e.user_id?e.user_id:null}),(0,l.jsx)(Y.Z,{children:e.user_role}),(0,l.jsx)(Y.Z,{children:(0,l.jsx)(G.Z,{icon:ev.Z,size:"sm"})})]},t)):null})]})})}),(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(o.Z,{className:"mx-auto mb-5",onClick:()=>j(!0),children:"+ Add viewer"}),(0,l.jsx)(B.Z,{title:"Add viewer",visible:p,width:800,footer:null,onOk:()=>{j(!1),n.resetFields()},onCancel:()=>{j(!1),n.resetFields()},children:(0,l.jsxs)(L.Z,{form:a,onFinish:y,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(L.Z.Item,{label:"Email",name:"user_email",className:"mb-4",children:(0,l.jsx)(z.Z,{name:"user_email",className:"px-3 py-2 border rounded-md w-full"})}),(0,l.jsx)("div",{className:"text-center mb-4",children:"OR"}),(0,l.jsx)(L.Z.Item,{label:"User ID",name:"user_id",className:"mb-4",children:(0,l.jsx)(z.Z,{name:"user_id",className:"px-3 py-2 border rounded-md w-full"})})]}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(W.ZP,{htmlType:"submit",children:"Add member"})})]})})]})]})]})},eN=s(12968),eA=s(67951);async function eC(e,t,s,l){console.log("isLocal:",!1);let r=window.location.origin,a=new eN.ZP.OpenAI({apiKey:l,baseURL:r,dangerouslyAllowBrowser:!0});for await(let l of(await a.chat.completions.create({model:s,stream:!0,messages:[{role:"user",content:e}]})))console.log(l),l.choices[0].delta.content&&t(l.choices[0].delta.content)}var eT=e=>{let{accessToken:t,token:s,userRole:a,userID:n}=e,[o,i]=(0,r.useState)(""),[c,d]=(0,r.useState)([]),[h,m]=(0,r.useState)(void 0),[u,x]=(0,r.useState)(null);(0,r.useEffect)(()=>{t&&s&&a&&n&&(async()=>{let e=await y(t,n,a);console.log("model_info:",e),(null==e?void 0:e.data.length)>0&&(x(e.data),m(e.data[0].id))})()},[t,n,a]);let p=(e,t)=>{d(s=>{let l=s[s.length-1];return l&&l.role===e?[...s.slice(0,s.length-1),{role:e,content:l.content+t}]:[...s,{role:e,content:t}]})},j=async()=>{if(""!==o.trim()&&t&&s&&a&&n){d(e=>[...e,{role:"user",content:o}]);try{h&&await eC(o,e=>p("assistant",e),h,t)}catch(e){console.error("Error fetching model response",e),p("assistant","Error fetching model response")}i("")}};if(a&&"Admin Viewer"==a){let{Title:e,Paragraph:t}=en.default;return(0,l.jsxs)("div",{children:[(0,l.jsx)(e,{level:1,children:"Access Denied"}),(0,l.jsx)(t,{children:"Ask your proxy admin for access to test models"})]})}return(0,l.jsx)("div",{style:{width:"100%",position:"relative"},children:(0,l.jsx)(O.Z,{className:"gap-2 p-10 h-[75vh] w-full",children:(0,l.jsx)(M.Z,{children:(0,l.jsxs)(ey.Z,{children:[(0,l.jsxs)(eg.Z,{className:"mt-4",children:[(0,l.jsx)(ej.Z,{children:"Chat"}),(0,l.jsx)(ej.Z,{children:"API Reference"})]}),(0,l.jsxs)(eZ.Z,{children:[(0,l.jsxs)(ew.Z,{children:[(0,l.jsxs)("div",{children:[(0,l.jsx)("label",{children:"Select Model:"}),(0,l.jsx)("select",{value:h||"",onChange:e=>m(e.target.value),children:null==u?void 0:u.map(e=>(0,l.jsx)("option",{value:e.id,children:e.id},e.id))})]}),(0,l.jsxs)($.Z,{className:"mt-5",style:{display:"block",maxHeight:"60vh",overflowY:"auto"},children:[(0,l.jsx)(X.Z,{children:(0,l.jsx)(ee.Z,{children:(0,l.jsx)(Y.Z,{children:(0,l.jsx)(D.Z,{children:"Chat"})})})}),(0,l.jsx)(H.Z,{children:c.map((e,t)=>(0,l.jsx)(ee.Z,{children:(0,l.jsx)(Y.Z,{children:"".concat(e.role,": ").concat(e.content)})},t))})]}),(0,l.jsx)("div",{className:"mt-3",style:{position:"absolute",bottom:5,width:"95%"},children:(0,l.jsxs)("div",{className:"flex",children:[(0,l.jsx)("input",{type:"text",value:o,onChange:e=>i(e.target.value),className:"flex-1 p-2 border rounded-md mr-2",placeholder:"Type your message..."}),(0,l.jsx)("button",{onClick:j,className:"p-2 bg-blue-500 text-white rounded-md",children:"Send"})]})})]}),(0,l.jsx)(ew.Z,{children:(0,l.jsxs)(ey.Z,{children:[(0,l.jsxs)(eg.Z,{children:[(0,l.jsx)(ej.Z,{children:"OpenAI Python SDK"}),(0,l.jsx)(ej.Z,{children:"LlamaIndex"}),(0,l.jsx)(ej.Z,{children:"Langchain Py"})]}),(0,l.jsxs)(eZ.Z,{children:[(0,l.jsx)(ew.Z,{children:(0,l.jsx)(eA.Z,{language:"python",children:'\nimport openai\nclient = openai.OpenAI(\n api_key="your_api_key",\n base_url="http://0.0.0.0:4000" # proxy base url\n)\n\nresponse = client.chat.completions.create(\n model="gpt-3.5-turbo", # model to use from Models Tab\n messages = [\n {\n "role": "user",\n "content": "this is a test request, write a short poem"\n }\n ],\n extra_body={\n "metadata": {\n "generation_name": "ishaan-generation-openai-client",\n "generation_id": "openai-client-gen-id22",\n "trace_id": "openai-client-trace-id22",\n "trace_user_id": "openai-client-user-id2"\n }\n }\n)\n\nprint(response)\n '})}),(0,l.jsx)(ew.Z,{children:(0,l.jsx)(eA.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="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,l.jsx)(ew.Z,{children:(0,l.jsx)(eA.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:8000",\n model = "gpt-3.5-turbo",\n temperature=0.1,\n extra_body={\n "metadata": {\n "generation_name": "ishaan-generation-langchain-client",\n "generation_id": "langchain-client-gen-id22",\n "trace_id": "langchain-client-trace-id22",\n "trace_user_id": "langchain-client-user-id2"\n }\n }\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 '})})]})]})})]})]})})})})},eI=s(33509),eE=s(30569);let{Sider:eP}=eI.default;var eF=e=>{let{setPage:t,userRole:s,defaultSelectedKey:r}=e;return"Admin Viewer"==s?(0,l.jsx)(eI.default,{style:{minHeight:"100vh",maxWidth:"120px"},children:(0,l.jsx)(eP,{width:120,children:(0,l.jsxs)(eE.Z,{mode:"inline",defaultSelectedKeys:r||["4"],style:{height:"100%",borderRight:0},children:[(0,l.jsx)(eE.Z.Item,{onClick:()=>t("api-keys"),children:"API Keys"},"4"),(0,l.jsx)(eE.Z.Item,{onClick:()=>t("models"),children:"Models"},"2"),(0,l.jsx)(eE.Z.Item,{onClick:()=>t("llm-playground"),children:"Chat UI"},"3"),(0,l.jsx)(eE.Z.Item,{onClick:()=>t("usage"),children:"Usage"},"1")]})})}):(0,l.jsx)(eI.default,{style:{minHeight:"100vh",maxWidth:"120px"},children:(0,l.jsx)(eP,{width:120,children:(0,l.jsxs)(eE.Z,{mode:"inline",defaultSelectedKeys:r||["1"],style:{height:"100%",borderRight:0},children:[(0,l.jsx)(eE.Z.Item,{onClick:()=>t("api-keys"),children:"API Keys"},"1"),(0,l.jsx)(eE.Z.Item,{onClick:()=>t("models"),children:"Models"},"2"),(0,l.jsx)(eE.Z.Item,{onClick:()=>t("llm-playground"),children:"Chat UI"},"3"),(0,l.jsx)(eE.Z.Item,{onClick:()=>t("usage"),children:"Usage"},"4"),"Admin"==s?(0,l.jsx)(eE.Z.Item,{onClick:()=>t("users"),children:"Users"},"5"):null,"Admin"==s?(0,l.jsx)(eE.Z.Item,{onClick:()=>t("teams"),children:"Teams"},"6"):null,"Admin"==s?(0,l.jsx)(eE.Z.Item,{onClick:()=>t("admin-panel"),children:"Admin"},"7"):null]})})})},eO=e=>{let{accessToken:t,token:s,userRole:a,userID:n}=e,o=new Date,[i,c]=(0,r.useState)([]),[d,h]=(0,r.useState)([]),[m,u]=(0,r.useState)([]),[x,p]=(0,r.useState)([]),[j,y]=(0,r.useState)([]),[g,_]=(0,r.useState)([]),[S,N]=(0,r.useState)([]),A=new Date(o.getFullYear(),o.getMonth(),1),C=new Date(o.getFullYear(),o.getMonth()+1,0),T=E(A),I=E(C);function E(e){let t=e.getFullYear(),s=e.getMonth()+1,l=e.getDate();return"".concat(t,"-").concat(s<10?"0"+s:s,"-").concat(l<10?"0"+l:l)}return console.log("Start date is ".concat(T)),console.log("End date is ".concat(I)),(0,r.useEffect)(()=>{t&&s&&a&&n&&(async()=>{try{if(console.log("user role: ".concat(a)),"Admin"==a||"Admin Viewer"==a){let e=await f(t);c(e);let s=(await k(t)).map(e=>({key:(e.key_name||e.key_alias||e.api_key).substring(0,7),spend:e.total_spend}));h(s);let l=(await b(t)).map(e=>({key:e.model,spend:e.total_spend}));u(l);let r=await w(t);console.log("teamSpend",r),y(r.daily_spend),_(r.teams),N(r.total_spend_per_team)}else"App Owner"==a&&await Z(t,s,a,n,T,I).then(async e=>{if(console.log("result from spend logs call",e),"daily_spend"in e){let t=e.daily_spend;console.log("daily spend",t),c(t);let s=e.top_api_keys;h(s)}else{let s=(await v(t,function(e){let t=[];e.forEach(e=>{Object.entries(e).forEach(e=>{let[s,l]=e;"spend"!==s&&"startTime"!==s&&"models"!==s&&"users"!==s&&t.push({key:s,spend:l})})}),t.sort((e,t)=>Number(t.spend)-Number(e.spend));let s=t.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||e.token).substring(0,7),spend:e.spend}));h(s),p(function(e){let t={};e.forEach(e=>{Object.entries(e.users).forEach(e=>{let[s,l]=e;""!==s&&null!=s&&"None"!=s&&(t[s]||(t[s]=0),t[s]+=l)})});let s=Object.entries(t).map(e=>{let[t,s]=e;return{user_id:t,spend:s}});s.sort((e,t)=>t.spend-e.spend);let l=s.slice(0,5);return console.log("topKeys: ".concat(Object.values(l[0]))),l}(e)),c(e)}})}catch(e){console.error("There was an error fetching the data",e)}})()},[t,s,a,n,T,I]),(0,l.jsx)("div",{style:{width:"100%"},children:(0,l.jsxs)(ey.Z,{children:[(0,l.jsxs)(eg.Z,{className:"mt-4",children:[(0,l.jsx)(ej.Z,{children:"All Up"}),(0,l.jsx)(ej.Z,{children:"Team Based Usage"})]}),(0,l.jsxs)(eZ.Z,{children:[(0,l.jsx)(ew.Z,{children:(0,l.jsxs)(O.Z,{numItems:2,className:"gap-2 p-10 h-[75vh] w-full",children:[(0,l.jsx)(F.Z,{numColSpan:2,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Monthly Spend"}),(0,l.jsx)(et.Z,{data:i,index:"date",categories:["spend"],colors:["blue"],valueFormatter:e=>"$ ".concat(new Intl.NumberFormat("us").format(e).toString()),yAxisWidth:100,tickGap:5})]})}),(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Top API Keys"}),(0,l.jsx)(et.Z,{className:"mt-4 h-40",data:d,index:"key",categories:["spend"],colors:["blue"],yAxisWidth:80,tickGap:5,layout:"vertical",showXAxis:!1,showLegend:!1})]})}),(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Top Users"}),(0,l.jsx)(et.Z,{className:"mt-4 h-40",data:x,index:"user_id",categories:["spend"],colors:["blue"],yAxisWidth:200,layout:"vertical",showXAxis:!1,showLegend:!1})]})}),(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Top Models"}),(0,l.jsx)(et.Z,{className:"mt-4 h-40",data:m,index:"key",categories:["spend"],colors:["blue"],yAxisWidth:200,layout:"vertical",showXAxis:!1,showLegend:!1})]})})]})}),(0,l.jsx)(ew.Z,{children:(0,l.jsxs)(O.Z,{numItems:2,className:"gap-2 p-10 h-[75vh] w-full",children:[(0,l.jsx)(F.Z,{numColSpan:2,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Daily Spend Per Team"}),(0,l.jsx)(et.Z,{className:"h-72",data:j,index:"date",categories:g,yAxisWidth:30,stack:!0})]})}),(0,l.jsx)(F.Z,{numColSpan:2,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Total Spend Per Team"}),(0,l.jsx)(et.Z,{className:"h-72",data:S,index:"team_id",categories:["total_spend"],yAxisWidth:30})]})})]})})]})]})})},eM=()=>{let{Title:e,Paragraph:t}=en.default,[s,n]=(0,r.useState)(""),[o,c]=(0,r.useState)(null),[d,h]=(0,r.useState)(null),[m,u]=(0,r.useState)(null),[x,p]=(0,r.useState)(!0),j=(0,a.useSearchParams)(),y=j.get("userID"),g=j.get("token"),[w,Z]=(0,r.useState)("api-keys"),[f,k]=(0,r.useState)(null);return(0,r.useEffect)(()=>{if(g){let e=(0,ed.o)(g);if(e){if(console.log("Decoded token:",e),console.log("Decoded key:",e.key),k(e.key),e.user_role){let t=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"app_user":return"App User";default:return"Unknown Role"}}(e.user_role);console.log("Decoded user_role:",t),n(t),"Admin Viewer"==t&&Z("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?p("username_password"==e.login_method):console.log("User Email is not set ".concat(e))}}},[g]),(0,l.jsx)(r.Suspense,{fallback:(0,l.jsx)("div",{children:"Loading..."}),children:(0,l.jsxs)("div",{className:"flex flex-col min-h-screen",children:[(0,l.jsx)(i,{userID:y,userRole:s,userEmail:o,showSSOBanner:x}),(0,l.jsxs)("div",{className:"flex flex-1 overflow-auto",children:[(0,l.jsx)(eF,{setPage:Z,userRole:s,defaultSelectedKey:null}),"api-keys"==w?(0,l.jsx)(eh,{userID:y,userRole:s,teams:d,keys:m,setUserRole:n,userEmail:o,setUserEmail:c,setTeams:h,setKeys:u}):"models"==w?(0,l.jsx)(ep,{userID:y,userRole:s,token:g,accessToken:f}):"llm-playground"==w?(0,l.jsx)(eT,{userID:y,userRole:s,token:g,accessToken:f}):"users"==w?(0,l.jsx)(e_,{userID:y,userRole:s,token:g,keys:m,accessToken:f,setKeys:u}):"teams"==w?(0,l.jsx)(eb,{teams:d,setTeams:h,searchParams:j,accessToken:f,userID:y,userRole:s}):"admin-panel"==w?(0,l.jsx)(eS,{setTeams:h,searchParams:j,accessToken:f}):(0,l.jsx)(eO,{userID:y,userRole:s,token:g,accessToken:f})]})]})})}}},function(e){e.O(0,[730,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-a94f48a4c941dbe4.js b/ui/litellm-dashboard/out/_next/static/chunks/app/page-a94f48a4c941dbe4.js deleted file mode 100644 index 755ccbe7e..000000000 --- a/ui/litellm-dashboard/out/_next/static/chunks/app/page-a94f48a4c941dbe4.js +++ /dev/null @@ -1 +0,0 @@ -(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[931],{20661:function(e,t,s){Promise.resolve().then(s.bind(s,92182))},92182:function(e,t,s){"use strict";s.r(t),s.d(t,{default:function(){return eM}});var l=s(3827),r=s(64090),n=s(47907),a=s(8792),o=s(2179),i=e=>{let{userID:t,userRole:s,userEmail:r,showSSOBanner:n}=e;return console.log("User ID:",t),console.log("userEmail:",r),(0,l.jsxs)("nav",{className:"left-0 right-0 top-0 flex justify-between items-center h-12 mb-4",children:[(0,l.jsx)("div",{className:"text-left my-2 absolute top-0 left-0",children:(0,l.jsx)("div",{className:"flex flex-col items-center",children:(0,l.jsx)(a.default,{href:"/",children:(0,l.jsx)("button",{className:"text-gray-800 text-2xl py-1 rounded text-center",children:(0,l.jsx)("img",{src:"/get_image",width:200,height:200,alt:"LiteLLM Brand",className:"mr-2"})})})})}),(0,l.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,l.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/ui#setup-ssoauth-for-ui",target:"_blank",className:"mr-2"}):null,(0,l.jsxs)(o.Z,{variant:"secondary",size:"lg",children:[r,(0,l.jsxs)("p",{children:["Role: ",s]}),(0,l.jsxs)("p",{children:["ID: ",t]})]})]})]})},c=s(80588);let d=async(e,t,s)=>{try{if(console.log("Form Values in keyCreateCall:",s),s.description&&(s.metadata||(s.metadata={}),s.metadata.description=s.description,delete s.description,s.metadata=JSON.stringify(s.metadata)),s.metadata){console.log("formValues.metadata:",s.metadata);try{s.metadata=JSON.parse(s.metadata)}catch(e){throw c.ZP.error("Failed to parse metadata: "+e),Error("Failed to parse metadata: "+e)}}console.log("Form Values after check:",s);let l=await fetch("/key/generate",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({user_id:t,...s})});if(!l.ok){let e=await l.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let r=await l.json();return console.log("API Response:",r),r}catch(e){throw console.error("Failed to create key:",e),e}},h=async(e,t,s)=>{try{if(console.log("Form Values in keyCreateCall:",s),s.description&&(s.metadata||(s.metadata={}),s.metadata.description=s.description,delete s.description,s.metadata=JSON.stringify(s.metadata)),s.metadata){console.log("formValues.metadata:",s.metadata);try{s.metadata=JSON.parse(s.metadata)}catch(e){throw c.ZP.error("Failed to parse metadata: "+e),Error("Failed to parse metadata: "+e)}}console.log("Form Values after check:",s);let l=await fetch("/user/new",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({user_id:t,...s})});if(!l.ok){let e=await l.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let r=await l.json();return console.log("API Response:",r),r}catch(e){throw console.error("Failed to create key:",e),e}},m=async(e,t)=>{try{console.log("in keyDeleteCall:",t);let s=await fetch("/key/delete",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({keys:[t]})});if(!s.ok){let e=await s.text();throw c.ZP.error("Failed to delete key: "+e),Error("Network response was not ok")}let l=await s.json();return console.log(l),l}catch(e){throw console.error("Failed to create key:",e),e}},u=async function(e,t,s){let l=arguments.length>3&&void 0!==arguments[3]&&arguments[3];try{let r="/user/info";"App Owner"==s&&t&&(r="".concat(r,"?user_id=").concat(t)),console.log("in userInfoCall viewAll=",l),l&&(r="".concat(r,"?view_all=true"));let n=await fetch(r,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!n.ok){let e=await n.text();throw c.ZP.error(e),Error("Network response was not ok")}let a=await n.json();return console.log("API Response:",a),a}catch(e){throw console.error("Failed to create key:",e),e}},x=async e=>{try{let t=await fetch("/global/spend",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},p=async(e,t,s)=>{try{let t=await fetch("/v2/model/info",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},j=async(e,t,s)=>{try{let t=await fetch("/model/metrics",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},y=async(e,t,s)=>{try{let t=await fetch("/models",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},g=async(e,t)=>{try{let s="/global/spend/logs";console.log("in keySpendLogsCall:",s);let l=await fetch("".concat(s,"?api_key=").concat(t),{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw c.ZP.error(e),Error("Network response was not ok")}let r=await l.json();return console.log(r),r}catch(e){throw console.error("Failed to create key:",e),e}},w=async e=>{try{let t="/global/spend/teams";console.log("in teamSpendLogsCall:",t);let s=await fetch("".concat(t),{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!s.ok){let e=await s.text();throw c.ZP.error(e),Error("Network response was not ok")}let l=await s.json();return console.log(l),l}catch(e){throw console.error("Failed to create key:",e),e}},Z=async(e,t,s,l,r,n)=>{try{console.log("user role in spend logs call: ".concat(s));let t="/spend/logs";t="App Owner"==s?"".concat(t,"?user_id=").concat(l,"&start_date=").concat(r,"&end_date=").concat(n):"".concat(t,"?start_date=").concat(r,"&end_date=").concat(n);let a=await fetch(t,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!a.ok){let e=await a.text();throw c.ZP.error(e),Error("Network response was not ok")}let o=await a.json();return console.log(o),o}catch(e){throw console.error("Failed to create key:",e),e}},f=async e=>{try{let t=await fetch("/global/spend/logs",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to create key:",e),e}},k=async e=>{try{let t=await fetch("/global/spend/keys?limit=5",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to create key:",e),e}},_=async(e,t)=>{try{t&&JSON.stringify({api_key:t});let s={method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}};t&&(s.body=JSON.stringify({api_key:t}));let l=await fetch("/global/spend/end_users",s);if(!l.ok){let e=await l.text();throw c.ZP.error(e),Error("Network response was not ok")}let r=await l.json();return console.log(r),r}catch(e){throw console.error("Failed to create key:",e),e}},b=async e=>{try{let t=await fetch("/global/spend/models?limit=5",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to create key:",e),e}},v=async(e,t)=>{try{let s=await fetch("/v2/key/info",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({keys:t})});if(!s.ok){let e=await s.text();throw c.ZP.error(e),Error("Network response was not ok")}let l=await s.json();return console.log(l),l}catch(e){throw console.error("Failed to create key:",e),e}},S=async(e,t,s,l)=>{try{let r=await fetch("/user/request_model",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({models:[t],user_id:s,justification:l})});if(!r.ok){let e=await r.text();throw c.ZP.error("Failed to delete key: "+e),Error("Network response was not ok")}let n=await r.json();return console.log(n),n}catch(e){throw console.error("Failed to create key:",e),e}},N=async e=>{try{let t="/user/get_requests";console.log("in userGetRequesedtModelsCall:",t);let s=await fetch(t,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!s.ok){let e=await s.text();throw c.ZP.error("Failed to delete key: "+e),Error("Network response was not ok")}let l=await s.json();return console.log(l),l}catch(e){throw console.error("Failed to get requested models:",e),e}},A=async(e,t)=>{try{let s="/user/get_users?role=".concat(t);console.log("in userGetAllUsersCall:",s);let l=await fetch(s,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw c.ZP.error("Failed to delete key: "+e),Error("Network response was not ok")}let r=await l.json();return console.log(r),r}catch(e){throw console.error("Failed to get requested models:",e),e}},C=async(e,t)=>{try{console.log("Form Values in teamCreateCall:",t);let s=await fetch("/team/new",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...t})});if(!s.ok){let e=await s.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let l=await s.json();return console.log("API Response:",l),l}catch(e){throw console.error("Failed to create key:",e),e}},T=async(e,t,s)=>{try{console.log("Form Values in teamMemberAddCall:",s);let l=await fetch("/team/member_add",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({team_id:t,member:s})});if(!l.ok){let e=await l.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let r=await l.json();return console.log("API Response:",r),r}catch(e){throw console.error("Failed to create key:",e),e}},I=async(e,t)=>{try{console.log("Form Values in userUpdateUserCall:",t);let s=await fetch("/user/update",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({user_role:"proxy_admin_viewer",...t})});if(!s.ok){let e=await s.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let l=await s.json();return console.log("API Response:",l),l}catch(e){throw console.error("Failed to create key:",e),e}},P=async(e,t)=>{try{let s=await fetch("/global/predict/spend/logs",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({data:t})});if(!s.ok){let e=await s.text();throw c.ZP.error(e),Error("Network response was not ok")}let l=await s.json();return console.log(l),l}catch(e){throw console.error("Failed to create key:",e),e}},E=async e=>{try{console.log("Checking Slack Budget Alerts service health");let t=await fetch("/health/services?service=slack_budget_alerts",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error("Failed Slack Alert test: "+e),Error(e)}let s=await t.json();return c.ZP.success("Test Slack Alert worked - check your Slack!"),console.log("Service Health Response:",s),s}catch(e){throw console.error("Failed to perform health check:",e),e}};var F=s(10384),O=s(46453),M=s(13810),R=s(71801),D=s(42440),U=s(17189),L=s(12143),B=s(77171),z=s(42539),K=s(88707),W=s(1861);let{Option:V}=U.default;var q=e=>{let{userID:t,teamID:s,userRole:n,accessToken:a,data:i,userModels:h,setData:m}=e,[u]=L.Z.useForm(),[x,p]=(0,r.useState)(!1),[j,y]=(0,r.useState)(null),[g,w]=(0,r.useState)(null),Z=()=>{p(!1),u.resetFields()},f=()=>{p(!1),y(null),u.resetFields()},k=async e=>{try{c.ZP.info("Making API Call"),p(!0);let s=await d(a,t,e);console.log("key create Response:",s),m(e=>e?[...e,s]:[s]),y(s.key),w(s.soft_budget),c.ZP.success("API Key Created"),u.resetFields(),localStorage.removeItem("userData"+t)}catch(e){console.error("Error creating the key:",e)}},_=async()=>{try{console.log("Sending Slack alert...");let e=await E(a);console.log("slackBudgetAlertsHealthCheck Response:",e),console.log("Testing Slack alert successful")}catch(e){console.error("Error sending Slack alert:",e)}};return(0,l.jsxs)("div",{children:[(0,l.jsx)(o.Z,{className:"mx-auto",onClick:()=>p(!0),children:"+ Create New Key"}),(0,l.jsx)(B.Z,{title:"Create Key",visible:x,width:800,footer:null,onOk:Z,onCancel:f,children:(0,l.jsxs)(L.Z,{form:u,onFinish:k,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:["App Owner"===n||"Admin"===n?(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(L.Z.Item,{label:"Key Name",name:"key_alias",children:(0,l.jsx)(z.Z,{})}),(0,l.jsx)(L.Z.Item,{label:"Team ID",name:"team_id",children:(0,l.jsx)(z.Z,{placeholder:"ai_team",defaultValue:s||""})}),(0,l.jsx)(L.Z.Item,{label:"Models",name:"models",children:(0,l.jsx)(U.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:h.map(e=>(0,l.jsx)(V,{value:e,children:e},e))})}),(0,l.jsx)(L.Z.Item,{label:"Soft Budget (USD) Monthly",name:"soft_budget",initialValue:50,children:(0,l.jsx)(K.Z,{step:.01,precision:2,defaultValue:50,width:200})}),(0,l.jsx)(L.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,l.jsx)(K.Z,{step:.01,precision:2,width:200})}),(0,l.jsx)(L.Z.Item,{label:"Reset Budget",name:"budget_duration",children:(0,l.jsxs)(U.default,{defaultValue:null,placeholder:"n/a",children:[(0,l.jsx)(U.default.Option,{value:"24h",children:"daily"}),(0,l.jsx)(U.default.Option,{value:"30d",children:"monthly"})]})}),(0,l.jsx)(L.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})}),(0,l.jsx)(L.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})}),(0,l.jsx)(L.Z.Item,{label:"Expire Key (eg: 30s, 30h, 30d)",name:"duration",children:(0,l.jsx)(z.Z,{})}),(0,l.jsx)(L.Z.Item,{label:"Metadata",name:"metadata",children:(0,l.jsx)(z.Z.TextArea,{rows:4,placeholder:"Enter metadata as JSON"})})]}):(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(L.Z.Item,{label:"Key Name",name:"key_alias",children:(0,l.jsx)(z.Z,{})}),(0,l.jsx)(L.Z.Item,{label:"Team ID (Contact Group)",name:"team_id",children:(0,l.jsx)(z.Z,{placeholder:"ai_team"})}),(0,l.jsx)(L.Z.Item,{label:"Description",name:"description",children:(0,l.jsx)(z.Z.TextArea,{placeholder:"Enter description",rows:4})})]}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(W.ZP,{htmlType:"submit",children:"Create Key"})})]})}),j&&(0,l.jsx)(B.Z,{visible:x,onOk:Z,onCancel:f,footer:null,children:(0,l.jsx)(O.Z,{numItems:1,className:"gap-2 w-full",children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Save your Key"}),(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsxs)("p",{children:["Please save this secret key somewhere safe and accessible. For security reasons, ",(0,l.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,l.jsx)(F.Z,{numColSpan:1,children:null!=j?(0,l.jsxs)("div",{children:[(0,l.jsxs)(R.Z,{children:["API Key: ",j]}),(0,l.jsx)(D.Z,{className:"mt-6",children:"Budgets"}),(0,l.jsxs)(R.Z,{children:["Soft Limit Budget: $",g]}),(0,l.jsx)(o.Z,{className:"mt-3",onClick:_,children:"Test Slack Alert"}),(0,l.jsxs)(R.Z,{className:"mt-2",children:["(LiteLLM Docs -",(0,l.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/alerting",target:"_blank",className:"text-blue-500",children:"Set Up Slack Alerting)"})]})]}):(0,l.jsx)(R.Z,{children:"Key being created, this might take 30s"})})]})})})]})},J=s(33393),G=s(61244),$=s(10827),H=s(3851),Y=s(2044),X=s(64167),Q=s(74480),ee=s(7178),et=s(9853),es=s(56863),el=e=>{let{token:t,accessToken:s,keySpend:n,keyBudget:a,keyName:i}=e,[c,d]=(0,r.useState)(!1),[h,m]=(0,r.useState)(null),[u,x]=(0,r.useState)(""),[p,j]=(0,r.useState)(null),y=async()=>{try{if(null==s||null==t)return;console.log("accessToken: ".concat(s,"; token: ").concat(t));let e=await g(s,t);console.log("Response:",e),m(e);let l=await P(s,e);console.log("Response2:",l);let r=[...e,...l.response];m(r),x(l.predicted_spend),console.log("Combined Data:",r)}catch(e){console.error("There was an error fetching the data",e)}};return t?(0,l.jsxs)("div",{children:[(0,l.jsx)(o.Z,{size:"xs",onClick:()=>{console.log("Show Modal triggered"),d(!0),y()},variant:"secondary",children:"Spend Report"}),(0,l.jsxs)(B.Z,{visible:c,width:1400,onOk:()=>{d(!1)},onCancel:()=>{d(!1)},footer:null,children:[(0,l.jsxs)(D.Z,{style:{textAlign:"left"},children:["Key Name: ",i]}),(0,l.jsxs)(es.Z,{children:["Monthly Spend $",n]}),(0,l.jsx)(D.Z,{children:u}),(0,l.jsx)(M.Z,{className:"mt-6 mb-6",children:h&&(0,l.jsx)(et.Z,{className:"mt-6",data:h,colors:["blue","amber"],index:"date",categories:["spend","predicted_spend"],yAxisWidth:80})})]})]}):null},er=e=>{let{userID:t,accessToken:s,data:n,setData:a}=e,[i,c]=(0,r.useState)(!1),[d,h]=(0,r.useState)(!1),[u,x]=(0,r.useState)(null),p=async e=>{null!=n&&(x(e),localStorage.removeItem("userData"+t),h(!0))},j=async()=>{if(null!=u&&null!=n){try{await m(s,u);let e=n.filter(e=>e.token!==u);a(e)}catch(e){console.error("Error deleting the key:",e)}h(!1),x(null)}};if(null!=n)return console.log("RERENDER TRIGGERED"),(0,l.jsxs)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh] mb-4",children:[(0,l.jsxs)($.Z,{className:"mt-5",children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"Key Alias"}),(0,l.jsx)(Q.Z,{children:"Secret Key"}),(0,l.jsx)(Q.Z,{children:"Spend (USD)"}),(0,l.jsx)(Q.Z,{children:"Key Budget (USD)"}),(0,l.jsx)(Q.Z,{children:"Spend Report"}),(0,l.jsx)(Q.Z,{children:"Team ID"}),(0,l.jsx)(Q.Z,{children:"Metadata"}),(0,l.jsx)(Q.Z,{children:"Models"}),(0,l.jsx)(Q.Z,{children:"TPM / RPM Limits"}),(0,l.jsx)(Q.Z,{children:"Expires"})]})}),(0,l.jsx)(H.Z,{children:n.map(e=>(console.log(e),"litellm-dashboard"===e.team_id)?null:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",whiteSpace:"pre-wrap",overflow:"hidden"},children:null!=e.key_alias?(0,l.jsx)(R.Z,{children:e.key_alias}):(0,l.jsx)(R.Z,{children:"Not Set"})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:e.key_name})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:(()=>{try{return parseFloat(e.spend).toFixed(4)}catch(t){return e.spend}})()})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",whiteSpace:"pre-wrap",overflow:"hidden"},children:null!=e.max_budget?(0,l.jsx)(R.Z,{children:e.max_budget}):(0,l.jsx)(R.Z,{children:"Unlimited Budget"})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px"},children:(0,l.jsx)(el,{token:e.token,accessToken:s,keySpend:e.spend,keyBudget:e.max_budget,keyName:e.key_name})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:e.team_id})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:JSON.stringify(e.metadata).slice(0,400)})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:JSON.stringify(e.models)})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",overflowWrap:"break-word"},children:(0,l.jsxs)(R.Z,{children:["TPM Limit: ",e.tpm_limit?e.tpm_limit:"Unlimited"," ",(0,l.jsx)("br",{})," RPM Limit:"," ",e.rpm_limit?e.rpm_limit:"Unlimited"]})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",wordWrap:"break-word"},children:null!=e.expires?(0,l.jsx)(R.Z,{children:e.expires}):(0,l.jsx)(R.Z,{children:"Never"})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"2px",wordWrap:"break-word"},children:(0,l.jsx)(G.Z,{onClick:()=>p(e.token),icon:J.Z,size:"sm"})})]},e.token))})]}),d&&(0,l.jsx)("div",{className:"fixed z-10 inset-0 overflow-y-auto",children:(0,l.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,l.jsx)("div",{className:"fixed inset-0 transition-opacity","aria-hidden":"true",children:(0,l.jsx)("div",{className:"absolute inset-0 bg-gray-500 opacity-75"})}),(0,l.jsx)("span",{className:"hidden sm:inline-block sm:align-middle sm:h-screen","aria-hidden":"true",children:"​"}),(0,l.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,l.jsx)("div",{className:"bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4",children:(0,l.jsx)("div",{className:"sm:flex sm:items-start",children:(0,l.jsxs)("div",{className:"mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left",children:[(0,l.jsx)("h3",{className:"text-lg leading-6 font-medium text-gray-900",children:"Delete Key"}),(0,l.jsx)("div",{className:"mt-2",children:(0,l.jsx)("p",{className:"text-sm text-gray-500",children:"Are you sure you want to delete this key ?"})})]})})}),(0,l.jsxs)("div",{className:"bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse",children:[(0,l.jsx)(o.Z,{onClick:j,color:"red",className:"ml-2",children:"Delete"}),(0,l.jsx)(o.Z,{onClick:()=>{h(!1),x(null)},children:"Cancel"})]})]})]})})]})},en=e=>{let{userID:t,userSpendData:s,userRole:n,accessToken:a}=e,[o,i]=(0,r.useState)(null==s?void 0:s.spend),[c,d]=(0,r.useState)((null==s?void 0:s.max_budget)||null);(0,r.useEffect)(()=>{(async()=>{if("Admin"===n)try{let e=await x(a);i(e.spend),d(e.max_budget||null)}catch(e){console.error("Error fetching global spend data:",e)}})()},[n,a]);let h=void 0!==o?o.toFixed(4):null;return(0,l.jsx)(l.Fragment,{children:(0,l.jsxs)(M.Z,{className:"mx-auto mb-4",children:[(0,l.jsxs)(es.Z,{children:["$",h]}),(0,l.jsxs)(D.Z,{children:["/ ",null!==c?"$".concat(c," limit"):"No limit"]})]})})},ea=s(36083),eo=s(68967),ei=s(27166),ec=e=>{let{teams:t,setSelectedTeam:s}=e,{Title:n,Paragraph:a}=ea.default,[o,i]=(0,r.useState)("");return(0,l.jsxs)("div",{className:"mt-10",children:[(0,l.jsx)(n,{level:4,children:"Default Team"}),(0,l.jsx)(a,{children:"If you belong to multiple teams, this setting controls which team is used by default when creating new API Keys."}),t&&t.length>0?(0,l.jsx)(eo.Z,{defaultValue:"0",children:t.map((e,t)=>(0,l.jsx)(ei.Z,{value:String(t),onClick:()=>s(e),children:e.team_alias},t))}):(0,l.jsxs)(a,{children:["No team created. ",(0,l.jsx)("b",{children:"Defaulting to personal account."})]})]})},ed=s(37963);console.log("isLocal:",!1);var eh=e=>{let{userID:t,userRole:s,teams:a,keys:o,setUserRole:i,userEmail:c,setUserEmail:d,setTeams:h,setKeys:m}=e,[p,j]=(0,r.useState)(null),g=(0,n.useSearchParams)();g.get("viewSpend"),(0,n.useRouter)();let w=g.get("token"),[Z,f]=(0,r.useState)(null),[k,_]=(0,r.useState)([]),[b,v]=(0,r.useState)(a?a[0]:null);if(window.addEventListener("beforeunload",function(){sessionStorage.clear()}),(0,r.useEffect)(()=>{if(w){let e=(0,ed.o)(w);if(e){if(console.log("Decoded token:",e),console.log("Decoded key:",e.key),f(e.key),e.user_role){let t=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";default:return"Unknown Role"}}(e.user_role);console.log("Decoded user_role:",t),i(t)}else console.log("User role not defined");e.user_email?d(e.user_email):console.log("User Email is not set ".concat(e))}}if(t&&Z&&s&&!o&&!p){let e=sessionStorage.getItem("userModels"+t);e?_(JSON.parse(e)):(async()=>{try{let e=await u(Z,t,s);if(console.log("received teams in user dashboard: ".concat(Object.keys(e),"; team values: ").concat(Object.entries(e.teams))),"Admin"==s){let e=await x(Z);j(e),console.log("globalSpend:",e)}else j(e.user_info);m(e.keys),h(e.teams),v(e.teams?e.teams[0]:null),sessionStorage.setItem("userData"+t,JSON.stringify(e.keys)),sessionStorage.setItem("userSpendData"+t,JSON.stringify(e.user_info));let l=(await y(Z,t,s)).data.map(e=>e.id);console.log("available_model_names:",l),_(l),console.log("userModels:",k),sessionStorage.setItem("userModels"+t,JSON.stringify(l))}catch(e){console.error("There was an error fetching the data",e)}})()}},[t,w,Z,o,s]),null==t||null==w){let e="/sso/key/generate";return console.log("Full URL:",e),window.location.href=e,null}if(null==Z)return null;if(null==s&&i("App Owner"),s&&"Admin Viewer"==s){let{Title:e,Paragraph:t}=ea.default;return(0,l.jsxs)("div",{children:[(0,l.jsx)(e,{level:1,children:"Access Denied"}),(0,l.jsx)(t,{children:"Ask your proxy admin for access to create keys"})]})}return(0,l.jsx)("div",{children:(0,l.jsx)(O.Z,{numItems:1,className:"gap-0 p-10 h-[75vh] w-full",children:(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(en,{userID:t,userSpendData:p,userRole:s,accessToken:Z}),(0,l.jsx)(er,{userID:t,accessToken:Z,data:o,setData:m}),(0,l.jsx)(q,{userID:t,teamID:b?b.team_id:null,userRole:s,userModels:k,accessToken:Z,data:o,setData:m}),(0,l.jsx)(ec,{teams:a,setSelectedTeam:v})]})})})},em=s(5);let{Option:eu}=U.default;var ex=e=>{let{userModels:t,accessToken:s,userID:n}=e,[a]=L.Z.useForm(),[i,d]=(0,r.useState)(!1),h=async e=>{try{c.ZP.info("Requesting access");let{selectedModel:t,accessReason:l}=e;await S(s,t,n,l),d(!0)}catch(e){console.error("Error requesting access:",e)}};return(0,l.jsxs)("div",{children:[(0,l.jsx)(o.Z,{size:"xs",onClick:()=>d(!0),children:"Request Access"}),(0,l.jsx)(B.Z,{title:"Request Access",visible:i,width:800,footer:null,onOk:()=>{d(!1),a.resetFields()},onCancel:()=>{d(!1),a.resetFields()},children:(0,l.jsxs)(L.Z,{form:a,onFinish:h,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsx)(L.Z.Item,{label:"Select Model",name:"selectedModel",children:(0,l.jsx)(U.default,{placeholder:"Select model",style:{width:"100%"},children:t.map(e=>(0,l.jsx)(eu,{value:e,children:e},e))})}),(0,l.jsx)(L.Z.Item,{label:"Reason for Access",name:"accessReason",children:(0,l.jsx)(z.Z.TextArea,{rows:4,placeholder:"Enter reason for access"})}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(o.Z,{children:"Request Access"})})]})})]})},ep=e=>{let{accessToken:t,token:s,userRole:n,userID:a}=e,[o,i]=(0,r.useState)({data:[]}),[c,d]=(0,r.useState)([]),[h,m]=(0,r.useState)([]);if((0,r.useEffect)(()=>{if(!t||!s||!n||!a)return;let e=async()=>{try{let e=await p(t,a,n);console.log("Model data response:",e.data),i(e);let s=await j(t,a,n);if(console.log("Model metrics response:",s),d(s),"Admin"===n&&t){let e=await N(t);console.log("Pending Requests:",h),m(e.requests||[])}}catch(e){console.error("There was an error fetching the model data",e)}};t&&s&&n&&a&&e()},[t,s,n,a]),!o||!t||!s||!n||!a)return(0,l.jsx)("div",{children:"Loading..."});let u=[];for(let e=0;e(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{children:(0,l.jsx)(D.Z,{children:e.model_name})}),(0,l.jsx)(Y.Z,{children:e.provider}),"Admin"===n&&(0,l.jsx)(Y.Z,{children:e.api_base}),(0,l.jsx)(Y.Z,{children:e.user_access?(0,l.jsx)(em.Z,{color:"green",children:"Yes"}):(0,l.jsx)(ex,{userModels:u,accessToken:t,userID:a})}),(0,l.jsx)(Y.Z,{children:e.input_cost}),(0,l.jsx)(Y.Z,{children:e.output_cost}),(0,l.jsx)(Y.Z,{children:e.max_tokens})]},e.model_name))})]})}),(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Model Statistics (Number Requests)"}),(0,l.jsx)(et.Z,{data:c,index:"model",categories:["num_requests"],colors:["blue"],yAxisWidth:400,layout:"vertical",tickGap:5})]}),(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Model Statistics (Latency)"}),(0,l.jsx)(et.Z,{data:c,index:"model",categories:["avg_latency_seconds"],colors:["red"],yAxisWidth:400,layout:"vertical",tickGap:5})]})]})})},ej=s(92836),ey=s(26734),eg=s(41608),ew=s(32126),eZ=s(23682);let{Option:ef}=U.default;var ek=e=>{let{userID:t,accessToken:s}=e,[n]=L.Z.useForm(),[a,i]=(0,r.useState)(!1),[d,m]=(0,r.useState)(null),[u,x]=(0,r.useState)([]);(0,r.useEffect)(()=>{(async()=>{try{let e=await y(s,t,"any"),l=[];for(let t=0;t{i(!1),n.resetFields()},j=()=>{i(!1),m(null),n.resetFields()},g=async e=>{try{c.ZP.info("Making API Call"),i(!0),console.log("formValues in create user:",e);let l=await h(s,t,e);console.log("user create Response:",l),m(l.key),c.ZP.success("API user Created"),n.resetFields(),localStorage.removeItem("userData"+t)}catch(e){console.error("Error creating the user:",e)}};return(0,l.jsxs)("div",{children:[(0,l.jsx)(o.Z,{className:"mx-auto",onClick:()=>i(!0),children:"+ Create New User"}),(0,l.jsx)(B.Z,{title:"Create User",visible:a,width:800,footer:null,onOk:p,onCancel:j,children:(0,l.jsxs)(L.Z,{form:n,onFinish:g,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsx)(L.Z.Item,{label:"User ID",name:"user_id",children:(0,l.jsx)(z.Z,{placeholder:"Enter User ID"})}),(0,l.jsx)(L.Z.Item,{label:"Team ID",name:"team_id",children:(0,l.jsx)(z.Z,{placeholder:"ai_team"})}),(0,l.jsx)(L.Z.Item,{label:"Models",name:"models",children:(0,l.jsx)(U.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:u.map(e=>(0,l.jsx)(ef,{value:e,children:e},e))})}),(0,l.jsx)(L.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,l.jsx)(K.Z,{step:.01,precision:2,width:200})}),(0,l.jsx)(L.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})}),(0,l.jsx)(L.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})}),(0,l.jsx)(L.Z.Item,{label:"Duration (eg: 30s, 30h, 30d)",name:"duration",children:(0,l.jsx)(z.Z,{})}),(0,l.jsx)(L.Z.Item,{label:"Metadata",name:"metadata",children:(0,l.jsx)(z.Z.TextArea,{rows:4,placeholder:"Enter metadata as JSON"})}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(W.ZP,{htmlType:"submit",children:"Create User"})})]})}),d&&(0,l.jsxs)(B.Z,{title:"Save Your User",visible:a,onOk:p,onCancel:j,footer:null,children:[(0,l.jsxs)("p",{children:["Please save this secret user somewhere safe and accessible. For security reasons, ",(0,l.jsx)("b",{children:"you will not be able to view it again"})," ","through your LiteLLM account. If you lose this secret user, you will need to generate a new one."]}),(0,l.jsx)("p",{children:null!=d?"API user: ".concat(d):"User being created, this might take 30s"})]})]})},e_=e=>{let{accessToken:t,token:s,keys:n,userRole:a,userID:o,setKeys:i}=e,[c,d]=(0,r.useState)(null),[h,m]=(0,r.useState)(null),[x,p]=(0,r.useState)(1);if((0,r.useEffect)(()=>{if(!t||!s||!a||!o)return;let e=async()=>{try{let e=await u(t,null,a,!0);console.log("user data response:",e),d(e)}catch(e){console.error("There was an error fetching the model data",e)}};t&&s&&a&&o&&!c&&e();let l=async()=>{try{let e=await _(t,null);console.log("user data response:",e),m(e)}catch(e){console.error("There was an error fetching the model data",e)}};a&&("Admin"==a||"Admin Viewer"==a)&&!h&&l()},[t,s,a,o]),!c||!t||!s||!a||!o)return(0,l.jsx)("div",{children:"Loading..."});let j=async e=>{try{let s=await _(t,e);console.log("user data response:",s),m(s)}catch(e){console.error("There was an error fetching the model data",e)}};return(0,l.jsx)("div",{style:{width:"100%"},children:(0,l.jsxs)(O.Z,{className:"gap-2 p-10 h-[75vh] w-full",children:[(0,l.jsx)(ek,{userID:o,accessToken:t}),(0,l.jsx)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh] mb-4",children:(0,l.jsxs)(ey.Z,{children:[(0,l.jsxs)(eg.Z,{variant:"line",defaultValue:"1",children:[(0,l.jsx)(ej.Z,{value:"1",children:"Key Owners"}),(0,l.jsx)(ej.Z,{value:"2",children:"End-Users"})]}),(0,l.jsxs)(eZ.Z,{children:[(0,l.jsx)(ew.Z,{children:(0,l.jsxs)($.Z,{className:"mt-5",children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"User ID"}),(0,l.jsx)(Q.Z,{children:"User Role"}),(0,l.jsx)(Q.Z,{children:"User Models"}),(0,l.jsx)(Q.Z,{children:"User Spend ($ USD)"}),(0,l.jsx)(Q.Z,{children:"User Max Budget ($ USD)"})]})}),(0,l.jsx)(H.Z,{children:c.map(e=>(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{children:e.user_id}),(0,l.jsx)(Y.Z,{children:e.user_role?e.user_role:"app_owner"}),(0,l.jsx)(Y.Z,{children:e.models&&e.models.length>0?e.models:"All Models"}),(0,l.jsx)(Y.Z,{children:e.spend?e.spend:0}),(0,l.jsx)(Y.Z,{children:e.max_budget?e.max_budget:"Unlimited"})]},e.user_id))})]})}),(0,l.jsxs)(ew.Z,{children:[(0,l.jsxs)("div",{className:"flex items-center",children:[(0,l.jsx)("div",{className:"flex-1"}),(0,l.jsxs)("div",{className:"flex-1 flex justify-between items-center",children:[(0,l.jsx)(R.Z,{className:"w-1/4 mr-2 text-right",children:"Key"}),(0,l.jsx)(eo.Z,{defaultValue:"1",className:"w-3/4",children:null==n?void 0:n.map((e,t)=>{if(e&&null!==e.key_name&&e.key_name.length>0)return(0,l.jsx)(ei.Z,{value:String(t),onClick:()=>j(e.token),children:e.key_name},t)})})]})]}),(0,l.jsxs)($.Z,{children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"End User"}),(0,l.jsx)(Q.Z,{children:"Spend"}),(0,l.jsx)(Q.Z,{children:"Total Events"})]})}),(0,l.jsx)(H.Z,{children:null==h?void 0:h.map((e,t)=>(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{children:e.end_user}),(0,l.jsx)(Y.Z,{children:e.total_spend}),(0,l.jsx)(Y.Z,{children:e.total_events})]},t))})]})]})]})]})}),function(){if(!c)return null;let e=Math.ceil(c.length/25),t=Math.min(25*x,c.length);return(0,l.jsxs)("div",{className:"flex justify-between items-center",children:[(0,l.jsxs)("div",{children:["Showing ",(x-1)*25+1," – ",t," of ",c.length]}),(0,l.jsxs)("div",{className:"flex",children:[(0,l.jsx)("button",{className:"bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-l focus:outline-none",disabled:1===x,onClick:()=>p(x-1),children:"← Prev"}),(0,l.jsx)("button",{className:"bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-r focus:outline-none",disabled:x===e,onClick:()=>p(x+1),children:"Next →"})]})]})}()]})})},eb=e=>{let{teams:t,searchParams:s,accessToken:n,setTeams:a,userID:i,userRole:d}=e,[h]=L.Z.useForm(),[m]=L.Z.useForm(),{Title:u,Paragraph:x}=ea.default,[p,j]=(0,r.useState)(""),[g,w]=(0,r.useState)(t?t[0]:null),[Z,f]=(0,r.useState)(!1),[k,_]=(0,r.useState)(!1),[b,v]=(0,r.useState)([]);(0,r.useEffect)(()=>{(async()=>{try{if(null===i||null===d)return;if(null!==n){let e=(await y(n,i,d)).data.map(e=>e.id);console.log("available_model_names:",e),v(e)}}catch(e){console.error("Error fetching user models:",e)}})()},[n,i,d]);let S=async e=>{try{if(null!=n){c.ZP.info("Creating Team");let s=await C(n,e);null!==t?a([...t,s]):a([s]),console.log("response for team create call: ".concat(s)),c.ZP.success("Team created"),f(!1)}}catch(e){console.error("Error creating the key:",e),c.ZP.error("Error creating the team: "+e)}},N=async e=>{try{if(null!=n&&null!=t){c.ZP.info("Adding Member");let s={role:"user",user_email:e.user_email,user_id:e.user_id},l=await T(n,g.team_id,s);console.log("response for team create call: ".concat(l.data));let r=t.findIndex(e=>(console.log("team.team_id=".concat(e.team_id,"; response.data.team_id=").concat(l.data.team_id)),e.team_id===l.data.team_id));if(console.log("foundIndex: ".concat(r)),-1!==r){let e=[...t];e[r]=l.data,a(e),w(l.data)}_(!1)}}catch(e){console.error("Error creating the key:",e)}};return console.log("received teams ".concat(t)),(0,l.jsx)("div",{className:"w-full mx-4",children:(0,l.jsxs)(O.Z,{numItems:1,className:"gap-2 p-2 h-[75vh] w-full",children:[(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(u,{level:4,children:"All Teams"}),(0,l.jsx)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,l.jsxs)($.Z,{children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"Team Name"}),(0,l.jsx)(Q.Z,{children:"Spend (USD)"}),(0,l.jsx)(Q.Z,{children:"Budget (USD)"}),(0,l.jsx)(Q.Z,{children:"Models"}),(0,l.jsx)(Q.Z,{children:"TPM / RPM Limits"})]})}),(0,l.jsx)(H.Z,{children:t&&t.length>0?t.map(e=>(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:e.team_alias}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:e.spend}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:e.max_budget?e.max_budget:"No limit"}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsx)(R.Z,{children:JSON.stringify(e.models?e.models:[])})}),(0,l.jsx)(Y.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,l.jsxs)(R.Z,{children:["TPM Limit:"," ",e.tpm_limit?e.tpm_limit:"Unlimited"," ",(0,l.jsx)("br",{}),"RPM Limit:"," ",e.rpm_limit?e.rpm_limit:"Unlimited"]})})]},e.team_id)):null})]})})]}),(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(o.Z,{className:"mx-auto",onClick:()=>f(!0),children:"+ Create New Team"}),(0,l.jsx)(B.Z,{title:"Create Team",visible:Z,width:800,footer:null,onOk:()=>{f(!1),h.resetFields()},onCancel:()=>{f(!1),h.resetFields()},children:(0,l.jsxs)(L.Z,{form:h,onFinish:S,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(L.Z.Item,{label:"Team Name",name:"team_alias",children:(0,l.jsx)(z.Z,{})}),(0,l.jsx)(L.Z.Item,{label:"Models",name:"models",children:(0,l.jsx)(U.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:b.map(e=>(0,l.jsx)(U.default.Option,{value:e,children:e},e))})}),(0,l.jsx)(L.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,l.jsx)(K.Z,{step:.01,precision:2,width:200})}),(0,l.jsx)(L.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})}),(0,l.jsx)(L.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,l.jsx)(K.Z,{step:1,width:400})})]}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(W.ZP,{htmlType:"submit",children:"Create Team"})})]})})]}),(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(u,{level:4,children:"Team Members"}),(0,l.jsx)(x,{children:"If you belong to multiple teams, this setting controls which teams members you see."}),t&&t.length>0?(0,l.jsx)(eo.Z,{defaultValue:"0",children:t.map((e,t)=>(0,l.jsx)(ei.Z,{value:String(t),onClick:()=>{w(e)},children:e.team_alias},t))}):(0,l.jsxs)(x,{children:["No team created. ",(0,l.jsx)("b",{children:"Defaulting to personal account."})]})]}),(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsx)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,l.jsxs)($.Z,{children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"Member Name"}),(0,l.jsx)(Q.Z,{children:"Role"})]})}),(0,l.jsx)(H.Z,{children:g?g.members_with_roles.map((e,t)=>(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{children:e.user_email?e.user_email:e.user_id?e.user_id:null}),(0,l.jsx)(Y.Z,{children:e.role})]},t)):null})]})})}),(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(o.Z,{className:"mx-auto mb-5",onClick:()=>_(!0),children:"+ Add member"}),(0,l.jsx)(B.Z,{title:"Add member",visible:k,width:800,footer:null,onOk:()=>{_(!1),m.resetFields()},onCancel:()=>{_(!1),m.resetFields()},children:(0,l.jsxs)(L.Z,{form:h,onFinish:N,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(L.Z.Item,{label:"Email",name:"user_email",className:"mb-4",children:(0,l.jsx)(z.Z,{name:"user_email",className:"px-3 py-2 border rounded-md w-full"})}),(0,l.jsx)("div",{className:"text-center mb-4",children:"OR"}),(0,l.jsx)(L.Z.Item,{label:"User ID",name:"user_id",className:"mb-4",children:(0,l.jsx)(z.Z,{name:"user_id",className:"px-3 py-2 border rounded-md w-full"})})]}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(W.ZP,{htmlType:"submit",children:"Add member"})})]})})]})]})})},ev=s(8510),eS=e=>{let{searchParams:t,accessToken:s}=e,[n]=L.Z.useForm(),[a]=L.Z.useForm(),{Title:i,Paragraph:d}=ea.default,[h,m]=(0,r.useState)(""),[u,x]=(0,r.useState)(null),[p,j]=(0,r.useState)(!1);(0,r.useEffect)(()=>{(async()=>{if(null!=s){let e=[],t=await A(s,"proxy_admin_viewer");t.forEach(t=>{e.push({user_role:t.user_role,user_id:t.user_id,user_email:t.user_email})}),console.log("proxy viewers: ".concat(t));let l=await A(s,"proxy_admin");l.forEach(t=>{e.push({user_role:t.user_role,user_id:t.user_id,user_email:t.user_email})}),console.log("proxy admins: ".concat(l)),console.log("combinedList: ".concat(e)),x(e)}})()},[s]);let y=async e=>{try{if(null!=s&&null!=u){c.ZP.info("Making API Call"),e.user_email,e.user_id;let t=await I(s,e);console.log("response for team create call: ".concat(t));let l=u.findIndex(e=>(console.log("user.user_id=".concat(e.user_id,"; response.user_id=").concat(t.user_id)),e.user_id===t.user_id));console.log("foundIndex: ".concat(l)),-1==l&&(console.log("updates admin with new user"),u.push(t),x(u)),j(!1)}}catch(e){console.error("Error creating the key:",e)}};return console.log("admins: ".concat(null==u?void 0:u.length)),(0,l.jsxs)("div",{className:"w-full m-2",children:[(0,l.jsx)(i,{level:4,children:"Restricted Access"}),(0,l.jsxs)(d,{children:["Add other people to just view spend. They cannot create keys, teams or grant users access to new models."," ",(0,l.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/ui#restrict-ui-access",children:"Requires SSO Setup"})]}),(0,l.jsxs)(O.Z,{numItems:1,className:"gap-2 p-0 w-full",children:[(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsx)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,l.jsxs)($.Z,{children:[(0,l.jsx)(X.Z,{children:(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Q.Z,{children:"Member Name"}),(0,l.jsx)(Q.Z,{children:"Role"}),(0,l.jsx)(Q.Z,{children:"Action"})]})}),(0,l.jsx)(H.Z,{children:u?u.map((e,t)=>(0,l.jsxs)(ee.Z,{children:[(0,l.jsx)(Y.Z,{children:e.user_email?e.user_email:e.user_id?e.user_id:null}),(0,l.jsx)(Y.Z,{children:e.user_role}),(0,l.jsx)(Y.Z,{children:(0,l.jsx)(G.Z,{icon:ev.Z,size:"sm"})})]},t)):null})]})})}),(0,l.jsxs)(F.Z,{numColSpan:1,children:[(0,l.jsx)(o.Z,{className:"mx-auto mb-5",onClick:()=>j(!0),children:"+ Add viewer"}),(0,l.jsx)(B.Z,{title:"Add viewer",visible:p,width:800,footer:null,onOk:()=>{j(!1),a.resetFields()},onCancel:()=>{j(!1),a.resetFields()},children:(0,l.jsxs)(L.Z,{form:n,onFinish:y,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(L.Z.Item,{label:"Email",name:"user_email",className:"mb-4",children:(0,l.jsx)(z.Z,{name:"user_email",className:"px-3 py-2 border rounded-md w-full"})}),(0,l.jsx)("div",{className:"text-center mb-4",children:"OR"}),(0,l.jsx)(L.Z.Item,{label:"User ID",name:"user_id",className:"mb-4",children:(0,l.jsx)(z.Z,{name:"user_id",className:"px-3 py-2 border rounded-md w-full"})})]}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(W.ZP,{htmlType:"submit",children:"Add member"})})]})})]})]})]})},eN=s(12968),eA=s(67951);async function eC(e,t,s,l){console.log("isLocal:",!1);let r=window.location.origin,n=new eN.ZP.OpenAI({apiKey:l,baseURL:r,dangerouslyAllowBrowser:!0});for await(let l of(await n.chat.completions.create({model:s,stream:!0,messages:[{role:"user",content:e}]})))console.log(l),l.choices[0].delta.content&&t(l.choices[0].delta.content)}var eT=e=>{let{accessToken:t,token:s,userRole:n,userID:a}=e,[o,i]=(0,r.useState)(""),[c,d]=(0,r.useState)([]),[h,m]=(0,r.useState)(void 0),[u,x]=(0,r.useState)(null);(0,r.useEffect)(()=>{t&&s&&n&&a&&(async()=>{let e=await y(t,a,n);console.log("model_info:",e),(null==e?void 0:e.data.length)>0&&(x(e.data),m(e.data[0].id))})()},[t,a,n]);let p=(e,t)=>{d(s=>{let l=s[s.length-1];return l&&l.role===e?[...s.slice(0,s.length-1),{role:e,content:l.content+t}]:[...s,{role:e,content:t}]})},j=async()=>{if(""!==o.trim()&&t&&s&&n&&a){d(e=>[...e,{role:"user",content:o}]);try{h&&await eC(o,e=>p("assistant",e),h,t)}catch(e){console.error("Error fetching model response",e),p("assistant","Error fetching model response")}i("")}};if(n&&"Admin Viewer"==n){let{Title:e,Paragraph:t}=ea.default;return(0,l.jsxs)("div",{children:[(0,l.jsx)(e,{level:1,children:"Access Denied"}),(0,l.jsx)(t,{children:"Ask your proxy admin for access to test models"})]})}return(0,l.jsx)("div",{style:{width:"100%",position:"relative"},children:(0,l.jsx)(O.Z,{className:"gap-2 p-10 h-[75vh] w-full",children:(0,l.jsx)(M.Z,{children:(0,l.jsxs)(ey.Z,{children:[(0,l.jsxs)(eg.Z,{className:"mt-4",children:[(0,l.jsx)(ej.Z,{children:"Chat"}),(0,l.jsx)(ej.Z,{children:"API Reference"})]}),(0,l.jsxs)(eZ.Z,{children:[(0,l.jsxs)(ew.Z,{children:[(0,l.jsxs)("div",{children:[(0,l.jsx)("label",{children:"Select Model:"}),(0,l.jsx)("select",{value:h||"",onChange:e=>m(e.target.value),children:null==u?void 0:u.map(e=>(0,l.jsx)("option",{value:e.id,children:e.id},e.id))})]}),(0,l.jsxs)($.Z,{className:"mt-5",style:{display:"block",maxHeight:"60vh",overflowY:"auto"},children:[(0,l.jsx)(X.Z,{children:(0,l.jsx)(ee.Z,{children:(0,l.jsx)(Y.Z,{children:(0,l.jsx)(D.Z,{children:"Chat"})})})}),(0,l.jsx)(H.Z,{children:c.map((e,t)=>(0,l.jsx)(ee.Z,{children:(0,l.jsx)(Y.Z,{children:"".concat(e.role,": ").concat(e.content)})},t))})]}),(0,l.jsx)("div",{className:"mt-3",style:{position:"absolute",bottom:5,width:"95%"},children:(0,l.jsxs)("div",{className:"flex",children:[(0,l.jsx)("input",{type:"text",value:o,onChange:e=>i(e.target.value),className:"flex-1 p-2 border rounded-md mr-2",placeholder:"Type your message..."}),(0,l.jsx)("button",{onClick:j,className:"p-2 bg-blue-500 text-white rounded-md",children:"Send"})]})})]}),(0,l.jsx)(ew.Z,{children:(0,l.jsxs)(ey.Z,{children:[(0,l.jsxs)(eg.Z,{children:[(0,l.jsx)(ej.Z,{children:"OpenAI Python SDK"}),(0,l.jsx)(ej.Z,{children:"LlamaIndex"}),(0,l.jsx)(ej.Z,{children:"Langchain Py"})]}),(0,l.jsxs)(eZ.Z,{children:[(0,l.jsx)(ew.Z,{children:(0,l.jsx)(eA.Z,{language:"python",children:'\nimport openai\nclient = openai.OpenAI(\n api_key="your_api_key",\n base_url="http://0.0.0.0:4000" # proxy base url\n)\n\nresponse = client.chat.completions.create(\n model="gpt-3.5-turbo", # model to use from Models Tab\n messages = [\n {\n "role": "user",\n "content": "this is a test request, write a short poem"\n }\n ],\n extra_body={\n "metadata": {\n "generation_name": "ishaan-generation-openai-client",\n "generation_id": "openai-client-gen-id22",\n "trace_id": "openai-client-trace-id22",\n "trace_user_id": "openai-client-user-id2"\n }\n }\n)\n\nprint(response)\n '})}),(0,l.jsx)(ew.Z,{children:(0,l.jsx)(eA.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="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,l.jsx)(ew.Z,{children:(0,l.jsx)(eA.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:8000",\n model = "gpt-3.5-turbo",\n temperature=0.1,\n extra_body={\n "metadata": {\n "generation_name": "ishaan-generation-langchain-client",\n "generation_id": "langchain-client-gen-id22",\n "trace_id": "langchain-client-trace-id22",\n "trace_user_id": "langchain-client-user-id2"\n }\n }\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 '})})]})]})})]})]})})})})},eI=s(33509),eP=s(30569);let{Sider:eE}=eI.default;var eF=e=>{let{setPage:t,userRole:s,defaultSelectedKey:r}=e;return"Admin Viewer"==s?(0,l.jsx)(eI.default,{style:{minHeight:"100vh",maxWidth:"120px"},children:(0,l.jsx)(eE,{width:120,children:(0,l.jsxs)(eP.Z,{mode:"inline",defaultSelectedKeys:r||["4"],style:{height:"100%",borderRight:0},children:[(0,l.jsx)(eP.Z.Item,{onClick:()=>t("api-keys"),children:"API Keys"},"4"),(0,l.jsx)(eP.Z.Item,{onClick:()=>t("models"),children:"Models"},"2"),(0,l.jsx)(eP.Z.Item,{onClick:()=>t("llm-playground"),children:"Chat UI"},"3"),(0,l.jsx)(eP.Z.Item,{onClick:()=>t("usage"),children:"Usage"},"1")]})})}):(0,l.jsx)(eI.default,{style:{minHeight:"100vh",maxWidth:"120px"},children:(0,l.jsx)(eE,{width:120,children:(0,l.jsxs)(eP.Z,{mode:"inline",defaultSelectedKeys:r||["1"],style:{height:"100%",borderRight:0},children:[(0,l.jsx)(eP.Z.Item,{onClick:()=>t("api-keys"),children:"API Keys"},"1"),(0,l.jsx)(eP.Z.Item,{onClick:()=>t("models"),children:"Models"},"2"),(0,l.jsx)(eP.Z.Item,{onClick:()=>t("llm-playground"),children:"Chat UI"},"3"),(0,l.jsx)(eP.Z.Item,{onClick:()=>t("usage"),children:"Usage"},"4"),"Admin"==s?(0,l.jsx)(eP.Z.Item,{onClick:()=>t("users"),children:"Users"},"5"):null,"Admin"==s?(0,l.jsx)(eP.Z.Item,{onClick:()=>t("teams"),children:"Teams"},"6"):null,"Admin"==s?(0,l.jsx)(eP.Z.Item,{onClick:()=>t("admin-panel"),children:"Admin"},"7"):null]})})})},eO=e=>{let{accessToken:t,token:s,userRole:n,userID:a}=e,o=new Date,[i,c]=(0,r.useState)([]),[d,h]=(0,r.useState)([]),[m,u]=(0,r.useState)([]),[x,p]=(0,r.useState)([]),[j,y]=(0,r.useState)([]),[g,_]=(0,r.useState)([]),[S,N]=(0,r.useState)([]),A=new Date(o.getFullYear(),o.getMonth(),1),C=new Date(o.getFullYear(),o.getMonth()+1,0),T=P(A),I=P(C);function P(e){let t=e.getFullYear(),s=e.getMonth()+1,l=e.getDate();return"".concat(t,"-").concat(s<10?"0"+s:s,"-").concat(l<10?"0"+l:l)}return console.log("Start date is ".concat(T)),console.log("End date is ".concat(I)),(0,r.useEffect)(()=>{t&&s&&n&&a&&(async()=>{try{if(console.log("user role: ".concat(n)),"Admin"==n||"Admin Viewer"==n){let e=await f(t);c(e);let s=(await k(t)).map(e=>({key:(e.key_name||e.key_alias||e.api_key).substring(0,7),spend:e.total_spend}));h(s);let l=(await b(t)).map(e=>({key:e.model,spend:e.total_spend}));u(l);let r=await w(t);console.log("teamSpend",r),y(r.daily_spend),_(r.teams),N(r.total_spend_per_team)}else"App Owner"==n&&await Z(t,s,n,a,T,I).then(async e=>{if(console.log("result from spend logs call",e),"daily_spend"in e){let t=e.daily_spend;console.log("daily spend",t),c(t);let s=e.top_api_keys;h(s)}else{let s=(await v(t,function(e){let t=[];e.forEach(e=>{Object.entries(e).forEach(e=>{let[s,l]=e;"spend"!==s&&"startTime"!==s&&"models"!==s&&"users"!==s&&t.push({key:s,spend:l})})}),t.sort((e,t)=>Number(t.spend)-Number(e.spend));let s=t.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||e.token).substring(0,7),spend:e.spend}));h(s),p(function(e){let t={};e.forEach(e=>{Object.entries(e.users).forEach(e=>{let[s,l]=e;""!==s&&null!=s&&"None"!=s&&(t[s]||(t[s]=0),t[s]+=l)})});let s=Object.entries(t).map(e=>{let[t,s]=e;return{user_id:t,spend:s}});s.sort((e,t)=>t.spend-e.spend);let l=s.slice(0,5);return console.log("topKeys: ".concat(Object.values(l[0]))),l}(e)),c(e)}})}catch(e){console.error("There was an error fetching the data",e)}})()},[t,s,n,a,T,I]),(0,l.jsx)("div",{style:{width:"100%"},children:(0,l.jsxs)(ey.Z,{children:[(0,l.jsxs)(eg.Z,{className:"mt-4",children:[(0,l.jsx)(ej.Z,{children:"All Up"}),(0,l.jsx)(ej.Z,{children:"Team Based Usage"})]}),(0,l.jsxs)(eZ.Z,{children:[(0,l.jsx)(ew.Z,{children:(0,l.jsxs)(O.Z,{numItems:2,className:"gap-2 p-10 h-[75vh] w-full",children:[(0,l.jsx)(F.Z,{numColSpan:2,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Monthly Spend"}),(0,l.jsx)(et.Z,{data:i,index:"date",categories:["spend"],colors:["blue"],valueFormatter:e=>"$ ".concat(new Intl.NumberFormat("us").format(e).toString()),yAxisWidth:100,tickGap:5})]})}),(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Top API Keys"}),(0,l.jsx)(et.Z,{className:"mt-4 h-40",data:d,index:"key",categories:["spend"],colors:["blue"],yAxisWidth:80,tickGap:5,layout:"vertical",showXAxis:!1,showLegend:!1})]})}),(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Top Users"}),(0,l.jsx)(et.Z,{className:"mt-4 h-40",data:x,index:"user_id",categories:["spend"],colors:["blue"],yAxisWidth:200,layout:"vertical",showXAxis:!1,showLegend:!1})]})}),(0,l.jsx)(F.Z,{numColSpan:1,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Top Models"}),(0,l.jsx)(et.Z,{className:"mt-4 h-40",data:m,index:"key",categories:["spend"],colors:["blue"],yAxisWidth:200,layout:"vertical",showXAxis:!1,showLegend:!1})]})})]})}),(0,l.jsx)(ew.Z,{children:(0,l.jsxs)(O.Z,{numItems:2,className:"gap-2 p-10 h-[75vh] w-full",children:[(0,l.jsx)(F.Z,{numColSpan:2,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Daily Spend Per Team"}),(0,l.jsx)(et.Z,{className:"h-72",data:j,index:"date",categories:g,yAxisWidth:30,stack:!0})]})}),(0,l.jsx)(F.Z,{numColSpan:2,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(D.Z,{children:"Total Spend Per Team"}),(0,l.jsx)(et.Z,{className:"h-72",data:S,index:"team_id",categories:["total_spend"],yAxisWidth:30})]})})]})})]})]})})},eM=()=>{let{Title:e,Paragraph:t}=ea.default,[s,a]=(0,r.useState)(""),[o,c]=(0,r.useState)(null),[d,h]=(0,r.useState)(null),[m,u]=(0,r.useState)(null),[x,p]=(0,r.useState)(!0),j=(0,n.useSearchParams)(),y=j.get("userID"),g=j.get("token"),[w,Z]=(0,r.useState)("api-keys"),[f,k]=(0,r.useState)(null);return(0,r.useEffect)(()=>{if(g){let e=(0,ed.o)(g);if(e){if(console.log("Decoded token:",e),console.log("Decoded key:",e.key),k(e.key),e.user_role){let t=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"app_user":return"App User";default:return"Unknown Role"}}(e.user_role);console.log("Decoded user_role:",t),a(t),"Admin Viewer"==t&&Z("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?p("username_password"==e.login_method):console.log("User Email is not set ".concat(e))}}},[g]),(0,l.jsx)(r.Suspense,{fallback:(0,l.jsx)("div",{children:"Loading..."}),children:(0,l.jsxs)("div",{className:"flex flex-col min-h-screen",children:[(0,l.jsx)(i,{userID:y,userRole:s,userEmail:o,showSSOBanner:x}),(0,l.jsxs)("div",{className:"flex flex-1 overflow-auto",children:[(0,l.jsx)(eF,{setPage:Z,userRole:s,defaultSelectedKey:null}),"api-keys"==w?(0,l.jsx)(eh,{userID:y,userRole:s,teams:d,keys:m,setUserRole:a,userEmail:o,setUserEmail:c,setTeams:h,setKeys:u}):"models"==w?(0,l.jsx)(ep,{userID:y,userRole:s,token:g,accessToken:f}):"llm-playground"==w?(0,l.jsx)(eT,{userID:y,userRole:s,token:g,accessToken:f}):"users"==w?(0,l.jsx)(e_,{userID:y,userRole:s,token:g,keys:m,accessToken:f,setKeys:u}):"teams"==w?(0,l.jsx)(eb,{teams:d,setTeams:h,searchParams:j,accessToken:f,userID:y,userRole:s}):"admin-panel"==w?(0,l.jsx)(eS,{setTeams:h,searchParams:j,accessToken:f}):(0,l.jsx)(eO,{userID:y,userRole:s,token:g,accessToken:f})]})]})})}}},function(e){e.O(0,[730,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 c3784800b..acaf479cc 100644 --- a/ui/litellm-dashboard/out/index.html +++ b/ui/litellm-dashboard/out/index.html @@ -1 +1 @@ -🚅 LiteLLM \ No newline at end of file +🚅 LiteLLM \ No newline at end of file diff --git a/ui/litellm-dashboard/out/index.txt b/ui/litellm-dashboard/out/index.txt index c63474e28..90aef107e 100644 --- a/ui/litellm-dashboard/out/index.txt +++ b/ui/litellm-dashboard/out/index.txt @@ -1,7 +1,7 @@ 2:I[77831,[],""] -3:I[92182,["730","static/chunks/730-1411b729a1c79695.js","931","static/chunks/app/page-a94f48a4c941dbe4.js"],""] +3:I[92182,["730","static/chunks/730-1411b729a1c79695.js","931","static/chunks/app/page-07e952a07a29317d.js"],""] 4:I[5613,[],""] 5:I[31778,[],""] -0:["IXxGmLpL0ryrAsqCmdljD",[[["",{"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_c23dc8","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/68a21c6e6697f7ca.css","precedence":"next","crossOrigin":""}]],"$L6"]]]] +0:["1uJOwOGpazhj7AOlXoDnP",[[["",{"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_c23dc8","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/68a21c6e6697f7ca.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"}],["$","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/src/components/user_dashboard.tsx b/ui/litellm-dashboard/src/components/user_dashboard.tsx index ecbd0f6f9..9180fa3cd 100644 --- a/ui/litellm-dashboard/src/components/user_dashboard.tsx +++ b/ui/litellm-dashboard/src/components/user_dashboard.tsx @@ -226,7 +226,6 @@ const UserDashboard: React.FC = ({ userID={userID} team={selectedTeam ? selectedTeam : null} userRole={userRole} - userModels={userModels} accessToken={accessToken} data={keys} setData={setKeys} From 082f1e40851def587d730743de57f731eaf2fc56 Mon Sep 17 00:00:00 2001 From: Krrish Dholakia Date: Thu, 28 Mar 2024 09:14:30 -0700 Subject: [PATCH 32/54] fix(proxy_server.py): allow user to pass in spend logs collector url --- litellm/proxy/proxy_server.py | 28 +++++++++++++++------------- litellm/proxy/utils.py | 24 +++++++++++------------- 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/litellm/proxy/proxy_server.py b/litellm/proxy/proxy_server.py index f2918a04d..4440584b1 100644 --- a/litellm/proxy/proxy_server.py +++ b/litellm/proxy/proxy_server.py @@ -1233,10 +1233,11 @@ async def update_database( user_ids.append(litellm_proxy_budget_name) ### KEY CHANGE ### for _id in user_ids: - prisma_client.user_list_transactons[_id] = ( - response_cost - + prisma_client.user_list_transactons.get(_id, 0) - ) + if _id is not None: + prisma_client.user_list_transactons[_id] = ( + response_cost + + prisma_client.user_list_transactons.get(_id, 0) + ) if end_user_id is not None: prisma_client.end_user_list_transactons[end_user_id] = ( response_cost @@ -1364,16 +1365,17 @@ async def update_database( ) payload["spend"] = response_cost - if prisma_client is not None: + if ( + os.getenv("SPEND_LOGS_URL", None) is not None + and prisma_client is not None + ): + if isinstance(payload["startTime"], datetime): + payload["startTime"] = payload["startTime"].isoformat() + if isinstance(payload["endTime"], datetime): + payload["endTime"] = payload["endTime"].isoformat() prisma_client.spend_log_transactons.append(payload) - # if db_writer_client is not None: - # print("Tries to make call") - # response = await db_writer_client.post( - # url="http://0.0.0.0:3000/spend/update", - # data=json.dumps(payload), - # headers={"Content-Type": "application/json"}, - # ) - # print(f"response: {response}") + elif prisma_client is not None: + await prisma_client.insert_data(data=payload, table_name="spend") except Exception as e: verbose_proxy_logger.debug( f"Update Spend Logs DB failed to execute - {str(e)}\n{traceback.format_exc()}" diff --git a/litellm/proxy/utils.py b/litellm/proxy/utils.py index 1d5f5f819..1102766f9 100644 --- a/litellm/proxy/utils.py +++ b/litellm/proxy/utils.py @@ -1717,11 +1717,6 @@ def get_logging_payload(kwargs, response_obj, start_time, end_time): # hash the api_key api_key = hash_token(api_key) - # jsonify datetime object - # if isinstance(start_time, datetime): - # start_time = start_time.isoformat() - # if isinstance(end_time, datetime): - # end_time = end_time.isoformat() # clean up litellm metadata if isinstance(metadata, dict): clean_metadata = {} @@ -2000,14 +1995,17 @@ async def update_spend(prisma_client: PrismaClient, db_writer_client: HTTPHandle raise e ### UPDATE SPEND LOGS ### - # if len(prisma_client.spend_log_transactons) > 0: - # response = await db_writer_client.post( - # url="http://0.0.0.0:3000/spend/update", - # data=prisma_client.spend_log_transactons, - # headers={"Content-Type": "application/json"}, - # ) - # if response.status_code == 200: - # prisma_client.spend_log_transactons = [] + base_url = os.getenv("SPEND_LOGS_URL", None) + if len(prisma_client.spend_log_transactons) > 0 and base_url is not None: + if not base_url.endswith("/"): + base_url += "/" + response = await db_writer_client.post( + url=base_url + "spend/update", + data=json.dumps(prisma_client.spend_log_transactons), # type: ignore + headers={"Content-Type": "application/json"}, + ) + if response.status_code == 200: + prisma_client.spend_log_transactons = [] # async def monitor_spend_list(prisma_client: PrismaClient): From 3a820757c2a9a222d4df1a7edc876720b9b58abf Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Thu, 28 Mar 2024 09:14:50 -0700 Subject: [PATCH 33/54] =?UTF-8?q?bump:=20version=201.34.8=20=E2=86=92=201.?= =?UTF-8?q?34.9?= 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 8cc95050e..379220760 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "litellm" -version = "1.34.8" +version = "1.34.9" description = "Library to easily interface with LLM API providers" authors = ["BerriAI"] license = "MIT" @@ -80,7 +80,7 @@ requires = ["poetry-core", "wheel"] build-backend = "poetry.core.masonry.api" [tool.commitizen] -version = "1.34.8" +version = "1.34.9" version_files = [ "pyproject.toml:^version" ] From 6ba774ace414cd04c5d3a2e0564c762fb13cd9ef Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Thu, 28 Mar 2024 09:17:12 -0700 Subject: [PATCH 34/54] (ui) use default teams --- ui/litellm-dashboard/src/components/create_key_button.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ui/litellm-dashboard/src/components/create_key_button.tsx b/ui/litellm-dashboard/src/components/create_key_button.tsx index 7ce84b1f5..86ca6605f 100644 --- a/ui/litellm-dashboard/src/components/create_key_button.tsx +++ b/ui/litellm-dashboard/src/components/create_key_button.tsx @@ -129,7 +129,7 @@ const CreateKey: React.FC = ({ @@ -181,7 +181,7 @@ const CreateKey: React.FC = ({ - + From 7f793246c21583240d65bb89bb030ec08aa7f2a9 Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Thu, 28 Mar 2024 09:41:15 -0700 Subject: [PATCH 35/54] (feat) return team alias when hitting user/info --- litellm/proxy/proxy_server.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/litellm/proxy/proxy_server.py b/litellm/proxy/proxy_server.py index 73cbd55e4..be6c12db1 100644 --- a/litellm/proxy/proxy_server.py +++ b/litellm/proxy/proxy_server.py @@ -5290,6 +5290,18 @@ async def user_info( key = key.dict() key.pop("token", None) + if ( + "team_id" in key + and key["team_id"] is not None + and key["team_id"] != "litellm-dashboard" + ): + team_info = await prisma_client.get_data( + team_id=key["team_id"], table_name="team" + ) + key["team_alias"] = team_info["team_alias"] + else: + key["team_alias"] = "None" + response_data = { "user_id": user_id, "user_info": user_info, From 746cd3da11840d3cc366fe7e5212ac2e96a47011 Mon Sep 17 00:00:00 2001 From: Krrish Dholakia Date: Thu, 28 Mar 2024 10:12:53 -0700 Subject: [PATCH 36/54] docs(gemini.md): add link to google ai studio api key --- docs/my-website/docs/providers/gemini.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/my-website/docs/providers/gemini.md b/docs/my-website/docs/providers/gemini.md index 21e239d2b..628eeb999 100644 --- a/docs/my-website/docs/providers/gemini.md +++ b/docs/my-website/docs/providers/gemini.md @@ -2,6 +2,7 @@ ## Pre-requisites * `pip install -q google-generativeai` +* Get API Key - https://aistudio.google.com/ # Gemini-Pro ## Sample Usage From beb72f94e073a1a19f955d823117cb5c66098e17 Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Thu, 28 Mar 2024 10:16:07 -0700 Subject: [PATCH 37/54] (feat) return team alias in keys --- litellm/proxy/proxy_server.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/litellm/proxy/proxy_server.py b/litellm/proxy/proxy_server.py index be6c12db1..2fe4a3523 100644 --- a/litellm/proxy/proxy_server.py +++ b/litellm/proxy/proxy_server.py @@ -5282,6 +5282,7 @@ async def user_info( user_info = {"spend": spend} ## REMOVE HASHED TOKEN INFO before returning ## + returned_keys = [] for key in keys: try: key = key.model_dump() # noqa @@ -5298,14 +5299,16 @@ async def user_info( team_info = await prisma_client.get_data( team_id=key["team_id"], table_name="team" ) - key["team_alias"] = team_info["team_alias"] + team_alias = getattr(team_info, "team_alias", None) + key["team_alias"] = team_alias else: key["team_alias"] = "None" + returned_keys.append(key) response_data = { "user_id": user_id, "user_info": user_info, - "keys": keys, + "keys": returned_keys, "teams": team_list, } return response_data From b54e2f23a8c0cef019b46186199956b9a1e05fc4 Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Thu, 28 Mar 2024 10:23:42 -0700 Subject: [PATCH 38/54] (ui) show team alias on ui --- ui/litellm-dashboard/src/components/view_key_table.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/litellm-dashboard/src/components/view_key_table.tsx b/ui/litellm-dashboard/src/components/view_key_table.tsx index d987e3462..513693430 100644 --- a/ui/litellm-dashboard/src/components/view_key_table.tsx +++ b/ui/litellm-dashboard/src/components/view_key_table.tsx @@ -141,7 +141,7 @@ const ViewKeyTable: React.FC = ({ /> - {item.team_id} + {item.team_alias && item.team_alias != "None" ? item.team_alias : item.team_id} {JSON.stringify(item.metadata).slice(0, 400)} From 9a3201a321d52b7865ecb469051fd3250371df56 Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Thu, 28 Mar 2024 10:39:19 -0700 Subject: [PATCH 39/54] (feat) use team_id when creating keys --- .../src/components/create_key_button.tsx | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/ui/litellm-dashboard/src/components/create_key_button.tsx b/ui/litellm-dashboard/src/components/create_key_button.tsx index 86ca6605f..82ce56ed8 100644 --- a/ui/litellm-dashboard/src/components/create_key_button.tsx +++ b/ui/litellm-dashboard/src/components/create_key_button.tsx @@ -127,13 +127,15 @@ const CreateKey: React.FC = ({ - - + + +