diff --git a/docs/my-website/docs/providers/anthropic.md b/docs/my-website/docs/providers/anthropic.md
index 198a6a03d..21140f29b 100644
--- a/docs/my-website/docs/providers/anthropic.md
+++ b/docs/my-website/docs/providers/anthropic.md
@@ -1,3 +1,6 @@
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
# Anthropic
LiteLLM supports
@@ -45,7 +48,97 @@ for chunk in response:
print(chunk["choices"][0]["delta"]["content"]) # same as openai format
```
+## OpenAI Proxy Usage
+Here's how to call Anthropic with the LiteLLM Proxy Server
+
+### 1. Save key in your environment
+
+```bash
+export ANTHROPIC_API_KEY="your-api-key"
+```
+
+### 2. Start the proxy
+
+```bash
+$ litellm --model claude-3-opus-20240229
+
+# Server running on http://0.0.0.0:8000
+```
+
+### 3. Test it
+
+
+
+
+
+```shell
+curl --location 'http://0.0.0.0:8000/chat/completions' \
+--header 'Content-Type: application/json' \
+--data ' {
+ "model": "gpt-3.5-turbo",
+ "messages": [
+ {
+ "role": "user",
+ "content": "what llm are you"
+ }
+ ]
+ }
+'
+```
+
+
+
+```python
+import openai
+client = openai.OpenAI(
+ api_key="anything",
+ base_url="http://0.0.0.0:8000"
+)
+
+# request sent to model set on litellm proxy, `litellm --model`
+response = client.chat.completions.create(model="gpt-3.5-turbo", messages = [
+ {
+ "role": "user",
+ "content": "this is a test request, write a short poem"
+ }
+])
+
+print(response)
+
+```
+
+
+
+```python
+from langchain.chat_models import ChatOpenAI
+from langchain.prompts.chat import (
+ ChatPromptTemplate,
+ HumanMessagePromptTemplate,
+ SystemMessagePromptTemplate,
+)
+from langchain.schema import HumanMessage, SystemMessage
+
+chat = ChatOpenAI(
+ openai_api_base="http://0.0.0.0:8000", # set openai_api_base to the LiteLLM Proxy
+ model = "gpt-3.5-turbo",
+ temperature=0.1
+)
+
+messages = [
+ SystemMessage(
+ content="You are a helpful assistant that im using to make a test request to."
+ ),
+ HumanMessage(
+ content="test from litellm. tell me why it's amazing in 1 sentence"
+ ),
+]
+response = chat(messages)
+
+print(response)
+```
+
+
## Supported Models
@@ -56,6 +149,7 @@ for chunk in response:
| claude-2.1 | `completion('claude-2.1', messages)` | `os.environ['ANTHROPIC_API_KEY']` |
| claude-2 | `completion('claude-2', messages)` | `os.environ['ANTHROPIC_API_KEY']` |
| claude-instant-1.2 | `completion('claude-instant-1.2', messages)` | `os.environ['ANTHROPIC_API_KEY']` |
+| claude-instant-1 | `completion('claude-instant-1', messages)` | `os.environ['ANTHROPIC_API_KEY']` |
## Advanced
diff --git a/litellm/__init__.py b/litellm/__init__.py
index c64dc0ea8..017bd46ac 100644
--- a/litellm/__init__.py
+++ b/litellm/__init__.py
@@ -574,6 +574,7 @@ from .utils import (
)
from .llms.huggingface_restapi import HuggingfaceConfig
from .llms.anthropic import AnthropicConfig
+from .llms.anthropic_text import AnthropicTextConfig
from .llms.replicate import ReplicateConfig
from .llms.cohere import CohereConfig
from .llms.ai21 import AI21Config
diff --git a/litellm/llms/anthropic.py b/litellm/llms/anthropic.py
index 047616cfe..5e0887901 100644
--- a/litellm/llms/anthropic.py
+++ b/litellm/llms/anthropic.py
@@ -227,7 +227,7 @@ def completion(
else:
text_content = completion_response["content"][0].get("text", None)
## TOOL CALLING - OUTPUT PARSE
- if _is_function_call == True:
+ if text_content is not None and "invoke" in text_content:
function_name = extract_between_tags("tool_name", text_content)[0]
function_arguments_str = extract_between_tags("invoke", text_content)[
0
diff --git a/litellm/llms/anthropic_text.py b/litellm/llms/anthropic_text.py
new file mode 100644
index 000000000..bccc8c769
--- /dev/null
+++ b/litellm/llms/anthropic_text.py
@@ -0,0 +1,222 @@
+import os, types
+import json
+from enum import Enum
+import requests
+import time
+from typing import Callable, Optional
+from litellm.utils import ModelResponse, Usage
+import litellm
+from .prompt_templates.factory import prompt_factory, custom_prompt
+import httpx
+
+
+class AnthropicConstants(Enum):
+ HUMAN_PROMPT = "\n\nHuman: "
+ AI_PROMPT = "\n\nAssistant: "
+
+
+class AnthropicError(Exception):
+ def __init__(self, status_code, message):
+ self.status_code = status_code
+ self.message = message
+ self.request = httpx.Request(
+ method="POST", url="https://api.anthropic.com/v1/complete"
+ )
+ self.response = httpx.Response(status_code=status_code, request=self.request)
+ super().__init__(
+ self.message
+ ) # Call the base class constructor with the parameters it needs
+
+
+class AnthropicTextConfig:
+ """
+ Reference: https://docs.anthropic.com/claude/reference/complete_post
+
+ to pass metadata to anthropic, it's {"user_id": "any-relevant-information"}
+ """
+
+ max_tokens_to_sample: Optional[int] = (
+ litellm.max_tokens
+ ) # anthropic requires a default
+ stop_sequences: Optional[list] = None
+ temperature: Optional[int] = None
+ top_p: Optional[int] = None
+ top_k: Optional[int] = None
+ metadata: Optional[dict] = None
+
+ def __init__(
+ self,
+ max_tokens_to_sample: Optional[int] = 256, # anthropic requires a default
+ stop_sequences: Optional[list] = None,
+ temperature: Optional[int] = None,
+ top_p: Optional[int] = None,
+ top_k: Optional[int] = None,
+ metadata: 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
+ }
+
+
+# makes headers for API call
+def validate_environment(api_key, user_headers):
+ if api_key is None:
+ raise ValueError(
+ "Missing Anthropic API Key - A call is being made to anthropic but no key is set either in the environment variables or via params"
+ )
+ headers = {
+ "accept": "application/json",
+ "anthropic-version": "2023-06-01",
+ "content-type": "application/json",
+ "x-api-key": api_key,
+ }
+ if user_headers is not None and isinstance(user_headers, dict):
+ headers = {**headers, **user_headers}
+ return headers
+
+
+def completion(
+ model: str,
+ messages: list,
+ api_base: str,
+ custom_prompt_dict: dict,
+ model_response: ModelResponse,
+ print_verbose: Callable,
+ encoding,
+ api_key,
+ logging_obj,
+ optional_params=None,
+ litellm_params=None,
+ logger_fn=None,
+ headers={},
+):
+ headers = validate_environment(api_key, headers)
+ if model in custom_prompt_dict:
+ # check if the model has a registered custom prompt
+ model_prompt_details = custom_prompt_dict[model]
+ prompt = custom_prompt(
+ role_dict=model_prompt_details["roles"],
+ initial_prompt_value=model_prompt_details["initial_prompt_value"],
+ final_prompt_value=model_prompt_details["final_prompt_value"],
+ messages=messages,
+ )
+ else:
+ prompt = prompt_factory(
+ model=model, messages=messages, custom_llm_provider="anthropic"
+ )
+
+ ## Load Config
+ config = litellm.AnthropicTextConfig.get_config()
+ for k, v in config.items():
+ if (
+ k not in optional_params
+ ): # completion(top_k=3) > anthropic_config(top_k=3) <- allows for dynamic variables to be passed in
+ optional_params[k] = v
+
+ data = {
+ "model": model,
+ "prompt": prompt,
+ **optional_params,
+ }
+
+ ## LOGGING
+ logging_obj.pre_call(
+ input=prompt,
+ api_key=api_key,
+ additional_args={
+ "complete_input_dict": data,
+ "api_base": api_base,
+ "headers": headers,
+ },
+ )
+
+ ## COMPLETION CALL
+ if "stream" in optional_params and optional_params["stream"] == True:
+ response = requests.post(
+ api_base,
+ headers=headers,
+ data=json.dumps(data),
+ stream=optional_params["stream"],
+ )
+
+ if response.status_code != 200:
+ raise AnthropicError(
+ status_code=response.status_code, message=response.text
+ )
+
+ return response.iter_lines()
+ else:
+ response = requests.post(api_base, headers=headers, data=json.dumps(data))
+ if response.status_code != 200:
+ raise AnthropicError(
+ status_code=response.status_code, message=response.text
+ )
+
+ ## LOGGING
+ logging_obj.post_call(
+ input=prompt,
+ api_key=api_key,
+ original_response=response.text,
+ additional_args={"complete_input_dict": data},
+ )
+ print_verbose(f"raw model_response: {response.text}")
+ ## RESPONSE OBJECT
+ try:
+ completion_response = response.json()
+ except:
+ raise AnthropicError(
+ message=response.text, status_code=response.status_code
+ )
+ if "error" in completion_response:
+ raise AnthropicError(
+ message=str(completion_response["error"]),
+ status_code=response.status_code,
+ )
+ else:
+ if len(completion_response["completion"]) > 0:
+ model_response["choices"][0]["message"]["content"] = (
+ completion_response["completion"]
+ )
+ model_response.choices[0].finish_reason = completion_response["stop_reason"]
+
+ ## CALCULATING USAGE
+ prompt_tokens = len(
+ encoding.encode(prompt)
+ ) ##[TODO] use the anthropic tokenizer here
+ completion_tokens = len(
+ encoding.encode(model_response["choices"][0]["message"].get("content", ""))
+ ) ##[TODO] use the anthropic tokenizer here
+
+ model_response["created"] = int(time.time())
+ model_response["model"] = model
+ usage = Usage(
+ prompt_tokens=prompt_tokens,
+ completion_tokens=completion_tokens,
+ total_tokens=prompt_tokens + completion_tokens,
+ )
+ model_response.usage = usage
+ return model_response
+
+
+def embedding():
+ # logic for parsing in - calling - parsing out model embedding calls
+ pass
diff --git a/litellm/llms/huggingface_restapi.py b/litellm/llms/huggingface_restapi.py
index 61a6ac040..293773289 100644
--- a/litellm/llms/huggingface_restapi.py
+++ b/litellm/llms/huggingface_restapi.py
@@ -658,36 +658,26 @@ class Huggingface(BaseLLM):
message=first_chunk,
)
- return self.async_streaming_generator(
- first_chunk=first_chunk,
- response_iterator=response_iterator,
+ # Create a new async generator that begins with the first_chunk and includes the remaining items
+ async def custom_stream_with_first_chunk():
+ yield first_chunk # Yield back the first chunk
+ async for (
+ chunk
+ ) in response_iterator: # Continue yielding the rest of the chunks
+ yield chunk
+
+ # Creating a new completion stream that starts with the first chunk
+ completion_stream = custom_stream_with_first_chunk()
+
+ streamwrapper = CustomStreamWrapper(
+ completion_stream=completion_stream,
model=model,
+ custom_llm_provider="huggingface",
logging_obj=logging_obj,
)
- async def async_streaming_generator(
- self, first_chunk, response_iterator, model, logging_obj
- ):
- # Create a new async generator that begins with the first_chunk and includes the remaining items
- async def custom_stream_with_first_chunk():
- yield first_chunk # Yield back the first chunk
- async for (
- chunk
- ) in response_iterator: # Continue yielding the rest of the chunks
- yield chunk
-
- # Creating a new completion stream that starts with the first chunk
- completion_stream = custom_stream_with_first_chunk()
-
- streamwrapper = CustomStreamWrapper(
- completion_stream=completion_stream,
- model=model,
- custom_llm_provider="huggingface",
- logging_obj=logging_obj,
- )
-
- async for transformed_chunk in streamwrapper:
- yield transformed_chunk
+ async for transformed_chunk in streamwrapper:
+ yield transformed_chunk
def embedding(
self,
diff --git a/litellm/main.py b/litellm/main.py
index b7707b722..60effd96f 100644
--- a/litellm/main.py
+++ b/litellm/main.py
@@ -39,6 +39,7 @@ from litellm.utils import (
)
from .llms import (
anthropic,
+ anthropic_text,
together_ai,
ai21,
sagemaker,
@@ -1018,28 +1019,55 @@ def completion(
or litellm.api_key
or os.environ.get("ANTHROPIC_API_KEY")
)
- api_base = (
- api_base
- or litellm.api_base
- or get_secret("ANTHROPIC_API_BASE")
- or "https://api.anthropic.com/v1/messages"
- )
custom_prompt_dict = custom_prompt_dict or litellm.custom_prompt_dict
- response = anthropic.completion(
- model=model,
- messages=messages,
- api_base=api_base,
- custom_prompt_dict=litellm.custom_prompt_dict,
- model_response=model_response,
- print_verbose=print_verbose,
- optional_params=optional_params,
- litellm_params=litellm_params,
- logger_fn=logger_fn,
- encoding=encoding, # for calculating input/output tokens
- api_key=api_key,
- logging_obj=logging,
- headers=headers,
- )
+
+ if (model == "claude-2") or (model == "claude-instant-1"):
+ # call anthropic /completion, only use this route for claude-2, claude-instant-1
+ api_base = (
+ api_base
+ or litellm.api_base
+ or get_secret("ANTHROPIC_API_BASE")
+ or "https://api.anthropic.com/v1/complete"
+ )
+ response = anthropic_text.completion(
+ model=model,
+ messages=messages,
+ api_base=api_base,
+ custom_prompt_dict=litellm.custom_prompt_dict,
+ model_response=model_response,
+ print_verbose=print_verbose,
+ optional_params=optional_params,
+ litellm_params=litellm_params,
+ logger_fn=logger_fn,
+ encoding=encoding, # for calculating input/output tokens
+ api_key=api_key,
+ logging_obj=logging,
+ headers=headers,
+ )
+ else:
+ # call /messages
+ # default route for all anthropic models
+ api_base = (
+ api_base
+ or litellm.api_base
+ or get_secret("ANTHROPIC_API_BASE")
+ or "https://api.anthropic.com/v1/messages"
+ )
+ response = anthropic.completion(
+ model=model,
+ messages=messages,
+ api_base=api_base,
+ custom_prompt_dict=litellm.custom_prompt_dict,
+ model_response=model_response,
+ print_verbose=print_verbose,
+ optional_params=optional_params,
+ litellm_params=litellm_params,
+ logger_fn=logger_fn,
+ encoding=encoding, # for calculating input/output tokens
+ api_key=api_key,
+ logging_obj=logging,
+ headers=headers,
+ )
if "stream" in optional_params and optional_params["stream"] == True:
# don't try to access stream object,
response = CustomStreamWrapper(
diff --git a/litellm/proxy/_experimental/out/404.html b/litellm/proxy/_experimental/out/404.html
index 064bb2163..eb5cf4286 100644
--- a/litellm/proxy/_experimental/out/404.html
+++ b/litellm/proxy/_experimental/out/404.html
@@ -1 +1 @@
-
404: This page could not be found.🚅 LiteLLM
404
This page could not be found.
\ No newline at end of file
+404: This page could not be found.🚅 LiteLLM
404
This page could not be found.
\ No newline at end of file
diff --git a/litellm/proxy/_experimental/out/_next/static/p1zjZBLDqxGf-NaFvZkeF/_buildManifest.js b/litellm/proxy/_experimental/out/_next/static/ZF-EluyKCEJoZptE3dOXT/_buildManifest.js
similarity index 100%
rename from litellm/proxy/_experimental/out/_next/static/p1zjZBLDqxGf-NaFvZkeF/_buildManifest.js
rename to litellm/proxy/_experimental/out/_next/static/ZF-EluyKCEJoZptE3dOXT/_buildManifest.js
diff --git a/litellm/proxy/_experimental/out/_next/static/p1zjZBLDqxGf-NaFvZkeF/_ssgManifest.js b/litellm/proxy/_experimental/out/_next/static/ZF-EluyKCEJoZptE3dOXT/_ssgManifest.js
similarity index 100%
rename from litellm/proxy/_experimental/out/_next/static/p1zjZBLDqxGf-NaFvZkeF/_ssgManifest.js
rename to litellm/proxy/_experimental/out/_next/static/ZF-EluyKCEJoZptE3dOXT/_ssgManifest.js
diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/app/page-2ed0bc91ffef505b.js b/litellm/proxy/_experimental/out/_next/static/chunks/app/page-2ed0bc91ffef505b.js
new file mode 100644
index 000000000..a0bd09f21
--- /dev/null
+++ b/litellm/proxy/_experimental/out/_next/static/chunks/app/page-2ed0bc91ffef505b.js
@@ -0,0 +1 @@
+(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[931],{20661:function(e,t,s){Promise.resolve().then(s.bind(s,57492))},57492:function(e,t,s){"use strict";s.r(t),s.d(t,{default:function(){return eM}});var l=s(3827),n=s(64090),r=s(47907),a=s(8792),o=s(2179),i=e=>{let{userID:t,userRole:s,userEmail:n,showSSOBanner:r}=e;return console.log("User ID:",t),console.log("userEmail:",n),(0,l.jsxs)("nav",{className:"left-0 right-0 top-0 flex justify-between items-center h-12 mb-4",children:[(0,l.jsx)("div",{className:"text-left my-2 absolute top-0 left-0",children:(0,l.jsx)("div",{className:"flex flex-col items-center",children:(0,l.jsx)(a.default,{href:"/",children:(0,l.jsx)("button",{className:"text-gray-800 text-2xl py-1 rounded text-center",children:(0,l.jsx)("img",{src:"/get_image",width:200,height:200,alt:"LiteLLM Brand",className:"mr-2"})})})})}),(0,l.jsxs)("div",{className:"text-right mx-4 my-2 absolute top-0 right-0 flex items-center justify-end space-x-2",children:[r?(0,l.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/ui#setup-ssoauth-for-ui",target:"_blank",className:"mr-2",children:(0,l.jsx)(o.Z,{variant:"primary",size:"lg",children:"Enable SSO"})}):null,(0,l.jsxs)(o.Z,{variant:"secondary",size:"lg",children:[n,(0,l.jsxs)("p",{children:["Role: ",s]}),(0,l.jsxs)("p",{children:["ID: ",t]})]})]})]})},c=s(80588);let d=async(e,t,s)=>{try{if(console.log("Form Values in keyCreateCall:",s),s.description&&(s.metadata||(s.metadata={}),s.metadata.description=s.description,delete s.description,s.metadata=JSON.stringify(s.metadata)),s.metadata){console.log("formValues.metadata:",s.metadata);try{s.metadata=JSON.parse(s.metadata)}catch(e){throw c.ZP.error("Failed to parse metadata: "+e),Error("Failed to parse metadata: "+e)}}console.log("Form Values after check:",s);let l=await fetch("/key/generate",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({user_id:t,...s})});if(!l.ok){let e=await l.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let n=await l.json();return console.log("API Response:",n),n}catch(e){throw console.error("Failed to create key:",e),e}},h=async(e,t,s)=>{try{if(console.log("Form Values in keyCreateCall:",s),s.description&&(s.metadata||(s.metadata={}),s.metadata.description=s.description,delete s.description,s.metadata=JSON.stringify(s.metadata)),s.metadata){console.log("formValues.metadata:",s.metadata);try{s.metadata=JSON.parse(s.metadata)}catch(e){throw c.ZP.error("Failed to parse metadata: "+e),Error("Failed to parse metadata: "+e)}}console.log("Form Values after check:",s);let l=await fetch("/user/new",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({user_id:t,...s})});if(!l.ok){let e=await l.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let n=await l.json();return console.log("API Response:",n),n}catch(e){throw console.error("Failed to create key:",e),e}},m=async(e,t)=>{try{console.log("in keyDeleteCall:",t),c.ZP.info("Making key delete request");let s=await fetch("/key/delete",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({keys:[t]})});if(!s.ok){let e=await s.text();throw c.ZP.error("Failed to delete key: "+e),Error("Network response was not ok")}let l=await s.json();return console.log(l),c.ZP.success("API Key Deleted"),l}catch(e){throw console.error("Failed to create key:",e),e}},u=async function(e,t,s){let l=arguments.length>3&&void 0!==arguments[3]&&arguments[3];try{let n="/user/info";"App Owner"==s&&t&&(n="".concat(n,"/?user_id=").concat(t)),console.log("in userInfoCall viewAll=",l),l&&(n="".concat(n,"/?view_all=true")),c.ZP.info("Requesting user data");let r=await fetch(n,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!r.ok){let e=await r.text();throw c.ZP.error(e),Error("Network response was not ok")}let a=await r.json();return console.log("API Response:",a),c.ZP.info("Received user data"),a}catch(e){throw console.error("Failed to create key:",e),e}},x=async(e,t,s)=>{try{c.ZP.info("Requesting model data");let t=await fetch("/v2/model/info",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}let s=await t.json();return c.ZP.info("Received model data"),s}catch(e){throw console.error("Failed to create key:",e),e}},p=async(e,t,s)=>{try{let t=await fetch("/model/metrics",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},j=async(e,t,s)=>{try{c.ZP.info("Requesting model data");let t=await fetch("/models",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}let s=await t.json();return c.ZP.info("Received model data"),s}catch(e){throw console.error("Failed to create key:",e),e}},g=async(e,t)=>{try{let s="/global/spend/logs";console.log("in keySpendLogsCall:",s);let l=await fetch("".concat(s,"/?api_key=").concat(t),{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw c.ZP.error(e),Error("Network response was not ok")}let n=await l.json();return console.log(n),n}catch(e){throw console.error("Failed to create key:",e),e}},y=async(e,t,s,l,n,r)=>{try{console.log("user role in spend logs call: ".concat(s));let t="/spend/logs";t="App Owner"==s?"".concat(t,"/?user_id=").concat(l,"&start_date=").concat(n,"&end_date=").concat(r):"".concat(t,"/?start_date=").concat(n,"&end_date=").concat(r),c.ZP.info("Making spend logs request");let a=await fetch(t,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!a.ok){let e=await a.text();throw c.ZP.error(e),Error("Network response was not ok")}let o=await a.json();return console.log(o),c.ZP.success("Spend Logs received"),o}catch(e){throw console.error("Failed to create key:",e),e}},Z=async e=>{try{c.ZP.info("Making spend logs request");let t=await fetch("/global/spend/logs",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}let s=await t.json();return console.log(s),c.ZP.success("Spend Logs received"),s}catch(e){throw console.error("Failed to create key:",e),e}},f=async e=>{try{c.ZP.info("Making spend keys request");let t=await fetch("/global/spend/keys?limit=5",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}let s=await t.json();return console.log(s),c.ZP.success("Spend Logs received"),s}catch(e){throw console.error("Failed to create key:",e),e}},w=async(e,t)=>{try{t&&JSON.stringify({api_key:t}),c.ZP.info("Making top end users request");let s={method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}};t&&(s.body=JSON.stringify({api_key:t}));let l=await fetch("/global/spend/end_users",s);if(!l.ok){let e=await l.text();throw c.ZP.error(e),Error("Network response was not ok")}let n=await l.json();return console.log(n),c.ZP.success("Top End users received"),n}catch(e){throw console.error("Failed to create key:",e),e}},k=async e=>{try{c.ZP.info("Making top models request");let t=await fetch("/global/spend/models?limit=5",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}let s=await t.json();return console.log(s),c.ZP.success("Top Models received"),s}catch(e){throw console.error("Failed to create key:",e),e}},_=async(e,t)=>{try{let s=await fetch("/v2/key/info",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({keys:t})});if(!s.ok){let e=await s.text();throw c.ZP.error(e),Error("Network response was not ok")}let l=await s.json();return console.log(l),l}catch(e){throw console.error("Failed to create key:",e),e}},b=async(e,t)=>{try{let s="/spend/users";console.log("in spendUsersCall:",s);let l=await fetch("".concat(s,"/?user_id=").concat(t),{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw c.ZP.error(e),Error("Network response was not ok")}let n=await l.json();return console.log(n),n}catch(e){throw console.error("Failed to get spend for user",e),e}},v=async(e,t,s,l)=>{try{let n=await fetch("/user/request_model",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({models:[t],user_id:s,justification:l})});if(!n.ok){let e=await n.text();throw c.ZP.error("Failed to delete key: "+e),Error("Network response was not ok")}let r=await n.json();return console.log(r),c.ZP.success(""),r}catch(e){throw console.error("Failed to create key:",e),e}},S=async e=>{try{let t="/user/get_requests";console.log("in userGetRequesedtModelsCall:",t);let s=await fetch(t,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!s.ok){let e=await s.text();throw c.ZP.error("Failed to delete key: "+e),Error("Network response was not ok")}let l=await s.json();return console.log(l),c.ZP.success(""),l}catch(e){throw console.error("Failed to get requested models:",e),e}},N=async(e,t)=>{try{let s="/user/get_users?role=".concat(t);console.log("in userGetAllUsersCall:",s);let l=await fetch(s,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw c.ZP.error("Failed to delete key: "+e),Error("Network response was not ok")}let n=await l.json();return console.log(n),c.ZP.success("Got all users"),n}catch(e){throw console.error("Failed to get requested models:",e),e}},A=async(e,t)=>{try{console.log("Form Values in teamCreateCall:",t);let s=await fetch("/team/new",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...t})});if(!s.ok){let e=await s.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let l=await s.json();return console.log("API Response:",l),l}catch(e){throw console.error("Failed to create key:",e),e}},C=async(e,t,s)=>{try{console.log("Form Values in teamMemberAddCall:",s);let l=await fetch("/team/member_add",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({team_id:t,member:s})});if(!l.ok){let e=await l.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let n=await l.json();return console.log("API Response:",n),n}catch(e){throw console.error("Failed to create key:",e),e}},I=async(e,t)=>{try{console.log("Form Values in userUpdateUserCall:",t);let s=await fetch("/user/update",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({user_role:"proxy_admin_viewer",...t})});if(!s.ok){let e=await s.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let l=await s.json();return console.log("API Response:",l),c.ZP.success("User role updated"),l}catch(e){throw console.error("Failed to create key:",e),e}},P=async(e,t)=>{try{let s=await fetch("/global/predict/spend/logs",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({data:t})});if(!s.ok){let e=await s.text();throw c.ZP.error(e),Error("Network response was not ok")}let l=await s.json();return console.log(l),l}catch(e){throw console.error("Failed to create key:",e),e}},T=async e=>{try{console.log("Checking Slack Budget Alerts service health"),c.ZP.info("Sending Test Slack alert...");let t=await fetch("/health/services?service=slack_budget_alerts",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error("Failed Slack Alert test: "+e),Error(e)}let s=await t.json();return c.ZP.success("Test Slack Alert worked - check your Slack!"),console.log("Service Health Response:",s),s}catch(e){throw console.error("Failed to perform health check:",e),e}};var E=s(10384),F=s(46453),M=s(13810),R=s(71801),O=s(42440),D=s(17189),U=s(12143),L=s(77171),z=s(42539),B=s(88707),q=s(1861);let{Option:K}=D.default;var V=e=>{let{userID:t,teamID:s,userRole:r,accessToken:a,data:i,userModels:h,setData:m}=e,[u]=U.Z.useForm(),[x,p]=(0,n.useState)(!1),[j,g]=(0,n.useState)(null),[y,Z]=(0,n.useState)(null),f=()=>{p(!1),u.resetFields()},w=()=>{p(!1),g(null),u.resetFields()},k=async e=>{try{c.ZP.info("Making API Call"),p(!0);let s=await d(a,t,e);console.log("key create Response:",s),m(e=>e?[...e,s]:[s]),g(s.key),Z(s.soft_budget),c.ZP.success("API Key Created"),u.resetFields(),localStorage.removeItem("userData"+t)}catch(e){console.error("Error creating the key:",e)}},_=async()=>{try{console.log("Sending Slack alert...");let e=await T(a);console.log("slackBudgetAlertsHealthCheck Response:",e),console.log("Testing Slack alert successful")}catch(e){console.error("Error sending Slack alert:",e)}};return(0,l.jsxs)("div",{children:[(0,l.jsx)(o.Z,{className:"mx-auto",onClick:()=>p(!0),children:"+ Create New Key"}),(0,l.jsx)(L.Z,{title:"Create Key",visible:x,width:800,footer:null,onOk:f,onCancel:w,children:(0,l.jsxs)(U.Z,{form:u,onFinish:k,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:["App Owner"===r||"Admin"===r?(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(U.Z.Item,{label:"Key Name",name:"key_alias",children:(0,l.jsx)(z.Z,{})}),(0,l.jsx)(U.Z.Item,{label:"Team ID",name:"team_id",children:(0,l.jsx)(z.Z,{placeholder:"ai_team",defaultValue:s||""})}),(0,l.jsx)(U.Z.Item,{label:"Models",name:"models",children:(0,l.jsx)(D.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:h.map(e=>(0,l.jsx)(K,{value:e,children:e},e))})}),(0,l.jsx)(U.Z.Item,{label:"Soft Budget (USD) Monthly",name:"soft_budget",initialValue:50,children:(0,l.jsx)(B.Z,{step:.01,precision:2,defaultValue:50,width:200})}),(0,l.jsx)(U.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,l.jsx)(B.Z,{step:.01,precision:2,width:200})}),(0,l.jsx)(U.Z.Item,{label:"Reset Budget",name:"budget_duration",children:(0,l.jsxs)(D.default,{defaultValue:null,placeholder:"n/a",children:[(0,l.jsx)(D.default.Option,{value:"24h",children:"daily"}),(0,l.jsx)(D.default.Option,{value:"30d",children:"monthly"})]})}),(0,l.jsx)(U.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,l.jsx)(B.Z,{step:1,width:400})}),(0,l.jsx)(U.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,l.jsx)(B.Z,{step:1,width:400})}),(0,l.jsx)(U.Z.Item,{label:"Expire Key (eg: 30s, 30h, 30d)",name:"duration",children:(0,l.jsx)(z.Z,{})}),(0,l.jsx)(U.Z.Item,{label:"Metadata",name:"metadata",children:(0,l.jsx)(z.Z.TextArea,{rows:4,placeholder:"Enter metadata as JSON"})})]}):(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(U.Z.Item,{label:"Key Name",name:"key_alias",children:(0,l.jsx)(z.Z,{})}),(0,l.jsx)(U.Z.Item,{label:"Team ID (Contact Group)",name:"team_id",children:(0,l.jsx)(z.Z,{placeholder:"ai_team"})}),(0,l.jsx)(U.Z.Item,{label:"Description",name:"description",children:(0,l.jsx)(z.Z.TextArea,{placeholder:"Enter description",rows:4})})]}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(q.ZP,{htmlType:"submit",children:"Create Key"})})]})}),j&&(0,l.jsx)(L.Z,{visible:x,onOk:f,onCancel:w,footer:null,children:(0,l.jsx)(F.Z,{numItems:1,className:"gap-2 w-full",children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(O.Z,{children:"Save your Key"}),(0,l.jsx)(E.Z,{numColSpan:1,children:(0,l.jsxs)("p",{children:["Please save this secret key somewhere safe and accessible. For security reasons, ",(0,l.jsx)("b",{children:"you will not be able to view it again"})," ","through your LiteLLM account. If you lose this secret key, you will need to generate a new one."]})}),(0,l.jsx)(E.Z,{numColSpan:1,children:null!=j?(0,l.jsxs)("div",{children:[(0,l.jsxs)(R.Z,{children:["API Key: ",j]}),(0,l.jsx)(O.Z,{className:"mt-6",children:"Budgets"}),(0,l.jsxs)(R.Z,{children:["Soft Limit Budget: $",y]}),(0,l.jsx)(o.Z,{className:"mt-3",onClick:_,children:"Test Slack Alert"}),(0,l.jsxs)(R.Z,{className:"mt-2",children:["(LiteLLM Docs -",(0,l.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/alerting",target:"_blank",className:"text-blue-500",children:"Set Up Slack Alerting)"})]})]}):(0,l.jsx)(R.Z,{children:"Key being created, this might take 30s"})})]})})})]})},J=s(33393),G=s(61244),W=s(10827),$=s(3851),H=s(2044),Y=s(64167),X=s(74480),Q=s(7178),ee=s(9853),et=s(56863),es=e=>{let{token:t,accessToken:s,keySpend:r,keyBudget:a,keyName:i}=e,[c,d]=(0,n.useState)(!1),[h,m]=(0,n.useState)(null),[u,x]=(0,n.useState)(""),[p,j]=(0,n.useState)(null),y=async()=>{try{if(null==s||null==t)return;console.log("accessToken: ".concat(s,"; token: ").concat(t));let e=await g(s,t);console.log("Response:",e),m(e);let l=await P(s,e);console.log("Response2:",l);let n=[...e,...l.response];m(n),x(l.predicted_spend),console.log("Combined Data:",n)}catch(e){console.error("There was an error fetching the data",e)}};return t?(0,l.jsxs)("div",{children:[(0,l.jsx)(o.Z,{size:"xs",onClick:()=>{console.log("Show Modal triggered"),d(!0),y()},variant:"secondary",children:"View Spend Report"}),(0,l.jsxs)(L.Z,{visible:c,width:1400,onOk:()=>{d(!1)},onCancel:()=>{d(!1)},footer:null,children:[(0,l.jsxs)(O.Z,{style:{textAlign:"left"},children:["Key Name: ",i]}),(0,l.jsxs)(et.Z,{children:["Monthly Spend $",r]}),(0,l.jsx)(O.Z,{children:u}),(0,l.jsx)(M.Z,{className:"mt-6 mb-6",children:h&&(0,l.jsx)(ee.Z,{className:"mt-6",data:h,colors:["blue","amber"],index:"date",categories:["spend","predicted_spend"],yAxisWidth:80})})]})]}):null},el=e=>{let{userID:t,accessToken:s,data:r,setData:a}=e,[i,c]=(0,n.useState)(!1),[d,h]=(0,n.useState)(!1),[u,x]=(0,n.useState)(null),p=async e=>{null!=r&&(x(e),localStorage.removeItem("userData"+t),h(!0))},j=async()=>{if(null!=u&&null!=r){try{await m(s,u);let e=r.filter(e=>e.token!==u);a(e)}catch(e){console.error("Error deleting the key:",e)}h(!1),x(null)}};if(null!=r)return console.log("RERENDER TRIGGERED"),(0,l.jsxs)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh] mb-4",children:[(0,l.jsxs)(W.Z,{className:"mt-5",children:[(0,l.jsx)(Y.Z,{children:(0,l.jsxs)(Q.Z,{children:[(0,l.jsx)(X.Z,{children:"Key Alias"}),(0,l.jsx)(X.Z,{children:"Secret Key"}),(0,l.jsx)(X.Z,{children:"Spend (USD)"}),(0,l.jsx)(X.Z,{children:"Key Budget (USD)"}),(0,l.jsx)(X.Z,{children:"Spend Report"}),(0,l.jsx)(X.Z,{children:"Team ID"}),(0,l.jsx)(X.Z,{children:"Metadata"}),(0,l.jsx)(X.Z,{children:"Models"}),(0,l.jsx)(X.Z,{children:"TPM / RPM Limits"}),(0,l.jsx)(X.Z,{children:"Expires"})]})}),(0,l.jsx)($.Z,{children:r.map(e=>(console.log(e),"litellm-dashboard"===e.team_id)?null:(0,l.jsxs)(Q.Z,{children:[(0,l.jsx)(H.Z,{children:null!=e.key_alias?(0,l.jsx)(R.Z,{children:e.key_alias}):(0,l.jsx)(R.Z,{children:"Not Set"})}),(0,l.jsx)(H.Z,{children:(0,l.jsx)(R.Z,{children:e.key_name})}),(0,l.jsx)(H.Z,{children:(0,l.jsx)(R.Z,{children:e.spend})}),(0,l.jsx)(H.Z,{children:null!=e.max_budget?(0,l.jsx)(R.Z,{children:e.max_budget}):(0,l.jsx)(R.Z,{children:"Unlimited Budget"})}),(0,l.jsx)(H.Z,{children:(0,l.jsx)(es,{token:e.token,accessToken:s,keySpend:e.spend,keyBudget:e.max_budget,keyName:e.key_name})}),(0,l.jsx)(H.Z,{children:(0,l.jsx)(R.Z,{children:e.team_id})}),(0,l.jsx)(H.Z,{children:(0,l.jsx)(R.Z,{children:JSON.stringify(e.metadata)})}),(0,l.jsx)(H.Z,{children:(0,l.jsx)(R.Z,{children:JSON.stringify(e.models)})}),(0,l.jsx)(H.Z,{children:(0,l.jsxs)(R.Z,{children:["TPM Limit: ",e.tpm_limit?e.tpm_limit:"Unlimited"," ",(0,l.jsx)("br",{})," RPM Limit:"," ",e.rpm_limit?e.rpm_limit:"Unlimited"]})}),(0,l.jsx)(H.Z,{children:null!=e.expires?(0,l.jsx)(R.Z,{children:e.expires}):(0,l.jsx)(R.Z,{children:"Never expires"})}),(0,l.jsx)(H.Z,{children:(0,l.jsx)(G.Z,{onClick:()=>p(e.token),icon:J.Z,size:"sm"})})]},e.token))})]}),d&&(0,l.jsx)("div",{className:"fixed z-10 inset-0 overflow-y-auto",children:(0,l.jsxs)("div",{className:"flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0",children:[(0,l.jsx)("div",{className:"fixed inset-0 transition-opacity","aria-hidden":"true",children:(0,l.jsx)("div",{className:"absolute inset-0 bg-gray-500 opacity-75"})}),(0,l.jsx)("span",{className:"hidden sm:inline-block sm:align-middle sm:h-screen","aria-hidden":"true",children:""}),(0,l.jsxs)("div",{className:"inline-block align-bottom bg-white rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full",children:[(0,l.jsx)("div",{className:"bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4",children:(0,l.jsx)("div",{className:"sm:flex sm:items-start",children:(0,l.jsxs)("div",{className:"mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left",children:[(0,l.jsx)("h3",{className:"text-lg leading-6 font-medium text-gray-900",children:"Delete Key"}),(0,l.jsx)("div",{className:"mt-2",children:(0,l.jsx)("p",{className:"text-sm text-gray-500",children:"Are you sure you want to delete this key ?"})})]})})}),(0,l.jsxs)("div",{className:"bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse",children:[(0,l.jsx)(o.Z,{onClick:j,color:"red",className:"ml-2",children:"Delete"}),(0,l.jsx)(o.Z,{onClick:()=>{h(!1),x(null)},children:"Cancel"})]})]})]})})]})},en=e=>{let{userID:t,userSpendData:s,userRole:r,accessToken:a}=e;console.log("User SpendData:",s);let[o,i]=(0,n.useState)(null==s?void 0:s.spend),[c,d]=(0,n.useState)((null==s?void 0:s.max_budget)||null);return(0,n.useEffect)(()=>{(async()=>{if("Admin"===r)try{let e=await b(a,"litellm-proxy-budget");console.log("Result from callSpendUsers:",e);let t=e[0];i(null==t?void 0:t.spend),d((null==t?void 0:t.max_budget)||null)}catch(e){console.error("Failed to get spend for user",e)}})()},[r,a,t]),(0,l.jsx)(l.Fragment,{children:(0,l.jsxs)(M.Z,{className:"mx-auto mb-4",children:[(0,l.jsxs)(et.Z,{children:["$",o]}),(0,l.jsxs)(O.Z,{children:["/ ",null!==c?"$".concat(c," limit"):"No limit"]})]})})},er=s(36083),ea=s(68967),eo=s(27166),ei=e=>{let{teams:t,setSelectedTeam:s}=e,{Title:r,Paragraph:a}=er.default,[o,i]=(0,n.useState)("");return(0,l.jsxs)("div",{className:"mt-10",children:[(0,l.jsx)(r,{level:4,children:"Default Team"}),(0,l.jsx)(a,{children:"If you belong to multiple teams, this setting controls which team is used by default when creating new API Keys."}),t&&t.length>0?(0,l.jsx)(ea.Z,{defaultValue:"0",children:t.map((e,t)=>(0,l.jsx)(eo.Z,{value:String(t),onClick:()=>s(e),children:e.team_alias},t))}):(0,l.jsxs)(a,{children:["No team created. ",(0,l.jsx)("b",{children:"Defaulting to personal account."})]})]})},ec=s(37963);console.log("isLocal:",!1);var ed=e=>{let{userID:t,userRole:s,teams:a,keys:o,setUserRole:i,userEmail:c,setUserEmail:d,setTeams:h,setKeys:m}=e,[x,p]=(0,n.useState)(null),g=(0,r.useSearchParams)();g.get("viewSpend"),(0,r.useRouter)();let y=g.get("token"),[Z,f]=(0,n.useState)(null),[w,k]=(0,n.useState)([]),[_,b]=(0,n.useState)(a?a[0]:null);if(window.addEventListener("beforeunload",function(){sessionStorage.clear()}),(0,n.useEffect)(()=>{if(y){let e=(0,ec.o)(y);if(e){if(console.log("Decoded token:",e),console.log("Decoded key:",e.key),f(e.key),e.user_role){let t=function(e){if(!e)return"Undefined Role";switch(console.log("Received user role: ".concat(e)),e.toLowerCase()){case"app_owner":case"demo_app_owner":return"App Owner";case"app_admin":case"proxy_admin":return"Admin";case"proxy_admin_viewer":return"Admin Viewer";case"app_user":return"App User";default:return"Unknown Role"}}(e.user_role);console.log("Decoded user_role:",t),i(t)}else console.log("User role not defined");e.user_email?d(e.user_email):console.log("User Email is not set ".concat(e))}}if(t&&Z&&s&&!o&&!x){let e=sessionStorage.getItem("userModels"+t);e?k(JSON.parse(e)):(async()=>{try{let e=await u(Z,t,s);console.log("received teams in user dashboard: ".concat(Object.keys(e),"; team values: ").concat(Object.entries(e.teams))),p(e.user_info),m(e.keys),h(e.teams),b(e.teams?e.teams[0]:null),sessionStorage.setItem("userData"+t,JSON.stringify(e.keys)),sessionStorage.setItem("userSpendData"+t,JSON.stringify(e.user_info));let l=(await j(Z,t,s)).data.map(e=>e.id);console.log("available_model_names:",l),k(l),console.log("userModels:",w),sessionStorage.setItem("userModels"+t,JSON.stringify(l))}catch(e){console.error("There was an error fetching the data",e)}})()}},[t,y,Z,o,s]),null==t||null==y){let e="/sso/key/generate";return console.log("Full URL:",e),window.location.href=e,null}if(null==Z)return null;if(null==s&&i("App Owner"),s&&"Admin Viewer"==s){let{Title:e,Paragraph:t}=er.default;return(0,l.jsxs)("div",{children:[(0,l.jsx)(e,{level:1,children:"Access Denied"}),(0,l.jsx)(t,{children:"Ask your proxy admin for access to create keys"})]})}return(0,l.jsx)("div",{children:(0,l.jsx)(F.Z,{numItems:1,className:"gap-0 p-10 h-[75vh] w-full",children:(0,l.jsxs)(E.Z,{numColSpan:1,children:[(0,l.jsx)(en,{userID:t,userSpendData:x,userRole:s,accessToken:Z}),(0,l.jsx)(el,{userID:t,accessToken:Z,data:o,setData:m}),(0,l.jsx)(V,{userID:t,teamID:_?_.team_id:null,userRole:s,userModels:w,accessToken:Z,data:o,setData:m}),(0,l.jsx)(ei,{teams:a,setSelectedTeam:b})]})})})},eh=s(5);let{Option:em}=D.default;var eu=e=>{let{userModels:t,accessToken:s,userID:r}=e,[a]=U.Z.useForm(),[i,d]=(0,n.useState)(!1),h=async e=>{try{c.ZP.info("Requesting access");let{selectedModel:t,accessReason:l}=e;await v(s,t,r,l),d(!0)}catch(e){console.error("Error requesting access:",e)}};return(0,l.jsxs)("div",{children:[(0,l.jsx)(o.Z,{size:"xs",onClick:()=>d(!0),children:"Request Access"}),(0,l.jsx)(L.Z,{title:"Request Access",visible:i,width:800,footer:null,onOk:()=>{d(!1),a.resetFields()},onCancel:()=>{d(!1),a.resetFields()},children:(0,l.jsxs)(U.Z,{form:a,onFinish:h,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsx)(U.Z.Item,{label:"Select Model",name:"selectedModel",children:(0,l.jsx)(D.default,{placeholder:"Select model",style:{width:"100%"},children:t.map(e=>(0,l.jsx)(em,{value:e,children:e},e))})}),(0,l.jsx)(U.Z.Item,{label:"Reason for Access",name:"accessReason",children:(0,l.jsx)(z.Z.TextArea,{rows:4,placeholder:"Enter reason for access"})}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(o.Z,{children:"Request Access"})})]})})]})},ex=e=>{let{accessToken:t,token:s,userRole:r,userID:a}=e,[o,i]=(0,n.useState)({data:[]}),[c,d]=(0,n.useState)([]),[h,m]=(0,n.useState)([]);if((0,n.useEffect)(()=>{if(!t||!s||!r||!a)return;let e=async()=>{try{let e=await x(t,a,r);console.log("Model data response:",e.data),i(e);let s=await p(t,a,r);if(console.log("Model metrics response:",s),d(s),"Admin"===r&&t){let e=await S(t);console.log("Pending Requests:",h),m(e.requests||[])}}catch(e){console.error("There was an error fetching the model data",e)}};t&&s&&r&&a&&e()},[t,s,r,a]),!o||!t||!s||!r||!a)return(0,l.jsx)("div",{children:"Loading..."});let u=[];for(let e=0;e(0,l.jsxs)(Q.Z,{children:[(0,l.jsx)(H.Z,{children:(0,l.jsx)(O.Z,{children:e.model_name})}),(0,l.jsx)(H.Z,{children:e.provider}),"Admin"===r&&(0,l.jsx)(H.Z,{children:e.api_base}),(0,l.jsx)(H.Z,{children:e.user_access?(0,l.jsx)(eh.Z,{color:"green",children:"Yes"}):(0,l.jsx)(eu,{userModels:u,accessToken:t,userID:a})}),(0,l.jsx)(H.Z,{children:e.input_cost}),(0,l.jsx)(H.Z,{children:e.output_cost}),(0,l.jsx)(H.Z,{children:e.max_tokens})]},e.model_name))})]})}),(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(O.Z,{children:"Model Statistics (Number Requests, Latency)"}),(0,l.jsx)(ee.Z,{data:c,index:"model",categories:["num_requests","avg_latency_seconds"],colors:["blue","red"],yAxisWidth:100,tickGap:5})]})]})})},ep=s(92836),ej=s(26734),eg=s(41608),ey=s(32126),eZ=s(23682);let{Option:ef}=D.default;var ew=e=>{let{userID:t,accessToken:s}=e,[r]=U.Z.useForm(),[a,i]=(0,n.useState)(!1),[d,m]=(0,n.useState)(null),[u,x]=(0,n.useState)([]);(0,n.useEffect)(()=>{(async()=>{try{let e=await j(s,t,"any"),l=[];for(let t=0;t{i(!1),r.resetFields()},g=()=>{i(!1),m(null),r.resetFields()},y=async e=>{try{c.ZP.info("Making API Call"),i(!0),console.log("formValues in create user:",e);let l=await h(s,t,e);console.log("user create Response:",l),m(l.key),c.ZP.success("API user Created"),r.resetFields(),localStorage.removeItem("userData"+t)}catch(e){console.error("Error creating the user:",e)}};return(0,l.jsxs)("div",{children:[(0,l.jsx)(o.Z,{className:"mx-auto",onClick:()=>i(!0),children:"+ Create New User"}),(0,l.jsx)(L.Z,{title:"Create User",visible:a,width:800,footer:null,onOk:p,onCancel:g,children:(0,l.jsxs)(U.Z,{form:r,onFinish:y,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsx)(U.Z.Item,{label:"User ID",name:"user_id",children:(0,l.jsx)(z.Z,{placeholder:"Enter User ID"})}),(0,l.jsx)(U.Z.Item,{label:"Team ID",name:"team_id",children:(0,l.jsx)(z.Z,{placeholder:"ai_team"})}),(0,l.jsx)(U.Z.Item,{label:"Models",name:"models",children:(0,l.jsx)(D.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:u.map(e=>(0,l.jsx)(ef,{value:e,children:e},e))})}),(0,l.jsx)(U.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,l.jsx)(B.Z,{step:.01,precision:2,width:200})}),(0,l.jsx)(U.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,l.jsx)(B.Z,{step:1,width:400})}),(0,l.jsx)(U.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,l.jsx)(B.Z,{step:1,width:400})}),(0,l.jsx)(U.Z.Item,{label:"Duration (eg: 30s, 30h, 30d)",name:"duration",children:(0,l.jsx)(z.Z,{})}),(0,l.jsx)(U.Z.Item,{label:"Metadata",name:"metadata",children:(0,l.jsx)(z.Z.TextArea,{rows:4,placeholder:"Enter metadata as JSON"})}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(q.ZP,{htmlType:"submit",children:"Create User"})})]})}),d&&(0,l.jsxs)(L.Z,{title:"Save Your User",visible:a,onOk:p,onCancel:g,footer:null,children:[(0,l.jsxs)("p",{children:["Please save this secret user somewhere safe and accessible. For security reasons, ",(0,l.jsx)("b",{children:"you will not be able to view it again"})," ","through your LiteLLM account. If you lose this secret user, you will need to generate a new one."]}),(0,l.jsx)("p",{children:null!=d?"API user: ".concat(d):"User being created, this might take 30s"})]})]})},ek=e=>{let{accessToken:t,token:s,keys:r,userRole:a,userID:o,setKeys:i}=e,[c,d]=(0,n.useState)(null),[h,m]=(0,n.useState)(null),[x,p]=(0,n.useState)(1);if((0,n.useEffect)(()=>{if(!t||!s||!a||!o)return;let e=async()=>{try{let e=await u(t,null,a,!0);console.log("user data response:",e),d(e)}catch(e){console.error("There was an error fetching the model data",e)}};t&&s&&a&&o&&!c&&e();let l=async()=>{try{let e=await w(t,null);console.log("user data response:",e),m(e)}catch(e){console.error("There was an error fetching the model data",e)}};a&&("Admin"==a||"Admin Viewer"==a)&&!h&&l()},[t,s,a,o]),!c||!t||!s||!a||!o)return(0,l.jsx)("div",{children:"Loading..."});let j=async e=>{try{let s=await w(t,e);console.log("user data response:",s),m(s)}catch(e){console.error("There was an error fetching the model data",e)}};return(0,l.jsx)("div",{style:{width:"100%"},children:(0,l.jsxs)(F.Z,{className:"gap-2 p-10 h-[75vh] w-full",children:[(0,l.jsx)(ew,{userID:o,accessToken:t}),(0,l.jsx)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh] mb-4",children:(0,l.jsxs)(ej.Z,{children:[(0,l.jsxs)(eg.Z,{variant:"line",defaultValue:"1",children:[(0,l.jsx)(ep.Z,{value:"1",children:"Key Owners"}),(0,l.jsx)(ep.Z,{value:"2",children:"End-Users"})]}),(0,l.jsxs)(eZ.Z,{children:[(0,l.jsx)(ey.Z,{children:(0,l.jsxs)(W.Z,{className:"mt-5",children:[(0,l.jsx)(Y.Z,{children:(0,l.jsxs)(Q.Z,{children:[(0,l.jsx)(X.Z,{children:"User ID"}),(0,l.jsx)(X.Z,{children:"User Role"}),(0,l.jsx)(X.Z,{children:"User Models"}),(0,l.jsx)(X.Z,{children:"User Spend ($ USD)"}),(0,l.jsx)(X.Z,{children:"User Max Budget ($ USD)"})]})}),(0,l.jsx)($.Z,{children:c.map(e=>(0,l.jsxs)(Q.Z,{children:[(0,l.jsx)(H.Z,{children:e.user_id}),(0,l.jsx)(H.Z,{children:e.user_role?e.user_role:"app_owner"}),(0,l.jsx)(H.Z,{children:e.models&&e.models.length>0?e.models:"All Models"}),(0,l.jsx)(H.Z,{children:e.spend?e.spend:0}),(0,l.jsx)(H.Z,{children:e.max_budget?e.max_budget:"Unlimited"})]},e.user_id))})]})}),(0,l.jsxs)(ey.Z,{children:[(0,l.jsxs)("div",{className:"flex items-center",children:[(0,l.jsx)("div",{className:"flex-1"}),(0,l.jsxs)("div",{className:"flex-1 flex justify-between items-center",children:[(0,l.jsx)(R.Z,{className:"w-1/4 mr-2 text-right",children:"Key"}),(0,l.jsx)(ea.Z,{defaultValue:"1",className:"w-3/4",children:null==r?void 0:r.map((e,t)=>{if(e&&null!==e.key_name&&e.key_name.length>0)return(0,l.jsx)(eo.Z,{value:String(t),onClick:()=>j(e.token),children:e.key_name},t)})})]})]}),(0,l.jsxs)(W.Z,{children:[(0,l.jsx)(Y.Z,{children:(0,l.jsxs)(Q.Z,{children:[(0,l.jsx)(X.Z,{children:"End User"}),(0,l.jsx)(X.Z,{children:"Spend"}),(0,l.jsx)(X.Z,{children:"Total Events"})]})}),(0,l.jsx)($.Z,{children:null==h?void 0:h.map((e,t)=>(0,l.jsxs)(Q.Z,{children:[(0,l.jsx)(H.Z,{children:e.end_user}),(0,l.jsx)(H.Z,{children:e.total_spend}),(0,l.jsx)(H.Z,{children:e.total_events})]},t))})]})]})]})]})}),function(){if(!c)return null;let e=Math.ceil(c.length/25),t=Math.min(25*x,c.length);return(0,l.jsxs)("div",{className:"flex justify-between items-center",children:[(0,l.jsxs)("div",{children:["Showing ",(x-1)*25+1," – ",t," of ",c.length]}),(0,l.jsxs)("div",{className:"flex",children:[(0,l.jsx)("button",{className:"bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-l focus:outline-none",disabled:1===x,onClick:()=>p(x-1),children:"← Prev"}),(0,l.jsx)("button",{className:"bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-r focus:outline-none",disabled:x===e,onClick:()=>p(x+1),children:"Next →"})]})]})}()]})})},e_=s(8510),eb=e=>{let{teams:t,searchParams:s,accessToken:r,setTeams:a}=e,[i]=U.Z.useForm(),[d]=U.Z.useForm(),{Title:h,Paragraph:m}=er.default,[u,x]=(0,n.useState)(""),[p,j]=(0,n.useState)(t?t[0]:null),[g,y]=(0,n.useState)(!1),[Z,f]=(0,n.useState)(!1),w=async e=>{try{if(null!=r){c.ZP.info("Making API Call");let s=await A(r,e);null!==t?a([...t,s]):a([s]),console.log("response for team create call: ".concat(s)),y(!1)}}catch(e){console.error("Error creating the key:",e)}},k=async e=>{try{if(null!=r&&null!=t){c.ZP.info("Making API Call");let s={role:"user",user_email:e.user_email,user_id:e.user_id},l=await C(r,p.team_id,s);console.log("response for team create call: ".concat(l.data));let n=t.findIndex(e=>(console.log("team.team_id=".concat(e.team_id,"; response.data.team_id=").concat(l.data.team_id)),e.team_id===l.data.team_id));if(console.log("foundIndex: ".concat(n)),-1!==n){let e=[...t];e[n]=l.data,a(e),j(l.data)}f(!1)}}catch(e){console.error("Error creating the key:",e)}};return console.log("received teams ".concat(t)),(0,l.jsx)("div",{className:"w-full",children:(0,l.jsxs)(F.Z,{numItems:1,className:"gap-2 p-2 h-[75vh] w-full",children:[(0,l.jsxs)(E.Z,{numColSpan:1,children:[(0,l.jsx)(h,{level:4,children:"All Teams"}),(0,l.jsx)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,l.jsxs)(W.Z,{children:[(0,l.jsx)(Y.Z,{children:(0,l.jsxs)(Q.Z,{children:[(0,l.jsx)(X.Z,{children:"Team Name"}),(0,l.jsx)(X.Z,{children:"Spend (USD)"}),(0,l.jsx)(X.Z,{children:"Budget (USD)"}),(0,l.jsx)(X.Z,{children:"TPM / RPM Limits"})]})}),(0,l.jsx)($.Z,{children:t&&t.length>0?t.map(e=>(0,l.jsxs)(Q.Z,{children:[(0,l.jsx)(H.Z,{children:e.team_alias}),(0,l.jsx)(H.Z,{children:e.spend}),(0,l.jsx)(H.Z,{children:e.max_budget?e.max_budget:"No limit"}),(0,l.jsx)(H.Z,{children:(0,l.jsxs)(R.Z,{children:["TPM Limit:"," ",e.tpm_limit?e.tpm_limit:"Unlimited"," ",(0,l.jsx)("br",{})," RPM Limit:"," ",e.rpm_limit?e.rpm_limit:"Unlimited"]})}),(0,l.jsx)(H.Z,{children:(0,l.jsx)(G.Z,{icon:e_.Z,size:"sm"})})]},e.team_id)):null})]})})]}),(0,l.jsxs)(E.Z,{numColSpan:1,children:[(0,l.jsx)(o.Z,{className:"mx-auto",onClick:()=>y(!0),children:"+ Create New Team"}),(0,l.jsx)(L.Z,{title:"Create Team",visible:g,width:800,footer:null,onOk:()=>{y(!1),i.resetFields()},onCancel:()=>{y(!1),i.resetFields()},children:(0,l.jsxs)(U.Z,{form:i,onFinish:w,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(U.Z.Item,{label:"Team Name",name:"team_alias",children:(0,l.jsx)(z.Z,{})}),(0,l.jsx)(U.Z.Item,{label:"Models",name:"models",children:(0,l.jsx)(D.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"}})}),(0,l.jsx)(U.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,l.jsx)(B.Z,{step:.01,precision:2,width:200})}),(0,l.jsx)(U.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,l.jsx)(B.Z,{step:1,width:400})}),(0,l.jsx)(U.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,l.jsx)(B.Z,{step:1,width:400})})]}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(q.ZP,{htmlType:"submit",children:"Create Team"})})]})})]}),(0,l.jsxs)(E.Z,{numColSpan:1,children:[(0,l.jsx)(h,{level:4,children:"Team Members"}),(0,l.jsx)(m,{children:"If you belong to multiple teams, this setting controls which teams members you see."}),t&&t.length>0?(0,l.jsx)(ea.Z,{defaultValue:"0",children:t.map((e,t)=>(0,l.jsx)(eo.Z,{value:String(t),onClick:()=>{j(e)},children:e.team_alias},t))}):(0,l.jsxs)(m,{children:["No team created. ",(0,l.jsx)("b",{children:"Defaulting to personal account."})]})]}),(0,l.jsx)(E.Z,{numColSpan:1,children:(0,l.jsx)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,l.jsxs)(W.Z,{children:[(0,l.jsx)(Y.Z,{children:(0,l.jsxs)(Q.Z,{children:[(0,l.jsx)(X.Z,{children:"Member Name"}),(0,l.jsx)(X.Z,{children:"Role"}),(0,l.jsx)(X.Z,{children:"Action"})]})}),(0,l.jsx)($.Z,{children:p?p.members_with_roles.map((e,t)=>(0,l.jsxs)(Q.Z,{children:[(0,l.jsx)(H.Z,{children:e.user_email?e.user_email:e.user_id?e.user_id:null}),(0,l.jsx)(H.Z,{children:e.role}),(0,l.jsx)(H.Z,{children:(0,l.jsx)(G.Z,{icon:e_.Z,size:"sm"})})]},t)):null})]})})}),(0,l.jsxs)(E.Z,{numColSpan:1,children:[(0,l.jsx)(o.Z,{className:"mx-auto mb-5",onClick:()=>f(!0),children:"+ Add member"}),(0,l.jsx)(L.Z,{title:"Add member",visible:Z,width:800,footer:null,onOk:()=>{f(!1),d.resetFields()},onCancel:()=>{f(!1),d.resetFields()},children:(0,l.jsxs)(U.Z,{form:i,onFinish:k,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(U.Z.Item,{label:"Email",name:"user_email",className:"mb-4",children:(0,l.jsx)(z.Z,{name:"user_email",className:"px-3 py-2 border rounded-md w-full"})}),(0,l.jsx)("div",{className:"text-center mb-4",children:"OR"}),(0,l.jsx)(U.Z.Item,{label:"User ID",name:"user_id",className:"mb-4",children:(0,l.jsx)(z.Z,{name:"user_id",className:"px-3 py-2 border rounded-md w-full"})})]}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(q.ZP,{htmlType:"submit",children:"Add member"})})]})})]})]})})},ev=e=>{let{searchParams:t,accessToken:s}=e,[r]=U.Z.useForm(),[a]=U.Z.useForm(),{Title:i,Paragraph:d}=er.default,[h,m]=(0,n.useState)(""),[u,x]=(0,n.useState)(null),[p,j]=(0,n.useState)(!1);(0,n.useEffect)(()=>{(async()=>{if(null!=s){let e=[],t=await N(s,"proxy_admin_viewer");t.forEach(t=>{e.push({user_role:t.user_role,user_id:t.user_id,user_email:t.user_email})}),console.log("proxy viewers: ".concat(t));let l=await N(s,"proxy_admin");l.forEach(t=>{e.push({user_role:t.user_role,user_id:t.user_id,user_email:t.user_email})}),console.log("proxy admins: ".concat(l)),console.log("combinedList: ".concat(e)),x(e)}})()},[s]);let g=async e=>{try{if(null!=s&&null!=u){c.ZP.info("Making API Call"),e.user_email,e.user_id;let t=await I(s,e);console.log("response for team create call: ".concat(t));let l=u.findIndex(e=>(console.log("user.user_id=".concat(e.user_id,"; response.user_id=").concat(t.user_id)),e.user_id===t.user_id));console.log("foundIndex: ".concat(l)),-1==l&&(console.log("updates admin with new user"),u.push(t),x(u)),j(!1)}}catch(e){console.error("Error creating the key:",e)}};return console.log("admins: ".concat(null==u?void 0:u.length)),(0,l.jsxs)("div",{className:"w-full m-2",children:[(0,l.jsx)(i,{level:4,children:"Restricted Access"}),(0,l.jsxs)(d,{children:["Add other people to just view spend. They cannot create keys, teams or grant users access to new models."," ",(0,l.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/ui#restrict-ui-access",children:"Requires SSO Setup"})]}),(0,l.jsxs)(F.Z,{numItems:1,className:"gap-2 p-0 w-full",children:[(0,l.jsx)(E.Z,{numColSpan:1,children:(0,l.jsx)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,l.jsxs)(W.Z,{children:[(0,l.jsx)(Y.Z,{children:(0,l.jsxs)(Q.Z,{children:[(0,l.jsx)(X.Z,{children:"Member Name"}),(0,l.jsx)(X.Z,{children:"Role"}),(0,l.jsx)(X.Z,{children:"Action"})]})}),(0,l.jsx)($.Z,{children:u?u.map((e,t)=>(0,l.jsxs)(Q.Z,{children:[(0,l.jsx)(H.Z,{children:e.user_email?e.user_email:e.user_id?e.user_id:null}),(0,l.jsx)(H.Z,{children:e.user_role}),(0,l.jsx)(H.Z,{children:(0,l.jsx)(G.Z,{icon:e_.Z,size:"sm"})})]},t)):null})]})})}),(0,l.jsxs)(E.Z,{numColSpan:1,children:[(0,l.jsx)(o.Z,{className:"mx-auto mb-5",onClick:()=>j(!0),children:"+ Add viewer"}),(0,l.jsx)(L.Z,{title:"Add viewer",visible:p,width:800,footer:null,onOk:()=>{j(!1),a.resetFields()},onCancel:()=>{j(!1),a.resetFields()},children:(0,l.jsxs)(U.Z,{form:r,onFinish:g,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(U.Z.Item,{label:"Email",name:"user_email",className:"mb-4",children:(0,l.jsx)(z.Z,{name:"user_email",className:"px-3 py-2 border rounded-md w-full"})}),(0,l.jsx)("div",{className:"text-center mb-4",children:"OR"}),(0,l.jsx)(U.Z.Item,{label:"User ID",name:"user_id",className:"mb-4",children:(0,l.jsx)(z.Z,{name:"user_id",className:"px-3 py-2 border rounded-md w-full"})})]}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(q.ZP,{htmlType:"submit",children:"Add member"})})]})})]})]})]})},eS=s(12968),eN=s(67951);async function eA(e,t,s,l){console.log("isLocal:",!1);let n=window.location.origin,r=new eS.ZP.OpenAI({apiKey:l,baseURL:n,dangerouslyAllowBrowser:!0});for await(let l of(await r.chat.completions.create({model:s,stream:!0,messages:[{role:"user",content:e}]})))console.log(l),l.choices[0].delta.content&&t(l.choices[0].delta.content)}var eC=e=>{let{accessToken:t,token:s,userRole:r,userID:a}=e,[o,i]=(0,n.useState)(""),[c,d]=(0,n.useState)([]),[h,m]=(0,n.useState)(void 0),[u,x]=(0,n.useState)(null);(0,n.useEffect)(()=>{t&&s&&r&&a&&(async()=>{let e=await j(t,a,r);console.log("model_info:",e),(null==e?void 0:e.data.length)>0&&(x(e.data),m(e.data[0].id))})()},[t,a,r]);let p=(e,t)=>{d(s=>{let l=s[s.length-1];return l&&l.role===e?[...s.slice(0,s.length-1),{role:e,content:l.content+t}]:[...s,{role:e,content:t}]})},g=async()=>{if(""!==o.trim()&&t&&s&&r&&a){d(e=>[...e,{role:"user",content:o}]);try{h&&await eA(o,e=>p("assistant",e),h,t)}catch(e){console.error("Error fetching model response",e),p("assistant","Error fetching model response")}i("")}};if(r&&"Admin Viewer"==r){let{Title:e,Paragraph:t}=er.default;return(0,l.jsxs)("div",{children:[(0,l.jsx)(e,{level:1,children:"Access Denied"}),(0,l.jsx)(t,{children:"Ask your proxy admin for access to test models"})]})}return(0,l.jsx)("div",{style:{width:"100%",position:"relative"},children:(0,l.jsx)(F.Z,{className:"gap-2 p-10 h-[75vh] w-full",children:(0,l.jsx)(M.Z,{children:(0,l.jsxs)(ej.Z,{children:[(0,l.jsxs)(eg.Z,{className:"mt-4",children:[(0,l.jsx)(ep.Z,{children:"Chat"}),(0,l.jsx)(ep.Z,{children:"API Reference"})]}),(0,l.jsxs)(eZ.Z,{children:[(0,l.jsxs)(ey.Z,{children:[(0,l.jsxs)("div",{children:[(0,l.jsx)("label",{children:"Select Model:"}),(0,l.jsx)("select",{value:h||"",onChange:e=>m(e.target.value),children:null==u?void 0:u.map(e=>(0,l.jsx)("option",{value:e.id,children:e.id},e.id))})]}),(0,l.jsxs)(W.Z,{className:"mt-5",style:{display:"block",maxHeight:"60vh",overflowY:"auto"},children:[(0,l.jsx)(Y.Z,{children:(0,l.jsx)(Q.Z,{children:(0,l.jsx)(H.Z,{children:(0,l.jsx)(O.Z,{children:"Chat"})})})}),(0,l.jsx)($.Z,{children:c.map((e,t)=>(0,l.jsx)(Q.Z,{children:(0,l.jsx)(H.Z,{children:"".concat(e.role,": ").concat(e.content)})},t))})]}),(0,l.jsx)("div",{className:"mt-3",style:{position:"absolute",bottom:5,width:"95%"},children:(0,l.jsxs)("div",{className:"flex",children:[(0,l.jsx)("input",{type:"text",value:o,onChange:e=>i(e.target.value),className:"flex-1 p-2 border rounded-md mr-2",placeholder:"Type your message..."}),(0,l.jsx)("button",{onClick:g,className:"p-2 bg-blue-500 text-white rounded-md",children:"Send"})]})})]}),(0,l.jsx)(ey.Z,{children:(0,l.jsxs)(ej.Z,{children:[(0,l.jsxs)(eg.Z,{children:[(0,l.jsx)(ep.Z,{children:"OpenAI Python SDK"}),(0,l.jsx)(ep.Z,{children:"LlamaIndex"}),(0,l.jsx)(ep.Z,{children:"Langchain Py"})]}),(0,l.jsxs)(eZ.Z,{children:[(0,l.jsx)(ey.Z,{children:(0,l.jsx)(eN.Z,{language:"python",children:'\nimport openai\nclient = openai.OpenAI(\n api_key="your_api_key",\n base_url="http://0.0.0.0:4000" # proxy base url\n)\n\nresponse = client.chat.completions.create(\n model="gpt-3.5-turbo", # model to use from Models Tab\n messages = [\n {\n "role": "user",\n "content": "this is a test request, write a short poem"\n }\n ],\n extra_body={\n "metadata": {\n "generation_name": "ishaan-generation-openai-client",\n "generation_id": "openai-client-gen-id22",\n "trace_id": "openai-client-trace-id22",\n "trace_user_id": "openai-client-user-id2"\n }\n }\n)\n\nprint(response)\n '})}),(0,l.jsx)(ey.Z,{children:(0,l.jsx)(eN.Z,{language:"python",children:'\nimport os, dotenv\n\nfrom llama_index.llms import AzureOpenAI\nfrom llama_index.embeddings import AzureOpenAIEmbedding\nfrom llama_index import VectorStoreIndex, SimpleDirectoryReader, ServiceContext\n\nllm = AzureOpenAI(\n engine="azure-gpt-3.5", # model_name on litellm proxy\n temperature=0.0,\n azure_endpoint="http://0.0.0.0:4000", # litellm proxy endpoint\n api_key="sk-1234", # litellm proxy API Key\n api_version="2023-07-01-preview",\n)\n\nembed_model = AzureOpenAIEmbedding(\n deployment_name="azure-embedding-model",\n azure_endpoint="http://0.0.0.0:4000",\n api_key="sk-1234",\n api_version="2023-07-01-preview",\n)\n\n\ndocuments = SimpleDirectoryReader("llama_index_data").load_data()\nservice_context = ServiceContext.from_defaults(llm=llm, embed_model=embed_model)\nindex = VectorStoreIndex.from_documents(documents, service_context=service_context)\n\nquery_engine = index.as_query_engine()\nresponse = query_engine.query("What did the author do growing up?")\nprint(response)\n\n '})}),(0,l.jsx)(ey.Z,{children:(0,l.jsx)(eN.Z,{language:"python",children:'\nfrom langchain.chat_models import ChatOpenAI\nfrom langchain.prompts.chat import (\n ChatPromptTemplate,\n HumanMessagePromptTemplate,\n SystemMessagePromptTemplate,\n)\nfrom langchain.schema import HumanMessage, SystemMessage\n\nchat = ChatOpenAI(\n openai_api_base="http://0.0.0.0:8000",\n model = "gpt-3.5-turbo",\n temperature=0.1,\n extra_body={\n "metadata": {\n "generation_name": "ishaan-generation-langchain-client",\n "generation_id": "langchain-client-gen-id22",\n "trace_id": "langchain-client-trace-id22",\n "trace_user_id": "langchain-client-user-id2"\n }\n }\n)\n\nmessages = [\n SystemMessage(\n content="You are a helpful assistant that im using to make a test request to."\n ),\n HumanMessage(\n content="test from litellm. tell me why it\'s amazing in 1 sentence"\n ),\n]\nresponse = chat(messages)\n\nprint(response)\n\n '})})]})]})})]})]})})})})},eI=s(33509),eP=s(30569);let{Sider:eT}=eI.default;var eE=e=>{let{setPage:t,userRole:s,defaultSelectedKey:n}=e;return"Admin Viewer"==s?(0,l.jsx)(eI.default,{style:{minHeight:"100vh",maxWidth:"120px"},children:(0,l.jsx)(eT,{width:120,children:(0,l.jsxs)(eP.Z,{mode:"inline",defaultSelectedKeys:n||["4"],style:{height:"100%",borderRight:0},children:[(0,l.jsx)(eP.Z.Item,{onClick:()=>t("api-keys"),children:"API Keys"},"4"),(0,l.jsx)(eP.Z.Item,{onClick:()=>t("models"),children:"Models"},"2"),(0,l.jsx)(eP.Z.Item,{onClick:()=>t("llm-playground"),children:"Chat UI"},"3"),(0,l.jsx)(eP.Z.Item,{onClick:()=>t("usage"),children:"Usage"},"1")]})})}):(0,l.jsx)(eI.default,{style:{minHeight:"100vh",maxWidth:"120px"},children:(0,l.jsx)(eT,{width:120,children:(0,l.jsxs)(eP.Z,{mode:"inline",defaultSelectedKeys:n||["1"],style:{height:"100%",borderRight:0},children:[(0,l.jsx)(eP.Z.Item,{onClick:()=>t("api-keys"),children:"API Keys"},"1"),(0,l.jsx)(eP.Z.Item,{onClick:()=>t("models"),children:"Models"},"2"),(0,l.jsx)(eP.Z.Item,{onClick:()=>t("llm-playground"),children:"Chat UI"},"3"),(0,l.jsx)(eP.Z.Item,{onClick:()=>t("usage"),children:"Usage"},"4"),"Admin"==s?(0,l.jsx)(eP.Z.Item,{onClick:()=>t("users"),children:"Users"},"5"):null,"Admin"==s?(0,l.jsx)(eP.Z.Item,{onClick:()=>t("teams"),children:"Teams"},"6"):null,"Admin"==s?(0,l.jsx)(eP.Z.Item,{onClick:()=>t("admin-panel"),children:"Admin"},"7"):null]})})})},eF=e=>{let{accessToken:t,token:s,userRole:r,userID:a}=e,o=new Date,[i,c]=(0,n.useState)([]),[d,h]=(0,n.useState)([]),[m,u]=(0,n.useState)([]),[x,p]=(0,n.useState)([]),j=new Date(o.getFullYear(),o.getMonth(),1),g=new Date(o.getFullYear(),o.getMonth()+1,0),w=v(j),b=v(g);function v(e){let t=e.getFullYear(),s=e.getMonth()+1,l=e.getDate();return"".concat(t,"-").concat(s<10?"0"+s:s,"-").concat(l<10?"0"+l:l)}return console.log("Start date is ".concat(w)),console.log("End date is ".concat(b)),(0,n.useEffect)(()=>{t&&s&&r&&a&&(async()=>{try{if(console.log("user role: ".concat(r)),"Admin"==r||"Admin Viewer"==r){let e=await Z(t);c(e);let s=(await f(t)).map(e=>({key:(e.key_name||e.key_alias||e.api_key).substring(0,7),spend:e.total_spend}));h(s);let l=(await k(t)).map(e=>({key:e.model,spend:e.total_spend}));u(l)}else"App Owner"==r&&await y(t,s,r,a,w,b).then(async e=>{if(console.log("result from spend logs call",e),"daily_spend"in e){let t=e.daily_spend;console.log("daily spend",t),c(t);let s=e.top_api_keys;h(s)}else{let s=(await _(t,function(e){let t=[];e.forEach(e=>{Object.entries(e).forEach(e=>{let[s,l]=e;"spend"!==s&&"startTime"!==s&&"models"!==s&&"users"!==s&&t.push({key:s,spend:l})})}),t.sort((e,t)=>Number(t.spend)-Number(e.spend));let s=t.slice(0,5).map(e=>e.key);return console.log("topKeys: ".concat(Object.keys(s[0]))),s}(e))).info.map(e=>({key:(e.key_name||e.key_alias||e.token).substring(0,7),spend:e.spend}));h(s),p(function(e){let t={};e.forEach(e=>{Object.entries(e.users).forEach(e=>{let[s,l]=e;""!==s&&null!=s&&"None"!=s&&(t[s]||(t[s]=0),t[s]+=l)})});let s=Object.entries(t).map(e=>{let[t,s]=e;return{user_id:t,spend:s}});s.sort((e,t)=>t.spend-e.spend);let l=s.slice(0,5);return console.log("topKeys: ".concat(Object.values(l[0]))),l}(e)),c(e)}})}catch(e){console.error("There was an error fetching the data",e)}})()},[t,s,r,a,w,b]),(0,l.jsx)("div",{style:{width:"100%"},children:(0,l.jsxs)(F.Z,{numItems:2,className:"gap-2 p-10 h-[75vh] w-full",children:[(0,l.jsx)(E.Z,{numColSpan:2,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(O.Z,{children:"Monthly Spend"}),(0,l.jsx)(ee.Z,{data:i,index:"date",categories:["spend"],colors:["blue"],valueFormatter:e=>"$ ".concat(new Intl.NumberFormat("us").format(e).toString()),yAxisWidth:100,tickGap:5})]})}),(0,l.jsx)(E.Z,{numColSpan:1,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(O.Z,{children:"Top API Keys"}),(0,l.jsx)(ee.Z,{className:"mt-4 h-40",data:d,index:"key",categories:["spend"],colors:["blue"],yAxisWidth:80,tickGap:5,layout:"vertical",showXAxis:!1,showLegend:!1})]})}),(0,l.jsx)(E.Z,{numColSpan:1,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(O.Z,{children:"Top Users"}),(0,l.jsx)(ee.Z,{className:"mt-4 h-40",data:x,index:"user_id",categories:["spend"],colors:["blue"],yAxisWidth:200,layout:"vertical",showXAxis:!1,showLegend:!1})]})}),(0,l.jsx)(E.Z,{numColSpan:1,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(O.Z,{children:"Top Models"}),(0,l.jsx)(ee.Z,{className:"mt-4 h-40",data:m,index:"key",categories:["spend"],colors:["blue"],yAxisWidth:200,layout:"vertical",showXAxis:!1,showLegend:!1})]})})]})})},eM=()=>{let{Title:e,Paragraph:t}=er.default,[s,a]=(0,n.useState)(""),[o,c]=(0,n.useState)(null),[d,h]=(0,n.useState)(null),[m,u]=(0,n.useState)(null),[x,p]=(0,n.useState)(!0),j=(0,r.useSearchParams)(),g=j.get("userID"),y=j.get("token"),[Z,f]=(0,n.useState)("api-keys"),[w,k]=(0,n.useState)(null);return(0,n.useEffect)(()=>{if(y){let e=(0,ec.o)(y);if(e){if(console.log("Decoded token:",e),console.log("Decoded key:",e.key),k(e.key),e.user_role){let t=function(e){if(!e)return"Undefined Role";switch(console.log("Received user role: ".concat(e.toLowerCase())),console.log("Received user role length: ".concat(e.toLowerCase().length)),e.toLowerCase()){case"app_owner":case"demo_app_owner":return"App Owner";case"app_admin":case"proxy_admin":return"Admin";case"proxy_admin_viewer":return"Admin Viewer";case"app_user":return"App User";default:return"Unknown Role"}}(e.user_role);console.log("Decoded user_role:",t),a(t),"Admin Viewer"==t&&f("usage")}else console.log("User role not defined");e.user_email?c(e.user_email):console.log("User Email is not set ".concat(e)),e.login_method?p("username_password"==e.login_method):console.log("User Email is not set ".concat(e))}}},[y]),(0,l.jsx)(n.Suspense,{fallback:(0,l.jsx)("div",{children:"Loading..."}),children:(0,l.jsxs)("div",{className:"flex flex-col min-h-screen",children:[(0,l.jsx)(i,{userID:g,userRole:s,userEmail:o,showSSOBanner:x}),(0,l.jsxs)("div",{className:"flex flex-1 overflow-auto",children:[(0,l.jsx)(eE,{setPage:f,userRole:s,defaultSelectedKey:null}),"api-keys"==Z?(0,l.jsx)(ed,{userID:g,userRole:s,teams:d,keys:m,setUserRole:a,userEmail:o,setUserEmail:c,setTeams:h,setKeys:u}):"models"==Z?(0,l.jsx)(ex,{userID:g,userRole:s,token:y,accessToken:w}):"llm-playground"==Z?(0,l.jsx)(eC,{userID:g,userRole:s,token:y,accessToken:w}):"users"==Z?(0,l.jsx)(ek,{userID:g,userRole:s,token:y,keys:m,accessToken:w,setKeys:u}):"teams"==Z?(0,l.jsx)(eb,{teams:d,setTeams:h,searchParams:j,accessToken:w}):"admin-panel"==Z?(0,l.jsx)(ev,{setTeams:h,searchParams:j,accessToken:w}):(0,l.jsx)(eF,{userID:g,userRole:s,token:y,accessToken:w})]})]})})}}},function(e){e.O(0,[730,971,69,744],function(){return e(e.s=20661)}),_N_E=e.O()}]);
\ No newline at end of file
diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/app/page-37bd7c3d0bb898a3.js b/litellm/proxy/_experimental/out/_next/static/chunks/app/page-37bd7c3d0bb898a3.js
deleted file mode 100644
index 8d5377ae4..000000000
--- a/litellm/proxy/_experimental/out/_next/static/chunks/app/page-37bd7c3d0bb898a3.js
+++ /dev/null
@@ -1 +0,0 @@
-(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[931],{20661:function(e,t,s){Promise.resolve().then(s.bind(s,56239))},56239:function(e,t,s){"use strict";s.r(t),s.d(t,{default:function(){return eF}});var l=s(3827),n=s(64090),r=s(47907),a=s(8792),o=s(2179),i=e=>{let{userID:t,userRole:s,userEmail:n,showSSOBanner:r}=e;return console.log("User ID:",t),console.log("userEmail:",n),(0,l.jsxs)("nav",{className:"left-0 right-0 top-0 flex justify-between items-center h-12 mb-4",children:[(0,l.jsx)("div",{className:"text-left my-2 absolute top-0 left-0",children:(0,l.jsx)("div",{className:"flex flex-col items-center",children:(0,l.jsx)(a.default,{href:"/",children:(0,l.jsx)("button",{className:"text-gray-800 text-2xl py-1 rounded text-center",children:(0,l.jsx)("img",{src:"/get_image",width:200,height:200,alt:"LiteLLM Brand",className:"mr-2"})})})})}),(0,l.jsxs)("div",{className:"text-right mx-4 my-2 absolute top-0 right-0 flex items-center justify-end space-x-2",children:[r?(0,l.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/ui#setup-ssoauth-for-ui",target:"_blank",className:"mr-2",children:(0,l.jsx)(o.Z,{variant:"primary",size:"lg",children:"Enable SSO"})}):null,(0,l.jsxs)(o.Z,{variant:"secondary",size:"lg",children:[n,(0,l.jsxs)("p",{children:["Role: ",s]}),(0,l.jsxs)("p",{children:["ID: ",t]})]})]})]})},c=s(80588);let d=async(e,t,s)=>{try{if(console.log("Form Values in keyCreateCall:",s),s.description&&(s.metadata||(s.metadata={}),s.metadata.description=s.description,delete s.description,s.metadata=JSON.stringify(s.metadata)),s.metadata){console.log("formValues.metadata:",s.metadata);try{s.metadata=JSON.parse(s.metadata)}catch(e){throw c.ZP.error("Failed to parse metadata: "+e),Error("Failed to parse metadata: "+e)}}console.log("Form Values after check:",s);let l=await fetch("/key/generate",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({user_id:t,...s})});if(!l.ok){let e=await l.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let n=await l.json();return console.log("API Response:",n),n}catch(e){throw console.error("Failed to create key:",e),e}},h=async(e,t,s)=>{try{if(console.log("Form Values in keyCreateCall:",s),s.description&&(s.metadata||(s.metadata={}),s.metadata.description=s.description,delete s.description,s.metadata=JSON.stringify(s.metadata)),s.metadata){console.log("formValues.metadata:",s.metadata);try{s.metadata=JSON.parse(s.metadata)}catch(e){throw c.ZP.error("Failed to parse metadata: "+e),Error("Failed to parse metadata: "+e)}}console.log("Form Values after check:",s);let l=await fetch("/user/new",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({user_id:t,...s})});if(!l.ok){let e=await l.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let n=await l.json();return console.log("API Response:",n),n}catch(e){throw console.error("Failed to create key:",e),e}},m=async(e,t)=>{try{console.log("in keyDeleteCall:",t),c.ZP.info("Making key delete request");let s=await fetch("/key/delete",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({keys:[t]})});if(!s.ok){let e=await s.text();throw c.ZP.error("Failed to delete key: "+e),Error("Network response was not ok")}let l=await s.json();return console.log(l),c.ZP.success("API Key Deleted"),l}catch(e){throw console.error("Failed to create key:",e),e}},u=async function(e,t,s){let l=arguments.length>3&&void 0!==arguments[3]&&arguments[3];try{let n="/user/info";"App Owner"==s&&t&&(n="".concat(n,"/?user_id=").concat(t)),console.log("in userInfoCall viewAll=",l),l&&(n="".concat(n,"/?view_all=true")),c.ZP.info("Requesting user data");let r=await fetch(n,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!r.ok){let e=await r.text();throw c.ZP.error(e),Error("Network response was not ok")}let a=await r.json();return console.log("API Response:",a),c.ZP.info("Received user data"),a}catch(e){throw console.error("Failed to create key:",e),e}},x=async(e,t,s)=>{try{c.ZP.info("Requesting model data");let t=await fetch("/v2/model/info",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}let s=await t.json();return c.ZP.info("Received model data"),s}catch(e){throw console.error("Failed to create key:",e),e}},p=async(e,t,s)=>{try{c.ZP.info("Requesting model data");let t=await fetch("/models",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}let s=await t.json();return c.ZP.info("Received model data"),s}catch(e){throw console.error("Failed to create key:",e),e}},j=async(e,t)=>{try{let s="/global/spend/logs";console.log("in keySpendLogsCall:",s);let l=await fetch("".concat(s,"/?api_key=").concat(t),{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw c.ZP.error(e),Error("Network response was not ok")}let n=await l.json();return console.log(n),n}catch(e){throw console.error("Failed to create key:",e),e}},g=async(e,t,s,l,n,r)=>{try{console.log("user role in spend logs call: ".concat(s));let t="/spend/logs";t="App Owner"==s?"".concat(t,"/?user_id=").concat(l,"&start_date=").concat(n,"&end_date=").concat(r):"".concat(t,"/?start_date=").concat(n,"&end_date=").concat(r),c.ZP.info("Making spend logs request");let a=await fetch(t,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!a.ok){let e=await a.text();throw c.ZP.error(e),Error("Network response was not ok")}let o=await a.json();return console.log(o),c.ZP.success("Spend Logs received"),o}catch(e){throw console.error("Failed to create key:",e),e}},Z=async e=>{try{c.ZP.info("Making spend logs request");let t=await fetch("/global/spend/logs",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}let s=await t.json();return console.log(s),c.ZP.success("Spend Logs received"),s}catch(e){throw console.error("Failed to create key:",e),e}},y=async e=>{try{c.ZP.info("Making spend keys request");let t=await fetch("/global/spend/keys?limit=5",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}let s=await t.json();return console.log(s),c.ZP.success("Spend Logs received"),s}catch(e){throw console.error("Failed to create key:",e),e}},f=async(e,t)=>{try{t&&JSON.stringify({api_key:t}),c.ZP.info("Making top end users request");let s={method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}};t&&(s.body=JSON.stringify({api_key:t}));let l=await fetch("/global/spend/end_users",s);if(!l.ok){let e=await l.text();throw c.ZP.error(e),Error("Network response was not ok")}let n=await l.json();return console.log(n),c.ZP.success("Top End users received"),n}catch(e){throw console.error("Failed to create key:",e),e}},w=async e=>{try{c.ZP.info("Making top models request");let t=await fetch("/global/spend/models?limit=5",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}let s=await t.json();return console.log(s),c.ZP.success("Top Models received"),s}catch(e){throw console.error("Failed to create key:",e),e}},k=async(e,t)=>{try{let s=await fetch("/v2/key/info",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({keys:t})});if(!s.ok){let e=await s.text();throw c.ZP.error(e),Error("Network response was not ok")}let l=await s.json();return console.log(l),l}catch(e){throw console.error("Failed to create key:",e),e}},_=async(e,t)=>{try{let s="/spend/users";console.log("in spendUsersCall:",s);let l=await fetch("".concat(s,"/?user_id=").concat(t),{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw c.ZP.error(e),Error("Network response was not ok")}let n=await l.json();return console.log(n),n}catch(e){throw console.error("Failed to get spend for user",e),e}},b=async(e,t,s,l)=>{try{let n=await fetch("/user/request_model",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({models:[t],user_id:s,justification:l})});if(!n.ok){let e=await n.text();throw c.ZP.error("Failed to delete key: "+e),Error("Network response was not ok")}let r=await n.json();return console.log(r),c.ZP.success(""),r}catch(e){throw console.error("Failed to create key:",e),e}},v=async e=>{try{let t="/user/get_requests";console.log("in userGetRequesedtModelsCall:",t);let s=await fetch(t,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!s.ok){let e=await s.text();throw c.ZP.error("Failed to delete key: "+e),Error("Network response was not ok")}let l=await s.json();return console.log(l),c.ZP.success(""),l}catch(e){throw console.error("Failed to get requested models:",e),e}},S=async(e,t)=>{try{let s="/user/get_users?role=".concat(t);console.log("in userGetAllUsersCall:",s);let l=await fetch(s,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw c.ZP.error("Failed to delete key: "+e),Error("Network response was not ok")}let n=await l.json();return console.log(n),c.ZP.success("Got all users"),n}catch(e){throw console.error("Failed to get requested models:",e),e}},N=async(e,t)=>{try{console.log("Form Values in teamCreateCall:",t);let s=await fetch("/team/new",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...t})});if(!s.ok){let e=await s.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let l=await s.json();return console.log("API Response:",l),l}catch(e){throw console.error("Failed to create key:",e),e}},A=async(e,t,s)=>{try{console.log("Form Values in teamMemberAddCall:",s);let l=await fetch("/team/member_add",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({team_id:t,member:s})});if(!l.ok){let e=await l.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let n=await l.json();return console.log("API Response:",n),n}catch(e){throw console.error("Failed to create key:",e),e}},C=async(e,t)=>{try{console.log("Form Values in userUpdateUserCall:",t);let s=await fetch("/user/update",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({user_role:"proxy_admin_viewer",...t})});if(!s.ok){let e=await s.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let l=await s.json();return console.log("API Response:",l),c.ZP.success("User role updated"),l}catch(e){throw console.error("Failed to create key:",e),e}},I=async(e,t)=>{try{let s=await fetch("/global/predict/spend/logs",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({data:t})});if(!s.ok){let e=await s.text();throw c.ZP.error(e),Error("Network response was not ok")}let l=await s.json();return console.log(l),l}catch(e){throw console.error("Failed to create key:",e),e}},P=async e=>{try{console.log("Checking Slack Budget Alerts service health"),c.ZP.info("Sending Test Slack alert...");let t=await fetch("/health/services?service=slack_budget_alerts",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error("Failed Slack Alert test: "+e),Error(e)}let s=await t.json();return c.ZP.success("Test Slack Alert worked - check your Slack!"),console.log("Service Health Response:",s),s}catch(e){throw console.error("Failed to perform health check:",e),e}};var T=s(10384),E=s(46453),F=s(13810),M=s(71801),R=s(42440),O=s(17189),D=s(12143),U=s(77171),L=s(42539),z=s(88707),B=s(1861);let{Option:q}=O.default;var K=e=>{let{userID:t,teamID:s,userRole:r,accessToken:a,data:i,userModels:h,setData:m}=e,[u]=D.Z.useForm(),[x,p]=(0,n.useState)(!1),[j,g]=(0,n.useState)(null),[Z,y]=(0,n.useState)(null),f=()=>{p(!1),u.resetFields()},w=()=>{p(!1),g(null),u.resetFields()},k=async e=>{try{c.ZP.info("Making API Call"),p(!0);let s=await d(a,t,e);console.log("key create Response:",s),m(e=>e?[...e,s]:[s]),g(s.key),y(s.soft_budget),c.ZP.success("API Key Created"),u.resetFields(),localStorage.removeItem("userData"+t)}catch(e){console.error("Error creating the key:",e)}},_=async()=>{try{console.log("Sending Slack alert...");let e=await P(a);console.log("slackBudgetAlertsHealthCheck Response:",e),console.log("Testing Slack alert successful")}catch(e){console.error("Error sending Slack alert:",e)}};return(0,l.jsxs)("div",{children:[(0,l.jsx)(o.Z,{className:"mx-auto",onClick:()=>p(!0),children:"+ Create New Key"}),(0,l.jsx)(U.Z,{title:"Create Key",visible:x,width:800,footer:null,onOk:f,onCancel:w,children:(0,l.jsxs)(D.Z,{form:u,onFinish:k,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:["App Owner"===r||"Admin"===r?(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(D.Z.Item,{label:"Key Name",name:"key_alias",children:(0,l.jsx)(L.Z,{})}),(0,l.jsx)(D.Z.Item,{label:"Team ID",name:"team_id",children:(0,l.jsx)(L.Z,{placeholder:"ai_team",defaultValue:s||""})}),(0,l.jsx)(D.Z.Item,{label:"Models",name:"models",children:(0,l.jsx)(O.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:h.map(e=>(0,l.jsx)(q,{value:e,children:e},e))})}),(0,l.jsx)(D.Z.Item,{label:"Soft Budget (USD) Monthly",name:"soft_budget",initialValue:50,children:(0,l.jsx)(z.Z,{step:.01,precision:2,defaultValue:50,width:200})}),(0,l.jsx)(D.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,l.jsx)(z.Z,{step:.01,precision:2,width:200})}),(0,l.jsx)(D.Z.Item,{label:"Reset Budget",name:"budget_duration",children:(0,l.jsxs)(O.default,{defaultValue:null,placeholder:"n/a",children:[(0,l.jsx)(O.default.Option,{value:"24h",children:"daily"}),(0,l.jsx)(O.default.Option,{value:"30d",children:"monthly"})]})}),(0,l.jsx)(D.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,l.jsx)(z.Z,{step:1,width:400})}),(0,l.jsx)(D.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,l.jsx)(z.Z,{step:1,width:400})}),(0,l.jsx)(D.Z.Item,{label:"Expire Key (eg: 30s, 30h, 30d)",name:"duration",children:(0,l.jsx)(L.Z,{})}),(0,l.jsx)(D.Z.Item,{label:"Metadata",name:"metadata",children:(0,l.jsx)(L.Z.TextArea,{rows:4,placeholder:"Enter metadata as JSON"})})]}):(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(D.Z.Item,{label:"Key Name",name:"key_alias",children:(0,l.jsx)(L.Z,{})}),(0,l.jsx)(D.Z.Item,{label:"Team ID (Contact Group)",name:"team_id",children:(0,l.jsx)(L.Z,{placeholder:"ai_team"})}),(0,l.jsx)(D.Z.Item,{label:"Description",name:"description",children:(0,l.jsx)(L.Z.TextArea,{placeholder:"Enter description",rows:4})})]}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(B.ZP,{htmlType:"submit",children:"Create Key"})})]})}),j&&(0,l.jsx)(U.Z,{visible:x,onOk:f,onCancel:w,footer:null,children:(0,l.jsx)(E.Z,{numItems:1,className:"gap-2 w-full",children:(0,l.jsxs)(F.Z,{children:[(0,l.jsx)(R.Z,{children:"Save your Key"}),(0,l.jsx)(T.Z,{numColSpan:1,children:(0,l.jsxs)("p",{children:["Please save this secret key somewhere safe and accessible. For security reasons, ",(0,l.jsx)("b",{children:"you will not be able to view it again"})," ","through your LiteLLM account. If you lose this secret key, you will need to generate a new one."]})}),(0,l.jsx)(T.Z,{numColSpan:1,children:null!=j?(0,l.jsxs)("div",{children:[(0,l.jsxs)(M.Z,{children:["API Key: ",j]}),(0,l.jsx)(R.Z,{className:"mt-6",children:"Budgets"}),(0,l.jsxs)(M.Z,{children:["Soft Limit Budget: $",Z]}),(0,l.jsx)(o.Z,{className:"mt-3",onClick:_,children:"Test Slack Alert"}),(0,l.jsxs)(M.Z,{className:"mt-2",children:["(LiteLLM Docs -",(0,l.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/alerting",target:"_blank",className:"text-blue-500",children:"Set Up Slack Alerting)"})]})]}):(0,l.jsx)(M.Z,{children:"Key being created, this might take 30s"})})]})})})]})},V=s(33393),J=s(61244),G=s(10827),$=s(3851),H=s(2044),W=s(64167),Y=s(74480),X=s(7178),Q=s(9853),ee=s(56863),et=e=>{let{token:t,accessToken:s,keySpend:r,keyBudget:a,keyName:i}=e,[c,d]=(0,n.useState)(!1),[h,m]=(0,n.useState)(null),[u,x]=(0,n.useState)(""),[p,g]=(0,n.useState)(null),Z=async()=>{try{if(null==s||null==t)return;console.log("accessToken: ".concat(s,"; token: ").concat(t));let e=await j(s,t);console.log("Response:",e),m(e);let l=await I(s,e);console.log("Response2:",l);let n=[...e,...l.response];m(n),x(l.predicted_spend),console.log("Combined Data:",n)}catch(e){console.error("There was an error fetching the data",e)}};return t?(0,l.jsxs)("div",{children:[(0,l.jsx)(o.Z,{size:"xs",onClick:()=>{console.log("Show Modal triggered"),d(!0),Z()},variant:"secondary",children:"View Spend Report"}),(0,l.jsxs)(U.Z,{visible:c,width:1400,onOk:()=>{d(!1)},onCancel:()=>{d(!1)},footer:null,children:[(0,l.jsxs)(R.Z,{style:{textAlign:"left"},children:["Key Name: ",i]}),(0,l.jsxs)(ee.Z,{children:["Monthly Spend $",r]}),(0,l.jsx)(R.Z,{children:u}),(0,l.jsx)(F.Z,{className:"mt-6 mb-6",children:h&&(0,l.jsx)(Q.Z,{className:"mt-6",data:h,colors:["blue","amber"],index:"date",categories:["spend","predicted_spend"],yAxisWidth:80})})]})]}):null},es=e=>{let{userID:t,accessToken:s,data:r,setData:a}=e,[i,c]=(0,n.useState)(!1),[d,h]=(0,n.useState)(!1),[u,x]=(0,n.useState)(null),p=async e=>{null!=r&&(x(e),localStorage.removeItem("userData"+t),h(!0))},j=async()=>{if(null!=u&&null!=r){try{await m(s,u);let e=r.filter(e=>e.token!==u);a(e)}catch(e){console.error("Error deleting the key:",e)}h(!1),x(null)}};if(null!=r)return console.log("RERENDER TRIGGERED"),(0,l.jsxs)(F.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh] mb-4",children:[(0,l.jsxs)(G.Z,{className:"mt-5",children:[(0,l.jsx)(W.Z,{children:(0,l.jsxs)(X.Z,{children:[(0,l.jsx)(Y.Z,{children:"Key Alias"}),(0,l.jsx)(Y.Z,{children:"Secret Key"}),(0,l.jsx)(Y.Z,{children:"Spend (USD)"}),(0,l.jsx)(Y.Z,{children:"Key Budget (USD)"}),(0,l.jsx)(Y.Z,{children:"Spend Report"}),(0,l.jsx)(Y.Z,{children:"Team ID"}),(0,l.jsx)(Y.Z,{children:"Metadata"}),(0,l.jsx)(Y.Z,{children:"Models"}),(0,l.jsx)(Y.Z,{children:"TPM / RPM Limits"}),(0,l.jsx)(Y.Z,{children:"Expires"})]})}),(0,l.jsx)($.Z,{children:r.map(e=>(console.log(e),"litellm-dashboard"===e.team_id)?null:(0,l.jsxs)(X.Z,{children:[(0,l.jsx)(H.Z,{children:null!=e.key_alias?(0,l.jsx)(M.Z,{children:e.key_alias}):(0,l.jsx)(M.Z,{children:"Not Set"})}),(0,l.jsx)(H.Z,{children:(0,l.jsx)(M.Z,{children:e.key_name})}),(0,l.jsx)(H.Z,{children:(0,l.jsx)(M.Z,{children:e.spend})}),(0,l.jsx)(H.Z,{children:null!=e.max_budget?(0,l.jsx)(M.Z,{children:e.max_budget}):(0,l.jsx)(M.Z,{children:"Unlimited Budget"})}),(0,l.jsx)(H.Z,{children:(0,l.jsx)(et,{token:e.token,accessToken:s,keySpend:e.spend,keyBudget:e.max_budget,keyName:e.key_name})}),(0,l.jsx)(H.Z,{children:(0,l.jsx)(M.Z,{children:e.team_id})}),(0,l.jsx)(H.Z,{children:(0,l.jsx)(M.Z,{children:JSON.stringify(e.metadata)})}),(0,l.jsx)(H.Z,{children:(0,l.jsx)(M.Z,{children:JSON.stringify(e.models)})}),(0,l.jsx)(H.Z,{children:(0,l.jsxs)(M.Z,{children:["TPM Limit: ",e.tpm_limit?e.tpm_limit:"Unlimited"," ",(0,l.jsx)("br",{})," RPM Limit:"," ",e.rpm_limit?e.rpm_limit:"Unlimited"]})}),(0,l.jsx)(H.Z,{children:null!=e.expires?(0,l.jsx)(M.Z,{children:e.expires}):(0,l.jsx)(M.Z,{children:"Never expires"})}),(0,l.jsx)(H.Z,{children:(0,l.jsx)(J.Z,{onClick:()=>p(e.token),icon:V.Z,size:"sm"})})]},e.token))})]}),d&&(0,l.jsx)("div",{className:"fixed z-10 inset-0 overflow-y-auto",children:(0,l.jsxs)("div",{className:"flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0",children:[(0,l.jsx)("div",{className:"fixed inset-0 transition-opacity","aria-hidden":"true",children:(0,l.jsx)("div",{className:"absolute inset-0 bg-gray-500 opacity-75"})}),(0,l.jsx)("span",{className:"hidden sm:inline-block sm:align-middle sm:h-screen","aria-hidden":"true",children:""}),(0,l.jsxs)("div",{className:"inline-block align-bottom bg-white rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full",children:[(0,l.jsx)("div",{className:"bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4",children:(0,l.jsx)("div",{className:"sm:flex sm:items-start",children:(0,l.jsxs)("div",{className:"mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left",children:[(0,l.jsx)("h3",{className:"text-lg leading-6 font-medium text-gray-900",children:"Delete Key"}),(0,l.jsx)("div",{className:"mt-2",children:(0,l.jsx)("p",{className:"text-sm text-gray-500",children:"Are you sure you want to delete this key ?"})})]})})}),(0,l.jsxs)("div",{className:"bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse",children:[(0,l.jsx)(o.Z,{onClick:j,color:"red",className:"ml-2",children:"Delete"}),(0,l.jsx)(o.Z,{onClick:()=>{h(!1),x(null)},children:"Cancel"})]})]})]})})]})},el=e=>{let{userID:t,userSpendData:s,userRole:r,accessToken:a}=e;console.log("User SpendData:",s);let[o,i]=(0,n.useState)(null==s?void 0:s.spend),[c,d]=(0,n.useState)((null==s?void 0:s.max_budget)||null);return(0,n.useEffect)(()=>{(async()=>{if("Admin"===r)try{let e=await _(a,"litellm-proxy-budget");console.log("Result from callSpendUsers:",e);let t=e[0];i(null==t?void 0:t.spend),d((null==t?void 0:t.max_budget)||null)}catch(e){console.error("Failed to get spend for user",e)}})()},[r,a,t]),(0,l.jsx)(l.Fragment,{children:(0,l.jsxs)(F.Z,{className:"mx-auto mb-4",children:[(0,l.jsxs)(ee.Z,{children:["$",o]}),(0,l.jsxs)(R.Z,{children:["/ ",null!==c?"$".concat(c," limit"):"No limit"]})]})})},en=s(36083),er=s(68967),ea=s(27166),eo=e=>{let{teams:t,setSelectedTeam:s}=e,{Title:r,Paragraph:a}=en.default,[o,i]=(0,n.useState)("");return(0,l.jsxs)("div",{className:"mt-10",children:[(0,l.jsx)(r,{level:4,children:"Default Team"}),(0,l.jsx)(a,{children:"If you belong to multiple teams, this setting controls which team is used by default when creating new API Keys."}),t&&t.length>0?(0,l.jsx)(er.Z,{defaultValue:"0",children:t.map((e,t)=>(0,l.jsx)(ea.Z,{value:String(t),onClick:()=>s(e),children:e.team_alias},t))}):(0,l.jsxs)(a,{children:["No team created. ",(0,l.jsx)("b",{children:"Defaulting to personal account."})]})]})},ei=s(37963);console.log("isLocal:",!1);var ec=e=>{let{userID:t,userRole:s,teams:a,keys:o,setUserRole:i,userEmail:c,setUserEmail:d,setTeams:h,setKeys:m}=e,[x,j]=(0,n.useState)(null),g=(0,r.useSearchParams)();g.get("viewSpend"),(0,r.useRouter)();let Z=g.get("token"),[y,f]=(0,n.useState)(null),[w,k]=(0,n.useState)([]),[_,b]=(0,n.useState)(a?a[0]:null);if(window.addEventListener("beforeunload",function(){sessionStorage.clear()}),(0,n.useEffect)(()=>{if(Z){let e=(0,ei.o)(Z);if(e){if(console.log("Decoded token:",e),console.log("Decoded key:",e.key),f(e.key),e.user_role){let t=function(e){if(!e)return"Undefined Role";switch(console.log("Received user role: ".concat(e)),e.toLowerCase()){case"app_owner":case"demo_app_owner":return"App Owner";case"app_admin":case"proxy_admin":return"Admin";case"proxy_admin_viewer":return"Admin Viewer";case"app_user":return"App User";default:return"Unknown Role"}}(e.user_role);console.log("Decoded user_role:",t),i(t)}else console.log("User role not defined");e.user_email?d(e.user_email):console.log("User Email is not set ".concat(e))}}if(t&&y&&s&&!o&&!x){let e=sessionStorage.getItem("userModels"+t);e?k(JSON.parse(e)):(async()=>{try{let e=await u(y,t,s);console.log("received teams in user dashboard: ".concat(Object.keys(e),"; team values: ").concat(Object.entries(e.teams))),j(e.user_info),m(e.keys),h(e.teams),b(e.teams?e.teams[0]:null),sessionStorage.setItem("userData"+t,JSON.stringify(e.keys)),sessionStorage.setItem("userSpendData"+t,JSON.stringify(e.user_info));let l=(await p(y,t,s)).data.map(e=>e.id);console.log("available_model_names:",l),k(l),console.log("userModels:",w),sessionStorage.setItem("userModels"+t,JSON.stringify(l))}catch(e){console.error("There was an error fetching the data",e)}})()}},[t,Z,y,o,s]),null==t||null==Z){let e="/sso/key/generate";return console.log("Full URL:",e),window.location.href=e,null}if(null==y)return null;if(null==s&&i("App Owner"),s&&"Admin Viewer"==s){let{Title:e,Paragraph:t}=en.default;return(0,l.jsxs)("div",{children:[(0,l.jsx)(e,{level:1,children:"Access Denied"}),(0,l.jsx)(t,{children:"Ask your proxy admin for access to create keys"})]})}return(0,l.jsx)("div",{children:(0,l.jsx)(E.Z,{numItems:1,className:"gap-0 p-10 h-[75vh] w-full",children:(0,l.jsxs)(T.Z,{numColSpan:1,children:[(0,l.jsx)(el,{userID:t,userSpendData:x,userRole:s,accessToken:y}),(0,l.jsx)(es,{userID:t,accessToken:y,data:o,setData:m}),(0,l.jsx)(K,{userID:t,teamID:_?_.team_id:null,userRole:s,userModels:w,accessToken:y,data:o,setData:m}),(0,l.jsx)(eo,{teams:a,setSelectedTeam:b})]})})})},ed=s(5);let{Option:eh}=O.default;var em=e=>{let{userModels:t,accessToken:s,userID:r}=e,[a]=D.Z.useForm(),[i,d]=(0,n.useState)(!1),h=async e=>{try{c.ZP.info("Requesting access");let{selectedModel:t,accessReason:l}=e;await b(s,t,r,l),d(!0)}catch(e){console.error("Error requesting access:",e)}};return(0,l.jsxs)("div",{children:[(0,l.jsx)(o.Z,{size:"xs",onClick:()=>d(!0),children:"Request Access"}),(0,l.jsx)(U.Z,{title:"Request Access",visible:i,width:800,footer:null,onOk:()=>{d(!1),a.resetFields()},onCancel:()=>{d(!1),a.resetFields()},children:(0,l.jsxs)(D.Z,{form:a,onFinish:h,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsx)(D.Z.Item,{label:"Select Model",name:"selectedModel",children:(0,l.jsx)(O.default,{placeholder:"Select model",style:{width:"100%"},children:t.map(e=>(0,l.jsx)(eh,{value:e,children:e},e))})}),(0,l.jsx)(D.Z.Item,{label:"Reason for Access",name:"accessReason",children:(0,l.jsx)(L.Z.TextArea,{rows:4,placeholder:"Enter reason for access"})}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(o.Z,{children:"Request Access"})})]})})]})},eu=e=>{let{accessToken:t,token:s,userRole:r,userID:a}=e,[i,c]=(0,n.useState)({data:[]}),[d,h]=(0,n.useState)([]);if((0,n.useEffect)(()=>{if(!t||!s||!r||!a)return;let e=async()=>{try{let e=await x(t,a,r);if(console.log("Model data response:",e.data),c(e),"Admin"===r&&t){let e=await v(t);console.log("Pending Requests:",d),h(e.requests||[])}}catch(e){console.error("There was an error fetching the model data",e)}};t&&s&&r&&a&&e()},[t,s,r,a]),!i||!t||!s||!r||!a)return(0,l.jsx)("div",{children:"Loading..."});let m=[];for(let e=0;e(0,l.jsxs)(X.Z,{children:[(0,l.jsx)(H.Z,{children:(0,l.jsx)(R.Z,{children:e.model_name})}),(0,l.jsx)(H.Z,{children:e.provider}),(0,l.jsx)(H.Z,{children:e.user_access?(0,l.jsx)(ed.Z,{color:"green",children:"Yes"}):(0,l.jsx)(em,{userModels:m,accessToken:t,userID:a})}),(0,l.jsx)(H.Z,{children:e.input_cost}),(0,l.jsx)(H.Z,{children:e.output_cost}),(0,l.jsx)(H.Z,{children:e.max_tokens})]},e.model_name))})]})}),"Admin"===r&&d&&d.length>0?(0,l.jsx)(F.Z,{children:(0,l.jsxs)(G.Z,{children:[(0,l.jsxs)(W.Z,{children:[(0,l.jsx)(R.Z,{children:"Pending Requests"}),(0,l.jsxs)(X.Z,{children:[(0,l.jsx)(H.Z,{children:(0,l.jsx)(R.Z,{children:"User ID"})}),(0,l.jsx)(H.Z,{children:(0,l.jsx)(R.Z,{children:"Requested Models"})}),(0,l.jsx)(H.Z,{children:(0,l.jsx)(R.Z,{children:"Justification"})}),(0,l.jsx)(H.Z,{children:(0,l.jsx)(R.Z,{children:"Justification"})})]})]}),(0,l.jsx)($.Z,{children:d.map(e=>(0,l.jsxs)(X.Z,{children:[(0,l.jsx)(H.Z,{children:(0,l.jsx)("p",{children:e.user_id})}),(0,l.jsx)(H.Z,{children:(0,l.jsx)("p",{children:e.models[0]})}),(0,l.jsx)(H.Z,{children:(0,l.jsx)("p",{children:e.justification})}),(0,l.jsx)(H.Z,{children:(0,l.jsx)("p",{children:e.user_id})}),(0,l.jsx)(o.Z,{children:"Approve"}),(0,l.jsx)(o.Z,{variant:"secondary",className:"ml-2",children:"Deny"})]},e.request_id))})]})}):null]})})},ex=s(92836),ep=s(26734),ej=s(41608),eg=s(32126),eZ=s(23682);let{Option:ey}=O.default;var ef=e=>{let{userID:t,accessToken:s}=e,[r]=D.Z.useForm(),[a,i]=(0,n.useState)(!1),[d,m]=(0,n.useState)(null),[u,x]=(0,n.useState)([]);(0,n.useEffect)(()=>{(async()=>{try{let e=await p(s,t,"any"),l=[];for(let t=0;t{i(!1),r.resetFields()},g=()=>{i(!1),m(null),r.resetFields()},Z=async e=>{try{c.ZP.info("Making API Call"),i(!0),console.log("formValues in create user:",e);let l=await h(s,t,e);console.log("user create Response:",l),m(l.key),c.ZP.success("API user Created"),r.resetFields(),localStorage.removeItem("userData"+t)}catch(e){console.error("Error creating the user:",e)}};return(0,l.jsxs)("div",{children:[(0,l.jsx)(o.Z,{className:"mx-auto",onClick:()=>i(!0),children:"+ Create New User"}),(0,l.jsx)(U.Z,{title:"Create User",visible:a,width:800,footer:null,onOk:j,onCancel:g,children:(0,l.jsxs)(D.Z,{form:r,onFinish:Z,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsx)(D.Z.Item,{label:"User ID",name:"user_id",children:(0,l.jsx)(L.Z,{placeholder:"Enter User ID"})}),(0,l.jsx)(D.Z.Item,{label:"Team ID",name:"team_id",children:(0,l.jsx)(L.Z,{placeholder:"ai_team"})}),(0,l.jsx)(D.Z.Item,{label:"Models",name:"models",children:(0,l.jsx)(O.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:u.map(e=>(0,l.jsx)(ey,{value:e,children:e},e))})}),(0,l.jsx)(D.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,l.jsx)(z.Z,{step:.01,precision:2,width:200})}),(0,l.jsx)(D.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,l.jsx)(z.Z,{step:1,width:400})}),(0,l.jsx)(D.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,l.jsx)(z.Z,{step:1,width:400})}),(0,l.jsx)(D.Z.Item,{label:"Duration (eg: 30s, 30h, 30d)",name:"duration",children:(0,l.jsx)(L.Z,{})}),(0,l.jsx)(D.Z.Item,{label:"Metadata",name:"metadata",children:(0,l.jsx)(L.Z.TextArea,{rows:4,placeholder:"Enter metadata as JSON"})}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(B.ZP,{htmlType:"submit",children:"Create User"})})]})}),d&&(0,l.jsxs)(U.Z,{title:"Save Your User",visible:a,onOk:j,onCancel:g,footer:null,children:[(0,l.jsxs)("p",{children:["Please save this secret user somewhere safe and accessible. For security reasons, ",(0,l.jsx)("b",{children:"you will not be able to view it again"})," ","through your LiteLLM account. If you lose this secret user, you will need to generate a new one."]}),(0,l.jsx)("p",{children:null!=d?"API user: ".concat(d):"User being created, this might take 30s"})]})]})},ew=e=>{let{accessToken:t,token:s,keys:r,userRole:a,userID:o,setKeys:i}=e,[c,d]=(0,n.useState)(null),[h,m]=(0,n.useState)(null),[x,p]=(0,n.useState)(1);if((0,n.useEffect)(()=>{if(!t||!s||!a||!o)return;let e=async()=>{try{let e=await u(t,null,a,!0);console.log("user data response:",e),d(e)}catch(e){console.error("There was an error fetching the model data",e)}};t&&s&&a&&o&&!c&&e();let l=async()=>{try{let e=await f(t,null);console.log("user data response:",e),m(e)}catch(e){console.error("There was an error fetching the model data",e)}};a&&("Admin"==a||"Admin Viewer"==a)&&!h&&l()},[t,s,a,o]),!c||!t||!s||!a||!o)return(0,l.jsx)("div",{children:"Loading..."});let j=async e=>{try{let s=await f(t,e);console.log("user data response:",s),m(s)}catch(e){console.error("There was an error fetching the model data",e)}};return(0,l.jsx)("div",{style:{width:"100%"},children:(0,l.jsxs)(E.Z,{className:"gap-2 p-10 h-[75vh] w-full",children:[(0,l.jsx)(ef,{userID:o,accessToken:t}),(0,l.jsx)(F.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh] mb-4",children:(0,l.jsxs)(ep.Z,{children:[(0,l.jsxs)(ej.Z,{variant:"line",defaultValue:"1",children:[(0,l.jsx)(ex.Z,{value:"1",children:"Key Owners"}),(0,l.jsx)(ex.Z,{value:"2",children:"End-Users"})]}),(0,l.jsxs)(eZ.Z,{children:[(0,l.jsx)(eg.Z,{children:(0,l.jsxs)(G.Z,{className:"mt-5",children:[(0,l.jsx)(W.Z,{children:(0,l.jsxs)(X.Z,{children:[(0,l.jsx)(Y.Z,{children:"User ID"}),(0,l.jsx)(Y.Z,{children:"User Role"}),(0,l.jsx)(Y.Z,{children:"User Models"}),(0,l.jsx)(Y.Z,{children:"User Spend ($ USD)"}),(0,l.jsx)(Y.Z,{children:"User Max Budget ($ USD)"})]})}),(0,l.jsx)($.Z,{children:c.map(e=>(0,l.jsxs)(X.Z,{children:[(0,l.jsx)(H.Z,{children:e.user_id}),(0,l.jsx)(H.Z,{children:e.user_role?e.user_role:"app_owner"}),(0,l.jsx)(H.Z,{children:e.models&&e.models.length>0?e.models:"All Models"}),(0,l.jsx)(H.Z,{children:e.spend?e.spend:0}),(0,l.jsx)(H.Z,{children:e.max_budget?e.max_budget:"Unlimited"})]},e.user_id))})]})}),(0,l.jsxs)(eg.Z,{children:[(0,l.jsxs)("div",{className:"flex items-center",children:[(0,l.jsx)("div",{className:"flex-1"}),(0,l.jsxs)("div",{className:"flex-1 flex justify-between items-center",children:[(0,l.jsx)(M.Z,{className:"w-1/4 mr-2 text-right",children:"Key"}),(0,l.jsx)(er.Z,{defaultValue:"1",className:"w-3/4",children:null==r?void 0:r.map((e,t)=>{if(e&&null!==e.key_name&&e.key_name.length>0)return(0,l.jsx)(ea.Z,{value:String(t),onClick:()=>j(e.token),children:e.key_name},t)})})]})]}),(0,l.jsxs)(G.Z,{children:[(0,l.jsx)(W.Z,{children:(0,l.jsxs)(X.Z,{children:[(0,l.jsx)(Y.Z,{children:"End User"}),(0,l.jsx)(Y.Z,{children:"Spend"}),(0,l.jsx)(Y.Z,{children:"Total Events"})]})}),(0,l.jsx)($.Z,{children:null==h?void 0:h.map((e,t)=>(0,l.jsxs)(X.Z,{children:[(0,l.jsx)(H.Z,{children:e.end_user}),(0,l.jsx)(H.Z,{children:e.total_spend}),(0,l.jsx)(H.Z,{children:e.total_events})]},t))})]})]})]})]})}),function(){if(!c)return null;let e=Math.ceil(c.length/25),t=Math.min(25*x,c.length);return(0,l.jsxs)("div",{className:"flex justify-between items-center",children:[(0,l.jsxs)("div",{children:["Showing ",(x-1)*25+1," – ",t," of ",c.length]}),(0,l.jsxs)("div",{className:"flex",children:[(0,l.jsx)("button",{className:"bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-l focus:outline-none",disabled:1===x,onClick:()=>p(x-1),children:"← Prev"}),(0,l.jsx)("button",{className:"bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-r focus:outline-none",disabled:x===e,onClick:()=>p(x+1),children:"Next →"})]})]})}()]})})},ek=s(8510),e_=e=>{let{teams:t,searchParams:s,accessToken:r,setTeams:a}=e,[i]=D.Z.useForm(),[d]=D.Z.useForm(),{Title:h,Paragraph:m}=en.default,[u,x]=(0,n.useState)(""),[p,j]=(0,n.useState)(t?t[0]:null),[g,Z]=(0,n.useState)(!1),[y,f]=(0,n.useState)(!1),w=async e=>{try{if(null!=r){c.ZP.info("Making API Call");let s=await N(r,e);null!==t?a([...t,s]):a([s]),console.log("response for team create call: ".concat(s)),Z(!1)}}catch(e){console.error("Error creating the key:",e)}},k=async e=>{try{if(null!=r&&null!=t){c.ZP.info("Making API Call");let s={role:"user",user_email:e.user_email,user_id:e.user_id},l=await A(r,p.team_id,s);console.log("response for team create call: ".concat(l.data));let n=t.findIndex(e=>(console.log("team.team_id=".concat(e.team_id,"; response.data.team_id=").concat(l.data.team_id)),e.team_id===l.data.team_id));if(console.log("foundIndex: ".concat(n)),-1!==n){let e=[...t];e[n]=l.data,a(e),j(l.data)}f(!1)}}catch(e){console.error("Error creating the key:",e)}};return console.log("received teams ".concat(t)),(0,l.jsx)("div",{className:"w-full",children:(0,l.jsxs)(E.Z,{numItems:1,className:"gap-2 p-2 h-[75vh] w-full",children:[(0,l.jsxs)(T.Z,{numColSpan:1,children:[(0,l.jsx)(h,{level:4,children:"All Teams"}),(0,l.jsx)(F.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,l.jsxs)(G.Z,{children:[(0,l.jsx)(W.Z,{children:(0,l.jsxs)(X.Z,{children:[(0,l.jsx)(Y.Z,{children:"Team Name"}),(0,l.jsx)(Y.Z,{children:"Spend (USD)"}),(0,l.jsx)(Y.Z,{children:"Budget (USD)"}),(0,l.jsx)(Y.Z,{children:"TPM / RPM Limits"})]})}),(0,l.jsx)($.Z,{children:t&&t.length>0?t.map(e=>(0,l.jsxs)(X.Z,{children:[(0,l.jsx)(H.Z,{children:e.team_alias}),(0,l.jsx)(H.Z,{children:e.spend}),(0,l.jsx)(H.Z,{children:e.max_budget?e.max_budget:"No limit"}),(0,l.jsx)(H.Z,{children:(0,l.jsxs)(M.Z,{children:["TPM Limit:"," ",e.tpm_limit?e.tpm_limit:"Unlimited"," ",(0,l.jsx)("br",{})," RPM Limit:"," ",e.rpm_limit?e.rpm_limit:"Unlimited"]})}),(0,l.jsx)(H.Z,{children:(0,l.jsx)(J.Z,{icon:ek.Z,size:"sm"})})]},e.team_id)):null})]})})]}),(0,l.jsxs)(T.Z,{numColSpan:1,children:[(0,l.jsx)(o.Z,{className:"mx-auto",onClick:()=>Z(!0),children:"+ Create New Team"}),(0,l.jsx)(U.Z,{title:"Create Team",visible:g,width:800,footer:null,onOk:()=>{Z(!1),i.resetFields()},onCancel:()=>{Z(!1),i.resetFields()},children:(0,l.jsxs)(D.Z,{form:i,onFinish:w,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(D.Z.Item,{label:"Team Name",name:"team_alias",children:(0,l.jsx)(L.Z,{})}),(0,l.jsx)(D.Z.Item,{label:"Models",name:"models",children:(0,l.jsx)(O.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"}})}),(0,l.jsx)(D.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,l.jsx)(z.Z,{step:.01,precision:2,width:200})}),(0,l.jsx)(D.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,l.jsx)(z.Z,{step:1,width:400})}),(0,l.jsx)(D.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,l.jsx)(z.Z,{step:1,width:400})})]}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(B.ZP,{htmlType:"submit",children:"Create Team"})})]})})]}),(0,l.jsxs)(T.Z,{numColSpan:1,children:[(0,l.jsx)(h,{level:4,children:"Team Members"}),(0,l.jsx)(m,{children:"If you belong to multiple teams, this setting controls which teams members you see."}),t&&t.length>0?(0,l.jsx)(er.Z,{defaultValue:"0",children:t.map((e,t)=>(0,l.jsx)(ea.Z,{value:String(t),onClick:()=>{j(e)},children:e.team_alias},t))}):(0,l.jsxs)(m,{children:["No team created. ",(0,l.jsx)("b",{children:"Defaulting to personal account."})]})]}),(0,l.jsx)(T.Z,{numColSpan:1,children:(0,l.jsx)(F.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,l.jsxs)(G.Z,{children:[(0,l.jsx)(W.Z,{children:(0,l.jsxs)(X.Z,{children:[(0,l.jsx)(Y.Z,{children:"Member Name"}),(0,l.jsx)(Y.Z,{children:"Role"}),(0,l.jsx)(Y.Z,{children:"Action"})]})}),(0,l.jsx)($.Z,{children:p?p.members_with_roles.map((e,t)=>(0,l.jsxs)(X.Z,{children:[(0,l.jsx)(H.Z,{children:e.user_email?e.user_email:e.user_id?e.user_id:null}),(0,l.jsx)(H.Z,{children:e.role}),(0,l.jsx)(H.Z,{children:(0,l.jsx)(J.Z,{icon:ek.Z,size:"sm"})})]},t)):null})]})})}),(0,l.jsxs)(T.Z,{numColSpan:1,children:[(0,l.jsx)(o.Z,{className:"mx-auto mb-5",onClick:()=>f(!0),children:"+ Add member"}),(0,l.jsx)(U.Z,{title:"Add member",visible:y,width:800,footer:null,onOk:()=>{f(!1),d.resetFields()},onCancel:()=>{f(!1),d.resetFields()},children:(0,l.jsxs)(D.Z,{form:i,onFinish:k,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(D.Z.Item,{label:"Email",name:"user_email",className:"mb-4",children:(0,l.jsx)(L.Z,{name:"user_email",className:"px-3 py-2 border rounded-md w-full"})}),(0,l.jsx)("div",{className:"text-center mb-4",children:"OR"}),(0,l.jsx)(D.Z.Item,{label:"User ID",name:"user_id",className:"mb-4",children:(0,l.jsx)(L.Z,{name:"user_id",className:"px-3 py-2 border rounded-md w-full"})})]}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(B.ZP,{htmlType:"submit",children:"Add member"})})]})})]})]})})},eb=e=>{let{searchParams:t,accessToken:s}=e,[r]=D.Z.useForm(),[a]=D.Z.useForm(),{Title:i,Paragraph:d}=en.default,[h,m]=(0,n.useState)(""),[u,x]=(0,n.useState)(null),[p,j]=(0,n.useState)(!1);(0,n.useEffect)(()=>{(async()=>{if(null!=s){let e=[],t=await S(s,"proxy_admin_viewer");t.forEach(t=>{e.push({user_role:t.user_role,user_id:t.user_id,user_email:t.user_email})}),console.log("proxy viewers: ".concat(t));let l=await S(s,"proxy_admin");l.forEach(t=>{e.push({user_role:t.user_role,user_id:t.user_id,user_email:t.user_email})}),console.log("proxy admins: ".concat(l)),console.log("combinedList: ".concat(e)),x(e)}})()},[s]);let g=async e=>{try{if(null!=s&&null!=u){c.ZP.info("Making API Call"),e.user_email,e.user_id;let t=await C(s,e);console.log("response for team create call: ".concat(t));let l=u.findIndex(e=>(console.log("user.user_id=".concat(e.user_id,"; response.user_id=").concat(t.user_id)),e.user_id===t.user_id));console.log("foundIndex: ".concat(l)),-1==l&&(console.log("updates admin with new user"),u.push(t),x(u)),j(!1)}}catch(e){console.error("Error creating the key:",e)}};return console.log("admins: ".concat(null==u?void 0:u.length)),(0,l.jsxs)("div",{className:"w-full m-2",children:[(0,l.jsx)(i,{level:4,children:"Restricted Access"}),(0,l.jsxs)(d,{children:["Add other people to just view spend. They cannot create keys, teams or grant users access to new models."," ",(0,l.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/ui#restrict-ui-access",children:"Requires SSO Setup"})]}),(0,l.jsxs)(E.Z,{numItems:1,className:"gap-2 p-0 w-full",children:[(0,l.jsx)(T.Z,{numColSpan:1,children:(0,l.jsx)(F.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,l.jsxs)(G.Z,{children:[(0,l.jsx)(W.Z,{children:(0,l.jsxs)(X.Z,{children:[(0,l.jsx)(Y.Z,{children:"Member Name"}),(0,l.jsx)(Y.Z,{children:"Role"}),(0,l.jsx)(Y.Z,{children:"Action"})]})}),(0,l.jsx)($.Z,{children:u?u.map((e,t)=>(0,l.jsxs)(X.Z,{children:[(0,l.jsx)(H.Z,{children:e.user_email?e.user_email:e.user_id?e.user_id:null}),(0,l.jsx)(H.Z,{children:e.user_role}),(0,l.jsx)(H.Z,{children:(0,l.jsx)(J.Z,{icon:ek.Z,size:"sm"})})]},t)):null})]})})}),(0,l.jsxs)(T.Z,{numColSpan:1,children:[(0,l.jsx)(o.Z,{className:"mx-auto mb-5",onClick:()=>j(!0),children:"+ Add viewer"}),(0,l.jsx)(U.Z,{title:"Add viewer",visible:p,width:800,footer:null,onOk:()=>{j(!1),a.resetFields()},onCancel:()=>{j(!1),a.resetFields()},children:(0,l.jsxs)(D.Z,{form:r,onFinish:g,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(D.Z.Item,{label:"Email",name:"user_email",className:"mb-4",children:(0,l.jsx)(L.Z,{name:"user_email",className:"px-3 py-2 border rounded-md w-full"})}),(0,l.jsx)("div",{className:"text-center mb-4",children:"OR"}),(0,l.jsx)(D.Z.Item,{label:"User ID",name:"user_id",className:"mb-4",children:(0,l.jsx)(L.Z,{name:"user_id",className:"px-3 py-2 border rounded-md w-full"})})]}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(B.ZP,{htmlType:"submit",children:"Add member"})})]})})]})]})]})},ev=s(12968),eS=s(67951);async function eN(e,t,s,l){console.log("isLocal:",!1);let n=window.location.origin,r=new ev.ZP.OpenAI({apiKey:l,baseURL:n,dangerouslyAllowBrowser:!0});for await(let l of(await r.chat.completions.create({model:s,stream:!0,messages:[{role:"user",content:e}]})))console.log(l),l.choices[0].delta.content&&t(l.choices[0].delta.content)}var eA=e=>{let{accessToken:t,token:s,userRole:r,userID:a}=e,[o,i]=(0,n.useState)(""),[c,d]=(0,n.useState)([]),[h,m]=(0,n.useState)(void 0),[u,x]=(0,n.useState)(null);(0,n.useEffect)(()=>{t&&s&&r&&a&&(async()=>{let e=await p(t,a,r);console.log("model_info:",e),(null==e?void 0:e.data.length)>0&&(x(e.data),m(e.data[0].id))})()},[t,a,r]);let j=(e,t)=>{d(s=>{let l=s[s.length-1];return l&&l.role===e?[...s.slice(0,s.length-1),{role:e,content:l.content+t}]:[...s,{role:e,content:t}]})},g=async()=>{if(""!==o.trim()&&t&&s&&r&&a){d(e=>[...e,{role:"user",content:o}]);try{h&&await eN(o,e=>j("assistant",e),h,t)}catch(e){console.error("Error fetching model response",e),j("assistant","Error fetching model response")}i("")}};if(r&&"Admin Viewer"==r){let{Title:e,Paragraph:t}=en.default;return(0,l.jsxs)("div",{children:[(0,l.jsx)(e,{level:1,children:"Access Denied"}),(0,l.jsx)(t,{children:"Ask your proxy admin for access to test models"})]})}return(0,l.jsx)("div",{style:{width:"100%",position:"relative"},children:(0,l.jsx)(E.Z,{className:"gap-2 p-10 h-[75vh] w-full",children:(0,l.jsx)(F.Z,{children:(0,l.jsxs)(ep.Z,{children:[(0,l.jsxs)(ej.Z,{className:"mt-4",children:[(0,l.jsx)(ex.Z,{children:"Chat"}),(0,l.jsx)(ex.Z,{children:"API Reference"})]}),(0,l.jsxs)(eZ.Z,{children:[(0,l.jsxs)(eg.Z,{children:[(0,l.jsxs)("div",{children:[(0,l.jsx)("label",{children:"Select Model:"}),(0,l.jsx)("select",{value:h||"",onChange:e=>m(e.target.value),children:null==u?void 0:u.map(e=>(0,l.jsx)("option",{value:e.id,children:e.id},e.id))})]}),(0,l.jsxs)(G.Z,{className:"mt-5",style:{display:"block",maxHeight:"60vh",overflowY:"auto"},children:[(0,l.jsx)(W.Z,{children:(0,l.jsx)(X.Z,{children:(0,l.jsx)(H.Z,{children:(0,l.jsx)(R.Z,{children:"Chat"})})})}),(0,l.jsx)($.Z,{children:c.map((e,t)=>(0,l.jsx)(X.Z,{children:(0,l.jsx)(H.Z,{children:"".concat(e.role,": ").concat(e.content)})},t))})]}),(0,l.jsx)("div",{className:"mt-3",style:{position:"absolute",bottom:5,width:"95%"},children:(0,l.jsxs)("div",{className:"flex",children:[(0,l.jsx)("input",{type:"text",value:o,onChange:e=>i(e.target.value),className:"flex-1 p-2 border rounded-md mr-2",placeholder:"Type your message..."}),(0,l.jsx)("button",{onClick:g,className:"p-2 bg-blue-500 text-white rounded-md",children:"Send"})]})})]}),(0,l.jsx)(eg.Z,{children:(0,l.jsxs)(ep.Z,{children:[(0,l.jsxs)(ej.Z,{children:[(0,l.jsx)(ex.Z,{children:"OpenAI Python SDK"}),(0,l.jsx)(ex.Z,{children:"LlamaIndex"}),(0,l.jsx)(ex.Z,{children:"Langchain Py"})]}),(0,l.jsxs)(eZ.Z,{children:[(0,l.jsx)(eg.Z,{children:(0,l.jsx)(eS.Z,{language:"python",children:'\nimport openai\nclient = openai.OpenAI(\n api_key="your_api_key",\n base_url="http://0.0.0.0:4000" # proxy base url\n)\n\nresponse = client.chat.completions.create(\n model="gpt-3.5-turbo", # model to use from Models Tab\n messages = [\n {\n "role": "user",\n "content": "this is a test request, write a short poem"\n }\n ],\n extra_body={\n "metadata": {\n "generation_name": "ishaan-generation-openai-client",\n "generation_id": "openai-client-gen-id22",\n "trace_id": "openai-client-trace-id22",\n "trace_user_id": "openai-client-user-id2"\n }\n }\n)\n\nprint(response)\n '})}),(0,l.jsx)(eg.Z,{children:(0,l.jsx)(eS.Z,{language:"python",children:'\nimport os, dotenv\n\nfrom llama_index.llms import AzureOpenAI\nfrom llama_index.embeddings import AzureOpenAIEmbedding\nfrom llama_index import VectorStoreIndex, SimpleDirectoryReader, ServiceContext\n\nllm = AzureOpenAI(\n engine="azure-gpt-3.5", # model_name on litellm proxy\n temperature=0.0,\n azure_endpoint="http://0.0.0.0:4000", # litellm proxy endpoint\n api_key="sk-1234", # litellm proxy API Key\n api_version="2023-07-01-preview",\n)\n\nembed_model = AzureOpenAIEmbedding(\n deployment_name="azure-embedding-model",\n azure_endpoint="http://0.0.0.0:4000",\n api_key="sk-1234",\n api_version="2023-07-01-preview",\n)\n\n\ndocuments = SimpleDirectoryReader("llama_index_data").load_data()\nservice_context = ServiceContext.from_defaults(llm=llm, embed_model=embed_model)\nindex = VectorStoreIndex.from_documents(documents, service_context=service_context)\n\nquery_engine = index.as_query_engine()\nresponse = query_engine.query("What did the author do growing up?")\nprint(response)\n\n '})}),(0,l.jsx)(eg.Z,{children:(0,l.jsx)(eS.Z,{language:"python",children:'\nfrom langchain.chat_models import ChatOpenAI\nfrom langchain.prompts.chat import (\n ChatPromptTemplate,\n HumanMessagePromptTemplate,\n SystemMessagePromptTemplate,\n)\nfrom langchain.schema import HumanMessage, SystemMessage\n\nchat = ChatOpenAI(\n openai_api_base="http://0.0.0.0:8000",\n model = "gpt-3.5-turbo",\n temperature=0.1,\n extra_body={\n "metadata": {\n "generation_name": "ishaan-generation-langchain-client",\n "generation_id": "langchain-client-gen-id22",\n "trace_id": "langchain-client-trace-id22",\n "trace_user_id": "langchain-client-user-id2"\n }\n }\n)\n\nmessages = [\n SystemMessage(\n content="You are a helpful assistant that im using to make a test request to."\n ),\n HumanMessage(\n content="test from litellm. tell me why it\'s amazing in 1 sentence"\n ),\n]\nresponse = chat(messages)\n\nprint(response)\n\n '})})]})]})})]})]})})})})},eC=s(33509),eI=s(30569);let{Sider:eP}=eC.default;var eT=e=>{let{setPage:t,userRole:s,defaultSelectedKey:n}=e;return"Admin Viewer"==s?(0,l.jsx)(eC.default,{style:{minHeight:"100vh",maxWidth:"120px"},children:(0,l.jsx)(eP,{width:120,children:(0,l.jsxs)(eI.Z,{mode:"inline",defaultSelectedKeys:n||["4"],style:{height:"100%",borderRight:0},children:[(0,l.jsx)(eI.Z.Item,{onClick:()=>t("api-keys"),children:"API Keys"},"4"),(0,l.jsx)(eI.Z.Item,{onClick:()=>t("models"),children:"Models"},"2"),(0,l.jsx)(eI.Z.Item,{onClick:()=>t("llm-playground"),children:"Chat UI"},"3"),(0,l.jsx)(eI.Z.Item,{onClick:()=>t("usage"),children:"Usage"},"1")]})})}):(0,l.jsx)(eC.default,{style:{minHeight:"100vh",maxWidth:"120px"},children:(0,l.jsx)(eP,{width:120,children:(0,l.jsxs)(eI.Z,{mode:"inline",defaultSelectedKeys:n||["1"],style:{height:"100%",borderRight:0},children:[(0,l.jsx)(eI.Z.Item,{onClick:()=>t("api-keys"),children:"API Keys"},"1"),(0,l.jsx)(eI.Z.Item,{onClick:()=>t("models"),children:"Models"},"2"),(0,l.jsx)(eI.Z.Item,{onClick:()=>t("llm-playground"),children:"Chat UI"},"3"),(0,l.jsx)(eI.Z.Item,{onClick:()=>t("usage"),children:"Usage"},"4"),"Admin"==s?(0,l.jsx)(eI.Z.Item,{onClick:()=>t("users"),children:"Users"},"5"):null,"Admin"==s?(0,l.jsx)(eI.Z.Item,{onClick:()=>t("teams"),children:"Teams"},"6"):null,"Admin"==s?(0,l.jsx)(eI.Z.Item,{onClick:()=>t("admin-panel"),children:"Admin"},"7"):null]})})})},eE=e=>{let{accessToken:t,token:s,userRole:r,userID:a}=e,o=new Date,[i,c]=(0,n.useState)([]),[d,h]=(0,n.useState)([]),[m,u]=(0,n.useState)([]),[x,p]=(0,n.useState)([]),j=new Date(o.getFullYear(),o.getMonth(),1),f=new Date(o.getFullYear(),o.getMonth()+1,0),_=v(j),b=v(f);function v(e){let t=e.getFullYear(),s=e.getMonth()+1,l=e.getDate();return"".concat(t,"-").concat(s<10?"0"+s:s,"-").concat(l<10?"0"+l:l)}return console.log("Start date is ".concat(_)),console.log("End date is ".concat(b)),(0,n.useEffect)(()=>{t&&s&&r&&a&&(async()=>{try{if(console.log("user role: ".concat(r)),"Admin"==r||"Admin Viewer"==r){let e=await Z(t);c(e);let s=(await y(t)).map(e=>({key:(e.key_name||e.key_alias||e.api_key).substring(0,7),spend:e.total_spend}));h(s);let l=(await w(t)).map(e=>({key:e.model,spend:e.total_spend}));u(l)}else"App Owner"==r&&await g(t,s,r,a,_,b).then(async e=>{if(console.log("result from spend logs call",e),"daily_spend"in e){let t=e.daily_spend;console.log("daily spend",t),c(t);let s=e.top_api_keys;h(s)}else{let s=(await k(t,function(e){let t=[];e.forEach(e=>{Object.entries(e).forEach(e=>{let[s,l]=e;"spend"!==s&&"startTime"!==s&&"models"!==s&&"users"!==s&&t.push({key:s,spend:l})})}),t.sort((e,t)=>Number(t.spend)-Number(e.spend));let s=t.slice(0,5).map(e=>e.key);return console.log("topKeys: ".concat(Object.keys(s[0]))),s}(e))).info.map(e=>({key:(e.key_name||e.key_alias||e.token).substring(0,7),spend:e.spend}));h(s),p(function(e){let t={};e.forEach(e=>{Object.entries(e.users).forEach(e=>{let[s,l]=e;""!==s&&null!=s&&"None"!=s&&(t[s]||(t[s]=0),t[s]+=l)})});let s=Object.entries(t).map(e=>{let[t,s]=e;return{user_id:t,spend:s}});s.sort((e,t)=>t.spend-e.spend);let l=s.slice(0,5);return console.log("topKeys: ".concat(Object.values(l[0]))),l}(e)),c(e)}})}catch(e){console.error("There was an error fetching the data",e)}})()},[t,s,r,a,_,b]),(0,l.jsx)("div",{style:{width:"100%"},children:(0,l.jsxs)(E.Z,{numItems:2,className:"gap-2 p-10 h-[75vh] w-full",children:[(0,l.jsx)(T.Z,{numColSpan:2,children:(0,l.jsxs)(F.Z,{children:[(0,l.jsx)(R.Z,{children:"Monthly Spend"}),(0,l.jsx)(Q.Z,{data:i,index:"date",categories:["spend"],colors:["blue"],valueFormatter:e=>"$ ".concat(new Intl.NumberFormat("us").format(e).toString()),yAxisWidth:100,tickGap:5})]})}),(0,l.jsx)(T.Z,{numColSpan:1,children:(0,l.jsxs)(F.Z,{children:[(0,l.jsx)(R.Z,{children:"Top API Keys"}),(0,l.jsx)(Q.Z,{className:"mt-4 h-40",data:d,index:"key",categories:["spend"],colors:["blue"],yAxisWidth:80,tickGap:5,layout:"vertical",showXAxis:!1,showLegend:!1})]})}),(0,l.jsx)(T.Z,{numColSpan:1,children:(0,l.jsxs)(F.Z,{children:[(0,l.jsx)(R.Z,{children:"Top Users"}),(0,l.jsx)(Q.Z,{className:"mt-4 h-40",data:x,index:"user_id",categories:["spend"],colors:["blue"],yAxisWidth:200,layout:"vertical",showXAxis:!1,showLegend:!1})]})}),(0,l.jsx)(T.Z,{numColSpan:1,children:(0,l.jsxs)(F.Z,{children:[(0,l.jsx)(R.Z,{children:"Top Models"}),(0,l.jsx)(Q.Z,{className:"mt-4 h-40",data:m,index:"key",categories:["spend"],colors:["blue"],yAxisWidth:200,layout:"vertical",showXAxis:!1,showLegend:!1})]})})]})})},eF=()=>{let{Title:e,Paragraph:t}=en.default,[s,a]=(0,n.useState)(""),[o,c]=(0,n.useState)(null),[d,h]=(0,n.useState)(null),[m,u]=(0,n.useState)(null),[x,p]=(0,n.useState)(!0),j=(0,r.useSearchParams)(),g=j.get("userID"),Z=j.get("token"),[y,f]=(0,n.useState)("api-keys"),[w,k]=(0,n.useState)(null);return(0,n.useEffect)(()=>{if(Z){let e=(0,ei.o)(Z);if(e){if(console.log("Decoded token:",e),console.log("Decoded key:",e.key),k(e.key),e.user_role){let t=function(e){if(!e)return"Undefined Role";switch(console.log("Received user role: ".concat(e.toLowerCase())),console.log("Received user role length: ".concat(e.toLowerCase().length)),e.toLowerCase()){case"app_owner":case"demo_app_owner":return"App Owner";case"app_admin":case"proxy_admin":return"Admin";case"proxy_admin_viewer":return"Admin Viewer";case"app_user":return"App User";default:return"Unknown Role"}}(e.user_role);console.log("Decoded user_role:",t),a(t),"Admin Viewer"==t&&f("usage")}else console.log("User role not defined");e.user_email?c(e.user_email):console.log("User Email is not set ".concat(e)),e.login_method?p("username_password"==e.login_method):console.log("User Email is not set ".concat(e))}}},[Z]),(0,l.jsx)(n.Suspense,{fallback:(0,l.jsx)("div",{children:"Loading..."}),children:(0,l.jsxs)("div",{className:"flex flex-col min-h-screen",children:[(0,l.jsx)(i,{userID:g,userRole:s,userEmail:o,showSSOBanner:x}),(0,l.jsxs)("div",{className:"flex flex-1 overflow-auto",children:[(0,l.jsx)(eT,{setPage:f,userRole:s,defaultSelectedKey:null}),"api-keys"==y?(0,l.jsx)(ec,{userID:g,userRole:s,teams:d,keys:m,setUserRole:a,userEmail:o,setUserEmail:c,setTeams:h,setKeys:u}):"models"==y?(0,l.jsx)(eu,{userID:g,userRole:s,token:Z,accessToken:w}):"llm-playground"==y?(0,l.jsx)(eA,{userID:g,userRole:s,token:Z,accessToken:w}):"users"==y?(0,l.jsx)(ew,{userID:g,userRole:s,token:Z,keys:m,accessToken:w,setKeys:u}):"teams"==y?(0,l.jsx)(e_,{teams:d,setTeams:h,searchParams:j,accessToken:w}):"admin-panel"==y?(0,l.jsx)(eb,{setTeams:h,searchParams:j,accessToken:w}):(0,l.jsx)(eE,{userID:g,userRole:s,token:Z,accessToken:w})]})]})})}}},function(e){e.O(0,[730,971,69,744],function(){return e(e.s=20661)}),_N_E=e.O()}]);
\ No newline at end of file
diff --git a/litellm/proxy/_experimental/out/index.html b/litellm/proxy/_experimental/out/index.html
index aaaaa698a..437d90aac 100644
--- a/litellm/proxy/_experimental/out/index.html
+++ b/litellm/proxy/_experimental/out/index.html
@@ -1 +1 @@
-🚅 LiteLLM
\ No newline at end of file
+🚅 LiteLLM
\ No newline at end of file
diff --git a/litellm/proxy/_experimental/out/index.txt b/litellm/proxy/_experimental/out/index.txt
index 72b67997a..28c9282be 100644
--- a/litellm/proxy/_experimental/out/index.txt
+++ b/litellm/proxy/_experimental/out/index.txt
@@ -1,7 +1,7 @@
2:I[77831,[],""]
-3:I[56239,["730","static/chunks/730-1411b729a1c79695.js","931","static/chunks/app/page-37bd7c3d0bb898a3.js"],""]
+3:I[57492,["730","static/chunks/730-1411b729a1c79695.js","931","static/chunks/app/page-2ed0bc91ffef505b.js"],""]
4:I[5613,[],""]
5:I[31778,[],""]
-0:["p1zjZBLDqxGf-NaFvZkeF",[[["",{"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/32e93a3d13512de5.css","precedence":"next","crossOrigin":""}]],"$L6"]]]]
+0:["ZF-EluyKCEJoZptE3dOXT",[[["",{"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/32e93a3d13512de5.css","precedence":"next","crossOrigin":""}]],"$L6"]]]]
6:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"🚅 LiteLLM"}],["$","meta","3",{"name":"description","content":"LiteLLM Proxy Admin UI"}],["$","link","4",{"rel":"icon","href":"/ui/favicon.ico","type":"image/x-icon","sizes":"16x16"}],["$","meta","5",{"name":"next-size-adjust"}]]
1:null
diff --git a/litellm/proxy/proxy_server.py b/litellm/proxy/proxy_server.py
index 7dbb068bc..47b8c1535 100644
--- a/litellm/proxy/proxy_server.py
+++ b/litellm/proxy/proxy_server.py
@@ -5811,6 +5811,58 @@ async def model_info_v2(
return {"data": all_models}
+@router.get(
+ "/model/metrics",
+ description="View number of requests & avg latency per model on config.yaml",
+ tags=["model management"],
+ dependencies=[Depends(user_api_key_auth)],
+)
+async def model_metrics(
+ user_api_key_dict: UserAPIKeyAuth = Depends(user_api_key_auth),
+):
+ global prisma_client
+ if prisma_client is None:
+ raise ProxyException(
+ message="Prisma Client is not initialized",
+ type="internal_error",
+ param="None",
+ code=status.HTTP_500_INTERNAL_SERVER_ERROR,
+ )
+
+ sql_query = """
+ SELECT
+ CASE WHEN api_base = '' THEN model ELSE CONCAT(model, '-', api_base) END AS combined_model_api_base,
+ COUNT(*) AS num_requests,
+ AVG(EXTRACT(epoch FROM ("endTime" - "startTime"))) AS avg_latency_seconds
+ FROM
+ "LiteLLM_SpendLogs"
+ WHERE
+ "startTime" >= NOW() - INTERVAL '10000 hours'
+ GROUP BY
+ CASE WHEN api_base = '' THEN model ELSE CONCAT(model, '-', api_base) END
+ ORDER BY
+ num_requests DESC
+ LIMIT 50;
+ """
+
+ db_response = await prisma_client.db.query_raw(query=sql_query)
+ response: List[dict] = []
+ if response is not None:
+ # loop through all models
+ for model_data in db_response:
+ model = model_data.get("combined_model_api_base", "")
+ num_requests = model_data.get("num_requests", 0)
+ avg_latency_seconds = model_data.get("avg_latency_seconds", 0)
+ response.append(
+ {
+ "model": model,
+ "num_requests": num_requests,
+ "avg_latency_seconds": avg_latency_seconds,
+ }
+ )
+ return response
+
+
@router.get(
"/model/info",
description="Provides more info about each model in /models, including config.yaml descriptions (except api key and api base)",
diff --git a/litellm/tests/test_completion.py b/litellm/tests/test_completion.py
index 9c7796c50..57b0e436f 100644
--- a/litellm/tests/test_completion.py
+++ b/litellm/tests/test_completion.py
@@ -56,7 +56,7 @@ def test_completion_custom_provider_model_name():
def test_completion_claude():
litellm.set_verbose = True
litellm.cache = None
- litellm.AnthropicConfig(max_tokens=200, metadata={"user_id": "1224"})
+ litellm.AnthropicTextConfig(max_tokens_to_sample=200, metadata={"user_id": "1224"})
messages = [
{
"role": "system",
@@ -67,10 +67,7 @@ def test_completion_claude():
try:
# test without max tokens
response = completion(
- model="claude-instant-1.2",
- messages=messages,
- request_timeout=10,
- max_tokens=10,
+ model="claude-instant-1", messages=messages, request_timeout=10
)
# Add any assertions, here to check response args
print(response)
diff --git a/litellm/utils.py b/litellm/utils.py
index e42ab836c..d4d85cad1 100644
--- a/litellm/utils.py
+++ b/litellm/utils.py
@@ -4216,6 +4216,11 @@ def get_optional_params(
if top_p is not None:
optional_params["top_p"] = top_p
if max_tokens is not None:
+ if (model == "claude-2") or (model == "claude-instant-1"):
+ # these models use antropic_text.py which only accepts max_tokens_to_sample
+ optional_params["max_tokens_to_sample"] = max_tokens
+ else:
+ optional_params["max_tokens"] = max_tokens
optional_params["max_tokens"] = max_tokens
if tools is not None:
optional_params["tools"] = tools
diff --git a/pyproject.toml b/pyproject.toml
index 78d4b5cea..8de9a9f10 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
[tool.poetry]
name = "litellm"
-version = "1.28.14"
+version = "1.29.2"
description = "Library to easily interface with LLM API providers"
authors = ["BerriAI"]
license = "MIT"
@@ -74,7 +74,7 @@ requires = ["poetry-core", "wheel"]
build-backend = "poetry.core.masonry.api"
[tool.commitizen]
-version = "1.28.14"
+version = "1.29.2"
version_files = [
"pyproject.toml:^version"
]
diff --git a/ui/litellm-dashboard/out/404.html b/ui/litellm-dashboard/out/404.html
index 064bb2163..eb5cf4286 100644
--- a/ui/litellm-dashboard/out/404.html
+++ b/ui/litellm-dashboard/out/404.html
@@ -1 +1 @@
-404: This page could not be found.🚅 LiteLLM
404
This page could not be found.
\ No newline at end of file
+404: This page could not be found.🚅 LiteLLM
404
This page could not be found.
\ No newline at end of file
diff --git a/ui/litellm-dashboard/out/_next/static/p1zjZBLDqxGf-NaFvZkeF/_buildManifest.js b/ui/litellm-dashboard/out/_next/static/ZF-EluyKCEJoZptE3dOXT/_buildManifest.js
similarity index 100%
rename from ui/litellm-dashboard/out/_next/static/p1zjZBLDqxGf-NaFvZkeF/_buildManifest.js
rename to ui/litellm-dashboard/out/_next/static/ZF-EluyKCEJoZptE3dOXT/_buildManifest.js
diff --git a/ui/litellm-dashboard/out/_next/static/p1zjZBLDqxGf-NaFvZkeF/_ssgManifest.js b/ui/litellm-dashboard/out/_next/static/ZF-EluyKCEJoZptE3dOXT/_ssgManifest.js
similarity index 100%
rename from ui/litellm-dashboard/out/_next/static/p1zjZBLDqxGf-NaFvZkeF/_ssgManifest.js
rename to ui/litellm-dashboard/out/_next/static/ZF-EluyKCEJoZptE3dOXT/_ssgManifest.js
diff --git a/ui/litellm-dashboard/out/_next/static/chunks/app/page-2ed0bc91ffef505b.js b/ui/litellm-dashboard/out/_next/static/chunks/app/page-2ed0bc91ffef505b.js
new file mode 100644
index 000000000..a0bd09f21
--- /dev/null
+++ b/ui/litellm-dashboard/out/_next/static/chunks/app/page-2ed0bc91ffef505b.js
@@ -0,0 +1 @@
+(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[931],{20661:function(e,t,s){Promise.resolve().then(s.bind(s,57492))},57492:function(e,t,s){"use strict";s.r(t),s.d(t,{default:function(){return eM}});var l=s(3827),n=s(64090),r=s(47907),a=s(8792),o=s(2179),i=e=>{let{userID:t,userRole:s,userEmail:n,showSSOBanner:r}=e;return console.log("User ID:",t),console.log("userEmail:",n),(0,l.jsxs)("nav",{className:"left-0 right-0 top-0 flex justify-between items-center h-12 mb-4",children:[(0,l.jsx)("div",{className:"text-left my-2 absolute top-0 left-0",children:(0,l.jsx)("div",{className:"flex flex-col items-center",children:(0,l.jsx)(a.default,{href:"/",children:(0,l.jsx)("button",{className:"text-gray-800 text-2xl py-1 rounded text-center",children:(0,l.jsx)("img",{src:"/get_image",width:200,height:200,alt:"LiteLLM Brand",className:"mr-2"})})})})}),(0,l.jsxs)("div",{className:"text-right mx-4 my-2 absolute top-0 right-0 flex items-center justify-end space-x-2",children:[r?(0,l.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/ui#setup-ssoauth-for-ui",target:"_blank",className:"mr-2",children:(0,l.jsx)(o.Z,{variant:"primary",size:"lg",children:"Enable SSO"})}):null,(0,l.jsxs)(o.Z,{variant:"secondary",size:"lg",children:[n,(0,l.jsxs)("p",{children:["Role: ",s]}),(0,l.jsxs)("p",{children:["ID: ",t]})]})]})]})},c=s(80588);let d=async(e,t,s)=>{try{if(console.log("Form Values in keyCreateCall:",s),s.description&&(s.metadata||(s.metadata={}),s.metadata.description=s.description,delete s.description,s.metadata=JSON.stringify(s.metadata)),s.metadata){console.log("formValues.metadata:",s.metadata);try{s.metadata=JSON.parse(s.metadata)}catch(e){throw c.ZP.error("Failed to parse metadata: "+e),Error("Failed to parse metadata: "+e)}}console.log("Form Values after check:",s);let l=await fetch("/key/generate",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({user_id:t,...s})});if(!l.ok){let e=await l.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let n=await l.json();return console.log("API Response:",n),n}catch(e){throw console.error("Failed to create key:",e),e}},h=async(e,t,s)=>{try{if(console.log("Form Values in keyCreateCall:",s),s.description&&(s.metadata||(s.metadata={}),s.metadata.description=s.description,delete s.description,s.metadata=JSON.stringify(s.metadata)),s.metadata){console.log("formValues.metadata:",s.metadata);try{s.metadata=JSON.parse(s.metadata)}catch(e){throw c.ZP.error("Failed to parse metadata: "+e),Error("Failed to parse metadata: "+e)}}console.log("Form Values after check:",s);let l=await fetch("/user/new",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({user_id:t,...s})});if(!l.ok){let e=await l.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let n=await l.json();return console.log("API Response:",n),n}catch(e){throw console.error("Failed to create key:",e),e}},m=async(e,t)=>{try{console.log("in keyDeleteCall:",t),c.ZP.info("Making key delete request");let s=await fetch("/key/delete",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({keys:[t]})});if(!s.ok){let e=await s.text();throw c.ZP.error("Failed to delete key: "+e),Error("Network response was not ok")}let l=await s.json();return console.log(l),c.ZP.success("API Key Deleted"),l}catch(e){throw console.error("Failed to create key:",e),e}},u=async function(e,t,s){let l=arguments.length>3&&void 0!==arguments[3]&&arguments[3];try{let n="/user/info";"App Owner"==s&&t&&(n="".concat(n,"/?user_id=").concat(t)),console.log("in userInfoCall viewAll=",l),l&&(n="".concat(n,"/?view_all=true")),c.ZP.info("Requesting user data");let r=await fetch(n,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!r.ok){let e=await r.text();throw c.ZP.error(e),Error("Network response was not ok")}let a=await r.json();return console.log("API Response:",a),c.ZP.info("Received user data"),a}catch(e){throw console.error("Failed to create key:",e),e}},x=async(e,t,s)=>{try{c.ZP.info("Requesting model data");let t=await fetch("/v2/model/info",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}let s=await t.json();return c.ZP.info("Received model data"),s}catch(e){throw console.error("Failed to create key:",e),e}},p=async(e,t,s)=>{try{let t=await fetch("/model/metrics",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},j=async(e,t,s)=>{try{c.ZP.info("Requesting model data");let t=await fetch("/models",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}let s=await t.json();return c.ZP.info("Received model data"),s}catch(e){throw console.error("Failed to create key:",e),e}},g=async(e,t)=>{try{let s="/global/spend/logs";console.log("in keySpendLogsCall:",s);let l=await fetch("".concat(s,"/?api_key=").concat(t),{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw c.ZP.error(e),Error("Network response was not ok")}let n=await l.json();return console.log(n),n}catch(e){throw console.error("Failed to create key:",e),e}},y=async(e,t,s,l,n,r)=>{try{console.log("user role in spend logs call: ".concat(s));let t="/spend/logs";t="App Owner"==s?"".concat(t,"/?user_id=").concat(l,"&start_date=").concat(n,"&end_date=").concat(r):"".concat(t,"/?start_date=").concat(n,"&end_date=").concat(r),c.ZP.info("Making spend logs request");let a=await fetch(t,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!a.ok){let e=await a.text();throw c.ZP.error(e),Error("Network response was not ok")}let o=await a.json();return console.log(o),c.ZP.success("Spend Logs received"),o}catch(e){throw console.error("Failed to create key:",e),e}},Z=async e=>{try{c.ZP.info("Making spend logs request");let t=await fetch("/global/spend/logs",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}let s=await t.json();return console.log(s),c.ZP.success("Spend Logs received"),s}catch(e){throw console.error("Failed to create key:",e),e}},f=async e=>{try{c.ZP.info("Making spend keys request");let t=await fetch("/global/spend/keys?limit=5",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}let s=await t.json();return console.log(s),c.ZP.success("Spend Logs received"),s}catch(e){throw console.error("Failed to create key:",e),e}},w=async(e,t)=>{try{t&&JSON.stringify({api_key:t}),c.ZP.info("Making top end users request");let s={method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}};t&&(s.body=JSON.stringify({api_key:t}));let l=await fetch("/global/spend/end_users",s);if(!l.ok){let e=await l.text();throw c.ZP.error(e),Error("Network response was not ok")}let n=await l.json();return console.log(n),c.ZP.success("Top End users received"),n}catch(e){throw console.error("Failed to create key:",e),e}},k=async e=>{try{c.ZP.info("Making top models request");let t=await fetch("/global/spend/models?limit=5",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}let s=await t.json();return console.log(s),c.ZP.success("Top Models received"),s}catch(e){throw console.error("Failed to create key:",e),e}},_=async(e,t)=>{try{let s=await fetch("/v2/key/info",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({keys:t})});if(!s.ok){let e=await s.text();throw c.ZP.error(e),Error("Network response was not ok")}let l=await s.json();return console.log(l),l}catch(e){throw console.error("Failed to create key:",e),e}},b=async(e,t)=>{try{let s="/spend/users";console.log("in spendUsersCall:",s);let l=await fetch("".concat(s,"/?user_id=").concat(t),{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw c.ZP.error(e),Error("Network response was not ok")}let n=await l.json();return console.log(n),n}catch(e){throw console.error("Failed to get spend for user",e),e}},v=async(e,t,s,l)=>{try{let n=await fetch("/user/request_model",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({models:[t],user_id:s,justification:l})});if(!n.ok){let e=await n.text();throw c.ZP.error("Failed to delete key: "+e),Error("Network response was not ok")}let r=await n.json();return console.log(r),c.ZP.success(""),r}catch(e){throw console.error("Failed to create key:",e),e}},S=async e=>{try{let t="/user/get_requests";console.log("in userGetRequesedtModelsCall:",t);let s=await fetch(t,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!s.ok){let e=await s.text();throw c.ZP.error("Failed to delete key: "+e),Error("Network response was not ok")}let l=await s.json();return console.log(l),c.ZP.success(""),l}catch(e){throw console.error("Failed to get requested models:",e),e}},N=async(e,t)=>{try{let s="/user/get_users?role=".concat(t);console.log("in userGetAllUsersCall:",s);let l=await fetch(s,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw c.ZP.error("Failed to delete key: "+e),Error("Network response was not ok")}let n=await l.json();return console.log(n),c.ZP.success("Got all users"),n}catch(e){throw console.error("Failed to get requested models:",e),e}},A=async(e,t)=>{try{console.log("Form Values in teamCreateCall:",t);let s=await fetch("/team/new",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...t})});if(!s.ok){let e=await s.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let l=await s.json();return console.log("API Response:",l),l}catch(e){throw console.error("Failed to create key:",e),e}},C=async(e,t,s)=>{try{console.log("Form Values in teamMemberAddCall:",s);let l=await fetch("/team/member_add",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({team_id:t,member:s})});if(!l.ok){let e=await l.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let n=await l.json();return console.log("API Response:",n),n}catch(e){throw console.error("Failed to create key:",e),e}},I=async(e,t)=>{try{console.log("Form Values in userUpdateUserCall:",t);let s=await fetch("/user/update",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({user_role:"proxy_admin_viewer",...t})});if(!s.ok){let e=await s.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let l=await s.json();return console.log("API Response:",l),c.ZP.success("User role updated"),l}catch(e){throw console.error("Failed to create key:",e),e}},P=async(e,t)=>{try{let s=await fetch("/global/predict/spend/logs",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({data:t})});if(!s.ok){let e=await s.text();throw c.ZP.error(e),Error("Network response was not ok")}let l=await s.json();return console.log(l),l}catch(e){throw console.error("Failed to create key:",e),e}},T=async e=>{try{console.log("Checking Slack Budget Alerts service health"),c.ZP.info("Sending Test Slack alert...");let t=await fetch("/health/services?service=slack_budget_alerts",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error("Failed Slack Alert test: "+e),Error(e)}let s=await t.json();return c.ZP.success("Test Slack Alert worked - check your Slack!"),console.log("Service Health Response:",s),s}catch(e){throw console.error("Failed to perform health check:",e),e}};var E=s(10384),F=s(46453),M=s(13810),R=s(71801),O=s(42440),D=s(17189),U=s(12143),L=s(77171),z=s(42539),B=s(88707),q=s(1861);let{Option:K}=D.default;var V=e=>{let{userID:t,teamID:s,userRole:r,accessToken:a,data:i,userModels:h,setData:m}=e,[u]=U.Z.useForm(),[x,p]=(0,n.useState)(!1),[j,g]=(0,n.useState)(null),[y,Z]=(0,n.useState)(null),f=()=>{p(!1),u.resetFields()},w=()=>{p(!1),g(null),u.resetFields()},k=async e=>{try{c.ZP.info("Making API Call"),p(!0);let s=await d(a,t,e);console.log("key create Response:",s),m(e=>e?[...e,s]:[s]),g(s.key),Z(s.soft_budget),c.ZP.success("API Key Created"),u.resetFields(),localStorage.removeItem("userData"+t)}catch(e){console.error("Error creating the key:",e)}},_=async()=>{try{console.log("Sending Slack alert...");let e=await T(a);console.log("slackBudgetAlertsHealthCheck Response:",e),console.log("Testing Slack alert successful")}catch(e){console.error("Error sending Slack alert:",e)}};return(0,l.jsxs)("div",{children:[(0,l.jsx)(o.Z,{className:"mx-auto",onClick:()=>p(!0),children:"+ Create New Key"}),(0,l.jsx)(L.Z,{title:"Create Key",visible:x,width:800,footer:null,onOk:f,onCancel:w,children:(0,l.jsxs)(U.Z,{form:u,onFinish:k,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:["App Owner"===r||"Admin"===r?(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(U.Z.Item,{label:"Key Name",name:"key_alias",children:(0,l.jsx)(z.Z,{})}),(0,l.jsx)(U.Z.Item,{label:"Team ID",name:"team_id",children:(0,l.jsx)(z.Z,{placeholder:"ai_team",defaultValue:s||""})}),(0,l.jsx)(U.Z.Item,{label:"Models",name:"models",children:(0,l.jsx)(D.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:h.map(e=>(0,l.jsx)(K,{value:e,children:e},e))})}),(0,l.jsx)(U.Z.Item,{label:"Soft Budget (USD) Monthly",name:"soft_budget",initialValue:50,children:(0,l.jsx)(B.Z,{step:.01,precision:2,defaultValue:50,width:200})}),(0,l.jsx)(U.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,l.jsx)(B.Z,{step:.01,precision:2,width:200})}),(0,l.jsx)(U.Z.Item,{label:"Reset Budget",name:"budget_duration",children:(0,l.jsxs)(D.default,{defaultValue:null,placeholder:"n/a",children:[(0,l.jsx)(D.default.Option,{value:"24h",children:"daily"}),(0,l.jsx)(D.default.Option,{value:"30d",children:"monthly"})]})}),(0,l.jsx)(U.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,l.jsx)(B.Z,{step:1,width:400})}),(0,l.jsx)(U.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,l.jsx)(B.Z,{step:1,width:400})}),(0,l.jsx)(U.Z.Item,{label:"Expire Key (eg: 30s, 30h, 30d)",name:"duration",children:(0,l.jsx)(z.Z,{})}),(0,l.jsx)(U.Z.Item,{label:"Metadata",name:"metadata",children:(0,l.jsx)(z.Z.TextArea,{rows:4,placeholder:"Enter metadata as JSON"})})]}):(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(U.Z.Item,{label:"Key Name",name:"key_alias",children:(0,l.jsx)(z.Z,{})}),(0,l.jsx)(U.Z.Item,{label:"Team ID (Contact Group)",name:"team_id",children:(0,l.jsx)(z.Z,{placeholder:"ai_team"})}),(0,l.jsx)(U.Z.Item,{label:"Description",name:"description",children:(0,l.jsx)(z.Z.TextArea,{placeholder:"Enter description",rows:4})})]}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(q.ZP,{htmlType:"submit",children:"Create Key"})})]})}),j&&(0,l.jsx)(L.Z,{visible:x,onOk:f,onCancel:w,footer:null,children:(0,l.jsx)(F.Z,{numItems:1,className:"gap-2 w-full",children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(O.Z,{children:"Save your Key"}),(0,l.jsx)(E.Z,{numColSpan:1,children:(0,l.jsxs)("p",{children:["Please save this secret key somewhere safe and accessible. For security reasons, ",(0,l.jsx)("b",{children:"you will not be able to view it again"})," ","through your LiteLLM account. If you lose this secret key, you will need to generate a new one."]})}),(0,l.jsx)(E.Z,{numColSpan:1,children:null!=j?(0,l.jsxs)("div",{children:[(0,l.jsxs)(R.Z,{children:["API Key: ",j]}),(0,l.jsx)(O.Z,{className:"mt-6",children:"Budgets"}),(0,l.jsxs)(R.Z,{children:["Soft Limit Budget: $",y]}),(0,l.jsx)(o.Z,{className:"mt-3",onClick:_,children:"Test Slack Alert"}),(0,l.jsxs)(R.Z,{className:"mt-2",children:["(LiteLLM Docs -",(0,l.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/alerting",target:"_blank",className:"text-blue-500",children:"Set Up Slack Alerting)"})]})]}):(0,l.jsx)(R.Z,{children:"Key being created, this might take 30s"})})]})})})]})},J=s(33393),G=s(61244),W=s(10827),$=s(3851),H=s(2044),Y=s(64167),X=s(74480),Q=s(7178),ee=s(9853),et=s(56863),es=e=>{let{token:t,accessToken:s,keySpend:r,keyBudget:a,keyName:i}=e,[c,d]=(0,n.useState)(!1),[h,m]=(0,n.useState)(null),[u,x]=(0,n.useState)(""),[p,j]=(0,n.useState)(null),y=async()=>{try{if(null==s||null==t)return;console.log("accessToken: ".concat(s,"; token: ").concat(t));let e=await g(s,t);console.log("Response:",e),m(e);let l=await P(s,e);console.log("Response2:",l);let n=[...e,...l.response];m(n),x(l.predicted_spend),console.log("Combined Data:",n)}catch(e){console.error("There was an error fetching the data",e)}};return t?(0,l.jsxs)("div",{children:[(0,l.jsx)(o.Z,{size:"xs",onClick:()=>{console.log("Show Modal triggered"),d(!0),y()},variant:"secondary",children:"View Spend Report"}),(0,l.jsxs)(L.Z,{visible:c,width:1400,onOk:()=>{d(!1)},onCancel:()=>{d(!1)},footer:null,children:[(0,l.jsxs)(O.Z,{style:{textAlign:"left"},children:["Key Name: ",i]}),(0,l.jsxs)(et.Z,{children:["Monthly Spend $",r]}),(0,l.jsx)(O.Z,{children:u}),(0,l.jsx)(M.Z,{className:"mt-6 mb-6",children:h&&(0,l.jsx)(ee.Z,{className:"mt-6",data:h,colors:["blue","amber"],index:"date",categories:["spend","predicted_spend"],yAxisWidth:80})})]})]}):null},el=e=>{let{userID:t,accessToken:s,data:r,setData:a}=e,[i,c]=(0,n.useState)(!1),[d,h]=(0,n.useState)(!1),[u,x]=(0,n.useState)(null),p=async e=>{null!=r&&(x(e),localStorage.removeItem("userData"+t),h(!0))},j=async()=>{if(null!=u&&null!=r){try{await m(s,u);let e=r.filter(e=>e.token!==u);a(e)}catch(e){console.error("Error deleting the key:",e)}h(!1),x(null)}};if(null!=r)return console.log("RERENDER TRIGGERED"),(0,l.jsxs)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh] mb-4",children:[(0,l.jsxs)(W.Z,{className:"mt-5",children:[(0,l.jsx)(Y.Z,{children:(0,l.jsxs)(Q.Z,{children:[(0,l.jsx)(X.Z,{children:"Key Alias"}),(0,l.jsx)(X.Z,{children:"Secret Key"}),(0,l.jsx)(X.Z,{children:"Spend (USD)"}),(0,l.jsx)(X.Z,{children:"Key Budget (USD)"}),(0,l.jsx)(X.Z,{children:"Spend Report"}),(0,l.jsx)(X.Z,{children:"Team ID"}),(0,l.jsx)(X.Z,{children:"Metadata"}),(0,l.jsx)(X.Z,{children:"Models"}),(0,l.jsx)(X.Z,{children:"TPM / RPM Limits"}),(0,l.jsx)(X.Z,{children:"Expires"})]})}),(0,l.jsx)($.Z,{children:r.map(e=>(console.log(e),"litellm-dashboard"===e.team_id)?null:(0,l.jsxs)(Q.Z,{children:[(0,l.jsx)(H.Z,{children:null!=e.key_alias?(0,l.jsx)(R.Z,{children:e.key_alias}):(0,l.jsx)(R.Z,{children:"Not Set"})}),(0,l.jsx)(H.Z,{children:(0,l.jsx)(R.Z,{children:e.key_name})}),(0,l.jsx)(H.Z,{children:(0,l.jsx)(R.Z,{children:e.spend})}),(0,l.jsx)(H.Z,{children:null!=e.max_budget?(0,l.jsx)(R.Z,{children:e.max_budget}):(0,l.jsx)(R.Z,{children:"Unlimited Budget"})}),(0,l.jsx)(H.Z,{children:(0,l.jsx)(es,{token:e.token,accessToken:s,keySpend:e.spend,keyBudget:e.max_budget,keyName:e.key_name})}),(0,l.jsx)(H.Z,{children:(0,l.jsx)(R.Z,{children:e.team_id})}),(0,l.jsx)(H.Z,{children:(0,l.jsx)(R.Z,{children:JSON.stringify(e.metadata)})}),(0,l.jsx)(H.Z,{children:(0,l.jsx)(R.Z,{children:JSON.stringify(e.models)})}),(0,l.jsx)(H.Z,{children:(0,l.jsxs)(R.Z,{children:["TPM Limit: ",e.tpm_limit?e.tpm_limit:"Unlimited"," ",(0,l.jsx)("br",{})," RPM Limit:"," ",e.rpm_limit?e.rpm_limit:"Unlimited"]})}),(0,l.jsx)(H.Z,{children:null!=e.expires?(0,l.jsx)(R.Z,{children:e.expires}):(0,l.jsx)(R.Z,{children:"Never expires"})}),(0,l.jsx)(H.Z,{children:(0,l.jsx)(G.Z,{onClick:()=>p(e.token),icon:J.Z,size:"sm"})})]},e.token))})]}),d&&(0,l.jsx)("div",{className:"fixed z-10 inset-0 overflow-y-auto",children:(0,l.jsxs)("div",{className:"flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0",children:[(0,l.jsx)("div",{className:"fixed inset-0 transition-opacity","aria-hidden":"true",children:(0,l.jsx)("div",{className:"absolute inset-0 bg-gray-500 opacity-75"})}),(0,l.jsx)("span",{className:"hidden sm:inline-block sm:align-middle sm:h-screen","aria-hidden":"true",children:""}),(0,l.jsxs)("div",{className:"inline-block align-bottom bg-white rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full",children:[(0,l.jsx)("div",{className:"bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4",children:(0,l.jsx)("div",{className:"sm:flex sm:items-start",children:(0,l.jsxs)("div",{className:"mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left",children:[(0,l.jsx)("h3",{className:"text-lg leading-6 font-medium text-gray-900",children:"Delete Key"}),(0,l.jsx)("div",{className:"mt-2",children:(0,l.jsx)("p",{className:"text-sm text-gray-500",children:"Are you sure you want to delete this key ?"})})]})})}),(0,l.jsxs)("div",{className:"bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse",children:[(0,l.jsx)(o.Z,{onClick:j,color:"red",className:"ml-2",children:"Delete"}),(0,l.jsx)(o.Z,{onClick:()=>{h(!1),x(null)},children:"Cancel"})]})]})]})})]})},en=e=>{let{userID:t,userSpendData:s,userRole:r,accessToken:a}=e;console.log("User SpendData:",s);let[o,i]=(0,n.useState)(null==s?void 0:s.spend),[c,d]=(0,n.useState)((null==s?void 0:s.max_budget)||null);return(0,n.useEffect)(()=>{(async()=>{if("Admin"===r)try{let e=await b(a,"litellm-proxy-budget");console.log("Result from callSpendUsers:",e);let t=e[0];i(null==t?void 0:t.spend),d((null==t?void 0:t.max_budget)||null)}catch(e){console.error("Failed to get spend for user",e)}})()},[r,a,t]),(0,l.jsx)(l.Fragment,{children:(0,l.jsxs)(M.Z,{className:"mx-auto mb-4",children:[(0,l.jsxs)(et.Z,{children:["$",o]}),(0,l.jsxs)(O.Z,{children:["/ ",null!==c?"$".concat(c," limit"):"No limit"]})]})})},er=s(36083),ea=s(68967),eo=s(27166),ei=e=>{let{teams:t,setSelectedTeam:s}=e,{Title:r,Paragraph:a}=er.default,[o,i]=(0,n.useState)("");return(0,l.jsxs)("div",{className:"mt-10",children:[(0,l.jsx)(r,{level:4,children:"Default Team"}),(0,l.jsx)(a,{children:"If you belong to multiple teams, this setting controls which team is used by default when creating new API Keys."}),t&&t.length>0?(0,l.jsx)(ea.Z,{defaultValue:"0",children:t.map((e,t)=>(0,l.jsx)(eo.Z,{value:String(t),onClick:()=>s(e),children:e.team_alias},t))}):(0,l.jsxs)(a,{children:["No team created. ",(0,l.jsx)("b",{children:"Defaulting to personal account."})]})]})},ec=s(37963);console.log("isLocal:",!1);var ed=e=>{let{userID:t,userRole:s,teams:a,keys:o,setUserRole:i,userEmail:c,setUserEmail:d,setTeams:h,setKeys:m}=e,[x,p]=(0,n.useState)(null),g=(0,r.useSearchParams)();g.get("viewSpend"),(0,r.useRouter)();let y=g.get("token"),[Z,f]=(0,n.useState)(null),[w,k]=(0,n.useState)([]),[_,b]=(0,n.useState)(a?a[0]:null);if(window.addEventListener("beforeunload",function(){sessionStorage.clear()}),(0,n.useEffect)(()=>{if(y){let e=(0,ec.o)(y);if(e){if(console.log("Decoded token:",e),console.log("Decoded key:",e.key),f(e.key),e.user_role){let t=function(e){if(!e)return"Undefined Role";switch(console.log("Received user role: ".concat(e)),e.toLowerCase()){case"app_owner":case"demo_app_owner":return"App Owner";case"app_admin":case"proxy_admin":return"Admin";case"proxy_admin_viewer":return"Admin Viewer";case"app_user":return"App User";default:return"Unknown Role"}}(e.user_role);console.log("Decoded user_role:",t),i(t)}else console.log("User role not defined");e.user_email?d(e.user_email):console.log("User Email is not set ".concat(e))}}if(t&&Z&&s&&!o&&!x){let e=sessionStorage.getItem("userModels"+t);e?k(JSON.parse(e)):(async()=>{try{let e=await u(Z,t,s);console.log("received teams in user dashboard: ".concat(Object.keys(e),"; team values: ").concat(Object.entries(e.teams))),p(e.user_info),m(e.keys),h(e.teams),b(e.teams?e.teams[0]:null),sessionStorage.setItem("userData"+t,JSON.stringify(e.keys)),sessionStorage.setItem("userSpendData"+t,JSON.stringify(e.user_info));let l=(await j(Z,t,s)).data.map(e=>e.id);console.log("available_model_names:",l),k(l),console.log("userModels:",w),sessionStorage.setItem("userModels"+t,JSON.stringify(l))}catch(e){console.error("There was an error fetching the data",e)}})()}},[t,y,Z,o,s]),null==t||null==y){let e="/sso/key/generate";return console.log("Full URL:",e),window.location.href=e,null}if(null==Z)return null;if(null==s&&i("App Owner"),s&&"Admin Viewer"==s){let{Title:e,Paragraph:t}=er.default;return(0,l.jsxs)("div",{children:[(0,l.jsx)(e,{level:1,children:"Access Denied"}),(0,l.jsx)(t,{children:"Ask your proxy admin for access to create keys"})]})}return(0,l.jsx)("div",{children:(0,l.jsx)(F.Z,{numItems:1,className:"gap-0 p-10 h-[75vh] w-full",children:(0,l.jsxs)(E.Z,{numColSpan:1,children:[(0,l.jsx)(en,{userID:t,userSpendData:x,userRole:s,accessToken:Z}),(0,l.jsx)(el,{userID:t,accessToken:Z,data:o,setData:m}),(0,l.jsx)(V,{userID:t,teamID:_?_.team_id:null,userRole:s,userModels:w,accessToken:Z,data:o,setData:m}),(0,l.jsx)(ei,{teams:a,setSelectedTeam:b})]})})})},eh=s(5);let{Option:em}=D.default;var eu=e=>{let{userModels:t,accessToken:s,userID:r}=e,[a]=U.Z.useForm(),[i,d]=(0,n.useState)(!1),h=async e=>{try{c.ZP.info("Requesting access");let{selectedModel:t,accessReason:l}=e;await v(s,t,r,l),d(!0)}catch(e){console.error("Error requesting access:",e)}};return(0,l.jsxs)("div",{children:[(0,l.jsx)(o.Z,{size:"xs",onClick:()=>d(!0),children:"Request Access"}),(0,l.jsx)(L.Z,{title:"Request Access",visible:i,width:800,footer:null,onOk:()=>{d(!1),a.resetFields()},onCancel:()=>{d(!1),a.resetFields()},children:(0,l.jsxs)(U.Z,{form:a,onFinish:h,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsx)(U.Z.Item,{label:"Select Model",name:"selectedModel",children:(0,l.jsx)(D.default,{placeholder:"Select model",style:{width:"100%"},children:t.map(e=>(0,l.jsx)(em,{value:e,children:e},e))})}),(0,l.jsx)(U.Z.Item,{label:"Reason for Access",name:"accessReason",children:(0,l.jsx)(z.Z.TextArea,{rows:4,placeholder:"Enter reason for access"})}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(o.Z,{children:"Request Access"})})]})})]})},ex=e=>{let{accessToken:t,token:s,userRole:r,userID:a}=e,[o,i]=(0,n.useState)({data:[]}),[c,d]=(0,n.useState)([]),[h,m]=(0,n.useState)([]);if((0,n.useEffect)(()=>{if(!t||!s||!r||!a)return;let e=async()=>{try{let e=await x(t,a,r);console.log("Model data response:",e.data),i(e);let s=await p(t,a,r);if(console.log("Model metrics response:",s),d(s),"Admin"===r&&t){let e=await S(t);console.log("Pending Requests:",h),m(e.requests||[])}}catch(e){console.error("There was an error fetching the model data",e)}};t&&s&&r&&a&&e()},[t,s,r,a]),!o||!t||!s||!r||!a)return(0,l.jsx)("div",{children:"Loading..."});let u=[];for(let e=0;e(0,l.jsxs)(Q.Z,{children:[(0,l.jsx)(H.Z,{children:(0,l.jsx)(O.Z,{children:e.model_name})}),(0,l.jsx)(H.Z,{children:e.provider}),"Admin"===r&&(0,l.jsx)(H.Z,{children:e.api_base}),(0,l.jsx)(H.Z,{children:e.user_access?(0,l.jsx)(eh.Z,{color:"green",children:"Yes"}):(0,l.jsx)(eu,{userModels:u,accessToken:t,userID:a})}),(0,l.jsx)(H.Z,{children:e.input_cost}),(0,l.jsx)(H.Z,{children:e.output_cost}),(0,l.jsx)(H.Z,{children:e.max_tokens})]},e.model_name))})]})}),(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(O.Z,{children:"Model Statistics (Number Requests, Latency)"}),(0,l.jsx)(ee.Z,{data:c,index:"model",categories:["num_requests","avg_latency_seconds"],colors:["blue","red"],yAxisWidth:100,tickGap:5})]})]})})},ep=s(92836),ej=s(26734),eg=s(41608),ey=s(32126),eZ=s(23682);let{Option:ef}=D.default;var ew=e=>{let{userID:t,accessToken:s}=e,[r]=U.Z.useForm(),[a,i]=(0,n.useState)(!1),[d,m]=(0,n.useState)(null),[u,x]=(0,n.useState)([]);(0,n.useEffect)(()=>{(async()=>{try{let e=await j(s,t,"any"),l=[];for(let t=0;t{i(!1),r.resetFields()},g=()=>{i(!1),m(null),r.resetFields()},y=async e=>{try{c.ZP.info("Making API Call"),i(!0),console.log("formValues in create user:",e);let l=await h(s,t,e);console.log("user create Response:",l),m(l.key),c.ZP.success("API user Created"),r.resetFields(),localStorage.removeItem("userData"+t)}catch(e){console.error("Error creating the user:",e)}};return(0,l.jsxs)("div",{children:[(0,l.jsx)(o.Z,{className:"mx-auto",onClick:()=>i(!0),children:"+ Create New User"}),(0,l.jsx)(L.Z,{title:"Create User",visible:a,width:800,footer:null,onOk:p,onCancel:g,children:(0,l.jsxs)(U.Z,{form:r,onFinish:y,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsx)(U.Z.Item,{label:"User ID",name:"user_id",children:(0,l.jsx)(z.Z,{placeholder:"Enter User ID"})}),(0,l.jsx)(U.Z.Item,{label:"Team ID",name:"team_id",children:(0,l.jsx)(z.Z,{placeholder:"ai_team"})}),(0,l.jsx)(U.Z.Item,{label:"Models",name:"models",children:(0,l.jsx)(D.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:u.map(e=>(0,l.jsx)(ef,{value:e,children:e},e))})}),(0,l.jsx)(U.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,l.jsx)(B.Z,{step:.01,precision:2,width:200})}),(0,l.jsx)(U.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,l.jsx)(B.Z,{step:1,width:400})}),(0,l.jsx)(U.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,l.jsx)(B.Z,{step:1,width:400})}),(0,l.jsx)(U.Z.Item,{label:"Duration (eg: 30s, 30h, 30d)",name:"duration",children:(0,l.jsx)(z.Z,{})}),(0,l.jsx)(U.Z.Item,{label:"Metadata",name:"metadata",children:(0,l.jsx)(z.Z.TextArea,{rows:4,placeholder:"Enter metadata as JSON"})}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(q.ZP,{htmlType:"submit",children:"Create User"})})]})}),d&&(0,l.jsxs)(L.Z,{title:"Save Your User",visible:a,onOk:p,onCancel:g,footer:null,children:[(0,l.jsxs)("p",{children:["Please save this secret user somewhere safe and accessible. For security reasons, ",(0,l.jsx)("b",{children:"you will not be able to view it again"})," ","through your LiteLLM account. If you lose this secret user, you will need to generate a new one."]}),(0,l.jsx)("p",{children:null!=d?"API user: ".concat(d):"User being created, this might take 30s"})]})]})},ek=e=>{let{accessToken:t,token:s,keys:r,userRole:a,userID:o,setKeys:i}=e,[c,d]=(0,n.useState)(null),[h,m]=(0,n.useState)(null),[x,p]=(0,n.useState)(1);if((0,n.useEffect)(()=>{if(!t||!s||!a||!o)return;let e=async()=>{try{let e=await u(t,null,a,!0);console.log("user data response:",e),d(e)}catch(e){console.error("There was an error fetching the model data",e)}};t&&s&&a&&o&&!c&&e();let l=async()=>{try{let e=await w(t,null);console.log("user data response:",e),m(e)}catch(e){console.error("There was an error fetching the model data",e)}};a&&("Admin"==a||"Admin Viewer"==a)&&!h&&l()},[t,s,a,o]),!c||!t||!s||!a||!o)return(0,l.jsx)("div",{children:"Loading..."});let j=async e=>{try{let s=await w(t,e);console.log("user data response:",s),m(s)}catch(e){console.error("There was an error fetching the model data",e)}};return(0,l.jsx)("div",{style:{width:"100%"},children:(0,l.jsxs)(F.Z,{className:"gap-2 p-10 h-[75vh] w-full",children:[(0,l.jsx)(ew,{userID:o,accessToken:t}),(0,l.jsx)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh] mb-4",children:(0,l.jsxs)(ej.Z,{children:[(0,l.jsxs)(eg.Z,{variant:"line",defaultValue:"1",children:[(0,l.jsx)(ep.Z,{value:"1",children:"Key Owners"}),(0,l.jsx)(ep.Z,{value:"2",children:"End-Users"})]}),(0,l.jsxs)(eZ.Z,{children:[(0,l.jsx)(ey.Z,{children:(0,l.jsxs)(W.Z,{className:"mt-5",children:[(0,l.jsx)(Y.Z,{children:(0,l.jsxs)(Q.Z,{children:[(0,l.jsx)(X.Z,{children:"User ID"}),(0,l.jsx)(X.Z,{children:"User Role"}),(0,l.jsx)(X.Z,{children:"User Models"}),(0,l.jsx)(X.Z,{children:"User Spend ($ USD)"}),(0,l.jsx)(X.Z,{children:"User Max Budget ($ USD)"})]})}),(0,l.jsx)($.Z,{children:c.map(e=>(0,l.jsxs)(Q.Z,{children:[(0,l.jsx)(H.Z,{children:e.user_id}),(0,l.jsx)(H.Z,{children:e.user_role?e.user_role:"app_owner"}),(0,l.jsx)(H.Z,{children:e.models&&e.models.length>0?e.models:"All Models"}),(0,l.jsx)(H.Z,{children:e.spend?e.spend:0}),(0,l.jsx)(H.Z,{children:e.max_budget?e.max_budget:"Unlimited"})]},e.user_id))})]})}),(0,l.jsxs)(ey.Z,{children:[(0,l.jsxs)("div",{className:"flex items-center",children:[(0,l.jsx)("div",{className:"flex-1"}),(0,l.jsxs)("div",{className:"flex-1 flex justify-between items-center",children:[(0,l.jsx)(R.Z,{className:"w-1/4 mr-2 text-right",children:"Key"}),(0,l.jsx)(ea.Z,{defaultValue:"1",className:"w-3/4",children:null==r?void 0:r.map((e,t)=>{if(e&&null!==e.key_name&&e.key_name.length>0)return(0,l.jsx)(eo.Z,{value:String(t),onClick:()=>j(e.token),children:e.key_name},t)})})]})]}),(0,l.jsxs)(W.Z,{children:[(0,l.jsx)(Y.Z,{children:(0,l.jsxs)(Q.Z,{children:[(0,l.jsx)(X.Z,{children:"End User"}),(0,l.jsx)(X.Z,{children:"Spend"}),(0,l.jsx)(X.Z,{children:"Total Events"})]})}),(0,l.jsx)($.Z,{children:null==h?void 0:h.map((e,t)=>(0,l.jsxs)(Q.Z,{children:[(0,l.jsx)(H.Z,{children:e.end_user}),(0,l.jsx)(H.Z,{children:e.total_spend}),(0,l.jsx)(H.Z,{children:e.total_events})]},t))})]})]})]})]})}),function(){if(!c)return null;let e=Math.ceil(c.length/25),t=Math.min(25*x,c.length);return(0,l.jsxs)("div",{className:"flex justify-between items-center",children:[(0,l.jsxs)("div",{children:["Showing ",(x-1)*25+1," – ",t," of ",c.length]}),(0,l.jsxs)("div",{className:"flex",children:[(0,l.jsx)("button",{className:"bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-l focus:outline-none",disabled:1===x,onClick:()=>p(x-1),children:"← Prev"}),(0,l.jsx)("button",{className:"bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-r focus:outline-none",disabled:x===e,onClick:()=>p(x+1),children:"Next →"})]})]})}()]})})},e_=s(8510),eb=e=>{let{teams:t,searchParams:s,accessToken:r,setTeams:a}=e,[i]=U.Z.useForm(),[d]=U.Z.useForm(),{Title:h,Paragraph:m}=er.default,[u,x]=(0,n.useState)(""),[p,j]=(0,n.useState)(t?t[0]:null),[g,y]=(0,n.useState)(!1),[Z,f]=(0,n.useState)(!1),w=async e=>{try{if(null!=r){c.ZP.info("Making API Call");let s=await A(r,e);null!==t?a([...t,s]):a([s]),console.log("response for team create call: ".concat(s)),y(!1)}}catch(e){console.error("Error creating the key:",e)}},k=async e=>{try{if(null!=r&&null!=t){c.ZP.info("Making API Call");let s={role:"user",user_email:e.user_email,user_id:e.user_id},l=await C(r,p.team_id,s);console.log("response for team create call: ".concat(l.data));let n=t.findIndex(e=>(console.log("team.team_id=".concat(e.team_id,"; response.data.team_id=").concat(l.data.team_id)),e.team_id===l.data.team_id));if(console.log("foundIndex: ".concat(n)),-1!==n){let e=[...t];e[n]=l.data,a(e),j(l.data)}f(!1)}}catch(e){console.error("Error creating the key:",e)}};return console.log("received teams ".concat(t)),(0,l.jsx)("div",{className:"w-full",children:(0,l.jsxs)(F.Z,{numItems:1,className:"gap-2 p-2 h-[75vh] w-full",children:[(0,l.jsxs)(E.Z,{numColSpan:1,children:[(0,l.jsx)(h,{level:4,children:"All Teams"}),(0,l.jsx)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,l.jsxs)(W.Z,{children:[(0,l.jsx)(Y.Z,{children:(0,l.jsxs)(Q.Z,{children:[(0,l.jsx)(X.Z,{children:"Team Name"}),(0,l.jsx)(X.Z,{children:"Spend (USD)"}),(0,l.jsx)(X.Z,{children:"Budget (USD)"}),(0,l.jsx)(X.Z,{children:"TPM / RPM Limits"})]})}),(0,l.jsx)($.Z,{children:t&&t.length>0?t.map(e=>(0,l.jsxs)(Q.Z,{children:[(0,l.jsx)(H.Z,{children:e.team_alias}),(0,l.jsx)(H.Z,{children:e.spend}),(0,l.jsx)(H.Z,{children:e.max_budget?e.max_budget:"No limit"}),(0,l.jsx)(H.Z,{children:(0,l.jsxs)(R.Z,{children:["TPM Limit:"," ",e.tpm_limit?e.tpm_limit:"Unlimited"," ",(0,l.jsx)("br",{})," RPM Limit:"," ",e.rpm_limit?e.rpm_limit:"Unlimited"]})}),(0,l.jsx)(H.Z,{children:(0,l.jsx)(G.Z,{icon:e_.Z,size:"sm"})})]},e.team_id)):null})]})})]}),(0,l.jsxs)(E.Z,{numColSpan:1,children:[(0,l.jsx)(o.Z,{className:"mx-auto",onClick:()=>y(!0),children:"+ Create New Team"}),(0,l.jsx)(L.Z,{title:"Create Team",visible:g,width:800,footer:null,onOk:()=>{y(!1),i.resetFields()},onCancel:()=>{y(!1),i.resetFields()},children:(0,l.jsxs)(U.Z,{form:i,onFinish:w,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(U.Z.Item,{label:"Team Name",name:"team_alias",children:(0,l.jsx)(z.Z,{})}),(0,l.jsx)(U.Z.Item,{label:"Models",name:"models",children:(0,l.jsx)(D.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"}})}),(0,l.jsx)(U.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,l.jsx)(B.Z,{step:.01,precision:2,width:200})}),(0,l.jsx)(U.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,l.jsx)(B.Z,{step:1,width:400})}),(0,l.jsx)(U.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,l.jsx)(B.Z,{step:1,width:400})})]}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(q.ZP,{htmlType:"submit",children:"Create Team"})})]})})]}),(0,l.jsxs)(E.Z,{numColSpan:1,children:[(0,l.jsx)(h,{level:4,children:"Team Members"}),(0,l.jsx)(m,{children:"If you belong to multiple teams, this setting controls which teams members you see."}),t&&t.length>0?(0,l.jsx)(ea.Z,{defaultValue:"0",children:t.map((e,t)=>(0,l.jsx)(eo.Z,{value:String(t),onClick:()=>{j(e)},children:e.team_alias},t))}):(0,l.jsxs)(m,{children:["No team created. ",(0,l.jsx)("b",{children:"Defaulting to personal account."})]})]}),(0,l.jsx)(E.Z,{numColSpan:1,children:(0,l.jsx)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,l.jsxs)(W.Z,{children:[(0,l.jsx)(Y.Z,{children:(0,l.jsxs)(Q.Z,{children:[(0,l.jsx)(X.Z,{children:"Member Name"}),(0,l.jsx)(X.Z,{children:"Role"}),(0,l.jsx)(X.Z,{children:"Action"})]})}),(0,l.jsx)($.Z,{children:p?p.members_with_roles.map((e,t)=>(0,l.jsxs)(Q.Z,{children:[(0,l.jsx)(H.Z,{children:e.user_email?e.user_email:e.user_id?e.user_id:null}),(0,l.jsx)(H.Z,{children:e.role}),(0,l.jsx)(H.Z,{children:(0,l.jsx)(G.Z,{icon:e_.Z,size:"sm"})})]},t)):null})]})})}),(0,l.jsxs)(E.Z,{numColSpan:1,children:[(0,l.jsx)(o.Z,{className:"mx-auto mb-5",onClick:()=>f(!0),children:"+ Add member"}),(0,l.jsx)(L.Z,{title:"Add member",visible:Z,width:800,footer:null,onOk:()=>{f(!1),d.resetFields()},onCancel:()=>{f(!1),d.resetFields()},children:(0,l.jsxs)(U.Z,{form:i,onFinish:k,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(U.Z.Item,{label:"Email",name:"user_email",className:"mb-4",children:(0,l.jsx)(z.Z,{name:"user_email",className:"px-3 py-2 border rounded-md w-full"})}),(0,l.jsx)("div",{className:"text-center mb-4",children:"OR"}),(0,l.jsx)(U.Z.Item,{label:"User ID",name:"user_id",className:"mb-4",children:(0,l.jsx)(z.Z,{name:"user_id",className:"px-3 py-2 border rounded-md w-full"})})]}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(q.ZP,{htmlType:"submit",children:"Add member"})})]})})]})]})})},ev=e=>{let{searchParams:t,accessToken:s}=e,[r]=U.Z.useForm(),[a]=U.Z.useForm(),{Title:i,Paragraph:d}=er.default,[h,m]=(0,n.useState)(""),[u,x]=(0,n.useState)(null),[p,j]=(0,n.useState)(!1);(0,n.useEffect)(()=>{(async()=>{if(null!=s){let e=[],t=await N(s,"proxy_admin_viewer");t.forEach(t=>{e.push({user_role:t.user_role,user_id:t.user_id,user_email:t.user_email})}),console.log("proxy viewers: ".concat(t));let l=await N(s,"proxy_admin");l.forEach(t=>{e.push({user_role:t.user_role,user_id:t.user_id,user_email:t.user_email})}),console.log("proxy admins: ".concat(l)),console.log("combinedList: ".concat(e)),x(e)}})()},[s]);let g=async e=>{try{if(null!=s&&null!=u){c.ZP.info("Making API Call"),e.user_email,e.user_id;let t=await I(s,e);console.log("response for team create call: ".concat(t));let l=u.findIndex(e=>(console.log("user.user_id=".concat(e.user_id,"; response.user_id=").concat(t.user_id)),e.user_id===t.user_id));console.log("foundIndex: ".concat(l)),-1==l&&(console.log("updates admin with new user"),u.push(t),x(u)),j(!1)}}catch(e){console.error("Error creating the key:",e)}};return console.log("admins: ".concat(null==u?void 0:u.length)),(0,l.jsxs)("div",{className:"w-full m-2",children:[(0,l.jsx)(i,{level:4,children:"Restricted Access"}),(0,l.jsxs)(d,{children:["Add other people to just view spend. They cannot create keys, teams or grant users access to new models."," ",(0,l.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/ui#restrict-ui-access",children:"Requires SSO Setup"})]}),(0,l.jsxs)(F.Z,{numItems:1,className:"gap-2 p-0 w-full",children:[(0,l.jsx)(E.Z,{numColSpan:1,children:(0,l.jsx)(M.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,l.jsxs)(W.Z,{children:[(0,l.jsx)(Y.Z,{children:(0,l.jsxs)(Q.Z,{children:[(0,l.jsx)(X.Z,{children:"Member Name"}),(0,l.jsx)(X.Z,{children:"Role"}),(0,l.jsx)(X.Z,{children:"Action"})]})}),(0,l.jsx)($.Z,{children:u?u.map((e,t)=>(0,l.jsxs)(Q.Z,{children:[(0,l.jsx)(H.Z,{children:e.user_email?e.user_email:e.user_id?e.user_id:null}),(0,l.jsx)(H.Z,{children:e.user_role}),(0,l.jsx)(H.Z,{children:(0,l.jsx)(G.Z,{icon:e_.Z,size:"sm"})})]},t)):null})]})})}),(0,l.jsxs)(E.Z,{numColSpan:1,children:[(0,l.jsx)(o.Z,{className:"mx-auto mb-5",onClick:()=>j(!0),children:"+ Add viewer"}),(0,l.jsx)(L.Z,{title:"Add viewer",visible:p,width:800,footer:null,onOk:()=>{j(!1),a.resetFields()},onCancel:()=>{j(!1),a.resetFields()},children:(0,l.jsxs)(U.Z,{form:r,onFinish:g,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(U.Z.Item,{label:"Email",name:"user_email",className:"mb-4",children:(0,l.jsx)(z.Z,{name:"user_email",className:"px-3 py-2 border rounded-md w-full"})}),(0,l.jsx)("div",{className:"text-center mb-4",children:"OR"}),(0,l.jsx)(U.Z.Item,{label:"User ID",name:"user_id",className:"mb-4",children:(0,l.jsx)(z.Z,{name:"user_id",className:"px-3 py-2 border rounded-md w-full"})})]}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(q.ZP,{htmlType:"submit",children:"Add member"})})]})})]})]})]})},eS=s(12968),eN=s(67951);async function eA(e,t,s,l){console.log("isLocal:",!1);let n=window.location.origin,r=new eS.ZP.OpenAI({apiKey:l,baseURL:n,dangerouslyAllowBrowser:!0});for await(let l of(await r.chat.completions.create({model:s,stream:!0,messages:[{role:"user",content:e}]})))console.log(l),l.choices[0].delta.content&&t(l.choices[0].delta.content)}var eC=e=>{let{accessToken:t,token:s,userRole:r,userID:a}=e,[o,i]=(0,n.useState)(""),[c,d]=(0,n.useState)([]),[h,m]=(0,n.useState)(void 0),[u,x]=(0,n.useState)(null);(0,n.useEffect)(()=>{t&&s&&r&&a&&(async()=>{let e=await j(t,a,r);console.log("model_info:",e),(null==e?void 0:e.data.length)>0&&(x(e.data),m(e.data[0].id))})()},[t,a,r]);let p=(e,t)=>{d(s=>{let l=s[s.length-1];return l&&l.role===e?[...s.slice(0,s.length-1),{role:e,content:l.content+t}]:[...s,{role:e,content:t}]})},g=async()=>{if(""!==o.trim()&&t&&s&&r&&a){d(e=>[...e,{role:"user",content:o}]);try{h&&await eA(o,e=>p("assistant",e),h,t)}catch(e){console.error("Error fetching model response",e),p("assistant","Error fetching model response")}i("")}};if(r&&"Admin Viewer"==r){let{Title:e,Paragraph:t}=er.default;return(0,l.jsxs)("div",{children:[(0,l.jsx)(e,{level:1,children:"Access Denied"}),(0,l.jsx)(t,{children:"Ask your proxy admin for access to test models"})]})}return(0,l.jsx)("div",{style:{width:"100%",position:"relative"},children:(0,l.jsx)(F.Z,{className:"gap-2 p-10 h-[75vh] w-full",children:(0,l.jsx)(M.Z,{children:(0,l.jsxs)(ej.Z,{children:[(0,l.jsxs)(eg.Z,{className:"mt-4",children:[(0,l.jsx)(ep.Z,{children:"Chat"}),(0,l.jsx)(ep.Z,{children:"API Reference"})]}),(0,l.jsxs)(eZ.Z,{children:[(0,l.jsxs)(ey.Z,{children:[(0,l.jsxs)("div",{children:[(0,l.jsx)("label",{children:"Select Model:"}),(0,l.jsx)("select",{value:h||"",onChange:e=>m(e.target.value),children:null==u?void 0:u.map(e=>(0,l.jsx)("option",{value:e.id,children:e.id},e.id))})]}),(0,l.jsxs)(W.Z,{className:"mt-5",style:{display:"block",maxHeight:"60vh",overflowY:"auto"},children:[(0,l.jsx)(Y.Z,{children:(0,l.jsx)(Q.Z,{children:(0,l.jsx)(H.Z,{children:(0,l.jsx)(O.Z,{children:"Chat"})})})}),(0,l.jsx)($.Z,{children:c.map((e,t)=>(0,l.jsx)(Q.Z,{children:(0,l.jsx)(H.Z,{children:"".concat(e.role,": ").concat(e.content)})},t))})]}),(0,l.jsx)("div",{className:"mt-3",style:{position:"absolute",bottom:5,width:"95%"},children:(0,l.jsxs)("div",{className:"flex",children:[(0,l.jsx)("input",{type:"text",value:o,onChange:e=>i(e.target.value),className:"flex-1 p-2 border rounded-md mr-2",placeholder:"Type your message..."}),(0,l.jsx)("button",{onClick:g,className:"p-2 bg-blue-500 text-white rounded-md",children:"Send"})]})})]}),(0,l.jsx)(ey.Z,{children:(0,l.jsxs)(ej.Z,{children:[(0,l.jsxs)(eg.Z,{children:[(0,l.jsx)(ep.Z,{children:"OpenAI Python SDK"}),(0,l.jsx)(ep.Z,{children:"LlamaIndex"}),(0,l.jsx)(ep.Z,{children:"Langchain Py"})]}),(0,l.jsxs)(eZ.Z,{children:[(0,l.jsx)(ey.Z,{children:(0,l.jsx)(eN.Z,{language:"python",children:'\nimport openai\nclient = openai.OpenAI(\n api_key="your_api_key",\n base_url="http://0.0.0.0:4000" # proxy base url\n)\n\nresponse = client.chat.completions.create(\n model="gpt-3.5-turbo", # model to use from Models Tab\n messages = [\n {\n "role": "user",\n "content": "this is a test request, write a short poem"\n }\n ],\n extra_body={\n "metadata": {\n "generation_name": "ishaan-generation-openai-client",\n "generation_id": "openai-client-gen-id22",\n "trace_id": "openai-client-trace-id22",\n "trace_user_id": "openai-client-user-id2"\n }\n }\n)\n\nprint(response)\n '})}),(0,l.jsx)(ey.Z,{children:(0,l.jsx)(eN.Z,{language:"python",children:'\nimport os, dotenv\n\nfrom llama_index.llms import AzureOpenAI\nfrom llama_index.embeddings import AzureOpenAIEmbedding\nfrom llama_index import VectorStoreIndex, SimpleDirectoryReader, ServiceContext\n\nllm = AzureOpenAI(\n engine="azure-gpt-3.5", # model_name on litellm proxy\n temperature=0.0,\n azure_endpoint="http://0.0.0.0:4000", # litellm proxy endpoint\n api_key="sk-1234", # litellm proxy API Key\n api_version="2023-07-01-preview",\n)\n\nembed_model = AzureOpenAIEmbedding(\n deployment_name="azure-embedding-model",\n azure_endpoint="http://0.0.0.0:4000",\n api_key="sk-1234",\n api_version="2023-07-01-preview",\n)\n\n\ndocuments = SimpleDirectoryReader("llama_index_data").load_data()\nservice_context = ServiceContext.from_defaults(llm=llm, embed_model=embed_model)\nindex = VectorStoreIndex.from_documents(documents, service_context=service_context)\n\nquery_engine = index.as_query_engine()\nresponse = query_engine.query("What did the author do growing up?")\nprint(response)\n\n '})}),(0,l.jsx)(ey.Z,{children:(0,l.jsx)(eN.Z,{language:"python",children:'\nfrom langchain.chat_models import ChatOpenAI\nfrom langchain.prompts.chat import (\n ChatPromptTemplate,\n HumanMessagePromptTemplate,\n SystemMessagePromptTemplate,\n)\nfrom langchain.schema import HumanMessage, SystemMessage\n\nchat = ChatOpenAI(\n openai_api_base="http://0.0.0.0:8000",\n model = "gpt-3.5-turbo",\n temperature=0.1,\n extra_body={\n "metadata": {\n "generation_name": "ishaan-generation-langchain-client",\n "generation_id": "langchain-client-gen-id22",\n "trace_id": "langchain-client-trace-id22",\n "trace_user_id": "langchain-client-user-id2"\n }\n }\n)\n\nmessages = [\n SystemMessage(\n content="You are a helpful assistant that im using to make a test request to."\n ),\n HumanMessage(\n content="test from litellm. tell me why it\'s amazing in 1 sentence"\n ),\n]\nresponse = chat(messages)\n\nprint(response)\n\n '})})]})]})})]})]})})})})},eI=s(33509),eP=s(30569);let{Sider:eT}=eI.default;var eE=e=>{let{setPage:t,userRole:s,defaultSelectedKey:n}=e;return"Admin Viewer"==s?(0,l.jsx)(eI.default,{style:{minHeight:"100vh",maxWidth:"120px"},children:(0,l.jsx)(eT,{width:120,children:(0,l.jsxs)(eP.Z,{mode:"inline",defaultSelectedKeys:n||["4"],style:{height:"100%",borderRight:0},children:[(0,l.jsx)(eP.Z.Item,{onClick:()=>t("api-keys"),children:"API Keys"},"4"),(0,l.jsx)(eP.Z.Item,{onClick:()=>t("models"),children:"Models"},"2"),(0,l.jsx)(eP.Z.Item,{onClick:()=>t("llm-playground"),children:"Chat UI"},"3"),(0,l.jsx)(eP.Z.Item,{onClick:()=>t("usage"),children:"Usage"},"1")]})})}):(0,l.jsx)(eI.default,{style:{minHeight:"100vh",maxWidth:"120px"},children:(0,l.jsx)(eT,{width:120,children:(0,l.jsxs)(eP.Z,{mode:"inline",defaultSelectedKeys:n||["1"],style:{height:"100%",borderRight:0},children:[(0,l.jsx)(eP.Z.Item,{onClick:()=>t("api-keys"),children:"API Keys"},"1"),(0,l.jsx)(eP.Z.Item,{onClick:()=>t("models"),children:"Models"},"2"),(0,l.jsx)(eP.Z.Item,{onClick:()=>t("llm-playground"),children:"Chat UI"},"3"),(0,l.jsx)(eP.Z.Item,{onClick:()=>t("usage"),children:"Usage"},"4"),"Admin"==s?(0,l.jsx)(eP.Z.Item,{onClick:()=>t("users"),children:"Users"},"5"):null,"Admin"==s?(0,l.jsx)(eP.Z.Item,{onClick:()=>t("teams"),children:"Teams"},"6"):null,"Admin"==s?(0,l.jsx)(eP.Z.Item,{onClick:()=>t("admin-panel"),children:"Admin"},"7"):null]})})})},eF=e=>{let{accessToken:t,token:s,userRole:r,userID:a}=e,o=new Date,[i,c]=(0,n.useState)([]),[d,h]=(0,n.useState)([]),[m,u]=(0,n.useState)([]),[x,p]=(0,n.useState)([]),j=new Date(o.getFullYear(),o.getMonth(),1),g=new Date(o.getFullYear(),o.getMonth()+1,0),w=v(j),b=v(g);function v(e){let t=e.getFullYear(),s=e.getMonth()+1,l=e.getDate();return"".concat(t,"-").concat(s<10?"0"+s:s,"-").concat(l<10?"0"+l:l)}return console.log("Start date is ".concat(w)),console.log("End date is ".concat(b)),(0,n.useEffect)(()=>{t&&s&&r&&a&&(async()=>{try{if(console.log("user role: ".concat(r)),"Admin"==r||"Admin Viewer"==r){let e=await Z(t);c(e);let s=(await f(t)).map(e=>({key:(e.key_name||e.key_alias||e.api_key).substring(0,7),spend:e.total_spend}));h(s);let l=(await k(t)).map(e=>({key:e.model,spend:e.total_spend}));u(l)}else"App Owner"==r&&await y(t,s,r,a,w,b).then(async e=>{if(console.log("result from spend logs call",e),"daily_spend"in e){let t=e.daily_spend;console.log("daily spend",t),c(t);let s=e.top_api_keys;h(s)}else{let s=(await _(t,function(e){let t=[];e.forEach(e=>{Object.entries(e).forEach(e=>{let[s,l]=e;"spend"!==s&&"startTime"!==s&&"models"!==s&&"users"!==s&&t.push({key:s,spend:l})})}),t.sort((e,t)=>Number(t.spend)-Number(e.spend));let s=t.slice(0,5).map(e=>e.key);return console.log("topKeys: ".concat(Object.keys(s[0]))),s}(e))).info.map(e=>({key:(e.key_name||e.key_alias||e.token).substring(0,7),spend:e.spend}));h(s),p(function(e){let t={};e.forEach(e=>{Object.entries(e.users).forEach(e=>{let[s,l]=e;""!==s&&null!=s&&"None"!=s&&(t[s]||(t[s]=0),t[s]+=l)})});let s=Object.entries(t).map(e=>{let[t,s]=e;return{user_id:t,spend:s}});s.sort((e,t)=>t.spend-e.spend);let l=s.slice(0,5);return console.log("topKeys: ".concat(Object.values(l[0]))),l}(e)),c(e)}})}catch(e){console.error("There was an error fetching the data",e)}})()},[t,s,r,a,w,b]),(0,l.jsx)("div",{style:{width:"100%"},children:(0,l.jsxs)(F.Z,{numItems:2,className:"gap-2 p-10 h-[75vh] w-full",children:[(0,l.jsx)(E.Z,{numColSpan:2,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(O.Z,{children:"Monthly Spend"}),(0,l.jsx)(ee.Z,{data:i,index:"date",categories:["spend"],colors:["blue"],valueFormatter:e=>"$ ".concat(new Intl.NumberFormat("us").format(e).toString()),yAxisWidth:100,tickGap:5})]})}),(0,l.jsx)(E.Z,{numColSpan:1,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(O.Z,{children:"Top API Keys"}),(0,l.jsx)(ee.Z,{className:"mt-4 h-40",data:d,index:"key",categories:["spend"],colors:["blue"],yAxisWidth:80,tickGap:5,layout:"vertical",showXAxis:!1,showLegend:!1})]})}),(0,l.jsx)(E.Z,{numColSpan:1,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(O.Z,{children:"Top Users"}),(0,l.jsx)(ee.Z,{className:"mt-4 h-40",data:x,index:"user_id",categories:["spend"],colors:["blue"],yAxisWidth:200,layout:"vertical",showXAxis:!1,showLegend:!1})]})}),(0,l.jsx)(E.Z,{numColSpan:1,children:(0,l.jsxs)(M.Z,{children:[(0,l.jsx)(O.Z,{children:"Top Models"}),(0,l.jsx)(ee.Z,{className:"mt-4 h-40",data:m,index:"key",categories:["spend"],colors:["blue"],yAxisWidth:200,layout:"vertical",showXAxis:!1,showLegend:!1})]})})]})})},eM=()=>{let{Title:e,Paragraph:t}=er.default,[s,a]=(0,n.useState)(""),[o,c]=(0,n.useState)(null),[d,h]=(0,n.useState)(null),[m,u]=(0,n.useState)(null),[x,p]=(0,n.useState)(!0),j=(0,r.useSearchParams)(),g=j.get("userID"),y=j.get("token"),[Z,f]=(0,n.useState)("api-keys"),[w,k]=(0,n.useState)(null);return(0,n.useEffect)(()=>{if(y){let e=(0,ec.o)(y);if(e){if(console.log("Decoded token:",e),console.log("Decoded key:",e.key),k(e.key),e.user_role){let t=function(e){if(!e)return"Undefined Role";switch(console.log("Received user role: ".concat(e.toLowerCase())),console.log("Received user role length: ".concat(e.toLowerCase().length)),e.toLowerCase()){case"app_owner":case"demo_app_owner":return"App Owner";case"app_admin":case"proxy_admin":return"Admin";case"proxy_admin_viewer":return"Admin Viewer";case"app_user":return"App User";default:return"Unknown Role"}}(e.user_role);console.log("Decoded user_role:",t),a(t),"Admin Viewer"==t&&f("usage")}else console.log("User role not defined");e.user_email?c(e.user_email):console.log("User Email is not set ".concat(e)),e.login_method?p("username_password"==e.login_method):console.log("User Email is not set ".concat(e))}}},[y]),(0,l.jsx)(n.Suspense,{fallback:(0,l.jsx)("div",{children:"Loading..."}),children:(0,l.jsxs)("div",{className:"flex flex-col min-h-screen",children:[(0,l.jsx)(i,{userID:g,userRole:s,userEmail:o,showSSOBanner:x}),(0,l.jsxs)("div",{className:"flex flex-1 overflow-auto",children:[(0,l.jsx)(eE,{setPage:f,userRole:s,defaultSelectedKey:null}),"api-keys"==Z?(0,l.jsx)(ed,{userID:g,userRole:s,teams:d,keys:m,setUserRole:a,userEmail:o,setUserEmail:c,setTeams:h,setKeys:u}):"models"==Z?(0,l.jsx)(ex,{userID:g,userRole:s,token:y,accessToken:w}):"llm-playground"==Z?(0,l.jsx)(eC,{userID:g,userRole:s,token:y,accessToken:w}):"users"==Z?(0,l.jsx)(ek,{userID:g,userRole:s,token:y,keys:m,accessToken:w,setKeys:u}):"teams"==Z?(0,l.jsx)(eb,{teams:d,setTeams:h,searchParams:j,accessToken:w}):"admin-panel"==Z?(0,l.jsx)(ev,{setTeams:h,searchParams:j,accessToken:w}):(0,l.jsx)(eF,{userID:g,userRole:s,token:y,accessToken:w})]})]})})}}},function(e){e.O(0,[730,971,69,744],function(){return e(e.s=20661)}),_N_E=e.O()}]);
\ No newline at end of file
diff --git a/ui/litellm-dashboard/out/_next/static/chunks/app/page-37bd7c3d0bb898a3.js b/ui/litellm-dashboard/out/_next/static/chunks/app/page-37bd7c3d0bb898a3.js
deleted file mode 100644
index 8d5377ae4..000000000
--- a/ui/litellm-dashboard/out/_next/static/chunks/app/page-37bd7c3d0bb898a3.js
+++ /dev/null
@@ -1 +0,0 @@
-(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[931],{20661:function(e,t,s){Promise.resolve().then(s.bind(s,56239))},56239:function(e,t,s){"use strict";s.r(t),s.d(t,{default:function(){return eF}});var l=s(3827),n=s(64090),r=s(47907),a=s(8792),o=s(2179),i=e=>{let{userID:t,userRole:s,userEmail:n,showSSOBanner:r}=e;return console.log("User ID:",t),console.log("userEmail:",n),(0,l.jsxs)("nav",{className:"left-0 right-0 top-0 flex justify-between items-center h-12 mb-4",children:[(0,l.jsx)("div",{className:"text-left my-2 absolute top-0 left-0",children:(0,l.jsx)("div",{className:"flex flex-col items-center",children:(0,l.jsx)(a.default,{href:"/",children:(0,l.jsx)("button",{className:"text-gray-800 text-2xl py-1 rounded text-center",children:(0,l.jsx)("img",{src:"/get_image",width:200,height:200,alt:"LiteLLM Brand",className:"mr-2"})})})})}),(0,l.jsxs)("div",{className:"text-right mx-4 my-2 absolute top-0 right-0 flex items-center justify-end space-x-2",children:[r?(0,l.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/ui#setup-ssoauth-for-ui",target:"_blank",className:"mr-2",children:(0,l.jsx)(o.Z,{variant:"primary",size:"lg",children:"Enable SSO"})}):null,(0,l.jsxs)(o.Z,{variant:"secondary",size:"lg",children:[n,(0,l.jsxs)("p",{children:["Role: ",s]}),(0,l.jsxs)("p",{children:["ID: ",t]})]})]})]})},c=s(80588);let d=async(e,t,s)=>{try{if(console.log("Form Values in keyCreateCall:",s),s.description&&(s.metadata||(s.metadata={}),s.metadata.description=s.description,delete s.description,s.metadata=JSON.stringify(s.metadata)),s.metadata){console.log("formValues.metadata:",s.metadata);try{s.metadata=JSON.parse(s.metadata)}catch(e){throw c.ZP.error("Failed to parse metadata: "+e),Error("Failed to parse metadata: "+e)}}console.log("Form Values after check:",s);let l=await fetch("/key/generate",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({user_id:t,...s})});if(!l.ok){let e=await l.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let n=await l.json();return console.log("API Response:",n),n}catch(e){throw console.error("Failed to create key:",e),e}},h=async(e,t,s)=>{try{if(console.log("Form Values in keyCreateCall:",s),s.description&&(s.metadata||(s.metadata={}),s.metadata.description=s.description,delete s.description,s.metadata=JSON.stringify(s.metadata)),s.metadata){console.log("formValues.metadata:",s.metadata);try{s.metadata=JSON.parse(s.metadata)}catch(e){throw c.ZP.error("Failed to parse metadata: "+e),Error("Failed to parse metadata: "+e)}}console.log("Form Values after check:",s);let l=await fetch("/user/new",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({user_id:t,...s})});if(!l.ok){let e=await l.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let n=await l.json();return console.log("API Response:",n),n}catch(e){throw console.error("Failed to create key:",e),e}},m=async(e,t)=>{try{console.log("in keyDeleteCall:",t),c.ZP.info("Making key delete request");let s=await fetch("/key/delete",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({keys:[t]})});if(!s.ok){let e=await s.text();throw c.ZP.error("Failed to delete key: "+e),Error("Network response was not ok")}let l=await s.json();return console.log(l),c.ZP.success("API Key Deleted"),l}catch(e){throw console.error("Failed to create key:",e),e}},u=async function(e,t,s){let l=arguments.length>3&&void 0!==arguments[3]&&arguments[3];try{let n="/user/info";"App Owner"==s&&t&&(n="".concat(n,"/?user_id=").concat(t)),console.log("in userInfoCall viewAll=",l),l&&(n="".concat(n,"/?view_all=true")),c.ZP.info("Requesting user data");let r=await fetch(n,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!r.ok){let e=await r.text();throw c.ZP.error(e),Error("Network response was not ok")}let a=await r.json();return console.log("API Response:",a),c.ZP.info("Received user data"),a}catch(e){throw console.error("Failed to create key:",e),e}},x=async(e,t,s)=>{try{c.ZP.info("Requesting model data");let t=await fetch("/v2/model/info",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}let s=await t.json();return c.ZP.info("Received model data"),s}catch(e){throw console.error("Failed to create key:",e),e}},p=async(e,t,s)=>{try{c.ZP.info("Requesting model data");let t=await fetch("/models",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}let s=await t.json();return c.ZP.info("Received model data"),s}catch(e){throw console.error("Failed to create key:",e),e}},j=async(e,t)=>{try{let s="/global/spend/logs";console.log("in keySpendLogsCall:",s);let l=await fetch("".concat(s,"/?api_key=").concat(t),{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw c.ZP.error(e),Error("Network response was not ok")}let n=await l.json();return console.log(n),n}catch(e){throw console.error("Failed to create key:",e),e}},g=async(e,t,s,l,n,r)=>{try{console.log("user role in spend logs call: ".concat(s));let t="/spend/logs";t="App Owner"==s?"".concat(t,"/?user_id=").concat(l,"&start_date=").concat(n,"&end_date=").concat(r):"".concat(t,"/?start_date=").concat(n,"&end_date=").concat(r),c.ZP.info("Making spend logs request");let a=await fetch(t,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!a.ok){let e=await a.text();throw c.ZP.error(e),Error("Network response was not ok")}let o=await a.json();return console.log(o),c.ZP.success("Spend Logs received"),o}catch(e){throw console.error("Failed to create key:",e),e}},Z=async e=>{try{c.ZP.info("Making spend logs request");let t=await fetch("/global/spend/logs",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}let s=await t.json();return console.log(s),c.ZP.success("Spend Logs received"),s}catch(e){throw console.error("Failed to create key:",e),e}},y=async e=>{try{c.ZP.info("Making spend keys request");let t=await fetch("/global/spend/keys?limit=5",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}let s=await t.json();return console.log(s),c.ZP.success("Spend Logs received"),s}catch(e){throw console.error("Failed to create key:",e),e}},f=async(e,t)=>{try{t&&JSON.stringify({api_key:t}),c.ZP.info("Making top end users request");let s={method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}};t&&(s.body=JSON.stringify({api_key:t}));let l=await fetch("/global/spend/end_users",s);if(!l.ok){let e=await l.text();throw c.ZP.error(e),Error("Network response was not ok")}let n=await l.json();return console.log(n),c.ZP.success("Top End users received"),n}catch(e){throw console.error("Failed to create key:",e),e}},w=async e=>{try{c.ZP.info("Making top models request");let t=await fetch("/global/spend/models?limit=5",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error(e),Error("Network response was not ok")}let s=await t.json();return console.log(s),c.ZP.success("Top Models received"),s}catch(e){throw console.error("Failed to create key:",e),e}},k=async(e,t)=>{try{let s=await fetch("/v2/key/info",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({keys:t})});if(!s.ok){let e=await s.text();throw c.ZP.error(e),Error("Network response was not ok")}let l=await s.json();return console.log(l),l}catch(e){throw console.error("Failed to create key:",e),e}},_=async(e,t)=>{try{let s="/spend/users";console.log("in spendUsersCall:",s);let l=await fetch("".concat(s,"/?user_id=").concat(t),{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw c.ZP.error(e),Error("Network response was not ok")}let n=await l.json();return console.log(n),n}catch(e){throw console.error("Failed to get spend for user",e),e}},b=async(e,t,s,l)=>{try{let n=await fetch("/user/request_model",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({models:[t],user_id:s,justification:l})});if(!n.ok){let e=await n.text();throw c.ZP.error("Failed to delete key: "+e),Error("Network response was not ok")}let r=await n.json();return console.log(r),c.ZP.success(""),r}catch(e){throw console.error("Failed to create key:",e),e}},v=async e=>{try{let t="/user/get_requests";console.log("in userGetRequesedtModelsCall:",t);let s=await fetch(t,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!s.ok){let e=await s.text();throw c.ZP.error("Failed to delete key: "+e),Error("Network response was not ok")}let l=await s.json();return console.log(l),c.ZP.success(""),l}catch(e){throw console.error("Failed to get requested models:",e),e}},S=async(e,t)=>{try{let s="/user/get_users?role=".concat(t);console.log("in userGetAllUsersCall:",s);let l=await fetch(s,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw c.ZP.error("Failed to delete key: "+e),Error("Network response was not ok")}let n=await l.json();return console.log(n),c.ZP.success("Got all users"),n}catch(e){throw console.error("Failed to get requested models:",e),e}},N=async(e,t)=>{try{console.log("Form Values in teamCreateCall:",t);let s=await fetch("/team/new",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...t})});if(!s.ok){let e=await s.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let l=await s.json();return console.log("API Response:",l),l}catch(e){throw console.error("Failed to create key:",e),e}},A=async(e,t,s)=>{try{console.log("Form Values in teamMemberAddCall:",s);let l=await fetch("/team/member_add",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({team_id:t,member:s})});if(!l.ok){let e=await l.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let n=await l.json();return console.log("API Response:",n),n}catch(e){throw console.error("Failed to create key:",e),e}},C=async(e,t)=>{try{console.log("Form Values in userUpdateUserCall:",t);let s=await fetch("/user/update",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({user_role:"proxy_admin_viewer",...t})});if(!s.ok){let e=await s.text();throw c.ZP.error("Failed to create key: "+e),console.error("Error response from the server:",e),Error("Network response was not ok")}let l=await s.json();return console.log("API Response:",l),c.ZP.success("User role updated"),l}catch(e){throw console.error("Failed to create key:",e),e}},I=async(e,t)=>{try{let s=await fetch("/global/predict/spend/logs",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({data:t})});if(!s.ok){let e=await s.text();throw c.ZP.error(e),Error("Network response was not ok")}let l=await s.json();return console.log(l),l}catch(e){throw console.error("Failed to create key:",e),e}},P=async e=>{try{console.log("Checking Slack Budget Alerts service health"),c.ZP.info("Sending Test Slack alert...");let t=await fetch("/health/services?service=slack_budget_alerts",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw c.ZP.error("Failed Slack Alert test: "+e),Error(e)}let s=await t.json();return c.ZP.success("Test Slack Alert worked - check your Slack!"),console.log("Service Health Response:",s),s}catch(e){throw console.error("Failed to perform health check:",e),e}};var T=s(10384),E=s(46453),F=s(13810),M=s(71801),R=s(42440),O=s(17189),D=s(12143),U=s(77171),L=s(42539),z=s(88707),B=s(1861);let{Option:q}=O.default;var K=e=>{let{userID:t,teamID:s,userRole:r,accessToken:a,data:i,userModels:h,setData:m}=e,[u]=D.Z.useForm(),[x,p]=(0,n.useState)(!1),[j,g]=(0,n.useState)(null),[Z,y]=(0,n.useState)(null),f=()=>{p(!1),u.resetFields()},w=()=>{p(!1),g(null),u.resetFields()},k=async e=>{try{c.ZP.info("Making API Call"),p(!0);let s=await d(a,t,e);console.log("key create Response:",s),m(e=>e?[...e,s]:[s]),g(s.key),y(s.soft_budget),c.ZP.success("API Key Created"),u.resetFields(),localStorage.removeItem("userData"+t)}catch(e){console.error("Error creating the key:",e)}},_=async()=>{try{console.log("Sending Slack alert...");let e=await P(a);console.log("slackBudgetAlertsHealthCheck Response:",e),console.log("Testing Slack alert successful")}catch(e){console.error("Error sending Slack alert:",e)}};return(0,l.jsxs)("div",{children:[(0,l.jsx)(o.Z,{className:"mx-auto",onClick:()=>p(!0),children:"+ Create New Key"}),(0,l.jsx)(U.Z,{title:"Create Key",visible:x,width:800,footer:null,onOk:f,onCancel:w,children:(0,l.jsxs)(D.Z,{form:u,onFinish:k,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:["App Owner"===r||"Admin"===r?(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(D.Z.Item,{label:"Key Name",name:"key_alias",children:(0,l.jsx)(L.Z,{})}),(0,l.jsx)(D.Z.Item,{label:"Team ID",name:"team_id",children:(0,l.jsx)(L.Z,{placeholder:"ai_team",defaultValue:s||""})}),(0,l.jsx)(D.Z.Item,{label:"Models",name:"models",children:(0,l.jsx)(O.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:h.map(e=>(0,l.jsx)(q,{value:e,children:e},e))})}),(0,l.jsx)(D.Z.Item,{label:"Soft Budget (USD) Monthly",name:"soft_budget",initialValue:50,children:(0,l.jsx)(z.Z,{step:.01,precision:2,defaultValue:50,width:200})}),(0,l.jsx)(D.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,l.jsx)(z.Z,{step:.01,precision:2,width:200})}),(0,l.jsx)(D.Z.Item,{label:"Reset Budget",name:"budget_duration",children:(0,l.jsxs)(O.default,{defaultValue:null,placeholder:"n/a",children:[(0,l.jsx)(O.default.Option,{value:"24h",children:"daily"}),(0,l.jsx)(O.default.Option,{value:"30d",children:"monthly"})]})}),(0,l.jsx)(D.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,l.jsx)(z.Z,{step:1,width:400})}),(0,l.jsx)(D.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,l.jsx)(z.Z,{step:1,width:400})}),(0,l.jsx)(D.Z.Item,{label:"Expire Key (eg: 30s, 30h, 30d)",name:"duration",children:(0,l.jsx)(L.Z,{})}),(0,l.jsx)(D.Z.Item,{label:"Metadata",name:"metadata",children:(0,l.jsx)(L.Z.TextArea,{rows:4,placeholder:"Enter metadata as JSON"})})]}):(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(D.Z.Item,{label:"Key Name",name:"key_alias",children:(0,l.jsx)(L.Z,{})}),(0,l.jsx)(D.Z.Item,{label:"Team ID (Contact Group)",name:"team_id",children:(0,l.jsx)(L.Z,{placeholder:"ai_team"})}),(0,l.jsx)(D.Z.Item,{label:"Description",name:"description",children:(0,l.jsx)(L.Z.TextArea,{placeholder:"Enter description",rows:4})})]}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(B.ZP,{htmlType:"submit",children:"Create Key"})})]})}),j&&(0,l.jsx)(U.Z,{visible:x,onOk:f,onCancel:w,footer:null,children:(0,l.jsx)(E.Z,{numItems:1,className:"gap-2 w-full",children:(0,l.jsxs)(F.Z,{children:[(0,l.jsx)(R.Z,{children:"Save your Key"}),(0,l.jsx)(T.Z,{numColSpan:1,children:(0,l.jsxs)("p",{children:["Please save this secret key somewhere safe and accessible. For security reasons, ",(0,l.jsx)("b",{children:"you will not be able to view it again"})," ","through your LiteLLM account. If you lose this secret key, you will need to generate a new one."]})}),(0,l.jsx)(T.Z,{numColSpan:1,children:null!=j?(0,l.jsxs)("div",{children:[(0,l.jsxs)(M.Z,{children:["API Key: ",j]}),(0,l.jsx)(R.Z,{className:"mt-6",children:"Budgets"}),(0,l.jsxs)(M.Z,{children:["Soft Limit Budget: $",Z]}),(0,l.jsx)(o.Z,{className:"mt-3",onClick:_,children:"Test Slack Alert"}),(0,l.jsxs)(M.Z,{className:"mt-2",children:["(LiteLLM Docs -",(0,l.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/alerting",target:"_blank",className:"text-blue-500",children:"Set Up Slack Alerting)"})]})]}):(0,l.jsx)(M.Z,{children:"Key being created, this might take 30s"})})]})})})]})},V=s(33393),J=s(61244),G=s(10827),$=s(3851),H=s(2044),W=s(64167),Y=s(74480),X=s(7178),Q=s(9853),ee=s(56863),et=e=>{let{token:t,accessToken:s,keySpend:r,keyBudget:a,keyName:i}=e,[c,d]=(0,n.useState)(!1),[h,m]=(0,n.useState)(null),[u,x]=(0,n.useState)(""),[p,g]=(0,n.useState)(null),Z=async()=>{try{if(null==s||null==t)return;console.log("accessToken: ".concat(s,"; token: ").concat(t));let e=await j(s,t);console.log("Response:",e),m(e);let l=await I(s,e);console.log("Response2:",l);let n=[...e,...l.response];m(n),x(l.predicted_spend),console.log("Combined Data:",n)}catch(e){console.error("There was an error fetching the data",e)}};return t?(0,l.jsxs)("div",{children:[(0,l.jsx)(o.Z,{size:"xs",onClick:()=>{console.log("Show Modal triggered"),d(!0),Z()},variant:"secondary",children:"View Spend Report"}),(0,l.jsxs)(U.Z,{visible:c,width:1400,onOk:()=>{d(!1)},onCancel:()=>{d(!1)},footer:null,children:[(0,l.jsxs)(R.Z,{style:{textAlign:"left"},children:["Key Name: ",i]}),(0,l.jsxs)(ee.Z,{children:["Monthly Spend $",r]}),(0,l.jsx)(R.Z,{children:u}),(0,l.jsx)(F.Z,{className:"mt-6 mb-6",children:h&&(0,l.jsx)(Q.Z,{className:"mt-6",data:h,colors:["blue","amber"],index:"date",categories:["spend","predicted_spend"],yAxisWidth:80})})]})]}):null},es=e=>{let{userID:t,accessToken:s,data:r,setData:a}=e,[i,c]=(0,n.useState)(!1),[d,h]=(0,n.useState)(!1),[u,x]=(0,n.useState)(null),p=async e=>{null!=r&&(x(e),localStorage.removeItem("userData"+t),h(!0))},j=async()=>{if(null!=u&&null!=r){try{await m(s,u);let e=r.filter(e=>e.token!==u);a(e)}catch(e){console.error("Error deleting the key:",e)}h(!1),x(null)}};if(null!=r)return console.log("RERENDER TRIGGERED"),(0,l.jsxs)(F.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh] mb-4",children:[(0,l.jsxs)(G.Z,{className:"mt-5",children:[(0,l.jsx)(W.Z,{children:(0,l.jsxs)(X.Z,{children:[(0,l.jsx)(Y.Z,{children:"Key Alias"}),(0,l.jsx)(Y.Z,{children:"Secret Key"}),(0,l.jsx)(Y.Z,{children:"Spend (USD)"}),(0,l.jsx)(Y.Z,{children:"Key Budget (USD)"}),(0,l.jsx)(Y.Z,{children:"Spend Report"}),(0,l.jsx)(Y.Z,{children:"Team ID"}),(0,l.jsx)(Y.Z,{children:"Metadata"}),(0,l.jsx)(Y.Z,{children:"Models"}),(0,l.jsx)(Y.Z,{children:"TPM / RPM Limits"}),(0,l.jsx)(Y.Z,{children:"Expires"})]})}),(0,l.jsx)($.Z,{children:r.map(e=>(console.log(e),"litellm-dashboard"===e.team_id)?null:(0,l.jsxs)(X.Z,{children:[(0,l.jsx)(H.Z,{children:null!=e.key_alias?(0,l.jsx)(M.Z,{children:e.key_alias}):(0,l.jsx)(M.Z,{children:"Not Set"})}),(0,l.jsx)(H.Z,{children:(0,l.jsx)(M.Z,{children:e.key_name})}),(0,l.jsx)(H.Z,{children:(0,l.jsx)(M.Z,{children:e.spend})}),(0,l.jsx)(H.Z,{children:null!=e.max_budget?(0,l.jsx)(M.Z,{children:e.max_budget}):(0,l.jsx)(M.Z,{children:"Unlimited Budget"})}),(0,l.jsx)(H.Z,{children:(0,l.jsx)(et,{token:e.token,accessToken:s,keySpend:e.spend,keyBudget:e.max_budget,keyName:e.key_name})}),(0,l.jsx)(H.Z,{children:(0,l.jsx)(M.Z,{children:e.team_id})}),(0,l.jsx)(H.Z,{children:(0,l.jsx)(M.Z,{children:JSON.stringify(e.metadata)})}),(0,l.jsx)(H.Z,{children:(0,l.jsx)(M.Z,{children:JSON.stringify(e.models)})}),(0,l.jsx)(H.Z,{children:(0,l.jsxs)(M.Z,{children:["TPM Limit: ",e.tpm_limit?e.tpm_limit:"Unlimited"," ",(0,l.jsx)("br",{})," RPM Limit:"," ",e.rpm_limit?e.rpm_limit:"Unlimited"]})}),(0,l.jsx)(H.Z,{children:null!=e.expires?(0,l.jsx)(M.Z,{children:e.expires}):(0,l.jsx)(M.Z,{children:"Never expires"})}),(0,l.jsx)(H.Z,{children:(0,l.jsx)(J.Z,{onClick:()=>p(e.token),icon:V.Z,size:"sm"})})]},e.token))})]}),d&&(0,l.jsx)("div",{className:"fixed z-10 inset-0 overflow-y-auto",children:(0,l.jsxs)("div",{className:"flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0",children:[(0,l.jsx)("div",{className:"fixed inset-0 transition-opacity","aria-hidden":"true",children:(0,l.jsx)("div",{className:"absolute inset-0 bg-gray-500 opacity-75"})}),(0,l.jsx)("span",{className:"hidden sm:inline-block sm:align-middle sm:h-screen","aria-hidden":"true",children:""}),(0,l.jsxs)("div",{className:"inline-block align-bottom bg-white rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full",children:[(0,l.jsx)("div",{className:"bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4",children:(0,l.jsx)("div",{className:"sm:flex sm:items-start",children:(0,l.jsxs)("div",{className:"mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left",children:[(0,l.jsx)("h3",{className:"text-lg leading-6 font-medium text-gray-900",children:"Delete Key"}),(0,l.jsx)("div",{className:"mt-2",children:(0,l.jsx)("p",{className:"text-sm text-gray-500",children:"Are you sure you want to delete this key ?"})})]})})}),(0,l.jsxs)("div",{className:"bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse",children:[(0,l.jsx)(o.Z,{onClick:j,color:"red",className:"ml-2",children:"Delete"}),(0,l.jsx)(o.Z,{onClick:()=>{h(!1),x(null)},children:"Cancel"})]})]})]})})]})},el=e=>{let{userID:t,userSpendData:s,userRole:r,accessToken:a}=e;console.log("User SpendData:",s);let[o,i]=(0,n.useState)(null==s?void 0:s.spend),[c,d]=(0,n.useState)((null==s?void 0:s.max_budget)||null);return(0,n.useEffect)(()=>{(async()=>{if("Admin"===r)try{let e=await _(a,"litellm-proxy-budget");console.log("Result from callSpendUsers:",e);let t=e[0];i(null==t?void 0:t.spend),d((null==t?void 0:t.max_budget)||null)}catch(e){console.error("Failed to get spend for user",e)}})()},[r,a,t]),(0,l.jsx)(l.Fragment,{children:(0,l.jsxs)(F.Z,{className:"mx-auto mb-4",children:[(0,l.jsxs)(ee.Z,{children:["$",o]}),(0,l.jsxs)(R.Z,{children:["/ ",null!==c?"$".concat(c," limit"):"No limit"]})]})})},en=s(36083),er=s(68967),ea=s(27166),eo=e=>{let{teams:t,setSelectedTeam:s}=e,{Title:r,Paragraph:a}=en.default,[o,i]=(0,n.useState)("");return(0,l.jsxs)("div",{className:"mt-10",children:[(0,l.jsx)(r,{level:4,children:"Default Team"}),(0,l.jsx)(a,{children:"If you belong to multiple teams, this setting controls which team is used by default when creating new API Keys."}),t&&t.length>0?(0,l.jsx)(er.Z,{defaultValue:"0",children:t.map((e,t)=>(0,l.jsx)(ea.Z,{value:String(t),onClick:()=>s(e),children:e.team_alias},t))}):(0,l.jsxs)(a,{children:["No team created. ",(0,l.jsx)("b",{children:"Defaulting to personal account."})]})]})},ei=s(37963);console.log("isLocal:",!1);var ec=e=>{let{userID:t,userRole:s,teams:a,keys:o,setUserRole:i,userEmail:c,setUserEmail:d,setTeams:h,setKeys:m}=e,[x,j]=(0,n.useState)(null),g=(0,r.useSearchParams)();g.get("viewSpend"),(0,r.useRouter)();let Z=g.get("token"),[y,f]=(0,n.useState)(null),[w,k]=(0,n.useState)([]),[_,b]=(0,n.useState)(a?a[0]:null);if(window.addEventListener("beforeunload",function(){sessionStorage.clear()}),(0,n.useEffect)(()=>{if(Z){let e=(0,ei.o)(Z);if(e){if(console.log("Decoded token:",e),console.log("Decoded key:",e.key),f(e.key),e.user_role){let t=function(e){if(!e)return"Undefined Role";switch(console.log("Received user role: ".concat(e)),e.toLowerCase()){case"app_owner":case"demo_app_owner":return"App Owner";case"app_admin":case"proxy_admin":return"Admin";case"proxy_admin_viewer":return"Admin Viewer";case"app_user":return"App User";default:return"Unknown Role"}}(e.user_role);console.log("Decoded user_role:",t),i(t)}else console.log("User role not defined");e.user_email?d(e.user_email):console.log("User Email is not set ".concat(e))}}if(t&&y&&s&&!o&&!x){let e=sessionStorage.getItem("userModels"+t);e?k(JSON.parse(e)):(async()=>{try{let e=await u(y,t,s);console.log("received teams in user dashboard: ".concat(Object.keys(e),"; team values: ").concat(Object.entries(e.teams))),j(e.user_info),m(e.keys),h(e.teams),b(e.teams?e.teams[0]:null),sessionStorage.setItem("userData"+t,JSON.stringify(e.keys)),sessionStorage.setItem("userSpendData"+t,JSON.stringify(e.user_info));let l=(await p(y,t,s)).data.map(e=>e.id);console.log("available_model_names:",l),k(l),console.log("userModels:",w),sessionStorage.setItem("userModels"+t,JSON.stringify(l))}catch(e){console.error("There was an error fetching the data",e)}})()}},[t,Z,y,o,s]),null==t||null==Z){let e="/sso/key/generate";return console.log("Full URL:",e),window.location.href=e,null}if(null==y)return null;if(null==s&&i("App Owner"),s&&"Admin Viewer"==s){let{Title:e,Paragraph:t}=en.default;return(0,l.jsxs)("div",{children:[(0,l.jsx)(e,{level:1,children:"Access Denied"}),(0,l.jsx)(t,{children:"Ask your proxy admin for access to create keys"})]})}return(0,l.jsx)("div",{children:(0,l.jsx)(E.Z,{numItems:1,className:"gap-0 p-10 h-[75vh] w-full",children:(0,l.jsxs)(T.Z,{numColSpan:1,children:[(0,l.jsx)(el,{userID:t,userSpendData:x,userRole:s,accessToken:y}),(0,l.jsx)(es,{userID:t,accessToken:y,data:o,setData:m}),(0,l.jsx)(K,{userID:t,teamID:_?_.team_id:null,userRole:s,userModels:w,accessToken:y,data:o,setData:m}),(0,l.jsx)(eo,{teams:a,setSelectedTeam:b})]})})})},ed=s(5);let{Option:eh}=O.default;var em=e=>{let{userModels:t,accessToken:s,userID:r}=e,[a]=D.Z.useForm(),[i,d]=(0,n.useState)(!1),h=async e=>{try{c.ZP.info("Requesting access");let{selectedModel:t,accessReason:l}=e;await b(s,t,r,l),d(!0)}catch(e){console.error("Error requesting access:",e)}};return(0,l.jsxs)("div",{children:[(0,l.jsx)(o.Z,{size:"xs",onClick:()=>d(!0),children:"Request Access"}),(0,l.jsx)(U.Z,{title:"Request Access",visible:i,width:800,footer:null,onOk:()=>{d(!1),a.resetFields()},onCancel:()=>{d(!1),a.resetFields()},children:(0,l.jsxs)(D.Z,{form:a,onFinish:h,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsx)(D.Z.Item,{label:"Select Model",name:"selectedModel",children:(0,l.jsx)(O.default,{placeholder:"Select model",style:{width:"100%"},children:t.map(e=>(0,l.jsx)(eh,{value:e,children:e},e))})}),(0,l.jsx)(D.Z.Item,{label:"Reason for Access",name:"accessReason",children:(0,l.jsx)(L.Z.TextArea,{rows:4,placeholder:"Enter reason for access"})}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(o.Z,{children:"Request Access"})})]})})]})},eu=e=>{let{accessToken:t,token:s,userRole:r,userID:a}=e,[i,c]=(0,n.useState)({data:[]}),[d,h]=(0,n.useState)([]);if((0,n.useEffect)(()=>{if(!t||!s||!r||!a)return;let e=async()=>{try{let e=await x(t,a,r);if(console.log("Model data response:",e.data),c(e),"Admin"===r&&t){let e=await v(t);console.log("Pending Requests:",d),h(e.requests||[])}}catch(e){console.error("There was an error fetching the model data",e)}};t&&s&&r&&a&&e()},[t,s,r,a]),!i||!t||!s||!r||!a)return(0,l.jsx)("div",{children:"Loading..."});let m=[];for(let e=0;e(0,l.jsxs)(X.Z,{children:[(0,l.jsx)(H.Z,{children:(0,l.jsx)(R.Z,{children:e.model_name})}),(0,l.jsx)(H.Z,{children:e.provider}),(0,l.jsx)(H.Z,{children:e.user_access?(0,l.jsx)(ed.Z,{color:"green",children:"Yes"}):(0,l.jsx)(em,{userModels:m,accessToken:t,userID:a})}),(0,l.jsx)(H.Z,{children:e.input_cost}),(0,l.jsx)(H.Z,{children:e.output_cost}),(0,l.jsx)(H.Z,{children:e.max_tokens})]},e.model_name))})]})}),"Admin"===r&&d&&d.length>0?(0,l.jsx)(F.Z,{children:(0,l.jsxs)(G.Z,{children:[(0,l.jsxs)(W.Z,{children:[(0,l.jsx)(R.Z,{children:"Pending Requests"}),(0,l.jsxs)(X.Z,{children:[(0,l.jsx)(H.Z,{children:(0,l.jsx)(R.Z,{children:"User ID"})}),(0,l.jsx)(H.Z,{children:(0,l.jsx)(R.Z,{children:"Requested Models"})}),(0,l.jsx)(H.Z,{children:(0,l.jsx)(R.Z,{children:"Justification"})}),(0,l.jsx)(H.Z,{children:(0,l.jsx)(R.Z,{children:"Justification"})})]})]}),(0,l.jsx)($.Z,{children:d.map(e=>(0,l.jsxs)(X.Z,{children:[(0,l.jsx)(H.Z,{children:(0,l.jsx)("p",{children:e.user_id})}),(0,l.jsx)(H.Z,{children:(0,l.jsx)("p",{children:e.models[0]})}),(0,l.jsx)(H.Z,{children:(0,l.jsx)("p",{children:e.justification})}),(0,l.jsx)(H.Z,{children:(0,l.jsx)("p",{children:e.user_id})}),(0,l.jsx)(o.Z,{children:"Approve"}),(0,l.jsx)(o.Z,{variant:"secondary",className:"ml-2",children:"Deny"})]},e.request_id))})]})}):null]})})},ex=s(92836),ep=s(26734),ej=s(41608),eg=s(32126),eZ=s(23682);let{Option:ey}=O.default;var ef=e=>{let{userID:t,accessToken:s}=e,[r]=D.Z.useForm(),[a,i]=(0,n.useState)(!1),[d,m]=(0,n.useState)(null),[u,x]=(0,n.useState)([]);(0,n.useEffect)(()=>{(async()=>{try{let e=await p(s,t,"any"),l=[];for(let t=0;t{i(!1),r.resetFields()},g=()=>{i(!1),m(null),r.resetFields()},Z=async e=>{try{c.ZP.info("Making API Call"),i(!0),console.log("formValues in create user:",e);let l=await h(s,t,e);console.log("user create Response:",l),m(l.key),c.ZP.success("API user Created"),r.resetFields(),localStorage.removeItem("userData"+t)}catch(e){console.error("Error creating the user:",e)}};return(0,l.jsxs)("div",{children:[(0,l.jsx)(o.Z,{className:"mx-auto",onClick:()=>i(!0),children:"+ Create New User"}),(0,l.jsx)(U.Z,{title:"Create User",visible:a,width:800,footer:null,onOk:j,onCancel:g,children:(0,l.jsxs)(D.Z,{form:r,onFinish:Z,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsx)(D.Z.Item,{label:"User ID",name:"user_id",children:(0,l.jsx)(L.Z,{placeholder:"Enter User ID"})}),(0,l.jsx)(D.Z.Item,{label:"Team ID",name:"team_id",children:(0,l.jsx)(L.Z,{placeholder:"ai_team"})}),(0,l.jsx)(D.Z.Item,{label:"Models",name:"models",children:(0,l.jsx)(O.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:u.map(e=>(0,l.jsx)(ey,{value:e,children:e},e))})}),(0,l.jsx)(D.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,l.jsx)(z.Z,{step:.01,precision:2,width:200})}),(0,l.jsx)(D.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,l.jsx)(z.Z,{step:1,width:400})}),(0,l.jsx)(D.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,l.jsx)(z.Z,{step:1,width:400})}),(0,l.jsx)(D.Z.Item,{label:"Duration (eg: 30s, 30h, 30d)",name:"duration",children:(0,l.jsx)(L.Z,{})}),(0,l.jsx)(D.Z.Item,{label:"Metadata",name:"metadata",children:(0,l.jsx)(L.Z.TextArea,{rows:4,placeholder:"Enter metadata as JSON"})}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(B.ZP,{htmlType:"submit",children:"Create User"})})]})}),d&&(0,l.jsxs)(U.Z,{title:"Save Your User",visible:a,onOk:j,onCancel:g,footer:null,children:[(0,l.jsxs)("p",{children:["Please save this secret user somewhere safe and accessible. For security reasons, ",(0,l.jsx)("b",{children:"you will not be able to view it again"})," ","through your LiteLLM account. If you lose this secret user, you will need to generate a new one."]}),(0,l.jsx)("p",{children:null!=d?"API user: ".concat(d):"User being created, this might take 30s"})]})]})},ew=e=>{let{accessToken:t,token:s,keys:r,userRole:a,userID:o,setKeys:i}=e,[c,d]=(0,n.useState)(null),[h,m]=(0,n.useState)(null),[x,p]=(0,n.useState)(1);if((0,n.useEffect)(()=>{if(!t||!s||!a||!o)return;let e=async()=>{try{let e=await u(t,null,a,!0);console.log("user data response:",e),d(e)}catch(e){console.error("There was an error fetching the model data",e)}};t&&s&&a&&o&&!c&&e();let l=async()=>{try{let e=await f(t,null);console.log("user data response:",e),m(e)}catch(e){console.error("There was an error fetching the model data",e)}};a&&("Admin"==a||"Admin Viewer"==a)&&!h&&l()},[t,s,a,o]),!c||!t||!s||!a||!o)return(0,l.jsx)("div",{children:"Loading..."});let j=async e=>{try{let s=await f(t,e);console.log("user data response:",s),m(s)}catch(e){console.error("There was an error fetching the model data",e)}};return(0,l.jsx)("div",{style:{width:"100%"},children:(0,l.jsxs)(E.Z,{className:"gap-2 p-10 h-[75vh] w-full",children:[(0,l.jsx)(ef,{userID:o,accessToken:t}),(0,l.jsx)(F.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh] mb-4",children:(0,l.jsxs)(ep.Z,{children:[(0,l.jsxs)(ej.Z,{variant:"line",defaultValue:"1",children:[(0,l.jsx)(ex.Z,{value:"1",children:"Key Owners"}),(0,l.jsx)(ex.Z,{value:"2",children:"End-Users"})]}),(0,l.jsxs)(eZ.Z,{children:[(0,l.jsx)(eg.Z,{children:(0,l.jsxs)(G.Z,{className:"mt-5",children:[(0,l.jsx)(W.Z,{children:(0,l.jsxs)(X.Z,{children:[(0,l.jsx)(Y.Z,{children:"User ID"}),(0,l.jsx)(Y.Z,{children:"User Role"}),(0,l.jsx)(Y.Z,{children:"User Models"}),(0,l.jsx)(Y.Z,{children:"User Spend ($ USD)"}),(0,l.jsx)(Y.Z,{children:"User Max Budget ($ USD)"})]})}),(0,l.jsx)($.Z,{children:c.map(e=>(0,l.jsxs)(X.Z,{children:[(0,l.jsx)(H.Z,{children:e.user_id}),(0,l.jsx)(H.Z,{children:e.user_role?e.user_role:"app_owner"}),(0,l.jsx)(H.Z,{children:e.models&&e.models.length>0?e.models:"All Models"}),(0,l.jsx)(H.Z,{children:e.spend?e.spend:0}),(0,l.jsx)(H.Z,{children:e.max_budget?e.max_budget:"Unlimited"})]},e.user_id))})]})}),(0,l.jsxs)(eg.Z,{children:[(0,l.jsxs)("div",{className:"flex items-center",children:[(0,l.jsx)("div",{className:"flex-1"}),(0,l.jsxs)("div",{className:"flex-1 flex justify-between items-center",children:[(0,l.jsx)(M.Z,{className:"w-1/4 mr-2 text-right",children:"Key"}),(0,l.jsx)(er.Z,{defaultValue:"1",className:"w-3/4",children:null==r?void 0:r.map((e,t)=>{if(e&&null!==e.key_name&&e.key_name.length>0)return(0,l.jsx)(ea.Z,{value:String(t),onClick:()=>j(e.token),children:e.key_name},t)})})]})]}),(0,l.jsxs)(G.Z,{children:[(0,l.jsx)(W.Z,{children:(0,l.jsxs)(X.Z,{children:[(0,l.jsx)(Y.Z,{children:"End User"}),(0,l.jsx)(Y.Z,{children:"Spend"}),(0,l.jsx)(Y.Z,{children:"Total Events"})]})}),(0,l.jsx)($.Z,{children:null==h?void 0:h.map((e,t)=>(0,l.jsxs)(X.Z,{children:[(0,l.jsx)(H.Z,{children:e.end_user}),(0,l.jsx)(H.Z,{children:e.total_spend}),(0,l.jsx)(H.Z,{children:e.total_events})]},t))})]})]})]})]})}),function(){if(!c)return null;let e=Math.ceil(c.length/25),t=Math.min(25*x,c.length);return(0,l.jsxs)("div",{className:"flex justify-between items-center",children:[(0,l.jsxs)("div",{children:["Showing ",(x-1)*25+1," – ",t," of ",c.length]}),(0,l.jsxs)("div",{className:"flex",children:[(0,l.jsx)("button",{className:"bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-l focus:outline-none",disabled:1===x,onClick:()=>p(x-1),children:"← Prev"}),(0,l.jsx)("button",{className:"bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-r focus:outline-none",disabled:x===e,onClick:()=>p(x+1),children:"Next →"})]})]})}()]})})},ek=s(8510),e_=e=>{let{teams:t,searchParams:s,accessToken:r,setTeams:a}=e,[i]=D.Z.useForm(),[d]=D.Z.useForm(),{Title:h,Paragraph:m}=en.default,[u,x]=(0,n.useState)(""),[p,j]=(0,n.useState)(t?t[0]:null),[g,Z]=(0,n.useState)(!1),[y,f]=(0,n.useState)(!1),w=async e=>{try{if(null!=r){c.ZP.info("Making API Call");let s=await N(r,e);null!==t?a([...t,s]):a([s]),console.log("response for team create call: ".concat(s)),Z(!1)}}catch(e){console.error("Error creating the key:",e)}},k=async e=>{try{if(null!=r&&null!=t){c.ZP.info("Making API Call");let s={role:"user",user_email:e.user_email,user_id:e.user_id},l=await A(r,p.team_id,s);console.log("response for team create call: ".concat(l.data));let n=t.findIndex(e=>(console.log("team.team_id=".concat(e.team_id,"; response.data.team_id=").concat(l.data.team_id)),e.team_id===l.data.team_id));if(console.log("foundIndex: ".concat(n)),-1!==n){let e=[...t];e[n]=l.data,a(e),j(l.data)}f(!1)}}catch(e){console.error("Error creating the key:",e)}};return console.log("received teams ".concat(t)),(0,l.jsx)("div",{className:"w-full",children:(0,l.jsxs)(E.Z,{numItems:1,className:"gap-2 p-2 h-[75vh] w-full",children:[(0,l.jsxs)(T.Z,{numColSpan:1,children:[(0,l.jsx)(h,{level:4,children:"All Teams"}),(0,l.jsx)(F.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,l.jsxs)(G.Z,{children:[(0,l.jsx)(W.Z,{children:(0,l.jsxs)(X.Z,{children:[(0,l.jsx)(Y.Z,{children:"Team Name"}),(0,l.jsx)(Y.Z,{children:"Spend (USD)"}),(0,l.jsx)(Y.Z,{children:"Budget (USD)"}),(0,l.jsx)(Y.Z,{children:"TPM / RPM Limits"})]})}),(0,l.jsx)($.Z,{children:t&&t.length>0?t.map(e=>(0,l.jsxs)(X.Z,{children:[(0,l.jsx)(H.Z,{children:e.team_alias}),(0,l.jsx)(H.Z,{children:e.spend}),(0,l.jsx)(H.Z,{children:e.max_budget?e.max_budget:"No limit"}),(0,l.jsx)(H.Z,{children:(0,l.jsxs)(M.Z,{children:["TPM Limit:"," ",e.tpm_limit?e.tpm_limit:"Unlimited"," ",(0,l.jsx)("br",{})," RPM Limit:"," ",e.rpm_limit?e.rpm_limit:"Unlimited"]})}),(0,l.jsx)(H.Z,{children:(0,l.jsx)(J.Z,{icon:ek.Z,size:"sm"})})]},e.team_id)):null})]})})]}),(0,l.jsxs)(T.Z,{numColSpan:1,children:[(0,l.jsx)(o.Z,{className:"mx-auto",onClick:()=>Z(!0),children:"+ Create New Team"}),(0,l.jsx)(U.Z,{title:"Create Team",visible:g,width:800,footer:null,onOk:()=>{Z(!1),i.resetFields()},onCancel:()=>{Z(!1),i.resetFields()},children:(0,l.jsxs)(D.Z,{form:i,onFinish:w,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(D.Z.Item,{label:"Team Name",name:"team_alias",children:(0,l.jsx)(L.Z,{})}),(0,l.jsx)(D.Z.Item,{label:"Models",name:"models",children:(0,l.jsx)(O.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"}})}),(0,l.jsx)(D.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,l.jsx)(z.Z,{step:.01,precision:2,width:200})}),(0,l.jsx)(D.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,l.jsx)(z.Z,{step:1,width:400})}),(0,l.jsx)(D.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,l.jsx)(z.Z,{step:1,width:400})})]}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(B.ZP,{htmlType:"submit",children:"Create Team"})})]})})]}),(0,l.jsxs)(T.Z,{numColSpan:1,children:[(0,l.jsx)(h,{level:4,children:"Team Members"}),(0,l.jsx)(m,{children:"If you belong to multiple teams, this setting controls which teams members you see."}),t&&t.length>0?(0,l.jsx)(er.Z,{defaultValue:"0",children:t.map((e,t)=>(0,l.jsx)(ea.Z,{value:String(t),onClick:()=>{j(e)},children:e.team_alias},t))}):(0,l.jsxs)(m,{children:["No team created. ",(0,l.jsx)("b",{children:"Defaulting to personal account."})]})]}),(0,l.jsx)(T.Z,{numColSpan:1,children:(0,l.jsx)(F.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,l.jsxs)(G.Z,{children:[(0,l.jsx)(W.Z,{children:(0,l.jsxs)(X.Z,{children:[(0,l.jsx)(Y.Z,{children:"Member Name"}),(0,l.jsx)(Y.Z,{children:"Role"}),(0,l.jsx)(Y.Z,{children:"Action"})]})}),(0,l.jsx)($.Z,{children:p?p.members_with_roles.map((e,t)=>(0,l.jsxs)(X.Z,{children:[(0,l.jsx)(H.Z,{children:e.user_email?e.user_email:e.user_id?e.user_id:null}),(0,l.jsx)(H.Z,{children:e.role}),(0,l.jsx)(H.Z,{children:(0,l.jsx)(J.Z,{icon:ek.Z,size:"sm"})})]},t)):null})]})})}),(0,l.jsxs)(T.Z,{numColSpan:1,children:[(0,l.jsx)(o.Z,{className:"mx-auto mb-5",onClick:()=>f(!0),children:"+ Add member"}),(0,l.jsx)(U.Z,{title:"Add member",visible:y,width:800,footer:null,onOk:()=>{f(!1),d.resetFields()},onCancel:()=>{f(!1),d.resetFields()},children:(0,l.jsxs)(D.Z,{form:i,onFinish:k,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(D.Z.Item,{label:"Email",name:"user_email",className:"mb-4",children:(0,l.jsx)(L.Z,{name:"user_email",className:"px-3 py-2 border rounded-md w-full"})}),(0,l.jsx)("div",{className:"text-center mb-4",children:"OR"}),(0,l.jsx)(D.Z.Item,{label:"User ID",name:"user_id",className:"mb-4",children:(0,l.jsx)(L.Z,{name:"user_id",className:"px-3 py-2 border rounded-md w-full"})})]}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(B.ZP,{htmlType:"submit",children:"Add member"})})]})})]})]})})},eb=e=>{let{searchParams:t,accessToken:s}=e,[r]=D.Z.useForm(),[a]=D.Z.useForm(),{Title:i,Paragraph:d}=en.default,[h,m]=(0,n.useState)(""),[u,x]=(0,n.useState)(null),[p,j]=(0,n.useState)(!1);(0,n.useEffect)(()=>{(async()=>{if(null!=s){let e=[],t=await S(s,"proxy_admin_viewer");t.forEach(t=>{e.push({user_role:t.user_role,user_id:t.user_id,user_email:t.user_email})}),console.log("proxy viewers: ".concat(t));let l=await S(s,"proxy_admin");l.forEach(t=>{e.push({user_role:t.user_role,user_id:t.user_id,user_email:t.user_email})}),console.log("proxy admins: ".concat(l)),console.log("combinedList: ".concat(e)),x(e)}})()},[s]);let g=async e=>{try{if(null!=s&&null!=u){c.ZP.info("Making API Call"),e.user_email,e.user_id;let t=await C(s,e);console.log("response for team create call: ".concat(t));let l=u.findIndex(e=>(console.log("user.user_id=".concat(e.user_id,"; response.user_id=").concat(t.user_id)),e.user_id===t.user_id));console.log("foundIndex: ".concat(l)),-1==l&&(console.log("updates admin with new user"),u.push(t),x(u)),j(!1)}}catch(e){console.error("Error creating the key:",e)}};return console.log("admins: ".concat(null==u?void 0:u.length)),(0,l.jsxs)("div",{className:"w-full m-2",children:[(0,l.jsx)(i,{level:4,children:"Restricted Access"}),(0,l.jsxs)(d,{children:["Add other people to just view spend. They cannot create keys, teams or grant users access to new models."," ",(0,l.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/ui#restrict-ui-access",children:"Requires SSO Setup"})]}),(0,l.jsxs)(E.Z,{numItems:1,className:"gap-2 p-0 w-full",children:[(0,l.jsx)(T.Z,{numColSpan:1,children:(0,l.jsx)(F.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,l.jsxs)(G.Z,{children:[(0,l.jsx)(W.Z,{children:(0,l.jsxs)(X.Z,{children:[(0,l.jsx)(Y.Z,{children:"Member Name"}),(0,l.jsx)(Y.Z,{children:"Role"}),(0,l.jsx)(Y.Z,{children:"Action"})]})}),(0,l.jsx)($.Z,{children:u?u.map((e,t)=>(0,l.jsxs)(X.Z,{children:[(0,l.jsx)(H.Z,{children:e.user_email?e.user_email:e.user_id?e.user_id:null}),(0,l.jsx)(H.Z,{children:e.user_role}),(0,l.jsx)(H.Z,{children:(0,l.jsx)(J.Z,{icon:ek.Z,size:"sm"})})]},t)):null})]})})}),(0,l.jsxs)(T.Z,{numColSpan:1,children:[(0,l.jsx)(o.Z,{className:"mx-auto mb-5",onClick:()=>j(!0),children:"+ Add viewer"}),(0,l.jsx)(U.Z,{title:"Add viewer",visible:p,width:800,footer:null,onOk:()=>{j(!1),a.resetFields()},onCancel:()=>{j(!1),a.resetFields()},children:(0,l.jsxs)(D.Z,{form:r,onFinish:g,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(D.Z.Item,{label:"Email",name:"user_email",className:"mb-4",children:(0,l.jsx)(L.Z,{name:"user_email",className:"px-3 py-2 border rounded-md w-full"})}),(0,l.jsx)("div",{className:"text-center mb-4",children:"OR"}),(0,l.jsx)(D.Z.Item,{label:"User ID",name:"user_id",className:"mb-4",children:(0,l.jsx)(L.Z,{name:"user_id",className:"px-3 py-2 border rounded-md w-full"})})]}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(B.ZP,{htmlType:"submit",children:"Add member"})})]})})]})]})]})},ev=s(12968),eS=s(67951);async function eN(e,t,s,l){console.log("isLocal:",!1);let n=window.location.origin,r=new ev.ZP.OpenAI({apiKey:l,baseURL:n,dangerouslyAllowBrowser:!0});for await(let l of(await r.chat.completions.create({model:s,stream:!0,messages:[{role:"user",content:e}]})))console.log(l),l.choices[0].delta.content&&t(l.choices[0].delta.content)}var eA=e=>{let{accessToken:t,token:s,userRole:r,userID:a}=e,[o,i]=(0,n.useState)(""),[c,d]=(0,n.useState)([]),[h,m]=(0,n.useState)(void 0),[u,x]=(0,n.useState)(null);(0,n.useEffect)(()=>{t&&s&&r&&a&&(async()=>{let e=await p(t,a,r);console.log("model_info:",e),(null==e?void 0:e.data.length)>0&&(x(e.data),m(e.data[0].id))})()},[t,a,r]);let j=(e,t)=>{d(s=>{let l=s[s.length-1];return l&&l.role===e?[...s.slice(0,s.length-1),{role:e,content:l.content+t}]:[...s,{role:e,content:t}]})},g=async()=>{if(""!==o.trim()&&t&&s&&r&&a){d(e=>[...e,{role:"user",content:o}]);try{h&&await eN(o,e=>j("assistant",e),h,t)}catch(e){console.error("Error fetching model response",e),j("assistant","Error fetching model response")}i("")}};if(r&&"Admin Viewer"==r){let{Title:e,Paragraph:t}=en.default;return(0,l.jsxs)("div",{children:[(0,l.jsx)(e,{level:1,children:"Access Denied"}),(0,l.jsx)(t,{children:"Ask your proxy admin for access to test models"})]})}return(0,l.jsx)("div",{style:{width:"100%",position:"relative"},children:(0,l.jsx)(E.Z,{className:"gap-2 p-10 h-[75vh] w-full",children:(0,l.jsx)(F.Z,{children:(0,l.jsxs)(ep.Z,{children:[(0,l.jsxs)(ej.Z,{className:"mt-4",children:[(0,l.jsx)(ex.Z,{children:"Chat"}),(0,l.jsx)(ex.Z,{children:"API Reference"})]}),(0,l.jsxs)(eZ.Z,{children:[(0,l.jsxs)(eg.Z,{children:[(0,l.jsxs)("div",{children:[(0,l.jsx)("label",{children:"Select Model:"}),(0,l.jsx)("select",{value:h||"",onChange:e=>m(e.target.value),children:null==u?void 0:u.map(e=>(0,l.jsx)("option",{value:e.id,children:e.id},e.id))})]}),(0,l.jsxs)(G.Z,{className:"mt-5",style:{display:"block",maxHeight:"60vh",overflowY:"auto"},children:[(0,l.jsx)(W.Z,{children:(0,l.jsx)(X.Z,{children:(0,l.jsx)(H.Z,{children:(0,l.jsx)(R.Z,{children:"Chat"})})})}),(0,l.jsx)($.Z,{children:c.map((e,t)=>(0,l.jsx)(X.Z,{children:(0,l.jsx)(H.Z,{children:"".concat(e.role,": ").concat(e.content)})},t))})]}),(0,l.jsx)("div",{className:"mt-3",style:{position:"absolute",bottom:5,width:"95%"},children:(0,l.jsxs)("div",{className:"flex",children:[(0,l.jsx)("input",{type:"text",value:o,onChange:e=>i(e.target.value),className:"flex-1 p-2 border rounded-md mr-2",placeholder:"Type your message..."}),(0,l.jsx)("button",{onClick:g,className:"p-2 bg-blue-500 text-white rounded-md",children:"Send"})]})})]}),(0,l.jsx)(eg.Z,{children:(0,l.jsxs)(ep.Z,{children:[(0,l.jsxs)(ej.Z,{children:[(0,l.jsx)(ex.Z,{children:"OpenAI Python SDK"}),(0,l.jsx)(ex.Z,{children:"LlamaIndex"}),(0,l.jsx)(ex.Z,{children:"Langchain Py"})]}),(0,l.jsxs)(eZ.Z,{children:[(0,l.jsx)(eg.Z,{children:(0,l.jsx)(eS.Z,{language:"python",children:'\nimport openai\nclient = openai.OpenAI(\n api_key="your_api_key",\n base_url="http://0.0.0.0:4000" # proxy base url\n)\n\nresponse = client.chat.completions.create(\n model="gpt-3.5-turbo", # model to use from Models Tab\n messages = [\n {\n "role": "user",\n "content": "this is a test request, write a short poem"\n }\n ],\n extra_body={\n "metadata": {\n "generation_name": "ishaan-generation-openai-client",\n "generation_id": "openai-client-gen-id22",\n "trace_id": "openai-client-trace-id22",\n "trace_user_id": "openai-client-user-id2"\n }\n }\n)\n\nprint(response)\n '})}),(0,l.jsx)(eg.Z,{children:(0,l.jsx)(eS.Z,{language:"python",children:'\nimport os, dotenv\n\nfrom llama_index.llms import AzureOpenAI\nfrom llama_index.embeddings import AzureOpenAIEmbedding\nfrom llama_index import VectorStoreIndex, SimpleDirectoryReader, ServiceContext\n\nllm = AzureOpenAI(\n engine="azure-gpt-3.5", # model_name on litellm proxy\n temperature=0.0,\n azure_endpoint="http://0.0.0.0:4000", # litellm proxy endpoint\n api_key="sk-1234", # litellm proxy API Key\n api_version="2023-07-01-preview",\n)\n\nembed_model = AzureOpenAIEmbedding(\n deployment_name="azure-embedding-model",\n azure_endpoint="http://0.0.0.0:4000",\n api_key="sk-1234",\n api_version="2023-07-01-preview",\n)\n\n\ndocuments = SimpleDirectoryReader("llama_index_data").load_data()\nservice_context = ServiceContext.from_defaults(llm=llm, embed_model=embed_model)\nindex = VectorStoreIndex.from_documents(documents, service_context=service_context)\n\nquery_engine = index.as_query_engine()\nresponse = query_engine.query("What did the author do growing up?")\nprint(response)\n\n '})}),(0,l.jsx)(eg.Z,{children:(0,l.jsx)(eS.Z,{language:"python",children:'\nfrom langchain.chat_models import ChatOpenAI\nfrom langchain.prompts.chat import (\n ChatPromptTemplate,\n HumanMessagePromptTemplate,\n SystemMessagePromptTemplate,\n)\nfrom langchain.schema import HumanMessage, SystemMessage\n\nchat = ChatOpenAI(\n openai_api_base="http://0.0.0.0:8000",\n model = "gpt-3.5-turbo",\n temperature=0.1,\n extra_body={\n "metadata": {\n "generation_name": "ishaan-generation-langchain-client",\n "generation_id": "langchain-client-gen-id22",\n "trace_id": "langchain-client-trace-id22",\n "trace_user_id": "langchain-client-user-id2"\n }\n }\n)\n\nmessages = [\n SystemMessage(\n content="You are a helpful assistant that im using to make a test request to."\n ),\n HumanMessage(\n content="test from litellm. tell me why it\'s amazing in 1 sentence"\n ),\n]\nresponse = chat(messages)\n\nprint(response)\n\n '})})]})]})})]})]})})})})},eC=s(33509),eI=s(30569);let{Sider:eP}=eC.default;var eT=e=>{let{setPage:t,userRole:s,defaultSelectedKey:n}=e;return"Admin Viewer"==s?(0,l.jsx)(eC.default,{style:{minHeight:"100vh",maxWidth:"120px"},children:(0,l.jsx)(eP,{width:120,children:(0,l.jsxs)(eI.Z,{mode:"inline",defaultSelectedKeys:n||["4"],style:{height:"100%",borderRight:0},children:[(0,l.jsx)(eI.Z.Item,{onClick:()=>t("api-keys"),children:"API Keys"},"4"),(0,l.jsx)(eI.Z.Item,{onClick:()=>t("models"),children:"Models"},"2"),(0,l.jsx)(eI.Z.Item,{onClick:()=>t("llm-playground"),children:"Chat UI"},"3"),(0,l.jsx)(eI.Z.Item,{onClick:()=>t("usage"),children:"Usage"},"1")]})})}):(0,l.jsx)(eC.default,{style:{minHeight:"100vh",maxWidth:"120px"},children:(0,l.jsx)(eP,{width:120,children:(0,l.jsxs)(eI.Z,{mode:"inline",defaultSelectedKeys:n||["1"],style:{height:"100%",borderRight:0},children:[(0,l.jsx)(eI.Z.Item,{onClick:()=>t("api-keys"),children:"API Keys"},"1"),(0,l.jsx)(eI.Z.Item,{onClick:()=>t("models"),children:"Models"},"2"),(0,l.jsx)(eI.Z.Item,{onClick:()=>t("llm-playground"),children:"Chat UI"},"3"),(0,l.jsx)(eI.Z.Item,{onClick:()=>t("usage"),children:"Usage"},"4"),"Admin"==s?(0,l.jsx)(eI.Z.Item,{onClick:()=>t("users"),children:"Users"},"5"):null,"Admin"==s?(0,l.jsx)(eI.Z.Item,{onClick:()=>t("teams"),children:"Teams"},"6"):null,"Admin"==s?(0,l.jsx)(eI.Z.Item,{onClick:()=>t("admin-panel"),children:"Admin"},"7"):null]})})})},eE=e=>{let{accessToken:t,token:s,userRole:r,userID:a}=e,o=new Date,[i,c]=(0,n.useState)([]),[d,h]=(0,n.useState)([]),[m,u]=(0,n.useState)([]),[x,p]=(0,n.useState)([]),j=new Date(o.getFullYear(),o.getMonth(),1),f=new Date(o.getFullYear(),o.getMonth()+1,0),_=v(j),b=v(f);function v(e){let t=e.getFullYear(),s=e.getMonth()+1,l=e.getDate();return"".concat(t,"-").concat(s<10?"0"+s:s,"-").concat(l<10?"0"+l:l)}return console.log("Start date is ".concat(_)),console.log("End date is ".concat(b)),(0,n.useEffect)(()=>{t&&s&&r&&a&&(async()=>{try{if(console.log("user role: ".concat(r)),"Admin"==r||"Admin Viewer"==r){let e=await Z(t);c(e);let s=(await y(t)).map(e=>({key:(e.key_name||e.key_alias||e.api_key).substring(0,7),spend:e.total_spend}));h(s);let l=(await w(t)).map(e=>({key:e.model,spend:e.total_spend}));u(l)}else"App Owner"==r&&await g(t,s,r,a,_,b).then(async e=>{if(console.log("result from spend logs call",e),"daily_spend"in e){let t=e.daily_spend;console.log("daily spend",t),c(t);let s=e.top_api_keys;h(s)}else{let s=(await k(t,function(e){let t=[];e.forEach(e=>{Object.entries(e).forEach(e=>{let[s,l]=e;"spend"!==s&&"startTime"!==s&&"models"!==s&&"users"!==s&&t.push({key:s,spend:l})})}),t.sort((e,t)=>Number(t.spend)-Number(e.spend));let s=t.slice(0,5).map(e=>e.key);return console.log("topKeys: ".concat(Object.keys(s[0]))),s}(e))).info.map(e=>({key:(e.key_name||e.key_alias||e.token).substring(0,7),spend:e.spend}));h(s),p(function(e){let t={};e.forEach(e=>{Object.entries(e.users).forEach(e=>{let[s,l]=e;""!==s&&null!=s&&"None"!=s&&(t[s]||(t[s]=0),t[s]+=l)})});let s=Object.entries(t).map(e=>{let[t,s]=e;return{user_id:t,spend:s}});s.sort((e,t)=>t.spend-e.spend);let l=s.slice(0,5);return console.log("topKeys: ".concat(Object.values(l[0]))),l}(e)),c(e)}})}catch(e){console.error("There was an error fetching the data",e)}})()},[t,s,r,a,_,b]),(0,l.jsx)("div",{style:{width:"100%"},children:(0,l.jsxs)(E.Z,{numItems:2,className:"gap-2 p-10 h-[75vh] w-full",children:[(0,l.jsx)(T.Z,{numColSpan:2,children:(0,l.jsxs)(F.Z,{children:[(0,l.jsx)(R.Z,{children:"Monthly Spend"}),(0,l.jsx)(Q.Z,{data:i,index:"date",categories:["spend"],colors:["blue"],valueFormatter:e=>"$ ".concat(new Intl.NumberFormat("us").format(e).toString()),yAxisWidth:100,tickGap:5})]})}),(0,l.jsx)(T.Z,{numColSpan:1,children:(0,l.jsxs)(F.Z,{children:[(0,l.jsx)(R.Z,{children:"Top API Keys"}),(0,l.jsx)(Q.Z,{className:"mt-4 h-40",data:d,index:"key",categories:["spend"],colors:["blue"],yAxisWidth:80,tickGap:5,layout:"vertical",showXAxis:!1,showLegend:!1})]})}),(0,l.jsx)(T.Z,{numColSpan:1,children:(0,l.jsxs)(F.Z,{children:[(0,l.jsx)(R.Z,{children:"Top Users"}),(0,l.jsx)(Q.Z,{className:"mt-4 h-40",data:x,index:"user_id",categories:["spend"],colors:["blue"],yAxisWidth:200,layout:"vertical",showXAxis:!1,showLegend:!1})]})}),(0,l.jsx)(T.Z,{numColSpan:1,children:(0,l.jsxs)(F.Z,{children:[(0,l.jsx)(R.Z,{children:"Top Models"}),(0,l.jsx)(Q.Z,{className:"mt-4 h-40",data:m,index:"key",categories:["spend"],colors:["blue"],yAxisWidth:200,layout:"vertical",showXAxis:!1,showLegend:!1})]})})]})})},eF=()=>{let{Title:e,Paragraph:t}=en.default,[s,a]=(0,n.useState)(""),[o,c]=(0,n.useState)(null),[d,h]=(0,n.useState)(null),[m,u]=(0,n.useState)(null),[x,p]=(0,n.useState)(!0),j=(0,r.useSearchParams)(),g=j.get("userID"),Z=j.get("token"),[y,f]=(0,n.useState)("api-keys"),[w,k]=(0,n.useState)(null);return(0,n.useEffect)(()=>{if(Z){let e=(0,ei.o)(Z);if(e){if(console.log("Decoded token:",e),console.log("Decoded key:",e.key),k(e.key),e.user_role){let t=function(e){if(!e)return"Undefined Role";switch(console.log("Received user role: ".concat(e.toLowerCase())),console.log("Received user role length: ".concat(e.toLowerCase().length)),e.toLowerCase()){case"app_owner":case"demo_app_owner":return"App Owner";case"app_admin":case"proxy_admin":return"Admin";case"proxy_admin_viewer":return"Admin Viewer";case"app_user":return"App User";default:return"Unknown Role"}}(e.user_role);console.log("Decoded user_role:",t),a(t),"Admin Viewer"==t&&f("usage")}else console.log("User role not defined");e.user_email?c(e.user_email):console.log("User Email is not set ".concat(e)),e.login_method?p("username_password"==e.login_method):console.log("User Email is not set ".concat(e))}}},[Z]),(0,l.jsx)(n.Suspense,{fallback:(0,l.jsx)("div",{children:"Loading..."}),children:(0,l.jsxs)("div",{className:"flex flex-col min-h-screen",children:[(0,l.jsx)(i,{userID:g,userRole:s,userEmail:o,showSSOBanner:x}),(0,l.jsxs)("div",{className:"flex flex-1 overflow-auto",children:[(0,l.jsx)(eT,{setPage:f,userRole:s,defaultSelectedKey:null}),"api-keys"==y?(0,l.jsx)(ec,{userID:g,userRole:s,teams:d,keys:m,setUserRole:a,userEmail:o,setUserEmail:c,setTeams:h,setKeys:u}):"models"==y?(0,l.jsx)(eu,{userID:g,userRole:s,token:Z,accessToken:w}):"llm-playground"==y?(0,l.jsx)(eA,{userID:g,userRole:s,token:Z,accessToken:w}):"users"==y?(0,l.jsx)(ew,{userID:g,userRole:s,token:Z,keys:m,accessToken:w,setKeys:u}):"teams"==y?(0,l.jsx)(e_,{teams:d,setTeams:h,searchParams:j,accessToken:w}):"admin-panel"==y?(0,l.jsx)(eb,{setTeams:h,searchParams:j,accessToken:w}):(0,l.jsx)(eE,{userID:g,userRole:s,token:Z,accessToken:w})]})]})})}}},function(e){e.O(0,[730,971,69,744],function(){return e(e.s=20661)}),_N_E=e.O()}]);
\ No newline at end of file
diff --git a/ui/litellm-dashboard/out/index.html b/ui/litellm-dashboard/out/index.html
index aaaaa698a..437d90aac 100644
--- a/ui/litellm-dashboard/out/index.html
+++ b/ui/litellm-dashboard/out/index.html
@@ -1 +1 @@
-🚅 LiteLLM
\ No newline at end of file
+🚅 LiteLLM
\ No newline at end of file
diff --git a/ui/litellm-dashboard/out/index.txt b/ui/litellm-dashboard/out/index.txt
index 72b67997a..28c9282be 100644
--- a/ui/litellm-dashboard/out/index.txt
+++ b/ui/litellm-dashboard/out/index.txt
@@ -1,7 +1,7 @@
2:I[77831,[],""]
-3:I[56239,["730","static/chunks/730-1411b729a1c79695.js","931","static/chunks/app/page-37bd7c3d0bb898a3.js"],""]
+3:I[57492,["730","static/chunks/730-1411b729a1c79695.js","931","static/chunks/app/page-2ed0bc91ffef505b.js"],""]
4:I[5613,[],""]
5:I[31778,[],""]
-0:["p1zjZBLDqxGf-NaFvZkeF",[[["",{"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/32e93a3d13512de5.css","precedence":"next","crossOrigin":""}]],"$L6"]]]]
+0:["ZF-EluyKCEJoZptE3dOXT",[[["",{"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/32e93a3d13512de5.css","precedence":"next","crossOrigin":""}]],"$L6"]]]]
6:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"🚅 LiteLLM"}],["$","meta","3",{"name":"description","content":"LiteLLM Proxy Admin UI"}],["$","link","4",{"rel":"icon","href":"/ui/favicon.ico","type":"image/x-icon","sizes":"16x16"}],["$","meta","5",{"name":"next-size-adjust"}]]
1:null
diff --git a/ui/litellm-dashboard/src/components/model_dashboard.tsx b/ui/litellm-dashboard/src/components/model_dashboard.tsx
index ce042c9aa..f18d76e6a 100644
--- a/ui/litellm-dashboard/src/components/model_dashboard.tsx
+++ b/ui/litellm-dashboard/src/components/model_dashboard.tsx
@@ -11,7 +11,8 @@ import {
Metric,
Grid,
} from "@tremor/react";
-import { modelInfoCall, userGetRequesedtModelsCall } from "./networking";
+import { modelInfoCall, userGetRequesedtModelsCall, modelMetricsCall } from "./networking";
+import { BarChart } from "@tremor/react";
import { Badge, BadgeDelta, Button } from "@tremor/react";
import RequestAccess from "./request_model_access";
import { Typography } from "antd";
@@ -30,6 +31,7 @@ const ModelDashboard: React.FC = ({
userID,
}) => {
const [modelData, setModelData] = useState({ data: [] });
+ const [modelMetrics, setModelMetrics] = useState([]);
const [pendingRequests, setPendingRequests] = useState([]);
useEffect(() => {
@@ -47,6 +49,15 @@ const ModelDashboard: React.FC = ({
console.log("Model data response:", modelDataResponse.data);
setModelData(modelDataResponse);
+ const modelMetricsResponse = await modelMetricsCall(
+ accessToken,
+ userID,
+ userRole
+ );
+
+ console.log("Model metrics response:", modelMetricsResponse);
+ setModelMetrics(modelMetricsResponse);
+
// if userRole is Admin, show the pending requests
if (userRole === "Admin" && accessToken) {
const user_requests = await userGetRequesedtModelsCall(accessToken);
@@ -75,8 +86,7 @@ const ModelDashboard: React.FC = ({
// loop through model data and edit each row
for (let i = 0; i < modelData.data.length; i++) {
let curr_model = modelData.data[i];
- let litellm_model_name = curr_model?.litellm_params?.model;
-
+ let litellm_model_name = curr_model?.litellm_params?.mode
let model_info = curr_model?.model_info;
let defaultProvider = "openai";
@@ -109,6 +119,7 @@ const ModelDashboard: React.FC = ({
modelData.data[i].input_cost = input_cost;
modelData.data[i].output_cost = output_cost;
modelData.data[i].max_tokens = max_tokens;
+ modelData.data[i].api_base = curr_model?.litellm_params?.api_base;
all_models_on_proxy.push(curr_model.model_name);
@@ -141,6 +152,14 @@ const ModelDashboard: React.FC = ({
Provider
+ {
+ userRole === "Admin" && (
+
+ API Base
+
+ )
+ }
+
Access
@@ -162,6 +181,11 @@ const ModelDashboard: React.FC = ({
{model.model_name}{model.provider}
+ {
+ userRole === "Admin" && (
+ {model.api_base}
+ )
+ }
{model.user_access ? (
@@ -183,7 +207,18 @@ const ModelDashboard: React.FC = ({
- {userRole === "Admin" &&
+
+ Model Statistics (Number Requests, Latency)
+
+
+ {/* {userRole === "Admin" &&
pendingRequests &&
pendingRequests.length > 0 ? (
@@ -229,7 +264,7 @@ const ModelDashboard: React.FC = ({
- ) : null}
+ ) : null} */}
);
diff --git a/ui/litellm-dashboard/src/components/networking.tsx b/ui/litellm-dashboard/src/components/networking.tsx
index 5993df34c..01cc61f3b 100644
--- a/ui/litellm-dashboard/src/components/networking.tsx
+++ b/ui/litellm-dashboard/src/components/networking.tsx
@@ -242,6 +242,41 @@ export const modelInfoCall = async (
}
};
+
+export const modelMetricsCall = async (
+ accessToken: String,
+ userID: String,
+ userRole: String
+) => {
+ /**
+ * Get all models on proxy
+ */
+ try {
+ let url = proxyBaseUrl ? `${proxyBaseUrl}/model/metrics` : `/model/metrics`;
+ // message.info("Requesting model data");
+ const response = await fetch(url, {
+ method: "GET",
+ headers: {
+ Authorization: `Bearer ${accessToken}`,
+ "Content-Type": "application/json",
+ },
+ });
+
+ if (!response.ok) {
+ const errorData = await response.text();
+ message.error(errorData);
+ throw new Error("Network response was not ok");
+ }
+ const data = await response.json();
+ // message.info("Received model data");
+ return data;
+ // Handle success - you might want to update some state or UI based on the created key
+ } catch (error) {
+ console.error("Failed to create key:", error);
+ throw error;
+ }
+};
+
export const modelAvailableCall = async (
accessToken: String,
userID: String,