diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 51c5789717..b7a1643686 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,6 +1,3 @@ - - - ## Title @@ -18,7 +15,6 @@ ๐Ÿ› Bug Fix ๐Ÿงน Refactoring ๐Ÿ“– Documentation -๐Ÿ’ป Development Environment ๐Ÿš„ Infrastructure โœ… Test @@ -26,22 +22,8 @@ -## Testing +## [REQUIRED] Testing - Attach a screenshot of any new tests passing locall +If UI changes, send a screenshot/GIF of working UI fixes -## Notes - - - - - -## Pre-Submission Checklist (optional but appreciated): - -- [ ] I have included relevant documentation updates (stored in /docs/my-website) - -## OS Tests (optional but appreciated): - -- [ ] Tested on Windows -- [ ] Tested on MacOS -- [ ] Tested on Linux diff --git a/docs/my-website/docs/completion/input.md b/docs/my-website/docs/completion/input.md index 451deaac47..ba01dd9d87 100644 --- a/docs/my-website/docs/completion/input.md +++ b/docs/my-website/docs/completion/input.md @@ -37,11 +37,12 @@ print(response) # ["max_tokens", "tools", "tool_choice", "stream"] This is a list of openai params we translate across providers. -This list is constantly being updated. +Use `litellm.get_supported_openai_params()` for an updated list of params for each model + provider | Provider | temperature | max_tokens | top_p | stream | stop | n | presence_penalty | frequency_penalty | functions | function_call | logit_bias | user | response_format | seed | tools | tool_choice | logprobs | top_logprobs | extra_headers | |---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|--| -|Anthropic| โœ… | โœ… | โœ… | โœ… | โœ… | | | | | | +|Anthropic| โœ… | โœ… | โœ… | โœ… | โœ… | | | | | | | | | | โœ… | โœ… | +|Anthropic| โœ… | โœ… | โœ… | โœ… | โœ… | | | | | | | | โœ… | โœ… | โœ… | โœ… | |OpenAI| โœ… | โœ… | โœ… | โœ… | โœ… | โœ… | โœ… | โœ… | โœ… | โœ… |โœ… | โœ… | โœ… | โœ… |โœ… | โœ… | โœ… | โœ… | โœ… | |Azure OpenAI| โœ… | โœ… | โœ… | โœ… | โœ… | โœ… | โœ… | โœ… | โœ… | โœ… |โœ… | โœ… | โœ… | โœ… |โœ… | โœ… | | | โœ… | |Replicate | โœ… | โœ… | โœ… | โœ… | โœ… | | | | | | diff --git a/docs/my-website/docs/exception_mapping.md b/docs/my-website/docs/exception_mapping.md index 2345e9f838..5e6006ebee 100644 --- a/docs/my-website/docs/exception_mapping.md +++ b/docs/my-website/docs/exception_mapping.md @@ -106,11 +106,12 @@ To see how it's implemented - [check out the code](https://github.com/BerriAI/li ## Custom mapping list -Base case - we return the original exception. +Base case - we return `litellm.APIConnectionError` exception (inherits from openai's APIConnectionError exception). | custom_llm_provider | Timeout | ContextWindowExceededError | BadRequestError | NotFoundError | ContentPolicyViolationError | AuthenticationError | APIError | RateLimitError | ServiceUnavailableError | PermissionDeniedError | UnprocessableEntityError | |----------------------------|---------|----------------------------|------------------|---------------|-----------------------------|---------------------|----------|----------------|-------------------------|-----------------------|-------------------------| | openai | โœ“ | โœ“ | โœ“ | | โœ“ | โœ“ | | | | | | +| watsonx | | | | | | | |โœ“| | | | | text-completion-openai | โœ“ | โœ“ | โœ“ | | โœ“ | โœ“ | | | | | | | custom_openai | โœ“ | โœ“ | โœ“ | | โœ“ | โœ“ | | | | | | | openai_compatible_providers| โœ“ | โœ“ | โœ“ | | โœ“ | โœ“ | | | | | | diff --git a/docs/my-website/docs/observability/langfuse_integration.md b/docs/my-website/docs/observability/langfuse_integration.md index 7ba204497a..508ba63cde 100644 --- a/docs/my-website/docs/observability/langfuse_integration.md +++ b/docs/my-website/docs/observability/langfuse_integration.md @@ -213,8 +213,20 @@ chat(messages) ## Redacting Messages, Response Content from Langfuse Logging +### Redact Messages and Responses from all Langfuse Logging + Set `litellm.turn_off_message_logging=True` This will prevent the messages and responses from being logged to langfuse, but request metadata will still be logged. +### Redact Messages and Responses from specific Langfuse Logging + +In the metadata typically passed for text completion or embedding calls you can set specific keys to mask the messages and responses for this call. + +Setting `mask_input` to `True` will mask the input from being logged for this call + +Setting `mask_output` to `True` will make the output from being logged for this call. + +Be aware that if you are continuing an existing trace, and you set `update_trace_keys` to include either `input` or `output` and you set the corresponding `mask_input` or `mask_output`, then that trace will have its existing input and/or output replaced with a redacted message. + ## Troubleshooting & Errors ### Data not getting logged to Langfuse ? - Ensure you're on the latest version of langfuse `pip install langfuse -U`. The latest version allows litellm to log JSON input/outputs to langfuse diff --git a/docs/my-website/docs/providers/openai.md b/docs/my-website/docs/providers/openai.md index a8fe541fc8..c44a67412c 100644 --- a/docs/my-website/docs/providers/openai.md +++ b/docs/my-website/docs/providers/openai.md @@ -20,7 +20,7 @@ os.environ["OPENAI_API_KEY"] = "your-api-key" # openai call response = completion( - model = "gpt-3.5-turbo", + model = "gpt-4o", messages=[{ "content": "Hello, how are you?","role": "user"}] ) ``` @@ -163,6 +163,8 @@ os.environ["OPENAI_API_BASE"] = "openaiai-api-base" # OPTIONAL | Model Name | Function Call | |-----------------------|-----------------------------------------------------------------| +| gpt-4o | `response = completion(model="gpt-4o", messages=messages)` | +| gpt-4o-2024-05-13 | `response = completion(model="gpt-4o-2024-05-13", messages=messages)` | | gpt-4-turbo | `response = completion(model="gpt-4-turbo", messages=messages)` | | gpt-4-turbo-preview | `response = completion(model="gpt-4-0125-preview", messages=messages)` | | gpt-4-0125-preview | `response = completion(model="gpt-4-0125-preview", messages=messages)` | diff --git a/docs/my-website/docs/proxy/alerting.md b/docs/my-website/docs/proxy/alerting.md index 4275e0bf06..095d40a17b 100644 --- a/docs/my-website/docs/proxy/alerting.md +++ b/docs/my-website/docs/proxy/alerting.md @@ -7,6 +7,7 @@ Get alerts for: - Budget Tracking per key/user: - When a User/Key crosses their Budget - When a User/Key is 15% away from crossing their Budget +- Spend Reports - Weekly & Monthly spend per Team, Tag - Failed db read/writes ## Quick Start diff --git a/docs/my-website/docs/proxy/cost_tracking.md b/docs/my-website/docs/proxy/cost_tracking.md index 887ec9e3ed..d4760d83fe 100644 --- a/docs/my-website/docs/proxy/cost_tracking.md +++ b/docs/my-website/docs/proxy/cost_tracking.md @@ -1,8 +1,136 @@ -# Cost Tracking - Azure +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# ๐Ÿ’ธ Spend Tracking + +Track spend for keys, users, and teams across 100+ LLMs. + +## Getting Spend Reports - To Charge Other Teams, API Keys + +Use the `/global/spend/report` endpoint to get daily spend per team, with a breakdown of spend per API Key, Model + +### Example Request + +```shell +curl -X GET 'http://localhost:4000/global/spend/report?start_date=2023-04-01&end_date=2024-06-30' \ + -H 'Authorization: Bearer sk-1234' +``` + +### Example Response + + + + +```shell +[ + { + "group_by_day": "2024-04-30T00:00:00+00:00", + "teams": [ + { + "team_name": "Prod Team", + "total_spend": 0.0015265, + "metadata": [ # see the spend by unique(key + model) + { + "model": "gpt-4", + "spend": 0.00123, + "total_tokens": 28, + "api_key": "88dc28.." # the hashed api key + }, + { + "model": "gpt-4", + "spend": 0.00123, + "total_tokens": 28, + "api_key": "a73dc2.." # the hashed api key + }, + { + "model": "chatgpt-v-2", + "spend": 0.000214, + "total_tokens": 122, + "api_key": "898c28.." # the hashed api key + }, + { + "model": "gpt-3.5-turbo", + "spend": 0.0000825, + "total_tokens": 85, + "api_key": "84dc28.." # the hashed api key + } + ] + } + ] + } +] +``` + + + + + + +```python +import requests +url = 'http://localhost:4000/global/spend/report' +params = { + 'start_date': '2023-04-01', + 'end_date': '2024-06-30' +} + +headers = { + 'Authorization': 'Bearer sk-1234' +} + +# Make the GET request +response = requests.get(url, headers=headers, params=params) +spend_report = response.json() + +for row in spend_report: + date = row["group_by_day"] + teams = row["teams"] + for team in teams: + team_name = team["team_name"] + total_spend = team["total_spend"] + metadata = team["metadata"] + + print(f"Date: {date}") + print(f"Team: {team_name}") + print(f"Total Spend: {total_spend}") + print("Metadata: ", metadata) + print() +``` + +Output from script +```shell +# Date: 2024-05-11T00:00:00+00:00 +# Team: local_test_team +# Total Spend: 0.003675099999999999 +# Metadata: [{'model': 'gpt-3.5-turbo', 'spend': 0.003675099999999999, 'api_key': 'b94d5e0bc3a71a573917fe1335dc0c14728c7016337451af9714924ff3a729db', 'total_tokens': 3105}] + +# Date: 2024-05-13T00:00:00+00:00 +# Team: Unassigned Team +# Total Spend: 3.4e-05 +# Metadata: [{'model': 'gpt-3.5-turbo', 'spend': 3.4e-05, 'api_key': '9569d13c9777dba68096dea49b0b03e0aaf4d2b65d4030eda9e8a2733c3cd6e0', 'total_tokens': 50}] + +# Date: 2024-05-13T00:00:00+00:00 +# Team: central +# Total Spend: 0.000684 +# Metadata: [{'model': 'gpt-3.5-turbo', 'spend': 0.000684, 'api_key': '0323facdf3af551594017b9ef162434a9b9a8ca1bbd9ccbd9d6ce173b1015605', 'total_tokens': 498}] + +# Date: 2024-05-13T00:00:00+00:00 +# Team: local_test_team +# Total Spend: 0.0005715000000000001 +# Metadata: [{'model': 'gpt-3.5-turbo', 'spend': 0.0005715000000000001, 'api_key': 'b94d5e0bc3a71a573917fe1335dc0c14728c7016337451af9714924ff3a729db', 'total_tokens': 423}] +``` + + + + + + + +## Spend Tracking for Azure Set base model for cost tracking azure image-gen call -## Image Generation +### Image Generation ```yaml model_list: @@ -17,7 +145,7 @@ model_list: mode: image_generation ``` -## Chat Completions / Embeddings +### Chat Completions / Embeddings **Problem**: Azure returns `gpt-4` in the response when `azure/gpt-4-1106-preview` is used. This leads to inaccurate cost tracking diff --git a/docs/my-website/docs/proxy/user_keys.md b/docs/my-website/docs/proxy/user_keys.md index 7aba832eb8..cda3a46af9 100644 --- a/docs/my-website/docs/proxy/user_keys.md +++ b/docs/my-website/docs/proxy/user_keys.md @@ -365,22 +365,113 @@ curl --location 'http://0.0.0.0:4000/moderations' \ ## Advanced -### (BETA) Batch Completions - pass `model` as List +### (BETA) Batch Completions - pass multiple models Use this when you want to send 1 request to N Models #### Expected Request Format +Pass model as a string of comma separated value of models. Example `"model"="llama3,gpt-3.5-turbo"` + This same request will be sent to the following model groups on the [litellm proxy config.yaml](https://docs.litellm.ai/docs/proxy/configs) - `model_name="llama3"` - `model_name="gpt-3.5-turbo"` + + + + + +```python +import openai + +client = openai.OpenAI(api_key="sk-1234", base_url="http://0.0.0.0:4000") + +response = client.chat.completions.create( + model="gpt-3.5-turbo,llama3", + messages=[ + {"role": "user", "content": "this is a test request, write a short poem"} + ], +) + +print(response) +``` + + + +#### Expected Response Format + +Get a list of responses when `model` is passed as a list + +```python +[ + ChatCompletion( + id='chatcmpl-9NoYhS2G0fswot0b6QpoQgmRQMaIf', + choices=[ + Choice( + finish_reason='stop', + index=0, + logprobs=None, + message=ChatCompletionMessage( + content='In the depths of my soul, a spark ignites\nA light that shines so pure and bright\nIt dances and leaps, refusing to die\nA flame of hope that reaches the sky\n\nIt warms my heart and fills me with bliss\nA reminder that in darkness, there is light to kiss\nSo I hold onto this fire, this guiding light\nAnd let it lead me through the darkest night.', + role='assistant', + function_call=None, + tool_calls=None + ) + ) + ], + created=1715462919, + model='gpt-3.5-turbo-0125', + object='chat.completion', + system_fingerprint=None, + usage=CompletionUsage( + completion_tokens=83, + prompt_tokens=17, + total_tokens=100 + ) + ), + ChatCompletion( + id='chatcmpl-4ac3e982-da4e-486d-bddb-ed1d5cb9c03c', + choices=[ + Choice( + finish_reason='stop', + index=0, + logprobs=None, + message=ChatCompletionMessage( + content="A test request, and I'm delighted!\nHere's a short poem, just for you:\n\nMoonbeams dance upon the sea,\nA path of light, for you to see.\nThe stars up high, a twinkling show,\nA night of wonder, for all to know.\n\nThe world is quiet, save the night,\nA peaceful hush, a gentle light.\nThe world is full, of beauty rare,\nA treasure trove, beyond compare.\n\nI hope you enjoyed this little test,\nA poem born, of whimsy and jest.\nLet me know, if there's anything else!", + role='assistant', + function_call=None, + tool_calls=None + ) + ) + ], + created=1715462919, + model='groq/llama3-8b-8192', + object='chat.completion', + system_fingerprint='fp_a2c8d063cb', + usage=CompletionUsage( + completion_tokens=120, + prompt_tokens=20, + total_tokens=140 + ) + ) +] +``` + + + + + + + + + ```shell curl --location 'http://localhost:4000/chat/completions' \ --header 'Authorization: Bearer sk-1234' \ --header 'Content-Type: application/json' \ --data '{ - "model": ["llama3", "gpt-3.5-turbo"], + "model": "llama3,gpt-3.5-turbo", "max_tokens": 10, "user": "litellm2", "messages": [ @@ -393,6 +484,8 @@ curl --location 'http://localhost:4000/chat/completions' \ ``` + + #### Expected Response Format Get a list of responses when `model` is passed as a list @@ -447,6 +540,11 @@ Get a list of responses when `model` is passed as a list ``` + + + + + ### Pass User LLM API Keys, Fallbacks diff --git a/docs/my-website/docs/routing.md b/docs/my-website/docs/routing.md index b1afad2fbe..5ba3221c97 100644 --- a/docs/my-website/docs/routing.md +++ b/docs/my-website/docs/routing.md @@ -653,7 +653,9 @@ from litellm import Router model_list = [{...}] router = Router(model_list=model_list, - allowed_fails=1) # cooldown model if it fails > 1 call in a minute. + allowed_fails=1, # cooldown model if it fails > 1 call in a minute. + cooldown_time=100 # cooldown the deployment for 100 seconds if it num_fails > allowed_fails + ) user_message = "Hello, whats the weather in San Francisco??" messages = [{"content": user_message, "role": "user"}] @@ -770,6 +772,8 @@ If the error is a context window exceeded error, fall back to a larger model gro Fallbacks are done in-order - ["gpt-3.5-turbo, "gpt-4", "gpt-4-32k"], will do 'gpt-3.5-turbo' first, then 'gpt-4', etc. +You can also set 'default_fallbacks', in case a specific model group is misconfigured / bad. + ```python from litellm import Router @@ -830,6 +834,7 @@ model_list = [ router = Router(model_list=model_list, fallbacks=[{"azure/gpt-3.5-turbo": ["gpt-3.5-turbo"]}], + default_fallbacks=["gpt-3.5-turbo-16k"], context_window_fallbacks=[{"azure/gpt-3.5-turbo-context-fallback": ["gpt-3.5-turbo-16k"]}, {"gpt-3.5-turbo": ["gpt-3.5-turbo-16k"]}], set_verbose=True) @@ -1309,10 +1314,11 @@ def __init__( num_retries: int = 0, timeout: Optional[float] = None, default_litellm_params={}, # default params for Router.chat.completion.create - fallbacks: List = [], + fallbacks: Optional[List] = None, + default_fallbacks: Optional[List] = None allowed_fails: Optional[int] = None, # Number of times a deployment can failbefore being added to cooldown cooldown_time: float = 1, # (seconds) time to cooldown a deployment after failure - context_window_fallbacks: List = [], + context_window_fallbacks: Optional[List] = None, model_group_alias: Optional[dict] = {}, retry_after: int = 0, # (min) time to wait before retrying a failed request routing_strategy: Literal[ diff --git a/docs/my-website/sidebars.js b/docs/my-website/sidebars.js index 3bb5dc88e5..2deca92586 100644 --- a/docs/my-website/sidebars.js +++ b/docs/my-website/sidebars.js @@ -39,6 +39,7 @@ const sidebars = { "proxy/demo", "proxy/configs", "proxy/reliability", + "proxy/cost_tracking", "proxy/users", "proxy/user_keys", "proxy/enterprise", @@ -52,7 +53,6 @@ const sidebars = { "proxy/team_based_routing", "proxy/customer_routing", "proxy/ui", - "proxy/cost_tracking", "proxy/token_auth", { type: "category", diff --git a/enterprise/utils.py b/enterprise/utils.py index 05bd7dac6e..90b14314c2 100644 --- a/enterprise/utils.py +++ b/enterprise/utils.py @@ -1,6 +1,7 @@ # Enterprise Proxy Util Endpoints from litellm._logging import verbose_logger import collections +from datetime import datetime async def get_spend_by_tags(start_date=None, end_date=None, prisma_client=None): @@ -18,26 +19,33 @@ async def get_spend_by_tags(start_date=None, end_date=None, prisma_client=None): return response -async def ui_get_spend_by_tags(start_date=None, end_date=None, prisma_client=None): - response = await prisma_client.db.query_raw( - """ +async def ui_get_spend_by_tags(start_date: str, end_date: str, prisma_client): + + sql_query = """ SELECT jsonb_array_elements_text(request_tags) AS individual_request_tag, DATE(s."startTime") AS spend_date, COUNT(*) AS log_count, SUM(spend) AS total_spend FROM "LiteLLM_SpendLogs" s - WHERE s."startTime" >= current_date - interval '30 days' + WHERE + DATE(s."startTime") >= $1::date + AND DATE(s."startTime") <= $2::date GROUP BY individual_request_tag, spend_date - ORDER BY spend_date; - """ + ORDER BY spend_date + LIMIT 100; + """ + response = await prisma_client.db.query_raw( + sql_query, + start_date, + end_date, ) # print("tags - spend") # print(response) # Bar Chart 1 - Spend per tag - Top 10 tags by spend - total_spend_per_tag = collections.defaultdict(float) - total_requests_per_tag = collections.defaultdict(int) + total_spend_per_tag: collections.defaultdict = collections.defaultdict(float) + total_requests_per_tag: collections.defaultdict = collections.defaultdict(int) for row in response: tag_name = row["individual_request_tag"] tag_spend = row["total_spend"] @@ -49,15 +57,18 @@ async def ui_get_spend_by_tags(start_date=None, end_date=None, prisma_client=Non # convert to ui format ui_tags = [] for tag in sorted_tags: + current_spend = tag[1] + if current_spend is not None and isinstance(current_spend, float): + current_spend = round(current_spend, 4) ui_tags.append( { "name": tag[0], - "value": tag[1], + "spend": current_spend, "log_count": total_requests_per_tag[tag[0]], } ) - return {"top_10_tags": ui_tags} + return {"spend_per_tag": ui_tags} async def view_spend_logs_from_clickhouse( diff --git a/litellm/__init__.py b/litellm/__init__.py index 6c7b26617e..16395b27f3 100644 --- a/litellm/__init__.py +++ b/litellm/__init__.py @@ -406,69 +406,69 @@ replicate_models: List = [ ] clarifai_models: List = [ - 'clarifai/meta.Llama-3.Llama-3-8B-Instruct', - 'clarifai/gcp.generate.gemma-1_1-7b-it', - 'clarifai/mistralai.completion.mixtral-8x22B', - 'clarifai/cohere.generate.command-r-plus', - 'clarifai/databricks.drbx.dbrx-instruct', - 'clarifai/mistralai.completion.mistral-large', - 'clarifai/mistralai.completion.mistral-medium', - 'clarifai/mistralai.completion.mistral-small', - 'clarifai/mistralai.completion.mixtral-8x7B-Instruct-v0_1', - 'clarifai/gcp.generate.gemma-2b-it', - 'clarifai/gcp.generate.gemma-7b-it', - 'clarifai/deci.decilm.deciLM-7B-instruct', - 'clarifai/mistralai.completion.mistral-7B-Instruct', - 'clarifai/gcp.generate.gemini-pro', - 'clarifai/anthropic.completion.claude-v1', - 'clarifai/anthropic.completion.claude-instant-1_2', - 'clarifai/anthropic.completion.claude-instant', - 'clarifai/anthropic.completion.claude-v2', - 'clarifai/anthropic.completion.claude-2_1', - 'clarifai/meta.Llama-2.codeLlama-70b-Python', - 'clarifai/meta.Llama-2.codeLlama-70b-Instruct', - 'clarifai/openai.completion.gpt-3_5-turbo-instruct', - 'clarifai/meta.Llama-2.llama2-7b-chat', - 'clarifai/meta.Llama-2.llama2-13b-chat', - 'clarifai/meta.Llama-2.llama2-70b-chat', - 'clarifai/openai.chat-completion.gpt-4-turbo', - 'clarifai/microsoft.text-generation.phi-2', - 'clarifai/meta.Llama-2.llama2-7b-chat-vllm', - 'clarifai/upstage.solar.solar-10_7b-instruct', - 'clarifai/openchat.openchat.openchat-3_5-1210', - 'clarifai/togethercomputer.stripedHyena.stripedHyena-Nous-7B', - 'clarifai/gcp.generate.text-bison', - 'clarifai/meta.Llama-2.llamaGuard-7b', - 'clarifai/fblgit.una-cybertron.una-cybertron-7b-v2', - 'clarifai/openai.chat-completion.GPT-4', - 'clarifai/openai.chat-completion.GPT-3_5-turbo', - 'clarifai/ai21.complete.Jurassic2-Grande', - 'clarifai/ai21.complete.Jurassic2-Grande-Instruct', - 'clarifai/ai21.complete.Jurassic2-Jumbo-Instruct', - 'clarifai/ai21.complete.Jurassic2-Jumbo', - 'clarifai/ai21.complete.Jurassic2-Large', - 'clarifai/cohere.generate.cohere-generate-command', - 'clarifai/wizardlm.generate.wizardCoder-Python-34B', - 'clarifai/wizardlm.generate.wizardLM-70B', - 'clarifai/tiiuae.falcon.falcon-40b-instruct', - 'clarifai/togethercomputer.RedPajama.RedPajama-INCITE-7B-Chat', - 'clarifai/gcp.generate.code-gecko', - 'clarifai/gcp.generate.code-bison', - 'clarifai/mistralai.completion.mistral-7B-OpenOrca', - 'clarifai/mistralai.completion.openHermes-2-mistral-7B', - 'clarifai/wizardlm.generate.wizardLM-13B', - 'clarifai/huggingface-research.zephyr.zephyr-7B-alpha', - 'clarifai/wizardlm.generate.wizardCoder-15B', - 'clarifai/microsoft.text-generation.phi-1_5', - 'clarifai/databricks.Dolly-v2.dolly-v2-12b', - 'clarifai/bigcode.code.StarCoder', - 'clarifai/salesforce.xgen.xgen-7b-8k-instruct', - 'clarifai/mosaicml.mpt.mpt-7b-instruct', - 'clarifai/anthropic.completion.claude-3-opus', - 'clarifai/anthropic.completion.claude-3-sonnet', - 'clarifai/gcp.generate.gemini-1_5-pro', - 'clarifai/gcp.generate.imagen-2', - 'clarifai/salesforce.blip.general-english-image-caption-blip-2', + "clarifai/meta.Llama-3.Llama-3-8B-Instruct", + "clarifai/gcp.generate.gemma-1_1-7b-it", + "clarifai/mistralai.completion.mixtral-8x22B", + "clarifai/cohere.generate.command-r-plus", + "clarifai/databricks.drbx.dbrx-instruct", + "clarifai/mistralai.completion.mistral-large", + "clarifai/mistralai.completion.mistral-medium", + "clarifai/mistralai.completion.mistral-small", + "clarifai/mistralai.completion.mixtral-8x7B-Instruct-v0_1", + "clarifai/gcp.generate.gemma-2b-it", + "clarifai/gcp.generate.gemma-7b-it", + "clarifai/deci.decilm.deciLM-7B-instruct", + "clarifai/mistralai.completion.mistral-7B-Instruct", + "clarifai/gcp.generate.gemini-pro", + "clarifai/anthropic.completion.claude-v1", + "clarifai/anthropic.completion.claude-instant-1_2", + "clarifai/anthropic.completion.claude-instant", + "clarifai/anthropic.completion.claude-v2", + "clarifai/anthropic.completion.claude-2_1", + "clarifai/meta.Llama-2.codeLlama-70b-Python", + "clarifai/meta.Llama-2.codeLlama-70b-Instruct", + "clarifai/openai.completion.gpt-3_5-turbo-instruct", + "clarifai/meta.Llama-2.llama2-7b-chat", + "clarifai/meta.Llama-2.llama2-13b-chat", + "clarifai/meta.Llama-2.llama2-70b-chat", + "clarifai/openai.chat-completion.gpt-4-turbo", + "clarifai/microsoft.text-generation.phi-2", + "clarifai/meta.Llama-2.llama2-7b-chat-vllm", + "clarifai/upstage.solar.solar-10_7b-instruct", + "clarifai/openchat.openchat.openchat-3_5-1210", + "clarifai/togethercomputer.stripedHyena.stripedHyena-Nous-7B", + "clarifai/gcp.generate.text-bison", + "clarifai/meta.Llama-2.llamaGuard-7b", + "clarifai/fblgit.una-cybertron.una-cybertron-7b-v2", + "clarifai/openai.chat-completion.GPT-4", + "clarifai/openai.chat-completion.GPT-3_5-turbo", + "clarifai/ai21.complete.Jurassic2-Grande", + "clarifai/ai21.complete.Jurassic2-Grande-Instruct", + "clarifai/ai21.complete.Jurassic2-Jumbo-Instruct", + "clarifai/ai21.complete.Jurassic2-Jumbo", + "clarifai/ai21.complete.Jurassic2-Large", + "clarifai/cohere.generate.cohere-generate-command", + "clarifai/wizardlm.generate.wizardCoder-Python-34B", + "clarifai/wizardlm.generate.wizardLM-70B", + "clarifai/tiiuae.falcon.falcon-40b-instruct", + "clarifai/togethercomputer.RedPajama.RedPajama-INCITE-7B-Chat", + "clarifai/gcp.generate.code-gecko", + "clarifai/gcp.generate.code-bison", + "clarifai/mistralai.completion.mistral-7B-OpenOrca", + "clarifai/mistralai.completion.openHermes-2-mistral-7B", + "clarifai/wizardlm.generate.wizardLM-13B", + "clarifai/huggingface-research.zephyr.zephyr-7B-alpha", + "clarifai/wizardlm.generate.wizardCoder-15B", + "clarifai/microsoft.text-generation.phi-1_5", + "clarifai/databricks.Dolly-v2.dolly-v2-12b", + "clarifai/bigcode.code.StarCoder", + "clarifai/salesforce.xgen.xgen-7b-8k-instruct", + "clarifai/mosaicml.mpt.mpt-7b-instruct", + "clarifai/anthropic.completion.claude-3-opus", + "clarifai/anthropic.completion.claude-3-sonnet", + "clarifai/gcp.generate.gemini-1_5-pro", + "clarifai/gcp.generate.imagen-2", + "clarifai/salesforce.blip.general-english-image-caption-blip-2", ] @@ -755,7 +755,7 @@ from .llms.bedrock import ( AmazonMistralConfig, AmazonBedrockGlobalConfig, ) -from .llms.openai import OpenAIConfig, OpenAITextCompletionConfig +from .llms.openai import OpenAIConfig, OpenAITextCompletionConfig, MistralConfig from .llms.azure import AzureOpenAIConfig, AzureOpenAIError from .llms.watsonx import IBMWatsonXAIConfig from .main import * # type: ignore diff --git a/litellm/integrations/langfuse.py b/litellm/integrations/langfuse.py index 0d9c0640cc..f4a581eb9f 100644 --- a/litellm/integrations/langfuse.py +++ b/litellm/integrations/langfuse.py @@ -322,6 +322,8 @@ class LangFuseLogger: existing_trace_id = clean_metadata.pop("existing_trace_id", None) update_trace_keys = clean_metadata.pop("update_trace_keys", []) debug = clean_metadata.pop("debug_langfuse", None) + mask_input = clean_metadata.pop("mask_input", False) + mask_output = clean_metadata.pop("mask_output", False) if trace_name is None and existing_trace_id is None: # just log `litellm-{call_type}` as the trace name @@ -349,15 +351,15 @@ class LangFuseLogger: # Special keys that are found in the function arguments and not the metadata if "input" in update_trace_keys: - trace_params["input"] = input + trace_params["input"] = input if not mask_input else "redacted-by-litellm" if "output" in update_trace_keys: - trace_params["output"] = output + trace_params["output"] = output if not mask_output else "redacted-by-litellm" else: # don't overwrite an existing trace trace_params = { "id": trace_id, "name": trace_name, "session_id": session_id, - "input": input, + "input": input if not mask_input else "redacted-by-litellm", "version": clean_metadata.pop( "trace_version", clean_metadata.get("version", None) ), # If provided just version, it will applied to the trace as well, if applied a trace version it will take precedence @@ -373,7 +375,7 @@ class LangFuseLogger: if level == "ERROR": trace_params["status_message"] = output else: - trace_params["output"] = output + trace_params["output"] = output if not mask_output else "redacted-by-litellm" if debug == True or (isinstance(debug, str) and debug.lower() == "true"): if "metadata" in trace_params: @@ -463,8 +465,8 @@ class LangFuseLogger: "end_time": end_time, "model": kwargs["model"], "model_parameters": optional_params, - "input": input, - "output": output, + "input": input if not mask_input else "redacted-by-litellm", + "output": output if not mask_output else "redacted-by-litellm", "usage": usage, "metadata": clean_metadata, "level": level, diff --git a/litellm/integrations/slack_alerting.py b/litellm/integrations/slack_alerting.py index 788b099ffa..a3d7e20d1a 100644 --- a/litellm/integrations/slack_alerting.py +++ b/litellm/integrations/slack_alerting.py @@ -76,16 +76,14 @@ class SlackAlerting(CustomLogger): internal_usage_cache: Optional[DualCache] = None, alerting_threshold: float = 300, # threshold for slow / hanging llm responses (in seconds) alerting: Optional[List] = [], - alert_types: Optional[ - List[ - Literal[ - "llm_exceptions", - "llm_too_slow", - "llm_requests_hanging", - "budget_alerts", - "db_exceptions", - "daily_reports", - ] + alert_types: List[ + Literal[ + "llm_exceptions", + "llm_too_slow", + "llm_requests_hanging", + "budget_alerts", + "db_exceptions", + "daily_reports", ] ] = [ "llm_exceptions", @@ -240,6 +238,8 @@ class SlackAlerting(CustomLogger): end_time=end_time, ) ) + if litellm.turn_off_message_logging: + messages = "Message not logged. `litellm.turn_off_message_logging=True`." request_info = f"\nRequest Model: `{model}`\nAPI Base: `{api_base}`\nMessages: `{messages}`" slow_message = f"`Responses are slow - {round(time_difference_float,2)}s response time > Alerting threshold: {self.alerting_threshold}s`" if time_difference_float > self.alerting_threshold: @@ -469,6 +469,11 @@ class SlackAlerting(CustomLogger): messages = messages[:100] except: messages = "" + + if litellm.turn_off_message_logging: + messages = ( + "Message not logged. `litellm.turn_off_message_logging=True`." + ) request_info = f"\nRequest Model: `{model}`\nMessages: `{messages}`" else: request_info = "" @@ -819,14 +824,6 @@ Model Info: updated_at=litellm.utils.get_utc_datetime(), ) ) - if "llm_exceptions" in self.alert_types: - original_exception = kwargs.get("exception", None) - - await self.send_alert( - message="LLM API Failure - " + str(original_exception), - level="High", - alert_type="llm_exceptions", - ) async def _run_scheduler_helper(self, llm_router) -> bool: """ @@ -890,3 +887,99 @@ Model Info: ) # shuffle to prevent collisions await asyncio.sleep(interval) return + + async def send_weekly_spend_report(self): + """ """ + try: + from litellm.proxy.proxy_server import _get_spend_report_for_time_range + + todays_date = datetime.datetime.now().date() + week_before = todays_date - datetime.timedelta(days=7) + + weekly_spend_per_team, weekly_spend_per_tag = ( + await _get_spend_report_for_time_range( + start_date=week_before.strftime("%Y-%m-%d"), + end_date=todays_date.strftime("%Y-%m-%d"), + ) + ) + + _weekly_spend_message = f"*๐Ÿ’ธ Weekly Spend Report for `{week_before.strftime('%m-%d-%Y')} - {todays_date.strftime('%m-%d-%Y')}` *\n" + + if weekly_spend_per_team is not None: + _weekly_spend_message += "\n*Team Spend Report:*\n" + for spend in weekly_spend_per_team: + _team_spend = spend["total_spend"] + _team_spend = float(_team_spend) + # round to 4 decimal places + _team_spend = round(_team_spend, 4) + _weekly_spend_message += ( + f"Team: `{spend['team_alias']}` | Spend: `${_team_spend}`\n" + ) + + if weekly_spend_per_tag is not None: + _weekly_spend_message += "\n*Tag Spend Report:*\n" + for spend in weekly_spend_per_tag: + _tag_spend = spend["total_spend"] + _tag_spend = float(_tag_spend) + # round to 4 decimal places + _tag_spend = round(_tag_spend, 4) + _weekly_spend_message += f"Tag: `{spend['individual_request_tag']}` | Spend: `${_tag_spend}`\n" + + await self.send_alert( + message=_weekly_spend_message, + level="Low", + alert_type="daily_reports", + ) + except Exception as e: + verbose_proxy_logger.error("Error sending weekly spend report", e) + + async def send_monthly_spend_report(self): + """ """ + try: + from calendar import monthrange + + from litellm.proxy.proxy_server import _get_spend_report_for_time_range + + todays_date = datetime.datetime.now().date() + first_day_of_month = todays_date.replace(day=1) + _, last_day_of_month = monthrange(todays_date.year, todays_date.month) + last_day_of_month = first_day_of_month + datetime.timedelta( + days=last_day_of_month - 1 + ) + + monthly_spend_per_team, monthly_spend_per_tag = ( + await _get_spend_report_for_time_range( + start_date=first_day_of_month.strftime("%Y-%m-%d"), + end_date=last_day_of_month.strftime("%Y-%m-%d"), + ) + ) + + _spend_message = f"*๐Ÿ’ธ Monthly Spend Report for `{first_day_of_month.strftime('%m-%d-%Y')} - {last_day_of_month.strftime('%m-%d-%Y')}` *\n" + + if monthly_spend_per_team is not None: + _spend_message += "\n*Team Spend Report:*\n" + for spend in monthly_spend_per_team: + _team_spend = spend["total_spend"] + _team_spend = float(_team_spend) + # round to 4 decimal places + _team_spend = round(_team_spend, 4) + _spend_message += ( + f"Team: `{spend['team_alias']}` | Spend: `${_team_spend}`\n" + ) + + if monthly_spend_per_tag is not None: + _spend_message += "\n*Tag Spend Report:*\n" + for spend in monthly_spend_per_tag: + _tag_spend = spend["total_spend"] + _tag_spend = float(_tag_spend) + # round to 4 decimal places + _tag_spend = round(_tag_spend, 4) + _spend_message += f"Tag: `{spend['individual_request_tag']}` | Spend: `${_tag_spend}`\n" + + await self.send_alert( + message=_spend_message, + level="Low", + alert_type="daily_reports", + ) + except Exception as e: + verbose_proxy_logger.error("Error sending weekly spend report", e) diff --git a/litellm/llms/ollama_chat.py b/litellm/llms/ollama_chat.py index 866761905f..d1ff4953fa 100644 --- a/litellm/llms/ollama_chat.py +++ b/litellm/llms/ollama_chat.py @@ -300,7 +300,7 @@ def get_ollama_response( model_response["choices"][0]["message"] = message model_response["choices"][0]["finish_reason"] = "tool_calls" else: - model_response["choices"][0]["message"] = response_json["message"] + model_response["choices"][0]["message"]["content"] = response_json["message"]["content"] model_response["created"] = int(time.time()) model_response["model"] = "ollama/" + model prompt_tokens = response_json.get("prompt_eval_count", litellm.token_counter(messages=messages)) # type: ignore @@ -484,7 +484,7 @@ async def ollama_acompletion( model_response["choices"][0]["message"] = message model_response["choices"][0]["finish_reason"] = "tool_calls" else: - model_response["choices"][0]["message"] = response_json["message"] + model_response["choices"][0]["message"]["content"] = response_json["message"]["content"] model_response["created"] = int(time.time()) model_response["model"] = "ollama_chat/" + data["model"] diff --git a/litellm/llms/openai.py b/litellm/llms/openai.py index 674cc86a25..7acbdfae02 100644 --- a/litellm/llms/openai.py +++ b/litellm/llms/openai.py @@ -53,6 +53,113 @@ class OpenAIError(Exception): ) # Call the base class constructor with the parameters it needs +class MistralConfig: + """ + Reference: https://docs.mistral.ai/api/ + + The class `MistralConfig` provides configuration for the Mistral's Chat API interface. Below are the parameters: + + - `temperature` (number or null): Defines the sampling temperature to use, varying between 0 and 2. API Default - 0.7. + + - `top_p` (number or null): An alternative to sampling with temperature, used for nucleus sampling. API Default - 1. + + - `max_tokens` (integer or null): This optional parameter helps to set the maximum number of tokens to generate in the chat completion. API Default - null. + + - `tools` (list or null): A list of available tools for the model. Use this to specify functions for which the model can generate JSON inputs. + + - `tool_choice` (string - 'auto'/'any'/'none' or null): Specifies if/how functions are called. If set to none the model won't call a function and will generate a message instead. If set to auto the model can choose to either generate a message or call a function. If set to any the model is forced to call a function. Default - 'auto'. + + - `random_seed` (integer or null): The seed to use for random sampling. If set, different calls will generate deterministic results. + + - `safe_prompt` (boolean): Whether to inject a safety prompt before all conversations. API Default - 'false'. + + - `response_format` (object or null): An object specifying the format that the model must output. Setting to { "type": "json_object" } enables JSON mode, which guarantees the message the model generates is in JSON. When using JSON mode you MUST also instruct the model to produce JSON yourself with a system or a user message. + """ + + temperature: Optional[int] = None + top_p: Optional[int] = None + max_tokens: Optional[int] = None + tools: Optional[list] = None + tool_choice: Optional[Literal["auto", "any", "none"]] = None + random_seed: Optional[int] = None + safe_prompt: Optional[bool] = None + response_format: Optional[dict] = None + + def __init__( + self, + temperature: Optional[int] = None, + top_p: Optional[int] = None, + max_tokens: Optional[int] = None, + tools: Optional[list] = None, + tool_choice: Optional[Literal["auto", "any", "none"]] = None, + random_seed: Optional[int] = None, + safe_prompt: Optional[bool] = None, + response_format: Optional[dict] = None, + ) -> None: + locals_ = locals() + for key, value in locals_.items(): + if key != "self" and value is not None: + setattr(self.__class__, key, value) + + @classmethod + def get_config(cls): + return { + k: v + for k, v in cls.__dict__.items() + if not k.startswith("__") + and not isinstance( + v, + ( + types.FunctionType, + types.BuiltinFunctionType, + classmethod, + staticmethod, + ), + ) + and v is not None + } + + def get_supported_openai_params(self): + return [ + "stream", + "temperature", + "top_p", + "max_tokens", + "tools", + "tool_choice", + "seed", + "response_format", + ] + + def _map_tool_choice(self, tool_choice: str) -> str: + if tool_choice == "auto" or tool_choice == "none": + return tool_choice + elif tool_choice == "required": + return "any" + else: # openai 'tool_choice' object param not supported by Mistral API + return "any" + + def map_openai_params(self, non_default_params: dict, optional_params: dict): + for param, value in non_default_params.items(): + if param == "max_tokens": + optional_params["max_tokens"] = value + if param == "tools": + optional_params["tools"] = value + if param == "stream" and value == True: + optional_params["stream"] = value + if param == "temperature": + optional_params["temperature"] = value + if param == "top_p": + optional_params["top_p"] = value + if param == "tool_choice" and isinstance(value, str): + optional_params["tool_choice"] = self._map_tool_choice( + tool_choice=value + ) + if param == "seed": + optional_params["extra_body"] = {"random_seed": value} + return optional_params + + class OpenAIConfig: """ Reference: https://platform.openai.com/docs/api-reference/chat/create @@ -1327,8 +1434,8 @@ class OpenAIAssistantsAPI(BaseLLM): client=client, ) - thread_message: OpenAIMessage = openai_client.beta.threads.messages.create( - thread_id, **message_data + thread_message: OpenAIMessage = openai_client.beta.threads.messages.create( # type: ignore + thread_id, **message_data # type: ignore ) response_obj: Optional[OpenAIMessage] = None @@ -1458,7 +1565,7 @@ class OpenAIAssistantsAPI(BaseLLM): client=client, ) - response = openai_client.beta.threads.runs.create_and_poll( + response = openai_client.beta.threads.runs.create_and_poll( # type: ignore thread_id=thread_id, assistant_id=assistant_id, additional_instructions=additional_instructions, diff --git a/litellm/llms/vertex_ai.py b/litellm/llms/vertex_ai.py index d3bb2c78ab..84fec734fd 100644 --- a/litellm/llms/vertex_ai.py +++ b/litellm/llms/vertex_ai.py @@ -867,6 +867,8 @@ async def async_completion( Add support for acompletion calls for gemini-pro """ try: + import proto # type: ignore + if mode == "vision": print_verbose("\nMaking VertexAI Gemini Pro/Vision Call") print_verbose(f"\nProcessing input messages = {messages}") @@ -901,9 +903,21 @@ async def async_completion( ): function_call = response.candidates[0].content.parts[0].function_call args_dict = {} - for k, v in function_call.args.items(): - args_dict[k] = v - args_str = json.dumps(args_dict) + + # Check if it's a RepeatedComposite instance + for key, val in function_call.args.items(): + if isinstance( + val, proto.marshal.collections.repeated.RepeatedComposite + ): + # If so, convert to list + args_dict[key] = [v for v in val] + else: + args_dict[key] = val + + try: + args_str = json.dumps(args_dict) + except Exception as e: + raise VertexAIError(status_code=422, message=str(e)) message = litellm.Message( content=None, tool_calls=[ diff --git a/litellm/main.py b/litellm/main.py index 0dbd5a1666..6156d9c398 100644 --- a/litellm/main.py +++ b/litellm/main.py @@ -9,12 +9,12 @@ import os, openai, sys, json, inspect, uuid, datetime, threading from typing import Any, Literal, Union, BinaryIO +from typing_extensions import overload from functools import partial import dotenv, traceback, random, asyncio, time, contextvars from copy import deepcopy import httpx import litellm - from ._logging import verbose_logger from litellm import ( # type: ignore client, @@ -727,7 +727,6 @@ def completion( ### REGISTER CUSTOM MODEL PRICING -- IF GIVEN ### if input_cost_per_token is not None and output_cost_per_token is not None: - print_verbose(f"Registering model={model} in model cost map") litellm.register_model( { f"{custom_llm_provider}/{model}": { @@ -849,6 +848,10 @@ def completion( proxy_server_request=proxy_server_request, preset_cache_key=preset_cache_key, no_log=no_log, + input_cost_per_second=input_cost_per_second, + input_cost_per_token=input_cost_per_token, + output_cost_per_second=output_cost_per_second, + output_cost_per_token=output_cost_per_token, ) logging.update_environment_variables( model=model, diff --git a/litellm/model_prices_and_context_window_backup.json b/litellm/model_prices_and_context_window_backup.json index 11e24dbdd3..0a262e3108 100644 --- a/litellm/model_prices_and_context_window_backup.json +++ b/litellm/model_prices_and_context_window_backup.json @@ -9,6 +9,30 @@ "mode": "chat", "supports_function_calling": true }, + "gpt-4o": { + "max_tokens": 4096, + "max_input_tokens": 128000, + "max_output_tokens": 4096, + "input_cost_per_token": 0.000005, + "output_cost_per_token": 0.000015, + "litellm_provider": "openai", + "mode": "chat", + "supports_function_calling": true, + "supports_parallel_function_calling": true, + "supports_vision": true + }, + "gpt-4o-2024-05-13": { + "max_tokens": 4096, + "max_input_tokens": 128000, + "max_output_tokens": 4096, + "input_cost_per_token": 0.000005, + "output_cost_per_token": 0.000015, + "litellm_provider": "openai", + "mode": "chat", + "supports_function_calling": true, + "supports_parallel_function_calling": true, + "supports_vision": true + }, "gpt-4-turbo-preview": { "max_tokens": 4096, "max_input_tokens": 128000, @@ -3366,4 +3390,4 @@ "mode": "embedding" } -} \ No newline at end of file +} diff --git a/litellm/proxy/_experimental/out/404.html b/litellm/proxy/_experimental/out/404.html index eaf5701355..b70559084d 100644 --- a/litellm/proxy/_experimental/out/404.html +++ b/litellm/proxy/_experimental/out/404.html @@ -1 +1 @@ -404: This page could not be found.LiteLLM Dashboard

404

This page could not be found.

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

404

This page could not be found.

\ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/app/page-6a39771cacf75ea6.js b/litellm/proxy/_experimental/out/_next/static/chunks/app/page-6a39771cacf75ea6.js new file mode 100644 index 0000000000..7d08a80c96 --- /dev/null +++ b/litellm/proxy/_experimental/out/_next/static/chunks/app/page-6a39771cacf75ea6.js @@ -0,0 +1 @@ +(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[931],{20661:function(e,l,t){Promise.resolve().then(t.bind(t,7926))},7926:function(e,l,t){"use strict";t.r(l),t.d(l,{default:function(){return lb}});var s,a,r=t(3827),n=t(64090),o=t(47907),i=t(8792),c=t(40491),d=t(65270),m=e=>{let{userID:l,userRole:t,userEmail:s,showSSOBanner:a}=e;console.log("User ID:",l),console.log("userEmail:",s),console.log("showSSOBanner:",a);let n=[{key:"1",label:(0,r.jsxs)(r.Fragment,{children:[(0,r.jsxs)("p",{children:["Role: ",t]}),(0,r.jsxs)("p",{children:["ID: ",l]})]})}];return(0,r.jsxs)("nav",{className:"left-0 right-0 top-0 flex justify-between items-center h-12 mb-4",children:[(0,r.jsx)("div",{className:"text-left my-2 absolute top-0 left-0",children:(0,r.jsx)("div",{className:"flex flex-col items-center",children:(0,r.jsx)(i.default,{href:"/",children:(0,r.jsx)("button",{className:"text-gray-800 rounded text-center",children:(0,r.jsx)("img",{src:"/get_image",width:160,height:160,alt:"LiteLLM Brand",className:"mr-2"})})})})}),(0,r.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,r.jsx)("div",{style:{padding:"6px",borderRadius:"8px"},children:(0,r.jsx)("a",{href:"https://calendly.com/d/4mp-gd3-k5k/litellm-1-1-onboarding-chat",target:"_blank",style:{fontSize:"14px",textDecoration:"underline"},children:"Request hosted proxy"})}):null,(0,r.jsx)("div",{style:{border:"1px solid #391085",padding:"6px",borderRadius:"8px"},children:(0,r.jsx)(c.Z,{menu:{items:n},children:(0,r.jsx)(d.Z,{children:s})})})]})]})},u=t(80588);let h=async()=>{try{let e=await fetch("https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json"),l=await e.json();return console.log("received data: ".concat(l)),l}catch(e){throw console.error("Failed to get model cost map:",e),e}},x=async(e,l)=>{try{let t=await fetch("/model/new",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...l})});if(!t.ok){let e=await t.text();throw u.ZP.error("Failed to create key: "+e,10),console.error("Error response from the server:",e),Error("Network response was not ok")}let s=await t.json();return console.log("API Response:",s),u.ZP.success("Model created successfully. Wait 60s and refresh on 'All Models' page"),s}catch(e){throw console.error("Failed to create key:",e),e}},p=async(e,l)=>{console.log("model_id in model delete call: ".concat(l));try{let t=await fetch("/model/delete",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({id:l})});if(!t.ok){let e=await t.text();throw u.ZP.error("Failed to create key: "+e,10),console.error("Error response from the server:",e),Error("Network response was not ok")}let s=await t.json();return console.log("API Response:",s),u.ZP.success("Model deleted successfully. Restart server to see this."),s}catch(e){throw console.error("Failed to create key:",e),e}},j=async(e,l,t)=>{try{if(console.log("Form Values in keyCreateCall:",t),t.description&&(t.metadata||(t.metadata={}),t.metadata.description=t.description,delete t.description,t.metadata=JSON.stringify(t.metadata)),t.metadata){console.log("formValues.metadata:",t.metadata);try{t.metadata=JSON.parse(t.metadata)}catch(e){throw u.ZP.error("Failed to parse metadata: "+e,10),Error("Failed to parse metadata: "+e)}}console.log("Form Values after check:",t);let s=await fetch("/key/generate",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({user_id:l,...t})});if(!s.ok){let e=await s.text();throw u.ZP.error("Failed to create key: "+e,10),console.error("Error response from the server:",e),Error("Network response was not ok")}let a=await s.json();return console.log("API Response:",a),a}catch(e){throw console.error("Failed to create key:",e),e}},g=async(e,l,t)=>{try{if(console.log("Form Values in keyCreateCall:",t),t.description&&(t.metadata||(t.metadata={}),t.metadata.description=t.description,delete t.description,t.metadata=JSON.stringify(t.metadata)),t.metadata){console.log("formValues.metadata:",t.metadata);try{t.metadata=JSON.parse(t.metadata)}catch(e){throw u.ZP.error("Failed to parse metadata: "+e,10),Error("Failed to parse metadata: "+e)}}console.log("Form Values after check:",t);let s=await fetch("/user/new",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({user_id:l,...t})});if(!s.ok){let e=await s.text();throw u.ZP.error("Failed to create key: "+e,10),console.error("Error response from the server:",e),Error("Network response was not ok")}let a=await s.json();return console.log("API Response:",a),a}catch(e){throw console.error("Failed to create key:",e),e}},y=async(e,l)=>{try{console.log("in keyDeleteCall:",l);let t=await fetch("/key/delete",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({keys:[l]})});if(!t.ok){let e=await t.text();throw u.ZP.error("Failed to delete key: "+e,10),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}},f=async(e,l)=>{try{console.log("in teamDeleteCall:",l);let t=await fetch("/team/delete",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({team_ids:[l]})});if(!t.ok){let e=await t.text();throw u.ZP.error("Failed to delete team: "+e,10),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to delete key:",e),e}},Z=async function(e,l,t){let s=arguments.length>3&&void 0!==arguments[3]&&arguments[3],a=arguments.length>4?arguments[4]:void 0,r=arguments.length>5?arguments[5]:void 0;try{let n="/user/info";"App Owner"==t&&l&&(n="".concat(n,"?user_id=").concat(l)),"App User"==t&&l&&(n="".concat(n,"?user_id=").concat(l)),console.log("in userInfoCall viewAll=",s),s&&r&&null!=a&&void 0!=a&&(n="".concat(n,"?view_all=true&page=").concat(a,"&page_size=").concat(r));let o=await fetch(n,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!o.ok){let e=await o.text();throw u.ZP.error(e,10),Error("Network response was not ok")}let i=await o.json();return console.log("API Response:",i),i}catch(e){throw console.error("Failed to create key:",e),e}},_=async(e,l)=>{try{let t="/team/info";l&&(t="".concat(t,"?team_id=").concat(l)),console.log("in teamInfoCall");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 u.ZP.error(e,10),Error("Network response was not ok")}let a=await s.json();return console.log("API Response:",a),a}catch(e){throw console.error("Failed to create key:",e),e}},w=async e=>{try{let l=await fetch("/global/spend",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw u.ZP.error(e,10),Error("Network response was not ok")}return await l.json()}catch(e){throw console.error("Failed to create key:",e),e}},b=async(e,l,t)=>{try{let l=await fetch("/v2/model/info",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw u.ZP.error(e,10),Error("Network response was not ok")}let t=await l.json();return console.log("modelInfoCall:",t),t}catch(e){throw console.error("Failed to create key:",e),e}},k=async(e,l,t,s,a,r)=>{try{let l="/model/metrics";s&&(l="".concat(l,"?_selected_model_group=").concat(s,"&startTime=").concat(a,"&endTime=").concat(r));let t=await fetch(l,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw u.ZP.error(e,10),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},v=async(e,l,t,s,a,r)=>{try{let l="/model/metrics/slow_responses";s&&(l="".concat(l,"?_selected_model_group=").concat(s,"&startTime=").concat(a,"&endTime=").concat(r));let t=await fetch(l,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw u.ZP.error(e,10),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},S=async(e,l,t,s,a,r)=>{try{let l="/model/metrics/exceptions";s&&(l="".concat(l,"?_selected_model_group=").concat(s,"&startTime=").concat(a,"&endTime=").concat(r));let t=await fetch(l,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw u.ZP.error(e,10),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},N=async(e,l,t)=>{try{let l=await fetch("/models",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw u.ZP.error(e,10),Error("Network response was not ok")}return await l.json()}catch(e){throw console.error("Failed to create key:",e),e}},A=async e=>{try{let l="/global/spend/teams";console.log("in teamSpendLogsCall:",l);let t=await fetch("".concat(l),{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw u.ZP.error(e,10),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}},E=async(e,l,t)=>{try{let s="/global/spend/tags";l&&t&&(s="".concat(s,"?start_date=").concat(l,"&end_date=").concat(t)),console.log("in tagsSpendLogsCall:",s);let a=await fetch("".concat(s),{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!a.ok){let e=await a.text();throw u.ZP.error(e,10),Error("Network response was not ok")}let r=await a.json();return console.log(r),r}catch(e){throw console.error("Failed to create key:",e),e}},I=async(e,l,t,s,a,r)=>{try{console.log("user role in spend logs call: ".concat(t));let l="/spend/logs";l="App Owner"==t?"".concat(l,"?user_id=").concat(s,"&start_date=").concat(a,"&end_date=").concat(r):"".concat(l,"?start_date=").concat(a,"&end_date=").concat(r);let n=await fetch(l,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!n.ok){let e=await n.text();throw u.ZP.error(e,10),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}},C=async e=>{try{let l=await fetch("/global/spend/logs",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw u.ZP.error(e,10),Error("Network response was not ok")}let t=await l.json();return console.log(t),t}catch(e){throw console.error("Failed to create key:",e),e}},P=async e=>{try{let l=await fetch("/global/spend/keys?limit=5",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw u.ZP.error(e,10),Error("Network response was not ok")}let t=await l.json();return console.log(t),t}catch(e){throw console.error("Failed to create key:",e),e}},T=async(e,l,t,s)=>{try{let a="";a=l?JSON.stringify({api_key:l,startTime:t,endTime:s}):JSON.stringify({startTime:t,endTime:s});let r={method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}};r.body=a;let n=await fetch("/global/spend/end_users",r);if(!n.ok){let e=await n.text();throw u.ZP.error(e,10),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}},O=async e=>{try{let l=await fetch("/global/spend/models?limit=5",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw u.ZP.error(e,10),Error("Network response was not ok")}let t=await l.json();return console.log(t),t}catch(e){throw console.error("Failed to create key:",e),e}},F=async(e,l)=>{try{let t=await fetch("/v2/key/info",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({keys:l})});if(!t.ok){let e=await t.text();throw u.ZP.error(e,10),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}},R=async(e,l)=>{try{let t="/user/get_users?role=".concat(l);console.log("in userGetAllUsersCall:",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 u.ZP.error("Failed to delete key: "+e,10),Error("Network response was not ok")}let a=await s.json();return console.log(a),a}catch(e){throw console.error("Failed to get requested models:",e),e}},M=async(e,l)=>{try{console.log("Form Values in teamCreateCall:",l);let t=await fetch("/team/new",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...l})});if(!t.ok){let e=await t.text();throw u.ZP.error("Failed to create key: "+e,10),console.error("Error response from the server:",e),Error("Network response was not ok")}let s=await t.json();return console.log("API Response:",s),s}catch(e){throw console.error("Failed to create key:",e),e}},L=async(e,l)=>{try{console.log("Form Values in keyUpdateCall:",l);let t=await fetch("/key/update",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...l})});if(!t.ok){let e=await t.text();throw u.ZP.error("Failed to update key: "+e,10),console.error("Error response from the server:",e),Error("Network response was not ok")}let s=await t.json();return console.log("Update key Response:",s),s}catch(e){throw console.error("Failed to create key:",e),e}},U=async(e,l)=>{try{console.log("Form Values in teamUpateCall:",l);let t=await fetch("/team/update",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...l})});if(!t.ok){let e=await t.text();throw u.ZP.error("Failed to update team: "+e,10),console.error("Error response from the server:",e),Error("Network response was not ok")}let s=await t.json();return console.log("Update Team Response:",s),s}catch(e){throw console.error("Failed to create key:",e),e}},D=async(e,l)=>{try{console.log("Form Values in modelUpateCall:",l);let t=await fetch("/model/update",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...l})});if(!t.ok){let e=await t.text();throw u.ZP.error("Failed to update model: "+e,10),console.error("Error update from the server:",e),Error("Network response was not ok")}let s=await t.json();return console.log("Update model Response:",s),s}catch(e){throw console.error("Failed to update model:",e),e}},K=async(e,l,t)=>{try{console.log("Form Values in teamMemberAddCall:",t);let s=await fetch("/team/member_add",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({team_id:l,member:t})});if(!s.ok){let e=await s.text();throw u.ZP.error("Failed to create key: "+e,10),console.error("Error response from the server:",e),Error("Network response was not ok")}let a=await s.json();return console.log("API Response:",a),a}catch(e){throw console.error("Failed to create key:",e),e}},B=async(e,l,t)=>{try{console.log("Form Values in userUpdateUserCall:",l);let s={...l};null!==t&&(s.user_role=t),s=JSON.stringify(s);let a=await fetch("/user/update",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:s});if(!a.ok){let e=await a.text();throw u.ZP.error("Failed to create key: "+e,10),console.error("Error response from the server:",e),Error("Network response was not ok")}let r=await a.json();return console.log("API Response:",r),r}catch(e){throw console.error("Failed to create key:",e),e}},z=async(e,l)=>{try{let t="/health/services?service=".concat(l);console.log("Checking Slack Budget Alerts service health");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 u.ZP.error("Failed ".concat(l," service health check ")+e),Error(e)}let a=await s.json();return u.ZP.success("Test request to ".concat(l," made - check logs/alerts on ").concat(l," to verify")),a}catch(e){throw console.error("Failed to perform health check:",e),e}},q=async(e,l,t)=>{try{let l=await fetch("/get/config/callbacks",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw u.ZP.error(e,10),Error("Network response was not ok")}return await l.json()}catch(e){throw console.error("Failed to get callbacks:",e),e}},V=async(e,l)=>{try{let t=await fetch("/config/update",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...l})});if(!t.ok){let e=await t.text();throw u.ZP.error(e,10),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to set callbacks:",e),e}},G=async e=>{try{let l=await fetch("/health",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw u.ZP.error(e),Error("Network response was not ok")}return await l.json()}catch(e){throw console.error("Failed to call /health:",e),e}};var Y=t(10384),W=t(46453),J=t(16450),H=t(52273),$=t(26780),X=t(15595),Q=t(6698),ee=t(71801),el=t(42440),et=t(42308),es=t(50670),ea=t(81583),er=t(99129),en=t(44839),eo=t(88707),ei=t(1861);let{Option:ec}=es.default;var ed=e=>{let{userID:l,team:t,userRole:s,accessToken:a,data:o,setData:i}=e,[c]=ea.Z.useForm(),[d,m]=(0,n.useState)(!1),[h,x]=(0,n.useState)(null),[p,g]=(0,n.useState)(null),[y,f]=(0,n.useState)([]),[Z,_]=(0,n.useState)([]),w=()=>{m(!1),c.resetFields()},b=()=>{m(!1),x(null),c.resetFields()};(0,n.useEffect)(()=>{(async()=>{try{if(null===l||null===s)return;if(null!==a){let e=(await N(a,l,s)).data.map(e=>e.id);console.log("available_model_names:",e),f(e)}}catch(e){console.error("Error fetching user models:",e)}})()},[a,l,s]);let k=async e=>{try{var t,s,r;let n=null!==(t=null==e?void 0:e.key_alias)&&void 0!==t?t:"",d=null!==(s=null==e?void 0:e.team_id)&&void 0!==s?s:null;if((null!==(r=null==o?void 0:o.filter(e=>e.team_id===d).map(e=>e.key_alias))&&void 0!==r?r:[]).includes(n))throw Error("Key alias ".concat(n," already exists for team with ID ").concat(d,", please provide another key alias"));u.ZP.info("Making API Call"),m(!0);let h=await j(a,l,e);console.log("key create Response:",h),i(e=>e?[...e,h]:[h]),x(h.key),g(h.soft_budget),u.ZP.success("API Key Created"),c.resetFields(),localStorage.removeItem("userData"+l)}catch(e){console.error("Error creating the key:",e),u.ZP.error("Error creating the key: ".concat(e),20)}};return(0,n.useEffect)(()=>{_(t&&t.models.length>0?t.models.includes("all-proxy-models")?y:t.models:y)},[t,y]),(0,r.jsxs)("div",{children:[(0,r.jsx)(J.Z,{className:"mx-auto",onClick:()=>m(!0),children:"+ Create New Key"}),(0,r.jsx)(er.Z,{title:"Create Key",visible:d,width:800,footer:null,onOk:w,onCancel:b,children:(0,r.jsxs)(ea.Z,{form:c,onFinish:k,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(ea.Z.Item,{label:"Key Name",name:"key_alias",rules:[{required:!0,message:"Please input a key name"}],help:"required",children:(0,r.jsx)(H.Z,{placeholder:""})}),(0,r.jsx)(ea.Z.Item,{label:"Team ID",name:"team_id",hidden:!0,initialValue:t?t.team_id:null,valuePropName:"team_id",className:"mt-8",children:(0,r.jsx)(en.Z,{value:t?t.team_alias:"",disabled:!0})}),(0,r.jsx)(ea.Z.Item,{label:"Models",name:"models",rules:[{required:!0,message:"Please select a model"}],help:"required",children:(0,r.jsxs)(es.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},onChange:e=>{e.includes("all-team-models")&&c.setFieldsValue({models:["all-team-models"]})},children:[(0,r.jsx)(ec,{value:"all-team-models",children:"All Team Models"},"all-team-models"),Z.map(e=>(0,r.jsx)(ec,{value:e,children:e},e))]})}),(0,r.jsxs)($.Z,{className:"mt-20 mb-8",children:[(0,r.jsx)(Q.Z,{children:(0,r.jsx)("b",{children:"Optional Settings"})}),(0,r.jsxs)(X.Z,{children:[(0,r.jsx)(ea.Z.Item,{className:"mt-8",label:"Max Budget (USD)",name:"max_budget",help:"Budget cannot exceed team max budget: $".concat((null==t?void 0:t.max_budget)!==null&&(null==t?void 0:t.max_budget)!==void 0?null==t?void 0:t.max_budget:"unlimited"),rules:[{validator:async(e,l)=>{if(l&&t&&null!==t.max_budget&&l>t.max_budget)throw Error("Budget cannot exceed team max budget: $".concat(t.max_budget))}}],children:(0,r.jsx)(eo.Z,{step:.01,precision:2,width:200})}),(0,r.jsx)(ea.Z.Item,{className:"mt-8",label:"Reset Budget",name:"budget_duration",help:"Team Reset Budget: ".concat((null==t?void 0:t.budget_duration)!==null&&(null==t?void 0:t.budget_duration)!==void 0?null==t?void 0:t.budget_duration:"None"),children:(0,r.jsxs)(es.default,{defaultValue:null,placeholder:"n/a",children:[(0,r.jsx)(es.default.Option,{value:"24h",children:"daily"}),(0,r.jsx)(es.default.Option,{value:"30d",children:"monthly"})]})}),(0,r.jsx)(ea.Z.Item,{className:"mt-8",label:"Tokens per minute Limit (TPM)",name:"tpm_limit",help:"TPM cannot exceed team TPM limit: ".concat((null==t?void 0:t.tpm_limit)!==null&&(null==t?void 0:t.tpm_limit)!==void 0?null==t?void 0:t.tpm_limit:"unlimited"),rules:[{validator:async(e,l)=>{if(l&&t&&null!==t.tpm_limit&&l>t.tpm_limit)throw Error("TPM limit cannot exceed team TPM limit: ".concat(t.tpm_limit))}}],children:(0,r.jsx)(eo.Z,{step:1,width:400})}),(0,r.jsx)(ea.Z.Item,{className:"mt-8",label:"Requests per minute Limit (RPM)",name:"rpm_limit",help:"RPM cannot exceed team RPM limit: ".concat((null==t?void 0:t.rpm_limit)!==null&&(null==t?void 0:t.rpm_limit)!==void 0?null==t?void 0:t.rpm_limit:"unlimited"),rules:[{validator:async(e,l)=>{if(l&&t&&null!==t.rpm_limit&&l>t.rpm_limit)throw Error("RPM limit cannot exceed team RPM limit: ".concat(t.rpm_limit))}}],children:(0,r.jsx)(eo.Z,{step:1,width:400})}),(0,r.jsx)(ea.Z.Item,{label:"Expire Key (eg: 30s, 30h, 30d)",name:"duration",className:"mt-8",children:(0,r.jsx)(H.Z,{placeholder:""})}),(0,r.jsx)(ea.Z.Item,{label:"Metadata",name:"metadata",children:(0,r.jsx)(en.Z.TextArea,{rows:4,placeholder:"Enter metadata as JSON"})})]})]})]}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ei.ZP,{htmlType:"submit",children:"Create Key"})})]})}),h&&(0,r.jsx)(er.Z,{visible:d,onOk:w,onCancel:b,footer:null,children:(0,r.jsxs)(W.Z,{numItems:1,className:"gap-2 w-full",children:[(0,r.jsx)(el.Z,{children:"Save your Key"}),(0,r.jsx)(Y.Z,{numColSpan:1,children:(0,r.jsxs)("p",{children:["Please save this secret key somewhere safe and accessible. For security reasons, ",(0,r.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,r.jsx)(Y.Z,{numColSpan:1,children:null!=h?(0,r.jsxs)("div",{children:[(0,r.jsx)(ee.Z,{className:"mt-3",children:"API Key:"}),(0,r.jsx)("div",{style:{background:"#f8f8f8",padding:"10px",borderRadius:"5px",marginBottom:"10px"},children:(0,r.jsx)("pre",{style:{wordWrap:"break-word",whiteSpace:"normal"},children:h})}),(0,r.jsx)(et.CopyToClipboard,{text:h,onCopy:()=>{u.ZP.success("API Key copied to clipboard")},children:(0,r.jsx)(J.Z,{className:"mt-3",children:"Copy API Key"})})]}):(0,r.jsx)(ee.Z,{children:"Key being created, this might take 30s"})})]})})]})},em=t(9454),eu=t(98941),eh=t(33393),ex=t(5),ep=t(13810),ej=t(61244),eg=t(10827),ey=t(3851),ef=t(2044),eZ=t(64167),e_=t(74480),ew=t(7178),eb=t(95093),ek=t(27166);let{Option:ev}=es.default;var eS=e=>{let{userID:l,userRole:t,accessToken:s,selectedTeam:a,data:o,setData:i,teams:c}=e,[d,m]=(0,n.useState)(!1),[h,x]=(0,n.useState)(!1),[p,j]=(0,n.useState)(null),[g,f]=(0,n.useState)(null),[Z,_]=(0,n.useState)(null),[w,b]=(0,n.useState)(""),[k,v]=(0,n.useState)(!1),[S,A]=(0,n.useState)(!1),[E,I]=(0,n.useState)(null),[C,P]=(0,n.useState)([]),T=new Set,[O,F]=(0,n.useState)(T);(0,n.useEffect)(()=>{(async()=>{try{if(null===l)return;if(null!==s&&null!==t){let e=(await N(s,l,t)).data.map(e=>e.id);console.log("available_model_names:",e),P(e)}}catch(e){console.error("Error fetching user models:",e)}})()},[s,l,t]),(0,n.useEffect)(()=>{if(c){let e=new Set;c.forEach((l,t)=>{let s=l.team_id;e.add(s)}),F(e)}},[c]);let R=e=>{console.log("handleEditClick:",e),null==e.token&&null!==e.token_id&&(e.token=e.token_id),I(e),v(!0)},M=async e=>{if(null==s)return;let l=e.token;e.key=l,console.log("handleEditSubmit:",e);let t=await L(s,e);console.log("handleEditSubmit: newKeyValues",t),o&&i(o.map(e=>e.token===l?t:e)),u.ZP.success("Key updated successfully"),v(!1),I(null)},U=async e=>{console.log("handleDelete:",e),null==e.token&&null!==e.token_id&&(e.token=e.token_id),null!=o&&(j(e.token),localStorage.removeItem("userData"+l),x(!0))},D=async()=>{if(null!=p&&null!=o){try{await y(s,p);let e=o.filter(e=>e.token!==p);i(e)}catch(e){console.error("Error deleting the key:",e)}x(!1),j(null)}};if(null!=o)return console.log("RERENDER TRIGGERED"),(0,r.jsxs)("div",{children:[(0,r.jsxs)(ep.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh] mb-4 mt-2",children:[(0,r.jsxs)(eg.Z,{className:"mt-5 max-h-[300px] min-h-[300px]",children:[(0,r.jsx)(eZ.Z,{children:(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(e_.Z,{children:"Key Alias"}),(0,r.jsx)(e_.Z,{children:"Secret Key"}),(0,r.jsx)(e_.Z,{children:"Spend (USD)"}),(0,r.jsx)(e_.Z,{children:"Budget (USD)"}),(0,r.jsx)(e_.Z,{children:"Models"}),(0,r.jsx)(e_.Z,{children:"TPM / RPM Limits"})]})}),(0,r.jsx)(ey.Z,{children:o.map(e=>{if(console.log(e),"litellm-dashboard"===e.team_id)return null;if(a){if(console.log("item team id: ".concat(e.team_id,", knownTeamIDs.has(item.team_id): ").concat(O.has(e.team_id),", selectedTeam id: ").concat(a.team_id)),(null!=a.team_id||null===e.team_id||O.has(e.team_id))&&e.team_id!=a.team_id)return null;console.log("item team id: ".concat(e.team_id,", is returned"))}return(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(ef.Z,{style:{maxWidth:"2px",whiteSpace:"pre-wrap",overflow:"hidden"},children:null!=e.key_alias?(0,r.jsx)(ee.Z,{children:e.key_alias}):(0,r.jsx)(ee.Z,{children:"Not Set"})}),(0,r.jsx)(ef.Z,{children:(0,r.jsx)(ee.Z,{children:e.key_name})}),(0,r.jsx)(ef.Z,{children:(0,r.jsx)(ee.Z,{children:(()=>{try{return parseFloat(e.spend).toFixed(4)}catch(l){return e.spend}})()})}),(0,r.jsx)(ef.Z,{children:null!=e.max_budget?(0,r.jsx)(ee.Z,{children:e.max_budget}):(0,r.jsx)(ee.Z,{children:"Unlimited"})}),(0,r.jsx)(ef.Z,{children:Array.isArray(e.models)?(0,r.jsx)("div",{style:{display:"flex",flexDirection:"column"},children:0===e.models.length?(0,r.jsx)(r.Fragment,{children:a&&a.models&&a.models.length>0?a.models.map((e,l)=>"all-proxy-models"===e?(0,r.jsx)(ex.Z,{size:"xs",className:"mb-1",color:"red",children:(0,r.jsx)(ee.Z,{children:"All Proxy Models"})},l):"all-team-models"===e?(0,r.jsx)(ex.Z,{size:"xs",className:"mb-1",color:"red",children:(0,r.jsx)(ee.Z,{children:"All Team Models"})},l):(0,r.jsx)(ex.Z,{size:"xs",className:"mb-1",color:"blue",children:(0,r.jsx)(ee.Z,{children:e.length>30?"".concat(e.slice(0,30),"..."):e})},l)):(0,r.jsx)(ex.Z,{size:"xs",className:"mb-1",color:"blue",children:(0,r.jsx)(ee.Z,{children:"all-proxy-models"})})}):e.models.map((e,l)=>"all-proxy-models"===e?(0,r.jsx)(ex.Z,{size:"xs",className:"mb-1",color:"red",children:(0,r.jsx)(ee.Z,{children:"All Proxy Models"})},l):"all-team-models"===e?(0,r.jsx)(ex.Z,{size:"xs",className:"mb-1",color:"red",children:(0,r.jsx)(ee.Z,{children:"All Team Models"})},l):(0,r.jsx)(ex.Z,{size:"xs",className:"mb-1",color:"blue",children:(0,r.jsx)(ee.Z,{children:e.length>30?"".concat(e.slice(0,30),"..."):e})},l))}):null}),(0,r.jsx)(ef.Z,{children:(0,r.jsxs)(ee.Z,{children:["TPM: ",e.tpm_limit?e.tpm_limit:"Unlimited"," ",(0,r.jsx)("br",{})," RPM:"," ",e.rpm_limit?e.rpm_limit:"Unlimited"]})}),(0,r.jsxs)(ef.Z,{children:[(0,r.jsx)(ej.Z,{onClick:()=>{I(e),A(!0)},icon:em.Z,size:"sm"}),(0,r.jsx)(er.Z,{open:S,onCancel:()=>{A(!1),I(null)},footer:null,width:800,children:E&&(0,r.jsxs)(r.Fragment,{children:[(0,r.jsxs)("div",{className:"grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3 mt-8",children:[(0,r.jsxs)(ep.Z,{children:[(0,r.jsx)("p",{className:"text-tremor-default font-medium text-tremor-content dark:text-dark-tremor-content",children:"Spend"}),(0,r.jsx)("div",{className:"mt-2 flex items-baseline space-x-2.5",children:(0,r.jsx)("p",{className:"text-tremor font-semibold text-tremor-content-strong dark:text-dark-tremor-content-strong",children:(()=>{try{return parseFloat(E.spend).toFixed(4)}catch(e){return E.spend}})()})})]}),(0,r.jsxs)(ep.Z,{children:[(0,r.jsx)("p",{className:"text-tremor-default font-medium text-tremor-content dark:text-dark-tremor-content",children:"Budget"}),(0,r.jsx)("div",{className:"mt-2 flex items-baseline space-x-2.5",children:(0,r.jsx)("p",{className:"text-tremor font-semibold text-tremor-content-strong dark:text-dark-tremor-content-strong",children:null!=E.max_budget?(0,r.jsx)(r.Fragment,{children:E.max_budget}):(0,r.jsx)(r.Fragment,{children:"Unlimited"})})})]},e.name),(0,r.jsxs)(ep.Z,{children:[(0,r.jsx)("p",{className:"text-tremor-default font-medium text-tremor-content dark:text-dark-tremor-content",children:"Expires"}),(0,r.jsx)("div",{className:"mt-2 flex items-baseline space-x-2.5",children:(0,r.jsx)("p",{className:"text-tremor-default font-small text-tremor-content-strong dark:text-dark-tremor-content-strong",children:null!=E.expires?(0,r.jsx)(r.Fragment,{children:new Date(E.expires).toLocaleString(void 0,{day:"numeric",month:"long",year:"numeric",hour:"numeric",minute:"numeric",second:"numeric"})}):(0,r.jsx)(r.Fragment,{children:"Never"})})})]},e.name)]}),(0,r.jsxs)(ep.Z,{className:"my-4",children:[(0,r.jsx)(el.Z,{children:"Token Name"}),(0,r.jsx)(ee.Z,{className:"my-1",children:E.key_alias?E.key_alias:E.key_name}),(0,r.jsx)(el.Z,{children:"Token ID"}),(0,r.jsx)(ee.Z,{className:"my-1 text-[12px]",children:E.token}),(0,r.jsx)(el.Z,{children:"Metadata"}),(0,r.jsx)(ee.Z,{className:"my-1",children:(0,r.jsxs)("pre",{children:[JSON.stringify(E.metadata)," "]})})]}),(0,r.jsx)(J.Z,{className:"mx-auto flex items-center",onClick:()=>{A(!1),I(null)},children:"Close"})]})}),(0,r.jsx)(ej.Z,{icon:eu.Z,size:"sm",onClick:()=>R(e)}),(0,r.jsx)(ej.Z,{onClick:()=>U(e),icon:eh.Z,size:"sm"})]})]},e.token)})})]}),h&&(0,r.jsx)("div",{className:"fixed z-10 inset-0 overflow-y-auto",children:(0,r.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,r.jsx)("div",{className:"fixed inset-0 transition-opacity","aria-hidden":"true",children:(0,r.jsx)("div",{className:"absolute inset-0 bg-gray-500 opacity-75"})}),(0,r.jsx)("span",{className:"hidden sm:inline-block sm:align-middle sm:h-screen","aria-hidden":"true",children:"โ€‹"}),(0,r.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,r.jsx)("div",{className:"bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4",children:(0,r.jsx)("div",{className:"sm:flex sm:items-start",children:(0,r.jsxs)("div",{className:"mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left",children:[(0,r.jsx)("h3",{className:"text-lg leading-6 font-medium text-gray-900",children:"Delete Key"}),(0,r.jsx)("div",{className:"mt-2",children:(0,r.jsx)("p",{className:"text-sm text-gray-500",children:"Are you sure you want to delete this key ?"})})]})})}),(0,r.jsxs)("div",{className:"bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse",children:[(0,r.jsx)(J.Z,{onClick:D,color:"red",className:"ml-2",children:"Delete"}),(0,r.jsx)(J.Z,{onClick:()=>{x(!1),j(null)},children:"Cancel"})]})]})]})})]}),E&&(0,r.jsx)(e=>{let{visible:l,onCancel:t,token:s,onSubmit:o}=e,[i]=ea.Z.useForm(),[d,m]=(0,n.useState)(a),[u,h]=(0,n.useState)([]),[x,p]=(0,n.useState)(!1);return(0,r.jsx)(er.Z,{title:"Edit Key",visible:l,width:800,footer:null,onOk:()=>{i.validateFields().then(e=>{i.resetFields()}).catch(e=>{console.error("Validation failed:",e)})},onCancel:t,children:(0,r.jsxs)(ea.Z,{form:i,onFinish:M,initialValues:s,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(ea.Z.Item,{label:"Key Name",name:"key_alias",rules:[{required:!0,message:"Please input a key name"}],help:"required",children:(0,r.jsx)(en.Z,{})}),(0,r.jsx)(ea.Z.Item,{label:"Models",name:"models",rules:[{validator:(e,l)=>{let t=l.filter(e=>!d.models.includes(e)&&"all-team-models"!==e&&"all-proxy-models"!==e&&!d.models.includes("all-proxy-models"));return(console.log("errorModels: ".concat(t)),t.length>0)?Promise.reject("Some models are not part of the new team's models - ".concat(t,"Team models: ").concat(d.models)):Promise.resolve()}}],children:(0,r.jsxs)(es.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:[(0,r.jsx)(ev,{value:"all-team-models",children:"All Team Models"},"all-team-models"),d&&d.models?d.models.includes("all-proxy-models")?C.filter(e=>"all-proxy-models"!==e).map(e=>(0,r.jsx)(ev,{value:e,children:e},e)):d.models.map(e=>(0,r.jsx)(ev,{value:e,children:e},e)):C.map(e=>(0,r.jsx)(ev,{value:e,children:e},e))]})}),(0,r.jsx)(ea.Z.Item,{className:"mt-8",label:"Max Budget (USD)",name:"max_budget",help:"Budget cannot exceed team max budget: ".concat((null==d?void 0:d.max_budget)!==null&&(null==d?void 0:d.max_budget)!==void 0?null==d?void 0:d.max_budget:"unlimited"),rules:[{validator:async(e,l)=>{if(l&&d&&null!==d.max_budget&&l>d.max_budget)throw console.log("keyTeam.max_budget: ".concat(d.max_budget)),Error("Budget cannot exceed team max budget: $".concat(d.max_budget))}}],children:(0,r.jsx)(eo.Z,{step:.01,precision:2,width:200})}),(0,r.jsx)(ea.Z.Item,{label:"token",name:"token",hidden:!0}),(0,r.jsx)(ea.Z.Item,{label:"Team",name:"team_id",help:"the team this key belongs to",children:(0,r.jsx)(eb.Z,{value:s.team_alias,children:null==c?void 0:c.map((e,l)=>(0,r.jsx)(ek.Z,{value:e.team_id,onClick:()=>m(e),children:e.team_alias},l))})})]}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ei.ZP,{htmlType:"submit",children:"Edit Key"})})]})})},{visible:k,onCancel:()=>{v(!1),I(null)},token:E,onSubmit:M})]})},eN=t(76032),eA=t(35152),eE=e=>{let{userID:l,userRole:t,accessToken:s,userSpend:a,selectedTeam:o}=e;console.log("userSpend: ".concat(a));let[i,c]=(0,n.useState)(null!==a?a:0),[d,m]=(0,n.useState)(0),[u,h]=(0,n.useState)([]);(0,n.useEffect)(()=>{let e=async()=>{if(s&&l&&t&&"Admin"===t&&null==a)try{let e=await w(s);e&&(e.spend?c(e.spend):c(0),e.max_budget?m(e.max_budget):m(0))}catch(e){console.error("Error fetching global spend data:",e)}};(async()=>{try{if(null===l||null===t)return;if(null!==s){let e=(await N(s,l,t)).data.map(e=>e.id);console.log("available_model_names:",e),h(e)}}catch(e){console.error("Error fetching user models:",e)}})(),e()},[t,s,l]),(0,n.useEffect)(()=>{null!==a&&c(a)},[a]);let x=[];o&&o.models&&(x=o.models),x&&x.includes("all-proxy-models")?(console.log("user models:",u),x=u):x&&x.includes("all-team-models")?x=o.models:x&&0===x.length&&(x=u);let p=void 0!==i?i.toFixed(4):null;return console.log("spend in view user spend: ".concat(i)),(0,r.jsxs)("div",{className:"flex items-center",children:[(0,r.jsxs)("div",{children:[(0,r.jsxs)("p",{className:"text-tremor-default text-tremor-content dark:text-dark-tremor-content",children:["Total Spend"," "]}),(0,r.jsxs)("p",{className:"text-2xl text-tremor-content-strong dark:text-dark-tremor-content-strong font-semibold",children:["$",p]})]}),(0,r.jsx)("div",{className:"ml-auto",children:(0,r.jsxs)($.Z,{children:[(0,r.jsx)(Q.Z,{children:(0,r.jsx)(ee.Z,{children:"Team Models"})}),(0,r.jsx)(X.Z,{className:"absolute right-0 z-10 bg-white p-2 shadow-lg max-w-xs",children:(0,r.jsx)(eN.Z,{children:x.map(e=>(0,r.jsx)(eA.Z,{children:(0,r.jsx)(ee.Z,{children:e})},e))})})]})})]})},eI=e=>{let{userID:l,userRole:t,selectedTeam:s,accessToken:a}=e,[o,i]=(0,n.useState)([]);(0,n.useEffect)(()=>{(async()=>{try{if(null===l||null===t)return;if(null!==a){let e=(await N(a,l,t)).data.map(e=>e.id);console.log("available_model_names:",e),i(e)}}catch(e){console.error("Error fetching user models:",e)}})()},[a,l,t]);let c=[];return s&&s.models&&(c=s.models),c&&c.includes("all-proxy-models")&&(console.log("user models:",o),c=o),(0,r.jsx)(r.Fragment,{children:(0,r.jsx)("div",{className:"mb-5",children:(0,r.jsx)("p",{className:"text-3xl text-tremor-content-strong dark:text-dark-tremor-content-strong font-semibold",children:null==s?void 0:s.team_alias})})})},eC=e=>{let l,{teams:t,setSelectedTeam:s,userRole:a}=e,o={models:[],team_id:null,team_alias:"Default Team"},[i,c]=(0,n.useState)(o);return(l="App User"===a?t:t?[...t,o]:[o],"App User"===a)?null:(0,r.jsxs)("div",{className:"mt-5 mb-5",children:[(0,r.jsx)(el.Z,{children:"Select Team"}),(0,r.jsx)(ee.Z,{children:"If you belong to multiple teams, this setting controls which team is used by default when creating new API Keys."}),(0,r.jsxs)(ee.Z,{className:"mt-3 mb-3",children:[(0,r.jsx)("b",{children:"Default Team:"})," If no team_id is set for a key, it will be grouped under here."]}),l&&l.length>0?(0,r.jsx)(eb.Z,{defaultValue:"0",children:l.map((e,l)=>(0,r.jsx)(ek.Z,{value:String(l),onClick:()=>s(e),children:e.team_alias},l))}):(0,r.jsxs)(ee.Z,{children:["No team created. ",(0,r.jsx)("b",{children:"Defaulting to personal account."})]})]})},eP=t(37963),eT=t(36083);console.log("isLocal:",!1);var eO=e=>{let{userID:l,userRole:t,teams:s,keys:a,setUserRole:i,userEmail:c,setUserEmail:d,setTeams:m,setKeys:u}=e,[h,x]=(0,n.useState)(null),p=(0,o.useSearchParams)();p.get("viewSpend"),(0,o.useRouter)();let j=p.get("token"),[g,y]=(0,n.useState)(null),[f,_]=(0,n.useState)(null),[b,k]=(0,n.useState)([]),v={models:[],team_alias:"Default Team",team_id:null},[S,A]=(0,n.useState)(s?s[0]:v);if(window.addEventListener("beforeunload",function(){sessionStorage.clear()}),(0,n.useEffect)(()=>{if(j){let e=(0,eP.o)(j);if(e){if(console.log("Decoded token:",e),console.log("Decoded key:",e.key),y(e.key),e.user_role){let l=function(e){if(!e)return"Undefined Role";switch(console.log("Received user role: ".concat(e)),e.toLowerCase()){case"app_owner":case"demo_app_owner":return"App Owner";case"app_admin":case"proxy_admin":return"Admin";case"proxy_admin_viewer":return"Admin Viewer";case"app_user":return"App User";default:return"Unknown Role"}}(e.user_role);console.log("Decoded user_role:",l),i(l)}else console.log("User role not defined");e.user_email?d(e.user_email):console.log("User Email is not set ".concat(e))}}if(l&&g&&t&&!a&&!h){let e=sessionStorage.getItem("userModels"+l);e?k(JSON.parse(e)):(async()=>{try{let e=await Z(g,l,t,!1,null,null);if(console.log("received teams in user dashboard: ".concat(Object.keys(e),"; team values: ").concat(Object.entries(e.teams))),"Admin"==t){let e=await w(g);x(e),console.log("globalSpend:",e)}else x(e.user_info);u(e.keys),m(e.teams);let s=[...e.teams];s.length>0?(console.log("response['teams']: ".concat(s)),A(s[0])):A(v),sessionStorage.setItem("userData"+l,JSON.stringify(e.keys)),sessionStorage.setItem("userSpendData"+l,JSON.stringify(e.user_info));let a=(await N(g,l,t)).data.map(e=>e.id);console.log("available_model_names:",a),k(a),console.log("userModels:",b),sessionStorage.setItem("userModels"+l,JSON.stringify(a))}catch(e){console.error("There was an error fetching the data",e)}})()}},[l,j,g,a,t]),(0,n.useEffect)(()=>{if(null!==a&&null!=S){let e=0;for(let l of a)S.hasOwnProperty("team_id")&&null!==l.team_id&&l.team_id===S.team_id&&(e+=l.spend);_(e)}else if(null!==a){let e=0;for(let l of a)e+=l.spend;_(e)}},[S]),null==l||null==j){let e="/sso/key/generate";return console.log("Full URL:",e),window.location.href=e,null}if(null==g)return null;if(null==t&&i("App Owner"),t&&"Admin Viewer"==t){let{Title:e,Paragraph:l}=eT.default;return(0,r.jsxs)("div",{children:[(0,r.jsx)(e,{level:1,children:"Access Denied"}),(0,r.jsx)(l,{children:"Ask your proxy admin for access to create keys"})]})}return console.log("inside user dashboard, selected team",S),console.log("teamSpend: ".concat(f)),(0,r.jsx)("div",{className:"w-full mx-4",children:(0,r.jsx)(W.Z,{numItems:1,className:"gap-2 p-8 h-[75vh] w-full mt-2",children:(0,r.jsxs)(Y.Z,{numColSpan:1,children:[(0,r.jsx)(eI,{userID:l,userRole:t,selectedTeam:S||null,accessToken:g}),(0,r.jsx)(eE,{userID:l,userRole:t,accessToken:g,userSpend:f,selectedTeam:S||null}),(0,r.jsx)(eS,{userID:l,userRole:t,accessToken:g,selectedTeam:S||null,data:a,setData:u,teams:s}),(0,r.jsx)(ed,{userID:l,team:S||null,userRole:t,accessToken:g,data:a,setData:u},S?S.team_id:null),(0,r.jsx)(eC,{teams:s,setSelectedTeam:A,userRole:t})]})})})},eF=t(35087),eR=t(92836),eM=t(26734),eL=t(41608),eU=t(32126),eD=t(23682),eK=t(47047),eB=t(76628),ez=t(57750),eq=t(44041),eV=t(38302),eG=t(28683),eY=t(1460),eW=t(78578),eJ=t(63954),eH=t(90252),e$=t(7905),eX=e=>{let{modelID:l,accessToken:t}=e,[s,a]=(0,n.useState)(!1),o=async()=>{try{u.ZP.info("Making API Call"),a(!0);let e=await p(t,l);console.log("model delete Response:",e),u.ZP.success("Model ".concat(l," deleted successfully")),a(!1)}catch(e){console.error("Error deleting the model:",e)}};return(0,r.jsxs)("div",{children:[(0,r.jsx)(ej.Z,{onClick:()=>a(!0),icon:eh.Z,size:"sm"}),(0,r.jsx)(er.Z,{open:s,onOk:o,okType:"danger",onCancel:()=>a(!1),children:(0,r.jsxs)(W.Z,{numItems:1,className:"gap-2 w-full",children:[(0,r.jsx)(el.Z,{children:"Delete Model"}),(0,r.jsx)(Y.Z,{numColSpan:1,children:(0,r.jsx)("p",{children:"Are you sure you want to delete this model? This action is irreversible."})}),(0,r.jsx)(Y.Z,{numColSpan:1,children:(0,r.jsxs)("p",{children:["Model ID: ",(0,r.jsx)("b",{children:l})]})})]})})]})},eQ=t(97766),e0=t(46495);let{Title:e1,Link:e2}=eT.default;(s=a||(a={})).OpenAI="OpenAI",s.Azure="Azure",s.Anthropic="Anthropic",s.Google_AI_Studio="Gemini (Google AI Studio)",s.Bedrock="Amazon Bedrock",s.OpenAI_Compatible="OpenAI-Compatible Endpoints (Groq, Together AI, Mistral AI, etc.)",s.Vertex_AI="Vertex AI (Anthropic, Gemini, etc.)";let e4={OpenAI:"openai",Azure:"azure",Anthropic:"anthropic",Google_AI_Studio:"gemini",Bedrock:"bedrock",OpenAI_Compatible:"openai",Vertex_AI:"vertex_ai"},e8={"BadRequestError (400)":"BadRequestErrorRetries","AuthenticationError (401)":"AuthenticationErrorRetries","TimeoutError (408)":"TimeoutErrorRetries","RateLimitError (429)":"RateLimitErrorRetries","ContentPolicyViolationError (400)":"ContentPolicyViolationErrorRetries","InternalServerError (500)":"InternalServerErrorRetries"},e5=async(e,l,t)=>{try{let s=Array.isArray(e.model)?e.model:[e.model];console.log("received deployments: ".concat(s)),console.log("received type of deployments: ".concat(typeof s)),s.forEach(async t=>{console.log("litellm_model: ".concat(t));let s={},a={};s.model=t;let r="";for(let[l,t]of Object.entries(e))if(""!==t){if("model_name"==l)r+=t;else if("custom_llm_provider"==l)continue;else if("model"==l)continue;else if("base_model"===l)a[l]=t;else if("litellm_extra_params"==l){console.log("litellm_extra_params:",t);let e={};if(t&&void 0!=t){try{e=JSON.parse(t)}catch(e){throw u.ZP.error("Failed to parse LiteLLM Extra Params: "+e,10),Error("Failed to parse litellm_extra_params: "+e)}for(let[l,t]of Object.entries(e))s[l]=t}}else s[l]=t}let n={model_name:r,litellm_params:s,model_info:a},o=await x(l,n);console.log("response for model create call: ".concat(o.data))}),t.resetFields()}catch(e){u.ZP.error("Failed to create model: "+e,10)}};var e3=e=>{var l,t,s;let{accessToken:o,token:i,userRole:c,userID:d,modelData:m={data:[]},setModelData:x}=e,[p,j]=(0,n.useState)([]),[g]=ea.Z.useForm(),[y,f]=(0,n.useState)(null),[Z,_]=(0,n.useState)(""),[w,N]=(0,n.useState)([]),A=Object.values(a).filter(e=>isNaN(Number(e))),[E,I]=(0,n.useState)("OpenAI"),[C,P]=(0,n.useState)(""),[T,O]=(0,n.useState)(!1),[F,R]=(0,n.useState)(null),[M,L]=(0,n.useState)([]),[U,K]=(0,n.useState)(null),[B,z]=(0,n.useState)([]),[Y,et]=(0,n.useState)([]),[es,en]=(0,n.useState)([]),[ec,ed]=(0,n.useState)([]),[em,eh]=(0,n.useState)([]),[ev,eS]=(0,n.useState)([]),[eN,eA]=(0,n.useState)([]),[eE,eI]=(0,n.useState)({from:new Date(Date.now()-6048e5),to:new Date}),[eC,eP]=(0,n.useState)(null),[eO,e3]=(0,n.useState)(0),e6=e=>{R(e),O(!0)},e7=async e=>{if(console.log("handleEditSubmit:",e),null==o)return;let l={},t=null;for(let[s,a]of Object.entries(e))"model_id"!==s?l[s]=a:t=a;let s={litellm_params:l,model_info:{id:t}};console.log("handleEditSubmit payload:",s);try{await D(o,s),u.ZP.success("Model updated successfully, restart server to see updates"),O(!1),R(null)}catch(e){console.log("Error occurred")}},e9=()=>{_(new Date().toLocaleString())},le=async()=>{if(!o){console.error("Access token is missing");return}console.log("new modelGroupRetryPolicy:",eC);try{await V(o,{router_settings:{model_group_retry_policy:eC}}),u.ZP.success("Retry settings saved successfully")}catch(e){console.error("Failed to save retry settings:",e),u.ZP.error("Failed to save retry settings")}};if((0,n.useEffect)(()=>{if(!o||!i||!c||!d)return;let e=async()=>{try{var e,l,t,s,a,r;let n=await b(o,d,c);console.log("Model data response:",n.data),x(n);let i=new Set;for(let e=0;e0&&(u=m[m.length-1],console.log("_initial_model_group:",u),K(u)),console.log("selectedModelGroup:",U);let h=await k(o,d,c,u,null===(e=eE.from)||void 0===e?void 0:e.toISOString(),null===(l=eE.to)||void 0===l?void 0:l.toISOString());console.log("Model metrics response:",h),et(h.data),en(h.all_api_bases);let p=await S(o,d,c,u,null===(t=eE.from)||void 0===t?void 0:t.toISOString(),null===(s=eE.to)||void 0===s?void 0:s.toISOString());console.log("Model exceptions response:",p),ed(p.data),eh(p.exception_types);let j=await v(o,d,c,u,null===(a=eE.from)||void 0===a?void 0:a.toISOString(),null===(r=eE.to)||void 0===r?void 0:r.toISOString());console.log("slowResponses:",j),eA(j);let g=(await q(o,d,c)).router_settings;console.log("routerSettingsInfo:",g);let y=g.model_group_retry_policy,f=g.num_retries;console.log("model_group_retry_policy:",y),console.log("default_retries:",f),eP(y),e3(f)}catch(e){console.error("There was an error fetching the model data",e)}};o&&i&&c&&d&&e();let l=async()=>{let e=await h();console.log("received model cost map data: ".concat(Object.keys(e))),f(e)};null==y&&l(),e9()},[o,i,c,d,y,Z]),!m||!o||!i||!c||!d)return(0,r.jsx)("div",{children:"Loading..."});let ll=[];for(let e=0;e(console.log("GET PROVIDER CALLED! - ".concat(y)),null!=y&&"object"==typeof y&&e in y)?y[e].litellm_provider:"openai";if(a){let e=a.split("/"),l=e[0];n=1===e.length?u(a):l}else n="openai";r&&(o=null==r?void 0:r.input_cost_per_token,i=null==r?void 0:r.output_cost_per_token,c=null==r?void 0:r.max_tokens),(null==s?void 0:s.litellm_params)&&(d=Object.fromEntries(Object.entries(null==s?void 0:s.litellm_params).filter(e=>{let[l]=e;return"model"!==l&&"api_base"!==l}))),m.data[e].provider=n,m.data[e].input_cost=o,m.data[e].output_cost=i,m.data[e].max_tokens=c,m.data[e].api_base=null==s?void 0:null===(t=s.litellm_params)||void 0===t?void 0:t.api_base,m.data[e].cleanedLitellmParams=d,ll.push(s.model_name),console.log(m.data[e])}if(c&&"Admin Viewer"==c){let{Title:e,Paragraph:l}=eT.default;return(0,r.jsxs)("div",{children:[(0,r.jsx)(e,{level:1,children:"Access Denied"}),(0,r.jsx)(l,{children:"Ask your proxy admin for access to view all models"})]})}let lt=e=>{console.log("received provider string: ".concat(e));let l=Object.keys(a).find(l=>a[l]===e);if(l){let e=e4[l];console.log("mappingResult: ".concat(e));let t=[];"object"==typeof y&&Object.entries(y).forEach(l=>{let[s,a]=l;null!==a&&"object"==typeof a&&"litellm_provider"in a&&(a.litellm_provider===e||a.litellm_provider.includes(e))&&t.push(s)}),N(t),console.log("providerModels: ".concat(w))}},ls=async()=>{try{u.ZP.info("Running health check..."),P("");let e=await G(o);P(e)}catch(e){console.error("Error running health check:",e),P("Error running health check")}},la=async(e,l,t)=>{if(console.log("Updating model metrics for group:",e),o&&d&&c&&l&&t){console.log("inside updateModelMetrics - startTime:",l,"endTime:",t),K(e);try{let s=await k(o,d,c,e,l.toISOString(),t.toISOString());console.log("Model metrics response:",s),et(s.data),en(s.all_api_bases);let a=await S(o,d,c,e,l.toISOString(),t.toISOString());console.log("Model exceptions response:",a),ed(a.data),eh(a.exception_types);let r=await v(o,d,c,e,l.toISOString(),t.toISOString());console.log("slowResponses:",r),eA(r)}catch(e){console.error("Failed to fetch model metrics",e)}}};return console.log("selectedProvider: ".concat(E)),console.log("providerModels.length: ".concat(w.length)),(0,r.jsx)("div",{style:{width:"100%",height:"100%"},children:(0,r.jsxs)(eM.Z,{className:"gap-2 p-8 h-[75vh] w-full mt-2",children:[(0,r.jsxs)(eL.Z,{className:"flex justify-between mt-2 w-full items-center",children:[(0,r.jsxs)("div",{className:"flex",children:[(0,r.jsx)(eR.Z,{children:"All Models"}),(0,r.jsx)(eR.Z,{children:"Add Model"}),(0,r.jsx)(eR.Z,{children:(0,r.jsx)("pre",{children:"/health Models"})}),(0,r.jsx)(eR.Z,{children:"Model Analytics"}),(0,r.jsx)(eR.Z,{children:"Model Retry Settings"})]}),(0,r.jsxs)("div",{className:"flex items-center space-x-2",children:[Z&&(0,r.jsxs)(ee.Z,{children:["Last Refreshed: ",Z]}),(0,r.jsx)(ej.Z,{icon:eJ.Z,variant:"shadow",size:"xs",className:"self-center",onClick:e9})]})]}),(0,r.jsxs)(eD.Z,{children:[(0,r.jsxs)(eU.Z,{children:[(0,r.jsxs)(W.Z,{children:[(0,r.jsxs)("div",{className:"flex items-center",children:[(0,r.jsx)(ee.Z,{children:"Filter by Public Model Name"}),(0,r.jsxs)(eb.Z,{className:"mb-4 mt-2 ml-2 w-50",defaultValue:"all",onValueChange:e=>K("all"===e?"all":e),children:[(0,r.jsx)(ek.Z,{value:"all",children:"All Models"}),M.map((e,l)=>(0,r.jsx)(ek.Z,{value:e,onClick:()=>K(e),children:e},l))]})]}),(0,r.jsx)(ep.Z,{children:(0,r.jsxs)(eg.Z,{className:"mt-5",children:[(0,r.jsx)(eZ.Z,{children:(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(e_.Z,{children:"Public Model Name "}),(0,r.jsx)(e_.Z,{children:"Provider"}),"Admin"===c&&(0,r.jsx)(e_.Z,{children:"API Base"}),(0,r.jsx)(e_.Z,{children:"Extra litellm Params"}),(0,r.jsx)(e_.Z,{children:"Input Price per token ($)"}),(0,r.jsx)(e_.Z,{children:"Output Price per token ($)"}),(0,r.jsx)(e_.Z,{children:"Max Tokens"}),(0,r.jsx)(e_.Z,{children:"Status"})]})}),(0,r.jsx)(ey.Z,{children:m.data.filter(e=>"all"===U||e.model_name===U||null==U||""===U).map((e,l)=>(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(ef.Z,{children:(0,r.jsx)(ee.Z,{children:e.model_name})}),(0,r.jsx)(ef.Z,{children:e.provider}),"Admin"===c&&(0,r.jsx)(ef.Z,{children:e.api_base}),(0,r.jsx)(ef.Z,{children:(0,r.jsxs)($.Z,{children:[(0,r.jsx)(Q.Z,{children:(0,r.jsx)(ee.Z,{children:"Litellm params"})}),(0,r.jsx)(X.Z,{children:(0,r.jsx)("pre",{children:JSON.stringify(e.cleanedLitellmParams,null,2)})})]})}),(0,r.jsx)(ef.Z,{children:e.input_cost||e.litellm_params.input_cost_per_token||null}),(0,r.jsx)(ef.Z,{children:e.output_cost||e.litellm_params.output_cost_per_token||null}),(0,r.jsx)(ef.Z,{children:e.max_tokens}),(0,r.jsx)(ef.Z,{children:e.model_info.db_model?(0,r.jsx)(ex.Z,{icon:eH.Z,className:"text-white",children:"DB Model"}):(0,r.jsx)(ex.Z,{icon:e$.Z,className:"text-black",children:"Config Model"})}),(0,r.jsxs)(ef.Z,{children:[(0,r.jsx)(ej.Z,{icon:eu.Z,size:"sm",onClick:()=>e6(e)}),(0,r.jsx)(eX,{modelID:e.model_info.id,accessToken:o})]})]},l))})]})})]}),(0,r.jsx)(e=>{let{visible:l,onCancel:t,model:s,onSubmit:a}=e,[n]=ea.Z.useForm(),o={},i="",c="";if(s){o=s.litellm_params,i=s.model_name;let e=s.model_info;e&&(c=e.id,console.log("model_id: ".concat(c)),o.model_id=c)}return(0,r.jsx)(er.Z,{title:"Edit Model "+i,visible:l,width:800,footer:null,onOk:()=>{n.validateFields().then(e=>{a(e),n.resetFields()}).catch(e=>{console.error("Validation failed:",e)})},onCancel:t,children:(0,r.jsxs)(ea.Z,{form:n,onFinish:e7,initialValues:o,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(ea.Z.Item,{className:"mt-8",label:"api_base",name:"api_base",children:(0,r.jsx)(H.Z,{})}),(0,r.jsx)(ea.Z.Item,{label:"tpm",name:"tpm",tooltip:"int (optional) - Tokens limit for this deployment: in tokens per minute (tpm). Find this information on your model/providers website",children:(0,r.jsx)(eo.Z,{min:0,step:1})}),(0,r.jsx)(ea.Z.Item,{label:"rpm",name:"rpm",tooltip:"int (optional) - Rate limit for this deployment: in requests per minute (rpm). Find this information on your model/providers website",children:(0,r.jsx)(eo.Z,{min:0,step:1})}),(0,r.jsx)(ea.Z.Item,{label:"max_retries",name:"max_retries",children:(0,r.jsx)(eo.Z,{min:0,step:1})}),(0,r.jsx)(ea.Z.Item,{label:"timeout",name:"timeout",tooltip:"int (optional) - Timeout in seconds for LLM requests (Defaults to 600 seconds)",children:(0,r.jsx)(eo.Z,{min:0,step:1})}),(0,r.jsx)(ea.Z.Item,{label:"stream_timeout",name:"stream_timeout",tooltip:"int (optional) - Timeout for stream requests (seconds)",children:(0,r.jsx)(eo.Z,{min:0,step:1})}),(0,r.jsx)(ea.Z.Item,{label:"input_cost_per_token",name:"input_cost_per_token",tooltip:"float (optional) - Input cost per token",children:(0,r.jsx)(eo.Z,{min:0,step:1e-4})}),(0,r.jsx)(ea.Z.Item,{label:"output_cost_per_token",name:"output_cost_per_token",tooltip:"float (optional) - Output cost per token",children:(0,r.jsx)(eo.Z,{min:0,step:1e-4})}),(0,r.jsx)(ea.Z.Item,{label:"model_id",name:"model_id",hidden:!0})]}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ei.ZP,{htmlType:"submit",children:"Save"})})]})})},{visible:T,onCancel:()=>{O(!1),R(null)},model:F,onSubmit:e7})]}),(0,r.jsxs)(eU.Z,{className:"h-full",children:[(0,r.jsx)(e1,{level:2,children:"Add new model"}),(0,r.jsx)(ep.Z,{children:(0,r.jsxs)(ea.Z,{form:g,onFinish:()=>{g.validateFields().then(e=>{e5(e,o,g)}).catch(e=>{console.error("Validation failed:",e)})},labelCol:{span:10},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(ea.Z.Item,{rules:[{required:!0,message:"Required"}],label:"Provider:",name:"custom_llm_provider",tooltip:"E.g. OpenAI, Azure OpenAI, Anthropic, Bedrock, etc.",labelCol:{span:10},labelAlign:"left",children:(0,r.jsx)(eb.Z,{value:E.toString(),children:A.map((e,l)=>(0,r.jsx)(ek.Z,{value:e,onClick:()=>{lt(e),I(e)},children:e},l))})}),(0,r.jsx)(ea.Z.Item,{rules:[{required:!0,message:"Required"}],label:"Public Model Name",name:"model_name",tooltip:"Model name your users will pass in. Also used for load-balancing, LiteLLM will load balance between all models with this public name.",className:"mb-0",children:(0,r.jsx)(H.Z,{placeholder:"Vertex AI (Anthropic, Gemini, etc.)"===(s=E.toString())?"gemini-pro":"Anthropic"==s?"claude-3-opus":"Amazon Bedrock"==s?"claude-3-opus":"Gemini (Google AI Studio)"==s?"gemini-pro":"gpt-3.5-turbo"})}),(0,r.jsxs)(eV.Z,{children:[(0,r.jsx)(eG.Z,{span:10}),(0,r.jsx)(eG.Z,{span:10,children:(0,r.jsx)(ee.Z,{className:"mb-3 mt-1",children:"Model name your users will pass in."})})]}),(0,r.jsx)(ea.Z.Item,{rules:[{required:!0,message:"Required"}],label:"LiteLLM Model Name(s)",name:"model",tooltip:"Actual model name used for making litellm.completion() call.",className:"mb-0",children:"Azure"===E?(0,r.jsx)(H.Z,{placeholder:"Enter model name"}):w.length>0?(0,r.jsx)(eK.Z,{value:w,children:w.map((e,l)=>(0,r.jsx)(eB.Z,{value:e,children:e},l))}):(0,r.jsx)(H.Z,{placeholder:"gpt-3.5-turbo-0125"})}),(0,r.jsxs)(eV.Z,{children:[(0,r.jsx)(eG.Z,{span:10}),(0,r.jsx)(eG.Z,{span:10,children:(0,r.jsxs)(ee.Z,{className:"mb-3 mt-1",children:["Actual model name used for making ",(0,r.jsx)(e2,{href:"https://docs.litellm.ai/docs/providers",target:"_blank",children:"litellm.completion() call"}),". We'll ",(0,r.jsx)(e2,{href:"https://docs.litellm.ai/docs/proxy/reliability#step-1---set-deployments-on-config",target:"_blank",children:"loadbalance"})," models with the same 'public name'"]})})]}),"Amazon Bedrock"!=E&&"Vertex AI (Anthropic, Gemini, etc.)"!=E&&(0,r.jsx)(ea.Z.Item,{rules:[{required:!0,message:"Required"}],label:"API Key",name:"api_key",children:(0,r.jsx)(H.Z,{placeholder:"sk-",type:"password"})}),"OpenAI"==E&&(0,r.jsx)(ea.Z.Item,{label:"Organization ID",name:"organization_id",children:(0,r.jsx)(H.Z,{placeholder:"[OPTIONAL] my-unique-org"})}),"Vertex AI (Anthropic, Gemini, etc.)"==E&&(0,r.jsx)(ea.Z.Item,{rules:[{required:!0,message:"Required"}],label:"Vertex Project",name:"vertex_project",children:(0,r.jsx)(H.Z,{placeholder:"adroit-cadet-1234.."})}),"Vertex AI (Anthropic, Gemini, etc.)"==E&&(0,r.jsx)(ea.Z.Item,{rules:[{required:!0,message:"Required"}],label:"Vertex Location",name:"vertex_location",children:(0,r.jsx)(H.Z,{placeholder:"us-east-1"})}),"Vertex AI (Anthropic, Gemini, etc.)"==E&&(0,r.jsx)(ea.Z.Item,{rules:[{required:!0,message:"Required"}],label:"Vertex Credentials",name:"vertex_credentials",className:"mb-0",children:(0,r.jsx)(e0.Z,{name:"file",accept:".json",beforeUpload:e=>{if("application/json"===e.type){let l=new FileReader;l.onload=e=>{if(e.target){let l=e.target.result;g.setFieldsValue({vertex_credentials:l})}},l.readAsText(e)}return!1},onChange(e){"uploading"!==e.file.status&&console.log(e.file,e.fileList),"done"===e.file.status?u.ZP.success("".concat(e.file.name," file uploaded successfully")):"error"===e.file.status&&u.ZP.error("".concat(e.file.name," file upload failed."))},children:(0,r.jsx)(ei.ZP,{icon:(0,r.jsx)(eQ.Z,{}),children:"Click to Upload"})})}),"Vertex AI (Anthropic, Gemini, etc.)"==E&&(0,r.jsxs)(eV.Z,{children:[(0,r.jsx)(eG.Z,{span:10}),(0,r.jsx)(eG.Z,{span:10,children:(0,r.jsx)(ee.Z,{className:"mb-3 mt-1",children:"Give litellm a gcp service account(.json file), so it can make the relevant calls"})})]}),("Azure"==E||"OpenAI-Compatible Endpoints (Groq, Together AI, Mistral AI, etc.)"==E)&&(0,r.jsx)(ea.Z.Item,{rules:[{required:!0,message:"Required"}],label:"API Base",name:"api_base",children:(0,r.jsx)(H.Z,{placeholder:"https://..."})}),"Azure"==E&&(0,r.jsx)(ea.Z.Item,{rules:[{required:!0,message:"Required"}],label:"API Version",name:"api_version",children:(0,r.jsx)(H.Z,{placeholder:"2023-07-01-preview"})}),"Azure"==E&&(0,r.jsxs)(ea.Z.Item,{label:"Base Model",name:"base_model",children:[(0,r.jsx)(H.Z,{placeholder:"azure/gpt-3.5-turbo"}),(0,r.jsxs)(ee.Z,{children:["The actual model your azure deployment uses. Used for accurate cost tracking. Select name from ",(0,r.jsx)(e2,{href:"https://github.com/BerriAI/litellm/blob/main/model_prices_and_context_window.json",target:"_blank",children:"here"})]})]}),"Amazon Bedrock"==E&&(0,r.jsx)(ea.Z.Item,{rules:[{required:!0,message:"Required"}],label:"AWS Access Key ID",name:"aws_access_key_id",tooltip:"You can provide the raw key or the environment variable (e.g. `os.environ/MY_SECRET_KEY`).",children:(0,r.jsx)(H.Z,{placeholder:""})}),"Amazon Bedrock"==E&&(0,r.jsx)(ea.Z.Item,{rules:[{required:!0,message:"Required"}],label:"AWS Secret Access Key",name:"aws_secret_access_key",tooltip:"You can provide the raw key or the environment variable (e.g. `os.environ/MY_SECRET_KEY`).",children:(0,r.jsx)(H.Z,{placeholder:""})}),"Amazon Bedrock"==E&&(0,r.jsx)(ea.Z.Item,{rules:[{required:!0,message:"Required"}],label:"AWS Region Name",name:"aws_region_name",tooltip:"You can provide the raw key or the environment variable (e.g. `os.environ/MY_SECRET_KEY`).",children:(0,r.jsx)(H.Z,{placeholder:"us-east-1"})}),(0,r.jsx)(ea.Z.Item,{label:"LiteLLM Params",name:"litellm_extra_params",tooltip:"Optional litellm params used for making a litellm.completion() call.",className:"mb-0",children:(0,r.jsx)(eW.Z,{rows:4,placeholder:'{ "rpm": 100, "timeout": 0, "stream_timeout": 0 }'})}),(0,r.jsxs)(eV.Z,{children:[(0,r.jsx)(eG.Z,{span:10}),(0,r.jsx)(eG.Z,{span:10,children:(0,r.jsxs)(ee.Z,{className:"mb-3 mt-1",children:["Pass JSON of litellm supported params ",(0,r.jsx)(e2,{href:"https://docs.litellm.ai/docs/completion/input",target:"_blank",children:"litellm.completion() call"})]})})]})]}),(0,r.jsx)("div",{style:{textAlign:"center",marginTop:"10px"},children:(0,r.jsx)(ei.ZP,{htmlType:"submit",children:"Add Model"})}),(0,r.jsx)(eY.Z,{title:"Get help on our github",children:(0,r.jsx)(eT.default.Link,{href:"https://github.com/BerriAI/litellm/issues",children:"Need Help?"})})]})})]}),(0,r.jsx)(eU.Z,{children:(0,r.jsxs)(ep.Z,{children:[(0,r.jsx)(ee.Z,{children:"`/health` will run a very small request through your models configured on litellm"}),(0,r.jsx)(J.Z,{onClick:ls,children:"Run `/health`"}),C&&(0,r.jsx)("pre",{children:JSON.stringify(C,null,2)})]})}),(0,r.jsxs)(eU.Z,{children:[(0,r.jsxs)(W.Z,{numItems:2,className:"mt-2",children:[(0,r.jsxs)(eG.Z,{children:[(0,r.jsx)(ee.Z,{children:"Select Time Range"}),(0,r.jsx)(eF.Z,{enableSelect:!0,value:eE,onValueChange:e=>{eI(e),la(U,e.from,e.to)}})]}),(0,r.jsxs)(eG.Z,{children:[(0,r.jsx)(ee.Z,{children:"Select Model Group"}),(0,r.jsx)(eb.Z,{className:"mb-4 mt-2",defaultValue:U||M[0],value:U||M[0],children:M.map((e,l)=>(0,r.jsx)(ek.Z,{value:e,onClick:()=>la(e,eE.from,eE.to),children:e},l))})]})]}),(0,r.jsxs)(W.Z,{numItems:2,children:[(0,r.jsx)(eG.Z,{children:(0,r.jsxs)(ep.Z,{className:"mr-2 max-h-[400px] min-h-[400px]",children:[(0,r.jsx)(el.Z,{children:"Avg Latency per Token"}),(0,r.jsx)("p",{className:"text-gray-500 italic",children:" (seconds/token)"}),(0,r.jsx)(ee.Z,{className:"text-gray-500 italic mt-1 mb-1",children:"average Latency for successfull requests divided by the total tokens"}),Y&&es&&(0,r.jsx)(ez.Z,{title:"Model Latency",className:"h-72",data:Y,showLegend:!1,index:"date",categories:es,connectNulls:!0,customTooltip:e=>{var l,t;let{payload:s,active:a}=e;if(!a||!s)return null;let n=null===(t=s[0])||void 0===t?void 0:null===(l=t.payload)||void 0===l?void 0:l.date,o=s.sort((e,l)=>l.value-e.value);if(o.length>5){let e=o.length-5;(o=o.slice(0,5)).push({dataKey:"".concat(e," other deployments"),value:s.slice(5).reduce((e,l)=>e+l.value,0),color:"gray"})}return(0,r.jsxs)("div",{className:"w-150 rounded-tremor-default border border-tremor-border bg-tremor-background p-2 text-tremor-default shadow-tremor-dropdown",children:[n&&(0,r.jsxs)("p",{className:"text-tremor-content-emphasis mb-2",children:["Date: ",n]}),o.map((e,l)=>{let t=parseFloat(e.value.toFixed(5)),s=0===t&&e.value>0?"<0.00001":t.toFixed(5);return(0,r.jsxs)("div",{className:"flex justify-between",children:[(0,r.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,r.jsx)("div",{className:"w-2 h-2 mt-1 rounded-full bg-".concat(e.color,"-500")}),(0,r.jsx)("p",{className:"text-tremor-content",children:e.dataKey})]}),(0,r.jsx)("p",{className:"font-medium text-tremor-content-emphasis text-righ ml-2",children:s})]},l)})]})}})]})}),(0,r.jsx)(eG.Z,{children:(0,r.jsx)(ep.Z,{className:"ml-2 max-h-[400px] min-h-[400px] overflow-y-auto",children:(0,r.jsxs)(eg.Z,{children:[(0,r.jsx)(eZ.Z,{children:(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(e_.Z,{children:"Deployment"}),(0,r.jsx)(e_.Z,{children:"Success Responses"}),(0,r.jsxs)(e_.Z,{children:["Slow Responses ",(0,r.jsx)("p",{children:"Success Responses taking 600+s"})]})]})}),(0,r.jsx)(ey.Z,{children:eN.map((e,l)=>(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(ef.Z,{children:e.api_base}),(0,r.jsx)(ef.Z,{children:e.total_count}),(0,r.jsx)(ef.Z,{children:e.slow_count})]},l))})]})})})]}),(0,r.jsxs)(ep.Z,{className:"mt-4",children:[(0,r.jsx)(el.Z,{children:"Exceptions per Model"}),(0,r.jsx)(eq.Z,{className:"h-72",data:ec,index:"model",categories:em,stack:!0,colors:["indigo-300","rose-200","#ffcc33"],yAxisWidth:30})]})]}),(0,r.jsxs)(eU.Z,{children:[(0,r.jsxs)("div",{className:"flex items-center",children:[(0,r.jsx)(ee.Z,{children:"Filter by Public Model Name"}),(0,r.jsx)(eb.Z,{className:"mb-4 mt-2 ml-2 w-50",defaultValue:U||M[0],value:U||M[0],onValueChange:e=>K(e),children:M.map((e,l)=>(0,r.jsx)(ek.Z,{value:e,onClick:()=>K(e),children:e},l))})]}),(0,r.jsxs)(el.Z,{children:["Retry Policy for ",U]}),(0,r.jsx)(ee.Z,{className:"mb-6",children:"How many retries should be attempted based on the Exception"}),e8&&(0,r.jsx)("table",{children:(0,r.jsx)("tbody",{children:Object.entries(e8).map((e,l)=>{var t;let[s,a]=e,n=null==eC?void 0:null===(t=eC[U])||void 0===t?void 0:t[a];return null==n&&(n=eO),(0,r.jsxs)("tr",{className:"flex justify-between items-center mt-2",children:[(0,r.jsx)("td",{children:(0,r.jsx)(ee.Z,{children:s})}),(0,r.jsx)("td",{children:(0,r.jsx)(eo.Z,{className:"ml-5",value:n,min:0,step:1,onChange:e=>{eP(l=>{var t;let s=null!==(t=null==l?void 0:l[U])&&void 0!==t?t:{};return{...null!=l?l:{},[U]:{...s,[a]:e}}})}})})]},l)})})}),(0,r.jsx)(J.Z,{className:"mt-6 mr-8",onClick:le,children:"Save"})]})]})]})})};let{Option:e6}=es.default;var e7=e=>{let{userID:l,accessToken:t,teams:s}=e,[a]=ea.Z.useForm(),[o,i]=(0,n.useState)(!1),[c,d]=(0,n.useState)(null),[m,h]=(0,n.useState)([]);(0,n.useEffect)(()=>{(async()=>{try{let e=await N(t,l,"any"),s=[];for(let l=0;l{i(!1),a.resetFields()},p=()=>{i(!1),d(null),a.resetFields()},j=async e=>{try{u.ZP.info("Making API Call"),i(!0),console.log("formValues in create user:",e);let s=await g(t,null,e);console.log("user create Response:",s),d(s.key),u.ZP.success("API user Created"),a.resetFields(),localStorage.removeItem("userData"+l)}catch(e){console.error("Error creating the user:",e)}};return(0,r.jsxs)("div",{children:[(0,r.jsx)(J.Z,{className:"mx-auto",onClick:()=>i(!0),children:"+ Invite User"}),(0,r.jsxs)(er.Z,{title:"Invite User",visible:o,width:800,footer:null,onOk:x,onCancel:p,children:[(0,r.jsx)(ee.Z,{className:"mb-1",children:"Invite a user to login to the Admin UI and create Keys"}),(0,r.jsx)(ee.Z,{className:"mb-6",children:(0,r.jsx)("b",{children:"Note: SSO Setup Required for this"})}),(0,r.jsxs)(ea.Z,{form:a,onFinish:j,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsx)(ea.Z.Item,{label:"User Email",name:"user_email",children:(0,r.jsx)(H.Z,{placeholder:""})}),(0,r.jsx)(ea.Z.Item,{label:"Team ID",name:"team_id",children:(0,r.jsx)(es.default,{placeholder:"Select Team ID",style:{width:"100%"},children:s?s.map(e=>(0,r.jsx)(e6,{value:e.team_id,children:e.team_alias},e.team_id)):(0,r.jsx)(e6,{value:null,children:"Default Team"},"default")})}),(0,r.jsx)(ea.Z.Item,{label:"Metadata",name:"metadata",children:(0,r.jsx)(en.Z.TextArea,{rows:4,placeholder:"Enter metadata as JSON"})}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ei.ZP,{htmlType:"submit",children:"Create User"})})]})]}),c&&(0,r.jsxs)(er.Z,{title:"User Created Successfully",visible:o,onOk:x,onCancel:p,footer:null,children:[(0,r.jsx)("p",{children:"User has been created to access your proxy. Please Ask them to Log In."}),(0,r.jsx)("br",{}),(0,r.jsx)("p",{children:(0,r.jsx)("b",{children:"Note: This Feature is only supported through SSO on the Admin UI"})})]})]})},e9=e=>{let{accessToken:l,token:t,keys:s,userRole:a,userID:o,teams:i,setKeys:c}=e,[d,m]=(0,n.useState)(null),[u,h]=(0,n.useState)(null),[x,p]=(0,n.useState)(0),[j,g]=n.useState(null),[y,f]=(0,n.useState)(null);return((0,n.useEffect)(()=>{if(!l||!t||!a||!o)return;let e=async()=>{try{let e=await Z(l,null,a,!0,x,25);console.log("user data response:",e),m(e)}catch(e){console.error("There was an error fetching the model data",e)}};l&&t&&a&&o&&e()},[l,t,a,o,x]),d&&l&&t&&a&&o)?(0,r.jsx)("div",{style:{width:"100%"},children:(0,r.jsxs)(W.Z,{className:"gap-2 p-2 h-[80vh] w-full mt-8",children:[(0,r.jsx)(e7,{userID:o,accessToken:l,teams:i}),(0,r.jsxs)(ep.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[80vh] mb-4",children:[(0,r.jsx)("div",{className:"mb-4 mt-1",children:(0,r.jsx)(ee.Z,{children:"These are Users on LiteLLM that created API Keys. Automatically tracked by LiteLLM"})}),(0,r.jsx)(eM.Z,{children:(0,r.jsxs)(eD.Z,{children:[(0,r.jsx)(eU.Z,{children:(0,r.jsxs)(eg.Z,{className:"mt-5",children:[(0,r.jsx)(eZ.Z,{children:(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(e_.Z,{children:"User ID"}),(0,r.jsx)(e_.Z,{children:"User Email"}),(0,r.jsx)(e_.Z,{children:"User Models"}),(0,r.jsx)(e_.Z,{children:"User Spend ($ USD)"}),(0,r.jsx)(e_.Z,{children:"User Max Budget ($ USD)"}),(0,r.jsx)(e_.Z,{children:"User API Key Aliases"})]})}),(0,r.jsx)(ey.Z,{children:d.map(e=>{var l;return(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(ef.Z,{children:e.user_id}),(0,r.jsx)(ef.Z,{children:e.user_email}),(0,r.jsx)(ef.Z,{children:e.models&&e.models.length>0?e.models:"All Models"}),(0,r.jsx)(ef.Z,{children:e.spend?null===(l=e.spend)||void 0===l?void 0:l.toFixed(2):0}),(0,r.jsx)(ef.Z,{children:e.max_budget?e.max_budget:"Unlimited"}),(0,r.jsx)(ef.Z,{children:(0,r.jsx)(W.Z,{numItems:2,children:e&&e.key_aliases&&e.key_aliases.filter(e=>null!==e).length>0?(0,r.jsx)(ex.Z,{size:"xs",color:"indigo",children:e.key_aliases.filter(e=>null!==e).join(", ")}):(0,r.jsx)(ex.Z,{size:"xs",color:"gray",children:"No Keys"})})})]},e.user_id)})})]})}),(0,r.jsx)(eU.Z,{children:(0,r.jsxs)("div",{className:"flex items-center",children:[(0,r.jsx)("div",{className:"flex-1"}),(0,r.jsx)("div",{className:"flex-1 flex justify-between items-center"})]})})]})})]}),function(){if(!d)return null;let e=Math.ceil(d.length/25);return(0,r.jsxs)("div",{className:"flex justify-between items-center",children:[(0,r.jsxs)("div",{children:["Showing Page ",x+1," of ",e]}),(0,r.jsxs)("div",{className:"flex",children:[(0,r.jsx)("button",{className:"bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-l focus:outline-none",disabled:0===x,onClick:()=>p(x-1),children:"โ† Prev"}),(0,r.jsx)("button",{className:"bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-r focus:outline-none",onClick:()=>{p(x+1)},children:"Next โ†’"})]})]})}()]})}):(0,r.jsx)("div",{children:"Loading..."})},le=e=>{let{teams:l,searchParams:t,accessToken:s,setTeams:a,userID:o,userRole:i}=e,[c]=ea.Z.useForm(),[d]=ea.Z.useForm(),{Title:m,Paragraph:h}=eT.default,[x,p]=(0,n.useState)(""),[j,g]=(0,n.useState)(!1),[y,Z]=(0,n.useState)(l?l[0]:null),[w,b]=(0,n.useState)(!1),[k,v]=(0,n.useState)(!1),[S,A]=(0,n.useState)([]),[E,I]=(0,n.useState)(!1),[C,P]=(0,n.useState)(null),[T,O]=(0,n.useState)({}),F=e=>{Z(e),g(!0)},R=async e=>{let t=e.team_id;if(console.log("handleEditSubmit:",e),null==s)return;let r=await U(s,e);l&&a(l.map(e=>e.team_id===t?r.data:e)),u.ZP.success("Team updated successfully"),g(!1),Z(null)},L=async e=>{P(e),I(!0)},D=async()=>{if(null!=C&&null!=l&&null!=s){try{await f(s,C);let e=l.filter(e=>e.team_id!==C);a(e)}catch(e){console.error("Error deleting the team:",e)}I(!1),P(null)}};(0,n.useEffect)(()=>{let e=async()=>{try{if(null===o||null===i||null===s||null===l)return;console.log("fetching team info:");let e={};for(let t=0;t<(null==l?void 0:l.length);t++){let a=l[t].team_id,r=await _(s,a);console.log("teamInfo response:",r),null!==r&&(e={...e,[a]:r})}O(e)}catch(e){console.error("Error fetching team info:",e)}};(async()=>{try{if(null===o||null===i)return;if(null!==s){let e=(await N(s,o,i)).data.map(e=>e.id);console.log("available_model_names:",e),A(e)}}catch(e){console.error("Error fetching user models:",e)}})(),e()},[s,o,i,l]);let B=async e=>{try{if(null!=s){var t;let r=null==e?void 0:e.team_alias;if((null!==(t=null==l?void 0:l.map(e=>e.team_alias))&&void 0!==t?t:[]).includes(r))throw Error("Team alias ".concat(r," already exists, please pick another alias"));u.ZP.info("Creating Team");let n=await M(s,e);null!==l?a([...l,n]):a([n]),console.log("response for team create call: ".concat(n)),u.ZP.success("Team created"),b(!1)}}catch(e){console.error("Error creating the team:",e),u.ZP.error("Error creating the team: "+e,20)}},z=async e=>{try{if(null!=s&&null!=l){u.ZP.info("Adding Member");let t={role:"user",user_email:e.user_email,user_id:e.user_id},r=await K(s,y.team_id,t);console.log("response for team create call: ".concat(r.data));let n=l.findIndex(e=>(console.log("team.team_id=".concat(e.team_id,"; response.data.team_id=").concat(r.data.team_id)),e.team_id===r.data.team_id));if(console.log("foundIndex: ".concat(n)),-1!==n){let e=[...l];e[n]=r.data,a(e),Z(r.data)}v(!1)}}catch(e){console.error("Error creating the team:",e)}};return console.log("received teams ".concat(JSON.stringify(l))),(0,r.jsx)("div",{className:"w-full mx-4",children:(0,r.jsxs)(W.Z,{numItems:1,className:"gap-2 p-8 h-[75vh] w-full mt-2",children:[(0,r.jsxs)(Y.Z,{numColSpan:1,children:[(0,r.jsx)(m,{level:4,children:"All Teams"}),(0,r.jsxs)(ep.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:[(0,r.jsxs)(eg.Z,{children:[(0,r.jsx)(eZ.Z,{children:(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(e_.Z,{children:"Team Name"}),(0,r.jsx)(e_.Z,{children:"Spend (USD)"}),(0,r.jsx)(e_.Z,{children:"Budget (USD)"}),(0,r.jsx)(e_.Z,{children:"Models"}),(0,r.jsx)(e_.Z,{children:"TPM / RPM Limits"}),(0,r.jsx)(e_.Z,{children:"Info"})]})}),(0,r.jsx)(ey.Z,{children:l&&l.length>0?l.map(e=>(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(ef.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:e.team_alias}),(0,r.jsx)(ef.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:e.spend}),(0,r.jsx)(ef.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:e.max_budget?e.max_budget:"No limit"}),(0,r.jsx)(ef.Z,{style:{maxWidth:"8-x",whiteSpace:"pre-wrap",overflow:"hidden"},children:Array.isArray(e.models)?(0,r.jsx)("div",{style:{display:"flex",flexDirection:"column"},children:0===e.models.length?(0,r.jsx)(ex.Z,{size:"xs",className:"mb-1",color:"red",children:(0,r.jsx)(ee.Z,{children:"All Proxy Models"})}):e.models.map((e,l)=>"all-proxy-models"===e?(0,r.jsx)(ex.Z,{size:"xs",className:"mb-1",color:"red",children:(0,r.jsx)(ee.Z,{children:"All Proxy Models"})},l):(0,r.jsx)(ex.Z,{size:"xs",className:"mb-1",color:"blue",children:(0,r.jsx)(ee.Z,{children:e.length>30?"".concat(e.slice(0,30),"..."):e})},l))}):null}),(0,r.jsx)(ef.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,r.jsxs)(ee.Z,{children:["TPM: ",e.tpm_limit?e.tpm_limit:"Unlimited"," ",(0,r.jsx)("br",{}),"RPM:"," ",e.rpm_limit?e.rpm_limit:"Unlimited"]})}),(0,r.jsxs)(ef.Z,{children:[(0,r.jsxs)(ee.Z,{children:[T&&e.team_id&&T[e.team_id]&&T[e.team_id].keys&&T[e.team_id].keys.length," ","Keys"]}),(0,r.jsxs)(ee.Z,{children:[T&&e.team_id&&T[e.team_id]&&T[e.team_id].team_info&&T[e.team_id].team_info.members_with_roles&&T[e.team_id].team_info.members_with_roles.length," ","Members"]})]}),(0,r.jsxs)(ef.Z,{children:[(0,r.jsx)(ej.Z,{icon:eu.Z,size:"sm",onClick:()=>F(e)}),(0,r.jsx)(ej.Z,{onClick:()=>L(e.team_id),icon:eh.Z,size:"sm"})]})]},e.team_id)):null})]}),E&&(0,r.jsx)("div",{className:"fixed z-10 inset-0 overflow-y-auto",children:(0,r.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,r.jsx)("div",{className:"fixed inset-0 transition-opacity","aria-hidden":"true",children:(0,r.jsx)("div",{className:"absolute inset-0 bg-gray-500 opacity-75"})}),(0,r.jsx)("span",{className:"hidden sm:inline-block sm:align-middle sm:h-screen","aria-hidden":"true",children:"โ€‹"}),(0,r.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,r.jsx)("div",{className:"bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4",children:(0,r.jsx)("div",{className:"sm:flex sm:items-start",children:(0,r.jsxs)("div",{className:"mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left",children:[(0,r.jsx)("h3",{className:"text-lg leading-6 font-medium text-gray-900",children:"Delete Team"}),(0,r.jsx)("div",{className:"mt-2",children:(0,r.jsx)("p",{className:"text-sm text-gray-500",children:"Are you sure you want to delete this team ?"})})]})})}),(0,r.jsxs)("div",{className:"bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse",children:[(0,r.jsx)(J.Z,{onClick:D,color:"red",className:"ml-2",children:"Delete"}),(0,r.jsx)(J.Z,{onClick:()=>{I(!1),P(null)},children:"Cancel"})]})]})]})})]})]}),(0,r.jsxs)(Y.Z,{numColSpan:1,children:[(0,r.jsx)(J.Z,{className:"mx-auto",onClick:()=>b(!0),children:"+ Create New Team"}),(0,r.jsx)(er.Z,{title:"Create Team",visible:w,width:800,footer:null,onOk:()=>{b(!1),c.resetFields()},onCancel:()=>{b(!1),c.resetFields()},children:(0,r.jsxs)(ea.Z,{form:c,onFinish:B,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(ea.Z.Item,{label:"Team Name",name:"team_alias",rules:[{required:!0,message:"Please input a team name"}],children:(0,r.jsx)(H.Z,{placeholder:""})}),(0,r.jsx)(ea.Z.Item,{label:"Models",name:"models",children:(0,r.jsxs)(es.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:[(0,r.jsx)(es.default.Option,{value:"all-proxy-models",children:"All Proxy Models"},"all-proxy-models"),S.map(e=>(0,r.jsx)(es.default.Option,{value:e,children:e},e))]})}),(0,r.jsx)(ea.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,r.jsx)(eo.Z,{step:.01,precision:2,width:200})}),(0,r.jsx)(ea.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,r.jsx)(eo.Z,{step:1,width:400})}),(0,r.jsx)(ea.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,r.jsx)(eo.Z,{step:1,width:400})})]}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ei.ZP,{htmlType:"submit",children:"Create Team"})})]})})]}),(0,r.jsxs)(Y.Z,{numColSpan:1,children:[(0,r.jsx)(m,{level:4,children:"Team Members"}),(0,r.jsx)(h,{children:"If you belong to multiple teams, this setting controls which teams members you see."}),l&&l.length>0?(0,r.jsx)(eb.Z,{defaultValue:"0",children:l.map((e,l)=>(0,r.jsx)(ek.Z,{value:String(l),onClick:()=>{Z(e)},children:e.team_alias},l))}):(0,r.jsxs)(h,{children:["No team created. ",(0,r.jsx)("b",{children:"Defaulting to personal account."})]})]}),(0,r.jsxs)(Y.Z,{numColSpan:1,children:[(0,r.jsx)(ep.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,r.jsxs)(eg.Z,{children:[(0,r.jsx)(eZ.Z,{children:(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(e_.Z,{children:"Member Name"}),(0,r.jsx)(e_.Z,{children:"Role"})]})}),(0,r.jsx)(ey.Z,{children:y?y.members_with_roles.map((e,l)=>(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(ef.Z,{children:e.user_email?e.user_email:e.user_id?e.user_id:null}),(0,r.jsx)(ef.Z,{children:e.role})]},l)):null})]})}),y&&(0,r.jsx)(e=>{let{visible:l,onCancel:t,team:s,onSubmit:a}=e,[n]=ea.Z.useForm();return(0,r.jsx)(er.Z,{title:"Edit Team",visible:l,width:800,footer:null,onOk:()=>{n.validateFields().then(e=>{a({...e,team_id:s.team_id}),n.resetFields()}).catch(e=>{console.error("Validation failed:",e)})},onCancel:t,children:(0,r.jsxs)(ea.Z,{form:n,onFinish:R,initialValues:s,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(ea.Z.Item,{label:"Team Name",name:"team_alias",rules:[{required:!0,message:"Please input a team name"}],children:(0,r.jsx)(H.Z,{})}),(0,r.jsx)(ea.Z.Item,{label:"Models",name:"models",children:(0,r.jsxs)(es.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:[(0,r.jsx)(es.default.Option,{value:"all-proxy-models",children:"All Proxy Models"},"all-proxy-models"),S&&S.map(e=>(0,r.jsx)(es.default.Option,{value:e,children:e},e))]})}),(0,r.jsx)(ea.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,r.jsx)(eo.Z,{step:.01,precision:2,width:200})}),(0,r.jsx)(ea.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,r.jsx)(eo.Z,{step:1,width:400})}),(0,r.jsx)(ea.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,r.jsx)(eo.Z,{step:1,width:400})}),(0,r.jsx)(ea.Z.Item,{label:"Requests per minute Limit (RPM)",name:"team_id",hidden:!0})]}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ei.ZP,{htmlType:"submit",children:"Edit Team"})})]})})},{visible:j,onCancel:()=>{g(!1),Z(null)},team:y,onSubmit:R})]}),(0,r.jsxs)(Y.Z,{numColSpan:1,children:[(0,r.jsx)(J.Z,{className:"mx-auto mb-5",onClick:()=>v(!0),children:"+ Add member"}),(0,r.jsx)(er.Z,{title:"Add member",visible:k,width:800,footer:null,onOk:()=>{v(!1),d.resetFields()},onCancel:()=>{v(!1),d.resetFields()},children:(0,r.jsxs)(ea.Z,{form:c,onFinish:z,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(ea.Z.Item,{label:"Email",name:"user_email",className:"mb-4",children:(0,r.jsx)(en.Z,{name:"user_email",className:"px-3 py-2 border rounded-md w-full"})}),(0,r.jsx)("div",{className:"text-center mb-4",children:"OR"}),(0,r.jsx)(ea.Z.Item,{label:"User ID",name:"user_id",className:"mb-4",children:(0,r.jsx)(en.Z,{name:"user_id",className:"px-3 py-2 border rounded-md w-full"})})]}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ei.ZP,{htmlType:"submit",children:"Add member"})})]})})]})]})})},ll=t(18190),lt=e=>{let l,{searchParams:t,accessToken:s,showSSOBanner:a}=e,[o]=ea.Z.useForm(),[i]=ea.Z.useForm(),{Title:c,Paragraph:d}=eT.default,[m,h]=(0,n.useState)(""),[x,p]=(0,n.useState)(null),[j,g]=(0,n.useState)(!1),[y,f]=(0,n.useState)(!1),[Z,_]=(0,n.useState)(!1),[w,b]=(0,n.useState)(!1),[k,v]=(0,n.useState)(!1);try{l=window.location.origin}catch(e){l=""}l+="/fallback/login";let S=()=>{v(!1)},N=["proxy_admin","proxy_admin_viewer"];(0,n.useEffect)(()=>{(async()=>{if(null!=s){let e=[],l=await R(s,"proxy_admin_viewer");l.forEach(l=>{e.push({user_role:l.user_role,user_id:l.user_id,user_email:l.user_email})}),console.log("proxy viewers: ".concat(l));let t=await R(s,"proxy_admin");t.forEach(l=>{e.push({user_role:l.user_role,user_id:l.user_id,user_email:l.user_email})}),console.log("proxy admins: ".concat(t)),console.log("combinedList: ".concat(e)),p(e)}})()},[s]);let A=()=>{_(!1),i.resetFields()},E=()=>{_(!1),i.resetFields()},I=e=>(0,r.jsxs)(ea.Z,{form:o,onFinish:e,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(ea.Z.Item,{label:"Email",name:"user_email",className:"mb-4",children:(0,r.jsx)(en.Z,{name:"user_email",className:"px-3 py-2 border rounded-md w-full"})}),(0,r.jsx)("div",{className:"text-center mb-4",children:"OR"}),(0,r.jsx)(ea.Z.Item,{label:"User ID",name:"user_id",className:"mb-4",children:(0,r.jsx)(en.Z,{name:"user_id",className:"px-3 py-2 border rounded-md w-full"})})]}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ei.ZP,{htmlType:"submit",children:"Add member"})})]}),C=(e,l,t)=>(0,r.jsxs)(ea.Z,{form:o,onFinish:e,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(ea.Z.Item,{rules:[{required:!0,message:"Required"}],label:"User Role",name:"user_role",labelCol:{span:10},labelAlign:"left",children:(0,r.jsx)(eb.Z,{value:l,children:N.map((e,l)=>(0,r.jsx)(ek.Z,{value:e,children:e},l))})}),(0,r.jsx)(ea.Z.Item,{label:"Team ID",name:"user_id",hidden:!0,initialValue:t,valuePropName:"user_id",className:"mt-8",children:(0,r.jsx)(en.Z,{value:t,disabled:!0})})]}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ei.ZP,{htmlType:"submit",children:"Update role"})})]}),P=async e=>{try{if(null!=s&&null!=x){u.ZP.info("Making API Call");let l=await B(s,e,null);console.log("response for team create call: ".concat(l));let t=x.findIndex(e=>(console.log("user.user_id=".concat(e.user_id,"; response.user_id=").concat(l.user_id)),e.user_id===l.user_id));console.log("foundIndex: ".concat(t)),-1==t&&(console.log("updates admin with new user"),x.push(l),p(x)),u.ZP.success("Refresh tab to see updated user role"),_(!1)}}catch(e){console.error("Error creating the key:",e)}},T=async e=>{try{if(null!=s&&null!=x){u.ZP.info("Making API Call");let l=await B(s,e,"proxy_admin_viewer");console.log("response for team create call: ".concat(l));let t=x.findIndex(e=>(console.log("user.user_id=".concat(e.user_id,"; response.user_id=").concat(l.user_id)),e.user_id===l.user_id));console.log("foundIndex: ".concat(t)),-1==t&&(console.log("updates admin with new user"),x.push(l),p(x)),g(!1)}}catch(e){console.error("Error creating the key:",e)}},O=async e=>{try{if(null!=s&&null!=x){u.ZP.info("Making API Call"),e.user_email,e.user_id;let l=await B(s,e,"proxy_admin");console.log("response for team create call: ".concat(l));let t=x.findIndex(e=>(console.log("user.user_id=".concat(e.user_id,"; response.user_id=").concat(l.user_id)),e.user_id===l.user_id));console.log("foundIndex: ".concat(t)),-1==t&&(console.log("updates admin with new user"),x.push(l),p(x)),f(!1)}}catch(e){console.error("Error creating the key:",e)}},F=async e=>{null!=s&&V(s,{environment_variables:{PROXY_BASE_URL:e.proxy_base_url,GOOGLE_CLIENT_ID:e.google_client_id,GOOGLE_CLIENT_SECRET:e.google_client_secret}})};return console.log("admins: ".concat(null==x?void 0:x.length)),(0,r.jsxs)("div",{className:"w-full m-2 mt-2 p-8",children:[(0,r.jsx)(c,{level:4,children:"Admin Access "}),(0,r.jsxs)(d,{children:[a&&(0,r.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/ui#restrict-ui-access",children:"Requires SSO Setup"}),(0,r.jsx)("br",{}),(0,r.jsx)("b",{children:"Proxy Admin: "})," Can create keys, teams, users, add models, etc. ",(0,r.jsx)("br",{}),(0,r.jsx)("b",{children:"Proxy Admin Viewer: "}),"Can just view spend. They cannot create keys, teams or grant users access to new models."," "]}),(0,r.jsxs)(W.Z,{numItems:1,className:"gap-2 p-2 w-full",children:[(0,r.jsx)(Y.Z,{numColSpan:1,children:(0,r.jsx)(ep.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,r.jsxs)(eg.Z,{children:[(0,r.jsx)(eZ.Z,{children:(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(e_.Z,{children:"Member Name"}),(0,r.jsx)(e_.Z,{children:"Role"})]})}),(0,r.jsx)(ey.Z,{children:x?x.map((e,l)=>(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(ef.Z,{children:e.user_email?e.user_email:e.user_id?e.user_id:null}),(0,r.jsx)(ef.Z,{children:e.user_role}),(0,r.jsxs)(ef.Z,{children:[(0,r.jsx)(ej.Z,{icon:eu.Z,size:"sm",onClick:()=>_(!0)}),(0,r.jsx)(er.Z,{title:"Update role",visible:Z,width:800,footer:null,onOk:A,onCancel:E,children:C(P,e.user_role,e.user_id)})]})]},l)):null})]})})}),(0,r.jsx)(Y.Z,{numColSpan:1,children:(0,r.jsxs)("div",{className:"flex justify-start",children:[(0,r.jsx)(J.Z,{className:"mr-4 mb-5",onClick:()=>f(!0),children:"+ Add admin"}),(0,r.jsx)(er.Z,{title:"Add admin",visible:y,width:800,footer:null,onOk:()=>{f(!1),i.resetFields()},onCancel:()=>{f(!1),i.resetFields()},children:I(O)}),(0,r.jsx)(J.Z,{className:"mb-5",onClick:()=>g(!0),children:"+ Add viewer"}),(0,r.jsx)(er.Z,{title:"Add viewer",visible:j,width:800,footer:null,onOk:()=>{g(!1),i.resetFields()},onCancel:()=>{g(!1),i.resetFields()},children:I(T)})]})})]}),(0,r.jsxs)(W.Z,{children:[(0,r.jsx)(c,{level:4,children:"Add SSO"}),(0,r.jsxs)("div",{className:"flex justify-start mb-4",children:[(0,r.jsx)(J.Z,{onClick:()=>b(!0),children:"Add SSO"}),(0,r.jsx)(er.Z,{title:"Add SSO",visible:w,width:800,footer:null,onOk:()=>{b(!1),o.resetFields()},onCancel:()=>{b(!1),o.resetFields()},children:(0,r.jsxs)(ea.Z,{form:o,onFinish:e=>{O(e),F(e),b(!1),v(!0)},labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(ea.Z.Item,{label:"Admin Email",name:"user_email",rules:[{required:!0,message:"Please enter the email of the proxy admin"}],children:(0,r.jsx)(en.Z,{})}),(0,r.jsx)(ea.Z.Item,{label:"PROXY BASE URL",name:"proxy_base_url",rules:[{required:!0,message:"Please enter the proxy base url"}],children:(0,r.jsx)(en.Z,{})}),(0,r.jsx)(ea.Z.Item,{label:"GOOGLE CLIENT ID",name:"google_client_id",rules:[{required:!0,message:"Please enter the google client id"}],children:(0,r.jsx)(en.Z.Password,{})}),(0,r.jsx)(ea.Z.Item,{label:"GOOGLE CLIENT SECRET",name:"google_client_secret",rules:[{required:!0,message:"Please enter the google client secret"}],children:(0,r.jsx)(en.Z.Password,{})})]}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ei.ZP,{htmlType:"submit",children:"Save"})})]})}),(0,r.jsxs)(er.Z,{title:"SSO Setup Instructions",visible:k,width:800,footer:null,onOk:S,onCancel:()=>{v(!1)},children:[(0,r.jsx)("p",{children:"Follow these steps to complete the SSO setup:"}),(0,r.jsx)(ee.Z,{className:"mt-2",children:"1. DO NOT Exit this TAB"}),(0,r.jsx)(ee.Z,{className:"mt-2",children:"2. Open a new tab, visit your proxy base url"}),(0,r.jsx)(ee.Z,{className:"mt-2",children:"3. Confirm your SSO is configured correctly and you can login on the new Tab"}),(0,r.jsx)(ee.Z,{className:"mt-2",children:"4. If Step 3 is successful, you can close this tab"}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ei.ZP,{onClick:S,children:"Done"})})]})]}),(0,r.jsxs)(ll.Z,{title:"Login without SSO",color:"teal",children:["If you need to login without sso, you can access ",(0,r.jsxs)("a",{href:l,target:"_blank",children:[(0,r.jsx)("b",{children:l})," "]})]})]})]})},ls=t(42556);let la=[{name:"slack",variables:{LANGFUSE_HOST:null,LANGFUSE_PUBLIC_KEY:null,LANGFUSE_SECRET_KEY:null,OPENMETER_API_KEY:null,SLACK_WEBHOOK_URL:null}},{name:"langfuse",variables:{LANGFUSE_HOST:null,LANGFUSE_PUBLIC_KEY:null,LANGFUSE_SECRET_KEY:null,OPENMETER_API_KEY:null,SLACK_WEBHOOK_URL:null}},{name:"openmeter",variables:{LANGFUSE_HOST:null,LANGFUSE_PUBLIC_KEY:null,LANGFUSE_SECRET_KEY:null,OPENMETER_API_KEY:null,SLACK_WEBHOOK_URL:null}}];var lr=e=>{let{accessToken:l,userRole:t,userID:s}=e,[a,o]=(0,n.useState)(la),[i,c]=(0,n.useState)([]),[d,m]=(0,n.useState)(!1),[h]=ea.Z.useForm(),[x,p]=(0,n.useState)(null),[j,g]=(0,n.useState)([]),[y,f]=(0,n.useState)(""),[Z,_]=(0,n.useState)({}),[w,b]=(0,n.useState)([]),k=e=>{w.includes(e)?b(w.filter(l=>l!==e)):b([...w,e])},v={llm_exceptions:"LLM Exceptions",llm_too_slow:"LLM Responses Too Slow",llm_requests_hanging:"LLM Requests Hanging",budget_alerts:"Budget Alerts (API Keys, Users)",db_exceptions:"Database Exceptions (Read/Write)",daily_reports:"Weekly/Monthly Spend Reports"};(0,n.useEffect)(()=>{l&&t&&s&&q(l,s,t).then(e=>{console.log("callbacks",e);let l=la;o(l=l.map(l=>{let t=e.callbacks.find(e=>e.name===l.name);return t?{...l,variables:{...l.variables,...t.variables}}:l}));let t=e.alerts;if(console.log("alerts_data",t),t&&t.length>0){let e=t[0];console.log("_alert_info",e);let l=e.variables.SLACK_WEBHOOK_URL;console.log("catch_all_webhook",l),b(e.active_alerts),f(l),_(e.alerts_to_webhook)}c(t)})},[l,t,s]);let S=e=>w&&w.includes(e),N=e=>{if(!l)return;let t=Object.fromEntries(Object.entries(e.variables).map(e=>{var l;let[t,s]=e;return[t,(null===(l=document.querySelector('input[name="'.concat(t,'"]')))||void 0===l?void 0:l.value)||s]}));console.log("updatedVariables",t),console.log("updateAlertTypes",j);let s={environment_variables:t,litellm_settings:{success_callback:[e.name]}};try{V(l,s)}catch(e){u.ZP.error("Failed to update callback: "+e,20)}u.ZP.success("Callback updated successfully")},A=()=>{l&&h.validateFields().then(e=>{if(console.log("Form values:",e),"langfuse"===e.callback){V(l,{environment_variables:{LANGFUSE_PUBLIC_KEY:e.langfusePublicKey,LANGFUSE_SECRET_KEY:e.langfusePrivateKey},litellm_settings:{success_callback:[e.callback]}});let t={name:e.callback,variables:{SLACK_WEBHOOK_URL:null,LANGFUSE_HOST:null,LANGFUSE_PUBLIC_KEY:e.langfusePublicKey,LANGFUSE_SECRET_KEY:e.langfusePrivateKey,OPENMETER_API_KEY:null}};o(a?[...a,t]:[t])}else if("slack"===e.callback){console.log("values.slackWebhookUrl: ".concat(e.slackWebhookUrl)),V(l,{general_settings:{alerting:["slack"],alerting_threshold:300},environment_variables:{SLACK_WEBHOOK_URL:e.slackWebhookUrl}}),console.log("values.callback: ".concat(e.callback));let t={name:e.callback,variables:{SLACK_WEBHOOK_URL:e.slackWebhookUrl,LANGFUSE_HOST:null,LANGFUSE_PUBLIC_KEY:null,LANGFUSE_SECRET_KEY:null,OPENMETER_API_KEY:null}};o(a?[...a,t]:[t])}else if("openmeter"==e.callback){console.log("values.openMeterApiKey: ".concat(e.openMeterApiKey)),V(l,{environment_variables:{OPENMETER_API_KEY:e.openMeterApiKey},litellm_settings:{success_callback:[e.callback]}});let t={name:e.callback,variables:{SLACK_WEBHOOK_URL:null,LANGFUSE_HOST:null,LANGFUSE_PUBLIC_KEY:null,LANGFUSE_SECRET_KEY:null,OPENMETER_API_KEY:e.openMeterAPIKey}};o(a?[...a,t]:[t])}m(!1),h.resetFields(),p(null)})};return l?(console.log("callbacks: ".concat(a)),(0,r.jsxs)("div",{className:"w-full mx-4",children:[(0,r.jsxs)(W.Z,{numItems:1,className:"gap-2 p-8 w-full mt-2",children:[(0,r.jsx)(ll.Z,{title:"[UI] Presidio PII + Guardrails Coming Soon. https://docs.litellm.ai/docs/proxy/pii_masking",color:"sky"}),(0,r.jsxs)(eM.Z,{children:[(0,r.jsxs)(eL.Z,{variant:"line",defaultValue:"1",children:[(0,r.jsx)(eR.Z,{value:"1",children:"Logging Callbacks"}),(0,r.jsx)(eR.Z,{value:"2",children:"Alerting"})]}),(0,r.jsxs)(eD.Z,{children:[(0,r.jsx)(eU.Z,{children:(0,r.jsx)(ep.Z,{children:(0,r.jsxs)(eg.Z,{children:[(0,r.jsx)(eZ.Z,{children:(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(e_.Z,{children:"Callback"}),(0,r.jsx)(e_.Z,{children:"Callback Env Vars"})]})}),(0,r.jsx)(ey.Z,{children:a.filter(e=>"slack"!==e.name).map((e,t)=>{var s;return(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(ef.Z,{children:(0,r.jsx)(ex.Z,{color:"emerald",children:e.name})}),(0,r.jsxs)(ef.Z,{children:[(0,r.jsx)("ul",{children:Object.entries(null!==(s=e.variables)&&void 0!==s?s:{}).filter(l=>{let[t,s]=l;return t.toLowerCase().includes(e.name)}).map(e=>{let[l,t]=e;return(0,r.jsxs)("li",{children:[(0,r.jsx)(ee.Z,{className:"mt-2",children:l}),"LANGFUSE_HOST"===l?(0,r.jsx)("p",{children:"default value=https://cloud.langfuse.com"}):(0,r.jsx)("div",{}),(0,r.jsx)(H.Z,{name:l,defaultValue:t,type:"password"})]},l)})}),(0,r.jsx)(J.Z,{className:"mt-2",onClick:()=>N(e),children:"Save Changes"}),(0,r.jsx)(J.Z,{onClick:()=>z(l,e.name),className:"mx-2",children:"Test Callback"})]})]},t)})})]})})}),(0,r.jsx)(eU.Z,{children:(0,r.jsxs)(ep.Z,{children:[(0,r.jsxs)(ee.Z,{className:"my-2",children:["Alerts are only supported for Slack Webhook URLs. Get your webhook urls from ",(0,r.jsx)("a",{href:"https://api.slack.com/messaging/webhooks",target:"_blank",style:{color:"blue"},children:"here"})]}),(0,r.jsxs)(eg.Z,{children:[(0,r.jsx)(eZ.Z,{children:(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(e_.Z,{}),(0,r.jsx)(e_.Z,{}),(0,r.jsx)(e_.Z,{children:"Slack Webhook URL"})]})}),(0,r.jsx)(ey.Z,{children:Object.entries(v).map((e,l)=>{let[t,s]=e;return(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(ef.Z,{children:(0,r.jsx)(ls.Z,{id:"switch",name:"switch",checked:S(t),onChange:()=>k(t)})}),(0,r.jsx)(ef.Z,{children:(0,r.jsx)(ee.Z,{children:s})}),(0,r.jsx)(ef.Z,{children:(0,r.jsx)(H.Z,{name:t,type:"password",defaultValue:Z&&Z[t]?Z[t]:y})})]},l)})})]}),(0,r.jsx)(J.Z,{size:"xs",className:"mt-2",onClick:()=>{if(!l)return;let e={};Object.entries(v).forEach(l=>{let[t,s]=l,a=document.querySelector('input[name="'.concat(t,'"]'));console.log("key",t),console.log("webhookInput",a);let r=(null==a?void 0:a.value)||"";console.log("newWebhookValue",r),e[t]=r}),console.log("updatedAlertToWebhooks",e);let t={general_settings:{alert_to_webhook_url:e,alert_types:w}};console.log("payload",t);try{V(l,t)}catch(e){u.ZP.error("Failed to update alerts: "+e,20)}u.ZP.success("Alerts updated successfully")},children:"Save Changes"}),(0,r.jsx)(J.Z,{onClick:()=>z(l,"slack"),className:"mx-2",children:"Test Alerts"})]})})]})]})]}),(0,r.jsx)(er.Z,{title:"Add Callback",visible:d,onOk:A,width:800,onCancel:()=>{m(!1),h.resetFields(),p(null)},footer:null,children:(0,r.jsxs)(ea.Z,{form:h,layout:"vertical",onFinish:A,children:[(0,r.jsx)(ea.Z.Item,{label:"Callback",name:"callback",rules:[{required:!0,message:"Please select a callback"}],children:(0,r.jsxs)(es.default,{onChange:e=>{p(e)},children:[(0,r.jsx)(es.default.Option,{value:"langfuse",children:"langfuse"}),(0,r.jsx)(es.default.Option,{value:"openmeter",children:"openmeter"})]})}),"langfuse"===x&&(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(ea.Z.Item,{label:"LANGFUSE_PUBLIC_KEY",name:"langfusePublicKey",rules:[{required:!0,message:"Please enter the public key"}],children:(0,r.jsx)(H.Z,{type:"password"})}),(0,r.jsx)(ea.Z.Item,{label:"LANGFUSE_PRIVATE_KEY",name:"langfusePrivateKey",rules:[{required:!0,message:"Please enter the private key"}],children:(0,r.jsx)(H.Z,{type:"password"})})]}),"openmeter"==x&&(0,r.jsx)(r.Fragment,{children:(0,r.jsx)(ea.Z.Item,{label:"OPENMETER_API_KEY",name:"openMeterApiKey",rules:[{required:!0,message:"Please enter the openmeter api key"}],children:(0,r.jsx)(H.Z,{type:"password"})})}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ei.ZP,{htmlType:"submit",children:"Save"})})]})})]})):null};let{Option:ln}=es.default;var lo=e=>{let{models:l,accessToken:t,routerSettings:s,setRouterSettings:a}=e,[o]=ea.Z.useForm(),[i,c]=(0,n.useState)(!1),[d,m]=(0,n.useState)("");return(0,r.jsxs)("div",{children:[(0,r.jsx)(J.Z,{className:"mx-auto",onClick:()=>c(!0),children:"+ Add Fallbacks"}),(0,r.jsx)(er.Z,{title:"Add Fallbacks",visible:i,width:800,footer:null,onOk:()=>{c(!1),o.resetFields()},onCancel:()=>{c(!1),o.resetFields()},children:(0,r.jsxs)(ea.Z,{form:o,onFinish:e=>{console.log(e);let{model_name:l,models:r}=e,n=[...s.fallbacks||[],{[l]:r}],i={...s,fallbacks:n};console.log(i);try{V(t,{router_settings:i}),a(i)}catch(e){u.ZP.error("Failed to update router settings: "+e,20)}u.ZP.success("router settings updated successfully"),c(!1),o.resetFields()},labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(ea.Z.Item,{label:"Public Model Name",name:"model_name",rules:[{required:!0,message:"Set the model to fallback for"}],help:"required",children:(0,r.jsx)(eb.Z,{defaultValue:d,children:l&&l.map((e,l)=>(0,r.jsx)(ek.Z,{value:e,onClick:()=>m(e),children:e},l))})}),(0,r.jsx)(ea.Z.Item,{label:"Fallback Models",name:"models",rules:[{required:!0,message:"Please select a model"}],help:"required",children:(0,r.jsx)(eK.Z,{value:l,children:l&&l.filter(e=>e!=d).map(e=>(0,r.jsx)(eB.Z,{value:e,children:e},e))})})]}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ei.ZP,{htmlType:"submit",children:"Add Fallbacks"})})]})})]})},li=t(12968);async function lc(e,l){console.log("isLocal:",!1);let t=window.location.origin,s=new li.ZP.OpenAI({apiKey:l,baseURL:t,dangerouslyAllowBrowser:!0});try{let l=await s.chat.completions.create({model:e,messages:[{role:"user",content:"Hi, this is a test message"}],mock_testing_fallbacks:!0});u.ZP.success((0,r.jsxs)("span",{children:["Test model=",(0,r.jsx)("strong",{children:e}),", received model=",(0,r.jsx)("strong",{children:l.model}),". See ",(0,r.jsx)("a",{href:"#",onClick:()=>window.open("https://docs.litellm.ai/docs/proxy/reliability","_blank"),style:{textDecoration:"underline",color:"blue"},children:"curl"})]}))}catch(e){u.ZP.error("Error occurred while generating model response. Please try again. Error: ".concat(e),20)}}let ld={ttl:3600,lowest_latency_buffer:0},lm=e=>{let{selectedStrategy:l,strategyArgs:t,paramExplanation:s}=e;return(0,r.jsxs)($.Z,{children:[(0,r.jsx)(Q.Z,{className:"text-sm font-medium text-tremor-content-strong dark:text-dark-tremor-content-strong",children:"Routing Strategy Specific Args"}),(0,r.jsx)(X.Z,{children:"latency-based-routing"==l?(0,r.jsx)(ep.Z,{children:(0,r.jsxs)(eg.Z,{children:[(0,r.jsx)(eZ.Z,{children:(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(e_.Z,{children:"Setting"}),(0,r.jsx)(e_.Z,{children:"Value"})]})}),(0,r.jsx)(ey.Z,{children:Object.entries(t).map(e=>{let[l,t]=e;return(0,r.jsxs)(ew.Z,{children:[(0,r.jsxs)(ef.Z,{children:[(0,r.jsx)(ee.Z,{children:l}),(0,r.jsx)("p",{style:{fontSize:"0.65rem",color:"#808080",fontStyle:"italic"},className:"mt-1",children:s[l]})]}),(0,r.jsx)(ef.Z,{children:(0,r.jsx)(H.Z,{name:l,defaultValue:"object"==typeof t?JSON.stringify(t,null,2):t.toString()})})]},l)})})]})}):(0,r.jsx)(ee.Z,{children:"No specific settings"})})]})};var lu=e=>{let{accessToken:l,userRole:t,userID:s,modelData:a}=e,[o,i]=(0,n.useState)({}),[c,d]=(0,n.useState)(!1),[m]=ea.Z.useForm(),[h,x]=(0,n.useState)(null),[p,j]=(0,n.useState)(null),[g,y]=(0,n.useState)(null),f={routing_strategy_args:"(dict) Arguments to pass to the routing strategy",routing_strategy:"(string) Routing strategy to use",allowed_fails:"(int) Number of times a deployment can fail before being added to cooldown",cooldown_time:"(int) time in seconds to cooldown a deployment after failure",num_retries:"(int) Number of retries for failed requests. Defaults to 0.",timeout:"(float) Timeout for requests. Defaults to None.",retry_after:"(int) Minimum time to wait before retrying a failed request",ttl:"(int) Sliding window to look back over when calculating the average latency of a deployment. Default - 1 hour (in seconds).",lowest_latency_buffer:"(float) Shuffle between deployments within this % of the lowest latency. Default - 0 (i.e. always pick lowest latency)."};(0,n.useEffect)(()=>{l&&t&&s&&q(l,s,t).then(e=>{console.log("callbacks",e),i(e.router_settings)})},[l,t,s]);let Z=async e=>{if(l){console.log("received key: ".concat(e)),console.log("routerSettings['fallbacks']: ".concat(o.fallbacks)),o.fallbacks.map(l=>(e in l&&delete l[e],l));try{await V(l,{router_settings:o}),i({...o}),j(o.routing_strategy),u.ZP.success("Router settings updated successfully")}catch(e){u.ZP.error("Failed to update router settings: "+e,20)}}},_=e=>{if(!l)return;console.log("router_settings",e);let t=Object.fromEntries(Object.entries(e).map(e=>{let[l,t]=e;if("routing_strategy_args"!==l&&"routing_strategy"!==l){var s;return[l,(null===(s=document.querySelector('input[name="'.concat(l,'"]')))||void 0===s?void 0:s.value)||t]}if("routing_strategy"==l)return[l,p];if("routing_strategy_args"==l&&"latency-based-routing"==p){let e={},l=document.querySelector('input[name="lowest_latency_buffer"]'),t=document.querySelector('input[name="ttl"]');return(null==l?void 0:l.value)&&(e.lowest_latency_buffer=Number(l.value)),(null==t?void 0:t.value)&&(e.ttl=Number(t.value)),console.log("setRoutingStrategyArgs: ".concat(e)),["routing_strategy_args",e]}return null}).filter(e=>null!=e));console.log("updatedVariables",t);try{V(l,{router_settings:t})}catch(e){u.ZP.error("Failed to update router settings: "+e,20)}u.ZP.success("router settings updated successfully")};return l?(0,r.jsx)("div",{className:"w-full mx-4",children:(0,r.jsxs)(eM.Z,{className:"gap-2 p-8 h-[75vh] w-full mt-2",children:[(0,r.jsxs)(eL.Z,{variant:"line",defaultValue:"1",children:[(0,r.jsx)(eR.Z,{value:"1",children:"General Settings"}),(0,r.jsx)(eR.Z,{value:"2",children:"Fallbacks"})]}),(0,r.jsxs)(eD.Z,{children:[(0,r.jsx)(eU.Z,{children:(0,r.jsxs)(W.Z,{numItems:1,className:"gap-2 p-8 w-full mt-2",children:[(0,r.jsx)(el.Z,{children:"Router Settings"}),(0,r.jsxs)(ep.Z,{children:[(0,r.jsxs)(eg.Z,{children:[(0,r.jsx)(eZ.Z,{children:(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(e_.Z,{children:"Setting"}),(0,r.jsx)(e_.Z,{children:"Value"})]})}),(0,r.jsx)(ey.Z,{children:Object.entries(o).filter(e=>{let[l,t]=e;return"fallbacks"!=l&&"context_window_fallbacks"!=l&&"routing_strategy_args"!=l}).map(e=>{let[l,t]=e;return(0,r.jsxs)(ew.Z,{children:[(0,r.jsxs)(ef.Z,{children:[(0,r.jsx)(ee.Z,{children:l}),(0,r.jsx)("p",{style:{fontSize:"0.65rem",color:"#808080",fontStyle:"italic"},className:"mt-1",children:f[l]})]}),(0,r.jsx)(ef.Z,{children:"routing_strategy"==l?(0,r.jsxs)(eb.Z,{defaultValue:t,className:"w-full max-w-md",onValueChange:j,children:[(0,r.jsx)(ek.Z,{value:"usage-based-routing",children:"usage-based-routing"}),(0,r.jsx)(ek.Z,{value:"latency-based-routing",children:"latency-based-routing"}),(0,r.jsx)(ek.Z,{value:"simple-shuffle",children:"simple-shuffle"})]}):(0,r.jsx)(H.Z,{name:l,defaultValue:"object"==typeof t?JSON.stringify(t,null,2):t.toString()})})]},l)})})]}),(0,r.jsx)(lm,{selectedStrategy:p,strategyArgs:o&&o.routing_strategy_args&&Object.keys(o.routing_strategy_args).length>0?o.routing_strategy_args:ld,paramExplanation:f})]}),(0,r.jsx)(Y.Z,{children:(0,r.jsx)(J.Z,{className:"mt-2",onClick:()=>_(o),children:"Save Changes"})})]})}),(0,r.jsxs)(eU.Z,{children:[(0,r.jsxs)(eg.Z,{children:[(0,r.jsx)(eZ.Z,{children:(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(e_.Z,{children:"Model Name"}),(0,r.jsx)(e_.Z,{children:"Fallbacks"})]})}),(0,r.jsx)(ey.Z,{children:o.fallbacks&&o.fallbacks.map((e,t)=>Object.entries(e).map(e=>{let[s,a]=e;return(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(ef.Z,{children:s}),(0,r.jsx)(ef.Z,{children:Array.isArray(a)?a.join(", "):a}),(0,r.jsx)(ef.Z,{children:(0,r.jsx)(J.Z,{onClick:()=>lc(s,l),children:"Test Fallback"})}),(0,r.jsx)(ef.Z,{children:(0,r.jsx)(ej.Z,{icon:eh.Z,size:"sm",onClick:()=>Z(s)})})]},t.toString()+s)}))})]}),(0,r.jsx)(lo,{models:(null==a?void 0:a.data)?a.data.map(e=>e.model_name):[],accessToken:l,routerSettings:o,setRouterSettings:i})]})]})]})}):null},lh=t(67951),lx=e=>{let{}=e;return(0,r.jsx)(r.Fragment,{children:(0,r.jsx)(W.Z,{className:"gap-2 p-8 h-[80vh] w-full mt-2",children:(0,r.jsxs)("div",{className:"mb-5",children:[(0,r.jsx)("p",{className:"text-2xl text-tremor-content-strong dark:text-dark-tremor-content-strong font-semibold",children:"OpenAI Compatible Proxy: API Reference"}),(0,r.jsx)(ee.Z,{className:"mt-2 mb-2",children:"LiteLLM is OpenAI Compatible. This means your API Key works with the OpenAI SDK. Just replace the base_url to point to your litellm proxy. Example Below "}),(0,r.jsxs)(eM.Z,{children:[(0,r.jsxs)(eL.Z,{children:[(0,r.jsx)(eR.Z,{children:"OpenAI Python SDK"}),(0,r.jsx)(eR.Z,{children:"LlamaIndex"}),(0,r.jsx)(eR.Z,{children:"Langchain Py"})]}),(0,r.jsxs)(eD.Z,{children:[(0,r.jsx)(eU.Z,{children:(0,r.jsx)(lh.Z,{language:"python",children:'\nimport openai\nclient = openai.OpenAI(\n api_key="your_api_key",\n base_url="http://0.0.0.0:4000" # LiteLLM Proxy is OpenAI compatible, Read More: https://docs.litellm.ai/docs/proxy/user_keys\n)\n\nresponse = client.chat.completions.create(\n model="gpt-3.5-turbo", # model to send to the proxy\n messages = [\n {\n "role": "user",\n "content": "this is a test request, write a short poem"\n }\n ]\n)\n\nprint(response)\n '})}),(0,r.jsx)(eU.Z,{children:(0,r.jsx)(lh.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,r.jsx)(eU.Z,{children:(0,r.jsx)(lh.Z,{language:"python",children:'\nfrom langchain.chat_models import ChatOpenAI\nfrom langchain.prompts.chat import (\n ChatPromptTemplate,\n HumanMessagePromptTemplate,\n SystemMessagePromptTemplate,\n)\nfrom langchain.schema import HumanMessage, SystemMessage\n\nchat = ChatOpenAI(\n openai_api_base="http://0.0.0.0:4000",\n model = "gpt-3.5-turbo",\n temperature=0.1\n)\n\nmessages = [\n SystemMessage(\n content="You are a helpful assistant that im using to make a test request to."\n ),\n HumanMessage(\n content="test from litellm. tell me why it\'s amazing in 1 sentence"\n ),\n]\nresponse = chat(messages)\n\nprint(response)\n\n '})})]})]})]})})})};async function lp(e,l,t,s){console.log("isLocal:",!1);let a=window.location.origin,r=new li.ZP.OpenAI({apiKey:s,baseURL:a,dangerouslyAllowBrowser:!0});try{for await(let s of(await r.chat.completions.create({model:t,stream:!0,messages:[{role:"user",content:e}]})))console.log(s),s.choices[0].delta.content&&l(s.choices[0].delta.content)}catch(e){u.ZP.error("Error occurred while generating model response. Please try again. Error: ".concat(e),20)}}var lj=e=>{let{accessToken:l,token:t,userRole:s,userID:a}=e,[o,i]=(0,n.useState)(""),[c,d]=(0,n.useState)(""),[m,u]=(0,n.useState)([]),[h,x]=(0,n.useState)(void 0),[p,j]=(0,n.useState)([]);(0,n.useEffect)(()=>{l&&t&&s&&a&&(async()=>{try{let e=await N(l,a,s);if(console.log("model_info:",e),(null==e?void 0:e.data.length)>0){let l=e.data.map(e=>({value:e.id,label:e.id}));console.log(l),j(l),x(e.data[0].id)}}catch(e){console.error("Error fetching model info:",e)}})()},[l,a,s]);let g=(e,l)=>{u(t=>{let s=t[t.length-1];return s&&s.role===e?[...t.slice(0,t.length-1),{role:e,content:s.content+l}]:[...t,{role:e,content:l}]})},y=async()=>{if(""!==c.trim()&&o&&t&&s&&a){u(e=>[...e,{role:"user",content:c}]);try{h&&await lp(c,e=>g("assistant",e),h,o)}catch(e){console.error("Error fetching model response",e),g("assistant","Error fetching model response")}d("")}};if(s&&"Admin Viewer"==s){let{Title:e,Paragraph:l}=eT.default;return(0,r.jsxs)("div",{children:[(0,r.jsx)(e,{level:1,children:"Access Denied"}),(0,r.jsx)(l,{children:"Ask your proxy admin for access to test models"})]})}return(0,r.jsx)("div",{style:{width:"100%",position:"relative"},children:(0,r.jsx)(W.Z,{className:"gap-2 p-8 h-[80vh] w-full mt-2",children:(0,r.jsx)(ep.Z,{children:(0,r.jsxs)(eM.Z,{children:[(0,r.jsx)(eL.Z,{children:(0,r.jsx)(eR.Z,{children:"Chat"})}),(0,r.jsx)(eD.Z,{children:(0,r.jsxs)(eU.Z,{children:[(0,r.jsx)("div",{className:"sm:max-w-2xl",children:(0,r.jsxs)(W.Z,{numItems:2,children:[(0,r.jsxs)(Y.Z,{children:[(0,r.jsx)(ee.Z,{children:"API Key"}),(0,r.jsx)(H.Z,{placeholder:"Type API Key here",type:"password",onValueChange:i,value:o})]}),(0,r.jsxs)(Y.Z,{className:"mx-2",children:[(0,r.jsx)(ee.Z,{children:"Select Model:"}),(0,r.jsx)(es.default,{placeholder:"Select a Model",onChange:e=>{console.log("selected ".concat(e)),x(e)},options:p,style:{width:"200px"}})]})]})}),(0,r.jsxs)(eg.Z,{className:"mt-5",style:{display:"block",maxHeight:"60vh",overflowY:"auto"},children:[(0,r.jsx)(eZ.Z,{children:(0,r.jsx)(ew.Z,{children:(0,r.jsx)(ef.Z,{})})}),(0,r.jsx)(ey.Z,{children:m.map((e,l)=>(0,r.jsx)(ew.Z,{children:(0,r.jsx)(ef.Z,{children:"".concat(e.role,": ").concat(e.content)})},l))})]}),(0,r.jsx)("div",{className:"mt-3",style:{position:"absolute",bottom:5,width:"95%"},children:(0,r.jsxs)("div",{className:"flex",children:[(0,r.jsx)(H.Z,{type:"text",value:c,onChange:e=>d(e.target.value),placeholder:"Type your message..."}),(0,r.jsx)(J.Z,{onClick:y,className:"ml-2",children:"Send"})]})})]})})]})})})})},lg=t(33509),ly=t(95781);let{Sider:lf}=lg.default;var lZ=e=>{let{setPage:l,userRole:t,defaultSelectedKey:s}=e;return"Admin Viewer"==t?(0,r.jsx)(lg.default,{style:{minHeight:"100vh",maxWidth:"120px"},children:(0,r.jsx)(lf,{width:120,children:(0,r.jsxs)(ly.Z,{mode:"inline",defaultSelectedKeys:s||["4"],style:{height:"100%",borderRight:0},children:[(0,r.jsx)(ly.Z.Item,{onClick:()=>l("api-keys"),children:"API Keys"},"4"),(0,r.jsx)(ly.Z.Item,{onClick:()=>l("models"),children:"Models"},"2"),(0,r.jsx)(ly.Z.Item,{onClick:()=>l("llm-playground"),children:"Chat UI"},"3"),(0,r.jsx)(ly.Z.Item,{onClick:()=>l("usage"),children:"Usage"},"1")]})})}):(0,r.jsx)(lg.default,{style:{minHeight:"100vh",maxWidth:"145px"},children:(0,r.jsx)(lf,{width:145,children:(0,r.jsxs)(ly.Z,{mode:"inline",defaultSelectedKeys:s||["1"],style:{height:"100%",borderRight:0},children:[(0,r.jsx)(ly.Z.Item,{onClick:()=>l("api-keys"),children:(0,r.jsx)(ee.Z,{children:"API Keys"})},"1"),(0,r.jsx)(ly.Z.Item,{onClick:()=>l("llm-playground"),children:(0,r.jsx)(ee.Z,{children:"Test Key"})},"3"),"Admin"==t?(0,r.jsx)(ly.Z.Item,{onClick:()=>l("models"),children:(0,r.jsx)(ee.Z,{children:"Models"})},"2"):null,"Admin"==t?(0,r.jsx)(ly.Z.Item,{onClick:()=>l("usage"),children:(0,r.jsx)(ee.Z,{children:"Usage"})},"4"):null,"Admin"==t?(0,r.jsx)(ly.Z.Item,{onClick:()=>l("teams"),children:(0,r.jsx)(ee.Z,{children:"Teams"})},"6"):null,"Admin"==t?(0,r.jsx)(ly.Z.Item,{onClick:()=>l("users"),children:(0,r.jsx)(ee.Z,{children:"Users"})},"5"):null,"Admin"==t?(0,r.jsx)(ly.Z.Item,{onClick:()=>l("settings"),children:(0,r.jsx)(ee.Z,{children:"Logging & Alerts"})},"8"):null,"Admin"==t?(0,r.jsx)(ly.Z.Item,{onClick:()=>l("general-settings"),children:(0,r.jsx)(ee.Z,{children:"Router Settings"})},"9"):null,"Admin"==t?(0,r.jsx)(ly.Z.Item,{onClick:()=>l("admin-panel"),children:(0,r.jsx)(ee.Z,{children:"Admin"})},"7"):null,(0,r.jsx)(ly.Z.Item,{onClick:()=>l("api_ref"),children:(0,r.jsx)(ee.Z,{children:"API Reference"})},"11")]})})})},l_=t(67989),lw=e=>{let{accessToken:l,token:t,userRole:s,userID:a,keys:o}=e,i=new Date,[c,d]=(0,n.useState)([]),[m,u]=(0,n.useState)([]),[h,x]=(0,n.useState)([]),[p,j]=(0,n.useState)([]),[g,y]=(0,n.useState)([]),[f,Z]=(0,n.useState)([]),[_,w]=(0,n.useState)([]),[b,k]=(0,n.useState)([]),[v,S]=(0,n.useState)(""),[N,R]=(0,n.useState)({from:new Date(Date.now()-6048e5),to:new Date}),M=new Date(i.getFullYear(),i.getMonth(),1),L=new Date(i.getFullYear(),i.getMonth()+1,0),U=z(M),D=z(L);console.log("keys in usage",o);let K=async(e,t,s)=>{if(!e||!t||!l)return;console.log("uiSelectedKey",s);let a=await T(l,s,e.toISOString(),t.toISOString());console.log("End user data updated successfully",a),j(a)},B=async(e,t)=>{e&&t&&l&&(Z((await E(l,e.toISOString(),t.toISOString())).spend_per_tag),console.log("Tag spend data updated successfully"))};function z(e){let l=e.getFullYear(),t=e.getMonth()+1,s=e.getDate();return"".concat(l,"-").concat(t<10?"0"+t:t,"-").concat(s<10?"0"+s:s)}return console.log("Start date is ".concat(U)),console.log("End date is ".concat(D)),(0,n.useEffect)(()=>{l&&t&&s&&a&&(async()=>{try{if(console.log("user role: ".concat(s)),"Admin"==s||"Admin Viewer"==s){var e,r;let t=await C(l);d(t);let s=(await P(l)).map(e=>({key:(e.key_name||e.key_alias||e.api_key).substring(0,10),spend:e.total_spend}));u(s);let a=(await O(l)).map(e=>({key:e.model,spend:e.total_spend}));x(a);let n=await A(l);console.log("teamSpend",n),y(n.daily_spend),w(n.teams);let o=n.total_spend_per_team;o=o.map(e=>(e.name=e.team_id||"",e.value=e.total_spend||0,e)),k(o);let i=await E(l,null===(e=N.from)||void 0===e?void 0:e.toISOString(),null===(r=N.to)||void 0===r?void 0:r.toISOString());Z(i.spend_per_tag);let c=await T(l,null,void 0,void 0);j(c),console.log("spend/user result",c)}else"App Owner"==s&&await I(l,t,s,a,U,D).then(async e=>{if(console.log("result from spend logs call",e),"daily_spend"in e){let l=e.daily_spend;console.log("daily spend",l),d(l);let t=e.top_api_keys;u(t)}else{let t=(await F(l,function(e){let l=[];e.forEach(e=>{Object.entries(e).forEach(e=>{let[t,s]=e;"spend"!==t&&"startTime"!==t&&"models"!==t&&"users"!==t&&l.push({key:t,spend:s})})}),l.sort((e,l)=>Number(l.spend)-Number(e.spend));let t=l.slice(0,5).map(e=>e.key);return console.log("topKeys: ".concat(Object.keys(t[0]))),t}(e))).info.map(e=>({key:(e.key_name||e.key_alias).substring(0,10),spend:e.spend}));u(t),d(e)}})}catch(e){console.error("There was an error fetching the data",e)}})()},[l,t,s,a,U,D]),(0,r.jsxs)("div",{style:{width:"100%"},className:"p-8",children:[(0,r.jsx)(eE,{userID:a,userRole:s,accessToken:l,userSpend:null,selectedTeam:null}),(0,r.jsxs)(eM.Z,{children:[(0,r.jsxs)(eL.Z,{className:"mt-2",children:[(0,r.jsx)(eR.Z,{children:"All Up"}),(0,r.jsx)(eR.Z,{children:"Team Based Usage"}),(0,r.jsx)(eR.Z,{children:"End User Usage"}),(0,r.jsx)(eR.Z,{children:"Tag Based Usage"})]}),(0,r.jsxs)(eD.Z,{children:[(0,r.jsx)(eU.Z,{children:(0,r.jsxs)(W.Z,{numItems:2,className:"gap-2 h-[75vh] w-full",children:[(0,r.jsx)(Y.Z,{numColSpan:2,children:(0,r.jsxs)(ep.Z,{children:[(0,r.jsx)(el.Z,{children:"Monthly Spend"}),(0,r.jsx)(eq.Z,{data:c,index:"date",categories:["spend"],colors:["blue"],valueFormatter:e=>"$ ".concat(new Intl.NumberFormat("us").format(e).toString()),yAxisWidth:100,tickGap:5})]})}),(0,r.jsx)(Y.Z,{numColSpan:1,children:(0,r.jsxs)(ep.Z,{children:[(0,r.jsx)(el.Z,{children:"Top API Keys"}),(0,r.jsx)(eq.Z,{className:"mt-4 h-40",data:m,index:"key",categories:["spend"],colors:["blue"],yAxisWidth:80,tickGap:5,layout:"vertical",showXAxis:!1,showLegend:!1})]})}),(0,r.jsx)(Y.Z,{numColSpan:1,children:(0,r.jsxs)(ep.Z,{children:[(0,r.jsx)(el.Z,{children:"Top Models"}),(0,r.jsx)(eq.Z,{className:"mt-4 h-40",data:h,index:"key",categories:["spend"],colors:["blue"],yAxisWidth:200,layout:"vertical",showXAxis:!1,showLegend:!1})]})}),(0,r.jsx)(Y.Z,{numColSpan:1})]})}),(0,r.jsx)(eU.Z,{children:(0,r.jsxs)(W.Z,{numItems:2,className:"gap-2 h-[75vh] w-full",children:[(0,r.jsxs)(Y.Z,{numColSpan:2,children:[(0,r.jsxs)(ep.Z,{className:"mb-2",children:[(0,r.jsx)(el.Z,{children:"Total Spend Per Team"}),(0,r.jsx)(l_.Z,{data:b})]}),(0,r.jsxs)(ep.Z,{children:[(0,r.jsx)(el.Z,{children:"Daily Spend Per Team"}),(0,r.jsx)(eq.Z,{className:"h-72",data:g,showLegend:!0,index:"date",categories:_,yAxisWidth:80,colors:["blue","green","yellow","red","purple"],stack:!0})]})]}),(0,r.jsx)(Y.Z,{numColSpan:2})]})}),(0,r.jsxs)(eU.Z,{children:[(0,r.jsxs)("p",{className:"mb-2 text-gray-500 italic text-[12px]",children:["End-Users of your LLM API calls. Tracked when a `user` param is passed in your LLM calls ",(0,r.jsx)("a",{className:"text-blue-500",href:"https://docs.litellm.ai/docs/proxy/users",target:"_blank",children:"docs here"})]}),(0,r.jsxs)(W.Z,{numItems:2,children:[(0,r.jsxs)(Y.Z,{children:[(0,r.jsx)(ee.Z,{children:"Select Time Range"}),(0,r.jsx)(eF.Z,{enableSelect:!0,value:N,onValueChange:e=>{R(e),K(e.from,e.to,null)}})]}),(0,r.jsxs)(Y.Z,{children:[(0,r.jsx)(ee.Z,{children:"Select Key"}),(0,r.jsxs)(eb.Z,{defaultValue:"all-keys",children:[(0,r.jsx)(ek.Z,{value:"all-keys",onClick:()=>{K(N.from,N.to,null)},children:"All Keys"},"all-keys"),null==o?void 0:o.map((e,l)=>e&&null!==e.key_alias&&e.key_alias.length>0?(0,r.jsx)(ek.Z,{value:String(l),onClick:()=>{K(N.from,N.to,e.token)},children:e.key_alias},l):null)]})]})]}),(0,r.jsx)(ep.Z,{className:"mt-4",children:(0,r.jsxs)(eg.Z,{className:"max-h-[70vh] min-h-[500px]",children:[(0,r.jsx)(eZ.Z,{children:(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(e_.Z,{children:"End User"}),(0,r.jsx)(e_.Z,{children:"Spend"}),(0,r.jsx)(e_.Z,{children:"Total Events"})]})}),(0,r.jsx)(ey.Z,{children:null==p?void 0:p.map((e,l)=>{var t;return(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(ef.Z,{children:e.end_user}),(0,r.jsx)(ef.Z,{children:null===(t=e.total_spend)||void 0===t?void 0:t.toFixed(4)}),(0,r.jsx)(ef.Z,{children:e.total_count})]},l)})})]})})]}),(0,r.jsx)(eU.Z,{children:(0,r.jsxs)(W.Z,{numItems:2,className:"gap-2 h-[75vh] w-full mb-4",children:[(0,r.jsxs)(Y.Z,{numColSpan:2,children:[(0,r.jsx)(eF.Z,{className:"mb-4",enableSelect:!0,value:N,onValueChange:e=>{R(e),B(e.from,e.to)}}),(0,r.jsxs)(ep.Z,{children:[(0,r.jsx)(el.Z,{children:"Spend Per Tag"}),(0,r.jsxs)(ee.Z,{children:["Get Started Tracking cost per tag ",(0,r.jsx)("a",{className:"text-blue-500",href:"https://docs.litellm.ai/docs/proxy/enterprise#tracking-spend-for-custom-tags",target:"_blank",children:"here"})]}),(0,r.jsx)(eq.Z,{className:"h-72",data:f,index:"name",categories:["spend"],colors:["blue"]})]})]}),(0,r.jsx)(Y.Z,{numColSpan:2})]})})]})]})]})},lb=()=>{let{Title:e,Paragraph:l}=eT.default,[t,s]=(0,n.useState)(""),[a,i]=(0,n.useState)(null),[c,d]=(0,n.useState)(null),[u,h]=(0,n.useState)(null),[x,p]=(0,n.useState)(!0),j=(0,o.useSearchParams)(),[g,y]=(0,n.useState)({data:[]}),f=j.get("userID"),Z=j.get("token"),[_,w]=(0,n.useState)("api-keys"),[b,k]=(0,n.useState)(null);return(0,n.useEffect)(()=>{if(Z){let e=(0,eP.o)(Z);if(e){if(console.log("Decoded token:",e),console.log("Decoded key:",e.key),k(e.key),e.user_role){let l=function(e){if(!e)return"Undefined Role";switch(console.log("Received user role: ".concat(e.toLowerCase())),console.log("Received user role length: ".concat(e.toLowerCase().length)),e.toLowerCase()){case"app_owner":case"demo_app_owner":return"App Owner";case"app_admin":case"proxy_admin":return"Admin";case"proxy_admin_viewer":return"Admin Viewer";case"app_user":return"App User";default:return"Unknown Role"}}(e.user_role);console.log("Decoded user_role:",l),s(l),"Admin Viewer"==l&&w("usage")}else console.log("User role not defined");e.user_email?i(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))}}},[Z]),(0,r.jsx)(n.Suspense,{fallback:(0,r.jsx)("div",{children:"Loading..."}),children:(0,r.jsxs)("div",{className:"flex flex-col min-h-screen",children:[(0,r.jsx)(m,{userID:f,userRole:t,userEmail:a,showSSOBanner:x}),(0,r.jsxs)("div",{className:"flex flex-1 overflow-auto",children:[(0,r.jsx)("div",{className:"mt-8",children:(0,r.jsx)(lZ,{setPage:w,userRole:t,defaultSelectedKey:null})}),"api-keys"==_?(0,r.jsx)(eO,{userID:f,userRole:t,teams:c,keys:u,setUserRole:s,userEmail:a,setUserEmail:i,setTeams:d,setKeys:h}):"models"==_?(0,r.jsx)(e3,{userID:f,userRole:t,token:Z,accessToken:b,modelData:g,setModelData:y}):"llm-playground"==_?(0,r.jsx)(lj,{userID:f,userRole:t,token:Z,accessToken:b}):"users"==_?(0,r.jsx)(e9,{userID:f,userRole:t,token:Z,keys:u,teams:c,accessToken:b,setKeys:h}):"teams"==_?(0,r.jsx)(le,{teams:c,setTeams:d,searchParams:j,accessToken:b,userID:f,userRole:t}):"admin-panel"==_?(0,r.jsx)(lt,{setTeams:d,searchParams:j,accessToken:b,showSSOBanner:x}):"api_ref"==_?(0,r.jsx)(lx,{}):"settings"==_?(0,r.jsx)(lr,{userID:f,userRole:t,accessToken:b}):"general-settings"==_?(0,r.jsx)(lu,{userID:f,userRole:t,accessToken:b,modelData:g}):(0,r.jsx)(lw,{userID:f,userRole:t,token:Z,accessToken:b,keys:u})]})]})})}}},function(e){e.O(0,[936,884,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-e6190351ac8da62a.js b/litellm/proxy/_experimental/out/_next/static/chunks/app/page-e6190351ac8da62a.js deleted file mode 100644 index 672a1d857e..0000000000 --- a/litellm/proxy/_experimental/out/_next/static/chunks/app/page-e6190351ac8da62a.js +++ /dev/null @@ -1 +0,0 @@ -(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[931],{20661:function(e,l,t){Promise.resolve().then(t.bind(t,7926))},7926:function(e,l,t){"use strict";t.r(l),t.d(l,{default:function(){return lb}});var s,r,a=t(3827),n=t(64090),o=t(47907),i=t(8792),c=t(40491),d=t(65270),m=e=>{let{userID:l,userRole:t,userEmail:s,showSSOBanner:r}=e;console.log("User ID:",l),console.log("userEmail:",s),console.log("showSSOBanner:",r);let n=[{key:"1",label:(0,a.jsxs)(a.Fragment,{children:[(0,a.jsxs)("p",{children:["Role: ",t]}),(0,a.jsxs)("p",{children:["ID: ",l]})]})}];return(0,a.jsxs)("nav",{className:"left-0 right-0 top-0 flex justify-between items-center h-12 mb-4",children:[(0,a.jsx)("div",{className:"text-left my-2 absolute top-0 left-0",children:(0,a.jsx)("div",{className:"flex flex-col items-center",children:(0,a.jsx)(i.default,{href:"/",children:(0,a.jsx)("button",{className:"text-gray-800 rounded text-center",children:(0,a.jsx)("img",{src:"/get_image",width:160,height:160,alt:"LiteLLM Brand",className:"mr-2"})})})})}),(0,a.jsxs)("div",{className:"text-right mx-4 my-2 absolute top-0 right-0 flex items-center justify-end space-x-2",children:[r?(0,a.jsx)("div",{style:{padding:"6px",borderRadius:"8px"},children:(0,a.jsx)("a",{href:"https://calendly.com/d/4mp-gd3-k5k/litellm-1-1-onboarding-chat",target:"_blank",style:{fontSize:"14px",textDecoration:"underline"},children:"Request hosted proxy"})}):null,(0,a.jsx)("div",{style:{border:"1px solid #391085",padding:"6px",borderRadius:"8px"},children:(0,a.jsx)(c.Z,{menu:{items:n},children:(0,a.jsx)(d.Z,{children:s})})})]})]})},u=t(80588);let h=async()=>{try{let e=await fetch("https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json"),l=await e.json();return console.log("received data: ".concat(l)),l}catch(e){throw console.error("Failed to get model cost map:",e),e}},x=async(e,l)=>{try{let t=await fetch("/model/new",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...l})});if(!t.ok){let e=await t.text();throw u.ZP.error("Failed to create key: "+e,10),console.error("Error response from the server:",e),Error("Network response was not ok")}let s=await t.json();return console.log("API Response:",s),u.ZP.success("Model created successfully. Wait 60s and refresh on 'All Models' page"),s}catch(e){throw console.error("Failed to create key:",e),e}},p=async(e,l)=>{console.log("model_id in model delete call: ".concat(l));try{let t=await fetch("/model/delete",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({id:l})});if(!t.ok){let e=await t.text();throw u.ZP.error("Failed to create key: "+e,10),console.error("Error response from the server:",e),Error("Network response was not ok")}let s=await t.json();return console.log("API Response:",s),u.ZP.success("Model deleted successfully. Restart server to see this."),s}catch(e){throw console.error("Failed to create key:",e),e}},j=async(e,l,t)=>{try{if(console.log("Form Values in keyCreateCall:",t),t.description&&(t.metadata||(t.metadata={}),t.metadata.description=t.description,delete t.description,t.metadata=JSON.stringify(t.metadata)),t.metadata){console.log("formValues.metadata:",t.metadata);try{t.metadata=JSON.parse(t.metadata)}catch(e){throw u.ZP.error("Failed to parse metadata: "+e,10),Error("Failed to parse metadata: "+e)}}console.log("Form Values after check:",t);let s=await fetch("/key/generate",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({user_id:l,...t})});if(!s.ok){let e=await s.text();throw u.ZP.error("Failed to create key: "+e,10),console.error("Error response from the server:",e),Error("Network response was not ok")}let r=await s.json();return console.log("API Response:",r),r}catch(e){throw console.error("Failed to create key:",e),e}},g=async(e,l,t)=>{try{if(console.log("Form Values in keyCreateCall:",t),t.description&&(t.metadata||(t.metadata={}),t.metadata.description=t.description,delete t.description,t.metadata=JSON.stringify(t.metadata)),t.metadata){console.log("formValues.metadata:",t.metadata);try{t.metadata=JSON.parse(t.metadata)}catch(e){throw u.ZP.error("Failed to parse metadata: "+e,10),Error("Failed to parse metadata: "+e)}}console.log("Form Values after check:",t);let s=await fetch("/user/new",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({user_id:l,...t})});if(!s.ok){let e=await s.text();throw u.ZP.error("Failed to create key: "+e,10),console.error("Error response from the server:",e),Error("Network response was not ok")}let r=await s.json();return console.log("API Response:",r),r}catch(e){throw console.error("Failed to create key:",e),e}},y=async(e,l)=>{try{console.log("in keyDeleteCall:",l);let t=await fetch("/key/delete",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({keys:[l]})});if(!t.ok){let e=await t.text();throw u.ZP.error("Failed to delete key: "+e,10),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}},f=async(e,l)=>{try{console.log("in teamDeleteCall:",l);let t=await fetch("/team/delete",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({team_ids:[l]})});if(!t.ok){let e=await t.text();throw u.ZP.error("Failed to delete team: "+e,10),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to delete key:",e),e}},Z=async function(e,l,t){let s=arguments.length>3&&void 0!==arguments[3]&&arguments[3],r=arguments.length>4?arguments[4]:void 0,a=arguments.length>5?arguments[5]:void 0;try{let n="/user/info";"App Owner"==t&&l&&(n="".concat(n,"?user_id=").concat(l)),"App User"==t&&l&&(n="".concat(n,"?user_id=").concat(l)),console.log("in userInfoCall viewAll=",s),s&&a&&null!=r&&void 0!=r&&(n="".concat(n,"?view_all=true&page=").concat(r,"&page_size=").concat(a));let o=await fetch(n,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!o.ok){let e=await o.text();throw u.ZP.error(e,10),Error("Network response was not ok")}let i=await o.json();return console.log("API Response:",i),i}catch(e){throw console.error("Failed to create key:",e),e}},_=async(e,l)=>{try{let t="/team/info";l&&(t="".concat(t,"?team_id=").concat(l)),console.log("in teamInfoCall");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 u.ZP.error(e,10),Error("Network response was not ok")}let r=await s.json();return console.log("API Response:",r),r}catch(e){throw console.error("Failed to create key:",e),e}},w=async e=>{try{let l=await fetch("/global/spend",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw u.ZP.error(e,10),Error("Network response was not ok")}return await l.json()}catch(e){throw console.error("Failed to create key:",e),e}},b=async(e,l,t)=>{try{let l=await fetch("/v2/model/info",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw u.ZP.error(e,10),Error("Network response was not ok")}let t=await l.json();return console.log("modelInfoCall:",t),t}catch(e){throw console.error("Failed to create key:",e),e}},k=async(e,l,t,s,r,a)=>{try{let l="/model/metrics";s&&(l="".concat(l,"?_selected_model_group=").concat(s,"&startTime=").concat(r,"&endTime=").concat(a));let t=await fetch(l,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw u.ZP.error(e,10),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},v=async(e,l,t,s,r,a)=>{try{let l="/model/metrics/slow_responses";s&&(l="".concat(l,"?_selected_model_group=").concat(s,"&startTime=").concat(r,"&endTime=").concat(a));let t=await fetch(l,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw u.ZP.error(e,10),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},S=async(e,l,t,s,r,a)=>{try{let l="/model/metrics/exceptions";s&&(l="".concat(l,"?_selected_model_group=").concat(s,"&startTime=").concat(r,"&endTime=").concat(a));let t=await fetch(l,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw u.ZP.error(e,10),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},A=async(e,l,t)=>{try{let l=await fetch("/models",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw u.ZP.error(e,10),Error("Network response was not ok")}return await l.json()}catch(e){throw console.error("Failed to create key:",e),e}},N=async e=>{try{let l="/global/spend/teams";console.log("in teamSpendLogsCall:",l);let t=await fetch("".concat(l),{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw u.ZP.error(e,10),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}},E=async e=>{try{let l="/global/spend/tags";console.log("in tagsSpendLogsCall:",l);let t=await fetch("".concat(l),{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw u.ZP.error(e,10),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}},I=async(e,l,t,s,r,a)=>{try{console.log("user role in spend logs call: ".concat(t));let l="/spend/logs";l="App Owner"==t?"".concat(l,"?user_id=").concat(s,"&start_date=").concat(r,"&end_date=").concat(a):"".concat(l,"?start_date=").concat(r,"&end_date=").concat(a);let n=await fetch(l,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!n.ok){let e=await n.text();throw u.ZP.error(e,10),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}},C=async e=>{try{let l=await fetch("/global/spend/logs",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw u.ZP.error(e,10),Error("Network response was not ok")}let t=await l.json();return console.log(t),t}catch(e){throw console.error("Failed to create key:",e),e}},P=async e=>{try{let l=await fetch("/global/spend/keys?limit=5",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw u.ZP.error(e,10),Error("Network response was not ok")}let t=await l.json();return console.log(t),t}catch(e){throw console.error("Failed to create key:",e),e}},T=async(e,l,t,s)=>{try{let r="";r=l?JSON.stringify({api_key:l,startTime:t,endTime:s}):JSON.stringify({startTime:t,endTime:s});let a={method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}};a.body=r;let n=await fetch("/global/spend/end_users",a);if(!n.ok){let e=await n.text();throw u.ZP.error(e,10),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}},O=async e=>{try{let l=await fetch("/global/spend/models?limit=5",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw u.ZP.error(e,10),Error("Network response was not ok")}let t=await l.json();return console.log(t),t}catch(e){throw console.error("Failed to create key:",e),e}},F=async(e,l)=>{try{let t=await fetch("/v2/key/info",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({keys:l})});if(!t.ok){let e=await t.text();throw u.ZP.error(e,10),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}},R=async(e,l)=>{try{let t="/user/get_users?role=".concat(l);console.log("in userGetAllUsersCall:",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 u.ZP.error("Failed to delete key: "+e,10),Error("Network response was not ok")}let r=await s.json();return console.log(r),r}catch(e){throw console.error("Failed to get requested models:",e),e}},M=async(e,l)=>{try{console.log("Form Values in teamCreateCall:",l);let t=await fetch("/team/new",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...l})});if(!t.ok){let e=await t.text();throw u.ZP.error("Failed to create key: "+e,10),console.error("Error response from the server:",e),Error("Network response was not ok")}let s=await t.json();return console.log("API Response:",s),s}catch(e){throw console.error("Failed to create key:",e),e}},L=async(e,l)=>{try{console.log("Form Values in keyUpdateCall:",l);let t=await fetch("/key/update",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...l})});if(!t.ok){let e=await t.text();throw u.ZP.error("Failed to update key: "+e,10),console.error("Error response from the server:",e),Error("Network response was not ok")}let s=await t.json();return console.log("Update key Response:",s),s}catch(e){throw console.error("Failed to create key:",e),e}},U=async(e,l)=>{try{console.log("Form Values in teamUpateCall:",l);let t=await fetch("/team/update",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...l})});if(!t.ok){let e=await t.text();throw u.ZP.error("Failed to update team: "+e,10),console.error("Error response from the server:",e),Error("Network response was not ok")}let s=await t.json();return console.log("Update Team Response:",s),s}catch(e){throw console.error("Failed to create key:",e),e}},D=async(e,l)=>{try{console.log("Form Values in modelUpateCall:",l);let t=await fetch("/model/update",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...l})});if(!t.ok){let e=await t.text();throw u.ZP.error("Failed to update model: "+e,10),console.error("Error update from the server:",e),Error("Network response was not ok")}let s=await t.json();return console.log("Update model Response:",s),s}catch(e){throw console.error("Failed to update model:",e),e}},K=async(e,l,t)=>{try{console.log("Form Values in teamMemberAddCall:",t);let s=await fetch("/team/member_add",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({team_id:l,member:t})});if(!s.ok){let e=await s.text();throw u.ZP.error("Failed to create key: "+e,10),console.error("Error response from the server:",e),Error("Network response was not ok")}let r=await s.json();return console.log("API Response:",r),r}catch(e){throw console.error("Failed to create key:",e),e}},B=async(e,l,t)=>{try{console.log("Form Values in userUpdateUserCall:",l);let s={...l};null!==t&&(s.user_role=t),s=JSON.stringify(s);let r=await fetch("/user/update",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:s});if(!r.ok){let e=await r.text();throw u.ZP.error("Failed to create key: "+e,10),console.error("Error response from the server:",e),Error("Network response was not ok")}let a=await r.json();return console.log("API Response:",a),a}catch(e){throw console.error("Failed to create key:",e),e}},z=async(e,l)=>{try{let t="/health/services?service=".concat(l);console.log("Checking Slack Budget Alerts service health");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 u.ZP.error("Failed ".concat(l," service health check ")+e),Error(e)}let r=await s.json();return u.ZP.success("Test request to ".concat(l," made - check logs/alerts on ").concat(l," to verify")),r}catch(e){throw console.error("Failed to perform health check:",e),e}},q=async(e,l,t)=>{try{let l=await fetch("/get/config/callbacks",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw u.ZP.error(e,10),Error("Network response was not ok")}return await l.json()}catch(e){throw console.error("Failed to get callbacks:",e),e}},V=async(e,l)=>{try{let t=await fetch("/config/update",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...l})});if(!t.ok){let e=await t.text();throw u.ZP.error(e,10),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to set callbacks:",e),e}},G=async e=>{try{let l=await fetch("/health",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw u.ZP.error(e),Error("Network response was not ok")}return await l.json()}catch(e){throw console.error("Failed to call /health:",e),e}};var Y=t(10384),W=t(46453),J=t(16450),H=t(52273),$=t(26780),X=t(15595),Q=t(6698),ee=t(71801),el=t(42440),et=t(42308),es=t(50670),er=t(81583),ea=t(99129),en=t(44839),eo=t(88707),ei=t(1861);let{Option:ec}=es.default;var ed=e=>{let{userID:l,team:t,userRole:s,accessToken:r,data:o,setData:i}=e,[c]=er.Z.useForm(),[d,m]=(0,n.useState)(!1),[h,x]=(0,n.useState)(null),[p,g]=(0,n.useState)(null),[y,f]=(0,n.useState)([]),[Z,_]=(0,n.useState)([]),w=()=>{m(!1),c.resetFields()},b=()=>{m(!1),x(null),c.resetFields()};(0,n.useEffect)(()=>{(async()=>{try{if(null===l||null===s)return;if(null!==r){let e=(await A(r,l,s)).data.map(e=>e.id);console.log("available_model_names:",e),f(e)}}catch(e){console.error("Error fetching user models:",e)}})()},[r,l,s]);let k=async e=>{try{var t,s,a;let n=null!==(t=null==e?void 0:e.key_alias)&&void 0!==t?t:"",d=null!==(s=null==e?void 0:e.team_id)&&void 0!==s?s:null;if((null!==(a=null==o?void 0:o.filter(e=>e.team_id===d).map(e=>e.key_alias))&&void 0!==a?a:[]).includes(n))throw Error("Key alias ".concat(n," already exists for team with ID ").concat(d,", please provide another key alias"));u.ZP.info("Making API Call"),m(!0);let h=await j(r,l,e);console.log("key create Response:",h),i(e=>e?[...e,h]:[h]),x(h.key),g(h.soft_budget),u.ZP.success("API Key Created"),c.resetFields(),localStorage.removeItem("userData"+l)}catch(e){console.error("Error creating the key:",e),u.ZP.error("Error creating the key: ".concat(e),20)}};return(0,n.useEffect)(()=>{_(t&&t.models.length>0?t.models.includes("all-proxy-models")?y:t.models:y)},[t,y]),(0,a.jsxs)("div",{children:[(0,a.jsx)(J.Z,{className:"mx-auto",onClick:()=>m(!0),children:"+ Create New Key"}),(0,a.jsx)(ea.Z,{title:"Create Key",visible:d,width:800,footer:null,onOk:w,onCancel:b,children:(0,a.jsxs)(er.Z,{form:c,onFinish:k,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(er.Z.Item,{label:"Key Name",name:"key_alias",rules:[{required:!0,message:"Please input a key name"}],help:"required",children:(0,a.jsx)(H.Z,{placeholder:""})}),(0,a.jsx)(er.Z.Item,{label:"Team ID",name:"team_id",hidden:!0,initialValue:t?t.team_id:null,valuePropName:"team_id",className:"mt-8",children:(0,a.jsx)(en.Z,{value:t?t.team_alias:"",disabled:!0})}),(0,a.jsx)(er.Z.Item,{label:"Models",name:"models",rules:[{required:!0,message:"Please select a model"}],help:"required",children:(0,a.jsxs)(es.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},onChange:e=>{e.includes("all-team-models")&&c.setFieldsValue({models:["all-team-models"]})},children:[(0,a.jsx)(ec,{value:"all-team-models",children:"All Team Models"},"all-team-models"),Z.map(e=>(0,a.jsx)(ec,{value:e,children:e},e))]})}),(0,a.jsxs)($.Z,{className:"mt-20 mb-8",children:[(0,a.jsx)(Q.Z,{children:(0,a.jsx)("b",{children:"Optional Settings"})}),(0,a.jsxs)(X.Z,{children:[(0,a.jsx)(er.Z.Item,{className:"mt-8",label:"Max Budget (USD)",name:"max_budget",help:"Budget cannot exceed team max budget: $".concat((null==t?void 0:t.max_budget)!==null&&(null==t?void 0:t.max_budget)!==void 0?null==t?void 0:t.max_budget:"unlimited"),rules:[{validator:async(e,l)=>{if(l&&t&&null!==t.max_budget&&l>t.max_budget)throw Error("Budget cannot exceed team max budget: $".concat(t.max_budget))}}],children:(0,a.jsx)(eo.Z,{step:.01,precision:2,width:200})}),(0,a.jsx)(er.Z.Item,{className:"mt-8",label:"Reset Budget",name:"budget_duration",help:"Team Reset Budget: ".concat((null==t?void 0:t.budget_duration)!==null&&(null==t?void 0:t.budget_duration)!==void 0?null==t?void 0:t.budget_duration:"None"),children:(0,a.jsxs)(es.default,{defaultValue:null,placeholder:"n/a",children:[(0,a.jsx)(es.default.Option,{value:"24h",children:"daily"}),(0,a.jsx)(es.default.Option,{value:"30d",children:"monthly"})]})}),(0,a.jsx)(er.Z.Item,{className:"mt-8",label:"Tokens per minute Limit (TPM)",name:"tpm_limit",help:"TPM cannot exceed team TPM limit: ".concat((null==t?void 0:t.tpm_limit)!==null&&(null==t?void 0:t.tpm_limit)!==void 0?null==t?void 0:t.tpm_limit:"unlimited"),rules:[{validator:async(e,l)=>{if(l&&t&&null!==t.tpm_limit&&l>t.tpm_limit)throw Error("TPM limit cannot exceed team TPM limit: ".concat(t.tpm_limit))}}],children:(0,a.jsx)(eo.Z,{step:1,width:400})}),(0,a.jsx)(er.Z.Item,{className:"mt-8",label:"Requests per minute Limit (RPM)",name:"rpm_limit",help:"RPM cannot exceed team RPM limit: ".concat((null==t?void 0:t.rpm_limit)!==null&&(null==t?void 0:t.rpm_limit)!==void 0?null==t?void 0:t.rpm_limit:"unlimited"),rules:[{validator:async(e,l)=>{if(l&&t&&null!==t.rpm_limit&&l>t.rpm_limit)throw Error("RPM limit cannot exceed team RPM limit: ".concat(t.rpm_limit))}}],children:(0,a.jsx)(eo.Z,{step:1,width:400})}),(0,a.jsx)(er.Z.Item,{label:"Expire Key (eg: 30s, 30h, 30d)",name:"duration",className:"mt-8",children:(0,a.jsx)(H.Z,{placeholder:""})}),(0,a.jsx)(er.Z.Item,{label:"Metadata",name:"metadata",children:(0,a.jsx)(en.Z.TextArea,{rows:4,placeholder:"Enter metadata as JSON"})})]})]})]}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(ei.ZP,{htmlType:"submit",children:"Create Key"})})]})}),h&&(0,a.jsx)(ea.Z,{visible:d,onOk:w,onCancel:b,footer:null,children:(0,a.jsxs)(W.Z,{numItems:1,className:"gap-2 w-full",children:[(0,a.jsx)(el.Z,{children:"Save your Key"}),(0,a.jsx)(Y.Z,{numColSpan:1,children:(0,a.jsxs)("p",{children:["Please save this secret key somewhere safe and accessible. For security reasons, ",(0,a.jsx)("b",{children:"you will not be able to view it again"})," ","through your LiteLLM account. If you lose this secret key, you will need to generate a new one."]})}),(0,a.jsx)(Y.Z,{numColSpan:1,children:null!=h?(0,a.jsxs)("div",{children:[(0,a.jsx)(ee.Z,{className:"mt-3",children:"API Key:"}),(0,a.jsx)("div",{style:{background:"#f8f8f8",padding:"10px",borderRadius:"5px",marginBottom:"10px"},children:(0,a.jsx)("pre",{style:{wordWrap:"break-word",whiteSpace:"normal"},children:h})}),(0,a.jsx)(et.CopyToClipboard,{text:h,onCopy:()=>{u.ZP.success("API Key copied to clipboard")},children:(0,a.jsx)(J.Z,{className:"mt-3",children:"Copy API Key"})})]}):(0,a.jsx)(ee.Z,{children:"Key being created, this might take 30s"})})]})})]})},em=t(9454),eu=t(98941),eh=t(33393),ex=t(5),ep=t(13810),ej=t(61244),eg=t(10827),ey=t(3851),ef=t(2044),eZ=t(64167),e_=t(74480),ew=t(7178),eb=t(95093),ek=t(27166);let{Option:ev}=es.default;var eS=e=>{let{userID:l,userRole:t,accessToken:s,selectedTeam:r,data:o,setData:i,teams:c}=e,[d,m]=(0,n.useState)(!1),[h,x]=(0,n.useState)(!1),[p,j]=(0,n.useState)(null),[g,f]=(0,n.useState)(null),[Z,_]=(0,n.useState)(null),[w,b]=(0,n.useState)(""),[k,v]=(0,n.useState)(!1),[S,N]=(0,n.useState)(!1),[E,I]=(0,n.useState)(null),[C,P]=(0,n.useState)([]),T=new Set,[O,F]=(0,n.useState)(T);(0,n.useEffect)(()=>{(async()=>{try{if(null===l)return;if(null!==s&&null!==t){let e=(await A(s,l,t)).data.map(e=>e.id);console.log("available_model_names:",e),P(e)}}catch(e){console.error("Error fetching user models:",e)}})()},[s,l,t]),(0,n.useEffect)(()=>{if(c){let e=new Set;c.forEach((l,t)=>{let s=l.team_id;e.add(s)}),F(e)}},[c]);let R=e=>{console.log("handleEditClick:",e),null==e.token&&null!==e.token_id&&(e.token=e.token_id),I(e),v(!0)},M=async e=>{if(null==s)return;let l=e.token;e.key=l,console.log("handleEditSubmit:",e);let t=await L(s,e);console.log("handleEditSubmit: newKeyValues",t),o&&i(o.map(e=>e.token===l?t:e)),u.ZP.success("Key updated successfully"),v(!1),I(null)},U=async e=>{console.log("handleDelete:",e),null==e.token&&null!==e.token_id&&(e.token=e.token_id),null!=o&&(j(e.token),localStorage.removeItem("userData"+l),x(!0))},D=async()=>{if(null!=p&&null!=o){try{await y(s,p);let e=o.filter(e=>e.token!==p);i(e)}catch(e){console.error("Error deleting the key:",e)}x(!1),j(null)}};if(null!=o)return console.log("RERENDER TRIGGERED"),(0,a.jsxs)("div",{children:[(0,a.jsxs)(ep.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh] mb-4 mt-2",children:[(0,a.jsxs)(eg.Z,{className:"mt-5 max-h-[300px] min-h-[300px]",children:[(0,a.jsx)(eZ.Z,{children:(0,a.jsxs)(ew.Z,{children:[(0,a.jsx)(e_.Z,{children:"Key Alias"}),(0,a.jsx)(e_.Z,{children:"Secret Key"}),(0,a.jsx)(e_.Z,{children:"Spend (USD)"}),(0,a.jsx)(e_.Z,{children:"Budget (USD)"}),(0,a.jsx)(e_.Z,{children:"Models"}),(0,a.jsx)(e_.Z,{children:"TPM / RPM Limits"})]})}),(0,a.jsx)(ey.Z,{children:o.map(e=>{if(console.log(e),"litellm-dashboard"===e.team_id)return null;if(r){if(console.log("item team id: ".concat(e.team_id,", knownTeamIDs.has(item.team_id): ").concat(O.has(e.team_id),", selectedTeam id: ").concat(r.team_id)),(null!=r.team_id||null===e.team_id||O.has(e.team_id))&&e.team_id!=r.team_id)return null;console.log("item team id: ".concat(e.team_id,", is returned"))}return(0,a.jsxs)(ew.Z,{children:[(0,a.jsx)(ef.Z,{style:{maxWidth:"2px",whiteSpace:"pre-wrap",overflow:"hidden"},children:null!=e.key_alias?(0,a.jsx)(ee.Z,{children:e.key_alias}):(0,a.jsx)(ee.Z,{children:"Not Set"})}),(0,a.jsx)(ef.Z,{children:(0,a.jsx)(ee.Z,{children:e.key_name})}),(0,a.jsx)(ef.Z,{children:(0,a.jsx)(ee.Z,{children:(()=>{try{return parseFloat(e.spend).toFixed(4)}catch(l){return e.spend}})()})}),(0,a.jsx)(ef.Z,{children:null!=e.max_budget?(0,a.jsx)(ee.Z,{children:e.max_budget}):(0,a.jsx)(ee.Z,{children:"Unlimited"})}),(0,a.jsx)(ef.Z,{children:Array.isArray(e.models)?(0,a.jsx)("div",{style:{display:"flex",flexDirection:"column"},children:0===e.models.length?(0,a.jsx)(a.Fragment,{children:r&&r.models&&r.models.length>0?r.models.map((e,l)=>"all-proxy-models"===e?(0,a.jsx)(ex.Z,{size:"xs",className:"mb-1",color:"red",children:(0,a.jsx)(ee.Z,{children:"All Proxy Models"})},l):"all-team-models"===e?(0,a.jsx)(ex.Z,{size:"xs",className:"mb-1",color:"red",children:(0,a.jsx)(ee.Z,{children:"All Team Models"})},l):(0,a.jsx)(ex.Z,{size:"xs",className:"mb-1",color:"blue",children:(0,a.jsx)(ee.Z,{children:e.length>30?"".concat(e.slice(0,30),"..."):e})},l)):(0,a.jsx)(ex.Z,{size:"xs",className:"mb-1",color:"blue",children:(0,a.jsx)(ee.Z,{children:"all-proxy-models"})})}):e.models.map((e,l)=>"all-proxy-models"===e?(0,a.jsx)(ex.Z,{size:"xs",className:"mb-1",color:"red",children:(0,a.jsx)(ee.Z,{children:"All Proxy Models"})},l):"all-team-models"===e?(0,a.jsx)(ex.Z,{size:"xs",className:"mb-1",color:"red",children:(0,a.jsx)(ee.Z,{children:"All Team Models"})},l):(0,a.jsx)(ex.Z,{size:"xs",className:"mb-1",color:"blue",children:(0,a.jsx)(ee.Z,{children:e.length>30?"".concat(e.slice(0,30),"..."):e})},l))}):null}),(0,a.jsx)(ef.Z,{children:(0,a.jsxs)(ee.Z,{children:["TPM: ",e.tpm_limit?e.tpm_limit:"Unlimited"," ",(0,a.jsx)("br",{})," RPM:"," ",e.rpm_limit?e.rpm_limit:"Unlimited"]})}),(0,a.jsxs)(ef.Z,{children:[(0,a.jsx)(ej.Z,{onClick:()=>{I(e),N(!0)},icon:em.Z,size:"sm"}),(0,a.jsx)(ea.Z,{open:S,onCancel:()=>{N(!1),I(null)},footer:null,width:800,children:E&&(0,a.jsxs)(a.Fragment,{children:[(0,a.jsxs)("div",{className:"grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3 mt-8",children:[(0,a.jsxs)(ep.Z,{children:[(0,a.jsx)("p",{className:"text-tremor-default font-medium text-tremor-content dark:text-dark-tremor-content",children:"Spend"}),(0,a.jsx)("div",{className:"mt-2 flex items-baseline space-x-2.5",children:(0,a.jsx)("p",{className:"text-tremor font-semibold text-tremor-content-strong dark:text-dark-tremor-content-strong",children:(()=>{try{return parseFloat(E.spend).toFixed(4)}catch(e){return E.spend}})()})})]}),(0,a.jsxs)(ep.Z,{children:[(0,a.jsx)("p",{className:"text-tremor-default font-medium text-tremor-content dark:text-dark-tremor-content",children:"Budget"}),(0,a.jsx)("div",{className:"mt-2 flex items-baseline space-x-2.5",children:(0,a.jsx)("p",{className:"text-tremor font-semibold text-tremor-content-strong dark:text-dark-tremor-content-strong",children:null!=E.max_budget?(0,a.jsx)(a.Fragment,{children:E.max_budget}):(0,a.jsx)(a.Fragment,{children:"Unlimited"})})})]},e.name),(0,a.jsxs)(ep.Z,{children:[(0,a.jsx)("p",{className:"text-tremor-default font-medium text-tremor-content dark:text-dark-tremor-content",children:"Expires"}),(0,a.jsx)("div",{className:"mt-2 flex items-baseline space-x-2.5",children:(0,a.jsx)("p",{className:"text-tremor-default font-small text-tremor-content-strong dark:text-dark-tremor-content-strong",children:null!=E.expires?(0,a.jsx)(a.Fragment,{children:new Date(E.expires).toLocaleString(void 0,{day:"numeric",month:"long",year:"numeric",hour:"numeric",minute:"numeric",second:"numeric"})}):(0,a.jsx)(a.Fragment,{children:"Never"})})})]},e.name)]}),(0,a.jsxs)(ep.Z,{className:"my-4",children:[(0,a.jsx)(el.Z,{children:"Token Name"}),(0,a.jsx)(ee.Z,{className:"my-1",children:E.key_alias?E.key_alias:E.key_name}),(0,a.jsx)(el.Z,{children:"Token ID"}),(0,a.jsx)(ee.Z,{className:"my-1 text-[12px]",children:E.token}),(0,a.jsx)(el.Z,{children:"Metadata"}),(0,a.jsx)(ee.Z,{className:"my-1",children:(0,a.jsxs)("pre",{children:[JSON.stringify(E.metadata)," "]})})]}),(0,a.jsx)(J.Z,{className:"mx-auto flex items-center",onClick:()=>{N(!1),I(null)},children:"Close"})]})}),(0,a.jsx)(ej.Z,{icon:eu.Z,size:"sm",onClick:()=>R(e)}),(0,a.jsx)(ej.Z,{onClick:()=>U(e),icon:eh.Z,size:"sm"})]})]},e.token)})})]}),h&&(0,a.jsx)("div",{className:"fixed z-10 inset-0 overflow-y-auto",children:(0,a.jsxs)("div",{className:"flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0",children:[(0,a.jsx)("div",{className:"fixed inset-0 transition-opacity","aria-hidden":"true",children:(0,a.jsx)("div",{className:"absolute inset-0 bg-gray-500 opacity-75"})}),(0,a.jsx)("span",{className:"hidden sm:inline-block sm:align-middle sm:h-screen","aria-hidden":"true",children:"โ€‹"}),(0,a.jsxs)("div",{className:"inline-block align-bottom bg-white rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full",children:[(0,a.jsx)("div",{className:"bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4",children:(0,a.jsx)("div",{className:"sm:flex sm:items-start",children:(0,a.jsxs)("div",{className:"mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left",children:[(0,a.jsx)("h3",{className:"text-lg leading-6 font-medium text-gray-900",children:"Delete Key"}),(0,a.jsx)("div",{className:"mt-2",children:(0,a.jsx)("p",{className:"text-sm text-gray-500",children:"Are you sure you want to delete this key ?"})})]})})}),(0,a.jsxs)("div",{className:"bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse",children:[(0,a.jsx)(J.Z,{onClick:D,color:"red",className:"ml-2",children:"Delete"}),(0,a.jsx)(J.Z,{onClick:()=>{x(!1),j(null)},children:"Cancel"})]})]})]})})]}),E&&(0,a.jsx)(e=>{let{visible:l,onCancel:t,token:s,onSubmit:o}=e,[i]=er.Z.useForm(),[d,m]=(0,n.useState)(r),[u,h]=(0,n.useState)([]),[x,p]=(0,n.useState)(!1);return(0,a.jsx)(ea.Z,{title:"Edit Key",visible:l,width:800,footer:null,onOk:()=>{i.validateFields().then(e=>{i.resetFields()}).catch(e=>{console.error("Validation failed:",e)})},onCancel:t,children:(0,a.jsxs)(er.Z,{form:i,onFinish:M,initialValues:s,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(er.Z.Item,{label:"Key Name",name:"key_alias",rules:[{required:!0,message:"Please input a key name"}],help:"required",children:(0,a.jsx)(en.Z,{})}),(0,a.jsx)(er.Z.Item,{label:"Models",name:"models",rules:[{validator:(e,l)=>{let t=l.filter(e=>!d.models.includes(e)&&"all-team-models"!==e&&"all-proxy-models"!==e&&!d.models.includes("all-proxy-models"));return(console.log("errorModels: ".concat(t)),t.length>0)?Promise.reject("Some models are not part of the new team's models - ".concat(t,"Team models: ").concat(d.models)):Promise.resolve()}}],children:(0,a.jsxs)(es.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:[(0,a.jsx)(ev,{value:"all-team-models",children:"All Team Models"},"all-team-models"),d&&d.models?d.models.includes("all-proxy-models")?C.filter(e=>"all-proxy-models"!==e).map(e=>(0,a.jsx)(ev,{value:e,children:e},e)):d.models.map(e=>(0,a.jsx)(ev,{value:e,children:e},e)):C.map(e=>(0,a.jsx)(ev,{value:e,children:e},e))]})}),(0,a.jsx)(er.Z.Item,{className:"mt-8",label:"Max Budget (USD)",name:"max_budget",help:"Budget cannot exceed team max budget: ".concat((null==d?void 0:d.max_budget)!==null&&(null==d?void 0:d.max_budget)!==void 0?null==d?void 0:d.max_budget:"unlimited"),rules:[{validator:async(e,l)=>{if(l&&d&&null!==d.max_budget&&l>d.max_budget)throw console.log("keyTeam.max_budget: ".concat(d.max_budget)),Error("Budget cannot exceed team max budget: $".concat(d.max_budget))}}],children:(0,a.jsx)(eo.Z,{step:.01,precision:2,width:200})}),(0,a.jsx)(er.Z.Item,{label:"token",name:"token",hidden:!0}),(0,a.jsx)(er.Z.Item,{label:"Team",name:"team_id",help:"the team this key belongs to",children:(0,a.jsx)(eb.Z,{value:s.team_alias,children:null==c?void 0:c.map((e,l)=>(0,a.jsx)(ek.Z,{value:e.team_id,onClick:()=>m(e),children:e.team_alias},l))})})]}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(ei.ZP,{htmlType:"submit",children:"Edit Key"})})]})})},{visible:k,onCancel:()=>{v(!1),I(null)},token:E,onSubmit:M})]})},eA=t(76032),eN=t(35152),eE=e=>{let{userID:l,userRole:t,accessToken:s,userSpend:r,selectedTeam:o}=e;console.log("userSpend: ".concat(r));let[i,c]=(0,n.useState)(null!==r?r:0),[d,m]=(0,n.useState)(0),[u,h]=(0,n.useState)([]);(0,n.useEffect)(()=>{let e=async()=>{if(s&&l&&t&&"Admin"===t&&null==r)try{let e=await w(s);e&&(e.spend?c(e.spend):c(0),e.max_budget?m(e.max_budget):m(0))}catch(e){console.error("Error fetching global spend data:",e)}};(async()=>{try{if(null===l||null===t)return;if(null!==s){let e=(await A(s,l,t)).data.map(e=>e.id);console.log("available_model_names:",e),h(e)}}catch(e){console.error("Error fetching user models:",e)}})(),e()},[t,s,l]),(0,n.useEffect)(()=>{null!==r&&c(r)},[r]);let x=[];o&&o.models&&(x=o.models),x&&x.includes("all-proxy-models")?(console.log("user models:",u),x=u):x&&x.includes("all-team-models")?x=o.models:x&&0===x.length&&(x=u);let p=void 0!==i?i.toFixed(4):null;return console.log("spend in view user spend: ".concat(i)),(0,a.jsxs)("div",{className:"flex items-center",children:[(0,a.jsxs)("div",{children:[(0,a.jsxs)("p",{className:"text-tremor-default text-tremor-content dark:text-dark-tremor-content",children:["Total Spend"," "]}),(0,a.jsxs)("p",{className:"text-2xl text-tremor-content-strong dark:text-dark-tremor-content-strong font-semibold",children:["$",p]})]}),(0,a.jsx)("div",{className:"ml-auto",children:(0,a.jsxs)($.Z,{children:[(0,a.jsx)(Q.Z,{children:(0,a.jsx)(ee.Z,{children:"Team Models"})}),(0,a.jsx)(X.Z,{className:"absolute right-0 z-10 bg-white p-2 shadow-lg max-w-xs",children:(0,a.jsx)(eA.Z,{children:x.map(e=>(0,a.jsx)(eN.Z,{children:(0,a.jsx)(ee.Z,{children:e})},e))})})]})})]})},eI=e=>{let{userID:l,userRole:t,selectedTeam:s,accessToken:r}=e,[o,i]=(0,n.useState)([]);(0,n.useEffect)(()=>{(async()=>{try{if(null===l||null===t)return;if(null!==r){let e=(await A(r,l,t)).data.map(e=>e.id);console.log("available_model_names:",e),i(e)}}catch(e){console.error("Error fetching user models:",e)}})()},[r,l,t]);let c=[];return s&&s.models&&(c=s.models),c&&c.includes("all-proxy-models")&&(console.log("user models:",o),c=o),(0,a.jsx)(a.Fragment,{children:(0,a.jsx)("div",{className:"mb-5",children:(0,a.jsx)("p",{className:"text-3xl text-tremor-content-strong dark:text-dark-tremor-content-strong font-semibold",children:null==s?void 0:s.team_alias})})})},eC=e=>{let l,{teams:t,setSelectedTeam:s,userRole:r}=e,o={models:[],team_id:null,team_alias:"Default Team"},[i,c]=(0,n.useState)(o);return(l="App User"===r?t:t?[...t,o]:[o],"App User"===r)?null:(0,a.jsxs)("div",{className:"mt-5 mb-5",children:[(0,a.jsx)(el.Z,{children:"Select Team"}),(0,a.jsx)(ee.Z,{children:"If you belong to multiple teams, this setting controls which team is used by default when creating new API Keys."}),(0,a.jsxs)(ee.Z,{className:"mt-3 mb-3",children:[(0,a.jsx)("b",{children:"Default Team:"})," If no team_id is set for a key, it will be grouped under here."]}),l&&l.length>0?(0,a.jsx)(eb.Z,{defaultValue:"0",children:l.map((e,l)=>(0,a.jsx)(ek.Z,{value:String(l),onClick:()=>s(e),children:e.team_alias},l))}):(0,a.jsxs)(ee.Z,{children:["No team created. ",(0,a.jsx)("b",{children:"Defaulting to personal account."})]})]})},eP=t(37963),eT=t(36083);console.log("isLocal:",!1);var eO=e=>{let{userID:l,userRole:t,teams:s,keys:r,setUserRole:i,userEmail:c,setUserEmail:d,setTeams:m,setKeys:u}=e,[h,x]=(0,n.useState)(null),p=(0,o.useSearchParams)();p.get("viewSpend"),(0,o.useRouter)();let j=p.get("token"),[g,y]=(0,n.useState)(null),[f,_]=(0,n.useState)(null),[b,k]=(0,n.useState)([]),v={models:[],team_alias:"Default Team",team_id:null},[S,N]=(0,n.useState)(s?s[0]:v);if(window.addEventListener("beforeunload",function(){sessionStorage.clear()}),(0,n.useEffect)(()=>{if(j){let e=(0,eP.o)(j);if(e){if(console.log("Decoded token:",e),console.log("Decoded key:",e.key),y(e.key),e.user_role){let l=function(e){if(!e)return"Undefined Role";switch(console.log("Received user role: ".concat(e)),e.toLowerCase()){case"app_owner":case"demo_app_owner":return"App Owner";case"app_admin":case"proxy_admin":return"Admin";case"proxy_admin_viewer":return"Admin Viewer";case"app_user":return"App User";default:return"Unknown Role"}}(e.user_role);console.log("Decoded user_role:",l),i(l)}else console.log("User role not defined");e.user_email?d(e.user_email):console.log("User Email is not set ".concat(e))}}if(l&&g&&t&&!r&&!h){let e=sessionStorage.getItem("userModels"+l);e?k(JSON.parse(e)):(async()=>{try{let e=await Z(g,l,t,!1,null,null);if(console.log("received teams in user dashboard: ".concat(Object.keys(e),"; team values: ").concat(Object.entries(e.teams))),"Admin"==t){let e=await w(g);x(e),console.log("globalSpend:",e)}else x(e.user_info);u(e.keys),m(e.teams);let s=[...e.teams];s.length>0?(console.log("response['teams']: ".concat(s)),N(s[0])):N(v),sessionStorage.setItem("userData"+l,JSON.stringify(e.keys)),sessionStorage.setItem("userSpendData"+l,JSON.stringify(e.user_info));let r=(await A(g,l,t)).data.map(e=>e.id);console.log("available_model_names:",r),k(r),console.log("userModels:",b),sessionStorage.setItem("userModels"+l,JSON.stringify(r))}catch(e){console.error("There was an error fetching the data",e)}})()}},[l,j,g,r,t]),(0,n.useEffect)(()=>{if(null!==r&&null!=S){let e=0;for(let l of r)S.hasOwnProperty("team_id")&&null!==l.team_id&&l.team_id===S.team_id&&(e+=l.spend);_(e)}else if(null!==r){let e=0;for(let l of r)e+=l.spend;_(e)}},[S]),null==l||null==j){let e="/sso/key/generate";return console.log("Full URL:",e),window.location.href=e,null}if(null==g)return null;if(null==t&&i("App Owner"),t&&"Admin Viewer"==t){let{Title:e,Paragraph:l}=eT.default;return(0,a.jsxs)("div",{children:[(0,a.jsx)(e,{level:1,children:"Access Denied"}),(0,a.jsx)(l,{children:"Ask your proxy admin for access to create keys"})]})}return console.log("inside user dashboard, selected team",S),console.log("teamSpend: ".concat(f)),(0,a.jsx)("div",{className:"w-full mx-4",children:(0,a.jsx)(W.Z,{numItems:1,className:"gap-2 p-8 h-[75vh] w-full mt-2",children:(0,a.jsxs)(Y.Z,{numColSpan:1,children:[(0,a.jsx)(eI,{userID:l,userRole:t,selectedTeam:S||null,accessToken:g}),(0,a.jsx)(eE,{userID:l,userRole:t,accessToken:g,userSpend:f,selectedTeam:S||null}),(0,a.jsx)(eS,{userID:l,userRole:t,accessToken:g,selectedTeam:S||null,data:r,setData:u,teams:s}),(0,a.jsx)(ed,{userID:l,team:S||null,userRole:t,accessToken:g,data:r,setData:u},S?S.team_id:null),(0,a.jsx)(eC,{teams:s,setSelectedTeam:N,userRole:t})]})})})},eF=t(35087),eR=t(92836),eM=t(26734),eL=t(41608),eU=t(32126),eD=t(23682),eK=t(47047),eB=t(76628),ez=t(57750),eq=t(44041),eV=t(38302),eG=t(28683),eY=t(1460),eW=t(78578),eJ=t(63954),eH=t(90252),e$=t(7905),eX=e=>{let{modelID:l,accessToken:t}=e,[s,r]=(0,n.useState)(!1),o=async()=>{try{u.ZP.info("Making API Call"),r(!0);let e=await p(t,l);console.log("model delete Response:",e),u.ZP.success("Model ".concat(l," deleted successfully")),r(!1)}catch(e){console.error("Error deleting the model:",e)}};return(0,a.jsxs)("div",{children:[(0,a.jsx)(ej.Z,{onClick:()=>r(!0),icon:eh.Z,size:"sm"}),(0,a.jsx)(ea.Z,{open:s,onOk:o,okType:"danger",onCancel:()=>r(!1),children:(0,a.jsxs)(W.Z,{numItems:1,className:"gap-2 w-full",children:[(0,a.jsx)(el.Z,{children:"Delete Model"}),(0,a.jsx)(Y.Z,{numColSpan:1,children:(0,a.jsx)("p",{children:"Are you sure you want to delete this model? This action is irreversible."})}),(0,a.jsx)(Y.Z,{numColSpan:1,children:(0,a.jsxs)("p",{children:["Model ID: ",(0,a.jsx)("b",{children:l})]})})]})})]})},eQ=t(97766),e0=t(46495);let{Title:e1,Link:e2}=eT.default;(s=r||(r={})).OpenAI="OpenAI",s.Azure="Azure",s.Anthropic="Anthropic",s.Google_AI_Studio="Gemini (Google AI Studio)",s.Bedrock="Amazon Bedrock",s.OpenAI_Compatible="OpenAI-Compatible Endpoints (Groq, Together AI, Mistral AI, etc.)",s.Vertex_AI="Vertex AI (Anthropic, Gemini, etc.)";let e4={OpenAI:"openai",Azure:"azure",Anthropic:"anthropic",Google_AI_Studio:"gemini",Bedrock:"bedrock",OpenAI_Compatible:"openai",Vertex_AI:"vertex_ai"},e8={"BadRequestError (400)":"BadRequestErrorRetries","AuthenticationError (401)":"AuthenticationErrorRetries","TimeoutError (408)":"TimeoutErrorRetries","RateLimitError (429)":"RateLimitErrorRetries","ContentPolicyViolationError (400)":"ContentPolicyViolationErrorRetries","InternalServerError (500)":"InternalServerErrorRetries"},e5=async(e,l,t)=>{try{let s=Array.isArray(e.model)?e.model:[e.model];console.log("received deployments: ".concat(s)),console.log("received type of deployments: ".concat(typeof s)),s.forEach(async t=>{console.log("litellm_model: ".concat(t));let s={},r={};s.model=t;let a="";for(let[l,t]of Object.entries(e))if(""!==t){if("model_name"==l)a+=t;else if("custom_llm_provider"==l)continue;else if("model"==l)continue;else if("base_model"===l)r[l]=t;else if("litellm_extra_params"==l){console.log("litellm_extra_params:",t);let e={};if(t&&void 0!=t){try{e=JSON.parse(t)}catch(e){throw u.ZP.error("Failed to parse LiteLLM Extra Params: "+e,10),Error("Failed to parse litellm_extra_params: "+e)}for(let[l,t]of Object.entries(e))s[l]=t}}else s[l]=t}let n={model_name:a,litellm_params:s,model_info:r},o=await x(l,n);console.log("response for model create call: ".concat(o.data))}),t.resetFields()}catch(e){u.ZP.error("Failed to create model: "+e,10)}};var e3=e=>{var l,t,s;let{accessToken:o,token:i,userRole:c,userID:d,modelData:m={data:[]},setModelData:x}=e,[p,j]=(0,n.useState)([]),[g]=er.Z.useForm(),[y,f]=(0,n.useState)(null),[Z,_]=(0,n.useState)(""),[w,A]=(0,n.useState)([]),N=Object.values(r).filter(e=>isNaN(Number(e))),[E,I]=(0,n.useState)("OpenAI"),[C,P]=(0,n.useState)(""),[T,O]=(0,n.useState)(!1),[F,R]=(0,n.useState)(null),[M,L]=(0,n.useState)([]),[U,K]=(0,n.useState)(null),[B,z]=(0,n.useState)([]),[Y,et]=(0,n.useState)([]),[es,en]=(0,n.useState)([]),[ec,ed]=(0,n.useState)([]),[em,eh]=(0,n.useState)([]),[ev,eS]=(0,n.useState)([]),[eA,eN]=(0,n.useState)([]),[eE,eI]=(0,n.useState)({from:new Date(Date.now()-6048e5),to:new Date}),[eC,eP]=(0,n.useState)(null),[eO,e3]=(0,n.useState)(0),e6=e=>{R(e),O(!0)},e7=async e=>{if(console.log("handleEditSubmit:",e),null==o)return;let l={},t=null;for(let[s,r]of Object.entries(e))"model_id"!==s?l[s]=r:t=r;let s={litellm_params:l,model_info:{id:t}};console.log("handleEditSubmit payload:",s);try{await D(o,s),u.ZP.success("Model updated successfully, restart server to see updates"),O(!1),R(null)}catch(e){console.log("Error occurred")}},e9=()=>{_(new Date().toLocaleString())},le=async()=>{if(!o){console.error("Access token is missing");return}console.log("new modelGroupRetryPolicy:",eC);try{await V(o,{router_settings:{model_group_retry_policy:eC}}),u.ZP.success("Retry settings saved successfully")}catch(e){console.error("Failed to save retry settings:",e),u.ZP.error("Failed to save retry settings")}};if((0,n.useEffect)(()=>{if(!o||!i||!c||!d)return;let e=async()=>{try{var e,l,t,s,r,a;let n=await b(o,d,c);console.log("Model data response:",n.data),x(n);let i=new Set;for(let e=0;e0&&(u=m[m.length-1],console.log("_initial_model_group:",u),K(u)),console.log("selectedModelGroup:",U);let h=await k(o,d,c,u,null===(e=eE.from)||void 0===e?void 0:e.toISOString(),null===(l=eE.to)||void 0===l?void 0:l.toISOString());console.log("Model metrics response:",h),et(h.data),en(h.all_api_bases);let p=await S(o,d,c,u,null===(t=eE.from)||void 0===t?void 0:t.toISOString(),null===(s=eE.to)||void 0===s?void 0:s.toISOString());console.log("Model exceptions response:",p),ed(p.data),eh(p.exception_types);let j=await v(o,d,c,u,null===(r=eE.from)||void 0===r?void 0:r.toISOString(),null===(a=eE.to)||void 0===a?void 0:a.toISOString());console.log("slowResponses:",j),eN(j);let g=(await q(o,d,c)).router_settings;console.log("routerSettingsInfo:",g);let y=g.model_group_retry_policy,f=g.num_retries;console.log("model_group_retry_policy:",y),console.log("default_retries:",f),eP(y),e3(f)}catch(e){console.error("There was an error fetching the model data",e)}};o&&i&&c&&d&&e();let l=async()=>{let e=await h();console.log("received model cost map data: ".concat(Object.keys(e))),f(e)};null==y&&l(),e9()},[o,i,c,d,y,Z]),!m||!o||!i||!c||!d)return(0,a.jsx)("div",{children:"Loading..."});let ll=[];for(let e=0;e(console.log("GET PROVIDER CALLED! - ".concat(y)),null!=y&&"object"==typeof y&&e in y)?y[e].litellm_provider:"openai";if(r){let e=r.split("/"),l=e[0];n=1===e.length?u(r):l}else n="openai";a&&(o=null==a?void 0:a.input_cost_per_token,i=null==a?void 0:a.output_cost_per_token,c=null==a?void 0:a.max_tokens),(null==s?void 0:s.litellm_params)&&(d=Object.fromEntries(Object.entries(null==s?void 0:s.litellm_params).filter(e=>{let[l]=e;return"model"!==l&&"api_base"!==l}))),m.data[e].provider=n,m.data[e].input_cost=o,m.data[e].output_cost=i,m.data[e].max_tokens=c,m.data[e].api_base=null==s?void 0:null===(t=s.litellm_params)||void 0===t?void 0:t.api_base,m.data[e].cleanedLitellmParams=d,ll.push(s.model_name),console.log(m.data[e])}if(c&&"Admin Viewer"==c){let{Title:e,Paragraph:l}=eT.default;return(0,a.jsxs)("div",{children:[(0,a.jsx)(e,{level:1,children:"Access Denied"}),(0,a.jsx)(l,{children:"Ask your proxy admin for access to view all models"})]})}let lt=e=>{console.log("received provider string: ".concat(e));let l=Object.keys(r).find(l=>r[l]===e);if(l){let e=e4[l];console.log("mappingResult: ".concat(e));let t=[];"object"==typeof y&&Object.entries(y).forEach(l=>{let[s,r]=l;null!==r&&"object"==typeof r&&"litellm_provider"in r&&(r.litellm_provider===e||r.litellm_provider.includes(e))&&t.push(s)}),A(t),console.log("providerModels: ".concat(w))}},ls=async()=>{try{u.ZP.info("Running health check..."),P("");let e=await G(o);P(e)}catch(e){console.error("Error running health check:",e),P("Error running health check")}},lr=async(e,l,t)=>{if(console.log("Updating model metrics for group:",e),o&&d&&c&&l&&t){console.log("inside updateModelMetrics - startTime:",l,"endTime:",t),K(e);try{let s=await k(o,d,c,e,l.toISOString(),t.toISOString());console.log("Model metrics response:",s),et(s.data),en(s.all_api_bases);let r=await S(o,d,c,e,l.toISOString(),t.toISOString());console.log("Model exceptions response:",r),ed(r.data),eh(r.exception_types);let a=await v(o,d,c,e,l.toISOString(),t.toISOString());console.log("slowResponses:",a),eN(a)}catch(e){console.error("Failed to fetch model metrics",e)}}};return console.log("selectedProvider: ".concat(E)),console.log("providerModels.length: ".concat(w.length)),(0,a.jsx)("div",{style:{width:"100%",height:"100%"},children:(0,a.jsxs)(eM.Z,{className:"gap-2 p-8 h-[75vh] w-full mt-2",children:[(0,a.jsxs)(eL.Z,{className:"flex justify-between mt-2 w-full items-center",children:[(0,a.jsxs)("div",{className:"flex",children:[(0,a.jsx)(eR.Z,{children:"All Models"}),(0,a.jsx)(eR.Z,{children:"Add Model"}),(0,a.jsx)(eR.Z,{children:(0,a.jsx)("pre",{children:"/health Models"})}),(0,a.jsx)(eR.Z,{children:"Model Analytics"}),(0,a.jsx)(eR.Z,{children:"Model Retry Settings"})]}),(0,a.jsxs)("div",{className:"flex items-center space-x-2",children:[Z&&(0,a.jsxs)(ee.Z,{children:["Last Refreshed: ",Z]}),(0,a.jsx)(ej.Z,{icon:eJ.Z,variant:"shadow",size:"xs",className:"self-center",onClick:e9})]})]}),(0,a.jsxs)(eD.Z,{children:[(0,a.jsxs)(eU.Z,{children:[(0,a.jsxs)(W.Z,{children:[(0,a.jsxs)("div",{className:"flex items-center",children:[(0,a.jsx)(ee.Z,{children:"Filter by Public Model Name"}),(0,a.jsxs)(eb.Z,{className:"mb-4 mt-2 ml-2 w-50",defaultValue:"all",onValueChange:e=>K("all"===e?"all":e),children:[(0,a.jsx)(ek.Z,{value:"all",children:"All Models"}),M.map((e,l)=>(0,a.jsx)(ek.Z,{value:e,onClick:()=>K(e),children:e},l))]})]}),(0,a.jsx)(ep.Z,{children:(0,a.jsxs)(eg.Z,{className:"mt-5",children:[(0,a.jsx)(eZ.Z,{children:(0,a.jsxs)(ew.Z,{children:[(0,a.jsx)(e_.Z,{children:"Public Model Name "}),(0,a.jsx)(e_.Z,{children:"Provider"}),"Admin"===c&&(0,a.jsx)(e_.Z,{children:"API Base"}),(0,a.jsx)(e_.Z,{children:"Extra litellm Params"}),(0,a.jsx)(e_.Z,{children:"Input Price per token ($)"}),(0,a.jsx)(e_.Z,{children:"Output Price per token ($)"}),(0,a.jsx)(e_.Z,{children:"Max Tokens"}),(0,a.jsx)(e_.Z,{children:"Status"})]})}),(0,a.jsx)(ey.Z,{children:m.data.filter(e=>"all"===U||e.model_name===U||null==U||""===U).map((e,l)=>(0,a.jsxs)(ew.Z,{children:[(0,a.jsx)(ef.Z,{children:(0,a.jsx)(ee.Z,{children:e.model_name})}),(0,a.jsx)(ef.Z,{children:e.provider}),"Admin"===c&&(0,a.jsx)(ef.Z,{children:e.api_base}),(0,a.jsx)(ef.Z,{children:(0,a.jsxs)($.Z,{children:[(0,a.jsx)(Q.Z,{children:(0,a.jsx)(ee.Z,{children:"Litellm params"})}),(0,a.jsx)(X.Z,{children:(0,a.jsx)("pre",{children:JSON.stringify(e.cleanedLitellmParams,null,2)})})]})}),(0,a.jsx)(ef.Z,{children:e.input_cost||e.litellm_params.input_cost_per_token||null}),(0,a.jsx)(ef.Z,{children:e.output_cost||e.litellm_params.output_cost_per_token||null}),(0,a.jsx)(ef.Z,{children:e.max_tokens}),(0,a.jsx)(ef.Z,{children:e.model_info.db_model?(0,a.jsx)(ex.Z,{icon:eH.Z,className:"text-white",children:"DB Model"}):(0,a.jsx)(ex.Z,{icon:e$.Z,className:"text-black",children:"Config Model"})}),(0,a.jsxs)(ef.Z,{children:[(0,a.jsx)(ej.Z,{icon:eu.Z,size:"sm",onClick:()=>e6(e)}),(0,a.jsx)(eX,{modelID:e.model_info.id,accessToken:o})]})]},l))})]})})]}),(0,a.jsx)(e=>{let{visible:l,onCancel:t,model:s,onSubmit:r}=e,[n]=er.Z.useForm(),o={},i="",c="";if(s){o=s.litellm_params,i=s.model_name;let e=s.model_info;e&&(c=e.id,console.log("model_id: ".concat(c)),o.model_id=c)}return(0,a.jsx)(ea.Z,{title:"Edit Model "+i,visible:l,width:800,footer:null,onOk:()=>{n.validateFields().then(e=>{r(e),n.resetFields()}).catch(e=>{console.error("Validation failed:",e)})},onCancel:t,children:(0,a.jsxs)(er.Z,{form:n,onFinish:e7,initialValues:o,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(er.Z.Item,{className:"mt-8",label:"api_base",name:"api_base",children:(0,a.jsx)(H.Z,{})}),(0,a.jsx)(er.Z.Item,{label:"tpm",name:"tpm",tooltip:"int (optional) - Tokens limit for this deployment: in tokens per minute (tpm). Find this information on your model/providers website",children:(0,a.jsx)(eo.Z,{min:0,step:1})}),(0,a.jsx)(er.Z.Item,{label:"rpm",name:"rpm",tooltip:"int (optional) - Rate limit for this deployment: in requests per minute (rpm). Find this information on your model/providers website",children:(0,a.jsx)(eo.Z,{min:0,step:1})}),(0,a.jsx)(er.Z.Item,{label:"max_retries",name:"max_retries",children:(0,a.jsx)(eo.Z,{min:0,step:1})}),(0,a.jsx)(er.Z.Item,{label:"timeout",name:"timeout",tooltip:"int (optional) - Timeout in seconds for LLM requests (Defaults to 600 seconds)",children:(0,a.jsx)(eo.Z,{min:0,step:1})}),(0,a.jsx)(er.Z.Item,{label:"stream_timeout",name:"stream_timeout",tooltip:"int (optional) - Timeout for stream requests (seconds)",children:(0,a.jsx)(eo.Z,{min:0,step:1})}),(0,a.jsx)(er.Z.Item,{label:"input_cost_per_token",name:"input_cost_per_token",tooltip:"float (optional) - Input cost per token",children:(0,a.jsx)(eo.Z,{min:0,step:1e-4})}),(0,a.jsx)(er.Z.Item,{label:"output_cost_per_token",name:"output_cost_per_token",tooltip:"float (optional) - Output cost per token",children:(0,a.jsx)(eo.Z,{min:0,step:1e-4})}),(0,a.jsx)(er.Z.Item,{label:"model_id",name:"model_id",hidden:!0})]}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(ei.ZP,{htmlType:"submit",children:"Save"})})]})})},{visible:T,onCancel:()=>{O(!1),R(null)},model:F,onSubmit:e7})]}),(0,a.jsxs)(eU.Z,{className:"h-full",children:[(0,a.jsx)(e1,{level:2,children:"Add new model"}),(0,a.jsx)(ep.Z,{children:(0,a.jsxs)(er.Z,{form:g,onFinish:()=>{g.validateFields().then(e=>{e5(e,o,g)}).catch(e=>{console.error("Validation failed:",e)})},labelCol:{span:10},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(er.Z.Item,{rules:[{required:!0,message:"Required"}],label:"Provider:",name:"custom_llm_provider",tooltip:"E.g. OpenAI, Azure OpenAI, Anthropic, Bedrock, etc.",labelCol:{span:10},labelAlign:"left",children:(0,a.jsx)(eb.Z,{value:E.toString(),children:N.map((e,l)=>(0,a.jsx)(ek.Z,{value:e,onClick:()=>{lt(e),I(e)},children:e},l))})}),(0,a.jsx)(er.Z.Item,{rules:[{required:!0,message:"Required"}],label:"Public Model Name",name:"model_name",tooltip:"Model name your users will pass in. Also used for load-balancing, LiteLLM will load balance between all models with this public name.",className:"mb-0",children:(0,a.jsx)(H.Z,{placeholder:"Vertex AI (Anthropic, Gemini, etc.)"===(s=E.toString())?"gemini-pro":"Anthropic"==s?"claude-3-opus":"Amazon Bedrock"==s?"claude-3-opus":"Gemini (Google AI Studio)"==s?"gemini-pro":"gpt-3.5-turbo"})}),(0,a.jsxs)(eV.Z,{children:[(0,a.jsx)(eG.Z,{span:10}),(0,a.jsx)(eG.Z,{span:10,children:(0,a.jsx)(ee.Z,{className:"mb-3 mt-1",children:"Model name your users will pass in."})})]}),(0,a.jsx)(er.Z.Item,{rules:[{required:!0,message:"Required"}],label:"LiteLLM Model Name(s)",name:"model",tooltip:"Actual model name used for making litellm.completion() call.",className:"mb-0",children:"Azure"===E?(0,a.jsx)(H.Z,{placeholder:"Enter model name"}):w.length>0?(0,a.jsx)(eK.Z,{value:w,children:w.map((e,l)=>(0,a.jsx)(eB.Z,{value:e,children:e},l))}):(0,a.jsx)(H.Z,{placeholder:"gpt-3.5-turbo-0125"})}),(0,a.jsxs)(eV.Z,{children:[(0,a.jsx)(eG.Z,{span:10}),(0,a.jsx)(eG.Z,{span:10,children:(0,a.jsxs)(ee.Z,{className:"mb-3 mt-1",children:["Actual model name used for making ",(0,a.jsx)(e2,{href:"https://docs.litellm.ai/docs/providers",target:"_blank",children:"litellm.completion() call"}),". We'll ",(0,a.jsx)(e2,{href:"https://docs.litellm.ai/docs/proxy/reliability#step-1---set-deployments-on-config",target:"_blank",children:"loadbalance"})," models with the same 'public name'"]})})]}),"Amazon Bedrock"!=E&&"Vertex AI (Anthropic, Gemini, etc.)"!=E&&(0,a.jsx)(er.Z.Item,{rules:[{required:!0,message:"Required"}],label:"API Key",name:"api_key",children:(0,a.jsx)(H.Z,{placeholder:"sk-",type:"password"})}),"OpenAI"==E&&(0,a.jsx)(er.Z.Item,{label:"Organization ID",name:"organization_id",children:(0,a.jsx)(H.Z,{placeholder:"[OPTIONAL] my-unique-org"})}),"Vertex AI (Anthropic, Gemini, etc.)"==E&&(0,a.jsx)(er.Z.Item,{rules:[{required:!0,message:"Required"}],label:"Vertex Project",name:"vertex_project",children:(0,a.jsx)(H.Z,{placeholder:"adroit-cadet-1234.."})}),"Vertex AI (Anthropic, Gemini, etc.)"==E&&(0,a.jsx)(er.Z.Item,{rules:[{required:!0,message:"Required"}],label:"Vertex Location",name:"vertex_location",children:(0,a.jsx)(H.Z,{placeholder:"us-east-1"})}),"Vertex AI (Anthropic, Gemini, etc.)"==E&&(0,a.jsx)(er.Z.Item,{rules:[{required:!0,message:"Required"}],label:"Vertex Credentials",name:"vertex_credentials",className:"mb-0",children:(0,a.jsx)(e0.Z,{name:"file",accept:".json",beforeUpload:e=>{if("application/json"===e.type){let l=new FileReader;l.onload=e=>{if(e.target){let l=e.target.result;g.setFieldsValue({vertex_credentials:l})}},l.readAsText(e)}return!1},onChange(e){"uploading"!==e.file.status&&console.log(e.file,e.fileList),"done"===e.file.status?u.ZP.success("".concat(e.file.name," file uploaded successfully")):"error"===e.file.status&&u.ZP.error("".concat(e.file.name," file upload failed."))},children:(0,a.jsx)(ei.ZP,{icon:(0,a.jsx)(eQ.Z,{}),children:"Click to Upload"})})}),"Vertex AI (Anthropic, Gemini, etc.)"==E&&(0,a.jsxs)(eV.Z,{children:[(0,a.jsx)(eG.Z,{span:10}),(0,a.jsx)(eG.Z,{span:10,children:(0,a.jsx)(ee.Z,{className:"mb-3 mt-1",children:"Give litellm a gcp service account(.json file), so it can make the relevant calls"})})]}),("Azure"==E||"OpenAI-Compatible Endpoints (Groq, Together AI, Mistral AI, etc.)"==E)&&(0,a.jsx)(er.Z.Item,{rules:[{required:!0,message:"Required"}],label:"API Base",name:"api_base",children:(0,a.jsx)(H.Z,{placeholder:"https://..."})}),"Azure"==E&&(0,a.jsx)(er.Z.Item,{rules:[{required:!0,message:"Required"}],label:"API Version",name:"api_version",children:(0,a.jsx)(H.Z,{placeholder:"2023-07-01-preview"})}),"Azure"==E&&(0,a.jsxs)(er.Z.Item,{label:"Base Model",name:"base_model",children:[(0,a.jsx)(H.Z,{placeholder:"azure/gpt-3.5-turbo"}),(0,a.jsxs)(ee.Z,{children:["The actual model your azure deployment uses. Used for accurate cost tracking. Select name from ",(0,a.jsx)(e2,{href:"https://github.com/BerriAI/litellm/blob/main/model_prices_and_context_window.json",target:"_blank",children:"here"})]})]}),"Amazon Bedrock"==E&&(0,a.jsx)(er.Z.Item,{rules:[{required:!0,message:"Required"}],label:"AWS Access Key ID",name:"aws_access_key_id",tooltip:"You can provide the raw key or the environment variable (e.g. `os.environ/MY_SECRET_KEY`).",children:(0,a.jsx)(H.Z,{placeholder:""})}),"Amazon Bedrock"==E&&(0,a.jsx)(er.Z.Item,{rules:[{required:!0,message:"Required"}],label:"AWS Secret Access Key",name:"aws_secret_access_key",tooltip:"You can provide the raw key or the environment variable (e.g. `os.environ/MY_SECRET_KEY`).",children:(0,a.jsx)(H.Z,{placeholder:""})}),"Amazon Bedrock"==E&&(0,a.jsx)(er.Z.Item,{rules:[{required:!0,message:"Required"}],label:"AWS Region Name",name:"aws_region_name",tooltip:"You can provide the raw key or the environment variable (e.g. `os.environ/MY_SECRET_KEY`).",children:(0,a.jsx)(H.Z,{placeholder:"us-east-1"})}),(0,a.jsx)(er.Z.Item,{label:"LiteLLM Params",name:"litellm_extra_params",tooltip:"Optional litellm params used for making a litellm.completion() call.",className:"mb-0",children:(0,a.jsx)(eW.Z,{rows:4,placeholder:'{ "rpm": 100, "timeout": 0, "stream_timeout": 0 }'})}),(0,a.jsxs)(eV.Z,{children:[(0,a.jsx)(eG.Z,{span:10}),(0,a.jsx)(eG.Z,{span:10,children:(0,a.jsxs)(ee.Z,{className:"mb-3 mt-1",children:["Pass JSON of litellm supported params ",(0,a.jsx)(e2,{href:"https://docs.litellm.ai/docs/completion/input",target:"_blank",children:"litellm.completion() call"})]})})]})]}),(0,a.jsx)("div",{style:{textAlign:"center",marginTop:"10px"},children:(0,a.jsx)(ei.ZP,{htmlType:"submit",children:"Add Model"})}),(0,a.jsx)(eY.Z,{title:"Get help on our github",children:(0,a.jsx)(eT.default.Link,{href:"https://github.com/BerriAI/litellm/issues",children:"Need Help?"})})]})})]}),(0,a.jsx)(eU.Z,{children:(0,a.jsxs)(ep.Z,{children:[(0,a.jsx)(ee.Z,{children:"`/health` will run a very small request through your models configured on litellm"}),(0,a.jsx)(J.Z,{onClick:ls,children:"Run `/health`"}),C&&(0,a.jsx)("pre",{children:JSON.stringify(C,null,2)})]})}),(0,a.jsxs)(eU.Z,{children:[(0,a.jsxs)(W.Z,{numItems:2,className:"mt-2",children:[(0,a.jsxs)(eG.Z,{children:[(0,a.jsx)(ee.Z,{children:"Select Time Range"}),(0,a.jsx)(eF.Z,{enableSelect:!0,value:eE,onValueChange:e=>{eI(e),lr(U,e.from,e.to)}})]}),(0,a.jsxs)(eG.Z,{children:[(0,a.jsx)(ee.Z,{children:"Select Model Group"}),(0,a.jsx)(eb.Z,{className:"mb-4 mt-2",defaultValue:U||M[0],value:U||M[0],children:M.map((e,l)=>(0,a.jsx)(ek.Z,{value:e,onClick:()=>lr(e,eE.from,eE.to),children:e},l))})]})]}),(0,a.jsxs)(W.Z,{numItems:2,children:[(0,a.jsx)(eG.Z,{children:(0,a.jsxs)(ep.Z,{className:"mr-2 max-h-[400px] min-h-[400px]",children:[(0,a.jsx)(el.Z,{children:"Avg Latency per Token"}),(0,a.jsx)("p",{className:"text-gray-500 italic",children:" (seconds/token)"}),(0,a.jsx)(ee.Z,{className:"text-gray-500 italic mt-1 mb-1",children:"average Latency for successfull requests divided by the total tokens"}),Y&&es&&(0,a.jsx)(ez.Z,{title:"Model Latency",className:"h-72",data:Y,showLegend:!1,index:"date",categories:es,connectNulls:!0,customTooltip:e=>{var l,t;let{payload:s,active:r}=e;if(!r||!s)return null;let n=null===(t=s[0])||void 0===t?void 0:null===(l=t.payload)||void 0===l?void 0:l.date,o=s.sort((e,l)=>l.value-e.value);if(o.length>5){let e=o.length-5;(o=o.slice(0,5)).push({dataKey:"".concat(e," other deployments"),value:s.slice(5).reduce((e,l)=>e+l.value,0),color:"gray"})}return(0,a.jsxs)("div",{className:"w-150 rounded-tremor-default border border-tremor-border bg-tremor-background p-2 text-tremor-default shadow-tremor-dropdown",children:[n&&(0,a.jsxs)("p",{className:"text-tremor-content-emphasis mb-2",children:["Date: ",n]}),o.map((e,l)=>{let t=parseFloat(e.value.toFixed(5)),s=0===t&&e.value>0?"<0.00001":t.toFixed(5);return(0,a.jsxs)("div",{className:"flex justify-between",children:[(0,a.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,a.jsx)("div",{className:"w-2 h-2 mt-1 rounded-full bg-".concat(e.color,"-500")}),(0,a.jsx)("p",{className:"text-tremor-content",children:e.dataKey})]}),(0,a.jsx)("p",{className:"font-medium text-tremor-content-emphasis text-righ ml-2",children:s})]},l)})]})}})]})}),(0,a.jsx)(eG.Z,{children:(0,a.jsx)(ep.Z,{className:"ml-2 max-h-[400px] min-h-[400px] overflow-y-auto",children:(0,a.jsxs)(eg.Z,{children:[(0,a.jsx)(eZ.Z,{children:(0,a.jsxs)(ew.Z,{children:[(0,a.jsx)(e_.Z,{children:"Deployment"}),(0,a.jsx)(e_.Z,{children:"Success Responses"}),(0,a.jsxs)(e_.Z,{children:["Slow Responses ",(0,a.jsx)("p",{children:"Success Responses taking 600+s"})]})]})}),(0,a.jsx)(ey.Z,{children:eA.map((e,l)=>(0,a.jsxs)(ew.Z,{children:[(0,a.jsx)(ef.Z,{children:e.api_base}),(0,a.jsx)(ef.Z,{children:e.total_count}),(0,a.jsx)(ef.Z,{children:e.slow_count})]},l))})]})})})]}),(0,a.jsxs)(ep.Z,{className:"mt-4",children:[(0,a.jsx)(el.Z,{children:"Exceptions per Model"}),(0,a.jsx)(eq.Z,{className:"h-72",data:ec,index:"model",categories:em,stack:!0,colors:["indigo-300","rose-200","#ffcc33"],yAxisWidth:30})]})]}),(0,a.jsxs)(eU.Z,{children:[(0,a.jsxs)("div",{className:"flex items-center",children:[(0,a.jsx)(ee.Z,{children:"Filter by Public Model Name"}),(0,a.jsx)(eb.Z,{className:"mb-4 mt-2 ml-2 w-50",defaultValue:U||M[0],value:U||M[0],onValueChange:e=>K(e),children:M.map((e,l)=>(0,a.jsx)(ek.Z,{value:e,onClick:()=>K(e),children:e},l))})]}),(0,a.jsxs)(el.Z,{children:["Retry Policy for ",U]}),(0,a.jsx)(ee.Z,{className:"mb-6",children:"How many retries should be attempted based on the Exception"}),e8&&(0,a.jsx)("table",{children:(0,a.jsx)("tbody",{children:Object.entries(e8).map((e,l)=>{var t;let[s,r]=e,n=null==eC?void 0:null===(t=eC[U])||void 0===t?void 0:t[r];return null==n&&(n=eO),(0,a.jsxs)("tr",{className:"flex justify-between items-center mt-2",children:[(0,a.jsx)("td",{children:(0,a.jsx)(ee.Z,{children:s})}),(0,a.jsx)("td",{children:(0,a.jsx)(eo.Z,{className:"ml-5",value:n,min:0,step:1,onChange:e=>{eP(l=>{var t;let s=null!==(t=null==l?void 0:l[U])&&void 0!==t?t:{};return{...null!=l?l:{},[U]:{...s,[r]:e}}})}})})]},l)})})}),(0,a.jsx)(J.Z,{className:"mt-6 mr-8",onClick:le,children:"Save"})]})]})]})})};let{Option:e6}=es.default;var e7=e=>{let{userID:l,accessToken:t,teams:s}=e,[r]=er.Z.useForm(),[o,i]=(0,n.useState)(!1),[c,d]=(0,n.useState)(null),[m,h]=(0,n.useState)([]);(0,n.useEffect)(()=>{(async()=>{try{let e=await A(t,l,"any"),s=[];for(let l=0;l{i(!1),r.resetFields()},p=()=>{i(!1),d(null),r.resetFields()},j=async e=>{try{u.ZP.info("Making API Call"),i(!0),console.log("formValues in create user:",e);let s=await g(t,null,e);console.log("user create Response:",s),d(s.key),u.ZP.success("API user Created"),r.resetFields(),localStorage.removeItem("userData"+l)}catch(e){console.error("Error creating the user:",e)}};return(0,a.jsxs)("div",{children:[(0,a.jsx)(J.Z,{className:"mx-auto",onClick:()=>i(!0),children:"+ Invite User"}),(0,a.jsxs)(ea.Z,{title:"Invite User",visible:o,width:800,footer:null,onOk:x,onCancel:p,children:[(0,a.jsx)(ee.Z,{className:"mb-1",children:"Invite a user to login to the Admin UI and create Keys"}),(0,a.jsx)(ee.Z,{className:"mb-6",children:(0,a.jsx)("b",{children:"Note: SSO Setup Required for this"})}),(0,a.jsxs)(er.Z,{form:r,onFinish:j,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsx)(er.Z.Item,{label:"User Email",name:"user_email",children:(0,a.jsx)(H.Z,{placeholder:""})}),(0,a.jsx)(er.Z.Item,{label:"Team ID",name:"team_id",children:(0,a.jsx)(es.default,{placeholder:"Select Team ID",style:{width:"100%"},children:s?s.map(e=>(0,a.jsx)(e6,{value:e.team_id,children:e.team_alias},e.team_id)):(0,a.jsx)(e6,{value:null,children:"Default Team"},"default")})}),(0,a.jsx)(er.Z.Item,{label:"Metadata",name:"metadata",children:(0,a.jsx)(en.Z.TextArea,{rows:4,placeholder:"Enter metadata as JSON"})}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(ei.ZP,{htmlType:"submit",children:"Create User"})})]})]}),c&&(0,a.jsxs)(ea.Z,{title:"User Created Successfully",visible:o,onOk:x,onCancel:p,footer:null,children:[(0,a.jsx)("p",{children:"User has been created to access your proxy. Please Ask them to Log In."}),(0,a.jsx)("br",{}),(0,a.jsx)("p",{children:(0,a.jsx)("b",{children:"Note: This Feature is only supported through SSO on the Admin UI"})})]})]})},e9=e=>{let{accessToken:l,token:t,keys:s,userRole:r,userID:o,teams:i,setKeys:c}=e,[d,m]=(0,n.useState)(null),[u,h]=(0,n.useState)(null),[x,p]=(0,n.useState)(0),[j,g]=n.useState(null),[y,f]=(0,n.useState)(null);return((0,n.useEffect)(()=>{if(!l||!t||!r||!o)return;let e=async()=>{try{let e=await Z(l,null,r,!0,x,25);console.log("user data response:",e),m(e)}catch(e){console.error("There was an error fetching the model data",e)}};l&&t&&r&&o&&e()},[l,t,r,o,x]),d&&l&&t&&r&&o)?(0,a.jsx)("div",{style:{width:"100%"},children:(0,a.jsxs)(W.Z,{className:"gap-2 p-2 h-[80vh] w-full mt-8",children:[(0,a.jsx)(e7,{userID:o,accessToken:l,teams:i}),(0,a.jsxs)(ep.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[80vh] mb-4",children:[(0,a.jsx)("div",{className:"mb-4 mt-1",children:(0,a.jsx)(ee.Z,{children:"These are Users on LiteLLM that created API Keys. Automatically tracked by LiteLLM"})}),(0,a.jsx)(eM.Z,{children:(0,a.jsxs)(eD.Z,{children:[(0,a.jsx)(eU.Z,{children:(0,a.jsxs)(eg.Z,{className:"mt-5",children:[(0,a.jsx)(eZ.Z,{children:(0,a.jsxs)(ew.Z,{children:[(0,a.jsx)(e_.Z,{children:"User ID"}),(0,a.jsx)(e_.Z,{children:"User Email"}),(0,a.jsx)(e_.Z,{children:"User Models"}),(0,a.jsx)(e_.Z,{children:"User Spend ($ USD)"}),(0,a.jsx)(e_.Z,{children:"User Max Budget ($ USD)"}),(0,a.jsx)(e_.Z,{children:"User API Key Aliases"})]})}),(0,a.jsx)(ey.Z,{children:d.map(e=>{var l;return(0,a.jsxs)(ew.Z,{children:[(0,a.jsx)(ef.Z,{children:e.user_id}),(0,a.jsx)(ef.Z,{children:e.user_email}),(0,a.jsx)(ef.Z,{children:e.models&&e.models.length>0?e.models:"All Models"}),(0,a.jsx)(ef.Z,{children:e.spend?null===(l=e.spend)||void 0===l?void 0:l.toFixed(2):0}),(0,a.jsx)(ef.Z,{children:e.max_budget?e.max_budget:"Unlimited"}),(0,a.jsx)(ef.Z,{children:(0,a.jsx)(W.Z,{numItems:2,children:e&&e.key_aliases&&e.key_aliases.filter(e=>null!==e).length>0?(0,a.jsx)(ex.Z,{size:"xs",color:"indigo",children:e.key_aliases.filter(e=>null!==e).join(", ")}):(0,a.jsx)(ex.Z,{size:"xs",color:"gray",children:"No Keys"})})})]},e.user_id)})})]})}),(0,a.jsx)(eU.Z,{children:(0,a.jsxs)("div",{className:"flex items-center",children:[(0,a.jsx)("div",{className:"flex-1"}),(0,a.jsx)("div",{className:"flex-1 flex justify-between items-center"})]})})]})})]}),function(){if(!d)return null;let e=Math.ceil(d.length/25);return(0,a.jsxs)("div",{className:"flex justify-between items-center",children:[(0,a.jsxs)("div",{children:["Showing Page ",x+1," of ",e]}),(0,a.jsxs)("div",{className:"flex",children:[(0,a.jsx)("button",{className:"bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-l focus:outline-none",disabled:0===x,onClick:()=>p(x-1),children:"โ† Prev"}),(0,a.jsx)("button",{className:"bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-r focus:outline-none",onClick:()=>{p(x+1)},children:"Next โ†’"})]})]})}()]})}):(0,a.jsx)("div",{children:"Loading..."})},le=e=>{let{teams:l,searchParams:t,accessToken:s,setTeams:r,userID:o,userRole:i}=e,[c]=er.Z.useForm(),[d]=er.Z.useForm(),{Title:m,Paragraph:h}=eT.default,[x,p]=(0,n.useState)(""),[j,g]=(0,n.useState)(!1),[y,Z]=(0,n.useState)(l?l[0]:null),[w,b]=(0,n.useState)(!1),[k,v]=(0,n.useState)(!1),[S,N]=(0,n.useState)([]),[E,I]=(0,n.useState)(!1),[C,P]=(0,n.useState)(null),[T,O]=(0,n.useState)({}),F=e=>{Z(e),g(!0)},R=async e=>{let t=e.team_id;if(console.log("handleEditSubmit:",e),null==s)return;let a=await U(s,e);l&&r(l.map(e=>e.team_id===t?a.data:e)),u.ZP.success("Team updated successfully"),g(!1),Z(null)},L=async e=>{P(e),I(!0)},D=async()=>{if(null!=C&&null!=l&&null!=s){try{await f(s,C);let e=l.filter(e=>e.team_id!==C);r(e)}catch(e){console.error("Error deleting the team:",e)}I(!1),P(null)}};(0,n.useEffect)(()=>{let e=async()=>{try{if(null===o||null===i||null===s||null===l)return;console.log("fetching team info:");let e={};for(let t=0;t<(null==l?void 0:l.length);t++){let r=l[t].team_id,a=await _(s,r);console.log("teamInfo response:",a),null!==a&&(e={...e,[r]:a})}O(e)}catch(e){console.error("Error fetching team info:",e)}};(async()=>{try{if(null===o||null===i)return;if(null!==s){let e=(await A(s,o,i)).data.map(e=>e.id);console.log("available_model_names:",e),N(e)}}catch(e){console.error("Error fetching user models:",e)}})(),e()},[s,o,i,l]);let B=async e=>{try{if(null!=s){var t;let a=null==e?void 0:e.team_alias;if((null!==(t=null==l?void 0:l.map(e=>e.team_alias))&&void 0!==t?t:[]).includes(a))throw Error("Team alias ".concat(a," already exists, please pick another alias"));u.ZP.info("Creating Team");let n=await M(s,e);null!==l?r([...l,n]):r([n]),console.log("response for team create call: ".concat(n)),u.ZP.success("Team created"),b(!1)}}catch(e){console.error("Error creating the team:",e),u.ZP.error("Error creating the team: "+e,20)}},z=async e=>{try{if(null!=s&&null!=l){u.ZP.info("Adding Member");let t={role:"user",user_email:e.user_email,user_id:e.user_id},a=await K(s,y.team_id,t);console.log("response for team create call: ".concat(a.data));let n=l.findIndex(e=>(console.log("team.team_id=".concat(e.team_id,"; response.data.team_id=").concat(a.data.team_id)),e.team_id===a.data.team_id));if(console.log("foundIndex: ".concat(n)),-1!==n){let e=[...l];e[n]=a.data,r(e),Z(a.data)}v(!1)}}catch(e){console.error("Error creating the team:",e)}};return console.log("received teams ".concat(JSON.stringify(l))),(0,a.jsx)("div",{className:"w-full mx-4",children:(0,a.jsxs)(W.Z,{numItems:1,className:"gap-2 p-8 h-[75vh] w-full mt-2",children:[(0,a.jsxs)(Y.Z,{numColSpan:1,children:[(0,a.jsx)(m,{level:4,children:"All Teams"}),(0,a.jsxs)(ep.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:[(0,a.jsxs)(eg.Z,{children:[(0,a.jsx)(eZ.Z,{children:(0,a.jsxs)(ew.Z,{children:[(0,a.jsx)(e_.Z,{children:"Team Name"}),(0,a.jsx)(e_.Z,{children:"Spend (USD)"}),(0,a.jsx)(e_.Z,{children:"Budget (USD)"}),(0,a.jsx)(e_.Z,{children:"Models"}),(0,a.jsx)(e_.Z,{children:"TPM / RPM Limits"}),(0,a.jsx)(e_.Z,{children:"Info"})]})}),(0,a.jsx)(ey.Z,{children:l&&l.length>0?l.map(e=>(0,a.jsxs)(ew.Z,{children:[(0,a.jsx)(ef.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:e.team_alias}),(0,a.jsx)(ef.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:e.spend}),(0,a.jsx)(ef.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:e.max_budget?e.max_budget:"No limit"}),(0,a.jsx)(ef.Z,{style:{maxWidth:"8-x",whiteSpace:"pre-wrap",overflow:"hidden"},children:Array.isArray(e.models)?(0,a.jsx)("div",{style:{display:"flex",flexDirection:"column"},children:0===e.models.length?(0,a.jsx)(ex.Z,{size:"xs",className:"mb-1",color:"red",children:(0,a.jsx)(ee.Z,{children:"All Proxy Models"})}):e.models.map((e,l)=>"all-proxy-models"===e?(0,a.jsx)(ex.Z,{size:"xs",className:"mb-1",color:"red",children:(0,a.jsx)(ee.Z,{children:"All Proxy Models"})},l):(0,a.jsx)(ex.Z,{size:"xs",className:"mb-1",color:"blue",children:(0,a.jsx)(ee.Z,{children:e.length>30?"".concat(e.slice(0,30),"..."):e})},l))}):null}),(0,a.jsx)(ef.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,a.jsxs)(ee.Z,{children:["TPM: ",e.tpm_limit?e.tpm_limit:"Unlimited"," ",(0,a.jsx)("br",{}),"RPM:"," ",e.rpm_limit?e.rpm_limit:"Unlimited"]})}),(0,a.jsxs)(ef.Z,{children:[(0,a.jsxs)(ee.Z,{children:[T&&e.team_id&&T[e.team_id]&&T[e.team_id].keys&&T[e.team_id].keys.length," ","Keys"]}),(0,a.jsxs)(ee.Z,{children:[T&&e.team_id&&T[e.team_id]&&T[e.team_id].team_info&&T[e.team_id].team_info.members_with_roles&&T[e.team_id].team_info.members_with_roles.length," ","Members"]})]}),(0,a.jsxs)(ef.Z,{children:[(0,a.jsx)(ej.Z,{icon:eu.Z,size:"sm",onClick:()=>F(e)}),(0,a.jsx)(ej.Z,{onClick:()=>L(e.team_id),icon:eh.Z,size:"sm"})]})]},e.team_id)):null})]}),E&&(0,a.jsx)("div",{className:"fixed z-10 inset-0 overflow-y-auto",children:(0,a.jsxs)("div",{className:"flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0",children:[(0,a.jsx)("div",{className:"fixed inset-0 transition-opacity","aria-hidden":"true",children:(0,a.jsx)("div",{className:"absolute inset-0 bg-gray-500 opacity-75"})}),(0,a.jsx)("span",{className:"hidden sm:inline-block sm:align-middle sm:h-screen","aria-hidden":"true",children:"โ€‹"}),(0,a.jsxs)("div",{className:"inline-block align-bottom bg-white rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full",children:[(0,a.jsx)("div",{className:"bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4",children:(0,a.jsx)("div",{className:"sm:flex sm:items-start",children:(0,a.jsxs)("div",{className:"mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left",children:[(0,a.jsx)("h3",{className:"text-lg leading-6 font-medium text-gray-900",children:"Delete Team"}),(0,a.jsx)("div",{className:"mt-2",children:(0,a.jsx)("p",{className:"text-sm text-gray-500",children:"Are you sure you want to delete this team ?"})})]})})}),(0,a.jsxs)("div",{className:"bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse",children:[(0,a.jsx)(J.Z,{onClick:D,color:"red",className:"ml-2",children:"Delete"}),(0,a.jsx)(J.Z,{onClick:()=>{I(!1),P(null)},children:"Cancel"})]})]})]})})]})]}),(0,a.jsxs)(Y.Z,{numColSpan:1,children:[(0,a.jsx)(J.Z,{className:"mx-auto",onClick:()=>b(!0),children:"+ Create New Team"}),(0,a.jsx)(ea.Z,{title:"Create Team",visible:w,width:800,footer:null,onOk:()=>{b(!1),c.resetFields()},onCancel:()=>{b(!1),c.resetFields()},children:(0,a.jsxs)(er.Z,{form:c,onFinish:B,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(er.Z.Item,{label:"Team Name",name:"team_alias",rules:[{required:!0,message:"Please input a team name"}],children:(0,a.jsx)(H.Z,{placeholder:""})}),(0,a.jsx)(er.Z.Item,{label:"Models",name:"models",children:(0,a.jsxs)(es.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:[(0,a.jsx)(es.default.Option,{value:"all-proxy-models",children:"All Proxy Models"},"all-proxy-models"),S.map(e=>(0,a.jsx)(es.default.Option,{value:e,children:e},e))]})}),(0,a.jsx)(er.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,a.jsx)(eo.Z,{step:.01,precision:2,width:200})}),(0,a.jsx)(er.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,a.jsx)(eo.Z,{step:1,width:400})}),(0,a.jsx)(er.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,a.jsx)(eo.Z,{step:1,width:400})})]}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(ei.ZP,{htmlType:"submit",children:"Create Team"})})]})})]}),(0,a.jsxs)(Y.Z,{numColSpan:1,children:[(0,a.jsx)(m,{level:4,children:"Team Members"}),(0,a.jsx)(h,{children:"If you belong to multiple teams, this setting controls which teams members you see."}),l&&l.length>0?(0,a.jsx)(eb.Z,{defaultValue:"0",children:l.map((e,l)=>(0,a.jsx)(ek.Z,{value:String(l),onClick:()=>{Z(e)},children:e.team_alias},l))}):(0,a.jsxs)(h,{children:["No team created. ",(0,a.jsx)("b",{children:"Defaulting to personal account."})]})]}),(0,a.jsxs)(Y.Z,{numColSpan:1,children:[(0,a.jsx)(ep.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,a.jsxs)(eg.Z,{children:[(0,a.jsx)(eZ.Z,{children:(0,a.jsxs)(ew.Z,{children:[(0,a.jsx)(e_.Z,{children:"Member Name"}),(0,a.jsx)(e_.Z,{children:"Role"})]})}),(0,a.jsx)(ey.Z,{children:y?y.members_with_roles.map((e,l)=>(0,a.jsxs)(ew.Z,{children:[(0,a.jsx)(ef.Z,{children:e.user_email?e.user_email:e.user_id?e.user_id:null}),(0,a.jsx)(ef.Z,{children:e.role})]},l)):null})]})}),y&&(0,a.jsx)(e=>{let{visible:l,onCancel:t,team:s,onSubmit:r}=e,[n]=er.Z.useForm();return(0,a.jsx)(ea.Z,{title:"Edit Team",visible:l,width:800,footer:null,onOk:()=>{n.validateFields().then(e=>{r({...e,team_id:s.team_id}),n.resetFields()}).catch(e=>{console.error("Validation failed:",e)})},onCancel:t,children:(0,a.jsxs)(er.Z,{form:n,onFinish:R,initialValues:s,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(er.Z.Item,{label:"Team Name",name:"team_alias",rules:[{required:!0,message:"Please input a team name"}],children:(0,a.jsx)(en.Z,{})}),(0,a.jsx)(er.Z.Item,{label:"Models",name:"models",children:(0,a.jsxs)(es.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:[(0,a.jsx)(es.default.Option,{value:"all-proxy-models",children:"All Proxy Models"},"all-proxy-models"),S&&S.map(e=>(0,a.jsx)(es.default.Option,{value:e,children:e},e))]})}),(0,a.jsx)(er.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,a.jsx)(eo.Z,{step:.01,precision:2,width:200})}),(0,a.jsx)(er.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,a.jsx)(eo.Z,{step:1,width:400})}),(0,a.jsx)(er.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,a.jsx)(eo.Z,{step:1,width:400})}),(0,a.jsx)(er.Z.Item,{label:"Requests per minute Limit (RPM)",name:"team_id",hidden:!0})]}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(ei.ZP,{htmlType:"submit",children:"Edit Team"})})]})})},{visible:j,onCancel:()=>{g(!1),Z(null)},team:y,onSubmit:R})]}),(0,a.jsxs)(Y.Z,{numColSpan:1,children:[(0,a.jsx)(J.Z,{className:"mx-auto mb-5",onClick:()=>v(!0),children:"+ Add member"}),(0,a.jsx)(ea.Z,{title:"Add member",visible:k,width:800,footer:null,onOk:()=>{v(!1),d.resetFields()},onCancel:()=>{v(!1),d.resetFields()},children:(0,a.jsxs)(er.Z,{form:c,onFinish:z,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(er.Z.Item,{label:"Email",name:"user_email",className:"mb-4",children:(0,a.jsx)(en.Z,{name:"user_email",className:"px-3 py-2 border rounded-md w-full"})}),(0,a.jsx)("div",{className:"text-center mb-4",children:"OR"}),(0,a.jsx)(er.Z.Item,{label:"User ID",name:"user_id",className:"mb-4",children:(0,a.jsx)(en.Z,{name:"user_id",className:"px-3 py-2 border rounded-md w-full"})})]}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(ei.ZP,{htmlType:"submit",children:"Add member"})})]})})]})]})})},ll=t(18190),lt=e=>{let l,{searchParams:t,accessToken:s,showSSOBanner:r}=e,[o]=er.Z.useForm(),[i]=er.Z.useForm(),{Title:c,Paragraph:d}=eT.default,[m,h]=(0,n.useState)(""),[x,p]=(0,n.useState)(null),[j,g]=(0,n.useState)(!1),[y,f]=(0,n.useState)(!1),[Z,_]=(0,n.useState)(!1),[w,b]=(0,n.useState)(!1),[k,v]=(0,n.useState)(!1);try{l=window.location.origin}catch(e){l=""}l+="/fallback/login";let S=()=>{v(!1)},A=["proxy_admin","proxy_admin_viewer"];(0,n.useEffect)(()=>{(async()=>{if(null!=s){let e=[],l=await R(s,"proxy_admin_viewer");l.forEach(l=>{e.push({user_role:l.user_role,user_id:l.user_id,user_email:l.user_email})}),console.log("proxy viewers: ".concat(l));let t=await R(s,"proxy_admin");t.forEach(l=>{e.push({user_role:l.user_role,user_id:l.user_id,user_email:l.user_email})}),console.log("proxy admins: ".concat(t)),console.log("combinedList: ".concat(e)),p(e)}})()},[s]);let N=()=>{_(!1),i.resetFields()},E=()=>{_(!1),i.resetFields()},I=e=>(0,a.jsxs)(er.Z,{form:o,onFinish:e,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(er.Z.Item,{label:"Email",name:"user_email",className:"mb-4",children:(0,a.jsx)(en.Z,{name:"user_email",className:"px-3 py-2 border rounded-md w-full"})}),(0,a.jsx)("div",{className:"text-center mb-4",children:"OR"}),(0,a.jsx)(er.Z.Item,{label:"User ID",name:"user_id",className:"mb-4",children:(0,a.jsx)(en.Z,{name:"user_id",className:"px-3 py-2 border rounded-md w-full"})})]}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(ei.ZP,{htmlType:"submit",children:"Add member"})})]}),C=(e,l,t)=>(0,a.jsxs)(er.Z,{form:o,onFinish:e,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(er.Z.Item,{rules:[{required:!0,message:"Required"}],label:"User Role",name:"user_role",labelCol:{span:10},labelAlign:"left",children:(0,a.jsx)(eb.Z,{value:l,children:A.map((e,l)=>(0,a.jsx)(ek.Z,{value:e,children:e},l))})}),(0,a.jsx)(er.Z.Item,{label:"Team ID",name:"user_id",hidden:!0,initialValue:t,valuePropName:"user_id",className:"mt-8",children:(0,a.jsx)(en.Z,{value:t,disabled:!0})})]}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(ei.ZP,{htmlType:"submit",children:"Update role"})})]}),P=async e=>{try{if(null!=s&&null!=x){u.ZP.info("Making API Call");let l=await B(s,e,null);console.log("response for team create call: ".concat(l));let t=x.findIndex(e=>(console.log("user.user_id=".concat(e.user_id,"; response.user_id=").concat(l.user_id)),e.user_id===l.user_id));console.log("foundIndex: ".concat(t)),-1==t&&(console.log("updates admin with new user"),x.push(l),p(x)),u.ZP.success("Refresh tab to see updated user role"),_(!1)}}catch(e){console.error("Error creating the key:",e)}},T=async e=>{try{if(null!=s&&null!=x){u.ZP.info("Making API Call");let l=await B(s,e,"proxy_admin_viewer");console.log("response for team create call: ".concat(l));let t=x.findIndex(e=>(console.log("user.user_id=".concat(e.user_id,"; response.user_id=").concat(l.user_id)),e.user_id===l.user_id));console.log("foundIndex: ".concat(t)),-1==t&&(console.log("updates admin with new user"),x.push(l),p(x)),g(!1)}}catch(e){console.error("Error creating the key:",e)}},O=async e=>{try{if(null!=s&&null!=x){u.ZP.info("Making API Call"),e.user_email,e.user_id;let l=await B(s,e,"proxy_admin");console.log("response for team create call: ".concat(l));let t=x.findIndex(e=>(console.log("user.user_id=".concat(e.user_id,"; response.user_id=").concat(l.user_id)),e.user_id===l.user_id));console.log("foundIndex: ".concat(t)),-1==t&&(console.log("updates admin with new user"),x.push(l),p(x)),f(!1)}}catch(e){console.error("Error creating the key:",e)}},F=async e=>{null!=s&&V(s,{environment_variables:{PROXY_BASE_URL:e.proxy_base_url,GOOGLE_CLIENT_ID:e.google_client_id,GOOGLE_CLIENT_SECRET:e.google_client_secret}})};return console.log("admins: ".concat(null==x?void 0:x.length)),(0,a.jsxs)("div",{className:"w-full m-2 mt-2 p-8",children:[(0,a.jsx)(c,{level:4,children:"Admin Access "}),(0,a.jsxs)(d,{children:[r&&(0,a.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/ui#restrict-ui-access",children:"Requires SSO Setup"}),(0,a.jsx)("br",{}),(0,a.jsx)("b",{children:"Proxy Admin: "})," Can create keys, teams, users, add models, etc. ",(0,a.jsx)("br",{}),(0,a.jsx)("b",{children:"Proxy Admin Viewer: "}),"Can just view spend. They cannot create keys, teams or grant users access to new models."," "]}),(0,a.jsxs)(W.Z,{numItems:1,className:"gap-2 p-2 w-full",children:[(0,a.jsx)(Y.Z,{numColSpan:1,children:(0,a.jsx)(ep.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,a.jsxs)(eg.Z,{children:[(0,a.jsx)(eZ.Z,{children:(0,a.jsxs)(ew.Z,{children:[(0,a.jsx)(e_.Z,{children:"Member Name"}),(0,a.jsx)(e_.Z,{children:"Role"})]})}),(0,a.jsx)(ey.Z,{children:x?x.map((e,l)=>(0,a.jsxs)(ew.Z,{children:[(0,a.jsx)(ef.Z,{children:e.user_email?e.user_email:e.user_id?e.user_id:null}),(0,a.jsx)(ef.Z,{children:e.user_role}),(0,a.jsxs)(ef.Z,{children:[(0,a.jsx)(ej.Z,{icon:eu.Z,size:"sm",onClick:()=>_(!0)}),(0,a.jsx)(ea.Z,{title:"Update role",visible:Z,width:800,footer:null,onOk:N,onCancel:E,children:C(P,e.user_role,e.user_id)})]})]},l)):null})]})})}),(0,a.jsx)(Y.Z,{numColSpan:1,children:(0,a.jsxs)("div",{className:"flex justify-start",children:[(0,a.jsx)(J.Z,{className:"mr-4 mb-5",onClick:()=>f(!0),children:"+ Add admin"}),(0,a.jsx)(ea.Z,{title:"Add admin",visible:y,width:800,footer:null,onOk:()=>{f(!1),i.resetFields()},onCancel:()=>{f(!1),i.resetFields()},children:I(O)}),(0,a.jsx)(J.Z,{className:"mb-5",onClick:()=>g(!0),children:"+ Add viewer"}),(0,a.jsx)(ea.Z,{title:"Add viewer",visible:j,width:800,footer:null,onOk:()=>{g(!1),i.resetFields()},onCancel:()=>{g(!1),i.resetFields()},children:I(T)})]})})]}),(0,a.jsxs)(W.Z,{children:[(0,a.jsx)(c,{level:4,children:"Add SSO"}),(0,a.jsxs)("div",{className:"flex justify-start mb-4",children:[(0,a.jsx)(J.Z,{onClick:()=>b(!0),children:"Add SSO"}),(0,a.jsx)(ea.Z,{title:"Add SSO",visible:w,width:800,footer:null,onOk:()=>{b(!1),o.resetFields()},onCancel:()=>{b(!1),o.resetFields()},children:(0,a.jsxs)(er.Z,{form:o,onFinish:e=>{O(e),F(e),b(!1),v(!0)},labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(er.Z.Item,{label:"Admin Email",name:"user_email",rules:[{required:!0,message:"Please enter the email of the proxy admin"}],children:(0,a.jsx)(en.Z,{})}),(0,a.jsx)(er.Z.Item,{label:"PROXY BASE URL",name:"proxy_base_url",rules:[{required:!0,message:"Please enter the proxy base url"}],children:(0,a.jsx)(en.Z,{})}),(0,a.jsx)(er.Z.Item,{label:"GOOGLE CLIENT ID",name:"google_client_id",rules:[{required:!0,message:"Please enter the google client id"}],children:(0,a.jsx)(en.Z.Password,{})}),(0,a.jsx)(er.Z.Item,{label:"GOOGLE CLIENT SECRET",name:"google_client_secret",rules:[{required:!0,message:"Please enter the google client secret"}],children:(0,a.jsx)(en.Z.Password,{})})]}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(ei.ZP,{htmlType:"submit",children:"Save"})})]})}),(0,a.jsxs)(ea.Z,{title:"SSO Setup Instructions",visible:k,width:800,footer:null,onOk:S,onCancel:()=>{v(!1)},children:[(0,a.jsx)("p",{children:"Follow these steps to complete the SSO setup:"}),(0,a.jsx)(ee.Z,{className:"mt-2",children:"1. DO NOT Exit this TAB"}),(0,a.jsx)(ee.Z,{className:"mt-2",children:"2. Open a new tab, visit your proxy base url"}),(0,a.jsx)(ee.Z,{className:"mt-2",children:"3. Confirm your SSO is configured correctly and you can login on the new Tab"}),(0,a.jsx)(ee.Z,{className:"mt-2",children:"4. If Step 3 is successful, you can close this tab"}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(ei.ZP,{onClick:S,children:"Done"})})]})]}),(0,a.jsxs)(ll.Z,{title:"Login without SSO",color:"teal",children:["If you need to login without sso, you can access ",(0,a.jsxs)("a",{href:l,target:"_blank",children:[(0,a.jsx)("b",{children:l})," "]})]})]})]})},ls=t(42556);let lr=[{name:"slack",variables:{LANGFUSE_HOST:null,LANGFUSE_PUBLIC_KEY:null,LANGFUSE_SECRET_KEY:null,OPENMETER_API_KEY:null,SLACK_WEBHOOK_URL:null}},{name:"langfuse",variables:{LANGFUSE_HOST:null,LANGFUSE_PUBLIC_KEY:null,LANGFUSE_SECRET_KEY:null,OPENMETER_API_KEY:null,SLACK_WEBHOOK_URL:null}},{name:"openmeter",variables:{LANGFUSE_HOST:null,LANGFUSE_PUBLIC_KEY:null,LANGFUSE_SECRET_KEY:null,OPENMETER_API_KEY:null,SLACK_WEBHOOK_URL:null}}];var la=e=>{let{accessToken:l,userRole:t,userID:s}=e,[r,o]=(0,n.useState)(lr),[i,c]=(0,n.useState)([]),[d,m]=(0,n.useState)(!1),[h]=er.Z.useForm(),[x,p]=(0,n.useState)(null),[j,g]=(0,n.useState)([]),[y,f]=(0,n.useState)(""),[Z,_]=(0,n.useState)({}),[w,b]=(0,n.useState)([]),k=e=>{w.includes(e)?b(w.filter(l=>l!==e)):b([...w,e])},v={llm_exceptions:"LLM Exceptions",llm_too_slow:"LLM Responses Too Slow",llm_requests_hanging:"LLM Requests Hanging",budget_alerts:"Budget Alerts (API Keys, Users)",db_exceptions:"Database Exceptions (Read/Write)"};(0,n.useEffect)(()=>{l&&t&&s&&q(l,s,t).then(e=>{console.log("callbacks",e);let l=lr;o(l=l.map(l=>{let t=e.callbacks.find(e=>e.name===l.name);return t?{...l,variables:{...l.variables,...t.variables}}:l}));let t=e.alerts;if(console.log("alerts_data",t),t&&t.length>0){let e=t[0];console.log("_alert_info",e);let l=e.variables.SLACK_WEBHOOK_URL;console.log("catch_all_webhook",l),b(e.active_alerts),f(l),_(e.alerts_to_webhook)}c(t)})},[l,t,s]);let S=e=>w&&w.includes(e),A=e=>{if(!l)return;let t=Object.fromEntries(Object.entries(e.variables).map(e=>{var l;let[t,s]=e;return[t,(null===(l=document.querySelector('input[name="'.concat(t,'"]')))||void 0===l?void 0:l.value)||s]}));console.log("updatedVariables",t),console.log("updateAlertTypes",j);let s={environment_variables:t,litellm_settings:{success_callback:[e.name]}};try{V(l,s)}catch(e){u.ZP.error("Failed to update callback: "+e,20)}u.ZP.success("Callback updated successfully")},N=()=>{l&&h.validateFields().then(e=>{if(console.log("Form values:",e),"langfuse"===e.callback){V(l,{environment_variables:{LANGFUSE_PUBLIC_KEY:e.langfusePublicKey,LANGFUSE_SECRET_KEY:e.langfusePrivateKey},litellm_settings:{success_callback:[e.callback]}});let t={name:e.callback,variables:{SLACK_WEBHOOK_URL:null,LANGFUSE_HOST:null,LANGFUSE_PUBLIC_KEY:e.langfusePublicKey,LANGFUSE_SECRET_KEY:e.langfusePrivateKey,OPENMETER_API_KEY:null}};o(r?[...r,t]:[t])}else if("slack"===e.callback){console.log("values.slackWebhookUrl: ".concat(e.slackWebhookUrl)),V(l,{general_settings:{alerting:["slack"],alerting_threshold:300},environment_variables:{SLACK_WEBHOOK_URL:e.slackWebhookUrl}}),console.log("values.callback: ".concat(e.callback));let t={name:e.callback,variables:{SLACK_WEBHOOK_URL:e.slackWebhookUrl,LANGFUSE_HOST:null,LANGFUSE_PUBLIC_KEY:null,LANGFUSE_SECRET_KEY:null,OPENMETER_API_KEY:null}};o(r?[...r,t]:[t])}else if("openmeter"==e.callback){console.log("values.openMeterApiKey: ".concat(e.openMeterApiKey)),V(l,{environment_variables:{OPENMETER_API_KEY:e.openMeterApiKey},litellm_settings:{success_callback:[e.callback]}});let t={name:e.callback,variables:{SLACK_WEBHOOK_URL:null,LANGFUSE_HOST:null,LANGFUSE_PUBLIC_KEY:null,LANGFUSE_SECRET_KEY:null,OPENMETER_API_KEY:e.openMeterAPIKey}};o(r?[...r,t]:[t])}m(!1),h.resetFields(),p(null)})};return l?(console.log("callbacks: ".concat(r)),(0,a.jsxs)("div",{className:"w-full mx-4",children:[(0,a.jsxs)(W.Z,{numItems:1,className:"gap-2 p-8 w-full mt-2",children:[(0,a.jsx)(ll.Z,{title:"[UI] Presidio PII + Guardrails Coming Soon. https://docs.litellm.ai/docs/proxy/pii_masking",color:"sky"}),(0,a.jsxs)(eM.Z,{children:[(0,a.jsxs)(eL.Z,{variant:"line",defaultValue:"1",children:[(0,a.jsx)(eR.Z,{value:"1",children:"Logging Callbacks"}),(0,a.jsx)(eR.Z,{value:"2",children:"Alerting"})]}),(0,a.jsxs)(eD.Z,{children:[(0,a.jsx)(eU.Z,{children:(0,a.jsx)(ep.Z,{children:(0,a.jsxs)(eg.Z,{children:[(0,a.jsx)(eZ.Z,{children:(0,a.jsxs)(ew.Z,{children:[(0,a.jsx)(e_.Z,{children:"Callback"}),(0,a.jsx)(e_.Z,{children:"Callback Env Vars"})]})}),(0,a.jsx)(ey.Z,{children:r.filter(e=>"slack"!==e.name).map((e,t)=>{var s;return(0,a.jsxs)(ew.Z,{children:[(0,a.jsx)(ef.Z,{children:(0,a.jsx)(ex.Z,{color:"emerald",children:e.name})}),(0,a.jsxs)(ef.Z,{children:[(0,a.jsx)("ul",{children:Object.entries(null!==(s=e.variables)&&void 0!==s?s:{}).filter(l=>{let[t,s]=l;return t.toLowerCase().includes(e.name)}).map(e=>{let[l,t]=e;return(0,a.jsxs)("li",{children:[(0,a.jsx)(ee.Z,{className:"mt-2",children:l}),"LANGFUSE_HOST"===l?(0,a.jsx)("p",{children:"default value=https://cloud.langfuse.com"}):(0,a.jsx)("div",{}),(0,a.jsx)(H.Z,{name:l,defaultValue:t,type:"password"})]},l)})}),(0,a.jsx)(J.Z,{className:"mt-2",onClick:()=>A(e),children:"Save Changes"}),(0,a.jsx)(J.Z,{onClick:()=>z(l,e.name),className:"mx-2",children:"Test Callback"})]})]},t)})})]})})}),(0,a.jsx)(eU.Z,{children:(0,a.jsxs)(ep.Z,{children:[(0,a.jsxs)(ee.Z,{className:"my-2",children:["Alerts are only supported for Slack Webhook URLs. Get your webhook urls from ",(0,a.jsx)("a",{href:"https://api.slack.com/messaging/webhooks",target:"_blank",style:{color:"blue"},children:"here"})]}),(0,a.jsxs)(eg.Z,{children:[(0,a.jsx)(eZ.Z,{children:(0,a.jsxs)(ew.Z,{children:[(0,a.jsx)(e_.Z,{}),(0,a.jsx)(e_.Z,{}),(0,a.jsx)(e_.Z,{children:"Slack Webhook URL"})]})}),(0,a.jsx)(ey.Z,{children:Object.entries(v).map((e,l)=>{let[t,s]=e;return(0,a.jsxs)(ew.Z,{children:[(0,a.jsx)(ef.Z,{children:(0,a.jsx)(ls.Z,{id:"switch",name:"switch",checked:S(t),onChange:()=>k(t)})}),(0,a.jsx)(ef.Z,{children:(0,a.jsx)(ee.Z,{children:s})}),(0,a.jsx)(ef.Z,{children:(0,a.jsx)(H.Z,{name:t,type:"password",defaultValue:Z&&Z[t]?Z[t]:y})})]},l)})})]}),(0,a.jsx)(J.Z,{size:"xs",className:"mt-2",onClick:()=>{if(!l)return;let e={};Object.entries(v).forEach(l=>{let[t,s]=l,r=document.querySelector('input[name="'.concat(t,'"]'));console.log("key",t),console.log("webhookInput",r);let a=(null==r?void 0:r.value)||"";console.log("newWebhookValue",a),e[t]=a}),console.log("updatedAlertToWebhooks",e);let t={general_settings:{alert_to_webhook_url:e,alert_types:w}};console.log("payload",t);try{V(l,t)}catch(e){u.ZP.error("Failed to update alerts: "+e,20)}u.ZP.success("Alerts updated successfully")},children:"Save Changes"}),(0,a.jsx)(J.Z,{onClick:()=>z(l,"slack"),className:"mx-2",children:"Test Alerts"})]})})]})]})]}),(0,a.jsx)(ea.Z,{title:"Add Callback",visible:d,onOk:N,width:800,onCancel:()=>{m(!1),h.resetFields(),p(null)},footer:null,children:(0,a.jsxs)(er.Z,{form:h,layout:"vertical",onFinish:N,children:[(0,a.jsx)(er.Z.Item,{label:"Callback",name:"callback",rules:[{required:!0,message:"Please select a callback"}],children:(0,a.jsxs)(es.default,{onChange:e=>{p(e)},children:[(0,a.jsx)(es.default.Option,{value:"langfuse",children:"langfuse"}),(0,a.jsx)(es.default.Option,{value:"openmeter",children:"openmeter"})]})}),"langfuse"===x&&(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(er.Z.Item,{label:"LANGFUSE_PUBLIC_KEY",name:"langfusePublicKey",rules:[{required:!0,message:"Please enter the public key"}],children:(0,a.jsx)(H.Z,{type:"password"})}),(0,a.jsx)(er.Z.Item,{label:"LANGFUSE_PRIVATE_KEY",name:"langfusePrivateKey",rules:[{required:!0,message:"Please enter the private key"}],children:(0,a.jsx)(H.Z,{type:"password"})})]}),"openmeter"==x&&(0,a.jsx)(a.Fragment,{children:(0,a.jsx)(er.Z.Item,{label:"OPENMETER_API_KEY",name:"openMeterApiKey",rules:[{required:!0,message:"Please enter the openmeter api key"}],children:(0,a.jsx)(H.Z,{type:"password"})})}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(ei.ZP,{htmlType:"submit",children:"Save"})})]})})]})):null};let{Option:ln}=es.default;var lo=e=>{let{models:l,accessToken:t,routerSettings:s,setRouterSettings:r}=e,[o]=er.Z.useForm(),[i,c]=(0,n.useState)(!1),[d,m]=(0,n.useState)("");return(0,a.jsxs)("div",{children:[(0,a.jsx)(J.Z,{className:"mx-auto",onClick:()=>c(!0),children:"+ Add Fallbacks"}),(0,a.jsx)(ea.Z,{title:"Add Fallbacks",visible:i,width:800,footer:null,onOk:()=>{c(!1),o.resetFields()},onCancel:()=>{c(!1),o.resetFields()},children:(0,a.jsxs)(er.Z,{form:o,onFinish:e=>{console.log(e);let{model_name:l,models:a}=e,n=[...s.fallbacks||[],{[l]:a}],i={...s,fallbacks:n};console.log(i);try{V(t,{router_settings:i}),r(i)}catch(e){u.ZP.error("Failed to update router settings: "+e,20)}u.ZP.success("router settings updated successfully"),c(!1),o.resetFields()},labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(er.Z.Item,{label:"Public Model Name",name:"model_name",rules:[{required:!0,message:"Set the model to fallback for"}],help:"required",children:(0,a.jsx)(eb.Z,{defaultValue:d,children:l&&l.map((e,l)=>(0,a.jsx)(ek.Z,{value:e,onClick:()=>m(e),children:e},l))})}),(0,a.jsx)(er.Z.Item,{label:"Fallback Models",name:"models",rules:[{required:!0,message:"Please select a model"}],help:"required",children:(0,a.jsx)(eK.Z,{value:l,children:l&&l.filter(e=>e!=d).map(e=>(0,a.jsx)(eB.Z,{value:e,children:e},e))})})]}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(ei.ZP,{htmlType:"submit",children:"Add Fallbacks"})})]})})]})},li=t(12968);async function lc(e,l){console.log("isLocal:",!1);let t=window.location.origin,s=new li.ZP.OpenAI({apiKey:l,baseURL:t,dangerouslyAllowBrowser:!0});try{let l=await s.chat.completions.create({model:e,messages:[{role:"user",content:"Hi, this is a test message"}],mock_testing_fallbacks:!0});u.ZP.success((0,a.jsxs)("span",{children:["Test model=",(0,a.jsx)("strong",{children:e}),", received model=",(0,a.jsx)("strong",{children:l.model}),". See ",(0,a.jsx)("a",{href:"#",onClick:()=>window.open("https://docs.litellm.ai/docs/proxy/reliability","_blank"),style:{textDecoration:"underline",color:"blue"},children:"curl"})]}))}catch(e){u.ZP.error("Error occurred while generating model response. Please try again. Error: ".concat(e),20)}}let ld={ttl:3600,lowest_latency_buffer:0},lm=e=>{let{selectedStrategy:l,strategyArgs:t,paramExplanation:s}=e;return(0,a.jsxs)($.Z,{children:[(0,a.jsx)(Q.Z,{className:"text-sm font-medium text-tremor-content-strong dark:text-dark-tremor-content-strong",children:"Routing Strategy Specific Args"}),(0,a.jsx)(X.Z,{children:"latency-based-routing"==l?(0,a.jsx)(ep.Z,{children:(0,a.jsxs)(eg.Z,{children:[(0,a.jsx)(eZ.Z,{children:(0,a.jsxs)(ew.Z,{children:[(0,a.jsx)(e_.Z,{children:"Setting"}),(0,a.jsx)(e_.Z,{children:"Value"})]})}),(0,a.jsx)(ey.Z,{children:Object.entries(t).map(e=>{let[l,t]=e;return(0,a.jsxs)(ew.Z,{children:[(0,a.jsxs)(ef.Z,{children:[(0,a.jsx)(ee.Z,{children:l}),(0,a.jsx)("p",{style:{fontSize:"0.65rem",color:"#808080",fontStyle:"italic"},className:"mt-1",children:s[l]})]}),(0,a.jsx)(ef.Z,{children:(0,a.jsx)(H.Z,{name:l,defaultValue:"object"==typeof t?JSON.stringify(t,null,2):t.toString()})})]},l)})})]})}):(0,a.jsx)(ee.Z,{children:"No specific settings"})})]})};var lu=e=>{let{accessToken:l,userRole:t,userID:s,modelData:r}=e,[o,i]=(0,n.useState)({}),[c,d]=(0,n.useState)(!1),[m]=er.Z.useForm(),[h,x]=(0,n.useState)(null),[p,j]=(0,n.useState)(null),[g,y]=(0,n.useState)(null),f={routing_strategy_args:"(dict) Arguments to pass to the routing strategy",routing_strategy:"(string) Routing strategy to use",allowed_fails:"(int) Number of times a deployment can fail before being added to cooldown",cooldown_time:"(int) time in seconds to cooldown a deployment after failure",num_retries:"(int) Number of retries for failed requests. Defaults to 0.",timeout:"(float) Timeout for requests. Defaults to None.",retry_after:"(int) Minimum time to wait before retrying a failed request",ttl:"(int) Sliding window to look back over when calculating the average latency of a deployment. Default - 1 hour (in seconds).",lowest_latency_buffer:"(float) Shuffle between deployments within this % of the lowest latency. Default - 0 (i.e. always pick lowest latency)."};(0,n.useEffect)(()=>{l&&t&&s&&q(l,s,t).then(e=>{console.log("callbacks",e),i(e.router_settings)})},[l,t,s]);let Z=async e=>{if(l){console.log("received key: ".concat(e)),console.log("routerSettings['fallbacks']: ".concat(o.fallbacks)),o.fallbacks.map(l=>(e in l&&delete l[e],l));try{await V(l,{router_settings:o}),i({...o}),j(o.routing_strategy),u.ZP.success("Router settings updated successfully")}catch(e){u.ZP.error("Failed to update router settings: "+e,20)}}},_=e=>{if(!l)return;console.log("router_settings",e);let t=Object.fromEntries(Object.entries(e).map(e=>{let[l,t]=e;if("routing_strategy_args"!==l&&"routing_strategy"!==l){var s;return[l,(null===(s=document.querySelector('input[name="'.concat(l,'"]')))||void 0===s?void 0:s.value)||t]}if("routing_strategy"==l)return[l,p];if("routing_strategy_args"==l&&"latency-based-routing"==p){let e={},l=document.querySelector('input[name="lowest_latency_buffer"]'),t=document.querySelector('input[name="ttl"]');return(null==l?void 0:l.value)&&(e.lowest_latency_buffer=Number(l.value)),(null==t?void 0:t.value)&&(e.ttl=Number(t.value)),console.log("setRoutingStrategyArgs: ".concat(e)),["routing_strategy_args",e]}return null}).filter(e=>null!=e));console.log("updatedVariables",t);try{V(l,{router_settings:t})}catch(e){u.ZP.error("Failed to update router settings: "+e,20)}u.ZP.success("router settings updated successfully")};return l?(0,a.jsx)("div",{className:"w-full mx-4",children:(0,a.jsxs)(eM.Z,{className:"gap-2 p-8 h-[75vh] w-full mt-2",children:[(0,a.jsxs)(eL.Z,{variant:"line",defaultValue:"1",children:[(0,a.jsx)(eR.Z,{value:"1",children:"General Settings"}),(0,a.jsx)(eR.Z,{value:"2",children:"Fallbacks"})]}),(0,a.jsxs)(eD.Z,{children:[(0,a.jsx)(eU.Z,{children:(0,a.jsxs)(W.Z,{numItems:1,className:"gap-2 p-8 w-full mt-2",children:[(0,a.jsx)(el.Z,{children:"Router Settings"}),(0,a.jsxs)(ep.Z,{children:[(0,a.jsxs)(eg.Z,{children:[(0,a.jsx)(eZ.Z,{children:(0,a.jsxs)(ew.Z,{children:[(0,a.jsx)(e_.Z,{children:"Setting"}),(0,a.jsx)(e_.Z,{children:"Value"})]})}),(0,a.jsx)(ey.Z,{children:Object.entries(o).filter(e=>{let[l,t]=e;return"fallbacks"!=l&&"context_window_fallbacks"!=l&&"routing_strategy_args"!=l}).map(e=>{let[l,t]=e;return(0,a.jsxs)(ew.Z,{children:[(0,a.jsxs)(ef.Z,{children:[(0,a.jsx)(ee.Z,{children:l}),(0,a.jsx)("p",{style:{fontSize:"0.65rem",color:"#808080",fontStyle:"italic"},className:"mt-1",children:f[l]})]}),(0,a.jsx)(ef.Z,{children:"routing_strategy"==l?(0,a.jsxs)(eb.Z,{defaultValue:t,className:"w-full max-w-md",onValueChange:j,children:[(0,a.jsx)(ek.Z,{value:"usage-based-routing",children:"usage-based-routing"}),(0,a.jsx)(ek.Z,{value:"latency-based-routing",children:"latency-based-routing"}),(0,a.jsx)(ek.Z,{value:"simple-shuffle",children:"simple-shuffle"})]}):(0,a.jsx)(H.Z,{name:l,defaultValue:"object"==typeof t?JSON.stringify(t,null,2):t.toString()})})]},l)})})]}),(0,a.jsx)(lm,{selectedStrategy:p,strategyArgs:o&&o.routing_strategy_args&&Object.keys(o.routing_strategy_args).length>0?o.routing_strategy_args:ld,paramExplanation:f})]}),(0,a.jsx)(Y.Z,{children:(0,a.jsx)(J.Z,{className:"mt-2",onClick:()=>_(o),children:"Save Changes"})})]})}),(0,a.jsxs)(eU.Z,{children:[(0,a.jsxs)(eg.Z,{children:[(0,a.jsx)(eZ.Z,{children:(0,a.jsxs)(ew.Z,{children:[(0,a.jsx)(e_.Z,{children:"Model Name"}),(0,a.jsx)(e_.Z,{children:"Fallbacks"})]})}),(0,a.jsx)(ey.Z,{children:o.fallbacks&&o.fallbacks.map((e,t)=>Object.entries(e).map(e=>{let[s,r]=e;return(0,a.jsxs)(ew.Z,{children:[(0,a.jsx)(ef.Z,{children:s}),(0,a.jsx)(ef.Z,{children:Array.isArray(r)?r.join(", "):r}),(0,a.jsx)(ef.Z,{children:(0,a.jsx)(J.Z,{onClick:()=>lc(s,l),children:"Test Fallback"})}),(0,a.jsx)(ef.Z,{children:(0,a.jsx)(ej.Z,{icon:eh.Z,size:"sm",onClick:()=>Z(s)})})]},t.toString()+s)}))})]}),(0,a.jsx)(lo,{models:(null==r?void 0:r.data)?r.data.map(e=>e.model_name):[],accessToken:l,routerSettings:o,setRouterSettings:i})]})]})]})}):null},lh=t(67951),lx=e=>{let{}=e;return(0,a.jsx)(a.Fragment,{children:(0,a.jsx)(W.Z,{className:"gap-2 p-8 h-[80vh] w-full mt-2",children:(0,a.jsxs)("div",{className:"mb-5",children:[(0,a.jsx)("p",{className:"text-2xl text-tremor-content-strong dark:text-dark-tremor-content-strong font-semibold",children:"OpenAI Compatible Proxy: API Reference"}),(0,a.jsx)(ee.Z,{className:"mt-2 mb-2",children:"LiteLLM is OpenAI Compatible. This means your API Key works with the OpenAI SDK. Just replace the base_url to point to your litellm proxy. Example Below "}),(0,a.jsxs)(eM.Z,{children:[(0,a.jsxs)(eL.Z,{children:[(0,a.jsx)(eR.Z,{children:"OpenAI Python SDK"}),(0,a.jsx)(eR.Z,{children:"LlamaIndex"}),(0,a.jsx)(eR.Z,{children:"Langchain Py"})]}),(0,a.jsxs)(eD.Z,{children:[(0,a.jsx)(eU.Z,{children:(0,a.jsx)(lh.Z,{language:"python",children:'\nimport openai\nclient = openai.OpenAI(\n api_key="your_api_key",\n base_url="http://0.0.0.0:4000" # LiteLLM Proxy is OpenAI compatible, Read More: https://docs.litellm.ai/docs/proxy/user_keys\n)\n\nresponse = client.chat.completions.create(\n model="gpt-3.5-turbo", # model to send to the proxy\n messages = [\n {\n "role": "user",\n "content": "this is a test request, write a short poem"\n }\n ]\n)\n\nprint(response)\n '})}),(0,a.jsx)(eU.Z,{children:(0,a.jsx)(lh.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,a.jsx)(eU.Z,{children:(0,a.jsx)(lh.Z,{language:"python",children:'\nfrom langchain.chat_models import ChatOpenAI\nfrom langchain.prompts.chat import (\n ChatPromptTemplate,\n HumanMessagePromptTemplate,\n SystemMessagePromptTemplate,\n)\nfrom langchain.schema import HumanMessage, SystemMessage\n\nchat = ChatOpenAI(\n openai_api_base="http://0.0.0.0:4000",\n model = "gpt-3.5-turbo",\n temperature=0.1\n)\n\nmessages = [\n SystemMessage(\n content="You are a helpful assistant that im using to make a test request to."\n ),\n HumanMessage(\n content="test from litellm. tell me why it\'s amazing in 1 sentence"\n ),\n]\nresponse = chat(messages)\n\nprint(response)\n\n '})})]})]})]})})})};async function lp(e,l,t,s){console.log("isLocal:",!1);let r=window.location.origin,a=new li.ZP.OpenAI({apiKey:s,baseURL:r,dangerouslyAllowBrowser:!0});try{for await(let s of(await a.chat.completions.create({model:t,stream:!0,messages:[{role:"user",content:e}]})))console.log(s),s.choices[0].delta.content&&l(s.choices[0].delta.content)}catch(e){u.ZP.error("Error occurred while generating model response. Please try again. Error: ".concat(e),20)}}var lj=e=>{let{accessToken:l,token:t,userRole:s,userID:r}=e,[o,i]=(0,n.useState)(""),[c,d]=(0,n.useState)(""),[m,u]=(0,n.useState)([]),[h,x]=(0,n.useState)(void 0),[p,j]=(0,n.useState)([]);(0,n.useEffect)(()=>{l&&t&&s&&r&&(async()=>{try{let e=await A(l,r,s);if(console.log("model_info:",e),(null==e?void 0:e.data.length)>0){let l=e.data.map(e=>({value:e.id,label:e.id}));console.log(l),j(l),x(e.data[0].id)}}catch(e){console.error("Error fetching model info:",e)}})()},[l,r,s]);let g=(e,l)=>{u(t=>{let s=t[t.length-1];return s&&s.role===e?[...t.slice(0,t.length-1),{role:e,content:s.content+l}]:[...t,{role:e,content:l}]})},y=async()=>{if(""!==c.trim()&&o&&t&&s&&r){u(e=>[...e,{role:"user",content:c}]);try{h&&await lp(c,e=>g("assistant",e),h,o)}catch(e){console.error("Error fetching model response",e),g("assistant","Error fetching model response")}d("")}};if(s&&"Admin Viewer"==s){let{Title:e,Paragraph:l}=eT.default;return(0,a.jsxs)("div",{children:[(0,a.jsx)(e,{level:1,children:"Access Denied"}),(0,a.jsx)(l,{children:"Ask your proxy admin for access to test models"})]})}return(0,a.jsx)("div",{style:{width:"100%",position:"relative"},children:(0,a.jsx)(W.Z,{className:"gap-2 p-8 h-[80vh] w-full mt-2",children:(0,a.jsx)(ep.Z,{children:(0,a.jsxs)(eM.Z,{children:[(0,a.jsx)(eL.Z,{children:(0,a.jsx)(eR.Z,{children:"Chat"})}),(0,a.jsx)(eD.Z,{children:(0,a.jsxs)(eU.Z,{children:[(0,a.jsx)("div",{className:"sm:max-w-2xl",children:(0,a.jsxs)(W.Z,{numItems:2,children:[(0,a.jsxs)(Y.Z,{children:[(0,a.jsx)(ee.Z,{children:"API Key"}),(0,a.jsx)(H.Z,{placeholder:"Type API Key here",type:"password",onValueChange:i,value:o})]}),(0,a.jsxs)(Y.Z,{className:"mx-2",children:[(0,a.jsx)(ee.Z,{children:"Select Model:"}),(0,a.jsx)(es.default,{placeholder:"Select a Model",onChange:e=>{console.log("selected ".concat(e)),x(e)},options:p,style:{width:"200px"}})]})]})}),(0,a.jsxs)(eg.Z,{className:"mt-5",style:{display:"block",maxHeight:"60vh",overflowY:"auto"},children:[(0,a.jsx)(eZ.Z,{children:(0,a.jsx)(ew.Z,{children:(0,a.jsx)(ef.Z,{})})}),(0,a.jsx)(ey.Z,{children:m.map((e,l)=>(0,a.jsx)(ew.Z,{children:(0,a.jsx)(ef.Z,{children:"".concat(e.role,": ").concat(e.content)})},l))})]}),(0,a.jsx)("div",{className:"mt-3",style:{position:"absolute",bottom:5,width:"95%"},children:(0,a.jsxs)("div",{className:"flex",children:[(0,a.jsx)(H.Z,{type:"text",value:c,onChange:e=>d(e.target.value),placeholder:"Type your message..."}),(0,a.jsx)(J.Z,{onClick:y,className:"ml-2",children:"Send"})]})})]})})]})})})})},lg=t(33509),ly=t(95781);let{Sider:lf}=lg.default;var lZ=e=>{let{setPage:l,userRole:t,defaultSelectedKey:s}=e;return"Admin Viewer"==t?(0,a.jsx)(lg.default,{style:{minHeight:"100vh",maxWidth:"120px"},children:(0,a.jsx)(lf,{width:120,children:(0,a.jsxs)(ly.Z,{mode:"inline",defaultSelectedKeys:s||["4"],style:{height:"100%",borderRight:0},children:[(0,a.jsx)(ly.Z.Item,{onClick:()=>l("api-keys"),children:"API Keys"},"4"),(0,a.jsx)(ly.Z.Item,{onClick:()=>l("models"),children:"Models"},"2"),(0,a.jsx)(ly.Z.Item,{onClick:()=>l("llm-playground"),children:"Chat UI"},"3"),(0,a.jsx)(ly.Z.Item,{onClick:()=>l("usage"),children:"Usage"},"1")]})})}):(0,a.jsx)(lg.default,{style:{minHeight:"100vh",maxWidth:"145px"},children:(0,a.jsx)(lf,{width:145,children:(0,a.jsxs)(ly.Z,{mode:"inline",defaultSelectedKeys:s||["1"],style:{height:"100%",borderRight:0},children:[(0,a.jsx)(ly.Z.Item,{onClick:()=>l("api-keys"),children:(0,a.jsx)(ee.Z,{children:"API Keys"})},"1"),(0,a.jsx)(ly.Z.Item,{onClick:()=>l("llm-playground"),children:(0,a.jsx)(ee.Z,{children:"Test Key"})},"3"),"Admin"==t?(0,a.jsx)(ly.Z.Item,{onClick:()=>l("models"),children:(0,a.jsx)(ee.Z,{children:"Models"})},"2"):null,"Admin"==t?(0,a.jsx)(ly.Z.Item,{onClick:()=>l("usage"),children:(0,a.jsx)(ee.Z,{children:"Usage"})},"4"):null,"Admin"==t?(0,a.jsx)(ly.Z.Item,{onClick:()=>l("teams"),children:(0,a.jsx)(ee.Z,{children:"Teams"})},"6"):null,"Admin"==t?(0,a.jsx)(ly.Z.Item,{onClick:()=>l("users"),children:(0,a.jsx)(ee.Z,{children:"Users"})},"5"):null,"Admin"==t?(0,a.jsx)(ly.Z.Item,{onClick:()=>l("settings"),children:(0,a.jsx)(ee.Z,{children:"Logging & Alerts"})},"8"):null,"Admin"==t?(0,a.jsx)(ly.Z.Item,{onClick:()=>l("general-settings"),children:(0,a.jsx)(ee.Z,{children:"Router Settings"})},"9"):null,"Admin"==t?(0,a.jsx)(ly.Z.Item,{onClick:()=>l("admin-panel"),children:(0,a.jsx)(ee.Z,{children:"Admin"})},"7"):null,(0,a.jsx)(ly.Z.Item,{onClick:()=>l("api_ref"),children:(0,a.jsx)(ee.Z,{children:"API Reference"})},"11")]})})})},l_=t(67989),lw=e=>{let{accessToken:l,token:t,userRole:s,userID:r,keys:o}=e,i=new Date,[c,d]=(0,n.useState)([]),[m,u]=(0,n.useState)([]),[h,x]=(0,n.useState)([]),[p,j]=(0,n.useState)([]),[g,y]=(0,n.useState)([]),[f,Z]=(0,n.useState)([]),[_,w]=(0,n.useState)([]),[b,k]=(0,n.useState)([]),[v,S]=(0,n.useState)(""),[A,R]=(0,n.useState)({from:new Date(Date.now()-6048e5),to:new Date}),M=new Date(i.getFullYear(),i.getMonth(),1),L=new Date(i.getFullYear(),i.getMonth()+1,0),U=B(M),D=B(L);console.log("keys in usage",o);let K=async(e,t,s)=>{if(!e||!t||!l)return;console.log("uiSelectedKey",s);let r=await T(l,s,e.toISOString(),t.toISOString());console.log("End user data updated successfully",r),j(r)};function B(e){let l=e.getFullYear(),t=e.getMonth()+1,s=e.getDate();return"".concat(l,"-").concat(t<10?"0"+t:t,"-").concat(s<10?"0"+s:s)}return console.log("Start date is ".concat(U)),console.log("End date is ".concat(D)),(0,n.useEffect)(()=>{l&&t&&s&&r&&(async()=>{try{if(console.log("user role: ".concat(s)),"Admin"==s||"Admin Viewer"==s){let e=await C(l);d(e);let t=(await P(l)).map(e=>({key:(e.key_name||e.key_alias||e.api_key).substring(0,10),spend:e.total_spend}));u(t);let s=(await O(l)).map(e=>({key:e.model,spend:e.total_spend}));x(s);let r=await N(l);console.log("teamSpend",r),y(r.daily_spend),w(r.teams);let a=r.total_spend_per_team;a=a.map(e=>(e.name=e.team_id||"",e.value=e.total_spend||0,e)),k(a);let n=await E(l);Z(n.top_10_tags);let o=await T(l,null,void 0,void 0);j(o),console.log("spend/user result",o)}else"App Owner"==s&&await I(l,t,s,r,U,D).then(async e=>{if(console.log("result from spend logs call",e),"daily_spend"in e){let l=e.daily_spend;console.log("daily spend",l),d(l);let t=e.top_api_keys;u(t)}else{let t=(await F(l,function(e){let l=[];e.forEach(e=>{Object.entries(e).forEach(e=>{let[t,s]=e;"spend"!==t&&"startTime"!==t&&"models"!==t&&"users"!==t&&l.push({key:t,spend:s})})}),l.sort((e,l)=>Number(l.spend)-Number(e.spend));let t=l.slice(0,5).map(e=>e.key);return console.log("topKeys: ".concat(Object.keys(t[0]))),t}(e))).info.map(e=>({key:(e.key_name||e.key_alias).substring(0,10),spend:e.spend}));u(t),d(e)}})}catch(e){console.error("There was an error fetching the data",e)}})()},[l,t,s,r,U,D]),(0,a.jsxs)("div",{style:{width:"100%"},className:"p-8",children:[(0,a.jsx)(eE,{userID:r,userRole:s,accessToken:l,userSpend:null,selectedTeam:null}),(0,a.jsxs)(eM.Z,{children:[(0,a.jsxs)(eL.Z,{className:"mt-2",children:[(0,a.jsx)(eR.Z,{children:"All Up"}),(0,a.jsx)(eR.Z,{children:"Team Based Usage"}),(0,a.jsx)(eR.Z,{children:"End User Usage"}),(0,a.jsx)(eR.Z,{children:"Tag Based Usage"})]}),(0,a.jsxs)(eD.Z,{children:[(0,a.jsx)(eU.Z,{children:(0,a.jsxs)(W.Z,{numItems:2,className:"gap-2 h-[75vh] w-full",children:[(0,a.jsx)(Y.Z,{numColSpan:2,children:(0,a.jsxs)(ep.Z,{children:[(0,a.jsx)(el.Z,{children:"Monthly Spend"}),(0,a.jsx)(eq.Z,{data:c,index:"date",categories:["spend"],colors:["blue"],valueFormatter:e=>"$ ".concat(new Intl.NumberFormat("us").format(e).toString()),yAxisWidth:100,tickGap:5})]})}),(0,a.jsx)(Y.Z,{numColSpan:1,children:(0,a.jsxs)(ep.Z,{children:[(0,a.jsx)(el.Z,{children:"Top API Keys"}),(0,a.jsx)(eq.Z,{className:"mt-4 h-40",data:m,index:"key",categories:["spend"],colors:["blue"],yAxisWidth:80,tickGap:5,layout:"vertical",showXAxis:!1,showLegend:!1})]})}),(0,a.jsx)(Y.Z,{numColSpan:1,children:(0,a.jsxs)(ep.Z,{children:[(0,a.jsx)(el.Z,{children:"Top Models"}),(0,a.jsx)(eq.Z,{className:"mt-4 h-40",data:h,index:"key",categories:["spend"],colors:["blue"],yAxisWidth:200,layout:"vertical",showXAxis:!1,showLegend:!1})]})}),(0,a.jsx)(Y.Z,{numColSpan:1})]})}),(0,a.jsx)(eU.Z,{children:(0,a.jsxs)(W.Z,{numItems:2,className:"gap-2 h-[75vh] w-full",children:[(0,a.jsxs)(Y.Z,{numColSpan:2,children:[(0,a.jsxs)(ep.Z,{className:"mb-2",children:[(0,a.jsx)(el.Z,{children:"Total Spend Per Team"}),(0,a.jsx)(l_.Z,{data:b})]}),(0,a.jsxs)(ep.Z,{children:[(0,a.jsx)(el.Z,{children:"Daily Spend Per Team"}),(0,a.jsx)(eq.Z,{className:"h-72",data:g,showLegend:!0,index:"date",categories:_,yAxisWidth:80,colors:["blue","green","yellow","red","purple"],stack:!0})]})]}),(0,a.jsx)(Y.Z,{numColSpan:2})]})}),(0,a.jsxs)(eU.Z,{children:[(0,a.jsxs)("p",{className:"mb-2 text-gray-500 italic text-[12px]",children:["End-Users of your LLM API calls. Tracked when a `user` param is passed in your LLM calls ",(0,a.jsx)("a",{className:"text-blue-500",href:"https://docs.litellm.ai/docs/proxy/users",target:"_blank",children:"docs here"})]}),(0,a.jsxs)(W.Z,{numItems:2,children:[(0,a.jsxs)(Y.Z,{children:[(0,a.jsx)(ee.Z,{children:"Select Time Range"}),(0,a.jsx)(eF.Z,{enableSelect:!0,value:A,onValueChange:e=>{R(e),K(e.from,e.to,null)}})]}),(0,a.jsxs)(Y.Z,{children:[(0,a.jsx)(ee.Z,{children:"Select Key"}),(0,a.jsxs)(eb.Z,{defaultValue:"all-keys",children:[(0,a.jsx)(ek.Z,{value:"all-keys",onClick:()=>{K(A.from,A.to,null)},children:"All Keys"},"all-keys"),null==o?void 0:o.map((e,l)=>e&&null!==e.key_alias&&e.key_alias.length>0?(0,a.jsx)(ek.Z,{value:String(l),onClick:()=>{K(A.from,A.to,e.token)},children:e.key_alias},l):null)]})]})]}),(0,a.jsx)(ep.Z,{className:"mt-4",children:(0,a.jsxs)(eg.Z,{className:"max-h-[70vh] min-h-[500px]",children:[(0,a.jsx)(eZ.Z,{children:(0,a.jsxs)(ew.Z,{children:[(0,a.jsx)(e_.Z,{children:"End User"}),(0,a.jsx)(e_.Z,{children:"Spend"}),(0,a.jsx)(e_.Z,{children:"Total Events"})]})}),(0,a.jsx)(ey.Z,{children:null==p?void 0:p.map((e,l)=>{var t;return(0,a.jsxs)(ew.Z,{children:[(0,a.jsx)(ef.Z,{children:e.end_user}),(0,a.jsx)(ef.Z,{children:null===(t=e.total_spend)||void 0===t?void 0:t.toFixed(4)}),(0,a.jsx)(ef.Z,{children:e.total_count})]},l)})})]})})]}),(0,a.jsx)(eU.Z,{children:(0,a.jsxs)(W.Z,{numItems:2,className:"gap-2 h-[75vh] w-full mb-4",children:[(0,a.jsx)(Y.Z,{numColSpan:2,children:(0,a.jsxs)(ep.Z,{children:[(0,a.jsx)(el.Z,{children:"Spend Per Tag - Last 30 Days"}),(0,a.jsxs)(ee.Z,{children:["Get Started Tracking cost per tag ",(0,a.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/enterprise#tracking-spend-for-custom-tags",target:"_blank",children:"here"})]}),(0,a.jsxs)(eg.Z,{children:[(0,a.jsx)(eZ.Z,{children:(0,a.jsxs)(ew.Z,{children:[(0,a.jsx)(e_.Z,{children:"Tag"}),(0,a.jsx)(e_.Z,{children:"Spend"}),(0,a.jsx)(e_.Z,{children:"Requests"})]})}),(0,a.jsx)(ey.Z,{children:f.map(e=>(0,a.jsxs)(ew.Z,{children:[(0,a.jsx)(ef.Z,{children:e.name}),(0,a.jsx)(ef.Z,{children:e.value}),(0,a.jsx)(ef.Z,{children:e.log_count})]},e.name))})]})]})}),(0,a.jsx)(Y.Z,{numColSpan:2})]})})]})]})]})},lb=()=>{let{Title:e,Paragraph:l}=eT.default,[t,s]=(0,n.useState)(""),[r,i]=(0,n.useState)(null),[c,d]=(0,n.useState)(null),[u,h]=(0,n.useState)(null),[x,p]=(0,n.useState)(!0),j=(0,o.useSearchParams)(),[g,y]=(0,n.useState)({data:[]}),f=j.get("userID"),Z=j.get("token"),[_,w]=(0,n.useState)("api-keys"),[b,k]=(0,n.useState)(null);return(0,n.useEffect)(()=>{if(Z){let e=(0,eP.o)(Z);if(e){if(console.log("Decoded token:",e),console.log("Decoded key:",e.key),k(e.key),e.user_role){let l=function(e){if(!e)return"Undefined Role";switch(console.log("Received user role: ".concat(e.toLowerCase())),console.log("Received user role length: ".concat(e.toLowerCase().length)),e.toLowerCase()){case"app_owner":case"demo_app_owner":return"App Owner";case"app_admin":case"proxy_admin":return"Admin";case"proxy_admin_viewer":return"Admin Viewer";case"app_user":return"App User";default:return"Unknown Role"}}(e.user_role);console.log("Decoded user_role:",l),s(l),"Admin Viewer"==l&&w("usage")}else console.log("User role not defined");e.user_email?i(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))}}},[Z]),(0,a.jsx)(n.Suspense,{fallback:(0,a.jsx)("div",{children:"Loading..."}),children:(0,a.jsxs)("div",{className:"flex flex-col min-h-screen",children:[(0,a.jsx)(m,{userID:f,userRole:t,userEmail:r,showSSOBanner:x}),(0,a.jsxs)("div",{className:"flex flex-1 overflow-auto",children:[(0,a.jsx)("div",{className:"mt-8",children:(0,a.jsx)(lZ,{setPage:w,userRole:t,defaultSelectedKey:null})}),"api-keys"==_?(0,a.jsx)(eO,{userID:f,userRole:t,teams:c,keys:u,setUserRole:s,userEmail:r,setUserEmail:i,setTeams:d,setKeys:h}):"models"==_?(0,a.jsx)(e3,{userID:f,userRole:t,token:Z,accessToken:b,modelData:g,setModelData:y}):"llm-playground"==_?(0,a.jsx)(lj,{userID:f,userRole:t,token:Z,accessToken:b}):"users"==_?(0,a.jsx)(e9,{userID:f,userRole:t,token:Z,keys:u,teams:c,accessToken:b,setKeys:h}):"teams"==_?(0,a.jsx)(le,{teams:c,setTeams:d,searchParams:j,accessToken:b,userID:f,userRole:t}):"admin-panel"==_?(0,a.jsx)(lt,{setTeams:d,searchParams:j,accessToken:b,showSSOBanner:x}):"api_ref"==_?(0,a.jsx)(lx,{}):"settings"==_?(0,a.jsx)(la,{userID:f,userRole:t,accessToken:b}):"general-settings"==_?(0,a.jsx)(lu,{userID:f,userRole:t,accessToken:b,modelData:g}):(0,a.jsx)(lw,{userID:f,userRole:t,token:Z,accessToken:b,keys:u})]})]})})}}},function(e){e.O(0,[936,884,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/84BZ5uERcn4DsO4_POsLl/_buildManifest.js b/litellm/proxy/_experimental/out/_next/static/obp5wqVSVDMiDTC414cR8/_buildManifest.js similarity index 100% rename from litellm/proxy/_experimental/out/_next/static/84BZ5uERcn4DsO4_POsLl/_buildManifest.js rename to litellm/proxy/_experimental/out/_next/static/obp5wqVSVDMiDTC414cR8/_buildManifest.js diff --git a/litellm/proxy/_experimental/out/_next/static/84BZ5uERcn4DsO4_POsLl/_ssgManifest.js b/litellm/proxy/_experimental/out/_next/static/obp5wqVSVDMiDTC414cR8/_ssgManifest.js similarity index 100% rename from litellm/proxy/_experimental/out/_next/static/84BZ5uERcn4DsO4_POsLl/_ssgManifest.js rename to litellm/proxy/_experimental/out/_next/static/obp5wqVSVDMiDTC414cR8/_ssgManifest.js diff --git a/litellm/proxy/_experimental/out/index.html b/litellm/proxy/_experimental/out/index.html index 3b7da2dd1e..930018e005 100644 --- a/litellm/proxy/_experimental/out/index.html +++ b/litellm/proxy/_experimental/out/index.html @@ -1 +1 @@ -LiteLLM Dashboard \ No newline at end of file +LiteLLM Dashboard \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/index.txt b/litellm/proxy/_experimental/out/index.txt index 5b09187ac5..d67a480b37 100644 --- a/litellm/proxy/_experimental/out/index.txt +++ b/litellm/proxy/_experimental/out/index.txt @@ -1,7 +1,7 @@ 2:I[77831,[],""] -3:I[7926,["936","static/chunks/2f6dbc85-052c4579f80d66ae.js","884","static/chunks/884-7576ee407a2ecbe6.js","931","static/chunks/app/page-e6190351ac8da62a.js"],""] +3:I[7926,["936","static/chunks/2f6dbc85-052c4579f80d66ae.js","884","static/chunks/884-7576ee407a2ecbe6.js","931","static/chunks/app/page-6a39771cacf75ea6.js"],""] 4:I[5613,[],""] 5:I[31778,[],""] -0:["84BZ5uERcn4DsO4_POsLl",[[["",{"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/f04e46b02318b660.css","precedence":"next","crossOrigin":""}]],"$L6"]]]] +0:["obp5wqVSVDMiDTC414cR8",[[["",{"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/f04e46b02318b660.css","precedence":"next","crossOrigin":""}]],"$L6"]]]] 6:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"LiteLLM Dashboard"}],["$","meta","3",{"name":"description","content":"LiteLLM Proxy Admin UI"}],["$","link","4",{"rel":"icon","href":"/ui/favicon.ico","type":"image/x-icon","sizes":"16x16"}],["$","meta","5",{"name":"next-size-adjust"}]] 1:null diff --git a/litellm/proxy/_super_secret_config.yaml b/litellm/proxy/_super_secret_config.yaml index 832e351133..5f5ee89c3f 100644 --- a/litellm/proxy/_super_secret_config.yaml +++ b/litellm/proxy/_super_secret_config.yaml @@ -8,15 +8,28 @@ model_list: base_model: text-embedding-ada-002 mode: embedding model_name: text-embedding-ada-002 +- model_name: gpt-3.5-turbo-012 + litellm_params: + model: gpt-3.5-turbo + api_base: http://0.0.0.0:8080 + api_key: "" +- model_name: gpt-3.5-turbo-0125-preview + litellm_params: + model: azure/chatgpt-v-2 + api_key: os.environ/AZURE_API_KEY + api_base: os.environ/AZURE_API_BASE + input_cost_per_token: 0.0 + output_cost_per_token: 0.0 router_settings: redis_host: redis # redis_password: redis_port: 6379 + enable_pre_call_checks: true litellm_settings: set_verbose: True - enable_preview_features: true + fallbacks: [{"gpt-3.5-turbo-012": ["gpt-3.5-turbo-0125-preview"]}] # service_callback: ["prometheus_system"] # success_callback: ["prometheus"] # failure_callback: ["prometheus"] @@ -25,4 +38,5 @@ general_settings: enable_jwt_auth: True disable_reset_budget: True proxy_batch_write_at: 60 # ๐Ÿ‘ˆ Frequency of batch writing logs to server (in seconds) - routing_strategy: simple-shuffle # Literal["simple-shuffle", "least-busy", "usage-based-routing","latency-based-routing"], default="simple-shuffle" \ No newline at end of file + routing_strategy: simple-shuffle # Literal["simple-shuffle", "least-busy", "usage-based-routing","latency-based-routing"], default="simple-shuffle" + alerting: ["slack"] diff --git a/litellm/proxy/_types.py b/litellm/proxy/_types.py index a2776f465e..f91b768e67 100644 --- a/litellm/proxy/_types.py +++ b/litellm/proxy/_types.py @@ -82,6 +82,7 @@ class LiteLLMRoutes(enum.Enum): info_routes: List = [ "/key/info", "/team/info", + "/team/list", "/user/info", "/model/info", "/v2/model/info", @@ -110,6 +111,7 @@ class LiteLLMRoutes(enum.Enum): "/team/new", "/team/update", "/team/delete", + "/team/list", "/team/info", "/team/block", "/team/unblock", @@ -189,7 +191,12 @@ class LiteLLM_JWTAuth(LiteLLMBase): "spend_tracking_routes", "global_spend_tracking_routes", ] - ] = ["management_routes", "spend_tracking_routes", "global_spend_tracking_routes"] + ] = [ + "management_routes", + "spend_tracking_routes", + "global_spend_tracking_routes", + "info_routes", + ] team_jwt_scope: str = "litellm_team" team_id_jwt_field: str = "client_id" team_allowed_routes: List[ diff --git a/litellm/proxy/proxy_server.py b/litellm/proxy/proxy_server.py index b24290f50e..6388bd5fd1 100644 --- a/litellm/proxy/proxy_server.py +++ b/litellm/proxy/proxy_server.py @@ -3479,6 +3479,26 @@ async def startup_event(): await proxy_config.add_deployment( prisma_client=prisma_client, proxy_logging_obj=proxy_logging_obj ) + + if ( + proxy_logging_obj is not None + and proxy_logging_obj.slack_alerting_instance is not None + and prisma_client is not None + ): + print("Alerting: Initializing Weekly/Monthly Spend Reports") # noqa + ### Schedule weekly/monhtly spend reports ### + scheduler.add_job( + proxy_logging_obj.slack_alerting_instance.send_weekly_spend_report, + "cron", + day_of_week="mon", + ) + + scheduler.add_job( + proxy_logging_obj.slack_alerting_instance.send_monthly_spend_report, + "cron", + day=1, + ) + scheduler.start() @@ -3698,8 +3718,9 @@ async def chat_completion( # skip router if user passed their key if "api_key" in data: tasks.append(litellm.acompletion(**data)) - elif isinstance(data["model"], list) and llm_router is not None: - _models = data.pop("model") + elif "," in data["model"] and llm_router is not None: + _models_csv_string = data.pop("model") + _models = _models_csv_string.split(",") tasks.append(llm_router.abatch_completion(models=_models, **data)) elif "user_config" in data: # initialize a new router instance. make request using this Router @@ -3761,6 +3782,7 @@ async def chat_completion( "x-litellm-cache-key": cache_key, "x-litellm-model-api-base": api_base, "x-litellm-version": version, + "x-litellm-model-region": user_api_key_dict.allowed_model_region or "", } selected_data_generator = select_data_generator( response=response, @@ -3777,6 +3799,9 @@ async def chat_completion( fastapi_response.headers["x-litellm-cache-key"] = cache_key fastapi_response.headers["x-litellm-model-api-base"] = api_base fastapi_response.headers["x-litellm-version"] = version + fastapi_response.headers["x-litellm-model-region"] = ( + user_api_key_dict.allowed_model_region or "" + ) ### CALL HOOKS ### - modify outgoing data response = await proxy_logging_obj.post_call_success_hook( @@ -4161,6 +4186,9 @@ async def embeddings( fastapi_response.headers["x-litellm-cache-key"] = cache_key fastapi_response.headers["x-litellm-model-api-base"] = api_base fastapi_response.headers["x-litellm-version"] = version + fastapi_response.headers["x-litellm-model-region"] = ( + user_api_key_dict.allowed_model_region or "" + ) return response except Exception as e: @@ -4330,6 +4358,9 @@ async def image_generation( fastapi_response.headers["x-litellm-cache-key"] = cache_key fastapi_response.headers["x-litellm-model-api-base"] = api_base fastapi_response.headers["x-litellm-version"] = version + fastapi_response.headers["x-litellm-model-region"] = ( + user_api_key_dict.allowed_model_region or "" + ) return response except Exception as e: @@ -4523,6 +4554,9 @@ async def audio_transcriptions( fastapi_response.headers["x-litellm-cache-key"] = cache_key fastapi_response.headers["x-litellm-model-api-base"] = api_base fastapi_response.headers["x-litellm-version"] = version + fastapi_response.headers["x-litellm-model-region"] = ( + user_api_key_dict.allowed_model_region or "" + ) return response except Exception as e: @@ -4698,6 +4732,9 @@ async def moderations( fastapi_response.headers["x-litellm-cache-key"] = cache_key fastapi_response.headers["x-litellm-model-api-base"] = api_base fastapi_response.headers["x-litellm-version"] = version + fastapi_response.headers["x-litellm-model-region"] = ( + user_api_key_dict.allowed_model_region or "" + ) return response except Exception as e: @@ -5347,6 +5384,141 @@ async def view_spend_tags( ) +@router.get( + "/global/spend/report", + tags=["Budget & Spend Tracking"], + dependencies=[Depends(user_api_key_auth)], + include_in_schema=False, + responses={ + 200: {"model": List[LiteLLM_SpendLogs]}, + }, +) +async def get_global_spend_report( + start_date: Optional[str] = fastapi.Query( + default=None, + description="Time from which to start viewing spend", + ), + end_date: Optional[str] = fastapi.Query( + default=None, + description="Time till which to view spend", + ), +): + """ + Get Daily Spend per Team, based on specific startTime and endTime. Per team, view usage by each key, model + [ + { + "group-by-day": "2024-05-10", + "teams": [ + { + "team_name": "team-1" + "spend": 10, + "keys": [ + "key": "1213", + "usage": { + "model-1": { + "cost": 12.50, + "input_tokens": 1000, + "output_tokens": 5000, + "requests": 100 + }, + "audio-modelname1": { + "cost": 25.50, + "seconds": 25, + "requests": 50 + }, + } + } + ] + ] + } + """ + if start_date is None or end_date is None: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail={"error": "Please provide start_date and end_date"}, + ) + + start_date_obj = datetime.strptime(start_date, "%Y-%m-%d") + end_date_obj = datetime.strptime(end_date, "%Y-%m-%d") + + global prisma_client + try: + if prisma_client is None: + raise Exception( + f"Database not connected. Connect a database to your proxy - https://docs.litellm.ai/docs/simple_proxy#managing-auth---virtual-keys" + ) + + # first get data from spend logs -> SpendByModelApiKey + # then read data from "SpendByModelApiKey" to format the response obj + sql_query = """ + + WITH SpendByModelApiKey AS ( + SELECT + date_trunc('day', sl."startTime") AS group_by_day, + COALESCE(tt.team_alias, 'Unassigned Team') AS team_name, + sl.model, + sl.api_key, + SUM(sl.spend) AS model_api_spend, + SUM(sl.total_tokens) AS model_api_tokens + FROM + "LiteLLM_SpendLogs" sl + LEFT JOIN + "LiteLLM_TeamTable" tt + ON + sl.team_id = tt.team_id + WHERE + sl."startTime" BETWEEN $1::date AND $2::date + GROUP BY + date_trunc('day', sl."startTime"), + tt.team_alias, + sl.model, + sl.api_key + ) + SELECT + group_by_day, + jsonb_agg(jsonb_build_object( + 'team_name', team_name, + 'total_spend', total_spend, + 'metadata', metadata + )) AS teams + FROM ( + SELECT + group_by_day, + team_name, + SUM(model_api_spend) AS total_spend, + jsonb_agg(jsonb_build_object( + 'model', model, + 'api_key', api_key, + 'spend', model_api_spend, + 'total_tokens', model_api_tokens + )) AS metadata + FROM + SpendByModelApiKey + GROUP BY + group_by_day, + team_name + ) AS aggregated + GROUP BY + group_by_day + ORDER BY + group_by_day; + """ + + db_response = await prisma_client.db.query_raw( + sql_query, start_date_obj, end_date_obj + ) + if db_response is None: + return [] + + return db_response + + except Exception as e: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail={"error": str(e)}, + ) + + @router.get( "/global/spend/tags", tags=["Budget & Spend Tracking"], @@ -5391,6 +5563,13 @@ async def global_view_spend_tags( f"Database not connected. Connect a database to your proxy - https://docs.litellm.ai/docs/simple_proxy#managing-auth---virtual-keys" ) + if end_date is None or start_date is None: + raise ProxyException( + message="Please provide start_date and end_date", + type="bad_request", + param=None, + code=status.HTTP_400_BAD_REQUEST, + ) response = await ui_get_spend_by_tags( start_date=start_date, end_date=end_date, prisma_client=prisma_client ) @@ -5414,6 +5593,55 @@ async def global_view_spend_tags( ) +async def _get_spend_report_for_time_range( + start_date: str, + end_date: str, +): + global prisma_client + if prisma_client is None: + verbose_proxy_logger.error( + f"Database not connected. Connect a database to your proxy for weekly, monthly spend reports" + ) + return None + + try: + sql_query = """ + SELECT + t.team_alias, + SUM(s.spend) AS total_spend + FROM + "LiteLLM_SpendLogs" s + LEFT JOIN + "LiteLLM_TeamTable" t ON s.team_id = t.team_id + WHERE + s."startTime"::DATE >= $1::date AND s."startTime"::DATE <= $2::date + GROUP BY + t.team_alias + ORDER BY + total_spend DESC; + """ + response = await prisma_client.db.query_raw(sql_query, start_date, end_date) + + # get spend per tag for today + sql_query = """ + SELECT + jsonb_array_elements_text(request_tags) AS individual_request_tag, + SUM(spend) AS total_spend + FROM "LiteLLM_SpendLogs" + WHERE "startTime"::DATE >= $1::date AND "startTime"::DATE <= $2::date + GROUP BY individual_request_tag + ORDER BY total_spend DESC; + """ + + spend_per_tag = await prisma_client.db.query_raw( + sql_query, start_date, end_date + ) + + return response, spend_per_tag + except Exception as e: + verbose_proxy_logger.error("Exception in _get_daily_spend_reports", e) # noqa + + @router.post( "/spend/calculate", tags=["Budget & Spend Tracking"], @@ -5801,7 +6029,7 @@ async def global_spend_keys( tags=["Budget & Spend Tracking"], dependencies=[Depends(user_api_key_auth)], ) -async def global_spend_per_tea(): +async def global_spend_per_team(): """ [BETA] This is a beta endpoint. It will change. @@ -9486,6 +9714,14 @@ async def health_services_endpoint( level="Low", alert_type="budget_alerts", ) + + if prisma_client is not None: + asyncio.create_task( + proxy_logging_obj.slack_alerting_instance.send_monthly_spend_report() + ) + asyncio.create_task( + proxy_logging_obj.slack_alerting_instance.send_weekly_spend_report() + ) return { "status": "success", "message": "Mock Slack Alert sent, verify Slack Alert Received on your channel", diff --git a/litellm/router.py b/litellm/router.py index 4c03125005..b4603c6d07 100644 --- a/litellm/router.py +++ b/litellm/router.py @@ -9,7 +9,8 @@ import copy, httpx from datetime import datetime -from typing import Dict, List, Optional, Union, Literal, Any, BinaryIO, Tuple +from typing import Dict, List, Optional, Union, Literal, Any, BinaryIO, Tuple, TypedDict +from typing_extensions import overload import random, threading, time, traceback, uuid import litellm, openai, hashlib, json from litellm.caching import RedisCache, InMemoryCache, DualCache @@ -46,6 +47,7 @@ from litellm.types.router import ( updateLiteLLMParams, RetryPolicy, AlertingConfig, + DeploymentTypedDict, ) from litellm.integrations.custom_logger import CustomLogger from litellm.llms.azure import get_azure_ad_token_from_oidc @@ -61,7 +63,7 @@ class Router: def __init__( self, - model_list: Optional[list] = None, + model_list: Optional[List[Union[DeploymentTypedDict, Dict]]] = None, ## CACHING ## redis_url: Optional[str] = None, redis_host: Optional[str] = None, @@ -82,6 +84,9 @@ class Router: default_max_parallel_requests: Optional[int] = None, set_verbose: bool = False, debug_level: Literal["DEBUG", "INFO"] = "INFO", + default_fallbacks: Optional[ + List[str] + ] = None, # generic fallbacks, works across all deployments fallbacks: List = [], context_window_fallbacks: List = [], model_group_alias: Optional[dict] = {}, @@ -258,6 +263,11 @@ class Router: self.retry_after = retry_after self.routing_strategy = routing_strategy self.fallbacks = fallbacks or litellm.fallbacks + if default_fallbacks is not None: + if self.fallbacks is not None: + self.fallbacks.append({"*": default_fallbacks}) + else: + self.fallbacks = [{"*": default_fallbacks}] self.context_window_fallbacks = ( context_window_fallbacks or litellm.context_window_fallbacks ) @@ -469,12 +479,30 @@ class Router: ) raise e + # fmt: off + + @overload async def acompletion( - self, model: str, messages: List[Dict[str, str]], **kwargs - ) -> Union[ModelResponse, CustomStreamWrapper]: + self, model: str, messages: List[Dict[str, str]], stream: Literal[True], **kwargs + ) -> CustomStreamWrapper: + ... + + @overload + async def acompletion( + self, model: str, messages: List[Dict[str, str]], stream: Literal[False] = False, **kwargs + ) -> ModelResponse: + ... + + # fmt: on + + # The actual implementation of the function + async def acompletion( + self, model: str, messages: List[Dict[str, str]], stream=False, **kwargs + ): try: kwargs["model"] = model kwargs["messages"] = messages + kwargs["stream"] = stream kwargs["original_function"] = self._acompletion kwargs["num_retries"] = kwargs.get("num_retries", self.num_retries) @@ -1413,7 +1441,7 @@ class Router: verbose_router_logger.debug(f"Trying to fallback b/w models") if ( hasattr(e, "status_code") - and e.status_code == 400 + and e.status_code == 400 # type: ignore and not isinstance(e, litellm.ContextWindowExceededError) ): # don't retry a malformed request raise e @@ -1444,18 +1472,29 @@ class Router: response = await self.async_function_with_retries( *args, **kwargs ) + verbose_router_logger.info( + "Successful fallback b/w models." + ) return response except Exception as e: pass elif fallbacks is not None: verbose_router_logger.debug(f"inside model fallbacks: {fallbacks}") - for item in fallbacks: - key_list = list(item.keys()) - if len(key_list) == 0: - continue - if key_list[0] == model_group: + generic_fallback_idx: Optional[int] = None + ## check for specific model group-specific fallbacks + for idx, item in enumerate(fallbacks): + if list(item.keys())[0] == model_group: fallback_model_group = item[model_group] break + elif list(item.keys())[0] == "*": + generic_fallback_idx = idx + ## if none, check for generic fallback + if ( + fallback_model_group is None + and generic_fallback_idx is not None + ): + fallback_model_group = fallbacks[generic_fallback_idx]["*"] + if fallback_model_group is None: verbose_router_logger.info( f"No fallback model group found for original model_group={model_group}. Fallbacks={fallbacks}" @@ -1478,6 +1517,9 @@ class Router: response = await self.async_function_with_fallbacks( *args, **kwargs ) + verbose_router_logger.info( + "Successful fallback b/w models." + ) return response except Exception as e: raise e @@ -1512,7 +1554,7 @@ class Router: """ _healthy_deployments = await self._async_get_healthy_deployments( - model=kwargs.get("model"), + model=kwargs.get("model") or "", ) # raises an exception if this error should not be retries @@ -1619,12 +1661,18 @@ class Router: Try calling the function_with_retries If it fails after num_retries, fall back to another model group """ + mock_testing_fallbacks = kwargs.pop("mock_testing_fallbacks", None) model_group = kwargs.get("model") fallbacks = kwargs.get("fallbacks", self.fallbacks) context_window_fallbacks = kwargs.get( "context_window_fallbacks", self.context_window_fallbacks ) try: + if mock_testing_fallbacks is not None and mock_testing_fallbacks == True: + raise Exception( + f"This is a mock exception for model={model_group}, to trigger a fallback. Fallbacks={fallbacks}" + ) + response = self.function_with_retries(*args, **kwargs) return response except Exception as e: @@ -1633,7 +1681,7 @@ class Router: try: if ( hasattr(e, "status_code") - and e.status_code == 400 + and e.status_code == 400 # type: ignore and not isinstance(e, litellm.ContextWindowExceededError) ): # don't retry a malformed request raise e @@ -1675,10 +1723,20 @@ class Router: elif fallbacks is not None: verbose_router_logger.debug(f"inside model fallbacks: {fallbacks}") fallback_model_group = None - for item in fallbacks: + generic_fallback_idx: Optional[int] = None + ## check for specific model group-specific fallbacks + for idx, item in enumerate(fallbacks): if list(item.keys())[0] == model_group: fallback_model_group = item[model_group] break + elif list(item.keys())[0] == "*": + generic_fallback_idx = idx + ## if none, check for generic fallback + if ( + fallback_model_group is None + and generic_fallback_idx is not None + ): + fallback_model_group = fallbacks[generic_fallback_idx]["*"] if fallback_model_group is None: raise original_exception @@ -3259,13 +3317,12 @@ class Router: healthy_deployments.remove(deployment) # filter pre-call checks + _allowed_model_region = ( + request_kwargs.get("allowed_model_region") + if request_kwargs is not None + else None + ) if self.enable_pre_call_checks and messages is not None: - _allowed_model_region = ( - request_kwargs.get("allowed_model_region") - if request_kwargs is not None - else None - ) - if _allowed_model_region == "eu": healthy_deployments = self._pre_call_checks( model=model, @@ -3286,8 +3343,10 @@ class Router: ) if len(healthy_deployments) == 0: + if _allowed_model_region is None: + _allowed_model_region = "n/a" raise ValueError( - f"{RouterErrors.no_deployments_available.value}, passed model={model}" + f"{RouterErrors.no_deployments_available.value}, passed model={model}. Enable pre-call-checks={self.enable_pre_call_checks}, allowed_model_region={_allowed_model_region}" ) if ( @@ -3647,7 +3706,7 @@ class Router: ) asyncio.create_task( proxy_logging_obj.slack_alerting_instance.send_alert( - message=f"Router: Cooling down deployment: {_api_base}, for {self.cooldown_time} seconds. Got exception: {str(exception_status)}", + message=f"Router: Cooling down deployment: {_api_base}, for {self.cooldown_time} seconds. Got exception: {str(exception_status)}. Change 'cooldown_time' + 'allowed_failes' under 'Router Settings' on proxy UI, or via config - https://docs.litellm.ai/docs/proxy/reliability#fallbacks--retries--timeouts--cooldowns", alert_type="cooldown_deployment", level="Low", ) diff --git a/litellm/tests/test_alangfuse.py b/litellm/tests/test_alangfuse.py index db2e970a85..31f1f7bf86 100644 --- a/litellm/tests/test_alangfuse.py +++ b/litellm/tests/test_alangfuse.py @@ -228,6 +228,40 @@ async def test_langfuse_logging_without_request_response(stream, langfuse_client pytest.fail(f"An exception occurred - {e}") +@pytest.mark.asyncio +async def test_langfuse_masked_input_output(langfuse_client): + """ + Test that creates a trace with masked input and output + """ + import uuid + + for mask_value in [True, False]: + _unique_trace_name = f"litellm-test-{str(uuid.uuid4())}" + litellm.set_verbose = True + litellm.success_callback = ["langfuse"] + response = await create_async_task( + model="gpt-3.5-turbo", + messages=[{"role": "user", "content": "This is a test"}], + metadata={"trace_id": _unique_trace_name, "mask_input": mask_value, "mask_output": mask_value}, + mock_response="This is a test response" + ) + print(response) + expected_input = "redacted-by-litellm" if mask_value else {'messages': [{'content': 'This is a test', 'role': 'user'}]} + expected_output = "redacted-by-litellm" if mask_value else {'content': 'This is a test response', 'role': 'assistant'} + langfuse_client.flush() + await asyncio.sleep(2) + + # get trace with _unique_trace_name + trace = langfuse_client.get_trace(id=_unique_trace_name) + generations = list( + reversed(langfuse_client.get_generations(trace_id=_unique_trace_name).data) + ) + + assert trace.input == expected_input + assert trace.output == expected_output + assert generations[0].input == expected_input + assert generations[0].output == expected_output + @pytest.mark.asyncio async def test_langfuse_logging_metadata(langfuse_client): """ diff --git a/litellm/tests/test_amazing_vertex_completion.py b/litellm/tests/test_amazing_vertex_completion.py index a56d7fe5a9..c58541a7d0 100644 --- a/litellm/tests/test_amazing_vertex_completion.py +++ b/litellm/tests/test_amazing_vertex_completion.py @@ -590,19 +590,20 @@ def test_gemini_pro_vision_base64(): pytest.fail(f"An exception occurred - {str(e)}") +@pytest.mark.parametrize("sync_mode", [True, False]) @pytest.mark.asyncio -def test_gemini_pro_function_calling(): +async def test_gemini_pro_function_calling(sync_mode): try: load_vertex_ai_credentials() - response = litellm.completion( - model="vertex_ai/gemini-pro", - messages=[ + data = { + "model": "vertex_ai/gemini-pro", + "messages": [ { "role": "user", "content": "Call the submit_cities function with San Francisco and New York", } ], - tools=[ + "tools": [ { "type": "function", "function": { @@ -618,11 +619,13 @@ def test_gemini_pro_function_calling(): }, } ], - ) + } + if sync_mode: + response = litellm.completion(**data) + else: + response = await litellm.acompletion(**data) print(f"response: {response}") - except litellm.APIError as e: - pass except litellm.RateLimitError as e: pass except Exception as e: @@ -635,73 +638,66 @@ def test_gemini_pro_function_calling(): # gemini_pro_function_calling() -@pytest.mark.parametrize("stream", [False, True]) @pytest.mark.parametrize("sync_mode", [False, True]) @pytest.mark.asyncio -async def test_gemini_pro_function_calling_streaming(stream, sync_mode): +async def test_gemini_pro_function_calling_streaming(sync_mode): load_vertex_ai_credentials() litellm.set_verbose = True - tools = [ - { - "type": "function", - "function": { - "name": "get_current_weather", - "description": "Get the current weather in a given location", - "parameters": { - "type": "object", - "properties": { - "location": { - "type": "string", - "description": "The city and state, e.g. San Francisco, CA", + data = { + "model": "vertex_ai/gemini-pro", + "messages": [ + { + "role": "user", + "content": "Call the submit_cities function with San Francisco and New York", + } + ], + "tools": [ + { + "type": "function", + "function": { + "name": "submit_cities", + "description": "Submits a list of cities", + "parameters": { + "type": "object", + "properties": { + "cities": {"type": "array", "items": {"type": "string"}} }, - "unit": {"type": "string", "enum": ["celsius", "fahrenheit"]}, + "required": ["cities"], }, - "required": ["location"], }, - }, - } - ] - messages = [ - { - "role": "user", - "content": "What's the weather like in Boston today in fahrenheit?", - } - ] - optional_params = { - "tools": tools, + } + ], "tool_choice": "auto", "n": 1, - "stream": stream, + "stream": True, "temperature": 0.1, } + chunks = [] try: if sync_mode == True: - response = litellm.completion( - model="gemini-pro", messages=messages, **optional_params - ) + response = litellm.completion(**data) print(f"completion: {response}") - if stream == True: - # assert completion.choices[0].message.content is None - # assert len(completion.choices[0].message.tool_calls) == 1 - for chunk in response: - assert isinstance(chunk, litellm.ModelResponse) - else: - assert isinstance(response, litellm.ModelResponse) + for chunk in response: + chunks.append(chunk) + assert isinstance(chunk, litellm.ModelResponse) else: - response = await litellm.acompletion( - model="gemini-pro", messages=messages, **optional_params - ) + response = await litellm.acompletion(**data) print(f"completion: {response}") - if stream == True: - # assert completion.choices[0].message.content is None - # assert len(completion.choices[0].message.tool_calls) == 1 - async for chunk in response: - print(f"chunk: {chunk}") - assert isinstance(chunk, litellm.ModelResponse) - else: - assert isinstance(response, litellm.ModelResponse) + assert isinstance(response, litellm.CustomStreamWrapper) + + async for chunk in response: + print(f"chunk: {chunk}") + chunks.append(chunk) + assert isinstance(chunk, litellm.ModelResponse) + + complete_response = litellm.stream_chunk_builder(chunks=chunks) + assert ( + complete_response.choices[0].message.content is not None + or len(complete_response.choices[0].message.tool_calls) > 0 + ) + print(f"complete_response: {complete_response}") except litellm.APIError as e: pass except litellm.RateLimitError as e: diff --git a/litellm/tests/test_azure_perf.py b/litellm/tests/test_azure_perf.py index 9654f12734..8afc59f929 100644 --- a/litellm/tests/test_azure_perf.py +++ b/litellm/tests/test_azure_perf.py @@ -26,7 +26,7 @@ model_list = [ } ] -router = litellm.Router(model_list=model_list) +router = litellm.Router(model_list=model_list) # type: ignore async def _openai_completion(): diff --git a/litellm/tests/test_completion.py b/litellm/tests/test_completion.py index 310a5f8186..ccc73a2603 100644 --- a/litellm/tests/test_completion.py +++ b/litellm/tests/test_completion.py @@ -68,6 +68,51 @@ def test_completion_custom_provider_model_name(): pytest.fail(f"Error occurred: {e}") +def _openai_mock_response(*args, **kwargs) -> litellm.ModelResponse: + _data = { + "id": "chatcmpl-123", + "object": "chat.completion", + "created": 1677652288, + "model": "gpt-3.5-turbo-0125", + "system_fingerprint": "fp_44709d6fcb", + "choices": [ + { + "index": 0, + "message": { + "role": None, + "content": "\n\nHello there, how may I assist you today?", + }, + "logprobs": None, + "finish_reason": "stop", + } + ], + "usage": {"prompt_tokens": 9, "completion_tokens": 12, "total_tokens": 21}, + } + return litellm.ModelResponse(**_data) + + +def test_null_role_response(): + """ + Test if api returns 'null' role, 'assistant' role is still returned + """ + import openai + + openai_client = openai.OpenAI() + with patch.object( + openai_client.chat.completions, "create", side_effect=_openai_mock_response + ) as mock_response: + response = litellm.completion( + model="gpt-3.5-turbo", + messages=[{"role": "user", "content": "Hey! how's it going?"}], + client=openai_client, + ) + print(f"response: {response}") + + assert response.id == "chatcmpl-123" + + assert response.choices[0].message.role == "assistant" + + def test_completion_azure_command_r(): try: litellm.set_verbose = True @@ -665,6 +710,7 @@ def test_completion_mistral_api(): "content": "Hey, how's it going?", } ], + seed=10, ) # Add any assertions here to check the response print(response) @@ -839,7 +885,7 @@ async def test_acompletion_claude2_1(): }, {"role": "user", "content": "Generate a 3 liner joke for me"}, ] - # test without max tokens + # test without max-tokens response = await litellm.acompletion(model="claude-2.1", messages=messages) # Add any assertions here to check the response print(response) @@ -3296,6 +3342,8 @@ def test_completion_watsonx(): print(response) except litellm.APIError as e: pass + except litellm.RateLimitError as e: + pass except Exception as e: pytest.fail(f"Error occurred: {e}") @@ -3315,6 +3363,8 @@ def test_completion_stream_watsonx(): print(chunk) except litellm.APIError as e: pass + except litellm.RateLimitError as e: + pass except Exception as e: pytest.fail(f"Error occurred: {e}") @@ -3379,6 +3429,8 @@ async def test_acompletion_watsonx(): ) # Add any assertions here to check the response print(response) + except litellm.RateLimitError as e: + pass except Exception as e: pytest.fail(f"Error occurred: {e}") @@ -3399,6 +3451,8 @@ async def test_acompletion_stream_watsonx(): # Add any assertions here to check the response async for chunk in response: print(chunk) + except litellm.RateLimitError as e: + pass except Exception as e: pytest.fail(f"Error occurred: {e}") diff --git a/litellm/tests/test_completion_cost.py b/litellm/tests/test_completion_cost.py index 35e0496fb4..8b817eb3cf 100644 --- a/litellm/tests/test_completion_cost.py +++ b/litellm/tests/test_completion_cost.py @@ -5,6 +5,7 @@ sys.path.insert( 0, os.path.abspath("../..") ) # Adds the parent directory to the system path import time +from typing import Optional import litellm from litellm import ( get_max_tokens, @@ -12,7 +13,56 @@ from litellm import ( open_ai_chat_completion_models, TranscriptionResponse, ) -import pytest +from litellm.utils import CustomLogger +import pytest, asyncio + + +class CustomLoggingHandler(CustomLogger): + response_cost: Optional[float] = None + + def __init__(self): + super().__init__() + + def log_success_event(self, kwargs, response_obj, start_time, end_time): + self.response_cost = kwargs["response_cost"] + + async def async_log_success_event(self, kwargs, response_obj, start_time, end_time): + print(f"kwargs - {kwargs}") + print(f"kwargs response cost - {kwargs.get('response_cost')}") + self.response_cost = kwargs["response_cost"] + + print(f"response_cost: {self.response_cost} ") + + +@pytest.mark.parametrize("sync_mode", [True, False]) +@pytest.mark.asyncio +async def test_custom_pricing(sync_mode): + new_handler = CustomLoggingHandler() + litellm.callbacks = [new_handler] + if sync_mode: + response = litellm.completion( + model="gpt-3.5-turbo", + messages=[{"role": "user", "content": "Hey!"}], + mock_response="What do you want?", + input_cost_per_token=0.0, + output_cost_per_token=0.0, + ) + time.sleep(5) + else: + response = await litellm.acompletion( + model="gpt-3.5-turbo", + messages=[{"role": "user", "content": "Hey!"}], + mock_response="What do you want?", + input_cost_per_token=0.0, + output_cost_per_token=0.0, + ) + + await asyncio.sleep(5) + + print(f"new_handler.response_cost: {new_handler.response_cost}") + assert new_handler.response_cost is not None + + assert new_handler.response_cost == 0 def test_get_gpt3_tokens(): diff --git a/litellm/tests/test_embedding.py b/litellm/tests/test_embedding.py index 8da847b64e..a441b0e70f 100644 --- a/litellm/tests/test_embedding.py +++ b/litellm/tests/test_embedding.py @@ -494,6 +494,8 @@ def test_watsonx_embeddings(): ) print(f"response: {response}") assert isinstance(response.usage, litellm.Usage) + except litellm.RateLimitError as e: + pass except Exception as e: pytest.fail(f"Error occurred: {e}") diff --git a/litellm/tests/test_function_calling.py b/litellm/tests/test_function_calling.py index aedc21665b..0d0a593d53 100644 --- a/litellm/tests/test_function_calling.py +++ b/litellm/tests/test_function_calling.py @@ -37,14 +37,19 @@ def get_current_weather(location, unit="fahrenheit"): # Example dummy function hard coded to return the same weather + + # In production, this could be your backend API or an external API -def test_parallel_function_call(): +@pytest.mark.parametrize( + "model", ["gpt-3.5-turbo-1106", "mistral/mistral-large-latest"] +) +def test_parallel_function_call(model): try: # Step 1: send the conversation and available functions to the model messages = [ { "role": "user", - "content": "What's the weather like in San Francisco, Tokyo, and Paris?", + "content": "What's the weather like in San Francisco, Tokyo, and Paris? - give me 3 responses", } ] tools = [ @@ -58,7 +63,7 @@ def test_parallel_function_call(): "properties": { "location": { "type": "string", - "description": "The city and state, e.g. San Francisco, CA", + "description": "The city and state", }, "unit": { "type": "string", @@ -71,7 +76,7 @@ def test_parallel_function_call(): } ] response = litellm.completion( - model="gpt-3.5-turbo-1106", + model=model, messages=messages, tools=tools, tool_choice="auto", # auto is default, but we'll be explicit @@ -83,8 +88,8 @@ def test_parallel_function_call(): print("length of tool calls", len(tool_calls)) print("Expecting there to be 3 tool calls") assert ( - len(tool_calls) > 1 - ) # this has to call the function for SF, Tokyo and parise + len(tool_calls) > 0 + ) # this has to call the function for SF, Tokyo and paris # Step 2: check if the model wanted to call a function if tool_calls: @@ -116,7 +121,7 @@ def test_parallel_function_call(): ) # extend conversation with function response print(f"messages: {messages}") second_response = litellm.completion( - model="gpt-3.5-turbo-1106", messages=messages, temperature=0.2, seed=22 + model=model, messages=messages, temperature=0.2, seed=22 ) # get a new response from the model where it can see the function response print("second response\n", second_response) return second_response diff --git a/litellm/tests/test_router.py b/litellm/tests/test_router.py index 7c59acb799..40b0410a43 100644 --- a/litellm/tests/test_router.py +++ b/litellm/tests/test_router.py @@ -134,11 +134,13 @@ async def test_router_retries(sync_mode): messages=[{"role": "user", "content": "Hey, how's it going?"}], ) else: - await router.acompletion( + response = await router.acompletion( model="gpt-3.5-turbo", messages=[{"role": "user", "content": "Hey, how's it going?"}], ) + print(response.choices[0].message) + @pytest.mark.parametrize( "mistral_api_base", diff --git a/litellm/tests/test_router_debug_logs.py b/litellm/tests/test_router_debug_logs.py index 202038d979..1d908abe81 100644 --- a/litellm/tests/test_router_debug_logs.py +++ b/litellm/tests/test_router_debug_logs.py @@ -85,6 +85,7 @@ def test_async_fallbacks(caplog): "litellm.acompletion(model=gpt-3.5-turbo)\x1b[31m Exception OpenAIException - Error code: 401 - {'error': {'message': 'Incorrect API key provided: bad-key. You can find your API key at https://platform.openai.com/account/api-keys.', 'type': 'invalid_request_error', 'param': None, 'code': 'invalid_api_key'}} \nModel: gpt-3.5-turbo\nAPI Base: https://api.openai.com\nMessages: [{'content': 'Hello, how are you?', 'role': 'user'}]\nmodel_group: gpt-3.5-turbo\n\ndeployment: gpt-3.5-turbo\n\x1b[0m", "Falling back to model_group = azure/gpt-3.5-turbo", "litellm.acompletion(model=azure/chatgpt-v-2)\x1b[32m 200 OK\x1b[0m", + "Successful fallback b/w models.", ] # Assert that the captured logs match the expected log messages diff --git a/litellm/tests/test_router_fallbacks.py b/litellm/tests/test_router_fallbacks.py index c1035e3e00..4ab97b274d 100644 --- a/litellm/tests/test_router_fallbacks.py +++ b/litellm/tests/test_router_fallbacks.py @@ -961,3 +961,96 @@ def test_custom_cooldown_times(): except Exception as e: print(e) + + +@pytest.mark.parametrize("sync_mode", [True, False]) +@pytest.mark.asyncio +async def test_service_unavailable_fallbacks(sync_mode): + """ + Initial model - openai + Fallback - azure + + Error - 503, service unavailable + """ + router = Router( + model_list=[ + { + "model_name": "gpt-3.5-turbo-012", + "litellm_params": { + "model": "gpt-3.5-turbo", + "api_key": "anything", + "api_base": "http://0.0.0.0:8080", + }, + }, + { + "model_name": "gpt-3.5-turbo-0125-preview", + "litellm_params": { + "model": "azure/chatgpt-v-2", + "api_key": os.getenv("AZURE_API_KEY"), + "api_version": os.getenv("AZURE_API_VERSION"), + "api_base": os.getenv("AZURE_API_BASE"), + }, + }, + ], + fallbacks=[{"gpt-3.5-turbo-012": ["gpt-3.5-turbo-0125-preview"]}], + ) + + if sync_mode: + response = router.completion( + model="gpt-3.5-turbo-012", + messages=[{"role": "user", "content": "Hey, how's it going?"}], + ) + else: + response = await router.acompletion( + model="gpt-3.5-turbo-012", + messages=[{"role": "user", "content": "Hey, how's it going?"}], + ) + + assert response.model == "gpt-35-turbo" + + +@pytest.mark.parametrize("sync_mode", [True, False]) +@pytest.mark.asyncio +async def test_default_model_fallbacks(sync_mode): + """ + Related issue - https://github.com/BerriAI/litellm/issues/3623 + + If model misconfigured, setup a default model for generic fallback + """ + router = Router( + model_list=[ + { + "model_name": "bad-model", + "litellm_params": { + "model": "openai/my-bad-model", + "api_key": "my-bad-api-key", + }, + }, + { + "model_name": "my-good-model", + "litellm_params": { + "model": "gpt-4o", + "api_key": os.getenv("OPENAI_API_KEY"), + }, + }, + ], + default_fallbacks=["my-good-model"], + ) + + if sync_mode: + response = router.completion( + model="bad-model", + messages=[{"role": "user", "content": "Hey, how's it going?"}], + mock_testing_fallbacks=True, + mock_response="Hey! nice day", + ) + else: + response = await router.acompletion( + model="bad-model", + messages=[{"role": "user", "content": "Hey, how's it going?"}], + mock_testing_fallbacks=True, + mock_response="Hey! nice day", + ) + + assert isinstance(response, litellm.ModelResponse) + assert response.model is not None and response.model == "gpt-4o" diff --git a/litellm/tests/test_streaming.py b/litellm/tests/test_streaming.py index a948a5683a..6dcdbeb177 100644 --- a/litellm/tests/test_streaming.py +++ b/litellm/tests/test_streaming.py @@ -456,7 +456,8 @@ def test_completion_claude_stream(): print(f"completion_response: {complete_response}") except Exception as e: pytest.fail(f"Error occurred: {e}") - + + # test_completion_claude_stream() def test_completion_claude_2_stream(): litellm.set_verbose = True @@ -1416,6 +1417,8 @@ def test_completion_watsonx_stream(): raise Exception("finish reason not set for last chunk") if complete_response.strip() == "": raise Exception("Empty response received") + except litellm.RateLimitError as e: + pass except Exception as e: pytest.fail(f"Error occurred: {e}") diff --git a/litellm/types/router.py b/litellm/types/router.py index e8f3ff6412..68ee387fea 100644 --- a/litellm/types/router.py +++ b/litellm/types/router.py @@ -1,4 +1,4 @@ -from typing import List, Optional, Union, Dict, Tuple, Literal +from typing import List, Optional, Union, Dict, Tuple, Literal, TypedDict import httpx from pydantic import BaseModel, validator, Field from .completion import CompletionRequest @@ -277,6 +277,47 @@ class updateDeployment(BaseModel): protected_namespaces = () +class LiteLLMParamsTypedDict(TypedDict, total=False): + """ + [TODO] + - allow additional params (not in list) + - set value to none if not set -> don't raise error if value not set + """ + + model: str + custom_llm_provider: Optional[str] + tpm: Optional[int] + rpm: Optional[int] + api_key: Optional[str] + api_base: Optional[str] + api_version: Optional[str] + timeout: Optional[Union[float, str, httpx.Timeout]] + stream_timeout: Optional[Union[float, str]] + max_retries: Optional[int] + organization: Optional[str] # for openai orgs + ## UNIFIED PROJECT/REGION ## + region_name: Optional[str] + ## VERTEX AI ## + vertex_project: Optional[str] + vertex_location: Optional[str] + ## AWS BEDROCK / SAGEMAKER ## + aws_access_key_id: Optional[str] + aws_secret_access_key: Optional[str] + aws_region_name: Optional[str] + ## IBM WATSONX ## + watsonx_region_name: Optional[str] + ## CUSTOM PRICING ## + input_cost_per_token: Optional[float] + output_cost_per_token: Optional[float] + input_cost_per_second: Optional[float] + output_cost_per_second: Optional[float] + + +class DeploymentTypedDict(TypedDict): + model_name: str + litellm_params: LiteLLMParamsTypedDict + + class Deployment(BaseModel): model_name: str litellm_params: LiteLLM_Params diff --git a/litellm/utils.py b/litellm/utils.py index f77baf8bd3..ab0f5c529a 100644 --- a/litellm/utils.py +++ b/litellm/utils.py @@ -13,6 +13,7 @@ import dotenv, json, traceback, threading, base64, ast import subprocess, os from os.path import abspath, join, dirname import litellm, openai + import itertools import random, uuid, requests # type: ignore from functools import wraps @@ -1083,6 +1084,8 @@ class CallTypes(Enum): class Logging: global supabaseClient, liteDebuggerClient, promptLayerLogger, weightsBiasesLogger, langsmithLogger, capture_exception, add_breadcrumb, lunaryLogger + custom_pricing: bool = False + def __init__( self, model, @@ -1165,6 +1168,15 @@ class Logging: **additional_params, } + ## check if custom pricing set ## + if ( + litellm_params.get("input_cost_per_token") is not None + or litellm_params.get("input_cost_per_second") is not None + or litellm_params.get("output_cost_per_token") is not None + or litellm_params.get("output_cost_per_second") is not None + ): + self.custom_pricing = True + def _pre_call(self, input, api_key, model=None, additional_args={}): """ Common helper function across the sync + async pre-call function @@ -1442,10 +1454,18 @@ class Logging: ) ) else: + base_model: Optional[str] = None # check if base_model set on azure base_model = _get_base_model_from_metadata( model_call_details=self.model_call_details ) + # litellm model name + litellm_model = self.model_call_details["model"] + if ( + litellm_model in litellm.model_cost + and self.custom_pricing == True + ): + base_model = litellm_model # base_model defaults to None if not set on model_info self.model_call_details["response_cost"] = ( litellm.completion_cost( @@ -4365,7 +4385,7 @@ def completion_cost( size=None, quality=None, n=None, # number of images -): +) -> float: """ Calculate the cost of a given completion call fot GPT-3.5-turbo, llama2, any litellm supported llm. @@ -4386,10 +4406,10 @@ def completion_cost( - If completion_response is not provided, the function calculates token counts based on the model and input text. - The cost is calculated based on the model, prompt tokens, and completion tokens. - For certain models containing "togethercomputer" in the name, prices are based on the model size. - - For Replicate models, the cost is calculated based on the total time used for the request. + - For un-mapped Replicate models, the cost is calculated based on the total time used for the request. Exceptions: - - If an error occurs during execution, the function returns 0.0 without blocking the user's execution path. + - If an error occurs during execution, the error is raised """ try: if ( @@ -4701,6 +4721,10 @@ def get_litellm_params( acompletion=None, preset_cache_key=None, no_log=None, + input_cost_per_second=None, + input_cost_per_token=None, + output_cost_per_token=None, + output_cost_per_second=None, ): litellm_params = { "acompletion": acompletion, @@ -4719,6 +4743,10 @@ def get_litellm_params( "preset_cache_key": preset_cache_key, "no-log": no_log, "stream_response": {}, # litellm_call_id: ModelResponse Dict + "input_cost_per_token": input_cost_per_token, + "input_cost_per_second": input_cost_per_second, + "output_cost_per_token": output_cost_per_token, + "output_cost_per_second": output_cost_per_second, } return litellm_params @@ -5617,32 +5645,9 @@ def get_optional_params( model=model, custom_llm_provider=custom_llm_provider ) _check_valid_arg(supported_params=supported_params) - if temperature is not None: - optional_params["temperature"] = temperature - if top_p is not None: - optional_params["top_p"] = top_p - if stream is not None: - optional_params["stream"] = stream - if max_tokens is not None: - optional_params["max_tokens"] = max_tokens - if tools is not None: - optional_params["tools"] = tools - if tool_choice is not None: - optional_params["tool_choice"] = tool_choice - if response_format is not None: - optional_params["response_format"] = response_format - # check safe_mode, random_seed: https://docs.mistral.ai/api/#operation/createChatCompletion - safe_mode = passed_params.pop("safe_mode", None) - random_seed = passed_params.pop("random_seed", None) - extra_body = {} - if safe_mode is not None: - extra_body["safe_mode"] = safe_mode - if random_seed is not None: - extra_body["random_seed"] = random_seed - optional_params["extra_body"] = ( - extra_body # openai client supports `extra_body` param + optional_params = litellm.MistralConfig().map_openai_params( + non_default_params=non_default_params, optional_params=optional_params ) - elif custom_llm_provider == "groq": supported_params = get_supported_openai_params( model=model, custom_llm_provider=custom_llm_provider @@ -5843,7 +5848,8 @@ def get_optional_params( for k in passed_params.keys(): if k not in default_params.keys(): extra_body[k] = passed_params[k] - optional_params["extra_body"] = extra_body + optional_params.setdefault("extra_body", {}) + optional_params["extra_body"] = {**optional_params["extra_body"], **extra_body} else: # if user passed in non-default kwargs for specific providers/models, pass them along for k in passed_params.keys(): @@ -6212,15 +6218,7 @@ def get_supported_openai_params(model: str, custom_llm_provider: str): "max_retries", ] elif custom_llm_provider == "mistral": - return [ - "temperature", - "top_p", - "stream", - "max_tokens", - "tools", - "tool_choice", - "response_format", - ] + return litellm.MistralConfig().get_supported_openai_params() elif custom_llm_provider == "replicate": return [ "stream", @@ -7712,7 +7710,7 @@ def convert_to_model_response_object( for idx, choice in enumerate(response_object["choices"]): message = Message( content=choice["message"].get("content", None), - role=choice["message"]["role"], + role=choice["message"]["role"] or "assistant", function_call=choice["message"].get("function_call", None), tool_calls=choice["message"].get("tool_calls", None), ) @@ -8516,6 +8514,15 @@ def exception_type( model=model, request=original_exception.request, ) + elif custom_llm_provider == "watsonx": + if "token_quota_reached" in error_str: + exception_mapping_worked = True + raise RateLimitError( + message=f"WatsonxException: Rate Limit Errror - {error_str}", + llm_provider="watsonx", + model=model, + response=original_exception.response, + ) elif custom_llm_provider == "bedrock": if ( "too many tokens" in error_str @@ -10761,6 +10768,8 @@ class CustomStreamWrapper: else: completion_obj["content"] = str(chunk) elif self.custom_llm_provider and (self.custom_llm_provider == "vertex_ai"): + import proto # type: ignore + if self.model.startswith("claude-3"): response_obj = self.handle_vertexai_anthropic_chunk(chunk=chunk) if response_obj is None: @@ -10798,10 +10807,24 @@ class CustomStreamWrapper: function_call = ( chunk.candidates[0].content.parts[0].function_call ) + args_dict = {} - for k, v in function_call.args.items(): - args_dict[k] = v - args_str = json.dumps(args_dict) + + # Check if it's a RepeatedComposite instance + for key, val in function_call.args.items(): + if isinstance( + val, + proto.marshal.collections.repeated.RepeatedComposite, + ): + # If so, convert to list + args_dict[key] = [v for v in val] + else: + args_dict[key] = val + + try: + args_str = json.dumps(args_dict) + except Exception as e: + raise e _delta_obj = litellm.utils.Delta( content=None, tool_calls=[ diff --git a/model_prices_and_context_window.json b/model_prices_and_context_window.json index 11e24dbdd3..0a262e3108 100644 --- a/model_prices_and_context_window.json +++ b/model_prices_and_context_window.json @@ -9,6 +9,30 @@ "mode": "chat", "supports_function_calling": true }, + "gpt-4o": { + "max_tokens": 4096, + "max_input_tokens": 128000, + "max_output_tokens": 4096, + "input_cost_per_token": 0.000005, + "output_cost_per_token": 0.000015, + "litellm_provider": "openai", + "mode": "chat", + "supports_function_calling": true, + "supports_parallel_function_calling": true, + "supports_vision": true + }, + "gpt-4o-2024-05-13": { + "max_tokens": 4096, + "max_input_tokens": 128000, + "max_output_tokens": 4096, + "input_cost_per_token": 0.000005, + "output_cost_per_token": 0.000015, + "litellm_provider": "openai", + "mode": "chat", + "supports_function_calling": true, + "supports_parallel_function_calling": true, + "supports_vision": true + }, "gpt-4-turbo-preview": { "max_tokens": 4096, "max_input_tokens": 128000, @@ -3366,4 +3390,4 @@ "mode": "embedding" } -} \ No newline at end of file +} diff --git a/poetry.lock b/poetry.lock index f3f7d40d5b..0c211500fb 100644 --- a/poetry.lock +++ b/poetry.lock @@ -667,22 +667,46 @@ test = ["pytest (>=6)"] [[package]] name = "fastapi" -version = "0.109.2" +version = "0.111.0" description = "FastAPI framework, high performance, easy to learn, fast to code, ready for production" optional = true python-versions = ">=3.8" files = [ - {file = "fastapi-0.109.2-py3-none-any.whl", hash = "sha256:2c9bab24667293b501cad8dd388c05240c850b58ec5876ee3283c47d6e1e3a4d"}, - {file = "fastapi-0.109.2.tar.gz", hash = "sha256:f3817eac96fe4f65a2ebb4baa000f394e55f5fccdaf7f75250804bc58f354f73"}, + {file = "fastapi-0.111.0-py3-none-any.whl", hash = "sha256:97ecbf994be0bcbdadedf88c3150252bed7b2087075ac99735403b1b76cc8fc0"}, + {file = "fastapi-0.111.0.tar.gz", hash = "sha256:b9db9dd147c91cb8b769f7183535773d8741dd46f9dc6676cd82eab510228cd7"}, ] [package.dependencies] +email_validator = ">=2.0.0" +fastapi-cli = ">=0.0.2" +httpx = ">=0.23.0" +jinja2 = ">=2.11.2" +orjson = ">=3.2.1" pydantic = ">=1.7.4,<1.8 || >1.8,<1.8.1 || >1.8.1,<2.0.0 || >2.0.0,<2.0.1 || >2.0.1,<2.1.0 || >2.1.0,<3.0.0" -starlette = ">=0.36.3,<0.37.0" +python-multipart = ">=0.0.7" +starlette = ">=0.37.2,<0.38.0" typing-extensions = ">=4.8.0" +ujson = ">=4.0.1,<4.0.2 || >4.0.2,<4.1.0 || >4.1.0,<4.2.0 || >4.2.0,<4.3.0 || >4.3.0,<5.0.0 || >5.0.0,<5.1.0 || >5.1.0" +uvicorn = {version = ">=0.12.0", extras = ["standard"]} [package.extras] -all = ["email-validator (>=2.0.0)", "httpx (>=0.23.0)", "itsdangerous (>=1.1.0)", "jinja2 (>=2.11.2)", "orjson (>=3.2.1)", "pydantic-extra-types (>=2.0.0)", "pydantic-settings (>=2.0.0)", "python-multipart (>=0.0.7)", "pyyaml (>=5.3.1)", "ujson (>=4.0.1,!=4.0.2,!=4.1.0,!=4.2.0,!=4.3.0,!=5.0.0,!=5.1.0)", "uvicorn[standard] (>=0.12.0)"] +all = ["email_validator (>=2.0.0)", "httpx (>=0.23.0)", "itsdangerous (>=1.1.0)", "jinja2 (>=2.11.2)", "orjson (>=3.2.1)", "pydantic-extra-types (>=2.0.0)", "pydantic-settings (>=2.0.0)", "python-multipart (>=0.0.7)", "pyyaml (>=5.3.1)", "ujson (>=4.0.1,!=4.0.2,!=4.1.0,!=4.2.0,!=4.3.0,!=5.0.0,!=5.1.0)", "uvicorn[standard] (>=0.12.0)"] + +[[package]] +name = "fastapi-cli" +version = "0.0.3" +description = "Run and manage FastAPI apps from the command line with FastAPI CLI. ๐Ÿš€" +optional = true +python-versions = ">=3.8" +files = [ + {file = "fastapi_cli-0.0.3-py3-none-any.whl", hash = "sha256:ae233115f729945479044917d949095e829d2d84f56f55ce1ca17627872825a5"}, + {file = "fastapi_cli-0.0.3.tar.gz", hash = "sha256:3b6e4d2c4daee940fb8db59ebbfd60a72c4b962bcf593e263e4cc69da4ea3d7f"}, +] + +[package.dependencies] +fastapi = "*" +typer = ">=0.12.3" +uvicorn = {version = ">=0.15.0", extras = ["standard"]} [[package]] name = "fastapi-sso" @@ -1087,6 +1111,54 @@ http2 = ["h2 (>=3,<5)"] socks = ["socksio (==1.*)"] trio = ["trio (>=0.22.0,<0.26.0)"] +[[package]] +name = "httptools" +version = "0.6.1" +description = "A collection of framework independent HTTP protocol utils." +optional = true +python-versions = ">=3.8.0" +files = [ + {file = "httptools-0.6.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d2f6c3c4cb1948d912538217838f6e9960bc4a521d7f9b323b3da579cd14532f"}, + {file = "httptools-0.6.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:00d5d4b68a717765b1fabfd9ca755bd12bf44105eeb806c03d1962acd9b8e563"}, + {file = "httptools-0.6.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:639dc4f381a870c9ec860ce5c45921db50205a37cc3334e756269736ff0aac58"}, + {file = "httptools-0.6.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e57997ac7fb7ee43140cc03664de5f268813a481dff6245e0075925adc6aa185"}, + {file = "httptools-0.6.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0ac5a0ae3d9f4fe004318d64b8a854edd85ab76cffbf7ef5e32920faef62f142"}, + {file = "httptools-0.6.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:3f30d3ce413088a98b9db71c60a6ada2001a08945cb42dd65a9a9fe228627658"}, + {file = "httptools-0.6.1-cp310-cp310-win_amd64.whl", hash = "sha256:1ed99a373e327f0107cb513b61820102ee4f3675656a37a50083eda05dc9541b"}, + {file = "httptools-0.6.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:7a7ea483c1a4485c71cb5f38be9db078f8b0e8b4c4dc0210f531cdd2ddac1ef1"}, + {file = "httptools-0.6.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:85ed077c995e942b6f1b07583e4eb0a8d324d418954fc6af913d36db7c05a5a0"}, + {file = "httptools-0.6.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b0bb634338334385351a1600a73e558ce619af390c2b38386206ac6a27fecfc"}, + {file = "httptools-0.6.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7d9ceb2c957320def533671fc9c715a80c47025139c8d1f3797477decbc6edd2"}, + {file = "httptools-0.6.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:4f0f8271c0a4db459f9dc807acd0eadd4839934a4b9b892f6f160e94da309837"}, + {file = "httptools-0.6.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:6a4f5ccead6d18ec072ac0b84420e95d27c1cdf5c9f1bc8fbd8daf86bd94f43d"}, + {file = "httptools-0.6.1-cp311-cp311-win_amd64.whl", hash = "sha256:5cceac09f164bcba55c0500a18fe3c47df29b62353198e4f37bbcc5d591172c3"}, + {file = "httptools-0.6.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:75c8022dca7935cba14741a42744eee13ba05db00b27a4b940f0d646bd4d56d0"}, + {file = "httptools-0.6.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:48ed8129cd9a0d62cf4d1575fcf90fb37e3ff7d5654d3a5814eb3d55f36478c2"}, + {file = "httptools-0.6.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f58e335a1402fb5a650e271e8c2d03cfa7cea46ae124649346d17bd30d59c90"}, + {file = "httptools-0.6.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:93ad80d7176aa5788902f207a4e79885f0576134695dfb0fefc15b7a4648d503"}, + {file = "httptools-0.6.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:9bb68d3a085c2174c2477eb3ffe84ae9fb4fde8792edb7bcd09a1d8467e30a84"}, + {file = "httptools-0.6.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:b512aa728bc02354e5ac086ce76c3ce635b62f5fbc32ab7082b5e582d27867bb"}, + {file = "httptools-0.6.1-cp312-cp312-win_amd64.whl", hash = "sha256:97662ce7fb196c785344d00d638fc9ad69e18ee4bfb4000b35a52efe5adcc949"}, + {file = "httptools-0.6.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:8e216a038d2d52ea13fdd9b9c9c7459fb80d78302b257828285eca1c773b99b3"}, + {file = "httptools-0.6.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:3e802e0b2378ade99cd666b5bffb8b2a7cc8f3d28988685dc300469ea8dd86cb"}, + {file = "httptools-0.6.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4bd3e488b447046e386a30f07af05f9b38d3d368d1f7b4d8f7e10af85393db97"}, + {file = "httptools-0.6.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe467eb086d80217b7584e61313ebadc8d187a4d95bb62031b7bab4b205c3ba3"}, + {file = "httptools-0.6.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:3c3b214ce057c54675b00108ac42bacf2ab8f85c58e3f324a4e963bbc46424f4"}, + {file = "httptools-0.6.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8ae5b97f690badd2ca27cbf668494ee1b6d34cf1c464271ef7bfa9ca6b83ffaf"}, + {file = "httptools-0.6.1-cp38-cp38-win_amd64.whl", hash = "sha256:405784577ba6540fa7d6ff49e37daf104e04f4b4ff2d1ac0469eaa6a20fde084"}, + {file = "httptools-0.6.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:95fb92dd3649f9cb139e9c56604cc2d7c7bf0fc2e7c8d7fbd58f96e35eddd2a3"}, + {file = "httptools-0.6.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:dcbab042cc3ef272adc11220517278519adf8f53fd3056d0e68f0a6f891ba94e"}, + {file = "httptools-0.6.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0cf2372e98406efb42e93bfe10f2948e467edfd792b015f1b4ecd897903d3e8d"}, + {file = "httptools-0.6.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:678fcbae74477a17d103b7cae78b74800d795d702083867ce160fc202104d0da"}, + {file = "httptools-0.6.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:e0b281cf5a125c35f7f6722b65d8542d2e57331be573e9e88bc8b0115c4a7a81"}, + {file = "httptools-0.6.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:95658c342529bba4e1d3d2b1a874db16c7cca435e8827422154c9da76ac4e13a"}, + {file = "httptools-0.6.1-cp39-cp39-win_amd64.whl", hash = "sha256:7ebaec1bf683e4bf5e9fbb49b8cc36da482033596a415b3e4ebab5a4c0d7ec5e"}, + {file = "httptools-0.6.1.tar.gz", hash = "sha256:c6e26c30455600b95d94b1b836085138e82f177351454ee841c148f93a9bad5a"}, +] + +[package.extras] +test = ["Cython (>=0.29.24,<0.30.0)"] + [[package]] name = "httpx" version = "0.27.0" @@ -1217,6 +1289,30 @@ MarkupSafe = ">=2.0" [package.extras] i18n = ["Babel (>=2.7)"] +[[package]] +name = "markdown-it-py" +version = "3.0.0" +description = "Python port of markdown-it. Markdown parsing, done right!" +optional = true +python-versions = ">=3.8" +files = [ + {file = "markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb"}, + {file = "markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1"}, +] + +[package.dependencies] +mdurl = ">=0.1,<1.0" + +[package.extras] +benchmarking = ["psutil", "pytest", "pytest-benchmark"] +code-style = ["pre-commit (>=3.0,<4.0)"] +compare = ["commonmark (>=0.9,<1.0)", "markdown (>=3.4,<4.0)", "mistletoe (>=1.0,<2.0)", "mistune (>=2.0,<3.0)", "panflute (>=2.3,<3.0)"] +linkify = ["linkify-it-py (>=1,<3)"] +plugins = ["mdit-py-plugins"] +profiling = ["gprof2dot"] +rtd = ["jupyter_sphinx", "mdit-py-plugins", "myst-parser", "pyyaml", "sphinx", "sphinx-copybutton", "sphinx-design", "sphinx_book_theme"] +testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] + [[package]] name = "markupsafe" version = "2.1.5" @@ -1297,6 +1393,17 @@ files = [ {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"}, ] +[[package]] +name = "mdurl" +version = "0.1.2" +description = "Markdown URL utilities" +optional = true +python-versions = ">=3.7" +files = [ + {file = "mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8"}, + {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"}, +] + [[package]] name = "msal" version = "1.28.0" @@ -1856,6 +1963,20 @@ files = [ {file = "pyflakes-3.1.0.tar.gz", hash = "sha256:a0aae034c444db0071aa077972ba4768d40c830d9539fd45bf4cd3f8f6992efc"}, ] +[[package]] +name = "pygments" +version = "2.18.0" +description = "Pygments is a syntax highlighting package written in Python." +optional = true +python-versions = ">=3.8" +files = [ + {file = "pygments-2.18.0-py3-none-any.whl", hash = "sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a"}, + {file = "pygments-2.18.0.tar.gz", hash = "sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199"}, +] + +[package.extras] +windows-terminal = ["colorama (>=0.4.6)"] + [[package]] name = "pyjwt" version = "2.8.0" @@ -2002,7 +2123,6 @@ files = [ {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, - {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"}, {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, @@ -2178,6 +2298,25 @@ files = [ [package.dependencies] requests = "2.31.0" +[[package]] +name = "rich" +version = "13.7.1" +description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" +optional = true +python-versions = ">=3.7.0" +files = [ + {file = "rich-13.7.1-py3-none-any.whl", hash = "sha256:4edbae314f59eb482f54e9e30bf00d33350aaa94f4bfcd4e9e3110e64d0d7222"}, + {file = "rich-13.7.1.tar.gz", hash = "sha256:9be308cb1fe2f1f57d67ce99e95af38a1e2bc71ad9813b0e247cf7ffbcc3a432"}, +] + +[package.dependencies] +markdown-it-py = ">=2.2.0" +pygments = ">=2.13.0,<3.0.0" +typing-extensions = {version = ">=4.0.0,<5.0", markers = "python_version < \"3.9\""} + +[package.extras] +jupyter = ["ipywidgets (>=7.5.1,<9)"] + [[package]] name = "rq" version = "1.16.2" @@ -2223,6 +2362,17 @@ docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments testing = ["build[virtualenv]", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "mypy (==1.9)", "packaging (>=23.2)", "pip (>=19.1)", "pytest (>=6,!=8.1.1)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy", "pytest-perf", "pytest-ruff (>=0.2.1)", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] testing-integration = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging (>=23.2)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] +[[package]] +name = "shellingham" +version = "1.5.4" +description = "Tool to Detect Surrounding Shell" +optional = true +python-versions = ">=3.7" +files = [ + {file = "shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686"}, + {file = "shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de"}, +] + [[package]] name = "six" version = "1.16.0" @@ -2247,13 +2397,13 @@ files = [ [[package]] name = "starlette" -version = "0.36.3" +version = "0.37.2" description = "The little ASGI library that shines." optional = true python-versions = ">=3.8" files = [ - {file = "starlette-0.36.3-py3-none-any.whl", hash = "sha256:13d429aa93a61dc40bf503e8c801db1f1bca3dc706b10ef2434a36123568f044"}, - {file = "starlette-0.36.3.tar.gz", hash = "sha256:90a671733cfb35771d8cc605e0b679d23b992f8dcfad48cc60b38cb29aeb7080"}, + {file = "starlette-0.37.2-py3-none-any.whl", hash = "sha256:6fe59f29268538e5d0d182f2791a479a0c64638e6935d1c6989e63fb2699c6ee"}, + {file = "starlette-0.37.2.tar.gz", hash = "sha256:9af890290133b79fc3db55474ade20f6220a364a0402e0b556e7cd5e1e093823"}, ] [package.dependencies] @@ -2474,6 +2624,23 @@ notebook = ["ipywidgets (>=6)"] slack = ["slack-sdk"] telegram = ["requests"] +[[package]] +name = "typer" +version = "0.12.3" +description = "Typer, build great CLIs. Easy to code. Based on Python type hints." +optional = true +python-versions = ">=3.7" +files = [ + {file = "typer-0.12.3-py3-none-any.whl", hash = "sha256:070d7ca53f785acbccba8e7d28b08dcd88f79f1fbda035ade0aecec71ca5c914"}, + {file = "typer-0.12.3.tar.gz", hash = "sha256:49e73131481d804288ef62598d97a1ceef3058905aa536a1134f90891ba35482"}, +] + +[package.dependencies] +click = ">=8.0.0" +rich = ">=10.11.0" +shellingham = ">=1.3.0" +typing-extensions = ">=3.7.4.3" + [[package]] name = "typing-extensions" version = "4.11.0" @@ -2514,6 +2681,80 @@ tzdata = {version = "*", markers = "platform_system == \"Windows\""} [package.extras] devenv = ["check-manifest", "pytest (>=4.3)", "pytest-cov", "pytest-mock (>=3.3)", "zest.releaser"] +[[package]] +name = "ujson" +version = "5.9.0" +description = "Ultra fast JSON encoder and decoder for Python" +optional = true +python-versions = ">=3.8" +files = [ + {file = "ujson-5.9.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ab71bf27b002eaf7d047c54a68e60230fbd5cd9da60de7ca0aa87d0bccead8fa"}, + {file = "ujson-5.9.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:7a365eac66f5aa7a7fdf57e5066ada6226700884fc7dce2ba5483538bc16c8c5"}, + {file = "ujson-5.9.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e015122b337858dba5a3dc3533af2a8fc0410ee9e2374092f6a5b88b182e9fcc"}, + {file = "ujson-5.9.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:779a2a88c53039bebfbccca934430dabb5c62cc179e09a9c27a322023f363e0d"}, + {file = "ujson-5.9.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:10ca3c41e80509fd9805f7c149068fa8dbee18872bbdc03d7cca928926a358d5"}, + {file = "ujson-5.9.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:4a566e465cb2fcfdf040c2447b7dd9718799d0d90134b37a20dff1e27c0e9096"}, + {file = "ujson-5.9.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:f833c529e922577226a05bc25b6a8b3eb6c4fb155b72dd88d33de99d53113124"}, + {file = "ujson-5.9.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b68a0caab33f359b4cbbc10065c88e3758c9f73a11a65a91f024b2e7a1257106"}, + {file = "ujson-5.9.0-cp310-cp310-win32.whl", hash = "sha256:7cc7e605d2aa6ae6b7321c3ae250d2e050f06082e71ab1a4200b4ae64d25863c"}, + {file = "ujson-5.9.0-cp310-cp310-win_amd64.whl", hash = "sha256:a6d3f10eb8ccba4316a6b5465b705ed70a06011c6f82418b59278fbc919bef6f"}, + {file = "ujson-5.9.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3b23bbb46334ce51ddb5dded60c662fbf7bb74a37b8f87221c5b0fec1ec6454b"}, + {file = "ujson-5.9.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6974b3a7c17bbf829e6c3bfdc5823c67922e44ff169851a755eab79a3dd31ec0"}, + {file = "ujson-5.9.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b5964ea916edfe24af1f4cc68488448fbb1ec27a3ddcddc2b236da575c12c8ae"}, + {file = "ujson-5.9.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8ba7cac47dd65ff88571eceeff48bf30ed5eb9c67b34b88cb22869b7aa19600d"}, + {file = "ujson-5.9.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6bbd91a151a8f3358c29355a491e915eb203f607267a25e6ab10531b3b157c5e"}, + {file = "ujson-5.9.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:829a69d451a49c0de14a9fecb2a2d544a9b2c884c2b542adb243b683a6f15908"}, + {file = "ujson-5.9.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:a807ae73c46ad5db161a7e883eec0fbe1bebc6a54890152ccc63072c4884823b"}, + {file = "ujson-5.9.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:8fc2aa18b13d97b3c8ccecdf1a3c405f411a6e96adeee94233058c44ff92617d"}, + {file = "ujson-5.9.0-cp311-cp311-win32.whl", hash = "sha256:70e06849dfeb2548be48fdd3ceb53300640bc8100c379d6e19d78045e9c26120"}, + {file = "ujson-5.9.0-cp311-cp311-win_amd64.whl", hash = "sha256:7309d063cd392811acc49b5016728a5e1b46ab9907d321ebbe1c2156bc3c0b99"}, + {file = "ujson-5.9.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:20509a8c9f775b3a511e308bbe0b72897ba6b800767a7c90c5cca59d20d7c42c"}, + {file = "ujson-5.9.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b28407cfe315bd1b34f1ebe65d3bd735d6b36d409b334100be8cdffae2177b2f"}, + {file = "ujson-5.9.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9d302bd17989b6bd90d49bade66943c78f9e3670407dbc53ebcf61271cadc399"}, + {file = "ujson-5.9.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f21315f51e0db8ee245e33a649dd2d9dce0594522de6f278d62f15f998e050e"}, + {file = "ujson-5.9.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5635b78b636a54a86fdbf6f027e461aa6c6b948363bdf8d4fbb56a42b7388320"}, + {file = "ujson-5.9.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:82b5a56609f1235d72835ee109163c7041b30920d70fe7dac9176c64df87c164"}, + {file = "ujson-5.9.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:5ca35f484622fd208f55041b042d9d94f3b2c9c5add4e9af5ee9946d2d30db01"}, + {file = "ujson-5.9.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:829b824953ebad76d46e4ae709e940bb229e8999e40881338b3cc94c771b876c"}, + {file = "ujson-5.9.0-cp312-cp312-win32.whl", hash = "sha256:25fa46e4ff0a2deecbcf7100af3a5d70090b461906f2299506485ff31d9ec437"}, + {file = "ujson-5.9.0-cp312-cp312-win_amd64.whl", hash = "sha256:60718f1720a61560618eff3b56fd517d107518d3c0160ca7a5a66ac949c6cf1c"}, + {file = "ujson-5.9.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d581db9db9e41d8ea0b2705c90518ba623cbdc74f8d644d7eb0d107be0d85d9c"}, + {file = "ujson-5.9.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ff741a5b4be2d08fceaab681c9d4bc89abf3c9db600ab435e20b9b6d4dfef12e"}, + {file = "ujson-5.9.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cdcb02cabcb1e44381221840a7af04433c1dc3297af76fde924a50c3054c708c"}, + {file = "ujson-5.9.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e208d3bf02c6963e6ef7324dadf1d73239fb7008491fdf523208f60be6437402"}, + {file = "ujson-5.9.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f4b3917296630a075e04d3d07601ce2a176479c23af838b6cf90a2d6b39b0d95"}, + {file = "ujson-5.9.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:0c4d6adb2c7bb9eb7c71ad6f6f612e13b264942e841f8cc3314a21a289a76c4e"}, + {file = "ujson-5.9.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:0b159efece9ab5c01f70b9d10bbb77241ce111a45bc8d21a44c219a2aec8ddfd"}, + {file = "ujson-5.9.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:f0cb4a7814940ddd6619bdce6be637a4b37a8c4760de9373bac54bb7b229698b"}, + {file = "ujson-5.9.0-cp38-cp38-win32.whl", hash = "sha256:dc80f0f5abf33bd7099f7ac94ab1206730a3c0a2d17549911ed2cb6b7aa36d2d"}, + {file = "ujson-5.9.0-cp38-cp38-win_amd64.whl", hash = "sha256:506a45e5fcbb2d46f1a51fead991c39529fc3737c0f5d47c9b4a1d762578fc30"}, + {file = "ujson-5.9.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d0fd2eba664a22447102062814bd13e63c6130540222c0aa620701dd01f4be81"}, + {file = "ujson-5.9.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:bdf7fc21a03bafe4ba208dafa84ae38e04e5d36c0e1c746726edf5392e9f9f36"}, + {file = "ujson-5.9.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e2f909bc08ce01f122fd9c24bc6f9876aa087188dfaf3c4116fe6e4daf7e194f"}, + {file = "ujson-5.9.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bd4ea86c2afd41429751d22a3ccd03311c067bd6aeee2d054f83f97e41e11d8f"}, + {file = "ujson-5.9.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:63fb2e6599d96fdffdb553af0ed3f76b85fda63281063f1cb5b1141a6fcd0617"}, + {file = "ujson-5.9.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:32bba5870c8fa2a97f4a68f6401038d3f1922e66c34280d710af00b14a3ca562"}, + {file = "ujson-5.9.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:37ef92e42535a81bf72179d0e252c9af42a4ed966dc6be6967ebfb929a87bc60"}, + {file = "ujson-5.9.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:f69f16b8f1c69da00e38dc5f2d08a86b0e781d0ad3e4cc6a13ea033a439c4844"}, + {file = "ujson-5.9.0-cp39-cp39-win32.whl", hash = "sha256:3382a3ce0ccc0558b1c1668950008cece9bf463ebb17463ebf6a8bfc060dae34"}, + {file = "ujson-5.9.0-cp39-cp39-win_amd64.whl", hash = "sha256:6adef377ed583477cf005b58c3025051b5faa6b8cc25876e594afbb772578f21"}, + {file = "ujson-5.9.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:ffdfebd819f492e48e4f31c97cb593b9c1a8251933d8f8972e81697f00326ff1"}, + {file = "ujson-5.9.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c4eec2ddc046360d087cf35659c7ba0cbd101f32035e19047013162274e71fcf"}, + {file = "ujson-5.9.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2fbb90aa5c23cb3d4b803c12aa220d26778c31b6e4b7a13a1f49971f6c7d088e"}, + {file = "ujson-5.9.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba0823cb70866f0d6a4ad48d998dd338dce7314598721bc1b7986d054d782dfd"}, + {file = "ujson-5.9.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:4e35d7885ed612feb6b3dd1b7de28e89baaba4011ecdf995e88be9ac614765e9"}, + {file = "ujson-5.9.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:b048aa93eace8571eedbd67b3766623e7f0acbf08ee291bef7d8106210432427"}, + {file = "ujson-5.9.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:323279e68c195110ef85cbe5edce885219e3d4a48705448720ad925d88c9f851"}, + {file = "ujson-5.9.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9ac92d86ff34296f881e12aa955f7014d276895e0e4e868ba7fddebbde38e378"}, + {file = "ujson-5.9.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:6eecbd09b316cea1fd929b1e25f70382917542ab11b692cb46ec9b0a26c7427f"}, + {file = "ujson-5.9.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:473fb8dff1d58f49912323d7cb0859df5585cfc932e4b9c053bf8cf7f2d7c5c4"}, + {file = "ujson-5.9.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f91719c6abafe429c1a144cfe27883eace9fb1c09a9c5ef1bcb3ae80a3076a4e"}, + {file = "ujson-5.9.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7b1c0991c4fe256f5fdb19758f7eac7f47caac29a6c57d0de16a19048eb86bad"}, + {file = "ujson-5.9.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a8ea0f55a1396708e564595aaa6696c0d8af532340f477162ff6927ecc46e21"}, + {file = "ujson-5.9.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:07e0cfdde5fd91f54cd2d7ffb3482c8ff1bf558abf32a8b953a5d169575ae1cd"}, + {file = "ujson-5.9.0.tar.gz", hash = "sha256:89cc92e73d5501b8a7f48575eeb14ad27156ad092c2e9fc7e3cf949f07e75532"}, +] + [[package]] name = "urllib3" version = "2.2.1" @@ -2544,11 +2785,230 @@ files = [ [package.dependencies] click = ">=7.0" +colorama = {version = ">=0.4", optional = true, markers = "sys_platform == \"win32\" and extra == \"standard\""} h11 = ">=0.8" +httptools = {version = ">=0.5.0", optional = true, markers = "extra == \"standard\""} +python-dotenv = {version = ">=0.13", optional = true, markers = "extra == \"standard\""} +pyyaml = {version = ">=5.1", optional = true, markers = "extra == \"standard\""} +uvloop = {version = ">=0.14.0,<0.15.0 || >0.15.0,<0.15.1 || >0.15.1", optional = true, markers = "(sys_platform != \"win32\" and sys_platform != \"cygwin\") and platform_python_implementation != \"PyPy\" and extra == \"standard\""} +watchfiles = {version = ">=0.13", optional = true, markers = "extra == \"standard\""} +websockets = {version = ">=10.4", optional = true, markers = "extra == \"standard\""} [package.extras] standard = ["colorama (>=0.4)", "httptools (>=0.5.0)", "python-dotenv (>=0.13)", "pyyaml (>=5.1)", "uvloop (>=0.14.0,!=0.15.0,!=0.15.1)", "watchfiles (>=0.13)", "websockets (>=10.4)"] +[[package]] +name = "uvloop" +version = "0.19.0" +description = "Fast implementation of asyncio event loop on top of libuv" +optional = true +python-versions = ">=3.8.0" +files = [ + {file = "uvloop-0.19.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:de4313d7f575474c8f5a12e163f6d89c0a878bc49219641d49e6f1444369a90e"}, + {file = "uvloop-0.19.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5588bd21cf1fcf06bded085f37e43ce0e00424197e7c10e77afd4bbefffef428"}, + {file = "uvloop-0.19.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7b1fd71c3843327f3bbc3237bedcdb6504fd50368ab3e04d0410e52ec293f5b8"}, + {file = "uvloop-0.19.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5a05128d315e2912791de6088c34136bfcdd0c7cbc1cf85fd6fd1bb321b7c849"}, + {file = "uvloop-0.19.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:cd81bdc2b8219cb4b2556eea39d2e36bfa375a2dd021404f90a62e44efaaf957"}, + {file = "uvloop-0.19.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:5f17766fb6da94135526273080f3455a112f82570b2ee5daa64d682387fe0dcd"}, + {file = "uvloop-0.19.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:4ce6b0af8f2729a02a5d1575feacb2a94fc7b2e983868b009d51c9a9d2149bef"}, + {file = "uvloop-0.19.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:31e672bb38b45abc4f26e273be83b72a0d28d074d5b370fc4dcf4c4eb15417d2"}, + {file = "uvloop-0.19.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:570fc0ed613883d8d30ee40397b79207eedd2624891692471808a95069a007c1"}, + {file = "uvloop-0.19.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5138821e40b0c3e6c9478643b4660bd44372ae1e16a322b8fc07478f92684e24"}, + {file = "uvloop-0.19.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:91ab01c6cd00e39cde50173ba4ec68a1e578fee9279ba64f5221810a9e786533"}, + {file = "uvloop-0.19.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:47bf3e9312f63684efe283f7342afb414eea4d3011542155c7e625cd799c3b12"}, + {file = "uvloop-0.19.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:da8435a3bd498419ee8c13c34b89b5005130a476bda1d6ca8cfdde3de35cd650"}, + {file = "uvloop-0.19.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:02506dc23a5d90e04d4f65c7791e65cf44bd91b37f24cfc3ef6cf2aff05dc7ec"}, + {file = "uvloop-0.19.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2693049be9d36fef81741fddb3f441673ba12a34a704e7b4361efb75cf30befc"}, + {file = "uvloop-0.19.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7010271303961c6f0fe37731004335401eb9075a12680738731e9c92ddd96ad6"}, + {file = "uvloop-0.19.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:5daa304d2161d2918fa9a17d5635099a2f78ae5b5960e742b2fcfbb7aefaa593"}, + {file = "uvloop-0.19.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:7207272c9520203fea9b93843bb775d03e1cf88a80a936ce760f60bb5add92f3"}, + {file = "uvloop-0.19.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:78ab247f0b5671cc887c31d33f9b3abfb88d2614b84e4303f1a63b46c046c8bd"}, + {file = "uvloop-0.19.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:472d61143059c84947aa8bb74eabbace30d577a03a1805b77933d6bd13ddebbd"}, + {file = "uvloop-0.19.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45bf4c24c19fb8a50902ae37c5de50da81de4922af65baf760f7c0c42e1088be"}, + {file = "uvloop-0.19.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:271718e26b3e17906b28b67314c45d19106112067205119dddbd834c2b7ce797"}, + {file = "uvloop-0.19.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:34175c9fd2a4bc3adc1380e1261f60306344e3407c20a4d684fd5f3be010fa3d"}, + {file = "uvloop-0.19.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:e27f100e1ff17f6feeb1f33968bc185bf8ce41ca557deee9d9bbbffeb72030b7"}, + {file = "uvloop-0.19.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:13dfdf492af0aa0a0edf66807d2b465607d11c4fa48f4a1fd41cbea5b18e8e8b"}, + {file = "uvloop-0.19.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6e3d4e85ac060e2342ff85e90d0c04157acb210b9ce508e784a944f852a40e67"}, + {file = "uvloop-0.19.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8ca4956c9ab567d87d59d49fa3704cf29e37109ad348f2d5223c9bf761a332e7"}, + {file = "uvloop-0.19.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f467a5fd23b4fc43ed86342641f3936a68ded707f4627622fa3f82a120e18256"}, + {file = "uvloop-0.19.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:492e2c32c2af3f971473bc22f086513cedfc66a130756145a931a90c3958cb17"}, + {file = "uvloop-0.19.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:2df95fca285a9f5bfe730e51945ffe2fa71ccbfdde3b0da5772b4ee4f2e770d5"}, + {file = "uvloop-0.19.0.tar.gz", hash = "sha256:0246f4fd1bf2bf702e06b0d45ee91677ee5c31242f39aab4ea6fe0c51aedd0fd"}, +] + +[package.extras] +docs = ["Sphinx (>=4.1.2,<4.2.0)", "sphinx-rtd-theme (>=0.5.2,<0.6.0)", "sphinxcontrib-asyncio (>=0.3.0,<0.4.0)"] +test = ["Cython (>=0.29.36,<0.30.0)", "aiohttp (==3.9.0b0)", "aiohttp (>=3.8.1)", "flake8 (>=5.0,<6.0)", "mypy (>=0.800)", "psutil", "pyOpenSSL (>=23.0.0,<23.1.0)", "pycodestyle (>=2.9.0,<2.10.0)"] + +[[package]] +name = "watchfiles" +version = "0.21.0" +description = "Simple, modern and high performance file watching and code reload in python." +optional = true +python-versions = ">=3.8" +files = [ + {file = "watchfiles-0.21.0-cp310-cp310-macosx_10_7_x86_64.whl", hash = "sha256:27b4035013f1ea49c6c0b42d983133b136637a527e48c132d368eb19bf1ac6aa"}, + {file = "watchfiles-0.21.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c81818595eff6e92535ff32825f31c116f867f64ff8cdf6562cd1d6b2e1e8f3e"}, + {file = "watchfiles-0.21.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:6c107ea3cf2bd07199d66f156e3ea756d1b84dfd43b542b2d870b77868c98c03"}, + {file = "watchfiles-0.21.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d9ac347653ebd95839a7c607608703b20bc07e577e870d824fa4801bc1cb124"}, + {file = "watchfiles-0.21.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5eb86c6acb498208e7663ca22dbe68ca2cf42ab5bf1c776670a50919a56e64ab"}, + {file = "watchfiles-0.21.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f564bf68404144ea6b87a78a3f910cc8de216c6b12a4cf0b27718bf4ec38d303"}, + {file = "watchfiles-0.21.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d0f32ebfaa9c6011f8454994f86108c2eb9c79b8b7de00b36d558cadcedaa3d"}, + {file = "watchfiles-0.21.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b6d45d9b699ecbac6c7bd8e0a2609767491540403610962968d258fd6405c17c"}, + {file = "watchfiles-0.21.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:aff06b2cac3ef4616e26ba17a9c250c1fe9dd8a5d907d0193f84c499b1b6e6a9"}, + {file = "watchfiles-0.21.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d9792dff410f266051025ecfaa927078b94cc7478954b06796a9756ccc7e14a9"}, + {file = "watchfiles-0.21.0-cp310-none-win32.whl", hash = "sha256:214cee7f9e09150d4fb42e24919a1e74d8c9b8a9306ed1474ecaddcd5479c293"}, + {file = "watchfiles-0.21.0-cp310-none-win_amd64.whl", hash = "sha256:1ad7247d79f9f55bb25ab1778fd47f32d70cf36053941f07de0b7c4e96b5d235"}, + {file = "watchfiles-0.21.0-cp311-cp311-macosx_10_7_x86_64.whl", hash = "sha256:668c265d90de8ae914f860d3eeb164534ba2e836811f91fecc7050416ee70aa7"}, + {file = "watchfiles-0.21.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3a23092a992e61c3a6a70f350a56db7197242f3490da9c87b500f389b2d01eef"}, + {file = "watchfiles-0.21.0-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:e7941bbcfdded9c26b0bf720cb7e6fd803d95a55d2c14b4bd1f6a2772230c586"}, + {file = "watchfiles-0.21.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:11cd0c3100e2233e9c53106265da31d574355c288e15259c0d40a4405cbae317"}, + {file = "watchfiles-0.21.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d78f30cbe8b2ce770160d3c08cff01b2ae9306fe66ce899b73f0409dc1846c1b"}, + {file = "watchfiles-0.21.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6674b00b9756b0af620aa2a3346b01f8e2a3dc729d25617e1b89cf6af4a54eb1"}, + {file = "watchfiles-0.21.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fd7ac678b92b29ba630d8c842d8ad6c555abda1b9ef044d6cc092dacbfc9719d"}, + {file = "watchfiles-0.21.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c873345680c1b87f1e09e0eaf8cf6c891b9851d8b4d3645e7efe2ec20a20cc7"}, + {file = "watchfiles-0.21.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:49f56e6ecc2503e7dbe233fa328b2be1a7797d31548e7a193237dcdf1ad0eee0"}, + {file = "watchfiles-0.21.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:02d91cbac553a3ad141db016e3350b03184deaafeba09b9d6439826ee594b365"}, + {file = "watchfiles-0.21.0-cp311-none-win32.whl", hash = "sha256:ebe684d7d26239e23d102a2bad2a358dedf18e462e8808778703427d1f584400"}, + {file = "watchfiles-0.21.0-cp311-none-win_amd64.whl", hash = "sha256:4566006aa44cb0d21b8ab53baf4b9c667a0ed23efe4aaad8c227bfba0bf15cbe"}, + {file = "watchfiles-0.21.0-cp311-none-win_arm64.whl", hash = "sha256:c550a56bf209a3d987d5a975cdf2063b3389a5d16caf29db4bdddeae49f22078"}, + {file = "watchfiles-0.21.0-cp312-cp312-macosx_10_7_x86_64.whl", hash = "sha256:51ddac60b96a42c15d24fbdc7a4bfcd02b5a29c047b7f8bf63d3f6f5a860949a"}, + {file = "watchfiles-0.21.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:511f0b034120cd1989932bf1e9081aa9fb00f1f949fbd2d9cab6264916ae89b1"}, + {file = "watchfiles-0.21.0-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:cfb92d49dbb95ec7a07511bc9efb0faff8fe24ef3805662b8d6808ba8409a71a"}, + {file = "watchfiles-0.21.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3f92944efc564867bbf841c823c8b71bb0be75e06b8ce45c084b46411475a915"}, + {file = "watchfiles-0.21.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:642d66b75eda909fd1112d35c53816d59789a4b38c141a96d62f50a3ef9b3360"}, + {file = "watchfiles-0.21.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d23bcd6c8eaa6324fe109d8cac01b41fe9a54b8c498af9ce464c1aeeb99903d6"}, + {file = "watchfiles-0.21.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:18d5b4da8cf3e41895b34e8c37d13c9ed294954907929aacd95153508d5d89d7"}, + {file = "watchfiles-0.21.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1b8d1eae0f65441963d805f766c7e9cd092f91e0c600c820c764a4ff71a0764c"}, + {file = "watchfiles-0.21.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:1fd9a5205139f3c6bb60d11f6072e0552f0a20b712c85f43d42342d162be1235"}, + {file = "watchfiles-0.21.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a1e3014a625bcf107fbf38eece0e47fa0190e52e45dc6eee5a8265ddc6dc5ea7"}, + {file = "watchfiles-0.21.0-cp312-none-win32.whl", hash = "sha256:9d09869f2c5a6f2d9df50ce3064b3391d3ecb6dced708ad64467b9e4f2c9bef3"}, + {file = "watchfiles-0.21.0-cp312-none-win_amd64.whl", hash = "sha256:18722b50783b5e30a18a8a5db3006bab146d2b705c92eb9a94f78c72beb94094"}, + {file = "watchfiles-0.21.0-cp312-none-win_arm64.whl", hash = "sha256:a3b9bec9579a15fb3ca2d9878deae789df72f2b0fdaf90ad49ee389cad5edab6"}, + {file = "watchfiles-0.21.0-cp38-cp38-macosx_10_7_x86_64.whl", hash = "sha256:4ea10a29aa5de67de02256a28d1bf53d21322295cb00bd2d57fcd19b850ebd99"}, + {file = "watchfiles-0.21.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:40bca549fdc929b470dd1dbfcb47b3295cb46a6d2c90e50588b0a1b3bd98f429"}, + {file = "watchfiles-0.21.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:9b37a7ba223b2f26122c148bb8d09a9ff312afca998c48c725ff5a0a632145f7"}, + {file = "watchfiles-0.21.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec8c8900dc5c83650a63dd48c4d1d245343f904c4b64b48798c67a3767d7e165"}, + {file = "watchfiles-0.21.0-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8ad3fe0a3567c2f0f629d800409cd528cb6251da12e81a1f765e5c5345fd0137"}, + {file = "watchfiles-0.21.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9d353c4cfda586db2a176ce42c88f2fc31ec25e50212650c89fdd0f560ee507b"}, + {file = "watchfiles-0.21.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:83a696da8922314ff2aec02987eefb03784f473281d740bf9170181829133765"}, + {file = "watchfiles-0.21.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5a03651352fc20975ee2a707cd2d74a386cd303cc688f407296064ad1e6d1562"}, + {file = "watchfiles-0.21.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:3ad692bc7792be8c32918c699638b660c0de078a6cbe464c46e1340dadb94c19"}, + {file = "watchfiles-0.21.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:06247538e8253975bdb328e7683f8515ff5ff041f43be6c40bff62d989b7d0b0"}, + {file = "watchfiles-0.21.0-cp38-none-win32.whl", hash = "sha256:9a0aa47f94ea9a0b39dd30850b0adf2e1cd32a8b4f9c7aa443d852aacf9ca214"}, + {file = "watchfiles-0.21.0-cp38-none-win_amd64.whl", hash = "sha256:8d5f400326840934e3507701f9f7269247f7c026d1b6cfd49477d2be0933cfca"}, + {file = "watchfiles-0.21.0-cp39-cp39-macosx_10_7_x86_64.whl", hash = "sha256:7f762a1a85a12cc3484f77eee7be87b10f8c50b0b787bb02f4e357403cad0c0e"}, + {file = "watchfiles-0.21.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6e9be3ef84e2bb9710f3f777accce25556f4a71e15d2b73223788d528fcc2052"}, + {file = "watchfiles-0.21.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:4c48a10d17571d1275701e14a601e36959ffada3add8cdbc9e5061a6e3579a5d"}, + {file = "watchfiles-0.21.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c889025f59884423428c261f212e04d438de865beda0b1e1babab85ef4c0f01"}, + {file = "watchfiles-0.21.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:66fac0c238ab9a2e72d026b5fb91cb902c146202bbd29a9a1a44e8db7b710b6f"}, + {file = "watchfiles-0.21.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b4a21f71885aa2744719459951819e7bf5a906a6448a6b2bbce8e9cc9f2c8128"}, + {file = "watchfiles-0.21.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1c9198c989f47898b2c22201756f73249de3748e0fc9de44adaf54a8b259cc0c"}, + {file = "watchfiles-0.21.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d8f57c4461cd24fda22493109c45b3980863c58a25b8bec885ca8bea6b8d4b28"}, + {file = "watchfiles-0.21.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:853853cbf7bf9408b404754b92512ebe3e3a83587503d766d23e6bf83d092ee6"}, + {file = "watchfiles-0.21.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d5b1dc0e708fad9f92c296ab2f948af403bf201db8fb2eb4c8179db143732e49"}, + {file = "watchfiles-0.21.0-cp39-none-win32.whl", hash = "sha256:59137c0c6826bd56c710d1d2bda81553b5e6b7c84d5a676747d80caf0409ad94"}, + {file = "watchfiles-0.21.0-cp39-none-win_amd64.whl", hash = "sha256:6cb8fdc044909e2078c248986f2fc76f911f72b51ea4a4fbbf472e01d14faa58"}, + {file = "watchfiles-0.21.0-pp310-pypy310_pp73-macosx_10_7_x86_64.whl", hash = "sha256:ab03a90b305d2588e8352168e8c5a1520b721d2d367f31e9332c4235b30b8994"}, + {file = "watchfiles-0.21.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:927c589500f9f41e370b0125c12ac9e7d3a2fd166b89e9ee2828b3dda20bfe6f"}, + {file = "watchfiles-0.21.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1bd467213195e76f838caf2c28cd65e58302d0254e636e7c0fca81efa4a2e62c"}, + {file = "watchfiles-0.21.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:02b73130687bc3f6bb79d8a170959042eb56eb3a42df3671c79b428cd73f17cc"}, + {file = "watchfiles-0.21.0-pp38-pypy38_pp73-macosx_10_7_x86_64.whl", hash = "sha256:08dca260e85ffae975448e344834d765983237ad6dc308231aa16e7933db763e"}, + {file = "watchfiles-0.21.0-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:3ccceb50c611c433145502735e0370877cced72a6c70fd2410238bcbc7fe51d8"}, + {file = "watchfiles-0.21.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:57d430f5fb63fea141ab71ca9c064e80de3a20b427ca2febcbfcef70ff0ce895"}, + {file = "watchfiles-0.21.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0dd5fad9b9c0dd89904bbdea978ce89a2b692a7ee8a0ce19b940e538c88a809c"}, + {file = "watchfiles-0.21.0-pp39-pypy39_pp73-macosx_10_7_x86_64.whl", hash = "sha256:be6dd5d52b73018b21adc1c5d28ac0c68184a64769052dfeb0c5d9998e7f56a2"}, + {file = "watchfiles-0.21.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:b3cab0e06143768499384a8a5efb9c4dc53e19382952859e4802f294214f36ec"}, + {file = "watchfiles-0.21.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c6ed10c2497e5fedadf61e465b3ca12a19f96004c15dcffe4bd442ebadc2d85"}, + {file = "watchfiles-0.21.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:43babacef21c519bc6631c5fce2a61eccdfc011b4bcb9047255e9620732c8097"}, + {file = "watchfiles-0.21.0.tar.gz", hash = "sha256:c76c635fabf542bb78524905718c39f736a98e5ab25b23ec6d4abede1a85a6a3"}, +] + +[package.dependencies] +anyio = ">=3.0.0" + +[[package]] +name = "websockets" +version = "12.0" +description = "An implementation of the WebSocket Protocol (RFC 6455 & 7692)" +optional = true +python-versions = ">=3.8" +files = [ + {file = "websockets-12.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d554236b2a2006e0ce16315c16eaa0d628dab009c33b63ea03f41c6107958374"}, + {file = "websockets-12.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2d225bb6886591b1746b17c0573e29804619c8f755b5598d875bb4235ea639be"}, + {file = "websockets-12.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:eb809e816916a3b210bed3c82fb88eaf16e8afcf9c115ebb2bacede1797d2547"}, + {file = "websockets-12.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c588f6abc13f78a67044c6b1273a99e1cf31038ad51815b3b016ce699f0d75c2"}, + {file = "websockets-12.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5aa9348186d79a5f232115ed3fa9020eab66d6c3437d72f9d2c8ac0c6858c558"}, + {file = "websockets-12.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6350b14a40c95ddd53e775dbdbbbc59b124a5c8ecd6fbb09c2e52029f7a9f480"}, + {file = "websockets-12.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:70ec754cc2a769bcd218ed8d7209055667b30860ffecb8633a834dde27d6307c"}, + {file = "websockets-12.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6e96f5ed1b83a8ddb07909b45bd94833b0710f738115751cdaa9da1fb0cb66e8"}, + {file = "websockets-12.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4d87be612cbef86f994178d5186add3d94e9f31cc3cb499a0482b866ec477603"}, + {file = "websockets-12.0-cp310-cp310-win32.whl", hash = "sha256:befe90632d66caaf72e8b2ed4d7f02b348913813c8b0a32fae1cc5fe3730902f"}, + {file = "websockets-12.0-cp310-cp310-win_amd64.whl", hash = "sha256:363f57ca8bc8576195d0540c648aa58ac18cf85b76ad5202b9f976918f4219cf"}, + {file = "websockets-12.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5d873c7de42dea355d73f170be0f23788cf3fa9f7bed718fd2830eefedce01b4"}, + {file = "websockets-12.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3f61726cae9f65b872502ff3c1496abc93ffbe31b278455c418492016e2afc8f"}, + {file = "websockets-12.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ed2fcf7a07334c77fc8a230755c2209223a7cc44fc27597729b8ef5425aa61a3"}, + {file = "websockets-12.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e332c210b14b57904869ca9f9bf4ca32f5427a03eeb625da9b616c85a3a506c"}, + {file = "websockets-12.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5693ef74233122f8ebab026817b1b37fe25c411ecfca084b29bc7d6efc548f45"}, + {file = "websockets-12.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e9e7db18b4539a29cc5ad8c8b252738a30e2b13f033c2d6e9d0549b45841c04"}, + {file = "websockets-12.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:6e2df67b8014767d0f785baa98393725739287684b9f8d8a1001eb2839031447"}, + {file = "websockets-12.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:bea88d71630c5900690fcb03161ab18f8f244805c59e2e0dc4ffadae0a7ee0ca"}, + {file = "websockets-12.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:dff6cdf35e31d1315790149fee351f9e52978130cef6c87c4b6c9b3baf78bc53"}, + {file = "websockets-12.0-cp311-cp311-win32.whl", hash = "sha256:3e3aa8c468af01d70332a382350ee95f6986db479ce7af14d5e81ec52aa2b402"}, + {file = "websockets-12.0-cp311-cp311-win_amd64.whl", hash = "sha256:25eb766c8ad27da0f79420b2af4b85d29914ba0edf69f547cc4f06ca6f1d403b"}, + {file = "websockets-12.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0e6e2711d5a8e6e482cacb927a49a3d432345dfe7dea8ace7b5790df5932e4df"}, + {file = "websockets-12.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:dbcf72a37f0b3316e993e13ecf32f10c0e1259c28ffd0a85cee26e8549595fbc"}, + {file = "websockets-12.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:12743ab88ab2af1d17dd4acb4645677cb7063ef4db93abffbf164218a5d54c6b"}, + {file = "websockets-12.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7b645f491f3c48d3f8a00d1fce07445fab7347fec54a3e65f0725d730d5b99cb"}, + {file = "websockets-12.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9893d1aa45a7f8b3bc4510f6ccf8db8c3b62120917af15e3de247f0780294b92"}, + {file = "websockets-12.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f38a7b376117ef7aff996e737583172bdf535932c9ca021746573bce40165ed"}, + {file = "websockets-12.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:f764ba54e33daf20e167915edc443b6f88956f37fb606449b4a5b10ba42235a5"}, + {file = "websockets-12.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:1e4b3f8ea6a9cfa8be8484c9221ec0257508e3a1ec43c36acdefb2a9c3b00aa2"}, + {file = "websockets-12.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9fdf06fd06c32205a07e47328ab49c40fc1407cdec801d698a7c41167ea45113"}, + {file = "websockets-12.0-cp312-cp312-win32.whl", hash = "sha256:baa386875b70cbd81798fa9f71be689c1bf484f65fd6fb08d051a0ee4e79924d"}, + {file = "websockets-12.0-cp312-cp312-win_amd64.whl", hash = "sha256:ae0a5da8f35a5be197f328d4727dbcfafa53d1824fac3d96cdd3a642fe09394f"}, + {file = "websockets-12.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:5f6ffe2c6598f7f7207eef9a1228b6f5c818f9f4d53ee920aacd35cec8110438"}, + {file = "websockets-12.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9edf3fc590cc2ec20dc9d7a45108b5bbaf21c0d89f9fd3fd1685e223771dc0b2"}, + {file = "websockets-12.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:8572132c7be52632201a35f5e08348137f658e5ffd21f51f94572ca6c05ea81d"}, + {file = "websockets-12.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:604428d1b87edbf02b233e2c207d7d528460fa978f9e391bd8aaf9c8311de137"}, + {file = "websockets-12.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1a9d160fd080c6285e202327aba140fc9a0d910b09e423afff4ae5cbbf1c7205"}, + {file = "websockets-12.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87b4aafed34653e465eb77b7c93ef058516cb5acf3eb21e42f33928616172def"}, + {file = "websockets-12.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:b2ee7288b85959797970114deae81ab41b731f19ebcd3bd499ae9ca0e3f1d2c8"}, + {file = "websockets-12.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:7fa3d25e81bfe6a89718e9791128398a50dec6d57faf23770787ff441d851967"}, + {file = "websockets-12.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:a571f035a47212288e3b3519944f6bf4ac7bc7553243e41eac50dd48552b6df7"}, + {file = "websockets-12.0-cp38-cp38-win32.whl", hash = "sha256:3c6cc1360c10c17463aadd29dd3af332d4a1adaa8796f6b0e9f9df1fdb0bad62"}, + {file = "websockets-12.0-cp38-cp38-win_amd64.whl", hash = "sha256:1bf386089178ea69d720f8db6199a0504a406209a0fc23e603b27b300fdd6892"}, + {file = "websockets-12.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:ab3d732ad50a4fbd04a4490ef08acd0517b6ae6b77eb967251f4c263011a990d"}, + {file = "websockets-12.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a1d9697f3337a89691e3bd8dc56dea45a6f6d975f92e7d5f773bc715c15dde28"}, + {file = "websockets-12.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1df2fbd2c8a98d38a66f5238484405b8d1d16f929bb7a33ed73e4801222a6f53"}, + {file = "websockets-12.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:23509452b3bc38e3a057382c2e941d5ac2e01e251acce7adc74011d7d8de434c"}, + {file = "websockets-12.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e5fc14ec6ea568200ea4ef46545073da81900a2b67b3e666f04adf53ad452ec"}, + {file = "websockets-12.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:46e71dbbd12850224243f5d2aeec90f0aaa0f2dde5aeeb8fc8df21e04d99eff9"}, + {file = "websockets-12.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b81f90dcc6c85a9b7f29873beb56c94c85d6f0dac2ea8b60d995bd18bf3e2aae"}, + {file = "websockets-12.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:a02413bc474feda2849c59ed2dfb2cddb4cd3d2f03a2fedec51d6e959d9b608b"}, + {file = "websockets-12.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:bbe6013f9f791944ed31ca08b077e26249309639313fff132bfbf3ba105673b9"}, + {file = "websockets-12.0-cp39-cp39-win32.whl", hash = "sha256:cbe83a6bbdf207ff0541de01e11904827540aa069293696dd528a6640bd6a5f6"}, + {file = "websockets-12.0-cp39-cp39-win_amd64.whl", hash = "sha256:fc4e7fa5414512b481a2483775a8e8be7803a35b30ca805afa4998a84f9fd9e8"}, + {file = "websockets-12.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:248d8e2446e13c1d4326e0a6a4e9629cb13a11195051a73acf414812700badbd"}, + {file = "websockets-12.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f44069528d45a933997a6fef143030d8ca8042f0dfaad753e2906398290e2870"}, + {file = "websockets-12.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c4e37d36f0d19f0a4413d3e18c0d03d0c268ada2061868c1e6f5ab1a6d575077"}, + {file = "websockets-12.0-pp310-pypy310_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d829f975fc2e527a3ef2f9c8f25e553eb7bc779c6665e8e1d52aa22800bb38b"}, + {file = "websockets-12.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:2c71bd45a777433dd9113847af751aae36e448bc6b8c361a566cb043eda6ec30"}, + {file = "websockets-12.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:0bee75f400895aef54157b36ed6d3b308fcab62e5260703add87f44cee9c82a6"}, + {file = "websockets-12.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:423fc1ed29f7512fceb727e2d2aecb952c46aa34895e9ed96071821309951123"}, + {file = "websockets-12.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27a5e9964ef509016759f2ef3f2c1e13f403725a5e6a1775555994966a66e931"}, + {file = "websockets-12.0-pp38-pypy38_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c3181df4583c4d3994d31fb235dc681d2aaad744fbdbf94c4802485ececdecf2"}, + {file = "websockets-12.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:b067cb952ce8bf40115f6c19f478dc71c5e719b7fbaa511359795dfd9d1a6468"}, + {file = "websockets-12.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:00700340c6c7ab788f176d118775202aadea7602c5cc6be6ae127761c16d6b0b"}, + {file = "websockets-12.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e469d01137942849cff40517c97a30a93ae79917752b34029f0ec72df6b46399"}, + {file = "websockets-12.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffefa1374cd508d633646d51a8e9277763a9b78ae71324183693959cf94635a7"}, + {file = "websockets-12.0-pp39-pypy39_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba0cab91b3956dfa9f512147860783a1829a8d905ee218a9837c18f683239611"}, + {file = "websockets-12.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:2cb388a5bfb56df4d9a406783b7f9dbefb888c09b71629351cc6b036e9259370"}, + {file = "websockets-12.0-py3-none-any.whl", hash = "sha256:dc284bbc8d7c78a6c69e0c7325ab46ee5e40bb4d50e494d8131a07ef47500e9e"}, + {file = "websockets-12.0.tar.gz", hash = "sha256:81df9cbcbb6c260de1e007e58c011bfebe2dafc8435107b0537f393dd38c8b1b"}, +] + [[package]] name = "yarl" version = "1.9.4" @@ -2674,4 +3134,4 @@ proxy = ["PyJWT", "apscheduler", "backoff", "cryptography", "fastapi", "fastapi- [metadata] lock-version = "2.0" python-versions = ">=3.8.1,<4.0, !=3.9.7" -content-hash = "ff38be297294f084a739ef869d41d3d80f09c80e1d05d2963073d49790f33f37" +content-hash = "51bdb74cce68f06211fd56fb57a0293f8b43d303f31d19995bd3c452c733a9f0" diff --git a/proxy_server_config.yaml b/proxy_server_config.yaml index 0673d967d1..9b0e7c9d0c 100644 --- a/proxy_server_config.yaml +++ b/proxy_server_config.yaml @@ -84,7 +84,6 @@ model_list: model: text-completion-openai/gpt-3.5-turbo-instruct litellm_settings: drop_params: True - enable_preview_features: True # max_budget: 100 # budget_duration: 30d num_retries: 5 diff --git a/pyproject.toml b/pyproject.toml index fa525496c9..fe88b06996 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "litellm" -version = "1.37.5" +version = "1.37.9" description = "Library to easily interface with LLM API providers" authors = ["BerriAI"] license = "MIT" @@ -25,7 +25,7 @@ requests = "^2.31.0" uvicorn = {version = "^0.22.0", optional = true} gunicorn = {version = "^22.0.0", optional = true} -fastapi = {version = "^0.109.1", optional = true} +fastapi = {version = "^0.111.0", optional = true} backoff = {version = "*", optional = true} pyyaml = {version = "^6.0.1", optional = true} rq = {version = "*", optional = true} @@ -80,7 +80,7 @@ requires = ["poetry-core", "wheel"] build-backend = "poetry.core.masonry.api" [tool.commitizen] -version = "1.37.5" +version = "1.37.9" version_files = [ "pyproject.toml:^version" ] diff --git a/requirements.txt b/requirements.txt index d16f0453ff..88f7174b3e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,7 @@ # LITELLM PROXY DEPENDENCIES # anyio==4.2.0 # openai + http req. openai==1.14.3 # openai req. -fastapi==0.100.0 # server dep +fastapi==0.111.0 # server dep backoff==2.2.1 # server dep pyyaml==6.0.0 # server dep uvicorn==0.29.0 # server dep diff --git a/tests/test_openai_endpoints.py b/tests/test_openai_endpoints.py index 7bc97ca593..43dcae3cd7 100644 --- a/tests/test_openai_endpoints.py +++ b/tests/test_openai_endpoints.py @@ -424,10 +424,7 @@ async def test_batch_chat_completions(): response = await chat_completion( session=session, key="sk-1234", - model=[ - "gpt-3.5-turbo", - "fake-openai-endpoint", - ], + model="gpt-3.5-turbo,fake-openai-endpoint", ) print(f"response: {response}") diff --git a/tests/test_spend_logs.py b/tests/test_spend_logs.py index 477fdb86f0..1a3373c9d7 100644 --- a/tests/test_spend_logs.py +++ b/tests/test_spend_logs.py @@ -138,6 +138,23 @@ async def get_predict_spend_logs(session): return await response.json() +async def get_spend_report(session, start_date, end_date): + url = "http://0.0.0.0:4000/global/spend/report" + headers = {"Authorization": "Bearer sk-1234", "Content-Type": "application/json"} + async with session.get( + url, headers=headers, params={"start_date": start_date, "end_date": end_date} + ) as response: + status = response.status + response_text = await response.text() + + print(response_text) + print() + + if status != 200: + raise Exception(f"Request did not return a 200 status code: {status}") + return await response.json() + + @pytest.mark.asyncio async def test_get_predicted_spend_logs(): """ @@ -205,3 +222,39 @@ async def test_spend_logs_high_traffic(): except: print(n, time.time() - start, 0) raise Exception("it worked!") + + +@pytest.mark.asyncio +async def test_spend_report_endpoint(): + async with aiohttp.ClientSession( + timeout=aiohttp.ClientTimeout(total=600) + ) as session: + import datetime + + todays_date = datetime.date.today() + datetime.timedelta(days=1) + todays_date = todays_date.strftime("%Y-%m-%d") + + print("todays_date", todays_date) + thirty_days_ago = ( + datetime.date.today() - datetime.timedelta(days=30) + ).strftime("%Y-%m-%d") + spend_report = await get_spend_report( + session=session, start_date=thirty_days_ago, end_date=todays_date + ) + print("spend report", spend_report) + + for row in spend_report: + date = row["group_by_day"] + teams = row["teams"] + for team in teams: + team_name = team["team_name"] + total_spend = team["total_spend"] + metadata = team["metadata"] + + assert team_name is not None + + print(f"Date: {date}") + print(f"Team: {team_name}") + print(f"Total Spend: {total_spend}") + print("Metadata: ", metadata) + print() diff --git a/ui/litellm-dashboard/out/404.html b/ui/litellm-dashboard/out/404.html index eaf5701355..b70559084d 100644 --- a/ui/litellm-dashboard/out/404.html +++ b/ui/litellm-dashboard/out/404.html @@ -1 +1 @@ -404: This page could not be found.LiteLLM Dashboard

404

This page could not be found.

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

404

This page could not be found.

\ No newline at end of file diff --git a/ui/litellm-dashboard/out/_next/static/chunks/app/page-6a39771cacf75ea6.js b/ui/litellm-dashboard/out/_next/static/chunks/app/page-6a39771cacf75ea6.js new file mode 100644 index 0000000000..7d08a80c96 --- /dev/null +++ b/ui/litellm-dashboard/out/_next/static/chunks/app/page-6a39771cacf75ea6.js @@ -0,0 +1 @@ +(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[931],{20661:function(e,l,t){Promise.resolve().then(t.bind(t,7926))},7926:function(e,l,t){"use strict";t.r(l),t.d(l,{default:function(){return lb}});var s,a,r=t(3827),n=t(64090),o=t(47907),i=t(8792),c=t(40491),d=t(65270),m=e=>{let{userID:l,userRole:t,userEmail:s,showSSOBanner:a}=e;console.log("User ID:",l),console.log("userEmail:",s),console.log("showSSOBanner:",a);let n=[{key:"1",label:(0,r.jsxs)(r.Fragment,{children:[(0,r.jsxs)("p",{children:["Role: ",t]}),(0,r.jsxs)("p",{children:["ID: ",l]})]})}];return(0,r.jsxs)("nav",{className:"left-0 right-0 top-0 flex justify-between items-center h-12 mb-4",children:[(0,r.jsx)("div",{className:"text-left my-2 absolute top-0 left-0",children:(0,r.jsx)("div",{className:"flex flex-col items-center",children:(0,r.jsx)(i.default,{href:"/",children:(0,r.jsx)("button",{className:"text-gray-800 rounded text-center",children:(0,r.jsx)("img",{src:"/get_image",width:160,height:160,alt:"LiteLLM Brand",className:"mr-2"})})})})}),(0,r.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,r.jsx)("div",{style:{padding:"6px",borderRadius:"8px"},children:(0,r.jsx)("a",{href:"https://calendly.com/d/4mp-gd3-k5k/litellm-1-1-onboarding-chat",target:"_blank",style:{fontSize:"14px",textDecoration:"underline"},children:"Request hosted proxy"})}):null,(0,r.jsx)("div",{style:{border:"1px solid #391085",padding:"6px",borderRadius:"8px"},children:(0,r.jsx)(c.Z,{menu:{items:n},children:(0,r.jsx)(d.Z,{children:s})})})]})]})},u=t(80588);let h=async()=>{try{let e=await fetch("https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json"),l=await e.json();return console.log("received data: ".concat(l)),l}catch(e){throw console.error("Failed to get model cost map:",e),e}},x=async(e,l)=>{try{let t=await fetch("/model/new",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...l})});if(!t.ok){let e=await t.text();throw u.ZP.error("Failed to create key: "+e,10),console.error("Error response from the server:",e),Error("Network response was not ok")}let s=await t.json();return console.log("API Response:",s),u.ZP.success("Model created successfully. Wait 60s and refresh on 'All Models' page"),s}catch(e){throw console.error("Failed to create key:",e),e}},p=async(e,l)=>{console.log("model_id in model delete call: ".concat(l));try{let t=await fetch("/model/delete",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({id:l})});if(!t.ok){let e=await t.text();throw u.ZP.error("Failed to create key: "+e,10),console.error("Error response from the server:",e),Error("Network response was not ok")}let s=await t.json();return console.log("API Response:",s),u.ZP.success("Model deleted successfully. Restart server to see this."),s}catch(e){throw console.error("Failed to create key:",e),e}},j=async(e,l,t)=>{try{if(console.log("Form Values in keyCreateCall:",t),t.description&&(t.metadata||(t.metadata={}),t.metadata.description=t.description,delete t.description,t.metadata=JSON.stringify(t.metadata)),t.metadata){console.log("formValues.metadata:",t.metadata);try{t.metadata=JSON.parse(t.metadata)}catch(e){throw u.ZP.error("Failed to parse metadata: "+e,10),Error("Failed to parse metadata: "+e)}}console.log("Form Values after check:",t);let s=await fetch("/key/generate",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({user_id:l,...t})});if(!s.ok){let e=await s.text();throw u.ZP.error("Failed to create key: "+e,10),console.error("Error response from the server:",e),Error("Network response was not ok")}let a=await s.json();return console.log("API Response:",a),a}catch(e){throw console.error("Failed to create key:",e),e}},g=async(e,l,t)=>{try{if(console.log("Form Values in keyCreateCall:",t),t.description&&(t.metadata||(t.metadata={}),t.metadata.description=t.description,delete t.description,t.metadata=JSON.stringify(t.metadata)),t.metadata){console.log("formValues.metadata:",t.metadata);try{t.metadata=JSON.parse(t.metadata)}catch(e){throw u.ZP.error("Failed to parse metadata: "+e,10),Error("Failed to parse metadata: "+e)}}console.log("Form Values after check:",t);let s=await fetch("/user/new",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({user_id:l,...t})});if(!s.ok){let e=await s.text();throw u.ZP.error("Failed to create key: "+e,10),console.error("Error response from the server:",e),Error("Network response was not ok")}let a=await s.json();return console.log("API Response:",a),a}catch(e){throw console.error("Failed to create key:",e),e}},y=async(e,l)=>{try{console.log("in keyDeleteCall:",l);let t=await fetch("/key/delete",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({keys:[l]})});if(!t.ok){let e=await t.text();throw u.ZP.error("Failed to delete key: "+e,10),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}},f=async(e,l)=>{try{console.log("in teamDeleteCall:",l);let t=await fetch("/team/delete",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({team_ids:[l]})});if(!t.ok){let e=await t.text();throw u.ZP.error("Failed to delete team: "+e,10),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to delete key:",e),e}},Z=async function(e,l,t){let s=arguments.length>3&&void 0!==arguments[3]&&arguments[3],a=arguments.length>4?arguments[4]:void 0,r=arguments.length>5?arguments[5]:void 0;try{let n="/user/info";"App Owner"==t&&l&&(n="".concat(n,"?user_id=").concat(l)),"App User"==t&&l&&(n="".concat(n,"?user_id=").concat(l)),console.log("in userInfoCall viewAll=",s),s&&r&&null!=a&&void 0!=a&&(n="".concat(n,"?view_all=true&page=").concat(a,"&page_size=").concat(r));let o=await fetch(n,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!o.ok){let e=await o.text();throw u.ZP.error(e,10),Error("Network response was not ok")}let i=await o.json();return console.log("API Response:",i),i}catch(e){throw console.error("Failed to create key:",e),e}},_=async(e,l)=>{try{let t="/team/info";l&&(t="".concat(t,"?team_id=").concat(l)),console.log("in teamInfoCall");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 u.ZP.error(e,10),Error("Network response was not ok")}let a=await s.json();return console.log("API Response:",a),a}catch(e){throw console.error("Failed to create key:",e),e}},w=async e=>{try{let l=await fetch("/global/spend",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw u.ZP.error(e,10),Error("Network response was not ok")}return await l.json()}catch(e){throw console.error("Failed to create key:",e),e}},b=async(e,l,t)=>{try{let l=await fetch("/v2/model/info",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw u.ZP.error(e,10),Error("Network response was not ok")}let t=await l.json();return console.log("modelInfoCall:",t),t}catch(e){throw console.error("Failed to create key:",e),e}},k=async(e,l,t,s,a,r)=>{try{let l="/model/metrics";s&&(l="".concat(l,"?_selected_model_group=").concat(s,"&startTime=").concat(a,"&endTime=").concat(r));let t=await fetch(l,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw u.ZP.error(e,10),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},v=async(e,l,t,s,a,r)=>{try{let l="/model/metrics/slow_responses";s&&(l="".concat(l,"?_selected_model_group=").concat(s,"&startTime=").concat(a,"&endTime=").concat(r));let t=await fetch(l,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw u.ZP.error(e,10),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},S=async(e,l,t,s,a,r)=>{try{let l="/model/metrics/exceptions";s&&(l="".concat(l,"?_selected_model_group=").concat(s,"&startTime=").concat(a,"&endTime=").concat(r));let t=await fetch(l,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw u.ZP.error(e,10),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},N=async(e,l,t)=>{try{let l=await fetch("/models",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw u.ZP.error(e,10),Error("Network response was not ok")}return await l.json()}catch(e){throw console.error("Failed to create key:",e),e}},A=async e=>{try{let l="/global/spend/teams";console.log("in teamSpendLogsCall:",l);let t=await fetch("".concat(l),{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw u.ZP.error(e,10),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}},E=async(e,l,t)=>{try{let s="/global/spend/tags";l&&t&&(s="".concat(s,"?start_date=").concat(l,"&end_date=").concat(t)),console.log("in tagsSpendLogsCall:",s);let a=await fetch("".concat(s),{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!a.ok){let e=await a.text();throw u.ZP.error(e,10),Error("Network response was not ok")}let r=await a.json();return console.log(r),r}catch(e){throw console.error("Failed to create key:",e),e}},I=async(e,l,t,s,a,r)=>{try{console.log("user role in spend logs call: ".concat(t));let l="/spend/logs";l="App Owner"==t?"".concat(l,"?user_id=").concat(s,"&start_date=").concat(a,"&end_date=").concat(r):"".concat(l,"?start_date=").concat(a,"&end_date=").concat(r);let n=await fetch(l,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!n.ok){let e=await n.text();throw u.ZP.error(e,10),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}},C=async e=>{try{let l=await fetch("/global/spend/logs",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw u.ZP.error(e,10),Error("Network response was not ok")}let t=await l.json();return console.log(t),t}catch(e){throw console.error("Failed to create key:",e),e}},P=async e=>{try{let l=await fetch("/global/spend/keys?limit=5",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw u.ZP.error(e,10),Error("Network response was not ok")}let t=await l.json();return console.log(t),t}catch(e){throw console.error("Failed to create key:",e),e}},T=async(e,l,t,s)=>{try{let a="";a=l?JSON.stringify({api_key:l,startTime:t,endTime:s}):JSON.stringify({startTime:t,endTime:s});let r={method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}};r.body=a;let n=await fetch("/global/spend/end_users",r);if(!n.ok){let e=await n.text();throw u.ZP.error(e,10),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}},O=async e=>{try{let l=await fetch("/global/spend/models?limit=5",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw u.ZP.error(e,10),Error("Network response was not ok")}let t=await l.json();return console.log(t),t}catch(e){throw console.error("Failed to create key:",e),e}},F=async(e,l)=>{try{let t=await fetch("/v2/key/info",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({keys:l})});if(!t.ok){let e=await t.text();throw u.ZP.error(e,10),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}},R=async(e,l)=>{try{let t="/user/get_users?role=".concat(l);console.log("in userGetAllUsersCall:",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 u.ZP.error("Failed to delete key: "+e,10),Error("Network response was not ok")}let a=await s.json();return console.log(a),a}catch(e){throw console.error("Failed to get requested models:",e),e}},M=async(e,l)=>{try{console.log("Form Values in teamCreateCall:",l);let t=await fetch("/team/new",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...l})});if(!t.ok){let e=await t.text();throw u.ZP.error("Failed to create key: "+e,10),console.error("Error response from the server:",e),Error("Network response was not ok")}let s=await t.json();return console.log("API Response:",s),s}catch(e){throw console.error("Failed to create key:",e),e}},L=async(e,l)=>{try{console.log("Form Values in keyUpdateCall:",l);let t=await fetch("/key/update",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...l})});if(!t.ok){let e=await t.text();throw u.ZP.error("Failed to update key: "+e,10),console.error("Error response from the server:",e),Error("Network response was not ok")}let s=await t.json();return console.log("Update key Response:",s),s}catch(e){throw console.error("Failed to create key:",e),e}},U=async(e,l)=>{try{console.log("Form Values in teamUpateCall:",l);let t=await fetch("/team/update",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...l})});if(!t.ok){let e=await t.text();throw u.ZP.error("Failed to update team: "+e,10),console.error("Error response from the server:",e),Error("Network response was not ok")}let s=await t.json();return console.log("Update Team Response:",s),s}catch(e){throw console.error("Failed to create key:",e),e}},D=async(e,l)=>{try{console.log("Form Values in modelUpateCall:",l);let t=await fetch("/model/update",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...l})});if(!t.ok){let e=await t.text();throw u.ZP.error("Failed to update model: "+e,10),console.error("Error update from the server:",e),Error("Network response was not ok")}let s=await t.json();return console.log("Update model Response:",s),s}catch(e){throw console.error("Failed to update model:",e),e}},K=async(e,l,t)=>{try{console.log("Form Values in teamMemberAddCall:",t);let s=await fetch("/team/member_add",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({team_id:l,member:t})});if(!s.ok){let e=await s.text();throw u.ZP.error("Failed to create key: "+e,10),console.error("Error response from the server:",e),Error("Network response was not ok")}let a=await s.json();return console.log("API Response:",a),a}catch(e){throw console.error("Failed to create key:",e),e}},B=async(e,l,t)=>{try{console.log("Form Values in userUpdateUserCall:",l);let s={...l};null!==t&&(s.user_role=t),s=JSON.stringify(s);let a=await fetch("/user/update",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:s});if(!a.ok){let e=await a.text();throw u.ZP.error("Failed to create key: "+e,10),console.error("Error response from the server:",e),Error("Network response was not ok")}let r=await a.json();return console.log("API Response:",r),r}catch(e){throw console.error("Failed to create key:",e),e}},z=async(e,l)=>{try{let t="/health/services?service=".concat(l);console.log("Checking Slack Budget Alerts service health");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 u.ZP.error("Failed ".concat(l," service health check ")+e),Error(e)}let a=await s.json();return u.ZP.success("Test request to ".concat(l," made - check logs/alerts on ").concat(l," to verify")),a}catch(e){throw console.error("Failed to perform health check:",e),e}},q=async(e,l,t)=>{try{let l=await fetch("/get/config/callbacks",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw u.ZP.error(e,10),Error("Network response was not ok")}return await l.json()}catch(e){throw console.error("Failed to get callbacks:",e),e}},V=async(e,l)=>{try{let t=await fetch("/config/update",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...l})});if(!t.ok){let e=await t.text();throw u.ZP.error(e,10),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to set callbacks:",e),e}},G=async e=>{try{let l=await fetch("/health",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw u.ZP.error(e),Error("Network response was not ok")}return await l.json()}catch(e){throw console.error("Failed to call /health:",e),e}};var Y=t(10384),W=t(46453),J=t(16450),H=t(52273),$=t(26780),X=t(15595),Q=t(6698),ee=t(71801),el=t(42440),et=t(42308),es=t(50670),ea=t(81583),er=t(99129),en=t(44839),eo=t(88707),ei=t(1861);let{Option:ec}=es.default;var ed=e=>{let{userID:l,team:t,userRole:s,accessToken:a,data:o,setData:i}=e,[c]=ea.Z.useForm(),[d,m]=(0,n.useState)(!1),[h,x]=(0,n.useState)(null),[p,g]=(0,n.useState)(null),[y,f]=(0,n.useState)([]),[Z,_]=(0,n.useState)([]),w=()=>{m(!1),c.resetFields()},b=()=>{m(!1),x(null),c.resetFields()};(0,n.useEffect)(()=>{(async()=>{try{if(null===l||null===s)return;if(null!==a){let e=(await N(a,l,s)).data.map(e=>e.id);console.log("available_model_names:",e),f(e)}}catch(e){console.error("Error fetching user models:",e)}})()},[a,l,s]);let k=async e=>{try{var t,s,r;let n=null!==(t=null==e?void 0:e.key_alias)&&void 0!==t?t:"",d=null!==(s=null==e?void 0:e.team_id)&&void 0!==s?s:null;if((null!==(r=null==o?void 0:o.filter(e=>e.team_id===d).map(e=>e.key_alias))&&void 0!==r?r:[]).includes(n))throw Error("Key alias ".concat(n," already exists for team with ID ").concat(d,", please provide another key alias"));u.ZP.info("Making API Call"),m(!0);let h=await j(a,l,e);console.log("key create Response:",h),i(e=>e?[...e,h]:[h]),x(h.key),g(h.soft_budget),u.ZP.success("API Key Created"),c.resetFields(),localStorage.removeItem("userData"+l)}catch(e){console.error("Error creating the key:",e),u.ZP.error("Error creating the key: ".concat(e),20)}};return(0,n.useEffect)(()=>{_(t&&t.models.length>0?t.models.includes("all-proxy-models")?y:t.models:y)},[t,y]),(0,r.jsxs)("div",{children:[(0,r.jsx)(J.Z,{className:"mx-auto",onClick:()=>m(!0),children:"+ Create New Key"}),(0,r.jsx)(er.Z,{title:"Create Key",visible:d,width:800,footer:null,onOk:w,onCancel:b,children:(0,r.jsxs)(ea.Z,{form:c,onFinish:k,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(ea.Z.Item,{label:"Key Name",name:"key_alias",rules:[{required:!0,message:"Please input a key name"}],help:"required",children:(0,r.jsx)(H.Z,{placeholder:""})}),(0,r.jsx)(ea.Z.Item,{label:"Team ID",name:"team_id",hidden:!0,initialValue:t?t.team_id:null,valuePropName:"team_id",className:"mt-8",children:(0,r.jsx)(en.Z,{value:t?t.team_alias:"",disabled:!0})}),(0,r.jsx)(ea.Z.Item,{label:"Models",name:"models",rules:[{required:!0,message:"Please select a model"}],help:"required",children:(0,r.jsxs)(es.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},onChange:e=>{e.includes("all-team-models")&&c.setFieldsValue({models:["all-team-models"]})},children:[(0,r.jsx)(ec,{value:"all-team-models",children:"All Team Models"},"all-team-models"),Z.map(e=>(0,r.jsx)(ec,{value:e,children:e},e))]})}),(0,r.jsxs)($.Z,{className:"mt-20 mb-8",children:[(0,r.jsx)(Q.Z,{children:(0,r.jsx)("b",{children:"Optional Settings"})}),(0,r.jsxs)(X.Z,{children:[(0,r.jsx)(ea.Z.Item,{className:"mt-8",label:"Max Budget (USD)",name:"max_budget",help:"Budget cannot exceed team max budget: $".concat((null==t?void 0:t.max_budget)!==null&&(null==t?void 0:t.max_budget)!==void 0?null==t?void 0:t.max_budget:"unlimited"),rules:[{validator:async(e,l)=>{if(l&&t&&null!==t.max_budget&&l>t.max_budget)throw Error("Budget cannot exceed team max budget: $".concat(t.max_budget))}}],children:(0,r.jsx)(eo.Z,{step:.01,precision:2,width:200})}),(0,r.jsx)(ea.Z.Item,{className:"mt-8",label:"Reset Budget",name:"budget_duration",help:"Team Reset Budget: ".concat((null==t?void 0:t.budget_duration)!==null&&(null==t?void 0:t.budget_duration)!==void 0?null==t?void 0:t.budget_duration:"None"),children:(0,r.jsxs)(es.default,{defaultValue:null,placeholder:"n/a",children:[(0,r.jsx)(es.default.Option,{value:"24h",children:"daily"}),(0,r.jsx)(es.default.Option,{value:"30d",children:"monthly"})]})}),(0,r.jsx)(ea.Z.Item,{className:"mt-8",label:"Tokens per minute Limit (TPM)",name:"tpm_limit",help:"TPM cannot exceed team TPM limit: ".concat((null==t?void 0:t.tpm_limit)!==null&&(null==t?void 0:t.tpm_limit)!==void 0?null==t?void 0:t.tpm_limit:"unlimited"),rules:[{validator:async(e,l)=>{if(l&&t&&null!==t.tpm_limit&&l>t.tpm_limit)throw Error("TPM limit cannot exceed team TPM limit: ".concat(t.tpm_limit))}}],children:(0,r.jsx)(eo.Z,{step:1,width:400})}),(0,r.jsx)(ea.Z.Item,{className:"mt-8",label:"Requests per minute Limit (RPM)",name:"rpm_limit",help:"RPM cannot exceed team RPM limit: ".concat((null==t?void 0:t.rpm_limit)!==null&&(null==t?void 0:t.rpm_limit)!==void 0?null==t?void 0:t.rpm_limit:"unlimited"),rules:[{validator:async(e,l)=>{if(l&&t&&null!==t.rpm_limit&&l>t.rpm_limit)throw Error("RPM limit cannot exceed team RPM limit: ".concat(t.rpm_limit))}}],children:(0,r.jsx)(eo.Z,{step:1,width:400})}),(0,r.jsx)(ea.Z.Item,{label:"Expire Key (eg: 30s, 30h, 30d)",name:"duration",className:"mt-8",children:(0,r.jsx)(H.Z,{placeholder:""})}),(0,r.jsx)(ea.Z.Item,{label:"Metadata",name:"metadata",children:(0,r.jsx)(en.Z.TextArea,{rows:4,placeholder:"Enter metadata as JSON"})})]})]})]}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ei.ZP,{htmlType:"submit",children:"Create Key"})})]})}),h&&(0,r.jsx)(er.Z,{visible:d,onOk:w,onCancel:b,footer:null,children:(0,r.jsxs)(W.Z,{numItems:1,className:"gap-2 w-full",children:[(0,r.jsx)(el.Z,{children:"Save your Key"}),(0,r.jsx)(Y.Z,{numColSpan:1,children:(0,r.jsxs)("p",{children:["Please save this secret key somewhere safe and accessible. For security reasons, ",(0,r.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,r.jsx)(Y.Z,{numColSpan:1,children:null!=h?(0,r.jsxs)("div",{children:[(0,r.jsx)(ee.Z,{className:"mt-3",children:"API Key:"}),(0,r.jsx)("div",{style:{background:"#f8f8f8",padding:"10px",borderRadius:"5px",marginBottom:"10px"},children:(0,r.jsx)("pre",{style:{wordWrap:"break-word",whiteSpace:"normal"},children:h})}),(0,r.jsx)(et.CopyToClipboard,{text:h,onCopy:()=>{u.ZP.success("API Key copied to clipboard")},children:(0,r.jsx)(J.Z,{className:"mt-3",children:"Copy API Key"})})]}):(0,r.jsx)(ee.Z,{children:"Key being created, this might take 30s"})})]})})]})},em=t(9454),eu=t(98941),eh=t(33393),ex=t(5),ep=t(13810),ej=t(61244),eg=t(10827),ey=t(3851),ef=t(2044),eZ=t(64167),e_=t(74480),ew=t(7178),eb=t(95093),ek=t(27166);let{Option:ev}=es.default;var eS=e=>{let{userID:l,userRole:t,accessToken:s,selectedTeam:a,data:o,setData:i,teams:c}=e,[d,m]=(0,n.useState)(!1),[h,x]=(0,n.useState)(!1),[p,j]=(0,n.useState)(null),[g,f]=(0,n.useState)(null),[Z,_]=(0,n.useState)(null),[w,b]=(0,n.useState)(""),[k,v]=(0,n.useState)(!1),[S,A]=(0,n.useState)(!1),[E,I]=(0,n.useState)(null),[C,P]=(0,n.useState)([]),T=new Set,[O,F]=(0,n.useState)(T);(0,n.useEffect)(()=>{(async()=>{try{if(null===l)return;if(null!==s&&null!==t){let e=(await N(s,l,t)).data.map(e=>e.id);console.log("available_model_names:",e),P(e)}}catch(e){console.error("Error fetching user models:",e)}})()},[s,l,t]),(0,n.useEffect)(()=>{if(c){let e=new Set;c.forEach((l,t)=>{let s=l.team_id;e.add(s)}),F(e)}},[c]);let R=e=>{console.log("handleEditClick:",e),null==e.token&&null!==e.token_id&&(e.token=e.token_id),I(e),v(!0)},M=async e=>{if(null==s)return;let l=e.token;e.key=l,console.log("handleEditSubmit:",e);let t=await L(s,e);console.log("handleEditSubmit: newKeyValues",t),o&&i(o.map(e=>e.token===l?t:e)),u.ZP.success("Key updated successfully"),v(!1),I(null)},U=async e=>{console.log("handleDelete:",e),null==e.token&&null!==e.token_id&&(e.token=e.token_id),null!=o&&(j(e.token),localStorage.removeItem("userData"+l),x(!0))},D=async()=>{if(null!=p&&null!=o){try{await y(s,p);let e=o.filter(e=>e.token!==p);i(e)}catch(e){console.error("Error deleting the key:",e)}x(!1),j(null)}};if(null!=o)return console.log("RERENDER TRIGGERED"),(0,r.jsxs)("div",{children:[(0,r.jsxs)(ep.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh] mb-4 mt-2",children:[(0,r.jsxs)(eg.Z,{className:"mt-5 max-h-[300px] min-h-[300px]",children:[(0,r.jsx)(eZ.Z,{children:(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(e_.Z,{children:"Key Alias"}),(0,r.jsx)(e_.Z,{children:"Secret Key"}),(0,r.jsx)(e_.Z,{children:"Spend (USD)"}),(0,r.jsx)(e_.Z,{children:"Budget (USD)"}),(0,r.jsx)(e_.Z,{children:"Models"}),(0,r.jsx)(e_.Z,{children:"TPM / RPM Limits"})]})}),(0,r.jsx)(ey.Z,{children:o.map(e=>{if(console.log(e),"litellm-dashboard"===e.team_id)return null;if(a){if(console.log("item team id: ".concat(e.team_id,", knownTeamIDs.has(item.team_id): ").concat(O.has(e.team_id),", selectedTeam id: ").concat(a.team_id)),(null!=a.team_id||null===e.team_id||O.has(e.team_id))&&e.team_id!=a.team_id)return null;console.log("item team id: ".concat(e.team_id,", is returned"))}return(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(ef.Z,{style:{maxWidth:"2px",whiteSpace:"pre-wrap",overflow:"hidden"},children:null!=e.key_alias?(0,r.jsx)(ee.Z,{children:e.key_alias}):(0,r.jsx)(ee.Z,{children:"Not Set"})}),(0,r.jsx)(ef.Z,{children:(0,r.jsx)(ee.Z,{children:e.key_name})}),(0,r.jsx)(ef.Z,{children:(0,r.jsx)(ee.Z,{children:(()=>{try{return parseFloat(e.spend).toFixed(4)}catch(l){return e.spend}})()})}),(0,r.jsx)(ef.Z,{children:null!=e.max_budget?(0,r.jsx)(ee.Z,{children:e.max_budget}):(0,r.jsx)(ee.Z,{children:"Unlimited"})}),(0,r.jsx)(ef.Z,{children:Array.isArray(e.models)?(0,r.jsx)("div",{style:{display:"flex",flexDirection:"column"},children:0===e.models.length?(0,r.jsx)(r.Fragment,{children:a&&a.models&&a.models.length>0?a.models.map((e,l)=>"all-proxy-models"===e?(0,r.jsx)(ex.Z,{size:"xs",className:"mb-1",color:"red",children:(0,r.jsx)(ee.Z,{children:"All Proxy Models"})},l):"all-team-models"===e?(0,r.jsx)(ex.Z,{size:"xs",className:"mb-1",color:"red",children:(0,r.jsx)(ee.Z,{children:"All Team Models"})},l):(0,r.jsx)(ex.Z,{size:"xs",className:"mb-1",color:"blue",children:(0,r.jsx)(ee.Z,{children:e.length>30?"".concat(e.slice(0,30),"..."):e})},l)):(0,r.jsx)(ex.Z,{size:"xs",className:"mb-1",color:"blue",children:(0,r.jsx)(ee.Z,{children:"all-proxy-models"})})}):e.models.map((e,l)=>"all-proxy-models"===e?(0,r.jsx)(ex.Z,{size:"xs",className:"mb-1",color:"red",children:(0,r.jsx)(ee.Z,{children:"All Proxy Models"})},l):"all-team-models"===e?(0,r.jsx)(ex.Z,{size:"xs",className:"mb-1",color:"red",children:(0,r.jsx)(ee.Z,{children:"All Team Models"})},l):(0,r.jsx)(ex.Z,{size:"xs",className:"mb-1",color:"blue",children:(0,r.jsx)(ee.Z,{children:e.length>30?"".concat(e.slice(0,30),"..."):e})},l))}):null}),(0,r.jsx)(ef.Z,{children:(0,r.jsxs)(ee.Z,{children:["TPM: ",e.tpm_limit?e.tpm_limit:"Unlimited"," ",(0,r.jsx)("br",{})," RPM:"," ",e.rpm_limit?e.rpm_limit:"Unlimited"]})}),(0,r.jsxs)(ef.Z,{children:[(0,r.jsx)(ej.Z,{onClick:()=>{I(e),A(!0)},icon:em.Z,size:"sm"}),(0,r.jsx)(er.Z,{open:S,onCancel:()=>{A(!1),I(null)},footer:null,width:800,children:E&&(0,r.jsxs)(r.Fragment,{children:[(0,r.jsxs)("div",{className:"grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3 mt-8",children:[(0,r.jsxs)(ep.Z,{children:[(0,r.jsx)("p",{className:"text-tremor-default font-medium text-tremor-content dark:text-dark-tremor-content",children:"Spend"}),(0,r.jsx)("div",{className:"mt-2 flex items-baseline space-x-2.5",children:(0,r.jsx)("p",{className:"text-tremor font-semibold text-tremor-content-strong dark:text-dark-tremor-content-strong",children:(()=>{try{return parseFloat(E.spend).toFixed(4)}catch(e){return E.spend}})()})})]}),(0,r.jsxs)(ep.Z,{children:[(0,r.jsx)("p",{className:"text-tremor-default font-medium text-tremor-content dark:text-dark-tremor-content",children:"Budget"}),(0,r.jsx)("div",{className:"mt-2 flex items-baseline space-x-2.5",children:(0,r.jsx)("p",{className:"text-tremor font-semibold text-tremor-content-strong dark:text-dark-tremor-content-strong",children:null!=E.max_budget?(0,r.jsx)(r.Fragment,{children:E.max_budget}):(0,r.jsx)(r.Fragment,{children:"Unlimited"})})})]},e.name),(0,r.jsxs)(ep.Z,{children:[(0,r.jsx)("p",{className:"text-tremor-default font-medium text-tremor-content dark:text-dark-tremor-content",children:"Expires"}),(0,r.jsx)("div",{className:"mt-2 flex items-baseline space-x-2.5",children:(0,r.jsx)("p",{className:"text-tremor-default font-small text-tremor-content-strong dark:text-dark-tremor-content-strong",children:null!=E.expires?(0,r.jsx)(r.Fragment,{children:new Date(E.expires).toLocaleString(void 0,{day:"numeric",month:"long",year:"numeric",hour:"numeric",minute:"numeric",second:"numeric"})}):(0,r.jsx)(r.Fragment,{children:"Never"})})})]},e.name)]}),(0,r.jsxs)(ep.Z,{className:"my-4",children:[(0,r.jsx)(el.Z,{children:"Token Name"}),(0,r.jsx)(ee.Z,{className:"my-1",children:E.key_alias?E.key_alias:E.key_name}),(0,r.jsx)(el.Z,{children:"Token ID"}),(0,r.jsx)(ee.Z,{className:"my-1 text-[12px]",children:E.token}),(0,r.jsx)(el.Z,{children:"Metadata"}),(0,r.jsx)(ee.Z,{className:"my-1",children:(0,r.jsxs)("pre",{children:[JSON.stringify(E.metadata)," "]})})]}),(0,r.jsx)(J.Z,{className:"mx-auto flex items-center",onClick:()=>{A(!1),I(null)},children:"Close"})]})}),(0,r.jsx)(ej.Z,{icon:eu.Z,size:"sm",onClick:()=>R(e)}),(0,r.jsx)(ej.Z,{onClick:()=>U(e),icon:eh.Z,size:"sm"})]})]},e.token)})})]}),h&&(0,r.jsx)("div",{className:"fixed z-10 inset-0 overflow-y-auto",children:(0,r.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,r.jsx)("div",{className:"fixed inset-0 transition-opacity","aria-hidden":"true",children:(0,r.jsx)("div",{className:"absolute inset-0 bg-gray-500 opacity-75"})}),(0,r.jsx)("span",{className:"hidden sm:inline-block sm:align-middle sm:h-screen","aria-hidden":"true",children:"โ€‹"}),(0,r.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,r.jsx)("div",{className:"bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4",children:(0,r.jsx)("div",{className:"sm:flex sm:items-start",children:(0,r.jsxs)("div",{className:"mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left",children:[(0,r.jsx)("h3",{className:"text-lg leading-6 font-medium text-gray-900",children:"Delete Key"}),(0,r.jsx)("div",{className:"mt-2",children:(0,r.jsx)("p",{className:"text-sm text-gray-500",children:"Are you sure you want to delete this key ?"})})]})})}),(0,r.jsxs)("div",{className:"bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse",children:[(0,r.jsx)(J.Z,{onClick:D,color:"red",className:"ml-2",children:"Delete"}),(0,r.jsx)(J.Z,{onClick:()=>{x(!1),j(null)},children:"Cancel"})]})]})]})})]}),E&&(0,r.jsx)(e=>{let{visible:l,onCancel:t,token:s,onSubmit:o}=e,[i]=ea.Z.useForm(),[d,m]=(0,n.useState)(a),[u,h]=(0,n.useState)([]),[x,p]=(0,n.useState)(!1);return(0,r.jsx)(er.Z,{title:"Edit Key",visible:l,width:800,footer:null,onOk:()=>{i.validateFields().then(e=>{i.resetFields()}).catch(e=>{console.error("Validation failed:",e)})},onCancel:t,children:(0,r.jsxs)(ea.Z,{form:i,onFinish:M,initialValues:s,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(ea.Z.Item,{label:"Key Name",name:"key_alias",rules:[{required:!0,message:"Please input a key name"}],help:"required",children:(0,r.jsx)(en.Z,{})}),(0,r.jsx)(ea.Z.Item,{label:"Models",name:"models",rules:[{validator:(e,l)=>{let t=l.filter(e=>!d.models.includes(e)&&"all-team-models"!==e&&"all-proxy-models"!==e&&!d.models.includes("all-proxy-models"));return(console.log("errorModels: ".concat(t)),t.length>0)?Promise.reject("Some models are not part of the new team's models - ".concat(t,"Team models: ").concat(d.models)):Promise.resolve()}}],children:(0,r.jsxs)(es.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:[(0,r.jsx)(ev,{value:"all-team-models",children:"All Team Models"},"all-team-models"),d&&d.models?d.models.includes("all-proxy-models")?C.filter(e=>"all-proxy-models"!==e).map(e=>(0,r.jsx)(ev,{value:e,children:e},e)):d.models.map(e=>(0,r.jsx)(ev,{value:e,children:e},e)):C.map(e=>(0,r.jsx)(ev,{value:e,children:e},e))]})}),(0,r.jsx)(ea.Z.Item,{className:"mt-8",label:"Max Budget (USD)",name:"max_budget",help:"Budget cannot exceed team max budget: ".concat((null==d?void 0:d.max_budget)!==null&&(null==d?void 0:d.max_budget)!==void 0?null==d?void 0:d.max_budget:"unlimited"),rules:[{validator:async(e,l)=>{if(l&&d&&null!==d.max_budget&&l>d.max_budget)throw console.log("keyTeam.max_budget: ".concat(d.max_budget)),Error("Budget cannot exceed team max budget: $".concat(d.max_budget))}}],children:(0,r.jsx)(eo.Z,{step:.01,precision:2,width:200})}),(0,r.jsx)(ea.Z.Item,{label:"token",name:"token",hidden:!0}),(0,r.jsx)(ea.Z.Item,{label:"Team",name:"team_id",help:"the team this key belongs to",children:(0,r.jsx)(eb.Z,{value:s.team_alias,children:null==c?void 0:c.map((e,l)=>(0,r.jsx)(ek.Z,{value:e.team_id,onClick:()=>m(e),children:e.team_alias},l))})})]}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ei.ZP,{htmlType:"submit",children:"Edit Key"})})]})})},{visible:k,onCancel:()=>{v(!1),I(null)},token:E,onSubmit:M})]})},eN=t(76032),eA=t(35152),eE=e=>{let{userID:l,userRole:t,accessToken:s,userSpend:a,selectedTeam:o}=e;console.log("userSpend: ".concat(a));let[i,c]=(0,n.useState)(null!==a?a:0),[d,m]=(0,n.useState)(0),[u,h]=(0,n.useState)([]);(0,n.useEffect)(()=>{let e=async()=>{if(s&&l&&t&&"Admin"===t&&null==a)try{let e=await w(s);e&&(e.spend?c(e.spend):c(0),e.max_budget?m(e.max_budget):m(0))}catch(e){console.error("Error fetching global spend data:",e)}};(async()=>{try{if(null===l||null===t)return;if(null!==s){let e=(await N(s,l,t)).data.map(e=>e.id);console.log("available_model_names:",e),h(e)}}catch(e){console.error("Error fetching user models:",e)}})(),e()},[t,s,l]),(0,n.useEffect)(()=>{null!==a&&c(a)},[a]);let x=[];o&&o.models&&(x=o.models),x&&x.includes("all-proxy-models")?(console.log("user models:",u),x=u):x&&x.includes("all-team-models")?x=o.models:x&&0===x.length&&(x=u);let p=void 0!==i?i.toFixed(4):null;return console.log("spend in view user spend: ".concat(i)),(0,r.jsxs)("div",{className:"flex items-center",children:[(0,r.jsxs)("div",{children:[(0,r.jsxs)("p",{className:"text-tremor-default text-tremor-content dark:text-dark-tremor-content",children:["Total Spend"," "]}),(0,r.jsxs)("p",{className:"text-2xl text-tremor-content-strong dark:text-dark-tremor-content-strong font-semibold",children:["$",p]})]}),(0,r.jsx)("div",{className:"ml-auto",children:(0,r.jsxs)($.Z,{children:[(0,r.jsx)(Q.Z,{children:(0,r.jsx)(ee.Z,{children:"Team Models"})}),(0,r.jsx)(X.Z,{className:"absolute right-0 z-10 bg-white p-2 shadow-lg max-w-xs",children:(0,r.jsx)(eN.Z,{children:x.map(e=>(0,r.jsx)(eA.Z,{children:(0,r.jsx)(ee.Z,{children:e})},e))})})]})})]})},eI=e=>{let{userID:l,userRole:t,selectedTeam:s,accessToken:a}=e,[o,i]=(0,n.useState)([]);(0,n.useEffect)(()=>{(async()=>{try{if(null===l||null===t)return;if(null!==a){let e=(await N(a,l,t)).data.map(e=>e.id);console.log("available_model_names:",e),i(e)}}catch(e){console.error("Error fetching user models:",e)}})()},[a,l,t]);let c=[];return s&&s.models&&(c=s.models),c&&c.includes("all-proxy-models")&&(console.log("user models:",o),c=o),(0,r.jsx)(r.Fragment,{children:(0,r.jsx)("div",{className:"mb-5",children:(0,r.jsx)("p",{className:"text-3xl text-tremor-content-strong dark:text-dark-tremor-content-strong font-semibold",children:null==s?void 0:s.team_alias})})})},eC=e=>{let l,{teams:t,setSelectedTeam:s,userRole:a}=e,o={models:[],team_id:null,team_alias:"Default Team"},[i,c]=(0,n.useState)(o);return(l="App User"===a?t:t?[...t,o]:[o],"App User"===a)?null:(0,r.jsxs)("div",{className:"mt-5 mb-5",children:[(0,r.jsx)(el.Z,{children:"Select Team"}),(0,r.jsx)(ee.Z,{children:"If you belong to multiple teams, this setting controls which team is used by default when creating new API Keys."}),(0,r.jsxs)(ee.Z,{className:"mt-3 mb-3",children:[(0,r.jsx)("b",{children:"Default Team:"})," If no team_id is set for a key, it will be grouped under here."]}),l&&l.length>0?(0,r.jsx)(eb.Z,{defaultValue:"0",children:l.map((e,l)=>(0,r.jsx)(ek.Z,{value:String(l),onClick:()=>s(e),children:e.team_alias},l))}):(0,r.jsxs)(ee.Z,{children:["No team created. ",(0,r.jsx)("b",{children:"Defaulting to personal account."})]})]})},eP=t(37963),eT=t(36083);console.log("isLocal:",!1);var eO=e=>{let{userID:l,userRole:t,teams:s,keys:a,setUserRole:i,userEmail:c,setUserEmail:d,setTeams:m,setKeys:u}=e,[h,x]=(0,n.useState)(null),p=(0,o.useSearchParams)();p.get("viewSpend"),(0,o.useRouter)();let j=p.get("token"),[g,y]=(0,n.useState)(null),[f,_]=(0,n.useState)(null),[b,k]=(0,n.useState)([]),v={models:[],team_alias:"Default Team",team_id:null},[S,A]=(0,n.useState)(s?s[0]:v);if(window.addEventListener("beforeunload",function(){sessionStorage.clear()}),(0,n.useEffect)(()=>{if(j){let e=(0,eP.o)(j);if(e){if(console.log("Decoded token:",e),console.log("Decoded key:",e.key),y(e.key),e.user_role){let l=function(e){if(!e)return"Undefined Role";switch(console.log("Received user role: ".concat(e)),e.toLowerCase()){case"app_owner":case"demo_app_owner":return"App Owner";case"app_admin":case"proxy_admin":return"Admin";case"proxy_admin_viewer":return"Admin Viewer";case"app_user":return"App User";default:return"Unknown Role"}}(e.user_role);console.log("Decoded user_role:",l),i(l)}else console.log("User role not defined");e.user_email?d(e.user_email):console.log("User Email is not set ".concat(e))}}if(l&&g&&t&&!a&&!h){let e=sessionStorage.getItem("userModels"+l);e?k(JSON.parse(e)):(async()=>{try{let e=await Z(g,l,t,!1,null,null);if(console.log("received teams in user dashboard: ".concat(Object.keys(e),"; team values: ").concat(Object.entries(e.teams))),"Admin"==t){let e=await w(g);x(e),console.log("globalSpend:",e)}else x(e.user_info);u(e.keys),m(e.teams);let s=[...e.teams];s.length>0?(console.log("response['teams']: ".concat(s)),A(s[0])):A(v),sessionStorage.setItem("userData"+l,JSON.stringify(e.keys)),sessionStorage.setItem("userSpendData"+l,JSON.stringify(e.user_info));let a=(await N(g,l,t)).data.map(e=>e.id);console.log("available_model_names:",a),k(a),console.log("userModels:",b),sessionStorage.setItem("userModels"+l,JSON.stringify(a))}catch(e){console.error("There was an error fetching the data",e)}})()}},[l,j,g,a,t]),(0,n.useEffect)(()=>{if(null!==a&&null!=S){let e=0;for(let l of a)S.hasOwnProperty("team_id")&&null!==l.team_id&&l.team_id===S.team_id&&(e+=l.spend);_(e)}else if(null!==a){let e=0;for(let l of a)e+=l.spend;_(e)}},[S]),null==l||null==j){let e="/sso/key/generate";return console.log("Full URL:",e),window.location.href=e,null}if(null==g)return null;if(null==t&&i("App Owner"),t&&"Admin Viewer"==t){let{Title:e,Paragraph:l}=eT.default;return(0,r.jsxs)("div",{children:[(0,r.jsx)(e,{level:1,children:"Access Denied"}),(0,r.jsx)(l,{children:"Ask your proxy admin for access to create keys"})]})}return console.log("inside user dashboard, selected team",S),console.log("teamSpend: ".concat(f)),(0,r.jsx)("div",{className:"w-full mx-4",children:(0,r.jsx)(W.Z,{numItems:1,className:"gap-2 p-8 h-[75vh] w-full mt-2",children:(0,r.jsxs)(Y.Z,{numColSpan:1,children:[(0,r.jsx)(eI,{userID:l,userRole:t,selectedTeam:S||null,accessToken:g}),(0,r.jsx)(eE,{userID:l,userRole:t,accessToken:g,userSpend:f,selectedTeam:S||null}),(0,r.jsx)(eS,{userID:l,userRole:t,accessToken:g,selectedTeam:S||null,data:a,setData:u,teams:s}),(0,r.jsx)(ed,{userID:l,team:S||null,userRole:t,accessToken:g,data:a,setData:u},S?S.team_id:null),(0,r.jsx)(eC,{teams:s,setSelectedTeam:A,userRole:t})]})})})},eF=t(35087),eR=t(92836),eM=t(26734),eL=t(41608),eU=t(32126),eD=t(23682),eK=t(47047),eB=t(76628),ez=t(57750),eq=t(44041),eV=t(38302),eG=t(28683),eY=t(1460),eW=t(78578),eJ=t(63954),eH=t(90252),e$=t(7905),eX=e=>{let{modelID:l,accessToken:t}=e,[s,a]=(0,n.useState)(!1),o=async()=>{try{u.ZP.info("Making API Call"),a(!0);let e=await p(t,l);console.log("model delete Response:",e),u.ZP.success("Model ".concat(l," deleted successfully")),a(!1)}catch(e){console.error("Error deleting the model:",e)}};return(0,r.jsxs)("div",{children:[(0,r.jsx)(ej.Z,{onClick:()=>a(!0),icon:eh.Z,size:"sm"}),(0,r.jsx)(er.Z,{open:s,onOk:o,okType:"danger",onCancel:()=>a(!1),children:(0,r.jsxs)(W.Z,{numItems:1,className:"gap-2 w-full",children:[(0,r.jsx)(el.Z,{children:"Delete Model"}),(0,r.jsx)(Y.Z,{numColSpan:1,children:(0,r.jsx)("p",{children:"Are you sure you want to delete this model? This action is irreversible."})}),(0,r.jsx)(Y.Z,{numColSpan:1,children:(0,r.jsxs)("p",{children:["Model ID: ",(0,r.jsx)("b",{children:l})]})})]})})]})},eQ=t(97766),e0=t(46495);let{Title:e1,Link:e2}=eT.default;(s=a||(a={})).OpenAI="OpenAI",s.Azure="Azure",s.Anthropic="Anthropic",s.Google_AI_Studio="Gemini (Google AI Studio)",s.Bedrock="Amazon Bedrock",s.OpenAI_Compatible="OpenAI-Compatible Endpoints (Groq, Together AI, Mistral AI, etc.)",s.Vertex_AI="Vertex AI (Anthropic, Gemini, etc.)";let e4={OpenAI:"openai",Azure:"azure",Anthropic:"anthropic",Google_AI_Studio:"gemini",Bedrock:"bedrock",OpenAI_Compatible:"openai",Vertex_AI:"vertex_ai"},e8={"BadRequestError (400)":"BadRequestErrorRetries","AuthenticationError (401)":"AuthenticationErrorRetries","TimeoutError (408)":"TimeoutErrorRetries","RateLimitError (429)":"RateLimitErrorRetries","ContentPolicyViolationError (400)":"ContentPolicyViolationErrorRetries","InternalServerError (500)":"InternalServerErrorRetries"},e5=async(e,l,t)=>{try{let s=Array.isArray(e.model)?e.model:[e.model];console.log("received deployments: ".concat(s)),console.log("received type of deployments: ".concat(typeof s)),s.forEach(async t=>{console.log("litellm_model: ".concat(t));let s={},a={};s.model=t;let r="";for(let[l,t]of Object.entries(e))if(""!==t){if("model_name"==l)r+=t;else if("custom_llm_provider"==l)continue;else if("model"==l)continue;else if("base_model"===l)a[l]=t;else if("litellm_extra_params"==l){console.log("litellm_extra_params:",t);let e={};if(t&&void 0!=t){try{e=JSON.parse(t)}catch(e){throw u.ZP.error("Failed to parse LiteLLM Extra Params: "+e,10),Error("Failed to parse litellm_extra_params: "+e)}for(let[l,t]of Object.entries(e))s[l]=t}}else s[l]=t}let n={model_name:r,litellm_params:s,model_info:a},o=await x(l,n);console.log("response for model create call: ".concat(o.data))}),t.resetFields()}catch(e){u.ZP.error("Failed to create model: "+e,10)}};var e3=e=>{var l,t,s;let{accessToken:o,token:i,userRole:c,userID:d,modelData:m={data:[]},setModelData:x}=e,[p,j]=(0,n.useState)([]),[g]=ea.Z.useForm(),[y,f]=(0,n.useState)(null),[Z,_]=(0,n.useState)(""),[w,N]=(0,n.useState)([]),A=Object.values(a).filter(e=>isNaN(Number(e))),[E,I]=(0,n.useState)("OpenAI"),[C,P]=(0,n.useState)(""),[T,O]=(0,n.useState)(!1),[F,R]=(0,n.useState)(null),[M,L]=(0,n.useState)([]),[U,K]=(0,n.useState)(null),[B,z]=(0,n.useState)([]),[Y,et]=(0,n.useState)([]),[es,en]=(0,n.useState)([]),[ec,ed]=(0,n.useState)([]),[em,eh]=(0,n.useState)([]),[ev,eS]=(0,n.useState)([]),[eN,eA]=(0,n.useState)([]),[eE,eI]=(0,n.useState)({from:new Date(Date.now()-6048e5),to:new Date}),[eC,eP]=(0,n.useState)(null),[eO,e3]=(0,n.useState)(0),e6=e=>{R(e),O(!0)},e7=async e=>{if(console.log("handleEditSubmit:",e),null==o)return;let l={},t=null;for(let[s,a]of Object.entries(e))"model_id"!==s?l[s]=a:t=a;let s={litellm_params:l,model_info:{id:t}};console.log("handleEditSubmit payload:",s);try{await D(o,s),u.ZP.success("Model updated successfully, restart server to see updates"),O(!1),R(null)}catch(e){console.log("Error occurred")}},e9=()=>{_(new Date().toLocaleString())},le=async()=>{if(!o){console.error("Access token is missing");return}console.log("new modelGroupRetryPolicy:",eC);try{await V(o,{router_settings:{model_group_retry_policy:eC}}),u.ZP.success("Retry settings saved successfully")}catch(e){console.error("Failed to save retry settings:",e),u.ZP.error("Failed to save retry settings")}};if((0,n.useEffect)(()=>{if(!o||!i||!c||!d)return;let e=async()=>{try{var e,l,t,s,a,r;let n=await b(o,d,c);console.log("Model data response:",n.data),x(n);let i=new Set;for(let e=0;e0&&(u=m[m.length-1],console.log("_initial_model_group:",u),K(u)),console.log("selectedModelGroup:",U);let h=await k(o,d,c,u,null===(e=eE.from)||void 0===e?void 0:e.toISOString(),null===(l=eE.to)||void 0===l?void 0:l.toISOString());console.log("Model metrics response:",h),et(h.data),en(h.all_api_bases);let p=await S(o,d,c,u,null===(t=eE.from)||void 0===t?void 0:t.toISOString(),null===(s=eE.to)||void 0===s?void 0:s.toISOString());console.log("Model exceptions response:",p),ed(p.data),eh(p.exception_types);let j=await v(o,d,c,u,null===(a=eE.from)||void 0===a?void 0:a.toISOString(),null===(r=eE.to)||void 0===r?void 0:r.toISOString());console.log("slowResponses:",j),eA(j);let g=(await q(o,d,c)).router_settings;console.log("routerSettingsInfo:",g);let y=g.model_group_retry_policy,f=g.num_retries;console.log("model_group_retry_policy:",y),console.log("default_retries:",f),eP(y),e3(f)}catch(e){console.error("There was an error fetching the model data",e)}};o&&i&&c&&d&&e();let l=async()=>{let e=await h();console.log("received model cost map data: ".concat(Object.keys(e))),f(e)};null==y&&l(),e9()},[o,i,c,d,y,Z]),!m||!o||!i||!c||!d)return(0,r.jsx)("div",{children:"Loading..."});let ll=[];for(let e=0;e(console.log("GET PROVIDER CALLED! - ".concat(y)),null!=y&&"object"==typeof y&&e in y)?y[e].litellm_provider:"openai";if(a){let e=a.split("/"),l=e[0];n=1===e.length?u(a):l}else n="openai";r&&(o=null==r?void 0:r.input_cost_per_token,i=null==r?void 0:r.output_cost_per_token,c=null==r?void 0:r.max_tokens),(null==s?void 0:s.litellm_params)&&(d=Object.fromEntries(Object.entries(null==s?void 0:s.litellm_params).filter(e=>{let[l]=e;return"model"!==l&&"api_base"!==l}))),m.data[e].provider=n,m.data[e].input_cost=o,m.data[e].output_cost=i,m.data[e].max_tokens=c,m.data[e].api_base=null==s?void 0:null===(t=s.litellm_params)||void 0===t?void 0:t.api_base,m.data[e].cleanedLitellmParams=d,ll.push(s.model_name),console.log(m.data[e])}if(c&&"Admin Viewer"==c){let{Title:e,Paragraph:l}=eT.default;return(0,r.jsxs)("div",{children:[(0,r.jsx)(e,{level:1,children:"Access Denied"}),(0,r.jsx)(l,{children:"Ask your proxy admin for access to view all models"})]})}let lt=e=>{console.log("received provider string: ".concat(e));let l=Object.keys(a).find(l=>a[l]===e);if(l){let e=e4[l];console.log("mappingResult: ".concat(e));let t=[];"object"==typeof y&&Object.entries(y).forEach(l=>{let[s,a]=l;null!==a&&"object"==typeof a&&"litellm_provider"in a&&(a.litellm_provider===e||a.litellm_provider.includes(e))&&t.push(s)}),N(t),console.log("providerModels: ".concat(w))}},ls=async()=>{try{u.ZP.info("Running health check..."),P("");let e=await G(o);P(e)}catch(e){console.error("Error running health check:",e),P("Error running health check")}},la=async(e,l,t)=>{if(console.log("Updating model metrics for group:",e),o&&d&&c&&l&&t){console.log("inside updateModelMetrics - startTime:",l,"endTime:",t),K(e);try{let s=await k(o,d,c,e,l.toISOString(),t.toISOString());console.log("Model metrics response:",s),et(s.data),en(s.all_api_bases);let a=await S(o,d,c,e,l.toISOString(),t.toISOString());console.log("Model exceptions response:",a),ed(a.data),eh(a.exception_types);let r=await v(o,d,c,e,l.toISOString(),t.toISOString());console.log("slowResponses:",r),eA(r)}catch(e){console.error("Failed to fetch model metrics",e)}}};return console.log("selectedProvider: ".concat(E)),console.log("providerModels.length: ".concat(w.length)),(0,r.jsx)("div",{style:{width:"100%",height:"100%"},children:(0,r.jsxs)(eM.Z,{className:"gap-2 p-8 h-[75vh] w-full mt-2",children:[(0,r.jsxs)(eL.Z,{className:"flex justify-between mt-2 w-full items-center",children:[(0,r.jsxs)("div",{className:"flex",children:[(0,r.jsx)(eR.Z,{children:"All Models"}),(0,r.jsx)(eR.Z,{children:"Add Model"}),(0,r.jsx)(eR.Z,{children:(0,r.jsx)("pre",{children:"/health Models"})}),(0,r.jsx)(eR.Z,{children:"Model Analytics"}),(0,r.jsx)(eR.Z,{children:"Model Retry Settings"})]}),(0,r.jsxs)("div",{className:"flex items-center space-x-2",children:[Z&&(0,r.jsxs)(ee.Z,{children:["Last Refreshed: ",Z]}),(0,r.jsx)(ej.Z,{icon:eJ.Z,variant:"shadow",size:"xs",className:"self-center",onClick:e9})]})]}),(0,r.jsxs)(eD.Z,{children:[(0,r.jsxs)(eU.Z,{children:[(0,r.jsxs)(W.Z,{children:[(0,r.jsxs)("div",{className:"flex items-center",children:[(0,r.jsx)(ee.Z,{children:"Filter by Public Model Name"}),(0,r.jsxs)(eb.Z,{className:"mb-4 mt-2 ml-2 w-50",defaultValue:"all",onValueChange:e=>K("all"===e?"all":e),children:[(0,r.jsx)(ek.Z,{value:"all",children:"All Models"}),M.map((e,l)=>(0,r.jsx)(ek.Z,{value:e,onClick:()=>K(e),children:e},l))]})]}),(0,r.jsx)(ep.Z,{children:(0,r.jsxs)(eg.Z,{className:"mt-5",children:[(0,r.jsx)(eZ.Z,{children:(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(e_.Z,{children:"Public Model Name "}),(0,r.jsx)(e_.Z,{children:"Provider"}),"Admin"===c&&(0,r.jsx)(e_.Z,{children:"API Base"}),(0,r.jsx)(e_.Z,{children:"Extra litellm Params"}),(0,r.jsx)(e_.Z,{children:"Input Price per token ($)"}),(0,r.jsx)(e_.Z,{children:"Output Price per token ($)"}),(0,r.jsx)(e_.Z,{children:"Max Tokens"}),(0,r.jsx)(e_.Z,{children:"Status"})]})}),(0,r.jsx)(ey.Z,{children:m.data.filter(e=>"all"===U||e.model_name===U||null==U||""===U).map((e,l)=>(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(ef.Z,{children:(0,r.jsx)(ee.Z,{children:e.model_name})}),(0,r.jsx)(ef.Z,{children:e.provider}),"Admin"===c&&(0,r.jsx)(ef.Z,{children:e.api_base}),(0,r.jsx)(ef.Z,{children:(0,r.jsxs)($.Z,{children:[(0,r.jsx)(Q.Z,{children:(0,r.jsx)(ee.Z,{children:"Litellm params"})}),(0,r.jsx)(X.Z,{children:(0,r.jsx)("pre",{children:JSON.stringify(e.cleanedLitellmParams,null,2)})})]})}),(0,r.jsx)(ef.Z,{children:e.input_cost||e.litellm_params.input_cost_per_token||null}),(0,r.jsx)(ef.Z,{children:e.output_cost||e.litellm_params.output_cost_per_token||null}),(0,r.jsx)(ef.Z,{children:e.max_tokens}),(0,r.jsx)(ef.Z,{children:e.model_info.db_model?(0,r.jsx)(ex.Z,{icon:eH.Z,className:"text-white",children:"DB Model"}):(0,r.jsx)(ex.Z,{icon:e$.Z,className:"text-black",children:"Config Model"})}),(0,r.jsxs)(ef.Z,{children:[(0,r.jsx)(ej.Z,{icon:eu.Z,size:"sm",onClick:()=>e6(e)}),(0,r.jsx)(eX,{modelID:e.model_info.id,accessToken:o})]})]},l))})]})})]}),(0,r.jsx)(e=>{let{visible:l,onCancel:t,model:s,onSubmit:a}=e,[n]=ea.Z.useForm(),o={},i="",c="";if(s){o=s.litellm_params,i=s.model_name;let e=s.model_info;e&&(c=e.id,console.log("model_id: ".concat(c)),o.model_id=c)}return(0,r.jsx)(er.Z,{title:"Edit Model "+i,visible:l,width:800,footer:null,onOk:()=>{n.validateFields().then(e=>{a(e),n.resetFields()}).catch(e=>{console.error("Validation failed:",e)})},onCancel:t,children:(0,r.jsxs)(ea.Z,{form:n,onFinish:e7,initialValues:o,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(ea.Z.Item,{className:"mt-8",label:"api_base",name:"api_base",children:(0,r.jsx)(H.Z,{})}),(0,r.jsx)(ea.Z.Item,{label:"tpm",name:"tpm",tooltip:"int (optional) - Tokens limit for this deployment: in tokens per minute (tpm). Find this information on your model/providers website",children:(0,r.jsx)(eo.Z,{min:0,step:1})}),(0,r.jsx)(ea.Z.Item,{label:"rpm",name:"rpm",tooltip:"int (optional) - Rate limit for this deployment: in requests per minute (rpm). Find this information on your model/providers website",children:(0,r.jsx)(eo.Z,{min:0,step:1})}),(0,r.jsx)(ea.Z.Item,{label:"max_retries",name:"max_retries",children:(0,r.jsx)(eo.Z,{min:0,step:1})}),(0,r.jsx)(ea.Z.Item,{label:"timeout",name:"timeout",tooltip:"int (optional) - Timeout in seconds for LLM requests (Defaults to 600 seconds)",children:(0,r.jsx)(eo.Z,{min:0,step:1})}),(0,r.jsx)(ea.Z.Item,{label:"stream_timeout",name:"stream_timeout",tooltip:"int (optional) - Timeout for stream requests (seconds)",children:(0,r.jsx)(eo.Z,{min:0,step:1})}),(0,r.jsx)(ea.Z.Item,{label:"input_cost_per_token",name:"input_cost_per_token",tooltip:"float (optional) - Input cost per token",children:(0,r.jsx)(eo.Z,{min:0,step:1e-4})}),(0,r.jsx)(ea.Z.Item,{label:"output_cost_per_token",name:"output_cost_per_token",tooltip:"float (optional) - Output cost per token",children:(0,r.jsx)(eo.Z,{min:0,step:1e-4})}),(0,r.jsx)(ea.Z.Item,{label:"model_id",name:"model_id",hidden:!0})]}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ei.ZP,{htmlType:"submit",children:"Save"})})]})})},{visible:T,onCancel:()=>{O(!1),R(null)},model:F,onSubmit:e7})]}),(0,r.jsxs)(eU.Z,{className:"h-full",children:[(0,r.jsx)(e1,{level:2,children:"Add new model"}),(0,r.jsx)(ep.Z,{children:(0,r.jsxs)(ea.Z,{form:g,onFinish:()=>{g.validateFields().then(e=>{e5(e,o,g)}).catch(e=>{console.error("Validation failed:",e)})},labelCol:{span:10},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(ea.Z.Item,{rules:[{required:!0,message:"Required"}],label:"Provider:",name:"custom_llm_provider",tooltip:"E.g. OpenAI, Azure OpenAI, Anthropic, Bedrock, etc.",labelCol:{span:10},labelAlign:"left",children:(0,r.jsx)(eb.Z,{value:E.toString(),children:A.map((e,l)=>(0,r.jsx)(ek.Z,{value:e,onClick:()=>{lt(e),I(e)},children:e},l))})}),(0,r.jsx)(ea.Z.Item,{rules:[{required:!0,message:"Required"}],label:"Public Model Name",name:"model_name",tooltip:"Model name your users will pass in. Also used for load-balancing, LiteLLM will load balance between all models with this public name.",className:"mb-0",children:(0,r.jsx)(H.Z,{placeholder:"Vertex AI (Anthropic, Gemini, etc.)"===(s=E.toString())?"gemini-pro":"Anthropic"==s?"claude-3-opus":"Amazon Bedrock"==s?"claude-3-opus":"Gemini (Google AI Studio)"==s?"gemini-pro":"gpt-3.5-turbo"})}),(0,r.jsxs)(eV.Z,{children:[(0,r.jsx)(eG.Z,{span:10}),(0,r.jsx)(eG.Z,{span:10,children:(0,r.jsx)(ee.Z,{className:"mb-3 mt-1",children:"Model name your users will pass in."})})]}),(0,r.jsx)(ea.Z.Item,{rules:[{required:!0,message:"Required"}],label:"LiteLLM Model Name(s)",name:"model",tooltip:"Actual model name used for making litellm.completion() call.",className:"mb-0",children:"Azure"===E?(0,r.jsx)(H.Z,{placeholder:"Enter model name"}):w.length>0?(0,r.jsx)(eK.Z,{value:w,children:w.map((e,l)=>(0,r.jsx)(eB.Z,{value:e,children:e},l))}):(0,r.jsx)(H.Z,{placeholder:"gpt-3.5-turbo-0125"})}),(0,r.jsxs)(eV.Z,{children:[(0,r.jsx)(eG.Z,{span:10}),(0,r.jsx)(eG.Z,{span:10,children:(0,r.jsxs)(ee.Z,{className:"mb-3 mt-1",children:["Actual model name used for making ",(0,r.jsx)(e2,{href:"https://docs.litellm.ai/docs/providers",target:"_blank",children:"litellm.completion() call"}),". We'll ",(0,r.jsx)(e2,{href:"https://docs.litellm.ai/docs/proxy/reliability#step-1---set-deployments-on-config",target:"_blank",children:"loadbalance"})," models with the same 'public name'"]})})]}),"Amazon Bedrock"!=E&&"Vertex AI (Anthropic, Gemini, etc.)"!=E&&(0,r.jsx)(ea.Z.Item,{rules:[{required:!0,message:"Required"}],label:"API Key",name:"api_key",children:(0,r.jsx)(H.Z,{placeholder:"sk-",type:"password"})}),"OpenAI"==E&&(0,r.jsx)(ea.Z.Item,{label:"Organization ID",name:"organization_id",children:(0,r.jsx)(H.Z,{placeholder:"[OPTIONAL] my-unique-org"})}),"Vertex AI (Anthropic, Gemini, etc.)"==E&&(0,r.jsx)(ea.Z.Item,{rules:[{required:!0,message:"Required"}],label:"Vertex Project",name:"vertex_project",children:(0,r.jsx)(H.Z,{placeholder:"adroit-cadet-1234.."})}),"Vertex AI (Anthropic, Gemini, etc.)"==E&&(0,r.jsx)(ea.Z.Item,{rules:[{required:!0,message:"Required"}],label:"Vertex Location",name:"vertex_location",children:(0,r.jsx)(H.Z,{placeholder:"us-east-1"})}),"Vertex AI (Anthropic, Gemini, etc.)"==E&&(0,r.jsx)(ea.Z.Item,{rules:[{required:!0,message:"Required"}],label:"Vertex Credentials",name:"vertex_credentials",className:"mb-0",children:(0,r.jsx)(e0.Z,{name:"file",accept:".json",beforeUpload:e=>{if("application/json"===e.type){let l=new FileReader;l.onload=e=>{if(e.target){let l=e.target.result;g.setFieldsValue({vertex_credentials:l})}},l.readAsText(e)}return!1},onChange(e){"uploading"!==e.file.status&&console.log(e.file,e.fileList),"done"===e.file.status?u.ZP.success("".concat(e.file.name," file uploaded successfully")):"error"===e.file.status&&u.ZP.error("".concat(e.file.name," file upload failed."))},children:(0,r.jsx)(ei.ZP,{icon:(0,r.jsx)(eQ.Z,{}),children:"Click to Upload"})})}),"Vertex AI (Anthropic, Gemini, etc.)"==E&&(0,r.jsxs)(eV.Z,{children:[(0,r.jsx)(eG.Z,{span:10}),(0,r.jsx)(eG.Z,{span:10,children:(0,r.jsx)(ee.Z,{className:"mb-3 mt-1",children:"Give litellm a gcp service account(.json file), so it can make the relevant calls"})})]}),("Azure"==E||"OpenAI-Compatible Endpoints (Groq, Together AI, Mistral AI, etc.)"==E)&&(0,r.jsx)(ea.Z.Item,{rules:[{required:!0,message:"Required"}],label:"API Base",name:"api_base",children:(0,r.jsx)(H.Z,{placeholder:"https://..."})}),"Azure"==E&&(0,r.jsx)(ea.Z.Item,{rules:[{required:!0,message:"Required"}],label:"API Version",name:"api_version",children:(0,r.jsx)(H.Z,{placeholder:"2023-07-01-preview"})}),"Azure"==E&&(0,r.jsxs)(ea.Z.Item,{label:"Base Model",name:"base_model",children:[(0,r.jsx)(H.Z,{placeholder:"azure/gpt-3.5-turbo"}),(0,r.jsxs)(ee.Z,{children:["The actual model your azure deployment uses. Used for accurate cost tracking. Select name from ",(0,r.jsx)(e2,{href:"https://github.com/BerriAI/litellm/blob/main/model_prices_and_context_window.json",target:"_blank",children:"here"})]})]}),"Amazon Bedrock"==E&&(0,r.jsx)(ea.Z.Item,{rules:[{required:!0,message:"Required"}],label:"AWS Access Key ID",name:"aws_access_key_id",tooltip:"You can provide the raw key or the environment variable (e.g. `os.environ/MY_SECRET_KEY`).",children:(0,r.jsx)(H.Z,{placeholder:""})}),"Amazon Bedrock"==E&&(0,r.jsx)(ea.Z.Item,{rules:[{required:!0,message:"Required"}],label:"AWS Secret Access Key",name:"aws_secret_access_key",tooltip:"You can provide the raw key or the environment variable (e.g. `os.environ/MY_SECRET_KEY`).",children:(0,r.jsx)(H.Z,{placeholder:""})}),"Amazon Bedrock"==E&&(0,r.jsx)(ea.Z.Item,{rules:[{required:!0,message:"Required"}],label:"AWS Region Name",name:"aws_region_name",tooltip:"You can provide the raw key or the environment variable (e.g. `os.environ/MY_SECRET_KEY`).",children:(0,r.jsx)(H.Z,{placeholder:"us-east-1"})}),(0,r.jsx)(ea.Z.Item,{label:"LiteLLM Params",name:"litellm_extra_params",tooltip:"Optional litellm params used for making a litellm.completion() call.",className:"mb-0",children:(0,r.jsx)(eW.Z,{rows:4,placeholder:'{ "rpm": 100, "timeout": 0, "stream_timeout": 0 }'})}),(0,r.jsxs)(eV.Z,{children:[(0,r.jsx)(eG.Z,{span:10}),(0,r.jsx)(eG.Z,{span:10,children:(0,r.jsxs)(ee.Z,{className:"mb-3 mt-1",children:["Pass JSON of litellm supported params ",(0,r.jsx)(e2,{href:"https://docs.litellm.ai/docs/completion/input",target:"_blank",children:"litellm.completion() call"})]})})]})]}),(0,r.jsx)("div",{style:{textAlign:"center",marginTop:"10px"},children:(0,r.jsx)(ei.ZP,{htmlType:"submit",children:"Add Model"})}),(0,r.jsx)(eY.Z,{title:"Get help on our github",children:(0,r.jsx)(eT.default.Link,{href:"https://github.com/BerriAI/litellm/issues",children:"Need Help?"})})]})})]}),(0,r.jsx)(eU.Z,{children:(0,r.jsxs)(ep.Z,{children:[(0,r.jsx)(ee.Z,{children:"`/health` will run a very small request through your models configured on litellm"}),(0,r.jsx)(J.Z,{onClick:ls,children:"Run `/health`"}),C&&(0,r.jsx)("pre",{children:JSON.stringify(C,null,2)})]})}),(0,r.jsxs)(eU.Z,{children:[(0,r.jsxs)(W.Z,{numItems:2,className:"mt-2",children:[(0,r.jsxs)(eG.Z,{children:[(0,r.jsx)(ee.Z,{children:"Select Time Range"}),(0,r.jsx)(eF.Z,{enableSelect:!0,value:eE,onValueChange:e=>{eI(e),la(U,e.from,e.to)}})]}),(0,r.jsxs)(eG.Z,{children:[(0,r.jsx)(ee.Z,{children:"Select Model Group"}),(0,r.jsx)(eb.Z,{className:"mb-4 mt-2",defaultValue:U||M[0],value:U||M[0],children:M.map((e,l)=>(0,r.jsx)(ek.Z,{value:e,onClick:()=>la(e,eE.from,eE.to),children:e},l))})]})]}),(0,r.jsxs)(W.Z,{numItems:2,children:[(0,r.jsx)(eG.Z,{children:(0,r.jsxs)(ep.Z,{className:"mr-2 max-h-[400px] min-h-[400px]",children:[(0,r.jsx)(el.Z,{children:"Avg Latency per Token"}),(0,r.jsx)("p",{className:"text-gray-500 italic",children:" (seconds/token)"}),(0,r.jsx)(ee.Z,{className:"text-gray-500 italic mt-1 mb-1",children:"average Latency for successfull requests divided by the total tokens"}),Y&&es&&(0,r.jsx)(ez.Z,{title:"Model Latency",className:"h-72",data:Y,showLegend:!1,index:"date",categories:es,connectNulls:!0,customTooltip:e=>{var l,t;let{payload:s,active:a}=e;if(!a||!s)return null;let n=null===(t=s[0])||void 0===t?void 0:null===(l=t.payload)||void 0===l?void 0:l.date,o=s.sort((e,l)=>l.value-e.value);if(o.length>5){let e=o.length-5;(o=o.slice(0,5)).push({dataKey:"".concat(e," other deployments"),value:s.slice(5).reduce((e,l)=>e+l.value,0),color:"gray"})}return(0,r.jsxs)("div",{className:"w-150 rounded-tremor-default border border-tremor-border bg-tremor-background p-2 text-tremor-default shadow-tremor-dropdown",children:[n&&(0,r.jsxs)("p",{className:"text-tremor-content-emphasis mb-2",children:["Date: ",n]}),o.map((e,l)=>{let t=parseFloat(e.value.toFixed(5)),s=0===t&&e.value>0?"<0.00001":t.toFixed(5);return(0,r.jsxs)("div",{className:"flex justify-between",children:[(0,r.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,r.jsx)("div",{className:"w-2 h-2 mt-1 rounded-full bg-".concat(e.color,"-500")}),(0,r.jsx)("p",{className:"text-tremor-content",children:e.dataKey})]}),(0,r.jsx)("p",{className:"font-medium text-tremor-content-emphasis text-righ ml-2",children:s})]},l)})]})}})]})}),(0,r.jsx)(eG.Z,{children:(0,r.jsx)(ep.Z,{className:"ml-2 max-h-[400px] min-h-[400px] overflow-y-auto",children:(0,r.jsxs)(eg.Z,{children:[(0,r.jsx)(eZ.Z,{children:(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(e_.Z,{children:"Deployment"}),(0,r.jsx)(e_.Z,{children:"Success Responses"}),(0,r.jsxs)(e_.Z,{children:["Slow Responses ",(0,r.jsx)("p",{children:"Success Responses taking 600+s"})]})]})}),(0,r.jsx)(ey.Z,{children:eN.map((e,l)=>(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(ef.Z,{children:e.api_base}),(0,r.jsx)(ef.Z,{children:e.total_count}),(0,r.jsx)(ef.Z,{children:e.slow_count})]},l))})]})})})]}),(0,r.jsxs)(ep.Z,{className:"mt-4",children:[(0,r.jsx)(el.Z,{children:"Exceptions per Model"}),(0,r.jsx)(eq.Z,{className:"h-72",data:ec,index:"model",categories:em,stack:!0,colors:["indigo-300","rose-200","#ffcc33"],yAxisWidth:30})]})]}),(0,r.jsxs)(eU.Z,{children:[(0,r.jsxs)("div",{className:"flex items-center",children:[(0,r.jsx)(ee.Z,{children:"Filter by Public Model Name"}),(0,r.jsx)(eb.Z,{className:"mb-4 mt-2 ml-2 w-50",defaultValue:U||M[0],value:U||M[0],onValueChange:e=>K(e),children:M.map((e,l)=>(0,r.jsx)(ek.Z,{value:e,onClick:()=>K(e),children:e},l))})]}),(0,r.jsxs)(el.Z,{children:["Retry Policy for ",U]}),(0,r.jsx)(ee.Z,{className:"mb-6",children:"How many retries should be attempted based on the Exception"}),e8&&(0,r.jsx)("table",{children:(0,r.jsx)("tbody",{children:Object.entries(e8).map((e,l)=>{var t;let[s,a]=e,n=null==eC?void 0:null===(t=eC[U])||void 0===t?void 0:t[a];return null==n&&(n=eO),(0,r.jsxs)("tr",{className:"flex justify-between items-center mt-2",children:[(0,r.jsx)("td",{children:(0,r.jsx)(ee.Z,{children:s})}),(0,r.jsx)("td",{children:(0,r.jsx)(eo.Z,{className:"ml-5",value:n,min:0,step:1,onChange:e=>{eP(l=>{var t;let s=null!==(t=null==l?void 0:l[U])&&void 0!==t?t:{};return{...null!=l?l:{},[U]:{...s,[a]:e}}})}})})]},l)})})}),(0,r.jsx)(J.Z,{className:"mt-6 mr-8",onClick:le,children:"Save"})]})]})]})})};let{Option:e6}=es.default;var e7=e=>{let{userID:l,accessToken:t,teams:s}=e,[a]=ea.Z.useForm(),[o,i]=(0,n.useState)(!1),[c,d]=(0,n.useState)(null),[m,h]=(0,n.useState)([]);(0,n.useEffect)(()=>{(async()=>{try{let e=await N(t,l,"any"),s=[];for(let l=0;l{i(!1),a.resetFields()},p=()=>{i(!1),d(null),a.resetFields()},j=async e=>{try{u.ZP.info("Making API Call"),i(!0),console.log("formValues in create user:",e);let s=await g(t,null,e);console.log("user create Response:",s),d(s.key),u.ZP.success("API user Created"),a.resetFields(),localStorage.removeItem("userData"+l)}catch(e){console.error("Error creating the user:",e)}};return(0,r.jsxs)("div",{children:[(0,r.jsx)(J.Z,{className:"mx-auto",onClick:()=>i(!0),children:"+ Invite User"}),(0,r.jsxs)(er.Z,{title:"Invite User",visible:o,width:800,footer:null,onOk:x,onCancel:p,children:[(0,r.jsx)(ee.Z,{className:"mb-1",children:"Invite a user to login to the Admin UI and create Keys"}),(0,r.jsx)(ee.Z,{className:"mb-6",children:(0,r.jsx)("b",{children:"Note: SSO Setup Required for this"})}),(0,r.jsxs)(ea.Z,{form:a,onFinish:j,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsx)(ea.Z.Item,{label:"User Email",name:"user_email",children:(0,r.jsx)(H.Z,{placeholder:""})}),(0,r.jsx)(ea.Z.Item,{label:"Team ID",name:"team_id",children:(0,r.jsx)(es.default,{placeholder:"Select Team ID",style:{width:"100%"},children:s?s.map(e=>(0,r.jsx)(e6,{value:e.team_id,children:e.team_alias},e.team_id)):(0,r.jsx)(e6,{value:null,children:"Default Team"},"default")})}),(0,r.jsx)(ea.Z.Item,{label:"Metadata",name:"metadata",children:(0,r.jsx)(en.Z.TextArea,{rows:4,placeholder:"Enter metadata as JSON"})}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ei.ZP,{htmlType:"submit",children:"Create User"})})]})]}),c&&(0,r.jsxs)(er.Z,{title:"User Created Successfully",visible:o,onOk:x,onCancel:p,footer:null,children:[(0,r.jsx)("p",{children:"User has been created to access your proxy. Please Ask them to Log In."}),(0,r.jsx)("br",{}),(0,r.jsx)("p",{children:(0,r.jsx)("b",{children:"Note: This Feature is only supported through SSO on the Admin UI"})})]})]})},e9=e=>{let{accessToken:l,token:t,keys:s,userRole:a,userID:o,teams:i,setKeys:c}=e,[d,m]=(0,n.useState)(null),[u,h]=(0,n.useState)(null),[x,p]=(0,n.useState)(0),[j,g]=n.useState(null),[y,f]=(0,n.useState)(null);return((0,n.useEffect)(()=>{if(!l||!t||!a||!o)return;let e=async()=>{try{let e=await Z(l,null,a,!0,x,25);console.log("user data response:",e),m(e)}catch(e){console.error("There was an error fetching the model data",e)}};l&&t&&a&&o&&e()},[l,t,a,o,x]),d&&l&&t&&a&&o)?(0,r.jsx)("div",{style:{width:"100%"},children:(0,r.jsxs)(W.Z,{className:"gap-2 p-2 h-[80vh] w-full mt-8",children:[(0,r.jsx)(e7,{userID:o,accessToken:l,teams:i}),(0,r.jsxs)(ep.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[80vh] mb-4",children:[(0,r.jsx)("div",{className:"mb-4 mt-1",children:(0,r.jsx)(ee.Z,{children:"These are Users on LiteLLM that created API Keys. Automatically tracked by LiteLLM"})}),(0,r.jsx)(eM.Z,{children:(0,r.jsxs)(eD.Z,{children:[(0,r.jsx)(eU.Z,{children:(0,r.jsxs)(eg.Z,{className:"mt-5",children:[(0,r.jsx)(eZ.Z,{children:(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(e_.Z,{children:"User ID"}),(0,r.jsx)(e_.Z,{children:"User Email"}),(0,r.jsx)(e_.Z,{children:"User Models"}),(0,r.jsx)(e_.Z,{children:"User Spend ($ USD)"}),(0,r.jsx)(e_.Z,{children:"User Max Budget ($ USD)"}),(0,r.jsx)(e_.Z,{children:"User API Key Aliases"})]})}),(0,r.jsx)(ey.Z,{children:d.map(e=>{var l;return(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(ef.Z,{children:e.user_id}),(0,r.jsx)(ef.Z,{children:e.user_email}),(0,r.jsx)(ef.Z,{children:e.models&&e.models.length>0?e.models:"All Models"}),(0,r.jsx)(ef.Z,{children:e.spend?null===(l=e.spend)||void 0===l?void 0:l.toFixed(2):0}),(0,r.jsx)(ef.Z,{children:e.max_budget?e.max_budget:"Unlimited"}),(0,r.jsx)(ef.Z,{children:(0,r.jsx)(W.Z,{numItems:2,children:e&&e.key_aliases&&e.key_aliases.filter(e=>null!==e).length>0?(0,r.jsx)(ex.Z,{size:"xs",color:"indigo",children:e.key_aliases.filter(e=>null!==e).join(", ")}):(0,r.jsx)(ex.Z,{size:"xs",color:"gray",children:"No Keys"})})})]},e.user_id)})})]})}),(0,r.jsx)(eU.Z,{children:(0,r.jsxs)("div",{className:"flex items-center",children:[(0,r.jsx)("div",{className:"flex-1"}),(0,r.jsx)("div",{className:"flex-1 flex justify-between items-center"})]})})]})})]}),function(){if(!d)return null;let e=Math.ceil(d.length/25);return(0,r.jsxs)("div",{className:"flex justify-between items-center",children:[(0,r.jsxs)("div",{children:["Showing Page ",x+1," of ",e]}),(0,r.jsxs)("div",{className:"flex",children:[(0,r.jsx)("button",{className:"bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-l focus:outline-none",disabled:0===x,onClick:()=>p(x-1),children:"โ† Prev"}),(0,r.jsx)("button",{className:"bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-r focus:outline-none",onClick:()=>{p(x+1)},children:"Next โ†’"})]})]})}()]})}):(0,r.jsx)("div",{children:"Loading..."})},le=e=>{let{teams:l,searchParams:t,accessToken:s,setTeams:a,userID:o,userRole:i}=e,[c]=ea.Z.useForm(),[d]=ea.Z.useForm(),{Title:m,Paragraph:h}=eT.default,[x,p]=(0,n.useState)(""),[j,g]=(0,n.useState)(!1),[y,Z]=(0,n.useState)(l?l[0]:null),[w,b]=(0,n.useState)(!1),[k,v]=(0,n.useState)(!1),[S,A]=(0,n.useState)([]),[E,I]=(0,n.useState)(!1),[C,P]=(0,n.useState)(null),[T,O]=(0,n.useState)({}),F=e=>{Z(e),g(!0)},R=async e=>{let t=e.team_id;if(console.log("handleEditSubmit:",e),null==s)return;let r=await U(s,e);l&&a(l.map(e=>e.team_id===t?r.data:e)),u.ZP.success("Team updated successfully"),g(!1),Z(null)},L=async e=>{P(e),I(!0)},D=async()=>{if(null!=C&&null!=l&&null!=s){try{await f(s,C);let e=l.filter(e=>e.team_id!==C);a(e)}catch(e){console.error("Error deleting the team:",e)}I(!1),P(null)}};(0,n.useEffect)(()=>{let e=async()=>{try{if(null===o||null===i||null===s||null===l)return;console.log("fetching team info:");let e={};for(let t=0;t<(null==l?void 0:l.length);t++){let a=l[t].team_id,r=await _(s,a);console.log("teamInfo response:",r),null!==r&&(e={...e,[a]:r})}O(e)}catch(e){console.error("Error fetching team info:",e)}};(async()=>{try{if(null===o||null===i)return;if(null!==s){let e=(await N(s,o,i)).data.map(e=>e.id);console.log("available_model_names:",e),A(e)}}catch(e){console.error("Error fetching user models:",e)}})(),e()},[s,o,i,l]);let B=async e=>{try{if(null!=s){var t;let r=null==e?void 0:e.team_alias;if((null!==(t=null==l?void 0:l.map(e=>e.team_alias))&&void 0!==t?t:[]).includes(r))throw Error("Team alias ".concat(r," already exists, please pick another alias"));u.ZP.info("Creating Team");let n=await M(s,e);null!==l?a([...l,n]):a([n]),console.log("response for team create call: ".concat(n)),u.ZP.success("Team created"),b(!1)}}catch(e){console.error("Error creating the team:",e),u.ZP.error("Error creating the team: "+e,20)}},z=async e=>{try{if(null!=s&&null!=l){u.ZP.info("Adding Member");let t={role:"user",user_email:e.user_email,user_id:e.user_id},r=await K(s,y.team_id,t);console.log("response for team create call: ".concat(r.data));let n=l.findIndex(e=>(console.log("team.team_id=".concat(e.team_id,"; response.data.team_id=").concat(r.data.team_id)),e.team_id===r.data.team_id));if(console.log("foundIndex: ".concat(n)),-1!==n){let e=[...l];e[n]=r.data,a(e),Z(r.data)}v(!1)}}catch(e){console.error("Error creating the team:",e)}};return console.log("received teams ".concat(JSON.stringify(l))),(0,r.jsx)("div",{className:"w-full mx-4",children:(0,r.jsxs)(W.Z,{numItems:1,className:"gap-2 p-8 h-[75vh] w-full mt-2",children:[(0,r.jsxs)(Y.Z,{numColSpan:1,children:[(0,r.jsx)(m,{level:4,children:"All Teams"}),(0,r.jsxs)(ep.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:[(0,r.jsxs)(eg.Z,{children:[(0,r.jsx)(eZ.Z,{children:(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(e_.Z,{children:"Team Name"}),(0,r.jsx)(e_.Z,{children:"Spend (USD)"}),(0,r.jsx)(e_.Z,{children:"Budget (USD)"}),(0,r.jsx)(e_.Z,{children:"Models"}),(0,r.jsx)(e_.Z,{children:"TPM / RPM Limits"}),(0,r.jsx)(e_.Z,{children:"Info"})]})}),(0,r.jsx)(ey.Z,{children:l&&l.length>0?l.map(e=>(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(ef.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:e.team_alias}),(0,r.jsx)(ef.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:e.spend}),(0,r.jsx)(ef.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:e.max_budget?e.max_budget:"No limit"}),(0,r.jsx)(ef.Z,{style:{maxWidth:"8-x",whiteSpace:"pre-wrap",overflow:"hidden"},children:Array.isArray(e.models)?(0,r.jsx)("div",{style:{display:"flex",flexDirection:"column"},children:0===e.models.length?(0,r.jsx)(ex.Z,{size:"xs",className:"mb-1",color:"red",children:(0,r.jsx)(ee.Z,{children:"All Proxy Models"})}):e.models.map((e,l)=>"all-proxy-models"===e?(0,r.jsx)(ex.Z,{size:"xs",className:"mb-1",color:"red",children:(0,r.jsx)(ee.Z,{children:"All Proxy Models"})},l):(0,r.jsx)(ex.Z,{size:"xs",className:"mb-1",color:"blue",children:(0,r.jsx)(ee.Z,{children:e.length>30?"".concat(e.slice(0,30),"..."):e})},l))}):null}),(0,r.jsx)(ef.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,r.jsxs)(ee.Z,{children:["TPM: ",e.tpm_limit?e.tpm_limit:"Unlimited"," ",(0,r.jsx)("br",{}),"RPM:"," ",e.rpm_limit?e.rpm_limit:"Unlimited"]})}),(0,r.jsxs)(ef.Z,{children:[(0,r.jsxs)(ee.Z,{children:[T&&e.team_id&&T[e.team_id]&&T[e.team_id].keys&&T[e.team_id].keys.length," ","Keys"]}),(0,r.jsxs)(ee.Z,{children:[T&&e.team_id&&T[e.team_id]&&T[e.team_id].team_info&&T[e.team_id].team_info.members_with_roles&&T[e.team_id].team_info.members_with_roles.length," ","Members"]})]}),(0,r.jsxs)(ef.Z,{children:[(0,r.jsx)(ej.Z,{icon:eu.Z,size:"sm",onClick:()=>F(e)}),(0,r.jsx)(ej.Z,{onClick:()=>L(e.team_id),icon:eh.Z,size:"sm"})]})]},e.team_id)):null})]}),E&&(0,r.jsx)("div",{className:"fixed z-10 inset-0 overflow-y-auto",children:(0,r.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,r.jsx)("div",{className:"fixed inset-0 transition-opacity","aria-hidden":"true",children:(0,r.jsx)("div",{className:"absolute inset-0 bg-gray-500 opacity-75"})}),(0,r.jsx)("span",{className:"hidden sm:inline-block sm:align-middle sm:h-screen","aria-hidden":"true",children:"โ€‹"}),(0,r.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,r.jsx)("div",{className:"bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4",children:(0,r.jsx)("div",{className:"sm:flex sm:items-start",children:(0,r.jsxs)("div",{className:"mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left",children:[(0,r.jsx)("h3",{className:"text-lg leading-6 font-medium text-gray-900",children:"Delete Team"}),(0,r.jsx)("div",{className:"mt-2",children:(0,r.jsx)("p",{className:"text-sm text-gray-500",children:"Are you sure you want to delete this team ?"})})]})})}),(0,r.jsxs)("div",{className:"bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse",children:[(0,r.jsx)(J.Z,{onClick:D,color:"red",className:"ml-2",children:"Delete"}),(0,r.jsx)(J.Z,{onClick:()=>{I(!1),P(null)},children:"Cancel"})]})]})]})})]})]}),(0,r.jsxs)(Y.Z,{numColSpan:1,children:[(0,r.jsx)(J.Z,{className:"mx-auto",onClick:()=>b(!0),children:"+ Create New Team"}),(0,r.jsx)(er.Z,{title:"Create Team",visible:w,width:800,footer:null,onOk:()=>{b(!1),c.resetFields()},onCancel:()=>{b(!1),c.resetFields()},children:(0,r.jsxs)(ea.Z,{form:c,onFinish:B,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(ea.Z.Item,{label:"Team Name",name:"team_alias",rules:[{required:!0,message:"Please input a team name"}],children:(0,r.jsx)(H.Z,{placeholder:""})}),(0,r.jsx)(ea.Z.Item,{label:"Models",name:"models",children:(0,r.jsxs)(es.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:[(0,r.jsx)(es.default.Option,{value:"all-proxy-models",children:"All Proxy Models"},"all-proxy-models"),S.map(e=>(0,r.jsx)(es.default.Option,{value:e,children:e},e))]})}),(0,r.jsx)(ea.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,r.jsx)(eo.Z,{step:.01,precision:2,width:200})}),(0,r.jsx)(ea.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,r.jsx)(eo.Z,{step:1,width:400})}),(0,r.jsx)(ea.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,r.jsx)(eo.Z,{step:1,width:400})})]}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ei.ZP,{htmlType:"submit",children:"Create Team"})})]})})]}),(0,r.jsxs)(Y.Z,{numColSpan:1,children:[(0,r.jsx)(m,{level:4,children:"Team Members"}),(0,r.jsx)(h,{children:"If you belong to multiple teams, this setting controls which teams members you see."}),l&&l.length>0?(0,r.jsx)(eb.Z,{defaultValue:"0",children:l.map((e,l)=>(0,r.jsx)(ek.Z,{value:String(l),onClick:()=>{Z(e)},children:e.team_alias},l))}):(0,r.jsxs)(h,{children:["No team created. ",(0,r.jsx)("b",{children:"Defaulting to personal account."})]})]}),(0,r.jsxs)(Y.Z,{numColSpan:1,children:[(0,r.jsx)(ep.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,r.jsxs)(eg.Z,{children:[(0,r.jsx)(eZ.Z,{children:(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(e_.Z,{children:"Member Name"}),(0,r.jsx)(e_.Z,{children:"Role"})]})}),(0,r.jsx)(ey.Z,{children:y?y.members_with_roles.map((e,l)=>(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(ef.Z,{children:e.user_email?e.user_email:e.user_id?e.user_id:null}),(0,r.jsx)(ef.Z,{children:e.role})]},l)):null})]})}),y&&(0,r.jsx)(e=>{let{visible:l,onCancel:t,team:s,onSubmit:a}=e,[n]=ea.Z.useForm();return(0,r.jsx)(er.Z,{title:"Edit Team",visible:l,width:800,footer:null,onOk:()=>{n.validateFields().then(e=>{a({...e,team_id:s.team_id}),n.resetFields()}).catch(e=>{console.error("Validation failed:",e)})},onCancel:t,children:(0,r.jsxs)(ea.Z,{form:n,onFinish:R,initialValues:s,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(ea.Z.Item,{label:"Team Name",name:"team_alias",rules:[{required:!0,message:"Please input a team name"}],children:(0,r.jsx)(H.Z,{})}),(0,r.jsx)(ea.Z.Item,{label:"Models",name:"models",children:(0,r.jsxs)(es.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:[(0,r.jsx)(es.default.Option,{value:"all-proxy-models",children:"All Proxy Models"},"all-proxy-models"),S&&S.map(e=>(0,r.jsx)(es.default.Option,{value:e,children:e},e))]})}),(0,r.jsx)(ea.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,r.jsx)(eo.Z,{step:.01,precision:2,width:200})}),(0,r.jsx)(ea.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,r.jsx)(eo.Z,{step:1,width:400})}),(0,r.jsx)(ea.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,r.jsx)(eo.Z,{step:1,width:400})}),(0,r.jsx)(ea.Z.Item,{label:"Requests per minute Limit (RPM)",name:"team_id",hidden:!0})]}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ei.ZP,{htmlType:"submit",children:"Edit Team"})})]})})},{visible:j,onCancel:()=>{g(!1),Z(null)},team:y,onSubmit:R})]}),(0,r.jsxs)(Y.Z,{numColSpan:1,children:[(0,r.jsx)(J.Z,{className:"mx-auto mb-5",onClick:()=>v(!0),children:"+ Add member"}),(0,r.jsx)(er.Z,{title:"Add member",visible:k,width:800,footer:null,onOk:()=>{v(!1),d.resetFields()},onCancel:()=>{v(!1),d.resetFields()},children:(0,r.jsxs)(ea.Z,{form:c,onFinish:z,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(ea.Z.Item,{label:"Email",name:"user_email",className:"mb-4",children:(0,r.jsx)(en.Z,{name:"user_email",className:"px-3 py-2 border rounded-md w-full"})}),(0,r.jsx)("div",{className:"text-center mb-4",children:"OR"}),(0,r.jsx)(ea.Z.Item,{label:"User ID",name:"user_id",className:"mb-4",children:(0,r.jsx)(en.Z,{name:"user_id",className:"px-3 py-2 border rounded-md w-full"})})]}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ei.ZP,{htmlType:"submit",children:"Add member"})})]})})]})]})})},ll=t(18190),lt=e=>{let l,{searchParams:t,accessToken:s,showSSOBanner:a}=e,[o]=ea.Z.useForm(),[i]=ea.Z.useForm(),{Title:c,Paragraph:d}=eT.default,[m,h]=(0,n.useState)(""),[x,p]=(0,n.useState)(null),[j,g]=(0,n.useState)(!1),[y,f]=(0,n.useState)(!1),[Z,_]=(0,n.useState)(!1),[w,b]=(0,n.useState)(!1),[k,v]=(0,n.useState)(!1);try{l=window.location.origin}catch(e){l=""}l+="/fallback/login";let S=()=>{v(!1)},N=["proxy_admin","proxy_admin_viewer"];(0,n.useEffect)(()=>{(async()=>{if(null!=s){let e=[],l=await R(s,"proxy_admin_viewer");l.forEach(l=>{e.push({user_role:l.user_role,user_id:l.user_id,user_email:l.user_email})}),console.log("proxy viewers: ".concat(l));let t=await R(s,"proxy_admin");t.forEach(l=>{e.push({user_role:l.user_role,user_id:l.user_id,user_email:l.user_email})}),console.log("proxy admins: ".concat(t)),console.log("combinedList: ".concat(e)),p(e)}})()},[s]);let A=()=>{_(!1),i.resetFields()},E=()=>{_(!1),i.resetFields()},I=e=>(0,r.jsxs)(ea.Z,{form:o,onFinish:e,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(ea.Z.Item,{label:"Email",name:"user_email",className:"mb-4",children:(0,r.jsx)(en.Z,{name:"user_email",className:"px-3 py-2 border rounded-md w-full"})}),(0,r.jsx)("div",{className:"text-center mb-4",children:"OR"}),(0,r.jsx)(ea.Z.Item,{label:"User ID",name:"user_id",className:"mb-4",children:(0,r.jsx)(en.Z,{name:"user_id",className:"px-3 py-2 border rounded-md w-full"})})]}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ei.ZP,{htmlType:"submit",children:"Add member"})})]}),C=(e,l,t)=>(0,r.jsxs)(ea.Z,{form:o,onFinish:e,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(ea.Z.Item,{rules:[{required:!0,message:"Required"}],label:"User Role",name:"user_role",labelCol:{span:10},labelAlign:"left",children:(0,r.jsx)(eb.Z,{value:l,children:N.map((e,l)=>(0,r.jsx)(ek.Z,{value:e,children:e},l))})}),(0,r.jsx)(ea.Z.Item,{label:"Team ID",name:"user_id",hidden:!0,initialValue:t,valuePropName:"user_id",className:"mt-8",children:(0,r.jsx)(en.Z,{value:t,disabled:!0})})]}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ei.ZP,{htmlType:"submit",children:"Update role"})})]}),P=async e=>{try{if(null!=s&&null!=x){u.ZP.info("Making API Call");let l=await B(s,e,null);console.log("response for team create call: ".concat(l));let t=x.findIndex(e=>(console.log("user.user_id=".concat(e.user_id,"; response.user_id=").concat(l.user_id)),e.user_id===l.user_id));console.log("foundIndex: ".concat(t)),-1==t&&(console.log("updates admin with new user"),x.push(l),p(x)),u.ZP.success("Refresh tab to see updated user role"),_(!1)}}catch(e){console.error("Error creating the key:",e)}},T=async e=>{try{if(null!=s&&null!=x){u.ZP.info("Making API Call");let l=await B(s,e,"proxy_admin_viewer");console.log("response for team create call: ".concat(l));let t=x.findIndex(e=>(console.log("user.user_id=".concat(e.user_id,"; response.user_id=").concat(l.user_id)),e.user_id===l.user_id));console.log("foundIndex: ".concat(t)),-1==t&&(console.log("updates admin with new user"),x.push(l),p(x)),g(!1)}}catch(e){console.error("Error creating the key:",e)}},O=async e=>{try{if(null!=s&&null!=x){u.ZP.info("Making API Call"),e.user_email,e.user_id;let l=await B(s,e,"proxy_admin");console.log("response for team create call: ".concat(l));let t=x.findIndex(e=>(console.log("user.user_id=".concat(e.user_id,"; response.user_id=").concat(l.user_id)),e.user_id===l.user_id));console.log("foundIndex: ".concat(t)),-1==t&&(console.log("updates admin with new user"),x.push(l),p(x)),f(!1)}}catch(e){console.error("Error creating the key:",e)}},F=async e=>{null!=s&&V(s,{environment_variables:{PROXY_BASE_URL:e.proxy_base_url,GOOGLE_CLIENT_ID:e.google_client_id,GOOGLE_CLIENT_SECRET:e.google_client_secret}})};return console.log("admins: ".concat(null==x?void 0:x.length)),(0,r.jsxs)("div",{className:"w-full m-2 mt-2 p-8",children:[(0,r.jsx)(c,{level:4,children:"Admin Access "}),(0,r.jsxs)(d,{children:[a&&(0,r.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/ui#restrict-ui-access",children:"Requires SSO Setup"}),(0,r.jsx)("br",{}),(0,r.jsx)("b",{children:"Proxy Admin: "})," Can create keys, teams, users, add models, etc. ",(0,r.jsx)("br",{}),(0,r.jsx)("b",{children:"Proxy Admin Viewer: "}),"Can just view spend. They cannot create keys, teams or grant users access to new models."," "]}),(0,r.jsxs)(W.Z,{numItems:1,className:"gap-2 p-2 w-full",children:[(0,r.jsx)(Y.Z,{numColSpan:1,children:(0,r.jsx)(ep.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,r.jsxs)(eg.Z,{children:[(0,r.jsx)(eZ.Z,{children:(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(e_.Z,{children:"Member Name"}),(0,r.jsx)(e_.Z,{children:"Role"})]})}),(0,r.jsx)(ey.Z,{children:x?x.map((e,l)=>(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(ef.Z,{children:e.user_email?e.user_email:e.user_id?e.user_id:null}),(0,r.jsx)(ef.Z,{children:e.user_role}),(0,r.jsxs)(ef.Z,{children:[(0,r.jsx)(ej.Z,{icon:eu.Z,size:"sm",onClick:()=>_(!0)}),(0,r.jsx)(er.Z,{title:"Update role",visible:Z,width:800,footer:null,onOk:A,onCancel:E,children:C(P,e.user_role,e.user_id)})]})]},l)):null})]})})}),(0,r.jsx)(Y.Z,{numColSpan:1,children:(0,r.jsxs)("div",{className:"flex justify-start",children:[(0,r.jsx)(J.Z,{className:"mr-4 mb-5",onClick:()=>f(!0),children:"+ Add admin"}),(0,r.jsx)(er.Z,{title:"Add admin",visible:y,width:800,footer:null,onOk:()=>{f(!1),i.resetFields()},onCancel:()=>{f(!1),i.resetFields()},children:I(O)}),(0,r.jsx)(J.Z,{className:"mb-5",onClick:()=>g(!0),children:"+ Add viewer"}),(0,r.jsx)(er.Z,{title:"Add viewer",visible:j,width:800,footer:null,onOk:()=>{g(!1),i.resetFields()},onCancel:()=>{g(!1),i.resetFields()},children:I(T)})]})})]}),(0,r.jsxs)(W.Z,{children:[(0,r.jsx)(c,{level:4,children:"Add SSO"}),(0,r.jsxs)("div",{className:"flex justify-start mb-4",children:[(0,r.jsx)(J.Z,{onClick:()=>b(!0),children:"Add SSO"}),(0,r.jsx)(er.Z,{title:"Add SSO",visible:w,width:800,footer:null,onOk:()=>{b(!1),o.resetFields()},onCancel:()=>{b(!1),o.resetFields()},children:(0,r.jsxs)(ea.Z,{form:o,onFinish:e=>{O(e),F(e),b(!1),v(!0)},labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(ea.Z.Item,{label:"Admin Email",name:"user_email",rules:[{required:!0,message:"Please enter the email of the proxy admin"}],children:(0,r.jsx)(en.Z,{})}),(0,r.jsx)(ea.Z.Item,{label:"PROXY BASE URL",name:"proxy_base_url",rules:[{required:!0,message:"Please enter the proxy base url"}],children:(0,r.jsx)(en.Z,{})}),(0,r.jsx)(ea.Z.Item,{label:"GOOGLE CLIENT ID",name:"google_client_id",rules:[{required:!0,message:"Please enter the google client id"}],children:(0,r.jsx)(en.Z.Password,{})}),(0,r.jsx)(ea.Z.Item,{label:"GOOGLE CLIENT SECRET",name:"google_client_secret",rules:[{required:!0,message:"Please enter the google client secret"}],children:(0,r.jsx)(en.Z.Password,{})})]}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ei.ZP,{htmlType:"submit",children:"Save"})})]})}),(0,r.jsxs)(er.Z,{title:"SSO Setup Instructions",visible:k,width:800,footer:null,onOk:S,onCancel:()=>{v(!1)},children:[(0,r.jsx)("p",{children:"Follow these steps to complete the SSO setup:"}),(0,r.jsx)(ee.Z,{className:"mt-2",children:"1. DO NOT Exit this TAB"}),(0,r.jsx)(ee.Z,{className:"mt-2",children:"2. Open a new tab, visit your proxy base url"}),(0,r.jsx)(ee.Z,{className:"mt-2",children:"3. Confirm your SSO is configured correctly and you can login on the new Tab"}),(0,r.jsx)(ee.Z,{className:"mt-2",children:"4. If Step 3 is successful, you can close this tab"}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ei.ZP,{onClick:S,children:"Done"})})]})]}),(0,r.jsxs)(ll.Z,{title:"Login without SSO",color:"teal",children:["If you need to login without sso, you can access ",(0,r.jsxs)("a",{href:l,target:"_blank",children:[(0,r.jsx)("b",{children:l})," "]})]})]})]})},ls=t(42556);let la=[{name:"slack",variables:{LANGFUSE_HOST:null,LANGFUSE_PUBLIC_KEY:null,LANGFUSE_SECRET_KEY:null,OPENMETER_API_KEY:null,SLACK_WEBHOOK_URL:null}},{name:"langfuse",variables:{LANGFUSE_HOST:null,LANGFUSE_PUBLIC_KEY:null,LANGFUSE_SECRET_KEY:null,OPENMETER_API_KEY:null,SLACK_WEBHOOK_URL:null}},{name:"openmeter",variables:{LANGFUSE_HOST:null,LANGFUSE_PUBLIC_KEY:null,LANGFUSE_SECRET_KEY:null,OPENMETER_API_KEY:null,SLACK_WEBHOOK_URL:null}}];var lr=e=>{let{accessToken:l,userRole:t,userID:s}=e,[a,o]=(0,n.useState)(la),[i,c]=(0,n.useState)([]),[d,m]=(0,n.useState)(!1),[h]=ea.Z.useForm(),[x,p]=(0,n.useState)(null),[j,g]=(0,n.useState)([]),[y,f]=(0,n.useState)(""),[Z,_]=(0,n.useState)({}),[w,b]=(0,n.useState)([]),k=e=>{w.includes(e)?b(w.filter(l=>l!==e)):b([...w,e])},v={llm_exceptions:"LLM Exceptions",llm_too_slow:"LLM Responses Too Slow",llm_requests_hanging:"LLM Requests Hanging",budget_alerts:"Budget Alerts (API Keys, Users)",db_exceptions:"Database Exceptions (Read/Write)",daily_reports:"Weekly/Monthly Spend Reports"};(0,n.useEffect)(()=>{l&&t&&s&&q(l,s,t).then(e=>{console.log("callbacks",e);let l=la;o(l=l.map(l=>{let t=e.callbacks.find(e=>e.name===l.name);return t?{...l,variables:{...l.variables,...t.variables}}:l}));let t=e.alerts;if(console.log("alerts_data",t),t&&t.length>0){let e=t[0];console.log("_alert_info",e);let l=e.variables.SLACK_WEBHOOK_URL;console.log("catch_all_webhook",l),b(e.active_alerts),f(l),_(e.alerts_to_webhook)}c(t)})},[l,t,s]);let S=e=>w&&w.includes(e),N=e=>{if(!l)return;let t=Object.fromEntries(Object.entries(e.variables).map(e=>{var l;let[t,s]=e;return[t,(null===(l=document.querySelector('input[name="'.concat(t,'"]')))||void 0===l?void 0:l.value)||s]}));console.log("updatedVariables",t),console.log("updateAlertTypes",j);let s={environment_variables:t,litellm_settings:{success_callback:[e.name]}};try{V(l,s)}catch(e){u.ZP.error("Failed to update callback: "+e,20)}u.ZP.success("Callback updated successfully")},A=()=>{l&&h.validateFields().then(e=>{if(console.log("Form values:",e),"langfuse"===e.callback){V(l,{environment_variables:{LANGFUSE_PUBLIC_KEY:e.langfusePublicKey,LANGFUSE_SECRET_KEY:e.langfusePrivateKey},litellm_settings:{success_callback:[e.callback]}});let t={name:e.callback,variables:{SLACK_WEBHOOK_URL:null,LANGFUSE_HOST:null,LANGFUSE_PUBLIC_KEY:e.langfusePublicKey,LANGFUSE_SECRET_KEY:e.langfusePrivateKey,OPENMETER_API_KEY:null}};o(a?[...a,t]:[t])}else if("slack"===e.callback){console.log("values.slackWebhookUrl: ".concat(e.slackWebhookUrl)),V(l,{general_settings:{alerting:["slack"],alerting_threshold:300},environment_variables:{SLACK_WEBHOOK_URL:e.slackWebhookUrl}}),console.log("values.callback: ".concat(e.callback));let t={name:e.callback,variables:{SLACK_WEBHOOK_URL:e.slackWebhookUrl,LANGFUSE_HOST:null,LANGFUSE_PUBLIC_KEY:null,LANGFUSE_SECRET_KEY:null,OPENMETER_API_KEY:null}};o(a?[...a,t]:[t])}else if("openmeter"==e.callback){console.log("values.openMeterApiKey: ".concat(e.openMeterApiKey)),V(l,{environment_variables:{OPENMETER_API_KEY:e.openMeterApiKey},litellm_settings:{success_callback:[e.callback]}});let t={name:e.callback,variables:{SLACK_WEBHOOK_URL:null,LANGFUSE_HOST:null,LANGFUSE_PUBLIC_KEY:null,LANGFUSE_SECRET_KEY:null,OPENMETER_API_KEY:e.openMeterAPIKey}};o(a?[...a,t]:[t])}m(!1),h.resetFields(),p(null)})};return l?(console.log("callbacks: ".concat(a)),(0,r.jsxs)("div",{className:"w-full mx-4",children:[(0,r.jsxs)(W.Z,{numItems:1,className:"gap-2 p-8 w-full mt-2",children:[(0,r.jsx)(ll.Z,{title:"[UI] Presidio PII + Guardrails Coming Soon. https://docs.litellm.ai/docs/proxy/pii_masking",color:"sky"}),(0,r.jsxs)(eM.Z,{children:[(0,r.jsxs)(eL.Z,{variant:"line",defaultValue:"1",children:[(0,r.jsx)(eR.Z,{value:"1",children:"Logging Callbacks"}),(0,r.jsx)(eR.Z,{value:"2",children:"Alerting"})]}),(0,r.jsxs)(eD.Z,{children:[(0,r.jsx)(eU.Z,{children:(0,r.jsx)(ep.Z,{children:(0,r.jsxs)(eg.Z,{children:[(0,r.jsx)(eZ.Z,{children:(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(e_.Z,{children:"Callback"}),(0,r.jsx)(e_.Z,{children:"Callback Env Vars"})]})}),(0,r.jsx)(ey.Z,{children:a.filter(e=>"slack"!==e.name).map((e,t)=>{var s;return(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(ef.Z,{children:(0,r.jsx)(ex.Z,{color:"emerald",children:e.name})}),(0,r.jsxs)(ef.Z,{children:[(0,r.jsx)("ul",{children:Object.entries(null!==(s=e.variables)&&void 0!==s?s:{}).filter(l=>{let[t,s]=l;return t.toLowerCase().includes(e.name)}).map(e=>{let[l,t]=e;return(0,r.jsxs)("li",{children:[(0,r.jsx)(ee.Z,{className:"mt-2",children:l}),"LANGFUSE_HOST"===l?(0,r.jsx)("p",{children:"default value=https://cloud.langfuse.com"}):(0,r.jsx)("div",{}),(0,r.jsx)(H.Z,{name:l,defaultValue:t,type:"password"})]},l)})}),(0,r.jsx)(J.Z,{className:"mt-2",onClick:()=>N(e),children:"Save Changes"}),(0,r.jsx)(J.Z,{onClick:()=>z(l,e.name),className:"mx-2",children:"Test Callback"})]})]},t)})})]})})}),(0,r.jsx)(eU.Z,{children:(0,r.jsxs)(ep.Z,{children:[(0,r.jsxs)(ee.Z,{className:"my-2",children:["Alerts are only supported for Slack Webhook URLs. Get your webhook urls from ",(0,r.jsx)("a",{href:"https://api.slack.com/messaging/webhooks",target:"_blank",style:{color:"blue"},children:"here"})]}),(0,r.jsxs)(eg.Z,{children:[(0,r.jsx)(eZ.Z,{children:(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(e_.Z,{}),(0,r.jsx)(e_.Z,{}),(0,r.jsx)(e_.Z,{children:"Slack Webhook URL"})]})}),(0,r.jsx)(ey.Z,{children:Object.entries(v).map((e,l)=>{let[t,s]=e;return(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(ef.Z,{children:(0,r.jsx)(ls.Z,{id:"switch",name:"switch",checked:S(t),onChange:()=>k(t)})}),(0,r.jsx)(ef.Z,{children:(0,r.jsx)(ee.Z,{children:s})}),(0,r.jsx)(ef.Z,{children:(0,r.jsx)(H.Z,{name:t,type:"password",defaultValue:Z&&Z[t]?Z[t]:y})})]},l)})})]}),(0,r.jsx)(J.Z,{size:"xs",className:"mt-2",onClick:()=>{if(!l)return;let e={};Object.entries(v).forEach(l=>{let[t,s]=l,a=document.querySelector('input[name="'.concat(t,'"]'));console.log("key",t),console.log("webhookInput",a);let r=(null==a?void 0:a.value)||"";console.log("newWebhookValue",r),e[t]=r}),console.log("updatedAlertToWebhooks",e);let t={general_settings:{alert_to_webhook_url:e,alert_types:w}};console.log("payload",t);try{V(l,t)}catch(e){u.ZP.error("Failed to update alerts: "+e,20)}u.ZP.success("Alerts updated successfully")},children:"Save Changes"}),(0,r.jsx)(J.Z,{onClick:()=>z(l,"slack"),className:"mx-2",children:"Test Alerts"})]})})]})]})]}),(0,r.jsx)(er.Z,{title:"Add Callback",visible:d,onOk:A,width:800,onCancel:()=>{m(!1),h.resetFields(),p(null)},footer:null,children:(0,r.jsxs)(ea.Z,{form:h,layout:"vertical",onFinish:A,children:[(0,r.jsx)(ea.Z.Item,{label:"Callback",name:"callback",rules:[{required:!0,message:"Please select a callback"}],children:(0,r.jsxs)(es.default,{onChange:e=>{p(e)},children:[(0,r.jsx)(es.default.Option,{value:"langfuse",children:"langfuse"}),(0,r.jsx)(es.default.Option,{value:"openmeter",children:"openmeter"})]})}),"langfuse"===x&&(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(ea.Z.Item,{label:"LANGFUSE_PUBLIC_KEY",name:"langfusePublicKey",rules:[{required:!0,message:"Please enter the public key"}],children:(0,r.jsx)(H.Z,{type:"password"})}),(0,r.jsx)(ea.Z.Item,{label:"LANGFUSE_PRIVATE_KEY",name:"langfusePrivateKey",rules:[{required:!0,message:"Please enter the private key"}],children:(0,r.jsx)(H.Z,{type:"password"})})]}),"openmeter"==x&&(0,r.jsx)(r.Fragment,{children:(0,r.jsx)(ea.Z.Item,{label:"OPENMETER_API_KEY",name:"openMeterApiKey",rules:[{required:!0,message:"Please enter the openmeter api key"}],children:(0,r.jsx)(H.Z,{type:"password"})})}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ei.ZP,{htmlType:"submit",children:"Save"})})]})})]})):null};let{Option:ln}=es.default;var lo=e=>{let{models:l,accessToken:t,routerSettings:s,setRouterSettings:a}=e,[o]=ea.Z.useForm(),[i,c]=(0,n.useState)(!1),[d,m]=(0,n.useState)("");return(0,r.jsxs)("div",{children:[(0,r.jsx)(J.Z,{className:"mx-auto",onClick:()=>c(!0),children:"+ Add Fallbacks"}),(0,r.jsx)(er.Z,{title:"Add Fallbacks",visible:i,width:800,footer:null,onOk:()=>{c(!1),o.resetFields()},onCancel:()=>{c(!1),o.resetFields()},children:(0,r.jsxs)(ea.Z,{form:o,onFinish:e=>{console.log(e);let{model_name:l,models:r}=e,n=[...s.fallbacks||[],{[l]:r}],i={...s,fallbacks:n};console.log(i);try{V(t,{router_settings:i}),a(i)}catch(e){u.ZP.error("Failed to update router settings: "+e,20)}u.ZP.success("router settings updated successfully"),c(!1),o.resetFields()},labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(ea.Z.Item,{label:"Public Model Name",name:"model_name",rules:[{required:!0,message:"Set the model to fallback for"}],help:"required",children:(0,r.jsx)(eb.Z,{defaultValue:d,children:l&&l.map((e,l)=>(0,r.jsx)(ek.Z,{value:e,onClick:()=>m(e),children:e},l))})}),(0,r.jsx)(ea.Z.Item,{label:"Fallback Models",name:"models",rules:[{required:!0,message:"Please select a model"}],help:"required",children:(0,r.jsx)(eK.Z,{value:l,children:l&&l.filter(e=>e!=d).map(e=>(0,r.jsx)(eB.Z,{value:e,children:e},e))})})]}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ei.ZP,{htmlType:"submit",children:"Add Fallbacks"})})]})})]})},li=t(12968);async function lc(e,l){console.log("isLocal:",!1);let t=window.location.origin,s=new li.ZP.OpenAI({apiKey:l,baseURL:t,dangerouslyAllowBrowser:!0});try{let l=await s.chat.completions.create({model:e,messages:[{role:"user",content:"Hi, this is a test message"}],mock_testing_fallbacks:!0});u.ZP.success((0,r.jsxs)("span",{children:["Test model=",(0,r.jsx)("strong",{children:e}),", received model=",(0,r.jsx)("strong",{children:l.model}),". See ",(0,r.jsx)("a",{href:"#",onClick:()=>window.open("https://docs.litellm.ai/docs/proxy/reliability","_blank"),style:{textDecoration:"underline",color:"blue"},children:"curl"})]}))}catch(e){u.ZP.error("Error occurred while generating model response. Please try again. Error: ".concat(e),20)}}let ld={ttl:3600,lowest_latency_buffer:0},lm=e=>{let{selectedStrategy:l,strategyArgs:t,paramExplanation:s}=e;return(0,r.jsxs)($.Z,{children:[(0,r.jsx)(Q.Z,{className:"text-sm font-medium text-tremor-content-strong dark:text-dark-tremor-content-strong",children:"Routing Strategy Specific Args"}),(0,r.jsx)(X.Z,{children:"latency-based-routing"==l?(0,r.jsx)(ep.Z,{children:(0,r.jsxs)(eg.Z,{children:[(0,r.jsx)(eZ.Z,{children:(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(e_.Z,{children:"Setting"}),(0,r.jsx)(e_.Z,{children:"Value"})]})}),(0,r.jsx)(ey.Z,{children:Object.entries(t).map(e=>{let[l,t]=e;return(0,r.jsxs)(ew.Z,{children:[(0,r.jsxs)(ef.Z,{children:[(0,r.jsx)(ee.Z,{children:l}),(0,r.jsx)("p",{style:{fontSize:"0.65rem",color:"#808080",fontStyle:"italic"},className:"mt-1",children:s[l]})]}),(0,r.jsx)(ef.Z,{children:(0,r.jsx)(H.Z,{name:l,defaultValue:"object"==typeof t?JSON.stringify(t,null,2):t.toString()})})]},l)})})]})}):(0,r.jsx)(ee.Z,{children:"No specific settings"})})]})};var lu=e=>{let{accessToken:l,userRole:t,userID:s,modelData:a}=e,[o,i]=(0,n.useState)({}),[c,d]=(0,n.useState)(!1),[m]=ea.Z.useForm(),[h,x]=(0,n.useState)(null),[p,j]=(0,n.useState)(null),[g,y]=(0,n.useState)(null),f={routing_strategy_args:"(dict) Arguments to pass to the routing strategy",routing_strategy:"(string) Routing strategy to use",allowed_fails:"(int) Number of times a deployment can fail before being added to cooldown",cooldown_time:"(int) time in seconds to cooldown a deployment after failure",num_retries:"(int) Number of retries for failed requests. Defaults to 0.",timeout:"(float) Timeout for requests. Defaults to None.",retry_after:"(int) Minimum time to wait before retrying a failed request",ttl:"(int) Sliding window to look back over when calculating the average latency of a deployment. Default - 1 hour (in seconds).",lowest_latency_buffer:"(float) Shuffle between deployments within this % of the lowest latency. Default - 0 (i.e. always pick lowest latency)."};(0,n.useEffect)(()=>{l&&t&&s&&q(l,s,t).then(e=>{console.log("callbacks",e),i(e.router_settings)})},[l,t,s]);let Z=async e=>{if(l){console.log("received key: ".concat(e)),console.log("routerSettings['fallbacks']: ".concat(o.fallbacks)),o.fallbacks.map(l=>(e in l&&delete l[e],l));try{await V(l,{router_settings:o}),i({...o}),j(o.routing_strategy),u.ZP.success("Router settings updated successfully")}catch(e){u.ZP.error("Failed to update router settings: "+e,20)}}},_=e=>{if(!l)return;console.log("router_settings",e);let t=Object.fromEntries(Object.entries(e).map(e=>{let[l,t]=e;if("routing_strategy_args"!==l&&"routing_strategy"!==l){var s;return[l,(null===(s=document.querySelector('input[name="'.concat(l,'"]')))||void 0===s?void 0:s.value)||t]}if("routing_strategy"==l)return[l,p];if("routing_strategy_args"==l&&"latency-based-routing"==p){let e={},l=document.querySelector('input[name="lowest_latency_buffer"]'),t=document.querySelector('input[name="ttl"]');return(null==l?void 0:l.value)&&(e.lowest_latency_buffer=Number(l.value)),(null==t?void 0:t.value)&&(e.ttl=Number(t.value)),console.log("setRoutingStrategyArgs: ".concat(e)),["routing_strategy_args",e]}return null}).filter(e=>null!=e));console.log("updatedVariables",t);try{V(l,{router_settings:t})}catch(e){u.ZP.error("Failed to update router settings: "+e,20)}u.ZP.success("router settings updated successfully")};return l?(0,r.jsx)("div",{className:"w-full mx-4",children:(0,r.jsxs)(eM.Z,{className:"gap-2 p-8 h-[75vh] w-full mt-2",children:[(0,r.jsxs)(eL.Z,{variant:"line",defaultValue:"1",children:[(0,r.jsx)(eR.Z,{value:"1",children:"General Settings"}),(0,r.jsx)(eR.Z,{value:"2",children:"Fallbacks"})]}),(0,r.jsxs)(eD.Z,{children:[(0,r.jsx)(eU.Z,{children:(0,r.jsxs)(W.Z,{numItems:1,className:"gap-2 p-8 w-full mt-2",children:[(0,r.jsx)(el.Z,{children:"Router Settings"}),(0,r.jsxs)(ep.Z,{children:[(0,r.jsxs)(eg.Z,{children:[(0,r.jsx)(eZ.Z,{children:(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(e_.Z,{children:"Setting"}),(0,r.jsx)(e_.Z,{children:"Value"})]})}),(0,r.jsx)(ey.Z,{children:Object.entries(o).filter(e=>{let[l,t]=e;return"fallbacks"!=l&&"context_window_fallbacks"!=l&&"routing_strategy_args"!=l}).map(e=>{let[l,t]=e;return(0,r.jsxs)(ew.Z,{children:[(0,r.jsxs)(ef.Z,{children:[(0,r.jsx)(ee.Z,{children:l}),(0,r.jsx)("p",{style:{fontSize:"0.65rem",color:"#808080",fontStyle:"italic"},className:"mt-1",children:f[l]})]}),(0,r.jsx)(ef.Z,{children:"routing_strategy"==l?(0,r.jsxs)(eb.Z,{defaultValue:t,className:"w-full max-w-md",onValueChange:j,children:[(0,r.jsx)(ek.Z,{value:"usage-based-routing",children:"usage-based-routing"}),(0,r.jsx)(ek.Z,{value:"latency-based-routing",children:"latency-based-routing"}),(0,r.jsx)(ek.Z,{value:"simple-shuffle",children:"simple-shuffle"})]}):(0,r.jsx)(H.Z,{name:l,defaultValue:"object"==typeof t?JSON.stringify(t,null,2):t.toString()})})]},l)})})]}),(0,r.jsx)(lm,{selectedStrategy:p,strategyArgs:o&&o.routing_strategy_args&&Object.keys(o.routing_strategy_args).length>0?o.routing_strategy_args:ld,paramExplanation:f})]}),(0,r.jsx)(Y.Z,{children:(0,r.jsx)(J.Z,{className:"mt-2",onClick:()=>_(o),children:"Save Changes"})})]})}),(0,r.jsxs)(eU.Z,{children:[(0,r.jsxs)(eg.Z,{children:[(0,r.jsx)(eZ.Z,{children:(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(e_.Z,{children:"Model Name"}),(0,r.jsx)(e_.Z,{children:"Fallbacks"})]})}),(0,r.jsx)(ey.Z,{children:o.fallbacks&&o.fallbacks.map((e,t)=>Object.entries(e).map(e=>{let[s,a]=e;return(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(ef.Z,{children:s}),(0,r.jsx)(ef.Z,{children:Array.isArray(a)?a.join(", "):a}),(0,r.jsx)(ef.Z,{children:(0,r.jsx)(J.Z,{onClick:()=>lc(s,l),children:"Test Fallback"})}),(0,r.jsx)(ef.Z,{children:(0,r.jsx)(ej.Z,{icon:eh.Z,size:"sm",onClick:()=>Z(s)})})]},t.toString()+s)}))})]}),(0,r.jsx)(lo,{models:(null==a?void 0:a.data)?a.data.map(e=>e.model_name):[],accessToken:l,routerSettings:o,setRouterSettings:i})]})]})]})}):null},lh=t(67951),lx=e=>{let{}=e;return(0,r.jsx)(r.Fragment,{children:(0,r.jsx)(W.Z,{className:"gap-2 p-8 h-[80vh] w-full mt-2",children:(0,r.jsxs)("div",{className:"mb-5",children:[(0,r.jsx)("p",{className:"text-2xl text-tremor-content-strong dark:text-dark-tremor-content-strong font-semibold",children:"OpenAI Compatible Proxy: API Reference"}),(0,r.jsx)(ee.Z,{className:"mt-2 mb-2",children:"LiteLLM is OpenAI Compatible. This means your API Key works with the OpenAI SDK. Just replace the base_url to point to your litellm proxy. Example Below "}),(0,r.jsxs)(eM.Z,{children:[(0,r.jsxs)(eL.Z,{children:[(0,r.jsx)(eR.Z,{children:"OpenAI Python SDK"}),(0,r.jsx)(eR.Z,{children:"LlamaIndex"}),(0,r.jsx)(eR.Z,{children:"Langchain Py"})]}),(0,r.jsxs)(eD.Z,{children:[(0,r.jsx)(eU.Z,{children:(0,r.jsx)(lh.Z,{language:"python",children:'\nimport openai\nclient = openai.OpenAI(\n api_key="your_api_key",\n base_url="http://0.0.0.0:4000" # LiteLLM Proxy is OpenAI compatible, Read More: https://docs.litellm.ai/docs/proxy/user_keys\n)\n\nresponse = client.chat.completions.create(\n model="gpt-3.5-turbo", # model to send to the proxy\n messages = [\n {\n "role": "user",\n "content": "this is a test request, write a short poem"\n }\n ]\n)\n\nprint(response)\n '})}),(0,r.jsx)(eU.Z,{children:(0,r.jsx)(lh.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,r.jsx)(eU.Z,{children:(0,r.jsx)(lh.Z,{language:"python",children:'\nfrom langchain.chat_models import ChatOpenAI\nfrom langchain.prompts.chat import (\n ChatPromptTemplate,\n HumanMessagePromptTemplate,\n SystemMessagePromptTemplate,\n)\nfrom langchain.schema import HumanMessage, SystemMessage\n\nchat = ChatOpenAI(\n openai_api_base="http://0.0.0.0:4000",\n model = "gpt-3.5-turbo",\n temperature=0.1\n)\n\nmessages = [\n SystemMessage(\n content="You are a helpful assistant that im using to make a test request to."\n ),\n HumanMessage(\n content="test from litellm. tell me why it\'s amazing in 1 sentence"\n ),\n]\nresponse = chat(messages)\n\nprint(response)\n\n '})})]})]})]})})})};async function lp(e,l,t,s){console.log("isLocal:",!1);let a=window.location.origin,r=new li.ZP.OpenAI({apiKey:s,baseURL:a,dangerouslyAllowBrowser:!0});try{for await(let s of(await r.chat.completions.create({model:t,stream:!0,messages:[{role:"user",content:e}]})))console.log(s),s.choices[0].delta.content&&l(s.choices[0].delta.content)}catch(e){u.ZP.error("Error occurred while generating model response. Please try again. Error: ".concat(e),20)}}var lj=e=>{let{accessToken:l,token:t,userRole:s,userID:a}=e,[o,i]=(0,n.useState)(""),[c,d]=(0,n.useState)(""),[m,u]=(0,n.useState)([]),[h,x]=(0,n.useState)(void 0),[p,j]=(0,n.useState)([]);(0,n.useEffect)(()=>{l&&t&&s&&a&&(async()=>{try{let e=await N(l,a,s);if(console.log("model_info:",e),(null==e?void 0:e.data.length)>0){let l=e.data.map(e=>({value:e.id,label:e.id}));console.log(l),j(l),x(e.data[0].id)}}catch(e){console.error("Error fetching model info:",e)}})()},[l,a,s]);let g=(e,l)=>{u(t=>{let s=t[t.length-1];return s&&s.role===e?[...t.slice(0,t.length-1),{role:e,content:s.content+l}]:[...t,{role:e,content:l}]})},y=async()=>{if(""!==c.trim()&&o&&t&&s&&a){u(e=>[...e,{role:"user",content:c}]);try{h&&await lp(c,e=>g("assistant",e),h,o)}catch(e){console.error("Error fetching model response",e),g("assistant","Error fetching model response")}d("")}};if(s&&"Admin Viewer"==s){let{Title:e,Paragraph:l}=eT.default;return(0,r.jsxs)("div",{children:[(0,r.jsx)(e,{level:1,children:"Access Denied"}),(0,r.jsx)(l,{children:"Ask your proxy admin for access to test models"})]})}return(0,r.jsx)("div",{style:{width:"100%",position:"relative"},children:(0,r.jsx)(W.Z,{className:"gap-2 p-8 h-[80vh] w-full mt-2",children:(0,r.jsx)(ep.Z,{children:(0,r.jsxs)(eM.Z,{children:[(0,r.jsx)(eL.Z,{children:(0,r.jsx)(eR.Z,{children:"Chat"})}),(0,r.jsx)(eD.Z,{children:(0,r.jsxs)(eU.Z,{children:[(0,r.jsx)("div",{className:"sm:max-w-2xl",children:(0,r.jsxs)(W.Z,{numItems:2,children:[(0,r.jsxs)(Y.Z,{children:[(0,r.jsx)(ee.Z,{children:"API Key"}),(0,r.jsx)(H.Z,{placeholder:"Type API Key here",type:"password",onValueChange:i,value:o})]}),(0,r.jsxs)(Y.Z,{className:"mx-2",children:[(0,r.jsx)(ee.Z,{children:"Select Model:"}),(0,r.jsx)(es.default,{placeholder:"Select a Model",onChange:e=>{console.log("selected ".concat(e)),x(e)},options:p,style:{width:"200px"}})]})]})}),(0,r.jsxs)(eg.Z,{className:"mt-5",style:{display:"block",maxHeight:"60vh",overflowY:"auto"},children:[(0,r.jsx)(eZ.Z,{children:(0,r.jsx)(ew.Z,{children:(0,r.jsx)(ef.Z,{})})}),(0,r.jsx)(ey.Z,{children:m.map((e,l)=>(0,r.jsx)(ew.Z,{children:(0,r.jsx)(ef.Z,{children:"".concat(e.role,": ").concat(e.content)})},l))})]}),(0,r.jsx)("div",{className:"mt-3",style:{position:"absolute",bottom:5,width:"95%"},children:(0,r.jsxs)("div",{className:"flex",children:[(0,r.jsx)(H.Z,{type:"text",value:c,onChange:e=>d(e.target.value),placeholder:"Type your message..."}),(0,r.jsx)(J.Z,{onClick:y,className:"ml-2",children:"Send"})]})})]})})]})})})})},lg=t(33509),ly=t(95781);let{Sider:lf}=lg.default;var lZ=e=>{let{setPage:l,userRole:t,defaultSelectedKey:s}=e;return"Admin Viewer"==t?(0,r.jsx)(lg.default,{style:{minHeight:"100vh",maxWidth:"120px"},children:(0,r.jsx)(lf,{width:120,children:(0,r.jsxs)(ly.Z,{mode:"inline",defaultSelectedKeys:s||["4"],style:{height:"100%",borderRight:0},children:[(0,r.jsx)(ly.Z.Item,{onClick:()=>l("api-keys"),children:"API Keys"},"4"),(0,r.jsx)(ly.Z.Item,{onClick:()=>l("models"),children:"Models"},"2"),(0,r.jsx)(ly.Z.Item,{onClick:()=>l("llm-playground"),children:"Chat UI"},"3"),(0,r.jsx)(ly.Z.Item,{onClick:()=>l("usage"),children:"Usage"},"1")]})})}):(0,r.jsx)(lg.default,{style:{minHeight:"100vh",maxWidth:"145px"},children:(0,r.jsx)(lf,{width:145,children:(0,r.jsxs)(ly.Z,{mode:"inline",defaultSelectedKeys:s||["1"],style:{height:"100%",borderRight:0},children:[(0,r.jsx)(ly.Z.Item,{onClick:()=>l("api-keys"),children:(0,r.jsx)(ee.Z,{children:"API Keys"})},"1"),(0,r.jsx)(ly.Z.Item,{onClick:()=>l("llm-playground"),children:(0,r.jsx)(ee.Z,{children:"Test Key"})},"3"),"Admin"==t?(0,r.jsx)(ly.Z.Item,{onClick:()=>l("models"),children:(0,r.jsx)(ee.Z,{children:"Models"})},"2"):null,"Admin"==t?(0,r.jsx)(ly.Z.Item,{onClick:()=>l("usage"),children:(0,r.jsx)(ee.Z,{children:"Usage"})},"4"):null,"Admin"==t?(0,r.jsx)(ly.Z.Item,{onClick:()=>l("teams"),children:(0,r.jsx)(ee.Z,{children:"Teams"})},"6"):null,"Admin"==t?(0,r.jsx)(ly.Z.Item,{onClick:()=>l("users"),children:(0,r.jsx)(ee.Z,{children:"Users"})},"5"):null,"Admin"==t?(0,r.jsx)(ly.Z.Item,{onClick:()=>l("settings"),children:(0,r.jsx)(ee.Z,{children:"Logging & Alerts"})},"8"):null,"Admin"==t?(0,r.jsx)(ly.Z.Item,{onClick:()=>l("general-settings"),children:(0,r.jsx)(ee.Z,{children:"Router Settings"})},"9"):null,"Admin"==t?(0,r.jsx)(ly.Z.Item,{onClick:()=>l("admin-panel"),children:(0,r.jsx)(ee.Z,{children:"Admin"})},"7"):null,(0,r.jsx)(ly.Z.Item,{onClick:()=>l("api_ref"),children:(0,r.jsx)(ee.Z,{children:"API Reference"})},"11")]})})})},l_=t(67989),lw=e=>{let{accessToken:l,token:t,userRole:s,userID:a,keys:o}=e,i=new Date,[c,d]=(0,n.useState)([]),[m,u]=(0,n.useState)([]),[h,x]=(0,n.useState)([]),[p,j]=(0,n.useState)([]),[g,y]=(0,n.useState)([]),[f,Z]=(0,n.useState)([]),[_,w]=(0,n.useState)([]),[b,k]=(0,n.useState)([]),[v,S]=(0,n.useState)(""),[N,R]=(0,n.useState)({from:new Date(Date.now()-6048e5),to:new Date}),M=new Date(i.getFullYear(),i.getMonth(),1),L=new Date(i.getFullYear(),i.getMonth()+1,0),U=z(M),D=z(L);console.log("keys in usage",o);let K=async(e,t,s)=>{if(!e||!t||!l)return;console.log("uiSelectedKey",s);let a=await T(l,s,e.toISOString(),t.toISOString());console.log("End user data updated successfully",a),j(a)},B=async(e,t)=>{e&&t&&l&&(Z((await E(l,e.toISOString(),t.toISOString())).spend_per_tag),console.log("Tag spend data updated successfully"))};function z(e){let l=e.getFullYear(),t=e.getMonth()+1,s=e.getDate();return"".concat(l,"-").concat(t<10?"0"+t:t,"-").concat(s<10?"0"+s:s)}return console.log("Start date is ".concat(U)),console.log("End date is ".concat(D)),(0,n.useEffect)(()=>{l&&t&&s&&a&&(async()=>{try{if(console.log("user role: ".concat(s)),"Admin"==s||"Admin Viewer"==s){var e,r;let t=await C(l);d(t);let s=(await P(l)).map(e=>({key:(e.key_name||e.key_alias||e.api_key).substring(0,10),spend:e.total_spend}));u(s);let a=(await O(l)).map(e=>({key:e.model,spend:e.total_spend}));x(a);let n=await A(l);console.log("teamSpend",n),y(n.daily_spend),w(n.teams);let o=n.total_spend_per_team;o=o.map(e=>(e.name=e.team_id||"",e.value=e.total_spend||0,e)),k(o);let i=await E(l,null===(e=N.from)||void 0===e?void 0:e.toISOString(),null===(r=N.to)||void 0===r?void 0:r.toISOString());Z(i.spend_per_tag);let c=await T(l,null,void 0,void 0);j(c),console.log("spend/user result",c)}else"App Owner"==s&&await I(l,t,s,a,U,D).then(async e=>{if(console.log("result from spend logs call",e),"daily_spend"in e){let l=e.daily_spend;console.log("daily spend",l),d(l);let t=e.top_api_keys;u(t)}else{let t=(await F(l,function(e){let l=[];e.forEach(e=>{Object.entries(e).forEach(e=>{let[t,s]=e;"spend"!==t&&"startTime"!==t&&"models"!==t&&"users"!==t&&l.push({key:t,spend:s})})}),l.sort((e,l)=>Number(l.spend)-Number(e.spend));let t=l.slice(0,5).map(e=>e.key);return console.log("topKeys: ".concat(Object.keys(t[0]))),t}(e))).info.map(e=>({key:(e.key_name||e.key_alias).substring(0,10),spend:e.spend}));u(t),d(e)}})}catch(e){console.error("There was an error fetching the data",e)}})()},[l,t,s,a,U,D]),(0,r.jsxs)("div",{style:{width:"100%"},className:"p-8",children:[(0,r.jsx)(eE,{userID:a,userRole:s,accessToken:l,userSpend:null,selectedTeam:null}),(0,r.jsxs)(eM.Z,{children:[(0,r.jsxs)(eL.Z,{className:"mt-2",children:[(0,r.jsx)(eR.Z,{children:"All Up"}),(0,r.jsx)(eR.Z,{children:"Team Based Usage"}),(0,r.jsx)(eR.Z,{children:"End User Usage"}),(0,r.jsx)(eR.Z,{children:"Tag Based Usage"})]}),(0,r.jsxs)(eD.Z,{children:[(0,r.jsx)(eU.Z,{children:(0,r.jsxs)(W.Z,{numItems:2,className:"gap-2 h-[75vh] w-full",children:[(0,r.jsx)(Y.Z,{numColSpan:2,children:(0,r.jsxs)(ep.Z,{children:[(0,r.jsx)(el.Z,{children:"Monthly Spend"}),(0,r.jsx)(eq.Z,{data:c,index:"date",categories:["spend"],colors:["blue"],valueFormatter:e=>"$ ".concat(new Intl.NumberFormat("us").format(e).toString()),yAxisWidth:100,tickGap:5})]})}),(0,r.jsx)(Y.Z,{numColSpan:1,children:(0,r.jsxs)(ep.Z,{children:[(0,r.jsx)(el.Z,{children:"Top API Keys"}),(0,r.jsx)(eq.Z,{className:"mt-4 h-40",data:m,index:"key",categories:["spend"],colors:["blue"],yAxisWidth:80,tickGap:5,layout:"vertical",showXAxis:!1,showLegend:!1})]})}),(0,r.jsx)(Y.Z,{numColSpan:1,children:(0,r.jsxs)(ep.Z,{children:[(0,r.jsx)(el.Z,{children:"Top Models"}),(0,r.jsx)(eq.Z,{className:"mt-4 h-40",data:h,index:"key",categories:["spend"],colors:["blue"],yAxisWidth:200,layout:"vertical",showXAxis:!1,showLegend:!1})]})}),(0,r.jsx)(Y.Z,{numColSpan:1})]})}),(0,r.jsx)(eU.Z,{children:(0,r.jsxs)(W.Z,{numItems:2,className:"gap-2 h-[75vh] w-full",children:[(0,r.jsxs)(Y.Z,{numColSpan:2,children:[(0,r.jsxs)(ep.Z,{className:"mb-2",children:[(0,r.jsx)(el.Z,{children:"Total Spend Per Team"}),(0,r.jsx)(l_.Z,{data:b})]}),(0,r.jsxs)(ep.Z,{children:[(0,r.jsx)(el.Z,{children:"Daily Spend Per Team"}),(0,r.jsx)(eq.Z,{className:"h-72",data:g,showLegend:!0,index:"date",categories:_,yAxisWidth:80,colors:["blue","green","yellow","red","purple"],stack:!0})]})]}),(0,r.jsx)(Y.Z,{numColSpan:2})]})}),(0,r.jsxs)(eU.Z,{children:[(0,r.jsxs)("p",{className:"mb-2 text-gray-500 italic text-[12px]",children:["End-Users of your LLM API calls. Tracked when a `user` param is passed in your LLM calls ",(0,r.jsx)("a",{className:"text-blue-500",href:"https://docs.litellm.ai/docs/proxy/users",target:"_blank",children:"docs here"})]}),(0,r.jsxs)(W.Z,{numItems:2,children:[(0,r.jsxs)(Y.Z,{children:[(0,r.jsx)(ee.Z,{children:"Select Time Range"}),(0,r.jsx)(eF.Z,{enableSelect:!0,value:N,onValueChange:e=>{R(e),K(e.from,e.to,null)}})]}),(0,r.jsxs)(Y.Z,{children:[(0,r.jsx)(ee.Z,{children:"Select Key"}),(0,r.jsxs)(eb.Z,{defaultValue:"all-keys",children:[(0,r.jsx)(ek.Z,{value:"all-keys",onClick:()=>{K(N.from,N.to,null)},children:"All Keys"},"all-keys"),null==o?void 0:o.map((e,l)=>e&&null!==e.key_alias&&e.key_alias.length>0?(0,r.jsx)(ek.Z,{value:String(l),onClick:()=>{K(N.from,N.to,e.token)},children:e.key_alias},l):null)]})]})]}),(0,r.jsx)(ep.Z,{className:"mt-4",children:(0,r.jsxs)(eg.Z,{className:"max-h-[70vh] min-h-[500px]",children:[(0,r.jsx)(eZ.Z,{children:(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(e_.Z,{children:"End User"}),(0,r.jsx)(e_.Z,{children:"Spend"}),(0,r.jsx)(e_.Z,{children:"Total Events"})]})}),(0,r.jsx)(ey.Z,{children:null==p?void 0:p.map((e,l)=>{var t;return(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(ef.Z,{children:e.end_user}),(0,r.jsx)(ef.Z,{children:null===(t=e.total_spend)||void 0===t?void 0:t.toFixed(4)}),(0,r.jsx)(ef.Z,{children:e.total_count})]},l)})})]})})]}),(0,r.jsx)(eU.Z,{children:(0,r.jsxs)(W.Z,{numItems:2,className:"gap-2 h-[75vh] w-full mb-4",children:[(0,r.jsxs)(Y.Z,{numColSpan:2,children:[(0,r.jsx)(eF.Z,{className:"mb-4",enableSelect:!0,value:N,onValueChange:e=>{R(e),B(e.from,e.to)}}),(0,r.jsxs)(ep.Z,{children:[(0,r.jsx)(el.Z,{children:"Spend Per Tag"}),(0,r.jsxs)(ee.Z,{children:["Get Started Tracking cost per tag ",(0,r.jsx)("a",{className:"text-blue-500",href:"https://docs.litellm.ai/docs/proxy/enterprise#tracking-spend-for-custom-tags",target:"_blank",children:"here"})]}),(0,r.jsx)(eq.Z,{className:"h-72",data:f,index:"name",categories:["spend"],colors:["blue"]})]})]}),(0,r.jsx)(Y.Z,{numColSpan:2})]})})]})]})]})},lb=()=>{let{Title:e,Paragraph:l}=eT.default,[t,s]=(0,n.useState)(""),[a,i]=(0,n.useState)(null),[c,d]=(0,n.useState)(null),[u,h]=(0,n.useState)(null),[x,p]=(0,n.useState)(!0),j=(0,o.useSearchParams)(),[g,y]=(0,n.useState)({data:[]}),f=j.get("userID"),Z=j.get("token"),[_,w]=(0,n.useState)("api-keys"),[b,k]=(0,n.useState)(null);return(0,n.useEffect)(()=>{if(Z){let e=(0,eP.o)(Z);if(e){if(console.log("Decoded token:",e),console.log("Decoded key:",e.key),k(e.key),e.user_role){let l=function(e){if(!e)return"Undefined Role";switch(console.log("Received user role: ".concat(e.toLowerCase())),console.log("Received user role length: ".concat(e.toLowerCase().length)),e.toLowerCase()){case"app_owner":case"demo_app_owner":return"App Owner";case"app_admin":case"proxy_admin":return"Admin";case"proxy_admin_viewer":return"Admin Viewer";case"app_user":return"App User";default:return"Unknown Role"}}(e.user_role);console.log("Decoded user_role:",l),s(l),"Admin Viewer"==l&&w("usage")}else console.log("User role not defined");e.user_email?i(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))}}},[Z]),(0,r.jsx)(n.Suspense,{fallback:(0,r.jsx)("div",{children:"Loading..."}),children:(0,r.jsxs)("div",{className:"flex flex-col min-h-screen",children:[(0,r.jsx)(m,{userID:f,userRole:t,userEmail:a,showSSOBanner:x}),(0,r.jsxs)("div",{className:"flex flex-1 overflow-auto",children:[(0,r.jsx)("div",{className:"mt-8",children:(0,r.jsx)(lZ,{setPage:w,userRole:t,defaultSelectedKey:null})}),"api-keys"==_?(0,r.jsx)(eO,{userID:f,userRole:t,teams:c,keys:u,setUserRole:s,userEmail:a,setUserEmail:i,setTeams:d,setKeys:h}):"models"==_?(0,r.jsx)(e3,{userID:f,userRole:t,token:Z,accessToken:b,modelData:g,setModelData:y}):"llm-playground"==_?(0,r.jsx)(lj,{userID:f,userRole:t,token:Z,accessToken:b}):"users"==_?(0,r.jsx)(e9,{userID:f,userRole:t,token:Z,keys:u,teams:c,accessToken:b,setKeys:h}):"teams"==_?(0,r.jsx)(le,{teams:c,setTeams:d,searchParams:j,accessToken:b,userID:f,userRole:t}):"admin-panel"==_?(0,r.jsx)(lt,{setTeams:d,searchParams:j,accessToken:b,showSSOBanner:x}):"api_ref"==_?(0,r.jsx)(lx,{}):"settings"==_?(0,r.jsx)(lr,{userID:f,userRole:t,accessToken:b}):"general-settings"==_?(0,r.jsx)(lu,{userID:f,userRole:t,accessToken:b,modelData:g}):(0,r.jsx)(lw,{userID:f,userRole:t,token:Z,accessToken:b,keys:u})]})]})})}}},function(e){e.O(0,[936,884,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-e6190351ac8da62a.js b/ui/litellm-dashboard/out/_next/static/chunks/app/page-e6190351ac8da62a.js deleted file mode 100644 index 672a1d857e..0000000000 --- a/ui/litellm-dashboard/out/_next/static/chunks/app/page-e6190351ac8da62a.js +++ /dev/null @@ -1 +0,0 @@ -(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[931],{20661:function(e,l,t){Promise.resolve().then(t.bind(t,7926))},7926:function(e,l,t){"use strict";t.r(l),t.d(l,{default:function(){return lb}});var s,r,a=t(3827),n=t(64090),o=t(47907),i=t(8792),c=t(40491),d=t(65270),m=e=>{let{userID:l,userRole:t,userEmail:s,showSSOBanner:r}=e;console.log("User ID:",l),console.log("userEmail:",s),console.log("showSSOBanner:",r);let n=[{key:"1",label:(0,a.jsxs)(a.Fragment,{children:[(0,a.jsxs)("p",{children:["Role: ",t]}),(0,a.jsxs)("p",{children:["ID: ",l]})]})}];return(0,a.jsxs)("nav",{className:"left-0 right-0 top-0 flex justify-between items-center h-12 mb-4",children:[(0,a.jsx)("div",{className:"text-left my-2 absolute top-0 left-0",children:(0,a.jsx)("div",{className:"flex flex-col items-center",children:(0,a.jsx)(i.default,{href:"/",children:(0,a.jsx)("button",{className:"text-gray-800 rounded text-center",children:(0,a.jsx)("img",{src:"/get_image",width:160,height:160,alt:"LiteLLM Brand",className:"mr-2"})})})})}),(0,a.jsxs)("div",{className:"text-right mx-4 my-2 absolute top-0 right-0 flex items-center justify-end space-x-2",children:[r?(0,a.jsx)("div",{style:{padding:"6px",borderRadius:"8px"},children:(0,a.jsx)("a",{href:"https://calendly.com/d/4mp-gd3-k5k/litellm-1-1-onboarding-chat",target:"_blank",style:{fontSize:"14px",textDecoration:"underline"},children:"Request hosted proxy"})}):null,(0,a.jsx)("div",{style:{border:"1px solid #391085",padding:"6px",borderRadius:"8px"},children:(0,a.jsx)(c.Z,{menu:{items:n},children:(0,a.jsx)(d.Z,{children:s})})})]})]})},u=t(80588);let h=async()=>{try{let e=await fetch("https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json"),l=await e.json();return console.log("received data: ".concat(l)),l}catch(e){throw console.error("Failed to get model cost map:",e),e}},x=async(e,l)=>{try{let t=await fetch("/model/new",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...l})});if(!t.ok){let e=await t.text();throw u.ZP.error("Failed to create key: "+e,10),console.error("Error response from the server:",e),Error("Network response was not ok")}let s=await t.json();return console.log("API Response:",s),u.ZP.success("Model created successfully. Wait 60s and refresh on 'All Models' page"),s}catch(e){throw console.error("Failed to create key:",e),e}},p=async(e,l)=>{console.log("model_id in model delete call: ".concat(l));try{let t=await fetch("/model/delete",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({id:l})});if(!t.ok){let e=await t.text();throw u.ZP.error("Failed to create key: "+e,10),console.error("Error response from the server:",e),Error("Network response was not ok")}let s=await t.json();return console.log("API Response:",s),u.ZP.success("Model deleted successfully. Restart server to see this."),s}catch(e){throw console.error("Failed to create key:",e),e}},j=async(e,l,t)=>{try{if(console.log("Form Values in keyCreateCall:",t),t.description&&(t.metadata||(t.metadata={}),t.metadata.description=t.description,delete t.description,t.metadata=JSON.stringify(t.metadata)),t.metadata){console.log("formValues.metadata:",t.metadata);try{t.metadata=JSON.parse(t.metadata)}catch(e){throw u.ZP.error("Failed to parse metadata: "+e,10),Error("Failed to parse metadata: "+e)}}console.log("Form Values after check:",t);let s=await fetch("/key/generate",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({user_id:l,...t})});if(!s.ok){let e=await s.text();throw u.ZP.error("Failed to create key: "+e,10),console.error("Error response from the server:",e),Error("Network response was not ok")}let r=await s.json();return console.log("API Response:",r),r}catch(e){throw console.error("Failed to create key:",e),e}},g=async(e,l,t)=>{try{if(console.log("Form Values in keyCreateCall:",t),t.description&&(t.metadata||(t.metadata={}),t.metadata.description=t.description,delete t.description,t.metadata=JSON.stringify(t.metadata)),t.metadata){console.log("formValues.metadata:",t.metadata);try{t.metadata=JSON.parse(t.metadata)}catch(e){throw u.ZP.error("Failed to parse metadata: "+e,10),Error("Failed to parse metadata: "+e)}}console.log("Form Values after check:",t);let s=await fetch("/user/new",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({user_id:l,...t})});if(!s.ok){let e=await s.text();throw u.ZP.error("Failed to create key: "+e,10),console.error("Error response from the server:",e),Error("Network response was not ok")}let r=await s.json();return console.log("API Response:",r),r}catch(e){throw console.error("Failed to create key:",e),e}},y=async(e,l)=>{try{console.log("in keyDeleteCall:",l);let t=await fetch("/key/delete",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({keys:[l]})});if(!t.ok){let e=await t.text();throw u.ZP.error("Failed to delete key: "+e,10),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}},f=async(e,l)=>{try{console.log("in teamDeleteCall:",l);let t=await fetch("/team/delete",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({team_ids:[l]})});if(!t.ok){let e=await t.text();throw u.ZP.error("Failed to delete team: "+e,10),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to delete key:",e),e}},Z=async function(e,l,t){let s=arguments.length>3&&void 0!==arguments[3]&&arguments[3],r=arguments.length>4?arguments[4]:void 0,a=arguments.length>5?arguments[5]:void 0;try{let n="/user/info";"App Owner"==t&&l&&(n="".concat(n,"?user_id=").concat(l)),"App User"==t&&l&&(n="".concat(n,"?user_id=").concat(l)),console.log("in userInfoCall viewAll=",s),s&&a&&null!=r&&void 0!=r&&(n="".concat(n,"?view_all=true&page=").concat(r,"&page_size=").concat(a));let o=await fetch(n,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!o.ok){let e=await o.text();throw u.ZP.error(e,10),Error("Network response was not ok")}let i=await o.json();return console.log("API Response:",i),i}catch(e){throw console.error("Failed to create key:",e),e}},_=async(e,l)=>{try{let t="/team/info";l&&(t="".concat(t,"?team_id=").concat(l)),console.log("in teamInfoCall");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 u.ZP.error(e,10),Error("Network response was not ok")}let r=await s.json();return console.log("API Response:",r),r}catch(e){throw console.error("Failed to create key:",e),e}},w=async e=>{try{let l=await fetch("/global/spend",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw u.ZP.error(e,10),Error("Network response was not ok")}return await l.json()}catch(e){throw console.error("Failed to create key:",e),e}},b=async(e,l,t)=>{try{let l=await fetch("/v2/model/info",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw u.ZP.error(e,10),Error("Network response was not ok")}let t=await l.json();return console.log("modelInfoCall:",t),t}catch(e){throw console.error("Failed to create key:",e),e}},k=async(e,l,t,s,r,a)=>{try{let l="/model/metrics";s&&(l="".concat(l,"?_selected_model_group=").concat(s,"&startTime=").concat(r,"&endTime=").concat(a));let t=await fetch(l,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw u.ZP.error(e,10),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},v=async(e,l,t,s,r,a)=>{try{let l="/model/metrics/slow_responses";s&&(l="".concat(l,"?_selected_model_group=").concat(s,"&startTime=").concat(r,"&endTime=").concat(a));let t=await fetch(l,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw u.ZP.error(e,10),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},S=async(e,l,t,s,r,a)=>{try{let l="/model/metrics/exceptions";s&&(l="".concat(l,"?_selected_model_group=").concat(s,"&startTime=").concat(r,"&endTime=").concat(a));let t=await fetch(l,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw u.ZP.error(e,10),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},A=async(e,l,t)=>{try{let l=await fetch("/models",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw u.ZP.error(e,10),Error("Network response was not ok")}return await l.json()}catch(e){throw console.error("Failed to create key:",e),e}},N=async e=>{try{let l="/global/spend/teams";console.log("in teamSpendLogsCall:",l);let t=await fetch("".concat(l),{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw u.ZP.error(e,10),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}},E=async e=>{try{let l="/global/spend/tags";console.log("in tagsSpendLogsCall:",l);let t=await fetch("".concat(l),{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw u.ZP.error(e,10),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}},I=async(e,l,t,s,r,a)=>{try{console.log("user role in spend logs call: ".concat(t));let l="/spend/logs";l="App Owner"==t?"".concat(l,"?user_id=").concat(s,"&start_date=").concat(r,"&end_date=").concat(a):"".concat(l,"?start_date=").concat(r,"&end_date=").concat(a);let n=await fetch(l,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!n.ok){let e=await n.text();throw u.ZP.error(e,10),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}},C=async e=>{try{let l=await fetch("/global/spend/logs",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw u.ZP.error(e,10),Error("Network response was not ok")}let t=await l.json();return console.log(t),t}catch(e){throw console.error("Failed to create key:",e),e}},P=async e=>{try{let l=await fetch("/global/spend/keys?limit=5",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw u.ZP.error(e,10),Error("Network response was not ok")}let t=await l.json();return console.log(t),t}catch(e){throw console.error("Failed to create key:",e),e}},T=async(e,l,t,s)=>{try{let r="";r=l?JSON.stringify({api_key:l,startTime:t,endTime:s}):JSON.stringify({startTime:t,endTime:s});let a={method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}};a.body=r;let n=await fetch("/global/spend/end_users",a);if(!n.ok){let e=await n.text();throw u.ZP.error(e,10),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}},O=async e=>{try{let l=await fetch("/global/spend/models?limit=5",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw u.ZP.error(e,10),Error("Network response was not ok")}let t=await l.json();return console.log(t),t}catch(e){throw console.error("Failed to create key:",e),e}},F=async(e,l)=>{try{let t=await fetch("/v2/key/info",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({keys:l})});if(!t.ok){let e=await t.text();throw u.ZP.error(e,10),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}},R=async(e,l)=>{try{let t="/user/get_users?role=".concat(l);console.log("in userGetAllUsersCall:",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 u.ZP.error("Failed to delete key: "+e,10),Error("Network response was not ok")}let r=await s.json();return console.log(r),r}catch(e){throw console.error("Failed to get requested models:",e),e}},M=async(e,l)=>{try{console.log("Form Values in teamCreateCall:",l);let t=await fetch("/team/new",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...l})});if(!t.ok){let e=await t.text();throw u.ZP.error("Failed to create key: "+e,10),console.error("Error response from the server:",e),Error("Network response was not ok")}let s=await t.json();return console.log("API Response:",s),s}catch(e){throw console.error("Failed to create key:",e),e}},L=async(e,l)=>{try{console.log("Form Values in keyUpdateCall:",l);let t=await fetch("/key/update",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...l})});if(!t.ok){let e=await t.text();throw u.ZP.error("Failed to update key: "+e,10),console.error("Error response from the server:",e),Error("Network response was not ok")}let s=await t.json();return console.log("Update key Response:",s),s}catch(e){throw console.error("Failed to create key:",e),e}},U=async(e,l)=>{try{console.log("Form Values in teamUpateCall:",l);let t=await fetch("/team/update",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...l})});if(!t.ok){let e=await t.text();throw u.ZP.error("Failed to update team: "+e,10),console.error("Error response from the server:",e),Error("Network response was not ok")}let s=await t.json();return console.log("Update Team Response:",s),s}catch(e){throw console.error("Failed to create key:",e),e}},D=async(e,l)=>{try{console.log("Form Values in modelUpateCall:",l);let t=await fetch("/model/update",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...l})});if(!t.ok){let e=await t.text();throw u.ZP.error("Failed to update model: "+e,10),console.error("Error update from the server:",e),Error("Network response was not ok")}let s=await t.json();return console.log("Update model Response:",s),s}catch(e){throw console.error("Failed to update model:",e),e}},K=async(e,l,t)=>{try{console.log("Form Values in teamMemberAddCall:",t);let s=await fetch("/team/member_add",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({team_id:l,member:t})});if(!s.ok){let e=await s.text();throw u.ZP.error("Failed to create key: "+e,10),console.error("Error response from the server:",e),Error("Network response was not ok")}let r=await s.json();return console.log("API Response:",r),r}catch(e){throw console.error("Failed to create key:",e),e}},B=async(e,l,t)=>{try{console.log("Form Values in userUpdateUserCall:",l);let s={...l};null!==t&&(s.user_role=t),s=JSON.stringify(s);let r=await fetch("/user/update",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:s});if(!r.ok){let e=await r.text();throw u.ZP.error("Failed to create key: "+e,10),console.error("Error response from the server:",e),Error("Network response was not ok")}let a=await r.json();return console.log("API Response:",a),a}catch(e){throw console.error("Failed to create key:",e),e}},z=async(e,l)=>{try{let t="/health/services?service=".concat(l);console.log("Checking Slack Budget Alerts service health");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 u.ZP.error("Failed ".concat(l," service health check ")+e),Error(e)}let r=await s.json();return u.ZP.success("Test request to ".concat(l," made - check logs/alerts on ").concat(l," to verify")),r}catch(e){throw console.error("Failed to perform health check:",e),e}},q=async(e,l,t)=>{try{let l=await fetch("/get/config/callbacks",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw u.ZP.error(e,10),Error("Network response was not ok")}return await l.json()}catch(e){throw console.error("Failed to get callbacks:",e),e}},V=async(e,l)=>{try{let t=await fetch("/config/update",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...l})});if(!t.ok){let e=await t.text();throw u.ZP.error(e,10),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to set callbacks:",e),e}},G=async e=>{try{let l=await fetch("/health",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw u.ZP.error(e),Error("Network response was not ok")}return await l.json()}catch(e){throw console.error("Failed to call /health:",e),e}};var Y=t(10384),W=t(46453),J=t(16450),H=t(52273),$=t(26780),X=t(15595),Q=t(6698),ee=t(71801),el=t(42440),et=t(42308),es=t(50670),er=t(81583),ea=t(99129),en=t(44839),eo=t(88707),ei=t(1861);let{Option:ec}=es.default;var ed=e=>{let{userID:l,team:t,userRole:s,accessToken:r,data:o,setData:i}=e,[c]=er.Z.useForm(),[d,m]=(0,n.useState)(!1),[h,x]=(0,n.useState)(null),[p,g]=(0,n.useState)(null),[y,f]=(0,n.useState)([]),[Z,_]=(0,n.useState)([]),w=()=>{m(!1),c.resetFields()},b=()=>{m(!1),x(null),c.resetFields()};(0,n.useEffect)(()=>{(async()=>{try{if(null===l||null===s)return;if(null!==r){let e=(await A(r,l,s)).data.map(e=>e.id);console.log("available_model_names:",e),f(e)}}catch(e){console.error("Error fetching user models:",e)}})()},[r,l,s]);let k=async e=>{try{var t,s,a;let n=null!==(t=null==e?void 0:e.key_alias)&&void 0!==t?t:"",d=null!==(s=null==e?void 0:e.team_id)&&void 0!==s?s:null;if((null!==(a=null==o?void 0:o.filter(e=>e.team_id===d).map(e=>e.key_alias))&&void 0!==a?a:[]).includes(n))throw Error("Key alias ".concat(n," already exists for team with ID ").concat(d,", please provide another key alias"));u.ZP.info("Making API Call"),m(!0);let h=await j(r,l,e);console.log("key create Response:",h),i(e=>e?[...e,h]:[h]),x(h.key),g(h.soft_budget),u.ZP.success("API Key Created"),c.resetFields(),localStorage.removeItem("userData"+l)}catch(e){console.error("Error creating the key:",e),u.ZP.error("Error creating the key: ".concat(e),20)}};return(0,n.useEffect)(()=>{_(t&&t.models.length>0?t.models.includes("all-proxy-models")?y:t.models:y)},[t,y]),(0,a.jsxs)("div",{children:[(0,a.jsx)(J.Z,{className:"mx-auto",onClick:()=>m(!0),children:"+ Create New Key"}),(0,a.jsx)(ea.Z,{title:"Create Key",visible:d,width:800,footer:null,onOk:w,onCancel:b,children:(0,a.jsxs)(er.Z,{form:c,onFinish:k,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(er.Z.Item,{label:"Key Name",name:"key_alias",rules:[{required:!0,message:"Please input a key name"}],help:"required",children:(0,a.jsx)(H.Z,{placeholder:""})}),(0,a.jsx)(er.Z.Item,{label:"Team ID",name:"team_id",hidden:!0,initialValue:t?t.team_id:null,valuePropName:"team_id",className:"mt-8",children:(0,a.jsx)(en.Z,{value:t?t.team_alias:"",disabled:!0})}),(0,a.jsx)(er.Z.Item,{label:"Models",name:"models",rules:[{required:!0,message:"Please select a model"}],help:"required",children:(0,a.jsxs)(es.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},onChange:e=>{e.includes("all-team-models")&&c.setFieldsValue({models:["all-team-models"]})},children:[(0,a.jsx)(ec,{value:"all-team-models",children:"All Team Models"},"all-team-models"),Z.map(e=>(0,a.jsx)(ec,{value:e,children:e},e))]})}),(0,a.jsxs)($.Z,{className:"mt-20 mb-8",children:[(0,a.jsx)(Q.Z,{children:(0,a.jsx)("b",{children:"Optional Settings"})}),(0,a.jsxs)(X.Z,{children:[(0,a.jsx)(er.Z.Item,{className:"mt-8",label:"Max Budget (USD)",name:"max_budget",help:"Budget cannot exceed team max budget: $".concat((null==t?void 0:t.max_budget)!==null&&(null==t?void 0:t.max_budget)!==void 0?null==t?void 0:t.max_budget:"unlimited"),rules:[{validator:async(e,l)=>{if(l&&t&&null!==t.max_budget&&l>t.max_budget)throw Error("Budget cannot exceed team max budget: $".concat(t.max_budget))}}],children:(0,a.jsx)(eo.Z,{step:.01,precision:2,width:200})}),(0,a.jsx)(er.Z.Item,{className:"mt-8",label:"Reset Budget",name:"budget_duration",help:"Team Reset Budget: ".concat((null==t?void 0:t.budget_duration)!==null&&(null==t?void 0:t.budget_duration)!==void 0?null==t?void 0:t.budget_duration:"None"),children:(0,a.jsxs)(es.default,{defaultValue:null,placeholder:"n/a",children:[(0,a.jsx)(es.default.Option,{value:"24h",children:"daily"}),(0,a.jsx)(es.default.Option,{value:"30d",children:"monthly"})]})}),(0,a.jsx)(er.Z.Item,{className:"mt-8",label:"Tokens per minute Limit (TPM)",name:"tpm_limit",help:"TPM cannot exceed team TPM limit: ".concat((null==t?void 0:t.tpm_limit)!==null&&(null==t?void 0:t.tpm_limit)!==void 0?null==t?void 0:t.tpm_limit:"unlimited"),rules:[{validator:async(e,l)=>{if(l&&t&&null!==t.tpm_limit&&l>t.tpm_limit)throw Error("TPM limit cannot exceed team TPM limit: ".concat(t.tpm_limit))}}],children:(0,a.jsx)(eo.Z,{step:1,width:400})}),(0,a.jsx)(er.Z.Item,{className:"mt-8",label:"Requests per minute Limit (RPM)",name:"rpm_limit",help:"RPM cannot exceed team RPM limit: ".concat((null==t?void 0:t.rpm_limit)!==null&&(null==t?void 0:t.rpm_limit)!==void 0?null==t?void 0:t.rpm_limit:"unlimited"),rules:[{validator:async(e,l)=>{if(l&&t&&null!==t.rpm_limit&&l>t.rpm_limit)throw Error("RPM limit cannot exceed team RPM limit: ".concat(t.rpm_limit))}}],children:(0,a.jsx)(eo.Z,{step:1,width:400})}),(0,a.jsx)(er.Z.Item,{label:"Expire Key (eg: 30s, 30h, 30d)",name:"duration",className:"mt-8",children:(0,a.jsx)(H.Z,{placeholder:""})}),(0,a.jsx)(er.Z.Item,{label:"Metadata",name:"metadata",children:(0,a.jsx)(en.Z.TextArea,{rows:4,placeholder:"Enter metadata as JSON"})})]})]})]}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(ei.ZP,{htmlType:"submit",children:"Create Key"})})]})}),h&&(0,a.jsx)(ea.Z,{visible:d,onOk:w,onCancel:b,footer:null,children:(0,a.jsxs)(W.Z,{numItems:1,className:"gap-2 w-full",children:[(0,a.jsx)(el.Z,{children:"Save your Key"}),(0,a.jsx)(Y.Z,{numColSpan:1,children:(0,a.jsxs)("p",{children:["Please save this secret key somewhere safe and accessible. For security reasons, ",(0,a.jsx)("b",{children:"you will not be able to view it again"})," ","through your LiteLLM account. If you lose this secret key, you will need to generate a new one."]})}),(0,a.jsx)(Y.Z,{numColSpan:1,children:null!=h?(0,a.jsxs)("div",{children:[(0,a.jsx)(ee.Z,{className:"mt-3",children:"API Key:"}),(0,a.jsx)("div",{style:{background:"#f8f8f8",padding:"10px",borderRadius:"5px",marginBottom:"10px"},children:(0,a.jsx)("pre",{style:{wordWrap:"break-word",whiteSpace:"normal"},children:h})}),(0,a.jsx)(et.CopyToClipboard,{text:h,onCopy:()=>{u.ZP.success("API Key copied to clipboard")},children:(0,a.jsx)(J.Z,{className:"mt-3",children:"Copy API Key"})})]}):(0,a.jsx)(ee.Z,{children:"Key being created, this might take 30s"})})]})})]})},em=t(9454),eu=t(98941),eh=t(33393),ex=t(5),ep=t(13810),ej=t(61244),eg=t(10827),ey=t(3851),ef=t(2044),eZ=t(64167),e_=t(74480),ew=t(7178),eb=t(95093),ek=t(27166);let{Option:ev}=es.default;var eS=e=>{let{userID:l,userRole:t,accessToken:s,selectedTeam:r,data:o,setData:i,teams:c}=e,[d,m]=(0,n.useState)(!1),[h,x]=(0,n.useState)(!1),[p,j]=(0,n.useState)(null),[g,f]=(0,n.useState)(null),[Z,_]=(0,n.useState)(null),[w,b]=(0,n.useState)(""),[k,v]=(0,n.useState)(!1),[S,N]=(0,n.useState)(!1),[E,I]=(0,n.useState)(null),[C,P]=(0,n.useState)([]),T=new Set,[O,F]=(0,n.useState)(T);(0,n.useEffect)(()=>{(async()=>{try{if(null===l)return;if(null!==s&&null!==t){let e=(await A(s,l,t)).data.map(e=>e.id);console.log("available_model_names:",e),P(e)}}catch(e){console.error("Error fetching user models:",e)}})()},[s,l,t]),(0,n.useEffect)(()=>{if(c){let e=new Set;c.forEach((l,t)=>{let s=l.team_id;e.add(s)}),F(e)}},[c]);let R=e=>{console.log("handleEditClick:",e),null==e.token&&null!==e.token_id&&(e.token=e.token_id),I(e),v(!0)},M=async e=>{if(null==s)return;let l=e.token;e.key=l,console.log("handleEditSubmit:",e);let t=await L(s,e);console.log("handleEditSubmit: newKeyValues",t),o&&i(o.map(e=>e.token===l?t:e)),u.ZP.success("Key updated successfully"),v(!1),I(null)},U=async e=>{console.log("handleDelete:",e),null==e.token&&null!==e.token_id&&(e.token=e.token_id),null!=o&&(j(e.token),localStorage.removeItem("userData"+l),x(!0))},D=async()=>{if(null!=p&&null!=o){try{await y(s,p);let e=o.filter(e=>e.token!==p);i(e)}catch(e){console.error("Error deleting the key:",e)}x(!1),j(null)}};if(null!=o)return console.log("RERENDER TRIGGERED"),(0,a.jsxs)("div",{children:[(0,a.jsxs)(ep.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh] mb-4 mt-2",children:[(0,a.jsxs)(eg.Z,{className:"mt-5 max-h-[300px] min-h-[300px]",children:[(0,a.jsx)(eZ.Z,{children:(0,a.jsxs)(ew.Z,{children:[(0,a.jsx)(e_.Z,{children:"Key Alias"}),(0,a.jsx)(e_.Z,{children:"Secret Key"}),(0,a.jsx)(e_.Z,{children:"Spend (USD)"}),(0,a.jsx)(e_.Z,{children:"Budget (USD)"}),(0,a.jsx)(e_.Z,{children:"Models"}),(0,a.jsx)(e_.Z,{children:"TPM / RPM Limits"})]})}),(0,a.jsx)(ey.Z,{children:o.map(e=>{if(console.log(e),"litellm-dashboard"===e.team_id)return null;if(r){if(console.log("item team id: ".concat(e.team_id,", knownTeamIDs.has(item.team_id): ").concat(O.has(e.team_id),", selectedTeam id: ").concat(r.team_id)),(null!=r.team_id||null===e.team_id||O.has(e.team_id))&&e.team_id!=r.team_id)return null;console.log("item team id: ".concat(e.team_id,", is returned"))}return(0,a.jsxs)(ew.Z,{children:[(0,a.jsx)(ef.Z,{style:{maxWidth:"2px",whiteSpace:"pre-wrap",overflow:"hidden"},children:null!=e.key_alias?(0,a.jsx)(ee.Z,{children:e.key_alias}):(0,a.jsx)(ee.Z,{children:"Not Set"})}),(0,a.jsx)(ef.Z,{children:(0,a.jsx)(ee.Z,{children:e.key_name})}),(0,a.jsx)(ef.Z,{children:(0,a.jsx)(ee.Z,{children:(()=>{try{return parseFloat(e.spend).toFixed(4)}catch(l){return e.spend}})()})}),(0,a.jsx)(ef.Z,{children:null!=e.max_budget?(0,a.jsx)(ee.Z,{children:e.max_budget}):(0,a.jsx)(ee.Z,{children:"Unlimited"})}),(0,a.jsx)(ef.Z,{children:Array.isArray(e.models)?(0,a.jsx)("div",{style:{display:"flex",flexDirection:"column"},children:0===e.models.length?(0,a.jsx)(a.Fragment,{children:r&&r.models&&r.models.length>0?r.models.map((e,l)=>"all-proxy-models"===e?(0,a.jsx)(ex.Z,{size:"xs",className:"mb-1",color:"red",children:(0,a.jsx)(ee.Z,{children:"All Proxy Models"})},l):"all-team-models"===e?(0,a.jsx)(ex.Z,{size:"xs",className:"mb-1",color:"red",children:(0,a.jsx)(ee.Z,{children:"All Team Models"})},l):(0,a.jsx)(ex.Z,{size:"xs",className:"mb-1",color:"blue",children:(0,a.jsx)(ee.Z,{children:e.length>30?"".concat(e.slice(0,30),"..."):e})},l)):(0,a.jsx)(ex.Z,{size:"xs",className:"mb-1",color:"blue",children:(0,a.jsx)(ee.Z,{children:"all-proxy-models"})})}):e.models.map((e,l)=>"all-proxy-models"===e?(0,a.jsx)(ex.Z,{size:"xs",className:"mb-1",color:"red",children:(0,a.jsx)(ee.Z,{children:"All Proxy Models"})},l):"all-team-models"===e?(0,a.jsx)(ex.Z,{size:"xs",className:"mb-1",color:"red",children:(0,a.jsx)(ee.Z,{children:"All Team Models"})},l):(0,a.jsx)(ex.Z,{size:"xs",className:"mb-1",color:"blue",children:(0,a.jsx)(ee.Z,{children:e.length>30?"".concat(e.slice(0,30),"..."):e})},l))}):null}),(0,a.jsx)(ef.Z,{children:(0,a.jsxs)(ee.Z,{children:["TPM: ",e.tpm_limit?e.tpm_limit:"Unlimited"," ",(0,a.jsx)("br",{})," RPM:"," ",e.rpm_limit?e.rpm_limit:"Unlimited"]})}),(0,a.jsxs)(ef.Z,{children:[(0,a.jsx)(ej.Z,{onClick:()=>{I(e),N(!0)},icon:em.Z,size:"sm"}),(0,a.jsx)(ea.Z,{open:S,onCancel:()=>{N(!1),I(null)},footer:null,width:800,children:E&&(0,a.jsxs)(a.Fragment,{children:[(0,a.jsxs)("div",{className:"grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3 mt-8",children:[(0,a.jsxs)(ep.Z,{children:[(0,a.jsx)("p",{className:"text-tremor-default font-medium text-tremor-content dark:text-dark-tremor-content",children:"Spend"}),(0,a.jsx)("div",{className:"mt-2 flex items-baseline space-x-2.5",children:(0,a.jsx)("p",{className:"text-tremor font-semibold text-tremor-content-strong dark:text-dark-tremor-content-strong",children:(()=>{try{return parseFloat(E.spend).toFixed(4)}catch(e){return E.spend}})()})})]}),(0,a.jsxs)(ep.Z,{children:[(0,a.jsx)("p",{className:"text-tremor-default font-medium text-tremor-content dark:text-dark-tremor-content",children:"Budget"}),(0,a.jsx)("div",{className:"mt-2 flex items-baseline space-x-2.5",children:(0,a.jsx)("p",{className:"text-tremor font-semibold text-tremor-content-strong dark:text-dark-tremor-content-strong",children:null!=E.max_budget?(0,a.jsx)(a.Fragment,{children:E.max_budget}):(0,a.jsx)(a.Fragment,{children:"Unlimited"})})})]},e.name),(0,a.jsxs)(ep.Z,{children:[(0,a.jsx)("p",{className:"text-tremor-default font-medium text-tremor-content dark:text-dark-tremor-content",children:"Expires"}),(0,a.jsx)("div",{className:"mt-2 flex items-baseline space-x-2.5",children:(0,a.jsx)("p",{className:"text-tremor-default font-small text-tremor-content-strong dark:text-dark-tremor-content-strong",children:null!=E.expires?(0,a.jsx)(a.Fragment,{children:new Date(E.expires).toLocaleString(void 0,{day:"numeric",month:"long",year:"numeric",hour:"numeric",minute:"numeric",second:"numeric"})}):(0,a.jsx)(a.Fragment,{children:"Never"})})})]},e.name)]}),(0,a.jsxs)(ep.Z,{className:"my-4",children:[(0,a.jsx)(el.Z,{children:"Token Name"}),(0,a.jsx)(ee.Z,{className:"my-1",children:E.key_alias?E.key_alias:E.key_name}),(0,a.jsx)(el.Z,{children:"Token ID"}),(0,a.jsx)(ee.Z,{className:"my-1 text-[12px]",children:E.token}),(0,a.jsx)(el.Z,{children:"Metadata"}),(0,a.jsx)(ee.Z,{className:"my-1",children:(0,a.jsxs)("pre",{children:[JSON.stringify(E.metadata)," "]})})]}),(0,a.jsx)(J.Z,{className:"mx-auto flex items-center",onClick:()=>{N(!1),I(null)},children:"Close"})]})}),(0,a.jsx)(ej.Z,{icon:eu.Z,size:"sm",onClick:()=>R(e)}),(0,a.jsx)(ej.Z,{onClick:()=>U(e),icon:eh.Z,size:"sm"})]})]},e.token)})})]}),h&&(0,a.jsx)("div",{className:"fixed z-10 inset-0 overflow-y-auto",children:(0,a.jsxs)("div",{className:"flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0",children:[(0,a.jsx)("div",{className:"fixed inset-0 transition-opacity","aria-hidden":"true",children:(0,a.jsx)("div",{className:"absolute inset-0 bg-gray-500 opacity-75"})}),(0,a.jsx)("span",{className:"hidden sm:inline-block sm:align-middle sm:h-screen","aria-hidden":"true",children:"โ€‹"}),(0,a.jsxs)("div",{className:"inline-block align-bottom bg-white rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full",children:[(0,a.jsx)("div",{className:"bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4",children:(0,a.jsx)("div",{className:"sm:flex sm:items-start",children:(0,a.jsxs)("div",{className:"mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left",children:[(0,a.jsx)("h3",{className:"text-lg leading-6 font-medium text-gray-900",children:"Delete Key"}),(0,a.jsx)("div",{className:"mt-2",children:(0,a.jsx)("p",{className:"text-sm text-gray-500",children:"Are you sure you want to delete this key ?"})})]})})}),(0,a.jsxs)("div",{className:"bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse",children:[(0,a.jsx)(J.Z,{onClick:D,color:"red",className:"ml-2",children:"Delete"}),(0,a.jsx)(J.Z,{onClick:()=>{x(!1),j(null)},children:"Cancel"})]})]})]})})]}),E&&(0,a.jsx)(e=>{let{visible:l,onCancel:t,token:s,onSubmit:o}=e,[i]=er.Z.useForm(),[d,m]=(0,n.useState)(r),[u,h]=(0,n.useState)([]),[x,p]=(0,n.useState)(!1);return(0,a.jsx)(ea.Z,{title:"Edit Key",visible:l,width:800,footer:null,onOk:()=>{i.validateFields().then(e=>{i.resetFields()}).catch(e=>{console.error("Validation failed:",e)})},onCancel:t,children:(0,a.jsxs)(er.Z,{form:i,onFinish:M,initialValues:s,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(er.Z.Item,{label:"Key Name",name:"key_alias",rules:[{required:!0,message:"Please input a key name"}],help:"required",children:(0,a.jsx)(en.Z,{})}),(0,a.jsx)(er.Z.Item,{label:"Models",name:"models",rules:[{validator:(e,l)=>{let t=l.filter(e=>!d.models.includes(e)&&"all-team-models"!==e&&"all-proxy-models"!==e&&!d.models.includes("all-proxy-models"));return(console.log("errorModels: ".concat(t)),t.length>0)?Promise.reject("Some models are not part of the new team's models - ".concat(t,"Team models: ").concat(d.models)):Promise.resolve()}}],children:(0,a.jsxs)(es.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:[(0,a.jsx)(ev,{value:"all-team-models",children:"All Team Models"},"all-team-models"),d&&d.models?d.models.includes("all-proxy-models")?C.filter(e=>"all-proxy-models"!==e).map(e=>(0,a.jsx)(ev,{value:e,children:e},e)):d.models.map(e=>(0,a.jsx)(ev,{value:e,children:e},e)):C.map(e=>(0,a.jsx)(ev,{value:e,children:e},e))]})}),(0,a.jsx)(er.Z.Item,{className:"mt-8",label:"Max Budget (USD)",name:"max_budget",help:"Budget cannot exceed team max budget: ".concat((null==d?void 0:d.max_budget)!==null&&(null==d?void 0:d.max_budget)!==void 0?null==d?void 0:d.max_budget:"unlimited"),rules:[{validator:async(e,l)=>{if(l&&d&&null!==d.max_budget&&l>d.max_budget)throw console.log("keyTeam.max_budget: ".concat(d.max_budget)),Error("Budget cannot exceed team max budget: $".concat(d.max_budget))}}],children:(0,a.jsx)(eo.Z,{step:.01,precision:2,width:200})}),(0,a.jsx)(er.Z.Item,{label:"token",name:"token",hidden:!0}),(0,a.jsx)(er.Z.Item,{label:"Team",name:"team_id",help:"the team this key belongs to",children:(0,a.jsx)(eb.Z,{value:s.team_alias,children:null==c?void 0:c.map((e,l)=>(0,a.jsx)(ek.Z,{value:e.team_id,onClick:()=>m(e),children:e.team_alias},l))})})]}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(ei.ZP,{htmlType:"submit",children:"Edit Key"})})]})})},{visible:k,onCancel:()=>{v(!1),I(null)},token:E,onSubmit:M})]})},eA=t(76032),eN=t(35152),eE=e=>{let{userID:l,userRole:t,accessToken:s,userSpend:r,selectedTeam:o}=e;console.log("userSpend: ".concat(r));let[i,c]=(0,n.useState)(null!==r?r:0),[d,m]=(0,n.useState)(0),[u,h]=(0,n.useState)([]);(0,n.useEffect)(()=>{let e=async()=>{if(s&&l&&t&&"Admin"===t&&null==r)try{let e=await w(s);e&&(e.spend?c(e.spend):c(0),e.max_budget?m(e.max_budget):m(0))}catch(e){console.error("Error fetching global spend data:",e)}};(async()=>{try{if(null===l||null===t)return;if(null!==s){let e=(await A(s,l,t)).data.map(e=>e.id);console.log("available_model_names:",e),h(e)}}catch(e){console.error("Error fetching user models:",e)}})(),e()},[t,s,l]),(0,n.useEffect)(()=>{null!==r&&c(r)},[r]);let x=[];o&&o.models&&(x=o.models),x&&x.includes("all-proxy-models")?(console.log("user models:",u),x=u):x&&x.includes("all-team-models")?x=o.models:x&&0===x.length&&(x=u);let p=void 0!==i?i.toFixed(4):null;return console.log("spend in view user spend: ".concat(i)),(0,a.jsxs)("div",{className:"flex items-center",children:[(0,a.jsxs)("div",{children:[(0,a.jsxs)("p",{className:"text-tremor-default text-tremor-content dark:text-dark-tremor-content",children:["Total Spend"," "]}),(0,a.jsxs)("p",{className:"text-2xl text-tremor-content-strong dark:text-dark-tremor-content-strong font-semibold",children:["$",p]})]}),(0,a.jsx)("div",{className:"ml-auto",children:(0,a.jsxs)($.Z,{children:[(0,a.jsx)(Q.Z,{children:(0,a.jsx)(ee.Z,{children:"Team Models"})}),(0,a.jsx)(X.Z,{className:"absolute right-0 z-10 bg-white p-2 shadow-lg max-w-xs",children:(0,a.jsx)(eA.Z,{children:x.map(e=>(0,a.jsx)(eN.Z,{children:(0,a.jsx)(ee.Z,{children:e})},e))})})]})})]})},eI=e=>{let{userID:l,userRole:t,selectedTeam:s,accessToken:r}=e,[o,i]=(0,n.useState)([]);(0,n.useEffect)(()=>{(async()=>{try{if(null===l||null===t)return;if(null!==r){let e=(await A(r,l,t)).data.map(e=>e.id);console.log("available_model_names:",e),i(e)}}catch(e){console.error("Error fetching user models:",e)}})()},[r,l,t]);let c=[];return s&&s.models&&(c=s.models),c&&c.includes("all-proxy-models")&&(console.log("user models:",o),c=o),(0,a.jsx)(a.Fragment,{children:(0,a.jsx)("div",{className:"mb-5",children:(0,a.jsx)("p",{className:"text-3xl text-tremor-content-strong dark:text-dark-tremor-content-strong font-semibold",children:null==s?void 0:s.team_alias})})})},eC=e=>{let l,{teams:t,setSelectedTeam:s,userRole:r}=e,o={models:[],team_id:null,team_alias:"Default Team"},[i,c]=(0,n.useState)(o);return(l="App User"===r?t:t?[...t,o]:[o],"App User"===r)?null:(0,a.jsxs)("div",{className:"mt-5 mb-5",children:[(0,a.jsx)(el.Z,{children:"Select Team"}),(0,a.jsx)(ee.Z,{children:"If you belong to multiple teams, this setting controls which team is used by default when creating new API Keys."}),(0,a.jsxs)(ee.Z,{className:"mt-3 mb-3",children:[(0,a.jsx)("b",{children:"Default Team:"})," If no team_id is set for a key, it will be grouped under here."]}),l&&l.length>0?(0,a.jsx)(eb.Z,{defaultValue:"0",children:l.map((e,l)=>(0,a.jsx)(ek.Z,{value:String(l),onClick:()=>s(e),children:e.team_alias},l))}):(0,a.jsxs)(ee.Z,{children:["No team created. ",(0,a.jsx)("b",{children:"Defaulting to personal account."})]})]})},eP=t(37963),eT=t(36083);console.log("isLocal:",!1);var eO=e=>{let{userID:l,userRole:t,teams:s,keys:r,setUserRole:i,userEmail:c,setUserEmail:d,setTeams:m,setKeys:u}=e,[h,x]=(0,n.useState)(null),p=(0,o.useSearchParams)();p.get("viewSpend"),(0,o.useRouter)();let j=p.get("token"),[g,y]=(0,n.useState)(null),[f,_]=(0,n.useState)(null),[b,k]=(0,n.useState)([]),v={models:[],team_alias:"Default Team",team_id:null},[S,N]=(0,n.useState)(s?s[0]:v);if(window.addEventListener("beforeunload",function(){sessionStorage.clear()}),(0,n.useEffect)(()=>{if(j){let e=(0,eP.o)(j);if(e){if(console.log("Decoded token:",e),console.log("Decoded key:",e.key),y(e.key),e.user_role){let l=function(e){if(!e)return"Undefined Role";switch(console.log("Received user role: ".concat(e)),e.toLowerCase()){case"app_owner":case"demo_app_owner":return"App Owner";case"app_admin":case"proxy_admin":return"Admin";case"proxy_admin_viewer":return"Admin Viewer";case"app_user":return"App User";default:return"Unknown Role"}}(e.user_role);console.log("Decoded user_role:",l),i(l)}else console.log("User role not defined");e.user_email?d(e.user_email):console.log("User Email is not set ".concat(e))}}if(l&&g&&t&&!r&&!h){let e=sessionStorage.getItem("userModels"+l);e?k(JSON.parse(e)):(async()=>{try{let e=await Z(g,l,t,!1,null,null);if(console.log("received teams in user dashboard: ".concat(Object.keys(e),"; team values: ").concat(Object.entries(e.teams))),"Admin"==t){let e=await w(g);x(e),console.log("globalSpend:",e)}else x(e.user_info);u(e.keys),m(e.teams);let s=[...e.teams];s.length>0?(console.log("response['teams']: ".concat(s)),N(s[0])):N(v),sessionStorage.setItem("userData"+l,JSON.stringify(e.keys)),sessionStorage.setItem("userSpendData"+l,JSON.stringify(e.user_info));let r=(await A(g,l,t)).data.map(e=>e.id);console.log("available_model_names:",r),k(r),console.log("userModels:",b),sessionStorage.setItem("userModels"+l,JSON.stringify(r))}catch(e){console.error("There was an error fetching the data",e)}})()}},[l,j,g,r,t]),(0,n.useEffect)(()=>{if(null!==r&&null!=S){let e=0;for(let l of r)S.hasOwnProperty("team_id")&&null!==l.team_id&&l.team_id===S.team_id&&(e+=l.spend);_(e)}else if(null!==r){let e=0;for(let l of r)e+=l.spend;_(e)}},[S]),null==l||null==j){let e="/sso/key/generate";return console.log("Full URL:",e),window.location.href=e,null}if(null==g)return null;if(null==t&&i("App Owner"),t&&"Admin Viewer"==t){let{Title:e,Paragraph:l}=eT.default;return(0,a.jsxs)("div",{children:[(0,a.jsx)(e,{level:1,children:"Access Denied"}),(0,a.jsx)(l,{children:"Ask your proxy admin for access to create keys"})]})}return console.log("inside user dashboard, selected team",S),console.log("teamSpend: ".concat(f)),(0,a.jsx)("div",{className:"w-full mx-4",children:(0,a.jsx)(W.Z,{numItems:1,className:"gap-2 p-8 h-[75vh] w-full mt-2",children:(0,a.jsxs)(Y.Z,{numColSpan:1,children:[(0,a.jsx)(eI,{userID:l,userRole:t,selectedTeam:S||null,accessToken:g}),(0,a.jsx)(eE,{userID:l,userRole:t,accessToken:g,userSpend:f,selectedTeam:S||null}),(0,a.jsx)(eS,{userID:l,userRole:t,accessToken:g,selectedTeam:S||null,data:r,setData:u,teams:s}),(0,a.jsx)(ed,{userID:l,team:S||null,userRole:t,accessToken:g,data:r,setData:u},S?S.team_id:null),(0,a.jsx)(eC,{teams:s,setSelectedTeam:N,userRole:t})]})})})},eF=t(35087),eR=t(92836),eM=t(26734),eL=t(41608),eU=t(32126),eD=t(23682),eK=t(47047),eB=t(76628),ez=t(57750),eq=t(44041),eV=t(38302),eG=t(28683),eY=t(1460),eW=t(78578),eJ=t(63954),eH=t(90252),e$=t(7905),eX=e=>{let{modelID:l,accessToken:t}=e,[s,r]=(0,n.useState)(!1),o=async()=>{try{u.ZP.info("Making API Call"),r(!0);let e=await p(t,l);console.log("model delete Response:",e),u.ZP.success("Model ".concat(l," deleted successfully")),r(!1)}catch(e){console.error("Error deleting the model:",e)}};return(0,a.jsxs)("div",{children:[(0,a.jsx)(ej.Z,{onClick:()=>r(!0),icon:eh.Z,size:"sm"}),(0,a.jsx)(ea.Z,{open:s,onOk:o,okType:"danger",onCancel:()=>r(!1),children:(0,a.jsxs)(W.Z,{numItems:1,className:"gap-2 w-full",children:[(0,a.jsx)(el.Z,{children:"Delete Model"}),(0,a.jsx)(Y.Z,{numColSpan:1,children:(0,a.jsx)("p",{children:"Are you sure you want to delete this model? This action is irreversible."})}),(0,a.jsx)(Y.Z,{numColSpan:1,children:(0,a.jsxs)("p",{children:["Model ID: ",(0,a.jsx)("b",{children:l})]})})]})})]})},eQ=t(97766),e0=t(46495);let{Title:e1,Link:e2}=eT.default;(s=r||(r={})).OpenAI="OpenAI",s.Azure="Azure",s.Anthropic="Anthropic",s.Google_AI_Studio="Gemini (Google AI Studio)",s.Bedrock="Amazon Bedrock",s.OpenAI_Compatible="OpenAI-Compatible Endpoints (Groq, Together AI, Mistral AI, etc.)",s.Vertex_AI="Vertex AI (Anthropic, Gemini, etc.)";let e4={OpenAI:"openai",Azure:"azure",Anthropic:"anthropic",Google_AI_Studio:"gemini",Bedrock:"bedrock",OpenAI_Compatible:"openai",Vertex_AI:"vertex_ai"},e8={"BadRequestError (400)":"BadRequestErrorRetries","AuthenticationError (401)":"AuthenticationErrorRetries","TimeoutError (408)":"TimeoutErrorRetries","RateLimitError (429)":"RateLimitErrorRetries","ContentPolicyViolationError (400)":"ContentPolicyViolationErrorRetries","InternalServerError (500)":"InternalServerErrorRetries"},e5=async(e,l,t)=>{try{let s=Array.isArray(e.model)?e.model:[e.model];console.log("received deployments: ".concat(s)),console.log("received type of deployments: ".concat(typeof s)),s.forEach(async t=>{console.log("litellm_model: ".concat(t));let s={},r={};s.model=t;let a="";for(let[l,t]of Object.entries(e))if(""!==t){if("model_name"==l)a+=t;else if("custom_llm_provider"==l)continue;else if("model"==l)continue;else if("base_model"===l)r[l]=t;else if("litellm_extra_params"==l){console.log("litellm_extra_params:",t);let e={};if(t&&void 0!=t){try{e=JSON.parse(t)}catch(e){throw u.ZP.error("Failed to parse LiteLLM Extra Params: "+e,10),Error("Failed to parse litellm_extra_params: "+e)}for(let[l,t]of Object.entries(e))s[l]=t}}else s[l]=t}let n={model_name:a,litellm_params:s,model_info:r},o=await x(l,n);console.log("response for model create call: ".concat(o.data))}),t.resetFields()}catch(e){u.ZP.error("Failed to create model: "+e,10)}};var e3=e=>{var l,t,s;let{accessToken:o,token:i,userRole:c,userID:d,modelData:m={data:[]},setModelData:x}=e,[p,j]=(0,n.useState)([]),[g]=er.Z.useForm(),[y,f]=(0,n.useState)(null),[Z,_]=(0,n.useState)(""),[w,A]=(0,n.useState)([]),N=Object.values(r).filter(e=>isNaN(Number(e))),[E,I]=(0,n.useState)("OpenAI"),[C,P]=(0,n.useState)(""),[T,O]=(0,n.useState)(!1),[F,R]=(0,n.useState)(null),[M,L]=(0,n.useState)([]),[U,K]=(0,n.useState)(null),[B,z]=(0,n.useState)([]),[Y,et]=(0,n.useState)([]),[es,en]=(0,n.useState)([]),[ec,ed]=(0,n.useState)([]),[em,eh]=(0,n.useState)([]),[ev,eS]=(0,n.useState)([]),[eA,eN]=(0,n.useState)([]),[eE,eI]=(0,n.useState)({from:new Date(Date.now()-6048e5),to:new Date}),[eC,eP]=(0,n.useState)(null),[eO,e3]=(0,n.useState)(0),e6=e=>{R(e),O(!0)},e7=async e=>{if(console.log("handleEditSubmit:",e),null==o)return;let l={},t=null;for(let[s,r]of Object.entries(e))"model_id"!==s?l[s]=r:t=r;let s={litellm_params:l,model_info:{id:t}};console.log("handleEditSubmit payload:",s);try{await D(o,s),u.ZP.success("Model updated successfully, restart server to see updates"),O(!1),R(null)}catch(e){console.log("Error occurred")}},e9=()=>{_(new Date().toLocaleString())},le=async()=>{if(!o){console.error("Access token is missing");return}console.log("new modelGroupRetryPolicy:",eC);try{await V(o,{router_settings:{model_group_retry_policy:eC}}),u.ZP.success("Retry settings saved successfully")}catch(e){console.error("Failed to save retry settings:",e),u.ZP.error("Failed to save retry settings")}};if((0,n.useEffect)(()=>{if(!o||!i||!c||!d)return;let e=async()=>{try{var e,l,t,s,r,a;let n=await b(o,d,c);console.log("Model data response:",n.data),x(n);let i=new Set;for(let e=0;e0&&(u=m[m.length-1],console.log("_initial_model_group:",u),K(u)),console.log("selectedModelGroup:",U);let h=await k(o,d,c,u,null===(e=eE.from)||void 0===e?void 0:e.toISOString(),null===(l=eE.to)||void 0===l?void 0:l.toISOString());console.log("Model metrics response:",h),et(h.data),en(h.all_api_bases);let p=await S(o,d,c,u,null===(t=eE.from)||void 0===t?void 0:t.toISOString(),null===(s=eE.to)||void 0===s?void 0:s.toISOString());console.log("Model exceptions response:",p),ed(p.data),eh(p.exception_types);let j=await v(o,d,c,u,null===(r=eE.from)||void 0===r?void 0:r.toISOString(),null===(a=eE.to)||void 0===a?void 0:a.toISOString());console.log("slowResponses:",j),eN(j);let g=(await q(o,d,c)).router_settings;console.log("routerSettingsInfo:",g);let y=g.model_group_retry_policy,f=g.num_retries;console.log("model_group_retry_policy:",y),console.log("default_retries:",f),eP(y),e3(f)}catch(e){console.error("There was an error fetching the model data",e)}};o&&i&&c&&d&&e();let l=async()=>{let e=await h();console.log("received model cost map data: ".concat(Object.keys(e))),f(e)};null==y&&l(),e9()},[o,i,c,d,y,Z]),!m||!o||!i||!c||!d)return(0,a.jsx)("div",{children:"Loading..."});let ll=[];for(let e=0;e(console.log("GET PROVIDER CALLED! - ".concat(y)),null!=y&&"object"==typeof y&&e in y)?y[e].litellm_provider:"openai";if(r){let e=r.split("/"),l=e[0];n=1===e.length?u(r):l}else n="openai";a&&(o=null==a?void 0:a.input_cost_per_token,i=null==a?void 0:a.output_cost_per_token,c=null==a?void 0:a.max_tokens),(null==s?void 0:s.litellm_params)&&(d=Object.fromEntries(Object.entries(null==s?void 0:s.litellm_params).filter(e=>{let[l]=e;return"model"!==l&&"api_base"!==l}))),m.data[e].provider=n,m.data[e].input_cost=o,m.data[e].output_cost=i,m.data[e].max_tokens=c,m.data[e].api_base=null==s?void 0:null===(t=s.litellm_params)||void 0===t?void 0:t.api_base,m.data[e].cleanedLitellmParams=d,ll.push(s.model_name),console.log(m.data[e])}if(c&&"Admin Viewer"==c){let{Title:e,Paragraph:l}=eT.default;return(0,a.jsxs)("div",{children:[(0,a.jsx)(e,{level:1,children:"Access Denied"}),(0,a.jsx)(l,{children:"Ask your proxy admin for access to view all models"})]})}let lt=e=>{console.log("received provider string: ".concat(e));let l=Object.keys(r).find(l=>r[l]===e);if(l){let e=e4[l];console.log("mappingResult: ".concat(e));let t=[];"object"==typeof y&&Object.entries(y).forEach(l=>{let[s,r]=l;null!==r&&"object"==typeof r&&"litellm_provider"in r&&(r.litellm_provider===e||r.litellm_provider.includes(e))&&t.push(s)}),A(t),console.log("providerModels: ".concat(w))}},ls=async()=>{try{u.ZP.info("Running health check..."),P("");let e=await G(o);P(e)}catch(e){console.error("Error running health check:",e),P("Error running health check")}},lr=async(e,l,t)=>{if(console.log("Updating model metrics for group:",e),o&&d&&c&&l&&t){console.log("inside updateModelMetrics - startTime:",l,"endTime:",t),K(e);try{let s=await k(o,d,c,e,l.toISOString(),t.toISOString());console.log("Model metrics response:",s),et(s.data),en(s.all_api_bases);let r=await S(o,d,c,e,l.toISOString(),t.toISOString());console.log("Model exceptions response:",r),ed(r.data),eh(r.exception_types);let a=await v(o,d,c,e,l.toISOString(),t.toISOString());console.log("slowResponses:",a),eN(a)}catch(e){console.error("Failed to fetch model metrics",e)}}};return console.log("selectedProvider: ".concat(E)),console.log("providerModels.length: ".concat(w.length)),(0,a.jsx)("div",{style:{width:"100%",height:"100%"},children:(0,a.jsxs)(eM.Z,{className:"gap-2 p-8 h-[75vh] w-full mt-2",children:[(0,a.jsxs)(eL.Z,{className:"flex justify-between mt-2 w-full items-center",children:[(0,a.jsxs)("div",{className:"flex",children:[(0,a.jsx)(eR.Z,{children:"All Models"}),(0,a.jsx)(eR.Z,{children:"Add Model"}),(0,a.jsx)(eR.Z,{children:(0,a.jsx)("pre",{children:"/health Models"})}),(0,a.jsx)(eR.Z,{children:"Model Analytics"}),(0,a.jsx)(eR.Z,{children:"Model Retry Settings"})]}),(0,a.jsxs)("div",{className:"flex items-center space-x-2",children:[Z&&(0,a.jsxs)(ee.Z,{children:["Last Refreshed: ",Z]}),(0,a.jsx)(ej.Z,{icon:eJ.Z,variant:"shadow",size:"xs",className:"self-center",onClick:e9})]})]}),(0,a.jsxs)(eD.Z,{children:[(0,a.jsxs)(eU.Z,{children:[(0,a.jsxs)(W.Z,{children:[(0,a.jsxs)("div",{className:"flex items-center",children:[(0,a.jsx)(ee.Z,{children:"Filter by Public Model Name"}),(0,a.jsxs)(eb.Z,{className:"mb-4 mt-2 ml-2 w-50",defaultValue:"all",onValueChange:e=>K("all"===e?"all":e),children:[(0,a.jsx)(ek.Z,{value:"all",children:"All Models"}),M.map((e,l)=>(0,a.jsx)(ek.Z,{value:e,onClick:()=>K(e),children:e},l))]})]}),(0,a.jsx)(ep.Z,{children:(0,a.jsxs)(eg.Z,{className:"mt-5",children:[(0,a.jsx)(eZ.Z,{children:(0,a.jsxs)(ew.Z,{children:[(0,a.jsx)(e_.Z,{children:"Public Model Name "}),(0,a.jsx)(e_.Z,{children:"Provider"}),"Admin"===c&&(0,a.jsx)(e_.Z,{children:"API Base"}),(0,a.jsx)(e_.Z,{children:"Extra litellm Params"}),(0,a.jsx)(e_.Z,{children:"Input Price per token ($)"}),(0,a.jsx)(e_.Z,{children:"Output Price per token ($)"}),(0,a.jsx)(e_.Z,{children:"Max Tokens"}),(0,a.jsx)(e_.Z,{children:"Status"})]})}),(0,a.jsx)(ey.Z,{children:m.data.filter(e=>"all"===U||e.model_name===U||null==U||""===U).map((e,l)=>(0,a.jsxs)(ew.Z,{children:[(0,a.jsx)(ef.Z,{children:(0,a.jsx)(ee.Z,{children:e.model_name})}),(0,a.jsx)(ef.Z,{children:e.provider}),"Admin"===c&&(0,a.jsx)(ef.Z,{children:e.api_base}),(0,a.jsx)(ef.Z,{children:(0,a.jsxs)($.Z,{children:[(0,a.jsx)(Q.Z,{children:(0,a.jsx)(ee.Z,{children:"Litellm params"})}),(0,a.jsx)(X.Z,{children:(0,a.jsx)("pre",{children:JSON.stringify(e.cleanedLitellmParams,null,2)})})]})}),(0,a.jsx)(ef.Z,{children:e.input_cost||e.litellm_params.input_cost_per_token||null}),(0,a.jsx)(ef.Z,{children:e.output_cost||e.litellm_params.output_cost_per_token||null}),(0,a.jsx)(ef.Z,{children:e.max_tokens}),(0,a.jsx)(ef.Z,{children:e.model_info.db_model?(0,a.jsx)(ex.Z,{icon:eH.Z,className:"text-white",children:"DB Model"}):(0,a.jsx)(ex.Z,{icon:e$.Z,className:"text-black",children:"Config Model"})}),(0,a.jsxs)(ef.Z,{children:[(0,a.jsx)(ej.Z,{icon:eu.Z,size:"sm",onClick:()=>e6(e)}),(0,a.jsx)(eX,{modelID:e.model_info.id,accessToken:o})]})]},l))})]})})]}),(0,a.jsx)(e=>{let{visible:l,onCancel:t,model:s,onSubmit:r}=e,[n]=er.Z.useForm(),o={},i="",c="";if(s){o=s.litellm_params,i=s.model_name;let e=s.model_info;e&&(c=e.id,console.log("model_id: ".concat(c)),o.model_id=c)}return(0,a.jsx)(ea.Z,{title:"Edit Model "+i,visible:l,width:800,footer:null,onOk:()=>{n.validateFields().then(e=>{r(e),n.resetFields()}).catch(e=>{console.error("Validation failed:",e)})},onCancel:t,children:(0,a.jsxs)(er.Z,{form:n,onFinish:e7,initialValues:o,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(er.Z.Item,{className:"mt-8",label:"api_base",name:"api_base",children:(0,a.jsx)(H.Z,{})}),(0,a.jsx)(er.Z.Item,{label:"tpm",name:"tpm",tooltip:"int (optional) - Tokens limit for this deployment: in tokens per minute (tpm). Find this information on your model/providers website",children:(0,a.jsx)(eo.Z,{min:0,step:1})}),(0,a.jsx)(er.Z.Item,{label:"rpm",name:"rpm",tooltip:"int (optional) - Rate limit for this deployment: in requests per minute (rpm). Find this information on your model/providers website",children:(0,a.jsx)(eo.Z,{min:0,step:1})}),(0,a.jsx)(er.Z.Item,{label:"max_retries",name:"max_retries",children:(0,a.jsx)(eo.Z,{min:0,step:1})}),(0,a.jsx)(er.Z.Item,{label:"timeout",name:"timeout",tooltip:"int (optional) - Timeout in seconds for LLM requests (Defaults to 600 seconds)",children:(0,a.jsx)(eo.Z,{min:0,step:1})}),(0,a.jsx)(er.Z.Item,{label:"stream_timeout",name:"stream_timeout",tooltip:"int (optional) - Timeout for stream requests (seconds)",children:(0,a.jsx)(eo.Z,{min:0,step:1})}),(0,a.jsx)(er.Z.Item,{label:"input_cost_per_token",name:"input_cost_per_token",tooltip:"float (optional) - Input cost per token",children:(0,a.jsx)(eo.Z,{min:0,step:1e-4})}),(0,a.jsx)(er.Z.Item,{label:"output_cost_per_token",name:"output_cost_per_token",tooltip:"float (optional) - Output cost per token",children:(0,a.jsx)(eo.Z,{min:0,step:1e-4})}),(0,a.jsx)(er.Z.Item,{label:"model_id",name:"model_id",hidden:!0})]}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(ei.ZP,{htmlType:"submit",children:"Save"})})]})})},{visible:T,onCancel:()=>{O(!1),R(null)},model:F,onSubmit:e7})]}),(0,a.jsxs)(eU.Z,{className:"h-full",children:[(0,a.jsx)(e1,{level:2,children:"Add new model"}),(0,a.jsx)(ep.Z,{children:(0,a.jsxs)(er.Z,{form:g,onFinish:()=>{g.validateFields().then(e=>{e5(e,o,g)}).catch(e=>{console.error("Validation failed:",e)})},labelCol:{span:10},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(er.Z.Item,{rules:[{required:!0,message:"Required"}],label:"Provider:",name:"custom_llm_provider",tooltip:"E.g. OpenAI, Azure OpenAI, Anthropic, Bedrock, etc.",labelCol:{span:10},labelAlign:"left",children:(0,a.jsx)(eb.Z,{value:E.toString(),children:N.map((e,l)=>(0,a.jsx)(ek.Z,{value:e,onClick:()=>{lt(e),I(e)},children:e},l))})}),(0,a.jsx)(er.Z.Item,{rules:[{required:!0,message:"Required"}],label:"Public Model Name",name:"model_name",tooltip:"Model name your users will pass in. Also used for load-balancing, LiteLLM will load balance between all models with this public name.",className:"mb-0",children:(0,a.jsx)(H.Z,{placeholder:"Vertex AI (Anthropic, Gemini, etc.)"===(s=E.toString())?"gemini-pro":"Anthropic"==s?"claude-3-opus":"Amazon Bedrock"==s?"claude-3-opus":"Gemini (Google AI Studio)"==s?"gemini-pro":"gpt-3.5-turbo"})}),(0,a.jsxs)(eV.Z,{children:[(0,a.jsx)(eG.Z,{span:10}),(0,a.jsx)(eG.Z,{span:10,children:(0,a.jsx)(ee.Z,{className:"mb-3 mt-1",children:"Model name your users will pass in."})})]}),(0,a.jsx)(er.Z.Item,{rules:[{required:!0,message:"Required"}],label:"LiteLLM Model Name(s)",name:"model",tooltip:"Actual model name used for making litellm.completion() call.",className:"mb-0",children:"Azure"===E?(0,a.jsx)(H.Z,{placeholder:"Enter model name"}):w.length>0?(0,a.jsx)(eK.Z,{value:w,children:w.map((e,l)=>(0,a.jsx)(eB.Z,{value:e,children:e},l))}):(0,a.jsx)(H.Z,{placeholder:"gpt-3.5-turbo-0125"})}),(0,a.jsxs)(eV.Z,{children:[(0,a.jsx)(eG.Z,{span:10}),(0,a.jsx)(eG.Z,{span:10,children:(0,a.jsxs)(ee.Z,{className:"mb-3 mt-1",children:["Actual model name used for making ",(0,a.jsx)(e2,{href:"https://docs.litellm.ai/docs/providers",target:"_blank",children:"litellm.completion() call"}),". We'll ",(0,a.jsx)(e2,{href:"https://docs.litellm.ai/docs/proxy/reliability#step-1---set-deployments-on-config",target:"_blank",children:"loadbalance"})," models with the same 'public name'"]})})]}),"Amazon Bedrock"!=E&&"Vertex AI (Anthropic, Gemini, etc.)"!=E&&(0,a.jsx)(er.Z.Item,{rules:[{required:!0,message:"Required"}],label:"API Key",name:"api_key",children:(0,a.jsx)(H.Z,{placeholder:"sk-",type:"password"})}),"OpenAI"==E&&(0,a.jsx)(er.Z.Item,{label:"Organization ID",name:"organization_id",children:(0,a.jsx)(H.Z,{placeholder:"[OPTIONAL] my-unique-org"})}),"Vertex AI (Anthropic, Gemini, etc.)"==E&&(0,a.jsx)(er.Z.Item,{rules:[{required:!0,message:"Required"}],label:"Vertex Project",name:"vertex_project",children:(0,a.jsx)(H.Z,{placeholder:"adroit-cadet-1234.."})}),"Vertex AI (Anthropic, Gemini, etc.)"==E&&(0,a.jsx)(er.Z.Item,{rules:[{required:!0,message:"Required"}],label:"Vertex Location",name:"vertex_location",children:(0,a.jsx)(H.Z,{placeholder:"us-east-1"})}),"Vertex AI (Anthropic, Gemini, etc.)"==E&&(0,a.jsx)(er.Z.Item,{rules:[{required:!0,message:"Required"}],label:"Vertex Credentials",name:"vertex_credentials",className:"mb-0",children:(0,a.jsx)(e0.Z,{name:"file",accept:".json",beforeUpload:e=>{if("application/json"===e.type){let l=new FileReader;l.onload=e=>{if(e.target){let l=e.target.result;g.setFieldsValue({vertex_credentials:l})}},l.readAsText(e)}return!1},onChange(e){"uploading"!==e.file.status&&console.log(e.file,e.fileList),"done"===e.file.status?u.ZP.success("".concat(e.file.name," file uploaded successfully")):"error"===e.file.status&&u.ZP.error("".concat(e.file.name," file upload failed."))},children:(0,a.jsx)(ei.ZP,{icon:(0,a.jsx)(eQ.Z,{}),children:"Click to Upload"})})}),"Vertex AI (Anthropic, Gemini, etc.)"==E&&(0,a.jsxs)(eV.Z,{children:[(0,a.jsx)(eG.Z,{span:10}),(0,a.jsx)(eG.Z,{span:10,children:(0,a.jsx)(ee.Z,{className:"mb-3 mt-1",children:"Give litellm a gcp service account(.json file), so it can make the relevant calls"})})]}),("Azure"==E||"OpenAI-Compatible Endpoints (Groq, Together AI, Mistral AI, etc.)"==E)&&(0,a.jsx)(er.Z.Item,{rules:[{required:!0,message:"Required"}],label:"API Base",name:"api_base",children:(0,a.jsx)(H.Z,{placeholder:"https://..."})}),"Azure"==E&&(0,a.jsx)(er.Z.Item,{rules:[{required:!0,message:"Required"}],label:"API Version",name:"api_version",children:(0,a.jsx)(H.Z,{placeholder:"2023-07-01-preview"})}),"Azure"==E&&(0,a.jsxs)(er.Z.Item,{label:"Base Model",name:"base_model",children:[(0,a.jsx)(H.Z,{placeholder:"azure/gpt-3.5-turbo"}),(0,a.jsxs)(ee.Z,{children:["The actual model your azure deployment uses. Used for accurate cost tracking. Select name from ",(0,a.jsx)(e2,{href:"https://github.com/BerriAI/litellm/blob/main/model_prices_and_context_window.json",target:"_blank",children:"here"})]})]}),"Amazon Bedrock"==E&&(0,a.jsx)(er.Z.Item,{rules:[{required:!0,message:"Required"}],label:"AWS Access Key ID",name:"aws_access_key_id",tooltip:"You can provide the raw key or the environment variable (e.g. `os.environ/MY_SECRET_KEY`).",children:(0,a.jsx)(H.Z,{placeholder:""})}),"Amazon Bedrock"==E&&(0,a.jsx)(er.Z.Item,{rules:[{required:!0,message:"Required"}],label:"AWS Secret Access Key",name:"aws_secret_access_key",tooltip:"You can provide the raw key or the environment variable (e.g. `os.environ/MY_SECRET_KEY`).",children:(0,a.jsx)(H.Z,{placeholder:""})}),"Amazon Bedrock"==E&&(0,a.jsx)(er.Z.Item,{rules:[{required:!0,message:"Required"}],label:"AWS Region Name",name:"aws_region_name",tooltip:"You can provide the raw key or the environment variable (e.g. `os.environ/MY_SECRET_KEY`).",children:(0,a.jsx)(H.Z,{placeholder:"us-east-1"})}),(0,a.jsx)(er.Z.Item,{label:"LiteLLM Params",name:"litellm_extra_params",tooltip:"Optional litellm params used for making a litellm.completion() call.",className:"mb-0",children:(0,a.jsx)(eW.Z,{rows:4,placeholder:'{ "rpm": 100, "timeout": 0, "stream_timeout": 0 }'})}),(0,a.jsxs)(eV.Z,{children:[(0,a.jsx)(eG.Z,{span:10}),(0,a.jsx)(eG.Z,{span:10,children:(0,a.jsxs)(ee.Z,{className:"mb-3 mt-1",children:["Pass JSON of litellm supported params ",(0,a.jsx)(e2,{href:"https://docs.litellm.ai/docs/completion/input",target:"_blank",children:"litellm.completion() call"})]})})]})]}),(0,a.jsx)("div",{style:{textAlign:"center",marginTop:"10px"},children:(0,a.jsx)(ei.ZP,{htmlType:"submit",children:"Add Model"})}),(0,a.jsx)(eY.Z,{title:"Get help on our github",children:(0,a.jsx)(eT.default.Link,{href:"https://github.com/BerriAI/litellm/issues",children:"Need Help?"})})]})})]}),(0,a.jsx)(eU.Z,{children:(0,a.jsxs)(ep.Z,{children:[(0,a.jsx)(ee.Z,{children:"`/health` will run a very small request through your models configured on litellm"}),(0,a.jsx)(J.Z,{onClick:ls,children:"Run `/health`"}),C&&(0,a.jsx)("pre",{children:JSON.stringify(C,null,2)})]})}),(0,a.jsxs)(eU.Z,{children:[(0,a.jsxs)(W.Z,{numItems:2,className:"mt-2",children:[(0,a.jsxs)(eG.Z,{children:[(0,a.jsx)(ee.Z,{children:"Select Time Range"}),(0,a.jsx)(eF.Z,{enableSelect:!0,value:eE,onValueChange:e=>{eI(e),lr(U,e.from,e.to)}})]}),(0,a.jsxs)(eG.Z,{children:[(0,a.jsx)(ee.Z,{children:"Select Model Group"}),(0,a.jsx)(eb.Z,{className:"mb-4 mt-2",defaultValue:U||M[0],value:U||M[0],children:M.map((e,l)=>(0,a.jsx)(ek.Z,{value:e,onClick:()=>lr(e,eE.from,eE.to),children:e},l))})]})]}),(0,a.jsxs)(W.Z,{numItems:2,children:[(0,a.jsx)(eG.Z,{children:(0,a.jsxs)(ep.Z,{className:"mr-2 max-h-[400px] min-h-[400px]",children:[(0,a.jsx)(el.Z,{children:"Avg Latency per Token"}),(0,a.jsx)("p",{className:"text-gray-500 italic",children:" (seconds/token)"}),(0,a.jsx)(ee.Z,{className:"text-gray-500 italic mt-1 mb-1",children:"average Latency for successfull requests divided by the total tokens"}),Y&&es&&(0,a.jsx)(ez.Z,{title:"Model Latency",className:"h-72",data:Y,showLegend:!1,index:"date",categories:es,connectNulls:!0,customTooltip:e=>{var l,t;let{payload:s,active:r}=e;if(!r||!s)return null;let n=null===(t=s[0])||void 0===t?void 0:null===(l=t.payload)||void 0===l?void 0:l.date,o=s.sort((e,l)=>l.value-e.value);if(o.length>5){let e=o.length-5;(o=o.slice(0,5)).push({dataKey:"".concat(e," other deployments"),value:s.slice(5).reduce((e,l)=>e+l.value,0),color:"gray"})}return(0,a.jsxs)("div",{className:"w-150 rounded-tremor-default border border-tremor-border bg-tremor-background p-2 text-tremor-default shadow-tremor-dropdown",children:[n&&(0,a.jsxs)("p",{className:"text-tremor-content-emphasis mb-2",children:["Date: ",n]}),o.map((e,l)=>{let t=parseFloat(e.value.toFixed(5)),s=0===t&&e.value>0?"<0.00001":t.toFixed(5);return(0,a.jsxs)("div",{className:"flex justify-between",children:[(0,a.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,a.jsx)("div",{className:"w-2 h-2 mt-1 rounded-full bg-".concat(e.color,"-500")}),(0,a.jsx)("p",{className:"text-tremor-content",children:e.dataKey})]}),(0,a.jsx)("p",{className:"font-medium text-tremor-content-emphasis text-righ ml-2",children:s})]},l)})]})}})]})}),(0,a.jsx)(eG.Z,{children:(0,a.jsx)(ep.Z,{className:"ml-2 max-h-[400px] min-h-[400px] overflow-y-auto",children:(0,a.jsxs)(eg.Z,{children:[(0,a.jsx)(eZ.Z,{children:(0,a.jsxs)(ew.Z,{children:[(0,a.jsx)(e_.Z,{children:"Deployment"}),(0,a.jsx)(e_.Z,{children:"Success Responses"}),(0,a.jsxs)(e_.Z,{children:["Slow Responses ",(0,a.jsx)("p",{children:"Success Responses taking 600+s"})]})]})}),(0,a.jsx)(ey.Z,{children:eA.map((e,l)=>(0,a.jsxs)(ew.Z,{children:[(0,a.jsx)(ef.Z,{children:e.api_base}),(0,a.jsx)(ef.Z,{children:e.total_count}),(0,a.jsx)(ef.Z,{children:e.slow_count})]},l))})]})})})]}),(0,a.jsxs)(ep.Z,{className:"mt-4",children:[(0,a.jsx)(el.Z,{children:"Exceptions per Model"}),(0,a.jsx)(eq.Z,{className:"h-72",data:ec,index:"model",categories:em,stack:!0,colors:["indigo-300","rose-200","#ffcc33"],yAxisWidth:30})]})]}),(0,a.jsxs)(eU.Z,{children:[(0,a.jsxs)("div",{className:"flex items-center",children:[(0,a.jsx)(ee.Z,{children:"Filter by Public Model Name"}),(0,a.jsx)(eb.Z,{className:"mb-4 mt-2 ml-2 w-50",defaultValue:U||M[0],value:U||M[0],onValueChange:e=>K(e),children:M.map((e,l)=>(0,a.jsx)(ek.Z,{value:e,onClick:()=>K(e),children:e},l))})]}),(0,a.jsxs)(el.Z,{children:["Retry Policy for ",U]}),(0,a.jsx)(ee.Z,{className:"mb-6",children:"How many retries should be attempted based on the Exception"}),e8&&(0,a.jsx)("table",{children:(0,a.jsx)("tbody",{children:Object.entries(e8).map((e,l)=>{var t;let[s,r]=e,n=null==eC?void 0:null===(t=eC[U])||void 0===t?void 0:t[r];return null==n&&(n=eO),(0,a.jsxs)("tr",{className:"flex justify-between items-center mt-2",children:[(0,a.jsx)("td",{children:(0,a.jsx)(ee.Z,{children:s})}),(0,a.jsx)("td",{children:(0,a.jsx)(eo.Z,{className:"ml-5",value:n,min:0,step:1,onChange:e=>{eP(l=>{var t;let s=null!==(t=null==l?void 0:l[U])&&void 0!==t?t:{};return{...null!=l?l:{},[U]:{...s,[r]:e}}})}})})]},l)})})}),(0,a.jsx)(J.Z,{className:"mt-6 mr-8",onClick:le,children:"Save"})]})]})]})})};let{Option:e6}=es.default;var e7=e=>{let{userID:l,accessToken:t,teams:s}=e,[r]=er.Z.useForm(),[o,i]=(0,n.useState)(!1),[c,d]=(0,n.useState)(null),[m,h]=(0,n.useState)([]);(0,n.useEffect)(()=>{(async()=>{try{let e=await A(t,l,"any"),s=[];for(let l=0;l{i(!1),r.resetFields()},p=()=>{i(!1),d(null),r.resetFields()},j=async e=>{try{u.ZP.info("Making API Call"),i(!0),console.log("formValues in create user:",e);let s=await g(t,null,e);console.log("user create Response:",s),d(s.key),u.ZP.success("API user Created"),r.resetFields(),localStorage.removeItem("userData"+l)}catch(e){console.error("Error creating the user:",e)}};return(0,a.jsxs)("div",{children:[(0,a.jsx)(J.Z,{className:"mx-auto",onClick:()=>i(!0),children:"+ Invite User"}),(0,a.jsxs)(ea.Z,{title:"Invite User",visible:o,width:800,footer:null,onOk:x,onCancel:p,children:[(0,a.jsx)(ee.Z,{className:"mb-1",children:"Invite a user to login to the Admin UI and create Keys"}),(0,a.jsx)(ee.Z,{className:"mb-6",children:(0,a.jsx)("b",{children:"Note: SSO Setup Required for this"})}),(0,a.jsxs)(er.Z,{form:r,onFinish:j,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsx)(er.Z.Item,{label:"User Email",name:"user_email",children:(0,a.jsx)(H.Z,{placeholder:""})}),(0,a.jsx)(er.Z.Item,{label:"Team ID",name:"team_id",children:(0,a.jsx)(es.default,{placeholder:"Select Team ID",style:{width:"100%"},children:s?s.map(e=>(0,a.jsx)(e6,{value:e.team_id,children:e.team_alias},e.team_id)):(0,a.jsx)(e6,{value:null,children:"Default Team"},"default")})}),(0,a.jsx)(er.Z.Item,{label:"Metadata",name:"metadata",children:(0,a.jsx)(en.Z.TextArea,{rows:4,placeholder:"Enter metadata as JSON"})}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(ei.ZP,{htmlType:"submit",children:"Create User"})})]})]}),c&&(0,a.jsxs)(ea.Z,{title:"User Created Successfully",visible:o,onOk:x,onCancel:p,footer:null,children:[(0,a.jsx)("p",{children:"User has been created to access your proxy. Please Ask them to Log In."}),(0,a.jsx)("br",{}),(0,a.jsx)("p",{children:(0,a.jsx)("b",{children:"Note: This Feature is only supported through SSO on the Admin UI"})})]})]})},e9=e=>{let{accessToken:l,token:t,keys:s,userRole:r,userID:o,teams:i,setKeys:c}=e,[d,m]=(0,n.useState)(null),[u,h]=(0,n.useState)(null),[x,p]=(0,n.useState)(0),[j,g]=n.useState(null),[y,f]=(0,n.useState)(null);return((0,n.useEffect)(()=>{if(!l||!t||!r||!o)return;let e=async()=>{try{let e=await Z(l,null,r,!0,x,25);console.log("user data response:",e),m(e)}catch(e){console.error("There was an error fetching the model data",e)}};l&&t&&r&&o&&e()},[l,t,r,o,x]),d&&l&&t&&r&&o)?(0,a.jsx)("div",{style:{width:"100%"},children:(0,a.jsxs)(W.Z,{className:"gap-2 p-2 h-[80vh] w-full mt-8",children:[(0,a.jsx)(e7,{userID:o,accessToken:l,teams:i}),(0,a.jsxs)(ep.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[80vh] mb-4",children:[(0,a.jsx)("div",{className:"mb-4 mt-1",children:(0,a.jsx)(ee.Z,{children:"These are Users on LiteLLM that created API Keys. Automatically tracked by LiteLLM"})}),(0,a.jsx)(eM.Z,{children:(0,a.jsxs)(eD.Z,{children:[(0,a.jsx)(eU.Z,{children:(0,a.jsxs)(eg.Z,{className:"mt-5",children:[(0,a.jsx)(eZ.Z,{children:(0,a.jsxs)(ew.Z,{children:[(0,a.jsx)(e_.Z,{children:"User ID"}),(0,a.jsx)(e_.Z,{children:"User Email"}),(0,a.jsx)(e_.Z,{children:"User Models"}),(0,a.jsx)(e_.Z,{children:"User Spend ($ USD)"}),(0,a.jsx)(e_.Z,{children:"User Max Budget ($ USD)"}),(0,a.jsx)(e_.Z,{children:"User API Key Aliases"})]})}),(0,a.jsx)(ey.Z,{children:d.map(e=>{var l;return(0,a.jsxs)(ew.Z,{children:[(0,a.jsx)(ef.Z,{children:e.user_id}),(0,a.jsx)(ef.Z,{children:e.user_email}),(0,a.jsx)(ef.Z,{children:e.models&&e.models.length>0?e.models:"All Models"}),(0,a.jsx)(ef.Z,{children:e.spend?null===(l=e.spend)||void 0===l?void 0:l.toFixed(2):0}),(0,a.jsx)(ef.Z,{children:e.max_budget?e.max_budget:"Unlimited"}),(0,a.jsx)(ef.Z,{children:(0,a.jsx)(W.Z,{numItems:2,children:e&&e.key_aliases&&e.key_aliases.filter(e=>null!==e).length>0?(0,a.jsx)(ex.Z,{size:"xs",color:"indigo",children:e.key_aliases.filter(e=>null!==e).join(", ")}):(0,a.jsx)(ex.Z,{size:"xs",color:"gray",children:"No Keys"})})})]},e.user_id)})})]})}),(0,a.jsx)(eU.Z,{children:(0,a.jsxs)("div",{className:"flex items-center",children:[(0,a.jsx)("div",{className:"flex-1"}),(0,a.jsx)("div",{className:"flex-1 flex justify-between items-center"})]})})]})})]}),function(){if(!d)return null;let e=Math.ceil(d.length/25);return(0,a.jsxs)("div",{className:"flex justify-between items-center",children:[(0,a.jsxs)("div",{children:["Showing Page ",x+1," of ",e]}),(0,a.jsxs)("div",{className:"flex",children:[(0,a.jsx)("button",{className:"bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-l focus:outline-none",disabled:0===x,onClick:()=>p(x-1),children:"โ† Prev"}),(0,a.jsx)("button",{className:"bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-r focus:outline-none",onClick:()=>{p(x+1)},children:"Next โ†’"})]})]})}()]})}):(0,a.jsx)("div",{children:"Loading..."})},le=e=>{let{teams:l,searchParams:t,accessToken:s,setTeams:r,userID:o,userRole:i}=e,[c]=er.Z.useForm(),[d]=er.Z.useForm(),{Title:m,Paragraph:h}=eT.default,[x,p]=(0,n.useState)(""),[j,g]=(0,n.useState)(!1),[y,Z]=(0,n.useState)(l?l[0]:null),[w,b]=(0,n.useState)(!1),[k,v]=(0,n.useState)(!1),[S,N]=(0,n.useState)([]),[E,I]=(0,n.useState)(!1),[C,P]=(0,n.useState)(null),[T,O]=(0,n.useState)({}),F=e=>{Z(e),g(!0)},R=async e=>{let t=e.team_id;if(console.log("handleEditSubmit:",e),null==s)return;let a=await U(s,e);l&&r(l.map(e=>e.team_id===t?a.data:e)),u.ZP.success("Team updated successfully"),g(!1),Z(null)},L=async e=>{P(e),I(!0)},D=async()=>{if(null!=C&&null!=l&&null!=s){try{await f(s,C);let e=l.filter(e=>e.team_id!==C);r(e)}catch(e){console.error("Error deleting the team:",e)}I(!1),P(null)}};(0,n.useEffect)(()=>{let e=async()=>{try{if(null===o||null===i||null===s||null===l)return;console.log("fetching team info:");let e={};for(let t=0;t<(null==l?void 0:l.length);t++){let r=l[t].team_id,a=await _(s,r);console.log("teamInfo response:",a),null!==a&&(e={...e,[r]:a})}O(e)}catch(e){console.error("Error fetching team info:",e)}};(async()=>{try{if(null===o||null===i)return;if(null!==s){let e=(await A(s,o,i)).data.map(e=>e.id);console.log("available_model_names:",e),N(e)}}catch(e){console.error("Error fetching user models:",e)}})(),e()},[s,o,i,l]);let B=async e=>{try{if(null!=s){var t;let a=null==e?void 0:e.team_alias;if((null!==(t=null==l?void 0:l.map(e=>e.team_alias))&&void 0!==t?t:[]).includes(a))throw Error("Team alias ".concat(a," already exists, please pick another alias"));u.ZP.info("Creating Team");let n=await M(s,e);null!==l?r([...l,n]):r([n]),console.log("response for team create call: ".concat(n)),u.ZP.success("Team created"),b(!1)}}catch(e){console.error("Error creating the team:",e),u.ZP.error("Error creating the team: "+e,20)}},z=async e=>{try{if(null!=s&&null!=l){u.ZP.info("Adding Member");let t={role:"user",user_email:e.user_email,user_id:e.user_id},a=await K(s,y.team_id,t);console.log("response for team create call: ".concat(a.data));let n=l.findIndex(e=>(console.log("team.team_id=".concat(e.team_id,"; response.data.team_id=").concat(a.data.team_id)),e.team_id===a.data.team_id));if(console.log("foundIndex: ".concat(n)),-1!==n){let e=[...l];e[n]=a.data,r(e),Z(a.data)}v(!1)}}catch(e){console.error("Error creating the team:",e)}};return console.log("received teams ".concat(JSON.stringify(l))),(0,a.jsx)("div",{className:"w-full mx-4",children:(0,a.jsxs)(W.Z,{numItems:1,className:"gap-2 p-8 h-[75vh] w-full mt-2",children:[(0,a.jsxs)(Y.Z,{numColSpan:1,children:[(0,a.jsx)(m,{level:4,children:"All Teams"}),(0,a.jsxs)(ep.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:[(0,a.jsxs)(eg.Z,{children:[(0,a.jsx)(eZ.Z,{children:(0,a.jsxs)(ew.Z,{children:[(0,a.jsx)(e_.Z,{children:"Team Name"}),(0,a.jsx)(e_.Z,{children:"Spend (USD)"}),(0,a.jsx)(e_.Z,{children:"Budget (USD)"}),(0,a.jsx)(e_.Z,{children:"Models"}),(0,a.jsx)(e_.Z,{children:"TPM / RPM Limits"}),(0,a.jsx)(e_.Z,{children:"Info"})]})}),(0,a.jsx)(ey.Z,{children:l&&l.length>0?l.map(e=>(0,a.jsxs)(ew.Z,{children:[(0,a.jsx)(ef.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:e.team_alias}),(0,a.jsx)(ef.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:e.spend}),(0,a.jsx)(ef.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:e.max_budget?e.max_budget:"No limit"}),(0,a.jsx)(ef.Z,{style:{maxWidth:"8-x",whiteSpace:"pre-wrap",overflow:"hidden"},children:Array.isArray(e.models)?(0,a.jsx)("div",{style:{display:"flex",flexDirection:"column"},children:0===e.models.length?(0,a.jsx)(ex.Z,{size:"xs",className:"mb-1",color:"red",children:(0,a.jsx)(ee.Z,{children:"All Proxy Models"})}):e.models.map((e,l)=>"all-proxy-models"===e?(0,a.jsx)(ex.Z,{size:"xs",className:"mb-1",color:"red",children:(0,a.jsx)(ee.Z,{children:"All Proxy Models"})},l):(0,a.jsx)(ex.Z,{size:"xs",className:"mb-1",color:"blue",children:(0,a.jsx)(ee.Z,{children:e.length>30?"".concat(e.slice(0,30),"..."):e})},l))}):null}),(0,a.jsx)(ef.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,a.jsxs)(ee.Z,{children:["TPM: ",e.tpm_limit?e.tpm_limit:"Unlimited"," ",(0,a.jsx)("br",{}),"RPM:"," ",e.rpm_limit?e.rpm_limit:"Unlimited"]})}),(0,a.jsxs)(ef.Z,{children:[(0,a.jsxs)(ee.Z,{children:[T&&e.team_id&&T[e.team_id]&&T[e.team_id].keys&&T[e.team_id].keys.length," ","Keys"]}),(0,a.jsxs)(ee.Z,{children:[T&&e.team_id&&T[e.team_id]&&T[e.team_id].team_info&&T[e.team_id].team_info.members_with_roles&&T[e.team_id].team_info.members_with_roles.length," ","Members"]})]}),(0,a.jsxs)(ef.Z,{children:[(0,a.jsx)(ej.Z,{icon:eu.Z,size:"sm",onClick:()=>F(e)}),(0,a.jsx)(ej.Z,{onClick:()=>L(e.team_id),icon:eh.Z,size:"sm"})]})]},e.team_id)):null})]}),E&&(0,a.jsx)("div",{className:"fixed z-10 inset-0 overflow-y-auto",children:(0,a.jsxs)("div",{className:"flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0",children:[(0,a.jsx)("div",{className:"fixed inset-0 transition-opacity","aria-hidden":"true",children:(0,a.jsx)("div",{className:"absolute inset-0 bg-gray-500 opacity-75"})}),(0,a.jsx)("span",{className:"hidden sm:inline-block sm:align-middle sm:h-screen","aria-hidden":"true",children:"โ€‹"}),(0,a.jsxs)("div",{className:"inline-block align-bottom bg-white rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full",children:[(0,a.jsx)("div",{className:"bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4",children:(0,a.jsx)("div",{className:"sm:flex sm:items-start",children:(0,a.jsxs)("div",{className:"mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left",children:[(0,a.jsx)("h3",{className:"text-lg leading-6 font-medium text-gray-900",children:"Delete Team"}),(0,a.jsx)("div",{className:"mt-2",children:(0,a.jsx)("p",{className:"text-sm text-gray-500",children:"Are you sure you want to delete this team ?"})})]})})}),(0,a.jsxs)("div",{className:"bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse",children:[(0,a.jsx)(J.Z,{onClick:D,color:"red",className:"ml-2",children:"Delete"}),(0,a.jsx)(J.Z,{onClick:()=>{I(!1),P(null)},children:"Cancel"})]})]})]})})]})]}),(0,a.jsxs)(Y.Z,{numColSpan:1,children:[(0,a.jsx)(J.Z,{className:"mx-auto",onClick:()=>b(!0),children:"+ Create New Team"}),(0,a.jsx)(ea.Z,{title:"Create Team",visible:w,width:800,footer:null,onOk:()=>{b(!1),c.resetFields()},onCancel:()=>{b(!1),c.resetFields()},children:(0,a.jsxs)(er.Z,{form:c,onFinish:B,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(er.Z.Item,{label:"Team Name",name:"team_alias",rules:[{required:!0,message:"Please input a team name"}],children:(0,a.jsx)(H.Z,{placeholder:""})}),(0,a.jsx)(er.Z.Item,{label:"Models",name:"models",children:(0,a.jsxs)(es.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:[(0,a.jsx)(es.default.Option,{value:"all-proxy-models",children:"All Proxy Models"},"all-proxy-models"),S.map(e=>(0,a.jsx)(es.default.Option,{value:e,children:e},e))]})}),(0,a.jsx)(er.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,a.jsx)(eo.Z,{step:.01,precision:2,width:200})}),(0,a.jsx)(er.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,a.jsx)(eo.Z,{step:1,width:400})}),(0,a.jsx)(er.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,a.jsx)(eo.Z,{step:1,width:400})})]}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(ei.ZP,{htmlType:"submit",children:"Create Team"})})]})})]}),(0,a.jsxs)(Y.Z,{numColSpan:1,children:[(0,a.jsx)(m,{level:4,children:"Team Members"}),(0,a.jsx)(h,{children:"If you belong to multiple teams, this setting controls which teams members you see."}),l&&l.length>0?(0,a.jsx)(eb.Z,{defaultValue:"0",children:l.map((e,l)=>(0,a.jsx)(ek.Z,{value:String(l),onClick:()=>{Z(e)},children:e.team_alias},l))}):(0,a.jsxs)(h,{children:["No team created. ",(0,a.jsx)("b",{children:"Defaulting to personal account."})]})]}),(0,a.jsxs)(Y.Z,{numColSpan:1,children:[(0,a.jsx)(ep.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,a.jsxs)(eg.Z,{children:[(0,a.jsx)(eZ.Z,{children:(0,a.jsxs)(ew.Z,{children:[(0,a.jsx)(e_.Z,{children:"Member Name"}),(0,a.jsx)(e_.Z,{children:"Role"})]})}),(0,a.jsx)(ey.Z,{children:y?y.members_with_roles.map((e,l)=>(0,a.jsxs)(ew.Z,{children:[(0,a.jsx)(ef.Z,{children:e.user_email?e.user_email:e.user_id?e.user_id:null}),(0,a.jsx)(ef.Z,{children:e.role})]},l)):null})]})}),y&&(0,a.jsx)(e=>{let{visible:l,onCancel:t,team:s,onSubmit:r}=e,[n]=er.Z.useForm();return(0,a.jsx)(ea.Z,{title:"Edit Team",visible:l,width:800,footer:null,onOk:()=>{n.validateFields().then(e=>{r({...e,team_id:s.team_id}),n.resetFields()}).catch(e=>{console.error("Validation failed:",e)})},onCancel:t,children:(0,a.jsxs)(er.Z,{form:n,onFinish:R,initialValues:s,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(er.Z.Item,{label:"Team Name",name:"team_alias",rules:[{required:!0,message:"Please input a team name"}],children:(0,a.jsx)(en.Z,{})}),(0,a.jsx)(er.Z.Item,{label:"Models",name:"models",children:(0,a.jsxs)(es.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:[(0,a.jsx)(es.default.Option,{value:"all-proxy-models",children:"All Proxy Models"},"all-proxy-models"),S&&S.map(e=>(0,a.jsx)(es.default.Option,{value:e,children:e},e))]})}),(0,a.jsx)(er.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,a.jsx)(eo.Z,{step:.01,precision:2,width:200})}),(0,a.jsx)(er.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,a.jsx)(eo.Z,{step:1,width:400})}),(0,a.jsx)(er.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,a.jsx)(eo.Z,{step:1,width:400})}),(0,a.jsx)(er.Z.Item,{label:"Requests per minute Limit (RPM)",name:"team_id",hidden:!0})]}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(ei.ZP,{htmlType:"submit",children:"Edit Team"})})]})})},{visible:j,onCancel:()=>{g(!1),Z(null)},team:y,onSubmit:R})]}),(0,a.jsxs)(Y.Z,{numColSpan:1,children:[(0,a.jsx)(J.Z,{className:"mx-auto mb-5",onClick:()=>v(!0),children:"+ Add member"}),(0,a.jsx)(ea.Z,{title:"Add member",visible:k,width:800,footer:null,onOk:()=>{v(!1),d.resetFields()},onCancel:()=>{v(!1),d.resetFields()},children:(0,a.jsxs)(er.Z,{form:c,onFinish:z,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(er.Z.Item,{label:"Email",name:"user_email",className:"mb-4",children:(0,a.jsx)(en.Z,{name:"user_email",className:"px-3 py-2 border rounded-md w-full"})}),(0,a.jsx)("div",{className:"text-center mb-4",children:"OR"}),(0,a.jsx)(er.Z.Item,{label:"User ID",name:"user_id",className:"mb-4",children:(0,a.jsx)(en.Z,{name:"user_id",className:"px-3 py-2 border rounded-md w-full"})})]}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(ei.ZP,{htmlType:"submit",children:"Add member"})})]})})]})]})})},ll=t(18190),lt=e=>{let l,{searchParams:t,accessToken:s,showSSOBanner:r}=e,[o]=er.Z.useForm(),[i]=er.Z.useForm(),{Title:c,Paragraph:d}=eT.default,[m,h]=(0,n.useState)(""),[x,p]=(0,n.useState)(null),[j,g]=(0,n.useState)(!1),[y,f]=(0,n.useState)(!1),[Z,_]=(0,n.useState)(!1),[w,b]=(0,n.useState)(!1),[k,v]=(0,n.useState)(!1);try{l=window.location.origin}catch(e){l=""}l+="/fallback/login";let S=()=>{v(!1)},A=["proxy_admin","proxy_admin_viewer"];(0,n.useEffect)(()=>{(async()=>{if(null!=s){let e=[],l=await R(s,"proxy_admin_viewer");l.forEach(l=>{e.push({user_role:l.user_role,user_id:l.user_id,user_email:l.user_email})}),console.log("proxy viewers: ".concat(l));let t=await R(s,"proxy_admin");t.forEach(l=>{e.push({user_role:l.user_role,user_id:l.user_id,user_email:l.user_email})}),console.log("proxy admins: ".concat(t)),console.log("combinedList: ".concat(e)),p(e)}})()},[s]);let N=()=>{_(!1),i.resetFields()},E=()=>{_(!1),i.resetFields()},I=e=>(0,a.jsxs)(er.Z,{form:o,onFinish:e,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(er.Z.Item,{label:"Email",name:"user_email",className:"mb-4",children:(0,a.jsx)(en.Z,{name:"user_email",className:"px-3 py-2 border rounded-md w-full"})}),(0,a.jsx)("div",{className:"text-center mb-4",children:"OR"}),(0,a.jsx)(er.Z.Item,{label:"User ID",name:"user_id",className:"mb-4",children:(0,a.jsx)(en.Z,{name:"user_id",className:"px-3 py-2 border rounded-md w-full"})})]}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(ei.ZP,{htmlType:"submit",children:"Add member"})})]}),C=(e,l,t)=>(0,a.jsxs)(er.Z,{form:o,onFinish:e,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(er.Z.Item,{rules:[{required:!0,message:"Required"}],label:"User Role",name:"user_role",labelCol:{span:10},labelAlign:"left",children:(0,a.jsx)(eb.Z,{value:l,children:A.map((e,l)=>(0,a.jsx)(ek.Z,{value:e,children:e},l))})}),(0,a.jsx)(er.Z.Item,{label:"Team ID",name:"user_id",hidden:!0,initialValue:t,valuePropName:"user_id",className:"mt-8",children:(0,a.jsx)(en.Z,{value:t,disabled:!0})})]}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(ei.ZP,{htmlType:"submit",children:"Update role"})})]}),P=async e=>{try{if(null!=s&&null!=x){u.ZP.info("Making API Call");let l=await B(s,e,null);console.log("response for team create call: ".concat(l));let t=x.findIndex(e=>(console.log("user.user_id=".concat(e.user_id,"; response.user_id=").concat(l.user_id)),e.user_id===l.user_id));console.log("foundIndex: ".concat(t)),-1==t&&(console.log("updates admin with new user"),x.push(l),p(x)),u.ZP.success("Refresh tab to see updated user role"),_(!1)}}catch(e){console.error("Error creating the key:",e)}},T=async e=>{try{if(null!=s&&null!=x){u.ZP.info("Making API Call");let l=await B(s,e,"proxy_admin_viewer");console.log("response for team create call: ".concat(l));let t=x.findIndex(e=>(console.log("user.user_id=".concat(e.user_id,"; response.user_id=").concat(l.user_id)),e.user_id===l.user_id));console.log("foundIndex: ".concat(t)),-1==t&&(console.log("updates admin with new user"),x.push(l),p(x)),g(!1)}}catch(e){console.error("Error creating the key:",e)}},O=async e=>{try{if(null!=s&&null!=x){u.ZP.info("Making API Call"),e.user_email,e.user_id;let l=await B(s,e,"proxy_admin");console.log("response for team create call: ".concat(l));let t=x.findIndex(e=>(console.log("user.user_id=".concat(e.user_id,"; response.user_id=").concat(l.user_id)),e.user_id===l.user_id));console.log("foundIndex: ".concat(t)),-1==t&&(console.log("updates admin with new user"),x.push(l),p(x)),f(!1)}}catch(e){console.error("Error creating the key:",e)}},F=async e=>{null!=s&&V(s,{environment_variables:{PROXY_BASE_URL:e.proxy_base_url,GOOGLE_CLIENT_ID:e.google_client_id,GOOGLE_CLIENT_SECRET:e.google_client_secret}})};return console.log("admins: ".concat(null==x?void 0:x.length)),(0,a.jsxs)("div",{className:"w-full m-2 mt-2 p-8",children:[(0,a.jsx)(c,{level:4,children:"Admin Access "}),(0,a.jsxs)(d,{children:[r&&(0,a.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/ui#restrict-ui-access",children:"Requires SSO Setup"}),(0,a.jsx)("br",{}),(0,a.jsx)("b",{children:"Proxy Admin: "})," Can create keys, teams, users, add models, etc. ",(0,a.jsx)("br",{}),(0,a.jsx)("b",{children:"Proxy Admin Viewer: "}),"Can just view spend. They cannot create keys, teams or grant users access to new models."," "]}),(0,a.jsxs)(W.Z,{numItems:1,className:"gap-2 p-2 w-full",children:[(0,a.jsx)(Y.Z,{numColSpan:1,children:(0,a.jsx)(ep.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,a.jsxs)(eg.Z,{children:[(0,a.jsx)(eZ.Z,{children:(0,a.jsxs)(ew.Z,{children:[(0,a.jsx)(e_.Z,{children:"Member Name"}),(0,a.jsx)(e_.Z,{children:"Role"})]})}),(0,a.jsx)(ey.Z,{children:x?x.map((e,l)=>(0,a.jsxs)(ew.Z,{children:[(0,a.jsx)(ef.Z,{children:e.user_email?e.user_email:e.user_id?e.user_id:null}),(0,a.jsx)(ef.Z,{children:e.user_role}),(0,a.jsxs)(ef.Z,{children:[(0,a.jsx)(ej.Z,{icon:eu.Z,size:"sm",onClick:()=>_(!0)}),(0,a.jsx)(ea.Z,{title:"Update role",visible:Z,width:800,footer:null,onOk:N,onCancel:E,children:C(P,e.user_role,e.user_id)})]})]},l)):null})]})})}),(0,a.jsx)(Y.Z,{numColSpan:1,children:(0,a.jsxs)("div",{className:"flex justify-start",children:[(0,a.jsx)(J.Z,{className:"mr-4 mb-5",onClick:()=>f(!0),children:"+ Add admin"}),(0,a.jsx)(ea.Z,{title:"Add admin",visible:y,width:800,footer:null,onOk:()=>{f(!1),i.resetFields()},onCancel:()=>{f(!1),i.resetFields()},children:I(O)}),(0,a.jsx)(J.Z,{className:"mb-5",onClick:()=>g(!0),children:"+ Add viewer"}),(0,a.jsx)(ea.Z,{title:"Add viewer",visible:j,width:800,footer:null,onOk:()=>{g(!1),i.resetFields()},onCancel:()=>{g(!1),i.resetFields()},children:I(T)})]})})]}),(0,a.jsxs)(W.Z,{children:[(0,a.jsx)(c,{level:4,children:"Add SSO"}),(0,a.jsxs)("div",{className:"flex justify-start mb-4",children:[(0,a.jsx)(J.Z,{onClick:()=>b(!0),children:"Add SSO"}),(0,a.jsx)(ea.Z,{title:"Add SSO",visible:w,width:800,footer:null,onOk:()=>{b(!1),o.resetFields()},onCancel:()=>{b(!1),o.resetFields()},children:(0,a.jsxs)(er.Z,{form:o,onFinish:e=>{O(e),F(e),b(!1),v(!0)},labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(er.Z.Item,{label:"Admin Email",name:"user_email",rules:[{required:!0,message:"Please enter the email of the proxy admin"}],children:(0,a.jsx)(en.Z,{})}),(0,a.jsx)(er.Z.Item,{label:"PROXY BASE URL",name:"proxy_base_url",rules:[{required:!0,message:"Please enter the proxy base url"}],children:(0,a.jsx)(en.Z,{})}),(0,a.jsx)(er.Z.Item,{label:"GOOGLE CLIENT ID",name:"google_client_id",rules:[{required:!0,message:"Please enter the google client id"}],children:(0,a.jsx)(en.Z.Password,{})}),(0,a.jsx)(er.Z.Item,{label:"GOOGLE CLIENT SECRET",name:"google_client_secret",rules:[{required:!0,message:"Please enter the google client secret"}],children:(0,a.jsx)(en.Z.Password,{})})]}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(ei.ZP,{htmlType:"submit",children:"Save"})})]})}),(0,a.jsxs)(ea.Z,{title:"SSO Setup Instructions",visible:k,width:800,footer:null,onOk:S,onCancel:()=>{v(!1)},children:[(0,a.jsx)("p",{children:"Follow these steps to complete the SSO setup:"}),(0,a.jsx)(ee.Z,{className:"mt-2",children:"1. DO NOT Exit this TAB"}),(0,a.jsx)(ee.Z,{className:"mt-2",children:"2. Open a new tab, visit your proxy base url"}),(0,a.jsx)(ee.Z,{className:"mt-2",children:"3. Confirm your SSO is configured correctly and you can login on the new Tab"}),(0,a.jsx)(ee.Z,{className:"mt-2",children:"4. If Step 3 is successful, you can close this tab"}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(ei.ZP,{onClick:S,children:"Done"})})]})]}),(0,a.jsxs)(ll.Z,{title:"Login without SSO",color:"teal",children:["If you need to login without sso, you can access ",(0,a.jsxs)("a",{href:l,target:"_blank",children:[(0,a.jsx)("b",{children:l})," "]})]})]})]})},ls=t(42556);let lr=[{name:"slack",variables:{LANGFUSE_HOST:null,LANGFUSE_PUBLIC_KEY:null,LANGFUSE_SECRET_KEY:null,OPENMETER_API_KEY:null,SLACK_WEBHOOK_URL:null}},{name:"langfuse",variables:{LANGFUSE_HOST:null,LANGFUSE_PUBLIC_KEY:null,LANGFUSE_SECRET_KEY:null,OPENMETER_API_KEY:null,SLACK_WEBHOOK_URL:null}},{name:"openmeter",variables:{LANGFUSE_HOST:null,LANGFUSE_PUBLIC_KEY:null,LANGFUSE_SECRET_KEY:null,OPENMETER_API_KEY:null,SLACK_WEBHOOK_URL:null}}];var la=e=>{let{accessToken:l,userRole:t,userID:s}=e,[r,o]=(0,n.useState)(lr),[i,c]=(0,n.useState)([]),[d,m]=(0,n.useState)(!1),[h]=er.Z.useForm(),[x,p]=(0,n.useState)(null),[j,g]=(0,n.useState)([]),[y,f]=(0,n.useState)(""),[Z,_]=(0,n.useState)({}),[w,b]=(0,n.useState)([]),k=e=>{w.includes(e)?b(w.filter(l=>l!==e)):b([...w,e])},v={llm_exceptions:"LLM Exceptions",llm_too_slow:"LLM Responses Too Slow",llm_requests_hanging:"LLM Requests Hanging",budget_alerts:"Budget Alerts (API Keys, Users)",db_exceptions:"Database Exceptions (Read/Write)"};(0,n.useEffect)(()=>{l&&t&&s&&q(l,s,t).then(e=>{console.log("callbacks",e);let l=lr;o(l=l.map(l=>{let t=e.callbacks.find(e=>e.name===l.name);return t?{...l,variables:{...l.variables,...t.variables}}:l}));let t=e.alerts;if(console.log("alerts_data",t),t&&t.length>0){let e=t[0];console.log("_alert_info",e);let l=e.variables.SLACK_WEBHOOK_URL;console.log("catch_all_webhook",l),b(e.active_alerts),f(l),_(e.alerts_to_webhook)}c(t)})},[l,t,s]);let S=e=>w&&w.includes(e),A=e=>{if(!l)return;let t=Object.fromEntries(Object.entries(e.variables).map(e=>{var l;let[t,s]=e;return[t,(null===(l=document.querySelector('input[name="'.concat(t,'"]')))||void 0===l?void 0:l.value)||s]}));console.log("updatedVariables",t),console.log("updateAlertTypes",j);let s={environment_variables:t,litellm_settings:{success_callback:[e.name]}};try{V(l,s)}catch(e){u.ZP.error("Failed to update callback: "+e,20)}u.ZP.success("Callback updated successfully")},N=()=>{l&&h.validateFields().then(e=>{if(console.log("Form values:",e),"langfuse"===e.callback){V(l,{environment_variables:{LANGFUSE_PUBLIC_KEY:e.langfusePublicKey,LANGFUSE_SECRET_KEY:e.langfusePrivateKey},litellm_settings:{success_callback:[e.callback]}});let t={name:e.callback,variables:{SLACK_WEBHOOK_URL:null,LANGFUSE_HOST:null,LANGFUSE_PUBLIC_KEY:e.langfusePublicKey,LANGFUSE_SECRET_KEY:e.langfusePrivateKey,OPENMETER_API_KEY:null}};o(r?[...r,t]:[t])}else if("slack"===e.callback){console.log("values.slackWebhookUrl: ".concat(e.slackWebhookUrl)),V(l,{general_settings:{alerting:["slack"],alerting_threshold:300},environment_variables:{SLACK_WEBHOOK_URL:e.slackWebhookUrl}}),console.log("values.callback: ".concat(e.callback));let t={name:e.callback,variables:{SLACK_WEBHOOK_URL:e.slackWebhookUrl,LANGFUSE_HOST:null,LANGFUSE_PUBLIC_KEY:null,LANGFUSE_SECRET_KEY:null,OPENMETER_API_KEY:null}};o(r?[...r,t]:[t])}else if("openmeter"==e.callback){console.log("values.openMeterApiKey: ".concat(e.openMeterApiKey)),V(l,{environment_variables:{OPENMETER_API_KEY:e.openMeterApiKey},litellm_settings:{success_callback:[e.callback]}});let t={name:e.callback,variables:{SLACK_WEBHOOK_URL:null,LANGFUSE_HOST:null,LANGFUSE_PUBLIC_KEY:null,LANGFUSE_SECRET_KEY:null,OPENMETER_API_KEY:e.openMeterAPIKey}};o(r?[...r,t]:[t])}m(!1),h.resetFields(),p(null)})};return l?(console.log("callbacks: ".concat(r)),(0,a.jsxs)("div",{className:"w-full mx-4",children:[(0,a.jsxs)(W.Z,{numItems:1,className:"gap-2 p-8 w-full mt-2",children:[(0,a.jsx)(ll.Z,{title:"[UI] Presidio PII + Guardrails Coming Soon. https://docs.litellm.ai/docs/proxy/pii_masking",color:"sky"}),(0,a.jsxs)(eM.Z,{children:[(0,a.jsxs)(eL.Z,{variant:"line",defaultValue:"1",children:[(0,a.jsx)(eR.Z,{value:"1",children:"Logging Callbacks"}),(0,a.jsx)(eR.Z,{value:"2",children:"Alerting"})]}),(0,a.jsxs)(eD.Z,{children:[(0,a.jsx)(eU.Z,{children:(0,a.jsx)(ep.Z,{children:(0,a.jsxs)(eg.Z,{children:[(0,a.jsx)(eZ.Z,{children:(0,a.jsxs)(ew.Z,{children:[(0,a.jsx)(e_.Z,{children:"Callback"}),(0,a.jsx)(e_.Z,{children:"Callback Env Vars"})]})}),(0,a.jsx)(ey.Z,{children:r.filter(e=>"slack"!==e.name).map((e,t)=>{var s;return(0,a.jsxs)(ew.Z,{children:[(0,a.jsx)(ef.Z,{children:(0,a.jsx)(ex.Z,{color:"emerald",children:e.name})}),(0,a.jsxs)(ef.Z,{children:[(0,a.jsx)("ul",{children:Object.entries(null!==(s=e.variables)&&void 0!==s?s:{}).filter(l=>{let[t,s]=l;return t.toLowerCase().includes(e.name)}).map(e=>{let[l,t]=e;return(0,a.jsxs)("li",{children:[(0,a.jsx)(ee.Z,{className:"mt-2",children:l}),"LANGFUSE_HOST"===l?(0,a.jsx)("p",{children:"default value=https://cloud.langfuse.com"}):(0,a.jsx)("div",{}),(0,a.jsx)(H.Z,{name:l,defaultValue:t,type:"password"})]},l)})}),(0,a.jsx)(J.Z,{className:"mt-2",onClick:()=>A(e),children:"Save Changes"}),(0,a.jsx)(J.Z,{onClick:()=>z(l,e.name),className:"mx-2",children:"Test Callback"})]})]},t)})})]})})}),(0,a.jsx)(eU.Z,{children:(0,a.jsxs)(ep.Z,{children:[(0,a.jsxs)(ee.Z,{className:"my-2",children:["Alerts are only supported for Slack Webhook URLs. Get your webhook urls from ",(0,a.jsx)("a",{href:"https://api.slack.com/messaging/webhooks",target:"_blank",style:{color:"blue"},children:"here"})]}),(0,a.jsxs)(eg.Z,{children:[(0,a.jsx)(eZ.Z,{children:(0,a.jsxs)(ew.Z,{children:[(0,a.jsx)(e_.Z,{}),(0,a.jsx)(e_.Z,{}),(0,a.jsx)(e_.Z,{children:"Slack Webhook URL"})]})}),(0,a.jsx)(ey.Z,{children:Object.entries(v).map((e,l)=>{let[t,s]=e;return(0,a.jsxs)(ew.Z,{children:[(0,a.jsx)(ef.Z,{children:(0,a.jsx)(ls.Z,{id:"switch",name:"switch",checked:S(t),onChange:()=>k(t)})}),(0,a.jsx)(ef.Z,{children:(0,a.jsx)(ee.Z,{children:s})}),(0,a.jsx)(ef.Z,{children:(0,a.jsx)(H.Z,{name:t,type:"password",defaultValue:Z&&Z[t]?Z[t]:y})})]},l)})})]}),(0,a.jsx)(J.Z,{size:"xs",className:"mt-2",onClick:()=>{if(!l)return;let e={};Object.entries(v).forEach(l=>{let[t,s]=l,r=document.querySelector('input[name="'.concat(t,'"]'));console.log("key",t),console.log("webhookInput",r);let a=(null==r?void 0:r.value)||"";console.log("newWebhookValue",a),e[t]=a}),console.log("updatedAlertToWebhooks",e);let t={general_settings:{alert_to_webhook_url:e,alert_types:w}};console.log("payload",t);try{V(l,t)}catch(e){u.ZP.error("Failed to update alerts: "+e,20)}u.ZP.success("Alerts updated successfully")},children:"Save Changes"}),(0,a.jsx)(J.Z,{onClick:()=>z(l,"slack"),className:"mx-2",children:"Test Alerts"})]})})]})]})]}),(0,a.jsx)(ea.Z,{title:"Add Callback",visible:d,onOk:N,width:800,onCancel:()=>{m(!1),h.resetFields(),p(null)},footer:null,children:(0,a.jsxs)(er.Z,{form:h,layout:"vertical",onFinish:N,children:[(0,a.jsx)(er.Z.Item,{label:"Callback",name:"callback",rules:[{required:!0,message:"Please select a callback"}],children:(0,a.jsxs)(es.default,{onChange:e=>{p(e)},children:[(0,a.jsx)(es.default.Option,{value:"langfuse",children:"langfuse"}),(0,a.jsx)(es.default.Option,{value:"openmeter",children:"openmeter"})]})}),"langfuse"===x&&(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(er.Z.Item,{label:"LANGFUSE_PUBLIC_KEY",name:"langfusePublicKey",rules:[{required:!0,message:"Please enter the public key"}],children:(0,a.jsx)(H.Z,{type:"password"})}),(0,a.jsx)(er.Z.Item,{label:"LANGFUSE_PRIVATE_KEY",name:"langfusePrivateKey",rules:[{required:!0,message:"Please enter the private key"}],children:(0,a.jsx)(H.Z,{type:"password"})})]}),"openmeter"==x&&(0,a.jsx)(a.Fragment,{children:(0,a.jsx)(er.Z.Item,{label:"OPENMETER_API_KEY",name:"openMeterApiKey",rules:[{required:!0,message:"Please enter the openmeter api key"}],children:(0,a.jsx)(H.Z,{type:"password"})})}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(ei.ZP,{htmlType:"submit",children:"Save"})})]})})]})):null};let{Option:ln}=es.default;var lo=e=>{let{models:l,accessToken:t,routerSettings:s,setRouterSettings:r}=e,[o]=er.Z.useForm(),[i,c]=(0,n.useState)(!1),[d,m]=(0,n.useState)("");return(0,a.jsxs)("div",{children:[(0,a.jsx)(J.Z,{className:"mx-auto",onClick:()=>c(!0),children:"+ Add Fallbacks"}),(0,a.jsx)(ea.Z,{title:"Add Fallbacks",visible:i,width:800,footer:null,onOk:()=>{c(!1),o.resetFields()},onCancel:()=>{c(!1),o.resetFields()},children:(0,a.jsxs)(er.Z,{form:o,onFinish:e=>{console.log(e);let{model_name:l,models:a}=e,n=[...s.fallbacks||[],{[l]:a}],i={...s,fallbacks:n};console.log(i);try{V(t,{router_settings:i}),r(i)}catch(e){u.ZP.error("Failed to update router settings: "+e,20)}u.ZP.success("router settings updated successfully"),c(!1),o.resetFields()},labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(er.Z.Item,{label:"Public Model Name",name:"model_name",rules:[{required:!0,message:"Set the model to fallback for"}],help:"required",children:(0,a.jsx)(eb.Z,{defaultValue:d,children:l&&l.map((e,l)=>(0,a.jsx)(ek.Z,{value:e,onClick:()=>m(e),children:e},l))})}),(0,a.jsx)(er.Z.Item,{label:"Fallback Models",name:"models",rules:[{required:!0,message:"Please select a model"}],help:"required",children:(0,a.jsx)(eK.Z,{value:l,children:l&&l.filter(e=>e!=d).map(e=>(0,a.jsx)(eB.Z,{value:e,children:e},e))})})]}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(ei.ZP,{htmlType:"submit",children:"Add Fallbacks"})})]})})]})},li=t(12968);async function lc(e,l){console.log("isLocal:",!1);let t=window.location.origin,s=new li.ZP.OpenAI({apiKey:l,baseURL:t,dangerouslyAllowBrowser:!0});try{let l=await s.chat.completions.create({model:e,messages:[{role:"user",content:"Hi, this is a test message"}],mock_testing_fallbacks:!0});u.ZP.success((0,a.jsxs)("span",{children:["Test model=",(0,a.jsx)("strong",{children:e}),", received model=",(0,a.jsx)("strong",{children:l.model}),". See ",(0,a.jsx)("a",{href:"#",onClick:()=>window.open("https://docs.litellm.ai/docs/proxy/reliability","_blank"),style:{textDecoration:"underline",color:"blue"},children:"curl"})]}))}catch(e){u.ZP.error("Error occurred while generating model response. Please try again. Error: ".concat(e),20)}}let ld={ttl:3600,lowest_latency_buffer:0},lm=e=>{let{selectedStrategy:l,strategyArgs:t,paramExplanation:s}=e;return(0,a.jsxs)($.Z,{children:[(0,a.jsx)(Q.Z,{className:"text-sm font-medium text-tremor-content-strong dark:text-dark-tremor-content-strong",children:"Routing Strategy Specific Args"}),(0,a.jsx)(X.Z,{children:"latency-based-routing"==l?(0,a.jsx)(ep.Z,{children:(0,a.jsxs)(eg.Z,{children:[(0,a.jsx)(eZ.Z,{children:(0,a.jsxs)(ew.Z,{children:[(0,a.jsx)(e_.Z,{children:"Setting"}),(0,a.jsx)(e_.Z,{children:"Value"})]})}),(0,a.jsx)(ey.Z,{children:Object.entries(t).map(e=>{let[l,t]=e;return(0,a.jsxs)(ew.Z,{children:[(0,a.jsxs)(ef.Z,{children:[(0,a.jsx)(ee.Z,{children:l}),(0,a.jsx)("p",{style:{fontSize:"0.65rem",color:"#808080",fontStyle:"italic"},className:"mt-1",children:s[l]})]}),(0,a.jsx)(ef.Z,{children:(0,a.jsx)(H.Z,{name:l,defaultValue:"object"==typeof t?JSON.stringify(t,null,2):t.toString()})})]},l)})})]})}):(0,a.jsx)(ee.Z,{children:"No specific settings"})})]})};var lu=e=>{let{accessToken:l,userRole:t,userID:s,modelData:r}=e,[o,i]=(0,n.useState)({}),[c,d]=(0,n.useState)(!1),[m]=er.Z.useForm(),[h,x]=(0,n.useState)(null),[p,j]=(0,n.useState)(null),[g,y]=(0,n.useState)(null),f={routing_strategy_args:"(dict) Arguments to pass to the routing strategy",routing_strategy:"(string) Routing strategy to use",allowed_fails:"(int) Number of times a deployment can fail before being added to cooldown",cooldown_time:"(int) time in seconds to cooldown a deployment after failure",num_retries:"(int) Number of retries for failed requests. Defaults to 0.",timeout:"(float) Timeout for requests. Defaults to None.",retry_after:"(int) Minimum time to wait before retrying a failed request",ttl:"(int) Sliding window to look back over when calculating the average latency of a deployment. Default - 1 hour (in seconds).",lowest_latency_buffer:"(float) Shuffle between deployments within this % of the lowest latency. Default - 0 (i.e. always pick lowest latency)."};(0,n.useEffect)(()=>{l&&t&&s&&q(l,s,t).then(e=>{console.log("callbacks",e),i(e.router_settings)})},[l,t,s]);let Z=async e=>{if(l){console.log("received key: ".concat(e)),console.log("routerSettings['fallbacks']: ".concat(o.fallbacks)),o.fallbacks.map(l=>(e in l&&delete l[e],l));try{await V(l,{router_settings:o}),i({...o}),j(o.routing_strategy),u.ZP.success("Router settings updated successfully")}catch(e){u.ZP.error("Failed to update router settings: "+e,20)}}},_=e=>{if(!l)return;console.log("router_settings",e);let t=Object.fromEntries(Object.entries(e).map(e=>{let[l,t]=e;if("routing_strategy_args"!==l&&"routing_strategy"!==l){var s;return[l,(null===(s=document.querySelector('input[name="'.concat(l,'"]')))||void 0===s?void 0:s.value)||t]}if("routing_strategy"==l)return[l,p];if("routing_strategy_args"==l&&"latency-based-routing"==p){let e={},l=document.querySelector('input[name="lowest_latency_buffer"]'),t=document.querySelector('input[name="ttl"]');return(null==l?void 0:l.value)&&(e.lowest_latency_buffer=Number(l.value)),(null==t?void 0:t.value)&&(e.ttl=Number(t.value)),console.log("setRoutingStrategyArgs: ".concat(e)),["routing_strategy_args",e]}return null}).filter(e=>null!=e));console.log("updatedVariables",t);try{V(l,{router_settings:t})}catch(e){u.ZP.error("Failed to update router settings: "+e,20)}u.ZP.success("router settings updated successfully")};return l?(0,a.jsx)("div",{className:"w-full mx-4",children:(0,a.jsxs)(eM.Z,{className:"gap-2 p-8 h-[75vh] w-full mt-2",children:[(0,a.jsxs)(eL.Z,{variant:"line",defaultValue:"1",children:[(0,a.jsx)(eR.Z,{value:"1",children:"General Settings"}),(0,a.jsx)(eR.Z,{value:"2",children:"Fallbacks"})]}),(0,a.jsxs)(eD.Z,{children:[(0,a.jsx)(eU.Z,{children:(0,a.jsxs)(W.Z,{numItems:1,className:"gap-2 p-8 w-full mt-2",children:[(0,a.jsx)(el.Z,{children:"Router Settings"}),(0,a.jsxs)(ep.Z,{children:[(0,a.jsxs)(eg.Z,{children:[(0,a.jsx)(eZ.Z,{children:(0,a.jsxs)(ew.Z,{children:[(0,a.jsx)(e_.Z,{children:"Setting"}),(0,a.jsx)(e_.Z,{children:"Value"})]})}),(0,a.jsx)(ey.Z,{children:Object.entries(o).filter(e=>{let[l,t]=e;return"fallbacks"!=l&&"context_window_fallbacks"!=l&&"routing_strategy_args"!=l}).map(e=>{let[l,t]=e;return(0,a.jsxs)(ew.Z,{children:[(0,a.jsxs)(ef.Z,{children:[(0,a.jsx)(ee.Z,{children:l}),(0,a.jsx)("p",{style:{fontSize:"0.65rem",color:"#808080",fontStyle:"italic"},className:"mt-1",children:f[l]})]}),(0,a.jsx)(ef.Z,{children:"routing_strategy"==l?(0,a.jsxs)(eb.Z,{defaultValue:t,className:"w-full max-w-md",onValueChange:j,children:[(0,a.jsx)(ek.Z,{value:"usage-based-routing",children:"usage-based-routing"}),(0,a.jsx)(ek.Z,{value:"latency-based-routing",children:"latency-based-routing"}),(0,a.jsx)(ek.Z,{value:"simple-shuffle",children:"simple-shuffle"})]}):(0,a.jsx)(H.Z,{name:l,defaultValue:"object"==typeof t?JSON.stringify(t,null,2):t.toString()})})]},l)})})]}),(0,a.jsx)(lm,{selectedStrategy:p,strategyArgs:o&&o.routing_strategy_args&&Object.keys(o.routing_strategy_args).length>0?o.routing_strategy_args:ld,paramExplanation:f})]}),(0,a.jsx)(Y.Z,{children:(0,a.jsx)(J.Z,{className:"mt-2",onClick:()=>_(o),children:"Save Changes"})})]})}),(0,a.jsxs)(eU.Z,{children:[(0,a.jsxs)(eg.Z,{children:[(0,a.jsx)(eZ.Z,{children:(0,a.jsxs)(ew.Z,{children:[(0,a.jsx)(e_.Z,{children:"Model Name"}),(0,a.jsx)(e_.Z,{children:"Fallbacks"})]})}),(0,a.jsx)(ey.Z,{children:o.fallbacks&&o.fallbacks.map((e,t)=>Object.entries(e).map(e=>{let[s,r]=e;return(0,a.jsxs)(ew.Z,{children:[(0,a.jsx)(ef.Z,{children:s}),(0,a.jsx)(ef.Z,{children:Array.isArray(r)?r.join(", "):r}),(0,a.jsx)(ef.Z,{children:(0,a.jsx)(J.Z,{onClick:()=>lc(s,l),children:"Test Fallback"})}),(0,a.jsx)(ef.Z,{children:(0,a.jsx)(ej.Z,{icon:eh.Z,size:"sm",onClick:()=>Z(s)})})]},t.toString()+s)}))})]}),(0,a.jsx)(lo,{models:(null==r?void 0:r.data)?r.data.map(e=>e.model_name):[],accessToken:l,routerSettings:o,setRouterSettings:i})]})]})]})}):null},lh=t(67951),lx=e=>{let{}=e;return(0,a.jsx)(a.Fragment,{children:(0,a.jsx)(W.Z,{className:"gap-2 p-8 h-[80vh] w-full mt-2",children:(0,a.jsxs)("div",{className:"mb-5",children:[(0,a.jsx)("p",{className:"text-2xl text-tremor-content-strong dark:text-dark-tremor-content-strong font-semibold",children:"OpenAI Compatible Proxy: API Reference"}),(0,a.jsx)(ee.Z,{className:"mt-2 mb-2",children:"LiteLLM is OpenAI Compatible. This means your API Key works with the OpenAI SDK. Just replace the base_url to point to your litellm proxy. Example Below "}),(0,a.jsxs)(eM.Z,{children:[(0,a.jsxs)(eL.Z,{children:[(0,a.jsx)(eR.Z,{children:"OpenAI Python SDK"}),(0,a.jsx)(eR.Z,{children:"LlamaIndex"}),(0,a.jsx)(eR.Z,{children:"Langchain Py"})]}),(0,a.jsxs)(eD.Z,{children:[(0,a.jsx)(eU.Z,{children:(0,a.jsx)(lh.Z,{language:"python",children:'\nimport openai\nclient = openai.OpenAI(\n api_key="your_api_key",\n base_url="http://0.0.0.0:4000" # LiteLLM Proxy is OpenAI compatible, Read More: https://docs.litellm.ai/docs/proxy/user_keys\n)\n\nresponse = client.chat.completions.create(\n model="gpt-3.5-turbo", # model to send to the proxy\n messages = [\n {\n "role": "user",\n "content": "this is a test request, write a short poem"\n }\n ]\n)\n\nprint(response)\n '})}),(0,a.jsx)(eU.Z,{children:(0,a.jsx)(lh.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,a.jsx)(eU.Z,{children:(0,a.jsx)(lh.Z,{language:"python",children:'\nfrom langchain.chat_models import ChatOpenAI\nfrom langchain.prompts.chat import (\n ChatPromptTemplate,\n HumanMessagePromptTemplate,\n SystemMessagePromptTemplate,\n)\nfrom langchain.schema import HumanMessage, SystemMessage\n\nchat = ChatOpenAI(\n openai_api_base="http://0.0.0.0:4000",\n model = "gpt-3.5-turbo",\n temperature=0.1\n)\n\nmessages = [\n SystemMessage(\n content="You are a helpful assistant that im using to make a test request to."\n ),\n HumanMessage(\n content="test from litellm. tell me why it\'s amazing in 1 sentence"\n ),\n]\nresponse = chat(messages)\n\nprint(response)\n\n '})})]})]})]})})})};async function lp(e,l,t,s){console.log("isLocal:",!1);let r=window.location.origin,a=new li.ZP.OpenAI({apiKey:s,baseURL:r,dangerouslyAllowBrowser:!0});try{for await(let s of(await a.chat.completions.create({model:t,stream:!0,messages:[{role:"user",content:e}]})))console.log(s),s.choices[0].delta.content&&l(s.choices[0].delta.content)}catch(e){u.ZP.error("Error occurred while generating model response. Please try again. Error: ".concat(e),20)}}var lj=e=>{let{accessToken:l,token:t,userRole:s,userID:r}=e,[o,i]=(0,n.useState)(""),[c,d]=(0,n.useState)(""),[m,u]=(0,n.useState)([]),[h,x]=(0,n.useState)(void 0),[p,j]=(0,n.useState)([]);(0,n.useEffect)(()=>{l&&t&&s&&r&&(async()=>{try{let e=await A(l,r,s);if(console.log("model_info:",e),(null==e?void 0:e.data.length)>0){let l=e.data.map(e=>({value:e.id,label:e.id}));console.log(l),j(l),x(e.data[0].id)}}catch(e){console.error("Error fetching model info:",e)}})()},[l,r,s]);let g=(e,l)=>{u(t=>{let s=t[t.length-1];return s&&s.role===e?[...t.slice(0,t.length-1),{role:e,content:s.content+l}]:[...t,{role:e,content:l}]})},y=async()=>{if(""!==c.trim()&&o&&t&&s&&r){u(e=>[...e,{role:"user",content:c}]);try{h&&await lp(c,e=>g("assistant",e),h,o)}catch(e){console.error("Error fetching model response",e),g("assistant","Error fetching model response")}d("")}};if(s&&"Admin Viewer"==s){let{Title:e,Paragraph:l}=eT.default;return(0,a.jsxs)("div",{children:[(0,a.jsx)(e,{level:1,children:"Access Denied"}),(0,a.jsx)(l,{children:"Ask your proxy admin for access to test models"})]})}return(0,a.jsx)("div",{style:{width:"100%",position:"relative"},children:(0,a.jsx)(W.Z,{className:"gap-2 p-8 h-[80vh] w-full mt-2",children:(0,a.jsx)(ep.Z,{children:(0,a.jsxs)(eM.Z,{children:[(0,a.jsx)(eL.Z,{children:(0,a.jsx)(eR.Z,{children:"Chat"})}),(0,a.jsx)(eD.Z,{children:(0,a.jsxs)(eU.Z,{children:[(0,a.jsx)("div",{className:"sm:max-w-2xl",children:(0,a.jsxs)(W.Z,{numItems:2,children:[(0,a.jsxs)(Y.Z,{children:[(0,a.jsx)(ee.Z,{children:"API Key"}),(0,a.jsx)(H.Z,{placeholder:"Type API Key here",type:"password",onValueChange:i,value:o})]}),(0,a.jsxs)(Y.Z,{className:"mx-2",children:[(0,a.jsx)(ee.Z,{children:"Select Model:"}),(0,a.jsx)(es.default,{placeholder:"Select a Model",onChange:e=>{console.log("selected ".concat(e)),x(e)},options:p,style:{width:"200px"}})]})]})}),(0,a.jsxs)(eg.Z,{className:"mt-5",style:{display:"block",maxHeight:"60vh",overflowY:"auto"},children:[(0,a.jsx)(eZ.Z,{children:(0,a.jsx)(ew.Z,{children:(0,a.jsx)(ef.Z,{})})}),(0,a.jsx)(ey.Z,{children:m.map((e,l)=>(0,a.jsx)(ew.Z,{children:(0,a.jsx)(ef.Z,{children:"".concat(e.role,": ").concat(e.content)})},l))})]}),(0,a.jsx)("div",{className:"mt-3",style:{position:"absolute",bottom:5,width:"95%"},children:(0,a.jsxs)("div",{className:"flex",children:[(0,a.jsx)(H.Z,{type:"text",value:c,onChange:e=>d(e.target.value),placeholder:"Type your message..."}),(0,a.jsx)(J.Z,{onClick:y,className:"ml-2",children:"Send"})]})})]})})]})})})})},lg=t(33509),ly=t(95781);let{Sider:lf}=lg.default;var lZ=e=>{let{setPage:l,userRole:t,defaultSelectedKey:s}=e;return"Admin Viewer"==t?(0,a.jsx)(lg.default,{style:{minHeight:"100vh",maxWidth:"120px"},children:(0,a.jsx)(lf,{width:120,children:(0,a.jsxs)(ly.Z,{mode:"inline",defaultSelectedKeys:s||["4"],style:{height:"100%",borderRight:0},children:[(0,a.jsx)(ly.Z.Item,{onClick:()=>l("api-keys"),children:"API Keys"},"4"),(0,a.jsx)(ly.Z.Item,{onClick:()=>l("models"),children:"Models"},"2"),(0,a.jsx)(ly.Z.Item,{onClick:()=>l("llm-playground"),children:"Chat UI"},"3"),(0,a.jsx)(ly.Z.Item,{onClick:()=>l("usage"),children:"Usage"},"1")]})})}):(0,a.jsx)(lg.default,{style:{minHeight:"100vh",maxWidth:"145px"},children:(0,a.jsx)(lf,{width:145,children:(0,a.jsxs)(ly.Z,{mode:"inline",defaultSelectedKeys:s||["1"],style:{height:"100%",borderRight:0},children:[(0,a.jsx)(ly.Z.Item,{onClick:()=>l("api-keys"),children:(0,a.jsx)(ee.Z,{children:"API Keys"})},"1"),(0,a.jsx)(ly.Z.Item,{onClick:()=>l("llm-playground"),children:(0,a.jsx)(ee.Z,{children:"Test Key"})},"3"),"Admin"==t?(0,a.jsx)(ly.Z.Item,{onClick:()=>l("models"),children:(0,a.jsx)(ee.Z,{children:"Models"})},"2"):null,"Admin"==t?(0,a.jsx)(ly.Z.Item,{onClick:()=>l("usage"),children:(0,a.jsx)(ee.Z,{children:"Usage"})},"4"):null,"Admin"==t?(0,a.jsx)(ly.Z.Item,{onClick:()=>l("teams"),children:(0,a.jsx)(ee.Z,{children:"Teams"})},"6"):null,"Admin"==t?(0,a.jsx)(ly.Z.Item,{onClick:()=>l("users"),children:(0,a.jsx)(ee.Z,{children:"Users"})},"5"):null,"Admin"==t?(0,a.jsx)(ly.Z.Item,{onClick:()=>l("settings"),children:(0,a.jsx)(ee.Z,{children:"Logging & Alerts"})},"8"):null,"Admin"==t?(0,a.jsx)(ly.Z.Item,{onClick:()=>l("general-settings"),children:(0,a.jsx)(ee.Z,{children:"Router Settings"})},"9"):null,"Admin"==t?(0,a.jsx)(ly.Z.Item,{onClick:()=>l("admin-panel"),children:(0,a.jsx)(ee.Z,{children:"Admin"})},"7"):null,(0,a.jsx)(ly.Z.Item,{onClick:()=>l("api_ref"),children:(0,a.jsx)(ee.Z,{children:"API Reference"})},"11")]})})})},l_=t(67989),lw=e=>{let{accessToken:l,token:t,userRole:s,userID:r,keys:o}=e,i=new Date,[c,d]=(0,n.useState)([]),[m,u]=(0,n.useState)([]),[h,x]=(0,n.useState)([]),[p,j]=(0,n.useState)([]),[g,y]=(0,n.useState)([]),[f,Z]=(0,n.useState)([]),[_,w]=(0,n.useState)([]),[b,k]=(0,n.useState)([]),[v,S]=(0,n.useState)(""),[A,R]=(0,n.useState)({from:new Date(Date.now()-6048e5),to:new Date}),M=new Date(i.getFullYear(),i.getMonth(),1),L=new Date(i.getFullYear(),i.getMonth()+1,0),U=B(M),D=B(L);console.log("keys in usage",o);let K=async(e,t,s)=>{if(!e||!t||!l)return;console.log("uiSelectedKey",s);let r=await T(l,s,e.toISOString(),t.toISOString());console.log("End user data updated successfully",r),j(r)};function B(e){let l=e.getFullYear(),t=e.getMonth()+1,s=e.getDate();return"".concat(l,"-").concat(t<10?"0"+t:t,"-").concat(s<10?"0"+s:s)}return console.log("Start date is ".concat(U)),console.log("End date is ".concat(D)),(0,n.useEffect)(()=>{l&&t&&s&&r&&(async()=>{try{if(console.log("user role: ".concat(s)),"Admin"==s||"Admin Viewer"==s){let e=await C(l);d(e);let t=(await P(l)).map(e=>({key:(e.key_name||e.key_alias||e.api_key).substring(0,10),spend:e.total_spend}));u(t);let s=(await O(l)).map(e=>({key:e.model,spend:e.total_spend}));x(s);let r=await N(l);console.log("teamSpend",r),y(r.daily_spend),w(r.teams);let a=r.total_spend_per_team;a=a.map(e=>(e.name=e.team_id||"",e.value=e.total_spend||0,e)),k(a);let n=await E(l);Z(n.top_10_tags);let o=await T(l,null,void 0,void 0);j(o),console.log("spend/user result",o)}else"App Owner"==s&&await I(l,t,s,r,U,D).then(async e=>{if(console.log("result from spend logs call",e),"daily_spend"in e){let l=e.daily_spend;console.log("daily spend",l),d(l);let t=e.top_api_keys;u(t)}else{let t=(await F(l,function(e){let l=[];e.forEach(e=>{Object.entries(e).forEach(e=>{let[t,s]=e;"spend"!==t&&"startTime"!==t&&"models"!==t&&"users"!==t&&l.push({key:t,spend:s})})}),l.sort((e,l)=>Number(l.spend)-Number(e.spend));let t=l.slice(0,5).map(e=>e.key);return console.log("topKeys: ".concat(Object.keys(t[0]))),t}(e))).info.map(e=>({key:(e.key_name||e.key_alias).substring(0,10),spend:e.spend}));u(t),d(e)}})}catch(e){console.error("There was an error fetching the data",e)}})()},[l,t,s,r,U,D]),(0,a.jsxs)("div",{style:{width:"100%"},className:"p-8",children:[(0,a.jsx)(eE,{userID:r,userRole:s,accessToken:l,userSpend:null,selectedTeam:null}),(0,a.jsxs)(eM.Z,{children:[(0,a.jsxs)(eL.Z,{className:"mt-2",children:[(0,a.jsx)(eR.Z,{children:"All Up"}),(0,a.jsx)(eR.Z,{children:"Team Based Usage"}),(0,a.jsx)(eR.Z,{children:"End User Usage"}),(0,a.jsx)(eR.Z,{children:"Tag Based Usage"})]}),(0,a.jsxs)(eD.Z,{children:[(0,a.jsx)(eU.Z,{children:(0,a.jsxs)(W.Z,{numItems:2,className:"gap-2 h-[75vh] w-full",children:[(0,a.jsx)(Y.Z,{numColSpan:2,children:(0,a.jsxs)(ep.Z,{children:[(0,a.jsx)(el.Z,{children:"Monthly Spend"}),(0,a.jsx)(eq.Z,{data:c,index:"date",categories:["spend"],colors:["blue"],valueFormatter:e=>"$ ".concat(new Intl.NumberFormat("us").format(e).toString()),yAxisWidth:100,tickGap:5})]})}),(0,a.jsx)(Y.Z,{numColSpan:1,children:(0,a.jsxs)(ep.Z,{children:[(0,a.jsx)(el.Z,{children:"Top API Keys"}),(0,a.jsx)(eq.Z,{className:"mt-4 h-40",data:m,index:"key",categories:["spend"],colors:["blue"],yAxisWidth:80,tickGap:5,layout:"vertical",showXAxis:!1,showLegend:!1})]})}),(0,a.jsx)(Y.Z,{numColSpan:1,children:(0,a.jsxs)(ep.Z,{children:[(0,a.jsx)(el.Z,{children:"Top Models"}),(0,a.jsx)(eq.Z,{className:"mt-4 h-40",data:h,index:"key",categories:["spend"],colors:["blue"],yAxisWidth:200,layout:"vertical",showXAxis:!1,showLegend:!1})]})}),(0,a.jsx)(Y.Z,{numColSpan:1})]})}),(0,a.jsx)(eU.Z,{children:(0,a.jsxs)(W.Z,{numItems:2,className:"gap-2 h-[75vh] w-full",children:[(0,a.jsxs)(Y.Z,{numColSpan:2,children:[(0,a.jsxs)(ep.Z,{className:"mb-2",children:[(0,a.jsx)(el.Z,{children:"Total Spend Per Team"}),(0,a.jsx)(l_.Z,{data:b})]}),(0,a.jsxs)(ep.Z,{children:[(0,a.jsx)(el.Z,{children:"Daily Spend Per Team"}),(0,a.jsx)(eq.Z,{className:"h-72",data:g,showLegend:!0,index:"date",categories:_,yAxisWidth:80,colors:["blue","green","yellow","red","purple"],stack:!0})]})]}),(0,a.jsx)(Y.Z,{numColSpan:2})]})}),(0,a.jsxs)(eU.Z,{children:[(0,a.jsxs)("p",{className:"mb-2 text-gray-500 italic text-[12px]",children:["End-Users of your LLM API calls. Tracked when a `user` param is passed in your LLM calls ",(0,a.jsx)("a",{className:"text-blue-500",href:"https://docs.litellm.ai/docs/proxy/users",target:"_blank",children:"docs here"})]}),(0,a.jsxs)(W.Z,{numItems:2,children:[(0,a.jsxs)(Y.Z,{children:[(0,a.jsx)(ee.Z,{children:"Select Time Range"}),(0,a.jsx)(eF.Z,{enableSelect:!0,value:A,onValueChange:e=>{R(e),K(e.from,e.to,null)}})]}),(0,a.jsxs)(Y.Z,{children:[(0,a.jsx)(ee.Z,{children:"Select Key"}),(0,a.jsxs)(eb.Z,{defaultValue:"all-keys",children:[(0,a.jsx)(ek.Z,{value:"all-keys",onClick:()=>{K(A.from,A.to,null)},children:"All Keys"},"all-keys"),null==o?void 0:o.map((e,l)=>e&&null!==e.key_alias&&e.key_alias.length>0?(0,a.jsx)(ek.Z,{value:String(l),onClick:()=>{K(A.from,A.to,e.token)},children:e.key_alias},l):null)]})]})]}),(0,a.jsx)(ep.Z,{className:"mt-4",children:(0,a.jsxs)(eg.Z,{className:"max-h-[70vh] min-h-[500px]",children:[(0,a.jsx)(eZ.Z,{children:(0,a.jsxs)(ew.Z,{children:[(0,a.jsx)(e_.Z,{children:"End User"}),(0,a.jsx)(e_.Z,{children:"Spend"}),(0,a.jsx)(e_.Z,{children:"Total Events"})]})}),(0,a.jsx)(ey.Z,{children:null==p?void 0:p.map((e,l)=>{var t;return(0,a.jsxs)(ew.Z,{children:[(0,a.jsx)(ef.Z,{children:e.end_user}),(0,a.jsx)(ef.Z,{children:null===(t=e.total_spend)||void 0===t?void 0:t.toFixed(4)}),(0,a.jsx)(ef.Z,{children:e.total_count})]},l)})})]})})]}),(0,a.jsx)(eU.Z,{children:(0,a.jsxs)(W.Z,{numItems:2,className:"gap-2 h-[75vh] w-full mb-4",children:[(0,a.jsx)(Y.Z,{numColSpan:2,children:(0,a.jsxs)(ep.Z,{children:[(0,a.jsx)(el.Z,{children:"Spend Per Tag - Last 30 Days"}),(0,a.jsxs)(ee.Z,{children:["Get Started Tracking cost per tag ",(0,a.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/enterprise#tracking-spend-for-custom-tags",target:"_blank",children:"here"})]}),(0,a.jsxs)(eg.Z,{children:[(0,a.jsx)(eZ.Z,{children:(0,a.jsxs)(ew.Z,{children:[(0,a.jsx)(e_.Z,{children:"Tag"}),(0,a.jsx)(e_.Z,{children:"Spend"}),(0,a.jsx)(e_.Z,{children:"Requests"})]})}),(0,a.jsx)(ey.Z,{children:f.map(e=>(0,a.jsxs)(ew.Z,{children:[(0,a.jsx)(ef.Z,{children:e.name}),(0,a.jsx)(ef.Z,{children:e.value}),(0,a.jsx)(ef.Z,{children:e.log_count})]},e.name))})]})]})}),(0,a.jsx)(Y.Z,{numColSpan:2})]})})]})]})]})},lb=()=>{let{Title:e,Paragraph:l}=eT.default,[t,s]=(0,n.useState)(""),[r,i]=(0,n.useState)(null),[c,d]=(0,n.useState)(null),[u,h]=(0,n.useState)(null),[x,p]=(0,n.useState)(!0),j=(0,o.useSearchParams)(),[g,y]=(0,n.useState)({data:[]}),f=j.get("userID"),Z=j.get("token"),[_,w]=(0,n.useState)("api-keys"),[b,k]=(0,n.useState)(null);return(0,n.useEffect)(()=>{if(Z){let e=(0,eP.o)(Z);if(e){if(console.log("Decoded token:",e),console.log("Decoded key:",e.key),k(e.key),e.user_role){let l=function(e){if(!e)return"Undefined Role";switch(console.log("Received user role: ".concat(e.toLowerCase())),console.log("Received user role length: ".concat(e.toLowerCase().length)),e.toLowerCase()){case"app_owner":case"demo_app_owner":return"App Owner";case"app_admin":case"proxy_admin":return"Admin";case"proxy_admin_viewer":return"Admin Viewer";case"app_user":return"App User";default:return"Unknown Role"}}(e.user_role);console.log("Decoded user_role:",l),s(l),"Admin Viewer"==l&&w("usage")}else console.log("User role not defined");e.user_email?i(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))}}},[Z]),(0,a.jsx)(n.Suspense,{fallback:(0,a.jsx)("div",{children:"Loading..."}),children:(0,a.jsxs)("div",{className:"flex flex-col min-h-screen",children:[(0,a.jsx)(m,{userID:f,userRole:t,userEmail:r,showSSOBanner:x}),(0,a.jsxs)("div",{className:"flex flex-1 overflow-auto",children:[(0,a.jsx)("div",{className:"mt-8",children:(0,a.jsx)(lZ,{setPage:w,userRole:t,defaultSelectedKey:null})}),"api-keys"==_?(0,a.jsx)(eO,{userID:f,userRole:t,teams:c,keys:u,setUserRole:s,userEmail:r,setUserEmail:i,setTeams:d,setKeys:h}):"models"==_?(0,a.jsx)(e3,{userID:f,userRole:t,token:Z,accessToken:b,modelData:g,setModelData:y}):"llm-playground"==_?(0,a.jsx)(lj,{userID:f,userRole:t,token:Z,accessToken:b}):"users"==_?(0,a.jsx)(e9,{userID:f,userRole:t,token:Z,keys:u,teams:c,accessToken:b,setKeys:h}):"teams"==_?(0,a.jsx)(le,{teams:c,setTeams:d,searchParams:j,accessToken:b,userID:f,userRole:t}):"admin-panel"==_?(0,a.jsx)(lt,{setTeams:d,searchParams:j,accessToken:b,showSSOBanner:x}):"api_ref"==_?(0,a.jsx)(lx,{}):"settings"==_?(0,a.jsx)(la,{userID:f,userRole:t,accessToken:b}):"general-settings"==_?(0,a.jsx)(lu,{userID:f,userRole:t,accessToken:b,modelData:g}):(0,a.jsx)(lw,{userID:f,userRole:t,token:Z,accessToken:b,keys:u})]})]})})}}},function(e){e.O(0,[936,884,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/84BZ5uERcn4DsO4_POsLl/_buildManifest.js b/ui/litellm-dashboard/out/_next/static/obp5wqVSVDMiDTC414cR8/_buildManifest.js similarity index 100% rename from ui/litellm-dashboard/out/_next/static/84BZ5uERcn4DsO4_POsLl/_buildManifest.js rename to ui/litellm-dashboard/out/_next/static/obp5wqVSVDMiDTC414cR8/_buildManifest.js diff --git a/ui/litellm-dashboard/out/_next/static/84BZ5uERcn4DsO4_POsLl/_ssgManifest.js b/ui/litellm-dashboard/out/_next/static/obp5wqVSVDMiDTC414cR8/_ssgManifest.js similarity index 100% rename from ui/litellm-dashboard/out/_next/static/84BZ5uERcn4DsO4_POsLl/_ssgManifest.js rename to ui/litellm-dashboard/out/_next/static/obp5wqVSVDMiDTC414cR8/_ssgManifest.js diff --git a/ui/litellm-dashboard/out/index.html b/ui/litellm-dashboard/out/index.html index 3b7da2dd1e..930018e005 100644 --- a/ui/litellm-dashboard/out/index.html +++ b/ui/litellm-dashboard/out/index.html @@ -1 +1 @@ -LiteLLM Dashboard \ No newline at end of file +LiteLLM Dashboard \ No newline at end of file diff --git a/ui/litellm-dashboard/out/index.txt b/ui/litellm-dashboard/out/index.txt index 5b09187ac5..d67a480b37 100644 --- a/ui/litellm-dashboard/out/index.txt +++ b/ui/litellm-dashboard/out/index.txt @@ -1,7 +1,7 @@ 2:I[77831,[],""] -3:I[7926,["936","static/chunks/2f6dbc85-052c4579f80d66ae.js","884","static/chunks/884-7576ee407a2ecbe6.js","931","static/chunks/app/page-e6190351ac8da62a.js"],""] +3:I[7926,["936","static/chunks/2f6dbc85-052c4579f80d66ae.js","884","static/chunks/884-7576ee407a2ecbe6.js","931","static/chunks/app/page-6a39771cacf75ea6.js"],""] 4:I[5613,[],""] 5:I[31778,[],""] -0:["84BZ5uERcn4DsO4_POsLl",[[["",{"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/f04e46b02318b660.css","precedence":"next","crossOrigin":""}]],"$L6"]]]] +0:["obp5wqVSVDMiDTC414cR8",[[["",{"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/f04e46b02318b660.css","precedence":"next","crossOrigin":""}]],"$L6"]]]] 6:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"LiteLLM Dashboard"}],["$","meta","3",{"name":"description","content":"LiteLLM Proxy Admin UI"}],["$","link","4",{"rel":"icon","href":"/ui/favicon.ico","type":"image/x-icon","sizes":"16x16"}],["$","meta","5",{"name":"next-size-adjust"}]] 1:null diff --git a/ui/litellm-dashboard/package-lock.json b/ui/litellm-dashboard/package-lock.json index 846189b27a..80efdd2cfc 100644 --- a/ui/litellm-dashboard/package-lock.json +++ b/ui/litellm-dashboard/package-lock.json @@ -17,7 +17,7 @@ "fs": "^0.0.1-security", "jsonwebtoken": "^9.0.2", "jwt-decode": "^4.0.0", - "next": "14.1.0", + "next": "14.1.1", "openai": "^4.28.0", "react": "^18", "react-copy-to-clipboard": "^5.1.0", @@ -412,9 +412,9 @@ } }, "node_modules/@next/env": { - "version": "14.1.0", - "resolved": "https://registry.npmjs.org/@next/env/-/env-14.1.0.tgz", - "integrity": "sha512-Py8zIo+02ht82brwwhTg36iogzFqGLPXlRGKQw5s+qP/kMNc4MAyDeEwBKDijk6zTIbegEgu8Qy7C1LboslQAw==" + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/@next/env/-/env-14.1.1.tgz", + "integrity": "sha512-7CnQyD5G8shHxQIIg3c7/pSeYFeMhsNbpU/bmvH7ZnDql7mNRgg8O2JZrhrc/soFnfBnKP4/xXNiiSIPn2w8gA==" }, "node_modules/@next/eslint-plugin-next": { "version": "14.1.0", @@ -426,9 +426,9 @@ } }, "node_modules/@next/swc-darwin-arm64": { - "version": "14.1.0", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.1.0.tgz", - "integrity": "sha512-nUDn7TOGcIeyQni6lZHfzNoo9S0euXnu0jhsbMOmMJUBfgsnESdjN97kM7cBqQxZa8L/bM9om/S5/1dzCrW6wQ==", + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.1.1.tgz", + "integrity": "sha512-yDjSFKQKTIjyT7cFv+DqQfW5jsD+tVxXTckSe1KIouKk75t1qZmj/mV3wzdmFb0XHVGtyRjDMulfVG8uCKemOQ==", "cpu": [ "arm64" ], @@ -441,9 +441,9 @@ } }, "node_modules/@next/swc-darwin-x64": { - "version": "14.1.0", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.1.0.tgz", - "integrity": "sha512-1jgudN5haWxiAl3O1ljUS2GfupPmcftu2RYJqZiMJmmbBT5M1XDffjUtRUzP4W3cBHsrvkfOFdQ71hAreNQP6g==", + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.1.1.tgz", + "integrity": "sha512-KCQmBL0CmFmN8D64FHIZVD9I4ugQsDBBEJKiblXGgwn7wBCSe8N4Dx47sdzl4JAg39IkSN5NNrr8AniXLMb3aw==", "cpu": [ "x64" ], @@ -456,9 +456,9 @@ } }, "node_modules/@next/swc-linux-arm64-gnu": { - "version": "14.1.0", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.1.0.tgz", - "integrity": "sha512-RHo7Tcj+jllXUbK7xk2NyIDod3YcCPDZxj1WLIYxd709BQ7WuRYl3OWUNG+WUfqeQBds6kvZYlc42NJJTNi4tQ==", + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.1.1.tgz", + "integrity": "sha512-YDQfbWyW0JMKhJf/T4eyFr4b3tceTorQ5w2n7I0mNVTFOvu6CGEzfwT3RSAQGTi/FFMTFcuspPec/7dFHuP7Eg==", "cpu": [ "arm64" ], @@ -471,9 +471,9 @@ } }, "node_modules/@next/swc-linux-arm64-musl": { - "version": "14.1.0", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.1.0.tgz", - "integrity": "sha512-v6kP8sHYxjO8RwHmWMJSq7VZP2nYCkRVQ0qolh2l6xroe9QjbgV8siTbduED4u0hlk0+tjS6/Tuy4n5XCp+l6g==", + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.1.1.tgz", + "integrity": "sha512-fiuN/OG6sNGRN/bRFxRvV5LyzLB8gaL8cbDH5o3mEiVwfcMzyE5T//ilMmaTrnA8HLMS6hoz4cHOu6Qcp9vxgQ==", "cpu": [ "arm64" ], @@ -486,9 +486,9 @@ } }, "node_modules/@next/swc-linux-x64-gnu": { - "version": "14.1.0", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.1.0.tgz", - "integrity": "sha512-zJ2pnoFYB1F4vmEVlb/eSe+VH679zT1VdXlZKX+pE66grOgjmKJHKacf82g/sWE4MQ4Rk2FMBCRnX+l6/TVYzQ==", + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.1.1.tgz", + "integrity": "sha512-rv6AAdEXoezjbdfp3ouMuVqeLjE1Bin0AuE6qxE6V9g3Giz5/R3xpocHoAi7CufRR+lnkuUjRBn05SYJ83oKNQ==", "cpu": [ "x64" ], @@ -501,9 +501,9 @@ } }, "node_modules/@next/swc-linux-x64-musl": { - "version": "14.1.0", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.1.0.tgz", - "integrity": "sha512-rbaIYFt2X9YZBSbH/CwGAjbBG2/MrACCVu2X0+kSykHzHnYH5FjHxwXLkcoJ10cX0aWCEynpu+rP76x0914atg==", + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.1.1.tgz", + "integrity": "sha512-YAZLGsaNeChSrpz/G7MxO3TIBLaMN8QWMr3X8bt6rCvKovwU7GqQlDu99WdvF33kI8ZahvcdbFsy4jAFzFX7og==", "cpu": [ "x64" ], @@ -516,9 +516,9 @@ } }, "node_modules/@next/swc-win32-arm64-msvc": { - "version": "14.1.0", - "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.1.0.tgz", - "integrity": "sha512-o1N5TsYc8f/HpGt39OUQpQ9AKIGApd3QLueu7hXk//2xq5Z9OxmV6sQfNp8C7qYmiOlHYODOGqNNa0e9jvchGQ==", + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.1.1.tgz", + "integrity": "sha512-1L4mUYPBMvVDMZg1inUYyPvFSduot0g73hgfD9CODgbr4xiTYe0VOMTZzaRqYJYBA9mana0x4eaAaypmWo1r5A==", "cpu": [ "arm64" ], @@ -531,9 +531,9 @@ } }, "node_modules/@next/swc-win32-ia32-msvc": { - "version": "14.1.0", - "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.1.0.tgz", - "integrity": "sha512-XXIuB1DBRCFwNO6EEzCTMHT5pauwaSj4SWs7CYnME57eaReAKBXCnkUE80p/pAZcewm7hs+vGvNqDPacEXHVkw==", + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.1.1.tgz", + "integrity": "sha512-jvIE9tsuj9vpbbXlR5YxrghRfMuG0Qm/nZ/1KDHc+y6FpnZ/apsgh+G6t15vefU0zp3WSpTMIdXRUsNl/7RSuw==", "cpu": [ "ia32" ], @@ -546,9 +546,9 @@ } }, "node_modules/@next/swc-win32-x64-msvc": { - "version": "14.1.0", - "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.1.0.tgz", - "integrity": "sha512-9WEbVRRAqJ3YFVqEZIxUqkiO8l1nool1LmNxygr5HWF8AcSYsEpneUDhmjUVJEzO2A04+oPtZdombzzPPkTtgg==", + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.1.1.tgz", + "integrity": "sha512-S6K6EHDU5+1KrBDLko7/c1MNy/Ya73pIAmvKeFwsF4RmBFJSO7/7YeD4FnZ4iBdzE69PpQ4sOMU9ORKeNuxe8A==", "cpu": [ "x64" ], @@ -4907,11 +4907,11 @@ "dev": true }, "node_modules/next": { - "version": "14.1.0", - "resolved": "https://registry.npmjs.org/next/-/next-14.1.0.tgz", - "integrity": "sha512-wlzrsbfeSU48YQBjZhDzOwhWhGsy+uQycR8bHAOt1LY1bn3zZEcDyHQOEoN3aWzQ8LHCAJ1nqrWCc9XF2+O45Q==", + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/next/-/next-14.1.1.tgz", + "integrity": "sha512-McrGJqlGSHeaz2yTRPkEucxQKe5Zq7uPwyeHNmJaZNY4wx9E9QdxmTp310agFRoMuIYgQrCrT3petg13fSVOww==", "dependencies": { - "@next/env": "14.1.0", + "@next/env": "14.1.1", "@swc/helpers": "0.5.2", "busboy": "1.6.0", "caniuse-lite": "^1.0.30001579", @@ -4926,15 +4926,15 @@ "node": ">=18.17.0" }, "optionalDependencies": { - "@next/swc-darwin-arm64": "14.1.0", - "@next/swc-darwin-x64": "14.1.0", - "@next/swc-linux-arm64-gnu": "14.1.0", - "@next/swc-linux-arm64-musl": "14.1.0", - "@next/swc-linux-x64-gnu": "14.1.0", - "@next/swc-linux-x64-musl": "14.1.0", - "@next/swc-win32-arm64-msvc": "14.1.0", - "@next/swc-win32-ia32-msvc": "14.1.0", - "@next/swc-win32-x64-msvc": "14.1.0" + "@next/swc-darwin-arm64": "14.1.1", + "@next/swc-darwin-x64": "14.1.1", + "@next/swc-linux-arm64-gnu": "14.1.1", + "@next/swc-linux-arm64-musl": "14.1.1", + "@next/swc-linux-x64-gnu": "14.1.1", + "@next/swc-linux-x64-musl": "14.1.1", + "@next/swc-win32-arm64-msvc": "14.1.1", + "@next/swc-win32-ia32-msvc": "14.1.1", + "@next/swc-win32-x64-msvc": "14.1.1" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", diff --git a/ui/litellm-dashboard/package.json b/ui/litellm-dashboard/package.json index 108d70d98a..0fb9f1a53e 100644 --- a/ui/litellm-dashboard/package.json +++ b/ui/litellm-dashboard/package.json @@ -18,7 +18,7 @@ "fs": "^0.0.1-security", "jsonwebtoken": "^9.0.2", "jwt-decode": "^4.0.0", - "next": "14.1.0", + "next": "14.1.1", "openai": "^4.28.0", "react": "^18", "react-copy-to-clipboard": "^5.1.0", diff --git a/ui/litellm-dashboard/src/components/networking.tsx b/ui/litellm-dashboard/src/components/networking.tsx index 4a629ed47c..1ec131f726 100644 --- a/ui/litellm-dashboard/src/components/networking.tsx +++ b/ui/litellm-dashboard/src/components/networking.tsx @@ -655,11 +655,20 @@ export const teamSpendLogsCall = async (accessToken: String) => { }; -export const tagsSpendLogsCall = async (accessToken: String) => { +export const tagsSpendLogsCall = async ( + accessToken: String, + startTime: String | undefined, + endTime: String | undefined + ) => { try { - const url = proxyBaseUrl + let url = proxyBaseUrl ? `${proxyBaseUrl}/global/spend/tags` : `/global/spend/tags`; + + if (startTime && endTime) { + url = `${url}?start_date=${startTime}&end_date=${endTime}` + } + console.log("in tagsSpendLogsCall:", url); const response = await fetch(`${url}`, { method: "GET", diff --git a/ui/litellm-dashboard/src/components/settings.tsx b/ui/litellm-dashboard/src/components/settings.tsx index ff7e07005d..96c20bf15c 100644 --- a/ui/litellm-dashboard/src/components/settings.tsx +++ b/ui/litellm-dashboard/src/components/settings.tsx @@ -109,6 +109,7 @@ const Settings: React.FC = ({ "llm_requests_hanging": "LLM Requests Hanging", "budget_alerts": "Budget Alerts (API Keys, Users)", "db_exceptions": "Database Exceptions (Read/Write)", + "daily_reports": "Weekly/Monthly Spend Reports", } useEffect(() => { diff --git a/ui/litellm-dashboard/src/components/teams.tsx b/ui/litellm-dashboard/src/components/teams.tsx index d22789420f..9e5758a283 100644 --- a/ui/litellm-dashboard/src/components/teams.tsx +++ b/ui/litellm-dashboard/src/components/teams.tsx @@ -129,7 +129,7 @@ const Team: React.FC = ({ name="team_alias" rules={[{ required: true, message: "Please input a team name" }]} > - + = ({ console.log("End user data updated successfully", newTopUserData); setTopUsers(newTopUserData); + } + + const updateTagSpendData = async (startTime: Date | undefined, endTime: Date | undefined) => { + if (!startTime || !endTime || !accessToken) { + return; + } + + let top_tags = await tagsSpendLogsCall(accessToken, startTime.toISOString(), endTime.toISOString()); + setTopTagsData(top_tags.spend_per_tag); + console.log("Tag spend data updated successfully"); + + + } function formatDate(date: Date) { @@ -218,8 +231,8 @@ const UsagePage: React.FC = ({ setTotalSpendPerTeam(total_spend_per_team); //get top tags - const top_tags = await tagsSpendLogsCall(accessToken); - setTopTagsData(top_tags.top_10_tags); + const top_tags = await tagsSpendLogsCall(accessToken, dateValue.from?.toISOString(), dateValue.to?.toISOString()); + setTopTagsData(top_tags.spend_per_tag); // get spend per end-user let spend_user_call = await adminTopEndUsersCall(accessToken, null, undefined, undefined); @@ -459,38 +472,28 @@ const UsagePage: React.FC = ({ + { + setDateValue(value); + updateTagSpendData(value.from, value.to); // Call updateModelMetrics with the new date range + }} + /> - Spend Per Tag - Last 30 Days - Get Started Tracking cost per tag here - - - - Tag - Spend - Requests - - - - {topTagsData.map((tag) => ( - - {tag.name} - {tag.value} - {tag.log_count} - - ))} - -
- {/* */} + Spend Per Tag + Get Started Tracking cost per tag here + + +