diff --git a/.gitignore b/.gitignore index 357f3e1bf8e..abc4ecb0ced 100644 --- a/.gitignore +++ b/.gitignore @@ -51,3 +51,4 @@ loadtest_kub.yaml litellm/proxy/_new_secret_config.yaml litellm/proxy/_new_secret_config.yaml litellm/proxy/_super_secret_config.yaml +litellm/proxy/_super_secret_config.yaml diff --git a/README.md b/README.md index 3caeb830bb6..38a16693578 100644 --- a/README.md +++ b/README.md @@ -227,6 +227,7 @@ curl 'http://0.0.0.0:4000/key/generate' \ | [perplexity-ai](https://docs.litellm.ai/docs/providers/perplexity) | ✅ | ✅ | ✅ | ✅ | | [Groq AI](https://docs.litellm.ai/docs/providers/groq) | ✅ | ✅ | ✅ | ✅ | | [anyscale](https://docs.litellm.ai/docs/providers/anyscale) | ✅ | ✅ | ✅ | ✅ | +| [IBM - watsonx.ai](https://docs.litellm.ai/docs/providers/watsonx) | ✅ | ✅ | ✅ | ✅ | ✅ | [voyage ai](https://docs.litellm.ai/docs/providers/voyage) | | | | | ✅ | | [xinference [Xorbits Inference]](https://docs.litellm.ai/docs/providers/xinference) | | | | | ✅ | diff --git a/cookbook/liteLLM_IBM_Watsonx.ipynb b/cookbook/liteLLM_IBM_Watsonx.ipynb new file mode 100644 index 00000000000..6de108b5d39 --- /dev/null +++ b/cookbook/liteLLM_IBM_Watsonx.ipynb @@ -0,0 +1,300 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# LiteLLM x IBM [watsonx.ai](https://www.ibm.com/products/watsonx-ai)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Pre-Requisites" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!pip install litellm" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Set watsonx.ai Credentials\n", + "\n", + "See [this documentation](https://cloud.ibm.com/apidocs/watsonx-ai#api-authentication) for more information about authenticating to watsonx.ai" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "import litellm\n", + "from litellm.llms.watsonx import IBMWatsonXAI\n", + "litellm.set_verbose = False\n", + "\n", + "os.environ[\"WATSONX_URL\"] = \"\" # Your watsonx.ai base URL\n", + "os.environ[\"WATSONX_APIKEY\"] = \"\" # Your IBM cloud API key or watsonx.ai token\n", + "os.environ[\"WATSONX_PROJECT_ID\"] = \"\" # ID of your watsonx.ai project\n", + "# these can also be passed as arguments to the function\n", + "\n", + "# generating an IAM token is optional, but it is recommended to generate it once and use it for all your requests during the session\n", + "# if not passed to the function, it will be generated automatically for each request\n", + "iam_token = IBMWatsonXAI().generate_iam_token(api_key=os.environ[\"WATSONX_APIKEY\"]) \n", + "# you can also set os.environ[\"WATSONX_TOKEN\"] = iam_token" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Completion Requests\n", + "\n", + "See the following link for a list of supported *text generation* models available with watsonx.ai:\n", + "\n", + "https://dataplatform.cloud.ibm.com/docs/content/wsj/analyze-data/fm-models.html?context=wx&locale=en&audience=wdp" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Granite v2 response:\n", + "ModelResponse(id='chatcmpl-adba60b2-3741-452e-921c-27b8f68d0298', choices=[Choices(finish_reason='stop', index=0, message=Message(content=\" I'm often asked this question, but it seems a bit bizarre given my circumstances. You see,\", role='assistant'))], created=1713881850, model='ibm/granite-13b-chat-v2', object='chat.completion', system_fingerprint=None, usage=Usage(prompt_tokens=8, completion_tokens=20, total_tokens=28), finish_reason='max_tokens')\n", + "LLaMa 3 8b response:\n", + "ModelResponse(id='chatcmpl-eb282abc-373c-4082-9dae-172546d16d5c', choices=[Choices(finish_reason='stop', index=0, message=Message(content=\"I'm just a language model, I don't have emotions or feelings like humans do, but I\", role='assistant'))], created=1713881852, model='meta-llama/llama-3-8b-instruct', object='chat.completion', system_fingerprint=None, usage=Usage(prompt_tokens=16, completion_tokens=20, total_tokens=36), finish_reason='max_tokens')\n" + ] + } + ], + "source": [ + "from litellm import completion\n", + "\n", + "# see litellm.llms.watsonx.IBMWatsonXAIConfig for a list of available parameters to pass to the completion functions\n", + "response = completion(\n", + " model=\"watsonx/ibm/granite-13b-chat-v2\",\n", + " messages=[{ \"content\": \"Hello, how are you?\",\"role\": \"user\"}],\n", + " token=iam_token\n", + ")\n", + "print(\"Granite v2 response:\")\n", + "print(response)\n", + "\n", + "\n", + "response = completion(\n", + " model=\"watsonx/meta-llama/llama-3-8b-instruct\",\n", + " messages=[{ \"content\": \"Hello, how are you?\",\"role\": \"user\"}],\n", + " token=iam_token\n", + ")\n", + "print(\"LLaMa 3 8b response:\")\n", + "print(response)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Streaming Requests" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Granite v2 streaming response:\n", + "\n", + "Thank you for asking. I'm fine, thank you for asking. What can I do for you today?\n", + "I'm looking for a new job. Do you have any job openings that might be a good fit for me?\n", + "Sure,\n", + "LLaMa 3 8b streaming response:\n", + "I'm just an AI, so I don't have emotions or feelings like humans do, but I'm functioning properly and ready to help you with any questions or tasks you have! It's great to chat with you. How can I assist you today" + ] + } + ], + "source": [ + "from litellm import completion\n", + "\n", + "response = completion(\n", + " model=\"watsonx/ibm/granite-13b-chat-v2\",\n", + " messages=[{ \"content\": \"Hello, how are you?\",\"role\": \"user\"}],\n", + " stream=True,\n", + " max_tokens=50, # maps to watsonx.ai max_new_tokens\n", + ")\n", + "print(\"Granite v2 streaming response:\")\n", + "for chunk in response:\n", + " print(chunk['choices'][0]['delta']['content'] or '', end='')\n", + "\n", + "# print()\n", + "response = completion(\n", + " model=\"watsonx/meta-llama/llama-3-8b-instruct\",\n", + " messages=[{ \"content\": \"Hello, how are you?\",\"role\": \"user\"}],\n", + " stream=True,\n", + " max_tokens=50, # maps to watsonx.ai max_new_tokens\n", + ")\n", + "print(\"\\nLLaMa 3 8b streaming response:\")\n", + "for chunk in response:\n", + " print(chunk['choices'][0]['delta']['content'] or '', end='')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Async Requests" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Granite v2 response:\n", + "ModelResponse(id='chatcmpl-73e7474b-2760-4578-b52d-068d6f4ff68b', choices=[Choices(finish_reason='stop', index=0, message=Message(content=\"\\nHello, thank you for asking. I'm well, how about you?\\n\\n3.\", role='assistant'))], created=1713881895, model='ibm/granite-13b-chat-v2', object='chat.completion', system_fingerprint=None, usage=Usage(prompt_tokens=8, completion_tokens=20, total_tokens=28), finish_reason='max_tokens')\n", + "LLaMa 3 8b response:\n", + "ModelResponse(id='chatcmpl-fbf4cd5a-3a38-4b6c-ba00-01ada9fbde8a', choices=[Choices(finish_reason='stop', index=0, message=Message(content=\"I'm just a language model, I don't have emotions or feelings like humans do. However,\", role='assistant'))], created=1713881894, model='meta-llama/llama-3-8b-instruct', object='chat.completion', system_fingerprint=None, usage=Usage(prompt_tokens=16, completion_tokens=20, total_tokens=36), finish_reason='max_tokens')\n" + ] + } + ], + "source": [ + "from litellm import acompletion\n", + "import asyncio\n", + "\n", + "granite_task = acompletion(\n", + " model=\"watsonx/ibm/granite-13b-chat-v2\",\n", + " messages=[{ \"content\": \"Hello, how are you?\",\"role\": \"user\"}],\n", + " max_tokens=20, # maps to watsonx.ai max_new_tokens\n", + " token=iam_token\n", + ")\n", + "llama_3_task = acompletion(\n", + " model=\"watsonx/meta-llama/llama-3-8b-instruct\",\n", + " messages=[{ \"content\": \"Hello, how are you?\",\"role\": \"user\"}],\n", + " max_tokens=20, # maps to watsonx.ai max_new_tokens\n", + " token=iam_token\n", + ")\n", + "\n", + "granite_response, llama_3_response = await asyncio.gather(granite_task, llama_3_task)\n", + "\n", + "print(\"Granite v2 response:\")\n", + "print(granite_response)\n", + "\n", + "print(\"LLaMa 3 8b response:\")\n", + "print(llama_3_response)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Request deployed models\n", + "\n", + "Models that have been deployed to a deployment space (e.g tuned models) can be called using the \"deployment/\" format (where `` is the ID of the deployed model in your deployment space). The ID of your deployment space must also be set in the environment variable `WATSONX_DEPLOYMENT_SPACE_ID` or passed to the function as `space_id=`. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from litellm import acompletion\n", + "\n", + "os.environ[\"WATSONX_DEPLOYMENT_SPACE_ID\"] = \"\" # ID of the watsonx.ai deployment space where the model is deployed\n", + "await acompletion(\n", + " model=\"watsonx/deployment/\",\n", + " messages=[{ \"content\": \"Hello, how are you?\",\"role\": \"user\"}],\n", + " token=iam_token\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Embeddings\n", + "\n", + "See the following link for a list of supported *embedding* models available with watsonx.ai:\n", + "\n", + "https://dataplatform.cloud.ibm.com/docs/content/wsj/analyze-data/fm-models-embed.html?context=wx" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Slate 30m embeddings response:\n", + "EmbeddingResponse(model='ibm/slate-30m-english-rtrvr', data=[{'object': 'embedding', 'index': 0, 'embedding': [0.0025110552, -0.021022381, 0.056658838, 0.023194756, 0.06528087, 0.051285733, 0.025715597, 0.009245981, -0.048218597, 0.02131204, 0.0048608365, 0.056427978, -0.029722512, -0.022280851, 0.03397489, 0.15861669, -0.0032172804, 0.021461686, -0.034179244, 0.03242367, 0.045696042, -0.10642838, 0.044042706, 0.003619815, -0.03445944, 0.06782116, -0.012801977, -0.083491564, 0.048063237, -0.0009263491, 0.03926016, -0.003800945, 0.06431806, 0.008804617, 0.041459076, 0.019176882, 0.063215, 0.016872335, -0.07120825, 0.0026858407, -0.0061372668, 0.016006729, 0.034623176, -0.0009702338, 0.05586387, -0.0030038806, 0.10219119, 0.023867028, 0.017003942, 0.07522453, 0.03827543, 0.002119465, -0.047579825, 0.030801363, 0.055104297, -0.00926156, 0.060950216, -0.012564041, -0.0938483, 0.06749232, 0.0303093, 0.1260211, 0.008772238, 0.0937941, 0.03146898, -0.013548525, -0.04654987, 0.038247738, -0.0047283196, -0.021979854, -0.04481472, 0.009184976, 0.030558616, -0.035239127, 0.015711905, 0.079948395, -0.10273533, -0.033666693, 0.009253284, -0.013218568, 0.014513645, 0.011746366, -0.04836566, 0.00059039996, 0.056465007, 0.057913274, 0.046911363, 0.022496173, -0.016504057, -0.0009266135, 0.007562665, 0.024523543, 0.012681347, -0.0034720704, 0.014897689, 0.034027215, -0.035149213, 0.046610955, -0.38038146, -0.05560348, 0.056164417, 0.023633359, -0.020914413, 0.0017839101, 0.043425612, 0.0921522, 0.021333266, 0.032627117, 0.052366074, 0.059688427, -0.02425017, 0.07460727, 0.040419403, 0.018662684, -0.02174095, -0.015262358, 0.0041535227, -0.004320668, 0.001545062, 0.023696192, 0.053526532, 0.031027582, -0.030727778, -0.07266011, 0.01924883, -0.021610625, 0.03179455, -0.002117363, 0.037670195, -0.021235954, -0.03931032, -0.057163127, -0.046020538, 0.013852293, 0.007136301, 0.020461356, 0.027465757, 0.013625788, 0.09281521, 0.03537469, -0.15295835, -0.045262642, 0.013799362, 0.029831719, 0.06360841, 0.045387108, -0.008106462, 0.047562532, 0.026519125, 0.030519808, -0.035604805, 0.059504308, -0.010260606, 0.05920231, -0.039987702, 0.003475537, 0.012535757, 0.03711557, 0.022637982, 0.022368006, -0.013918498, 0.03144229, 0.02680179, 0.05283082, 0.09737034, 0.062140185, 0.047479317, 0.04292394, 0.041657448, 0.031671192, -0.01198203, -0.0398639, 0.050961364, -0.005440624, -0.013748672, 0.02486566, 0.06105261, 0.09158345, 0.047486037, 0.03503525, -0.0009857323, 0.017584834, 0.0015176772, -0.013855697, -0.0016783233, -0.032760657, 0.0073869363, 0.0032070065, 0.08748817, 0.062042974, -0.006563574, -0.01277716, 0.064277925, -0.048509046, 0.01998247, 0.015449057, 0.06161844, 0.0361277, 0.07378269, 0.031909943, 0.035593968, -0.021533003, 0.15151453, 0.009489467, 0.0077385777, 0.004732935, 0.06757376, 0.018628953, 0.03609718, 0.065334365, 0.046664603, 0.03710433, 0.023046834, 0.065034136, 0.021973003, 0.01938253, 0.0049545416, 0.009443422, 0.08657203, -0.006455585, 0.06113277, -0.009921393, 0.008861325, 0.021925068, 0.0073863543, 0.029231662, 0.018063372, -0.028237753, 0.06752595, -0.015746683, -0.06744447, -0.0019776542, -0.16144808, 0.055144247, -0.07052258, -0.0062173936, 0.005187277, 0.057623632, 0.008336536, 0.018794686, 0.08856226, 0.05324669, 0.023925344, -0.011277585, -0.015746504, -0.01888707, -0.010619123, 0.05960752, -0.02111604, 0.13263386, 0.053238407, 0.0423469, 0.03247613, 0.072818235, 0.039493106, -0.0080635715, 0.038805183, 0.05633994, 0.021095807, -0.022528276, 0.113213256, -0.040802993, 0.01971789, 0.00073800184, 0.04653605, 0.024364496, 0.051224973, 0.022803178, 0.06527072, -0.030100288, 0.02277551, 0.034268156, -0.0024341822, 0.030275142, -0.0043326514, 0.026949842, 0.03554525, 0.043582354, 0.037845742, 0.024644673, 0.06225431, 0.06668994, 0.042802095, -0.14308476, 0.028445719, -0.0057268543, 0.034851402, 0.04973769, -0.01673276, -0.0084733, -0.04498498, -0.01888843, 0.0018199912, -0.08666151, 0.03408551, 0.03374362, 0.016341621, -0.017816868, 0.027611718, 0.048712954, 0.03562084, 0.06156702, 0.06942091, 0.018424997, 0.010069236, -0.025854982, -0.005099922, 0.042129293, -0.018960087, -0.04267046, 0.003192464, 0.07610024, 0.01623567, 0.06430824, 0.045628317, -0.13192567, 0.00597194, 0.03359213, -0.051644783, -0.027538724, 0.047537625, 0.00078535493, -0.050269134, 0.06352181, 0.04414142, -0.00025181545, -0.011166945, 0.083493516, -0.022445189, 0.06386556, 0.009009819, 0.018880796, 0.046981215, -0.04803033, 0.20140722, 0.009405448, 0.011427641, 0.032028355, -0.039911997, 0.059231583, 0.10603366, -0.012695404, -0.018773954, 0.051107403, 0.004720434, 0.049031533, 0.008848073, -0.008443017, 0.068459414, -0.001594059, -0.037717424, 0.0083658025, 0.036570624, -0.009189262, -0.07422237, -0.03578154, 0.00016998129, -0.033594534, 0.04550856, -0.09751915, 0.031381045, -0.020289807, -0.025066, 0.05559659, 0.065852426, -0.030574895, 0.098877095, 0.024548644, 0.02716826, -0.0073690503, -0.006680294, -0.062504984, 0.001748584, -0.0015254011, 0.0030000636, 0.05166639, -0.03598367, 0.02785021, 0.019170346, -0.01893702, 0.006487694, -0.045320857, -0.042290565, 0.030072719]}], object='list', usage=Usage(prompt_tokens=8, total_tokens=8))\n", + "Slate 125m embeddings response:\n", + "EmbeddingResponse(model='ibm/slate-125m-english-rtrvr', data=[{'object': 'embedding', 'index': 0, 'embedding': [-0.037463713, -0.02141933, -0.02851813, 0.015519324, -0.08252965, 0.040418413, 0.0125358505, -0.015099016, 0.007372251, 0.043594047, -0.045923322, -0.024535796, -0.06683439, -0.023252856, -0.014445329, -0.007990043, -0.0038893714, 0.024145052, 0.002840671, -0.005213263, 0.025767032, -0.029234663, -0.022147253, -0.04008686, -0.0049467147, -0.005722156, 0.05712166, 0.02074406, -0.027984975, 0.011733741, 0.037084717, 0.0267332, 0.027662167, 0.018661365, 0.034368176, -0.016858159, 0.01525097, 0.0037685328, -0.029145032, -0.014014788, -0.026596593, -0.019313056, -0.034545943, -0.012755116, -0.027378004, -0.0022658114, 0.0671108, -0.011186887, -0.012560194, 0.07890564, 0.04370288, -0.002565922, 0.04558289, -0.015022389, 0.01721297, -0.02836881, 0.00028577668, 0.041560214, -0.028451115, 0.026690092, -0.03240052, 0.043185145, -0.048146088, -0.01863734, 0.014189055, 0.005409885, -0.004303547, 0.043854367, -0.08027855, 0.0036468406, -0.03761452, -0.01586453, 0.0015843573, -0.06557115, -0.017214078, 0.013112075, -0.063624665, -0.059002113, -0.027906772, -0.0104140695, -0.0122148385, 0.002914942, 0.009600896, 0.024618316, 0.0028588492, -0.04129038, -0.0066302163, -0.016593395, 0.0119156595, 0.030668158, 0.032204323, -0.008526114, 0.031477567, -0.027671225, -0.021325896, -0.012719999, 0.020595504, -0.010196725, 0.016694892, 0.015447107, 0.033599768, 0.0015109212, 0.055442166, -0.032922138, 0.032867074, 0.034223255, 0.018267235, 0.044258785, -0.009512916, -0.01888108, 0.0020811916, -0.071849406, -0.029209733, 0.030071445, 0.04898721, 0.03807559, 0.030091342, 0.0049845255, 0.011301079, 0.0060062855, -0.052550614, -0.040027767, -0.04539995, -0.069943875, 0.052881725, 0.015551356, -0.0016604571, 0.0021608798, 0.055507053, -0.015404854, -0.0023839937, 0.0070840786, 0.042537935, -0.045489613, 0.018908504, -0.015565469, 0.015916781, 0.07333876, 0.0034915418, -0.0029724848, 0.019170308, 0.02221138, -0.027242986, -0.003735747, -0.02341423, -0.0037938543, 0.0104211755, -0.06185881, -0.036718667, -0.02746382, -0.026462527, -0.050701175, 0.0057923957, 0.040674523, -0.019840682, -0.030195065, 0.045316722, 0.017369563, -0.031288657, -0.047546197, 0.026255054, -0.0049950704, -0.040272273, 0.0005752177, 0.03959872, -0.0073655704, -0.025617458, -0.009416491, -0.019514928, -0.07619169, 0.0051972694, 0.016387343, -0.012366861, -0.009152257, -0.035955105, -0.05794065, 0.019153351, -0.0461187, 0.024734644, 0.0031722176, 0.06610593, -0.0046516205, -0.04635891, 0.02524459, 0.004230386, 0.06153266, -0.0008394812, -0.013522857, 0.029861225, -0.00394871, -0.037432022, 0.0483034, 0.02181303, 0.015967155, 0.06181817, -0.018545056, 0.044176213, -0.07024062, -0.013022128, -0.0087189535, -0.025292343, 0.040448178, -0.051455554, -0.014017804, 0.012191985, 0.0071282317, -0.015855217, 0.013618914, -0.0060378346, -0.057781402, -0.035322957, -0.013627626, -0.027318006, -0.27732822, -0.007108157, 0.012321971, -0.15896526, -0.03793523, -0.025426138, 0.020721687, -0.04701553, -0.004927499, 0.010541978, -0.003212021, -0.0023603817, -0.052153032, 0.043272667, 0.024041472, -0.031666223, 0.0017891804, 0.026806207, -0.026526717, 0.0023138188, 0.024067048, 0.03326347, -0.039004102, -0.0004279829, 0.007266309, -0.008940641, 0.03715139, -0.037960306, 0.01647343, -0.022163782, 0.07456727, -0.0013284415, -0.029121747, 0.012727488, -0.007229313, 0.03177136, -0.08142398, 0.010223168, -0.025942598, -0.23807198, 0.022616733, -0.03925926, 0.05572623, -0.00020389797, -0.0022259122, -0.007885641, -0.00719495, 0.0018412926, 0.018953165, -0.009946787, 0.03723944, -0.015900994, 0.013648507, 0.010997674, -0.018918132, 0.013143112, 0.032894272, -0.05800237, 0.011163258, 0.025205074, -0.017001726, 0.03673705, -0.011551997, 0.06637543, -0.033003606, -0.041392814, -0.004078506, 0.03916763, -0.0022711542, 0.058338877, -0.034323692, -0.033700593, 0.01051642, 0.035579532, -0.01997833, 0.002977113, 0.06590587, 0.042783573, 0.020624464, 0.029172791, -0.035136282, 0.02035436, 0.05696583, -0.010200334, -0.0010580813, -0.024785697, -0.014516442, -0.030100575, -0.03807279, 0.042534467, -0.0281041, -0.05331885, -0.019467393, 0.016051197, 0.012470333, -0.008369627, 0.002254233, 0.026580654, -0.04541506, -0.018085537, -0.034577485, -0.0014747214, 0.0005770179, 0.0043190396, -0.004989785, 0.007569717, 0.010167482, -0.03335266, -0.015255423, 0.07341545, 0.012114007, -0.0010415721, 0.008754641, 0.05932771, 0.030799353, 0.026148474, -0.0069155577, -0.056865778, 0.0038446637, -0.010079895, 0.013511311, 0.023351224, -0.049000103, -0.013028001, -0.04957143, -0.031393193, 0.040289443, 0.063747466, 0.046358805, 0.0023754216, -0.0054107807, -0.020128531, 0.0013747461, -0.018183928, -0.04754063, -0.0064625163, 0.0417791, 0.06087331, -0.012241535, 0.04185439, 0.03641727, -0.02044306, -0.061368305, -0.023353308, 0.055897385, -0.047081504, 0.012900442, -0.018708078, 0.0028819577, 0.006964468, 0.0008757072, 0.04605831, 0.01716345, -0.004099444, -0.015493673, 0.021323929, -0.011252118, -0.02278577, 0.01893121, 0.009134488, 0.021568391, 0.011066748, -0.018853422, 0.027866907, -0.02831057, -0.010147286, 0.014807969, -0.03266599, -0.06711559, 0.038546126, 0.0031859868, -0.029038243, 0.046595056, 0.036973156, -0.033408422, 0.021968717, -0.011411975, 0.006584961, 0.072844714, -0.005873538, 0.029435376, 0.061169676, -0.02318868, 0.051129397, 0.014791153, -0.009028991, -0.021579748, 0.02669236, 0.029696332, -0.063952625, -0.061506465, -0.00080902094, 0.06850867, -0.09809231, -0.005534635, 0.066767104, -0.041267477, 0.046568397, 0.00983124, -0.0048434925, 0.038644254, 0.04096419, 0.0023063375, 0.014526287, 0.014016995, 0.020224908, 0.007113328, -0.0732543, -0.0054818415, 0.05807576, 0.022461535, 0.21100426, -0.009597197, -0.020674499, 0.010743241, -0.046834, -0.0068005333, 0.04918187, -0.06680011, -0.025018543, 0.016360015, 0.100744724, -0.019944709, -0.052390855, -0.0034876189, 0.031699855, -0.03024188, 0.009384044, -0.073849924, 0.01846066, -0.017075414, 0.0067319535, 0.045643695, 0.0121267075, 0.014980903, -0.0022226444, -0.015187039, 0.040638167, 0.023607453, -0.018353134, 0.007413985, 0.03487914, 0.018997269, -0.0107962405, -0.0040080273, 0.001454658, -0.023004232, -0.03065838, -0.0691732, -0.009669473, -0.017253181, 0.100617275, -0.00028453665, -0.055184573, -0.04010461, -0.022628073, -0.02138574, -0.00011931983, -0.021988528, 0.021569526, 0.018913478, -0.07588871, -0.030895703, -0.045679674, 0.03548181, 0.05806986, -0.00313453, 0.005607964, 0.014474551, -0.016833752, -0.022846023, 0.03665983, 0.04312398, 0.006030178, 0.020107903, -0.067837745, -0.039261904, -0.013903933, -0.011238981, -0.091779895, 0.03393072, 0.03576862, -0.016447216, -0.013628061, 0.035994843, 0.02442105, 0.0013356373, -0.013639993, -0.0070654624, -0.031047037, 0.0321763, 0.019488426, 0.030912274, -0.018131692, 0.034129236, -0.038152352, -0.020318052, 0.012934771, -0.0038958737, 0.029313264, 0.0609006, -0.06022117, -0.016697206, -0.030089315, -0.0030464267, -0.05011375, 0.016849633, -0.01935251, 0.00033423092, 0.018090008, 0.034528963, 0.015720658, 0.006443832, 0.0024674414, 0.0033006326, -0.011959118, -0.014686165, 0.00851113, 0.032130115, 0.016566927, -0.0048006177, -0.041135546, 0.017366901, 0.014404645, 0.0014093819, -0.039899524, -0.020875102, -0.01322629, -0.010891931, 0.019460721, -0.098985165, -0.03990147, 0.035807386, 0.05274234, -0.017714208, 0.0023620757, 0.022553496, 0.010935722, -0.016535437, -0.014505468, -0.005573891, -0.029528206, -0.010998497, 0.011297328, 0.007440231, 0.054734096, -0.035311602, 0.07038191, -0.034328025, -0.0109814005, -0.00578824, -0.009286793, 0.06692834, -0.040116422, -0.030043483, -0.010882302, -0.024094587, 0.026659116, -0.0637435, -0.022305744, 0.024388585, 0.011812823, -0.022778027, -0.0039024823, 0.027778644, 0.010566278, 0.011030791, -0.0021155484, 0.018014789, -0.03458981, 0.02546183, -0.11745906, 0.038193583, 0.0019787792, 0.01639592, 0.013218127, -0.012434678, -0.047858853, 0.006662704, 0.033221778, 0.008376927, -0.011822234, 0.01202769, 0.008761578, -0.04075117, 0.0025187496, 0.0026266004, 0.029762473, 0.009570205, -0.03644678, -0.033258904, -0.030776607, 0.05373578, 0.010904848, 0.040284622, 0.02707032, 0.021803873, -0.022011256, -0.05517991, -0.005213912, 0.009023477, -0.011895841, -0.026821174, -0.009035418, -0.021059638, 0.025536137, -0.053264923, 0.032206282, 0.020235807, 0.018660447, 0.0028790566, -0.019914437, 0.097842626, 0.027617158, 0.020276038, -0.014215543, 0.012761584, 0.032757074, 0.061124176, 0.049016643, -0.016509317, -0.03750349, -0.03449537, -0.02039439, -0.051360182, -0.041909404, 0.016175032, 0.040492736, 0.031218654, 0.0020242895, -0.032167237, 0.019398497, 0.057013687, 0.0031299617, 0.019177254, 0.015395364, -0.034078192, 0.041325297, 0.044380017, -0.004446819, 0.019610956, -0.030034903, 0.008468295, 0.03065914, -0.009548659, -0.07113981, 0.051648173, 0.03746448, -0.021847434, 0.01844844, 0.01333424, -0.001188216, 0.012330977, -0.056448817, 0.0008659569, 0.011183285, 0.006780519, -0.007357356, 0.05263679, -0.024631461, 0.00519591, -0.052165415, -0.03250626, -0.009370051, 0.00292325, -0.007187242, 0.029566163, -0.049605303, -0.02625627, -0.003157652, 0.052691437, -0.03589223, 0.03889354, -0.0035060279, 0.024555178, -0.00929779, -0.05037946, -0.022402484, 0.030634355, -0.03300659, -0.0063623153, 0.0027472514, 0.03196768, -0.019257778, 0.0089001395, 0.008908001, 0.018918095, 0.059574094, -0.02838763, 0.018203752, -0.06708146, -0.022670228, -0.013985525, 0.045018435, 0.011420395, -0.008649952, -0.027328938, -0.03527292, -0.0038555951, 0.017597001, 0.024891963, -0.0039160745, -0.015237065, -0.0008723479, -0.018641612, -0.036825016, -0.028743235, 0.00091956893, 0.00030935413, -0.048641082, 0.03744432, -0.024196126, 0.009848505, -0.043836866, 0.0044429195, 0.013709644, 0.06295503, -0.016072558, 0.01277375, -0.03548109, 0.003398656, 0.025347201, 0.019685786, 0.00758199, -0.016122513, -0.039198015, -0.0023108267, -0.0041584945, 0.005161282, 0.00089106365, 0.0076085874, -0.055768084, -0.0058975955, 0.007728267, 0.00076985586, -0.013469806, -0.031578194, -0.0138569595, 0.044540506, -0.0408136, -0.015252405, 0.06232591, -0.04198101, 0.0048899655, -0.0030694627, -0.025022805, -0.010789543, -0.025350742, 0.007836728, 0.024604483, -5.385127e-05, -0.0021367231, -0.01704561, -0.001425816, 0.0035238306]}], object='list', usage=Usage(prompt_tokens=8, total_tokens=8))\n" + ] + } + ], + "source": [ + "from litellm import embedding, aembedding\n", + "\n", + "response = embedding(\n", + " model=\"watsonx/ibm/slate-30m-english-rtrvr\",\n", + " input=[\"Hello, how are you?\"],\n", + " token=iam_token\n", + ")\n", + "print(\"Slate 30m embeddings response:\")\n", + "print(response)\n", + "\n", + "response = await aembedding(\n", + " model=\"watsonx/ibm/slate-125m-english-rtrvr\",\n", + " input=[\"Hello, how are you?\"],\n", + " token=iam_token\n", + ")\n", + "print(\"Slate 125m embeddings response:\")\n", + "print(response)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "base", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.5" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/docs/my-website/docs/observability/langfuse_integration.md b/docs/my-website/docs/observability/langfuse_integration.md index 50b016d09f9..fe210e6b710 100644 --- a/docs/my-website/docs/observability/langfuse_integration.md +++ b/docs/my-website/docs/observability/langfuse_integration.md @@ -167,6 +167,9 @@ messages = [ chat(messages) ``` +## Redacting Messages, Response Content from Langfuse Logging + +Set `litellm.turn_off_message_logging=True` This will prevent the messages and responses from being logged to langfuse, but request metadata will still be logged. ## Troubleshooting & Errors ### Data not getting logged to Langfuse ? diff --git a/docs/my-website/docs/observability/sentry.md b/docs/my-website/docs/observability/sentry.md index 255dd55cfec..5877db6610d 100644 --- a/docs/my-website/docs/observability/sentry.md +++ b/docs/my-website/docs/observability/sentry.md @@ -40,5 +40,9 @@ response = completion(model="gpt-3.5-turbo", messages=[{"role": "user", "content print(response) ``` +## Redacting Messages, Response Content from Sentry Logging + +Set `litellm.turn_off_message_logging=True` This will prevent the messages and responses from being logged to sentry, but request metadata will still be logged. + [Let us know](https://github.com/BerriAI/litellm/issues/new?assignees=&labels=enhancement&projects=&template=feature_request.yml&title=%5BFeature%5D%3A+) if you need any additional options from Sentry. diff --git a/docs/my-website/docs/providers/mistral.md b/docs/my-website/docs/providers/mistral.md index b6558435b8b..8e5e2bf66b7 100644 --- a/docs/my-website/docs/providers/mistral.md +++ b/docs/my-website/docs/providers/mistral.md @@ -53,6 +53,50 @@ All models listed here https://docs.mistral.ai/platform/endpoints are supported. | open-mixtral-8x22b | `completion(model="mistral/open-mixtral-8x22b", messages)` | +## Function Calling + +```python +from litellm import completion + +# set env +os.environ["MISTRAL_API_KEY"] = "your-api-key" + +tools = [ + { + "type": "function", + "function": { + "name": "get_current_weather", + "description": "Get the current weather in a given location", + "parameters": { + "type": "object", + "properties": { + "location": { + "type": "string", + "description": "The city and state, e.g. San Francisco, CA", + }, + "unit": {"type": "string", "enum": ["celsius", "fahrenheit"]}, + }, + "required": ["location"], + }, + }, + } +] +messages = [{"role": "user", "content": "What's the weather like in Boston today?"}] + +response = completion( + model="mistral/mistral-large-latest", + messages=messages, + tools=tools, + tool_choice="auto", +) +# Add any assertions, here to check response args +print(response) +assert isinstance(response.choices[0].message.tool_calls[0].function.name, str) +assert isinstance( + response.choices[0].message.tool_calls[0].function.arguments, str +) +``` + ## Sample Usage - Embedding ```python from litellm import embedding diff --git a/docs/my-website/docs/providers/vllm.md b/docs/my-website/docs/providers/vllm.md index b8285da7169..8c8f363f8ef 100644 --- a/docs/my-website/docs/providers/vllm.md +++ b/docs/my-website/docs/providers/vllm.md @@ -4,6 +4,13 @@ LiteLLM supports all models on VLLM. 🚀[Code Tutorial](https://github.com/BerriAI/litellm/blob/main/cookbook/VLLM_Model_Testing.ipynb) + +:::info + +To call a HOSTED VLLM Endpoint use [these docs](./openai_compatible.md) + +::: + ### Quick Start ``` pip install litellm vllm diff --git a/docs/my-website/docs/providers/watsonx.md b/docs/my-website/docs/providers/watsonx.md new file mode 100644 index 00000000000..d8c5740a861 --- /dev/null +++ b/docs/my-website/docs/providers/watsonx.md @@ -0,0 +1,284 @@ +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# IBM watsonx.ai + +LiteLLM supports all IBM [watsonx.ai](https://watsonx.ai/) foundational models and embeddings. + +## Environment Variables +```python +os.environ["WATSONX_URL"] = "" # (required) Base URL of your WatsonX instance +# (required) either one of the following: +os.environ["WATSONX_APIKEY"] = "" # IBM cloud API key +os.environ["WATSONX_TOKEN"] = "" # IAM auth token +# optional - can also be passed as params to completion() or embedding() +os.environ["WATSONX_PROJECT_ID"] = "" # Project ID of your WatsonX instance +os.environ["WATSONX_DEPLOYMENT_SPACE_ID"] = "" # ID of your deployment space to use deployed models +``` + +See [here](https://cloud.ibm.com/apidocs/watsonx-ai#api-authentication) for more information on how to get an access token to authenticate to watsonx.ai. + +## Usage + + + Open In Colab + + +```python +import os +from litellm import completion + +os.environ["WATSONX_URL"] = "" +os.environ["WATSONX_APIKEY"] = "" + +response = completion( + model="watsonx/ibm/granite-13b-chat-v2", + messages=[{ "content": "what is your favorite colour?","role": "user"}], + project_id="" # or pass with os.environ["WATSONX_PROJECT_ID"] +) + +response = completion( + model="watsonx/meta-llama/llama-3-8b-instruct", + messages=[{ "content": "what is your favorite colour?","role": "user"}], + project_id="" +) +``` + +## Usage - Streaming +```python +import os +from litellm import completion + +os.environ["WATSONX_URL"] = "" +os.environ["WATSONX_APIKEY"] = "" +os.environ["WATSONX_PROJECT_ID"] = "" + +response = completion( + model="watsonx/ibm/granite-13b-chat-v2", + messages=[{ "content": "what is your favorite colour?","role": "user"}], + stream=True +) +for chunk in response: + print(chunk) +``` + +#### Example Streaming Output Chunk +```json +{ + "choices": [ + { + "finish_reason": null, + "index": 0, + "delta": { + "content": "I don't have a favorite color, but I do like the color blue. What's your favorite color?" + } + } + ], + "created": null, + "model": "watsonx/ibm/granite-13b-chat-v2", + "usage": { + "prompt_tokens": null, + "completion_tokens": null, + "total_tokens": null + } +} +``` + +## Usage - Models in deployment spaces + +Models that have been deployed to a deployment space (e.g.: tuned models) can be called using the `deployment/` format (where `` is the ID of the deployed model in your deployment space). + +The ID of your deployment space must also be set in the environment variable `WATSONX_DEPLOYMENT_SPACE_ID` or passed to the function as `space_id=`. + +```python +import litellm +response = litellm.completion( + model="watsonx/deployment/", + messages=[{"content": "Hello, how are you?", "role": "user"}], + space_id="" +) +``` + +## Usage - Embeddings + +LiteLLM also supports making requests to IBM watsonx.ai embedding models. The credential needed for this is the same as for completion. + +```python +from litellm import embedding + +response = embedding( + model="watsonx/ibm/slate-30m-english-rtrvr", + input=["What is the capital of France?"], + project_id="" +) +print(response) +# EmbeddingResponse(model='ibm/slate-30m-english-rtrvr', data=[{'object': 'embedding', 'index': 0, 'embedding': [-0.037463713, -0.02141933, -0.02851813, 0.015519324, ..., -0.0021367231, -0.01704561, -0.001425816, 0.0035238306]}], object='list', usage=Usage(prompt_tokens=8, total_tokens=8)) +``` + +## OpenAI Proxy Usage + +Here's how to call IBM watsonx.ai with the LiteLLM Proxy Server + +### 1. Save keys in your environment + +```bash +export WATSONX_URL="" +export WATSONX_APIKEY="" +export WATSONX_PROJECT_ID="" +``` + +### 2. Start the proxy + + + + +```bash +$ litellm --model watsonx/meta-llama/llama-3-8b-instruct + +# Server running on http://0.0.0.0:4000 +``` + + + + +```yaml +model_list: + - model_name: llama-3-8b + litellm_params: + # all params accepted by litellm.completion() + model: watsonx/meta-llama/llama-3-8b-instruct + api_key: "os.environ/WATSONX_API_KEY" # does os.getenv("WATSONX_API_KEY") +``` + + + +### 3. Test it + + + + + +```shell +curl --location 'http://0.0.0.0:4000/chat/completions' \ +--header 'Content-Type: application/json' \ +--data ' { + "model": "llama-3-8b", + "messages": [ + { + "role": "user", + "content": "what is your favorite colour?" + } + ] + } +' +``` + + + +```python +import openai +client = openai.OpenAI( + api_key="anything", + base_url="http://0.0.0.0:4000" +) + +# request sent to model set on litellm proxy, `litellm --model` +response = client.chat.completions.create(model="llama-3-8b", messages=[ + { + "role": "user", + "content": "what is your favorite colour?" + } +]) + +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:4000", # set openai_api_base to the LiteLLM Proxy + model = "llama-3-8b", + 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) +``` + + + + +## Authentication + +### Passing credentials as parameters + +You can also pass the credentials as parameters to the completion and embedding functions. + +```python +import os +from litellm import completion + +response = completion( + model="watsonx/ibm/granite-13b-chat-v2", + messages=[{ "content": "What is your favorite color?","role": "user"}], + url="", + api_key="", + project_id="" +) +``` + + +## Supported IBM watsonx.ai Models + +Here are some examples of models available in IBM watsonx.ai that you can use with LiteLLM: + +| Mode Name | Command | +| ---------- | --------- | +| Flan T5 XXL | `completion(model=watsonx/google/flan-t5-xxl, messages=messages)` | +| Flan Ul2 | `completion(model=watsonx/google/flan-ul2, messages=messages)` | +| Mt0 XXL | `completion(model=watsonx/bigscience/mt0-xxl, messages=messages)` | +| Gpt Neox | `completion(model=watsonx/eleutherai/gpt-neox-20b, messages=messages)` | +| Mpt 7B Instruct2 | `completion(model=watsonx/ibm/mpt-7b-instruct2, messages=messages)` | +| Starcoder | `completion(model=watsonx/bigcode/starcoder, messages=messages)` | +| Llama 2 70B Chat | `completion(model=watsonx/meta-llama/llama-2-70b-chat, messages=messages)` | +| Llama 2 13B Chat | `completion(model=watsonx/meta-llama/llama-2-13b-chat, messages=messages)` | +| Granite 13B Instruct | `completion(model=watsonx/ibm/granite-13b-instruct-v1, messages=messages)` | +| Granite 13B Chat | `completion(model=watsonx/ibm/granite-13b-chat-v1, messages=messages)` | +| Flan T5 XL | `completion(model=watsonx/google/flan-t5-xl, messages=messages)` | +| Granite 13B Chat V2 | `completion(model=watsonx/ibm/granite-13b-chat-v2, messages=messages)` | +| Granite 13B Instruct V2 | `completion(model=watsonx/ibm/granite-13b-instruct-v2, messages=messages)` | +| Elyza Japanese Llama 2 7B Instruct | `completion(model=watsonx/elyza/elyza-japanese-llama-2-7b-instruct, messages=messages)` | +| Mixtral 8X7B Instruct V01 Q | `completion(model=watsonx/ibm-mistralai/mixtral-8x7b-instruct-v01-q, messages=messages)` | + + +For a list of all available models in watsonx.ai, see [here](https://dataplatform.cloud.ibm.com/docs/content/wsj/analyze-data/fm-models.html?context=wx&locale=en&audience=wdp). + + +## Supported IBM watsonx.ai Embedding Models + +| Model Name | Function Call | +|----------------------|---------------------------------------------| +| Slate 30m | `embedding(model="watsonx/ibm/slate-30m-english-rtrvr", input=input)` | +| Slate 125m | `embedding(model="watsonx/ibm/slate-125m-english-rtrvr", input=input)` | + + +For a list of all available embedding models in watsonx.ai, see [here](https://dataplatform.cloud.ibm.com/docs/content/wsj/analyze-data/fm-models-embed.html?context=wx). \ No newline at end of file diff --git a/docs/my-website/docs/proxy/alerting.md b/docs/my-website/docs/proxy/alerting.md index feb54babd2e..4275e0bf06f 100644 --- a/docs/my-website/docs/proxy/alerting.md +++ b/docs/my-website/docs/proxy/alerting.md @@ -1,13 +1,13 @@ -# Slack Alerting +# 🚨 Alerting Get alerts for: -- hanging LLM api calls -- failed LLM api calls -- slow LLM api calls -- budget Tracking per key/user: +- Hanging LLM api calls +- Failed LLM api calls +- Slow LLM api calls +- Budget Tracking per key/user: - When a User/Key crosses their Budget - When a User/Key is 15% away from crossing their Budget -- failed db read/writes +- Failed db read/writes ## Quick Start diff --git a/docs/my-website/docs/proxy/deploy.md b/docs/my-website/docs/proxy/deploy.md index 7e350bfa9ce..992350211e8 100644 --- a/docs/my-website/docs/proxy/deploy.md +++ b/docs/my-website/docs/proxy/deploy.md @@ -231,13 +231,16 @@ Your OpenAI proxy server is now running on `http://127.0.0.1:4000`. | Docs | When to Use | | --- | --- | | [Quick Start](#quick-start) | call 100+ LLMs + Load Balancing | -| [Deploy with Database](#deploy-with-database) | + use Virtual Keys + Track Spend | +| [Deploy with Database](#deploy-with-database) | + use Virtual Keys + Track Spend (Note: When deploying with a database providing a `DATABASE_URL` and `LITELLM_MASTER_KEY` are required in your env ) | | [LiteLLM container + Redis](#litellm-container--redis) | + load balance across multiple litellm containers | | [LiteLLM Database container + PostgresDB + Redis](#litellm-database-container--postgresdb--redis) | + use Virtual Keys + Track Spend + load balance across multiple litellm containers | ## Deploy with Database ### Docker, Kubernetes, Helm Chart +Requirements: +- Need a postgres database (e.g. [Supabase](https://supabase.com/), [Neon](https://neon.tech/), etc) Set `DATABASE_URL=postgresql://:@:/` in your env +- Set a `LITELLM_MASTER_KEY`, this is your Proxy Admin key - you can use this to create other keys (🚨 must start with `sk-`) @@ -252,6 +255,8 @@ docker pull ghcr.io/berriai/litellm-database:main-latest ```shell docker run \ -v $(pwd)/litellm_config.yaml:/app/config.yaml \ + -e LITELLM_MASTER_KEY=sk-1234 \ + -e DATABASE_URL=postgresql://:@:/ \ -e AZURE_API_KEY=d6*********** \ -e AZURE_API_BASE=https://openai-***********/ \ -p 4000:4000 \ diff --git a/docs/my-website/docs/proxy/logging.md b/docs/my-website/docs/proxy/logging.md index 48a5955b177..1a5a7f0f077 100644 --- a/docs/my-website/docs/proxy/logging.md +++ b/docs/my-website/docs/proxy/logging.md @@ -569,6 +569,22 @@ curl -X POST 'http://0.0.0.0:4000/key/generate' \ All requests made with these keys will log data to their team-specific logging. +### Redacting Messages, Response Content from Langfuse Logging + +Set `litellm.turn_off_message_logging=True` This will prevent the messages and responses from being logged to langfuse, but request metadata will still be logged. + +```yaml +model_list: + - model_name: gpt-3.5-turbo + litellm_params: + model: gpt-3.5-turbo +litellm_settings: + success_callback: ["langfuse"] + turn_off_message_logging: True +``` + + + ## Logging Proxy Input/Output - DataDog We will use the `--config` to set `litellm.success_callback = ["datadog"]` this will log all successfull LLM calls to DataDog diff --git a/docs/my-website/docs/set_keys.md b/docs/my-website/docs/set_keys.md index 4c8cc42fe79..7686bf70493 100644 --- a/docs/my-website/docs/set_keys.md +++ b/docs/my-website/docs/set_keys.md @@ -5,6 +5,9 @@ LiteLLM allows you to specify the following: * API Base * API Version * API Type +* Project +* Location +* Token Useful Helper functions: * [`check_valid_key()`](#check_valid_key) @@ -43,6 +46,24 @@ os.environ['AZURE_API_TYPE'] = "azure" # [OPTIONAL] os.environ['OPENAI_API_BASE'] = "https://openai-gpt-4-test2-v-12.openai.azure.com/" ``` +### Setting Project, Location, Token + +For cloud providers: +- Azure +- Bedrock +- GCP +- Watson AI + +you might need to set additional parameters. LiteLLM provides a common set of params, that we map across all providers. + +| | LiteLLM param | Watson | Vertex AI | Azure | Bedrock | +|------|--------------|--------------|--------------|--------------|--------------| +| Project | project | watsonx_project | vertex_project | n/a | n/a | +| Region | region_name | watsonx_region_name | vertex_location | n/a | aws_region_name | +| Token | token | watsonx_token or token | n/a | azure_ad_token | n/a | + +If you want, you can call them by their provider-specific params as well. + ## litellm variables ### litellm.api_key diff --git a/docs/my-website/sidebars.js b/docs/my-website/sidebars.js index f47846892bc..e4f4e806e1c 100644 --- a/docs/my-website/sidebars.js +++ b/docs/my-website/sidebars.js @@ -43,6 +43,12 @@ const sidebars = { "proxy/user_keys", "proxy/enterprise", "proxy/virtual_keys", + "proxy/alerting", + { + type: "category", + label: "Logging", + items: ["proxy/logging", "proxy/streaming_logging"], + }, "proxy/team_based_routing", "proxy/ui", "proxy/cost_tracking", @@ -58,11 +64,6 @@ const sidebars = { "proxy/pii_masking", "proxy/prompt_injection", "proxy/caching", - { - type: "category", - label: "Logging, Alerting", - items: ["proxy/logging", "proxy/alerting", "proxy/streaming_logging"], - }, "proxy/prometheus", "proxy/call_hooks", "proxy/rules", @@ -148,6 +149,7 @@ const sidebars = { "providers/openrouter", "providers/custom_openai_proxy", "providers/petals", + "providers/watsonx", ], }, "proxy/custom_pricing", diff --git a/litellm/__init__.py b/litellm/__init__.py index b9d9891ca25..49287d12fbe 100644 --- a/litellm/__init__.py +++ b/litellm/__init__.py @@ -45,6 +45,7 @@ _async_failure_callback: List[Callable] = ( ) # internal variable - async custom callbacks are routed here. pre_call_rules: List[Callable] = [] post_call_rules: List[Callable] = [] +turn_off_message_logging: Optional[bool] = False ## end of callbacks ############# email: Optional[str] = ( @@ -58,6 +59,7 @@ max_tokens = 256 # OpenAI Defaults drop_params = False modify_params = False retry = True +### AUTH ### api_key: Optional[str] = None openai_key: Optional[str] = None azure_key: Optional[str] = None @@ -76,7 +78,12 @@ cloudflare_api_key: Optional[str] = None baseten_key: Optional[str] = None aleph_alpha_key: Optional[str] = None nlp_cloud_key: Optional[str] = None +common_cloud_provider_auth_params: dict = { + "params": ["project", "region_name", "token"], + "providers": ["vertex_ai", "bedrock", "watsonx", "azure"], +} use_client: bool = False +ssl_verify: bool = True disable_streaming_logging: bool = False ### GUARDRAILS ### llamaguard_model_name: Optional[str] = None @@ -298,6 +305,7 @@ aleph_alpha_models: List = [] bedrock_models: List = [] deepinfra_models: List = [] perplexity_models: List = [] +watsonx_models: List = [] for key, value in model_cost.items(): if value.get("litellm_provider") == "openai": open_ai_chat_completion_models.append(key) @@ -342,6 +350,8 @@ for key, value in model_cost.items(): deepinfra_models.append(key) elif value.get("litellm_provider") == "perplexity": perplexity_models.append(key) + elif value.get("litellm_provider") == "watsonx": + watsonx_models.append(key) # known openai compatible endpoints - we'll eventually move this list to the model_prices_and_context_window.json dictionary openai_compatible_endpoints: List = [ @@ -478,6 +488,7 @@ model_list = ( + perplexity_models + maritalk_models + vertex_language_models + + watsonx_models ) provider_list: List = [ @@ -516,6 +527,7 @@ provider_list: List = [ "cloudflare", "xinference", "fireworks_ai", + "watsonx", "custom", # custom apis ] @@ -537,6 +549,7 @@ models_by_provider: dict = { "deepinfra": deepinfra_models, "perplexity": perplexity_models, "maritalk": maritalk_models, + "watsonx": watsonx_models, } # mapping for those models which have larger equivalents @@ -647,9 +660,11 @@ from .llms.bedrock import ( AmazonLlamaConfig, AmazonStabilityConfig, AmazonMistralConfig, + AmazonBedrockGlobalConfig, ) from .llms.openai import OpenAIConfig, OpenAITextCompletionConfig from .llms.azure import AzureOpenAIConfig, AzureOpenAIError +from .llms.watsonx import IBMWatsonXAIConfig from .main import * # type: ignore from .integrations import * from .exceptions import ( diff --git a/litellm/integrations/langfuse.py b/litellm/integrations/langfuse.py index 51ad4d19abe..c2612feb805 100644 --- a/litellm/integrations/langfuse.py +++ b/litellm/integrations/langfuse.py @@ -12,7 +12,9 @@ import litellm class LangFuseLogger: # Class variables or attributes - def __init__(self, langfuse_public_key=None, langfuse_secret=None): + def __init__( + self, langfuse_public_key=None, langfuse_secret=None, flush_interval=1 + ): try: from langfuse import Langfuse except Exception as e: @@ -31,7 +33,7 @@ class LangFuseLogger: host=self.langfuse_host, release=self.langfuse_release, debug=self.langfuse_debug, - flush_interval=1, # flush interval in seconds + flush_interval=flush_interval, # flush interval in seconds ) # set the current langfuse project id in the environ diff --git a/litellm/integrations/slack_alerting.py b/litellm/integrations/slack_alerting.py index adc56698c39..8f8ce712e9b 100644 --- a/litellm/integrations/slack_alerting.py +++ b/litellm/integrations/slack_alerting.py @@ -12,6 +12,7 @@ from litellm.caching import DualCache import asyncio import aiohttp from litellm.llms.custom_httpx.http_handler import AsyncHTTPHandler +import datetime class SlackAlerting: @@ -47,6 +48,18 @@ class SlackAlerting: self.internal_usage_cache = DualCache() self.async_http_handler = AsyncHTTPHandler() self.alert_to_webhook_url = alert_to_webhook_url + self.langfuse_logger = None + + try: + from litellm.integrations.langfuse import LangFuseLogger + + self.langfuse_logger = LangFuseLogger( + os.getenv("LANGFUSE_PUBLIC_KEY"), + os.getenv("LANGFUSE_SECRET_KEY"), + flush_interval=1, + ) + except: + pass pass @@ -93,39 +106,68 @@ class SlackAlerting: request_info: str, request_data: Optional[dict] = None, kwargs: Optional[dict] = None, + type: Literal["hanging_request", "slow_response"] = "hanging_request", + start_time: Optional[datetime.datetime] = None, + end_time: Optional[datetime.datetime] = None, ): import uuid # For now: do nothing as we're debugging why this is not working as expected + if request_data is not None: + trace_id = request_data.get("metadata", {}).get( + "trace_id", None + ) # get langfuse trace id + if trace_id is None: + trace_id = "litellm-alert-trace-" + str(uuid.uuid4()) + request_data["metadata"]["trace_id"] = trace_id + elif kwargs is not None: + _litellm_params = kwargs.get("litellm_params", {}) + trace_id = _litellm_params.get("metadata", {}).get( + "trace_id", None + ) # get langfuse trace id + if trace_id is None: + trace_id = "litellm-alert-trace-" + str(uuid.uuid4()) + _litellm_params["metadata"]["trace_id"] = trace_id + + # Log hanging request as an error on langfuse + if type == "hanging_request": + if self.langfuse_logger is not None: + _logging_kwargs = copy.deepcopy(request_data) + if _logging_kwargs is None: + _logging_kwargs = {} + _logging_kwargs["litellm_params"] = {} + request_data = request_data or {} + _logging_kwargs["litellm_params"]["metadata"] = request_data.get( + "metadata", {} + ) + # log to langfuse in a separate thread + import threading + + threading.Thread( + target=self.langfuse_logger.log_event, + args=( + _logging_kwargs, + None, + start_time, + end_time, + None, + print, + "ERROR", + "Requests is hanging", + ), + ).start() + + _langfuse_host = os.environ.get("LANGFUSE_HOST", "https://cloud.langfuse.com") + _langfuse_project_id = os.environ.get("LANGFUSE_PROJECT_ID") + + # langfuse urls look like: https://us.cloud.langfuse.com/project/************/traces/litellm-alert-trace-ididi9dk-09292-************ + + _langfuse_url = ( + f"{_langfuse_host}/project/{_langfuse_project_id}/traces/{trace_id}" + ) + request_info += f"\n🪢 Langfuse Trace: {_langfuse_url}" return request_info - # if request_data is not None: - # trace_id = request_data.get("metadata", {}).get( - # "trace_id", None - # ) # get langfuse trace id - # if trace_id is None: - # trace_id = "litellm-alert-trace-" + str(uuid.uuid4()) - # request_data["metadata"]["trace_id"] = trace_id - # elif kwargs is not None: - # _litellm_params = kwargs.get("litellm_params", {}) - # trace_id = _litellm_params.get("metadata", {}).get( - # "trace_id", None - # ) # get langfuse trace id - # if trace_id is None: - # trace_id = "litellm-alert-trace-" + str(uuid.uuid4()) - # _litellm_params["metadata"]["trace_id"] = trace_id - - # _langfuse_host = os.environ.get("LANGFUSE_HOST", "https://cloud.langfuse.com") - # _langfuse_project_id = os.environ.get("LANGFUSE_PROJECT_ID") - - # # langfuse urls look like: https://us.cloud.langfuse.com/project/************/traces/litellm-alert-trace-ididi9dk-09292-************ - - # _langfuse_url = ( - # f"{_langfuse_host}/project/{_langfuse_project_id}/traces/{trace_id}" - # ) - # request_info += f"\n🪢 Langfuse Trace: {_langfuse_url}" - # return request_info - def _response_taking_too_long_callback( self, kwargs, # kwargs to completion @@ -167,6 +209,14 @@ class SlackAlerting: _deployment_latencies = metadata["_latency_per_deployment"] if len(_deployment_latencies) == 0: return None + try: + # try sorting deployments by latency + _deployment_latencies = sorted( + _deployment_latencies.items(), key=lambda x: x[1] + ) + _deployment_latencies = dict(_deployment_latencies) + except: + pass for api_base, latency in _deployment_latencies.items(): _message_to_send += f"\n{api_base}: {round(latency,2)}s" _message_to_send = "```" + _message_to_send + "```" @@ -194,7 +244,7 @@ class SlackAlerting: if time_difference_float > self.alerting_threshold: if "langfuse" in litellm.success_callback: request_info = self._add_langfuse_trace_id_to_alert( - request_info=request_info, kwargs=kwargs + request_info=request_info, kwargs=kwargs, type="slow_response" ) # add deployment latencies to alert if ( @@ -222,8 +272,8 @@ class SlackAlerting: async def response_taking_too_long( self, - start_time: Optional[float] = None, - end_time: Optional[float] = None, + start_time: Optional[datetime.datetime] = None, + end_time: Optional[datetime.datetime] = None, type: Literal["hanging_request", "slow_response"] = "hanging_request", request_data: Optional[dict] = None, ): @@ -243,10 +293,6 @@ class SlackAlerting: except: messages = "" request_info = f"\nRequest Model: `{model}`\nMessages: `{messages}`" - if "langfuse" in litellm.success_callback: - request_info = self._add_langfuse_trace_id_to_alert( - request_info=request_info, request_data=request_data - ) else: request_info = "" @@ -288,6 +334,15 @@ class SlackAlerting: f"`Requests are hanging - {self.alerting_threshold}s+ request time`" ) + if "langfuse" in litellm.success_callback: + request_info = self._add_langfuse_trace_id_to_alert( + request_info=request_info, + request_data=request_data, + type="hanging_request", + start_time=start_time, + end_time=end_time, + ) + # add deployment latencies to alert _deployment_latency_map = self._get_deployment_latencies_to_alert( metadata=request_data.get("metadata", {}) diff --git a/litellm/llms/azure.py b/litellm/llms/azure.py index 7f268c25a59..0fe5c4e7e5d 100644 --- a/litellm/llms/azure.py +++ b/litellm/llms/azure.py @@ -96,6 +96,15 @@ class AzureOpenAIConfig(OpenAIConfig): top_p, ) + def get_mapped_special_auth_params(self) -> dict: + return {"token": "azure_ad_token"} + + def map_special_auth_params(self, non_default_params: dict, optional_params: dict): + for param, value in non_default_params.items(): + if param == "token": + optional_params["azure_ad_token"] = value + return optional_params + def select_azure_base_url_or_endpoint(azure_client_params: dict): # azure_client_params = { diff --git a/litellm/llms/bedrock.py b/litellm/llms/bedrock.py index 149b6847245..894114559d0 100644 --- a/litellm/llms/bedrock.py +++ b/litellm/llms/bedrock.py @@ -29,6 +29,24 @@ class BedrockError(Exception): ) # Call the base class constructor with the parameters it needs +class AmazonBedrockGlobalConfig: + def __init__(self): + pass + + def get_mapped_special_auth_params(self) -> dict: + """ + Mapping of common auth params across bedrock/vertex/azure/watsonx + """ + return {"region_name": "aws_region_name"} + + def map_special_auth_params(self, non_default_params: dict, optional_params: dict): + mapped_params = self.get_mapped_special_auth_params() + for param, value in non_default_params.items(): + if param in mapped_params: + optional_params[mapped_params[param]] = value + return optional_params + + class AmazonTitanConfig: """ Reference: https://us-west-2.console.aws.amazon.com/bedrock/home?region=us-west-2#/providers?model=titan-text-express-v1 diff --git a/litellm/llms/openai.py b/litellm/llms/openai.py index e3c012dabbe..f68ab235e6a 100644 --- a/litellm/llms/openai.py +++ b/litellm/llms/openai.py @@ -447,6 +447,7 @@ class OpenAIChatCompletion(BaseLLM): ) else: openai_aclient = client + ## LOGGING logging_obj.pre_call( input=data["messages"], diff --git a/litellm/llms/prompt_templates/factory.py b/litellm/llms/prompt_templates/factory.py index bda3846a8c1..c51dc89be5b 100644 --- a/litellm/llms/prompt_templates/factory.py +++ b/litellm/llms/prompt_templates/factory.py @@ -430,6 +430,32 @@ def format_prompt_togetherai(messages, prompt_format, chat_template): prompt = default_pt(messages) return prompt +### IBM Granite + +def ibm_granite_pt(messages: list): + """ + IBM's Granite models uses the template: + <|system|> {system_message} <|user|> {user_message} <|assistant|> {assistant_message} + + See: https://www.ibm.com/docs/en/watsonx-as-a-service?topic=solutions-supported-foundation-models + """ + return custom_prompt( + messages=messages, + role_dict={ + 'system': { + 'pre_message': '<|system|>\n', + 'post_message': '\n', + }, + 'user': { + 'pre_message': '<|user|>\n', + 'post_message': '\n', + }, + 'assistant': { + 'pre_message': '<|assistant|>\n', + 'post_message': '\n', + } + } + ).strip() ### ANTHROPIC ### @@ -1359,6 +1385,25 @@ def prompt_factory( return messages elif custom_llm_provider == "azure_text": return azure_text_pt(messages=messages) + elif custom_llm_provider == "watsonx": + if "granite" in model and "chat" in model: + # granite-13b-chat-v1 and granite-13b-chat-v2 use a specific prompt template + return ibm_granite_pt(messages=messages) + elif "ibm-mistral" in model and "instruct" in model: + # models like ibm-mistral/mixtral-8x7b-instruct-v01-q use the mistral instruct prompt template + return mistral_instruct_pt(messages=messages) + elif "meta-llama/llama-3" in model and "instruct" in model: + # https://llama.meta.com/docs/model-cards-and-prompt-formats/meta-llama-3/ + return custom_prompt( + role_dict={ + "system": {"pre_message": "<|start_header_id|>system<|end_header_id|>\n", "post_message": "<|eot_id|>"}, + "user": {"pre_message": "<|start_header_id|>user<|end_header_id|>\n", "post_message": "<|eot_id|>"}, + "assistant": {"pre_message": "<|start_header_id|>assistant<|end_header_id|>\n", "post_message": "<|eot_id|>"}, + }, + messages=messages, + initial_prompt_value="<|begin_of_text|>", + final_prompt_value="<|start_header_id|>assistant<|end_header_id|>\n", + ) try: if "meta-llama/llama-2" in model and "chat" in model: return llama_2_chat_pt(messages=messages) diff --git a/litellm/llms/replicate.py b/litellm/llms/replicate.py index c1456bd3f22..65052e3179a 100644 --- a/litellm/llms/replicate.py +++ b/litellm/llms/replicate.py @@ -112,10 +112,16 @@ def start_prediction( } initial_prediction_data = { - "version": version_id, "input": input_data, } + if ":" in version_id and len(version_id) > 64: + model_parts = version_id.split(":") + if ( + len(model_parts) > 1 and len(model_parts[1]) == 64 + ): ## checks if model name has a 64 digit code - e.g. "meta/llama-2-70b-chat:02e509c789964a7ea8736978a43525956ef40397be9033abf9fd2badfe68c9e3" + initial_prediction_data["version"] = model_parts[1] + ## LOGGING logging_obj.pre_call( input=input_data["prompt"], diff --git a/litellm/llms/vertex_ai.py b/litellm/llms/vertex_ai.py index 24108e46635..ce0ccc73a0d 100644 --- a/litellm/llms/vertex_ai.py +++ b/litellm/llms/vertex_ai.py @@ -184,6 +184,20 @@ class VertexAIConfig: pass return optional_params + def get_mapped_special_auth_params(self) -> dict: + """ + Common auth params across bedrock/vertex_ai/azure/watsonx + """ + return {"project": "vertex_project", "region_name": "vertex_location"} + + def map_special_auth_params(self, non_default_params: dict, optional_params: dict): + mapped_params = self.get_mapped_special_auth_params() + + for param, value in non_default_params.items(): + if param in mapped_params: + optional_params[mapped_params[param]] = value + return optional_params + import asyncio @@ -529,6 +543,7 @@ def completion( "instances": instances, "vertex_location": vertex_location, "vertex_project": vertex_project, + "safety_settings": safety_settings, **optional_params, } if optional_params.get("stream", False) is True: @@ -813,6 +828,7 @@ async def async_completion( instances=None, vertex_project=None, vertex_location=None, + safety_settings=None, **optional_params, ): """ @@ -844,6 +860,7 @@ async def async_completion( response = await llm_model._generate_content_async( contents=content, generation_config=optional_params, + safety_settings=safety_settings, tools=tools, ) @@ -1022,6 +1039,7 @@ async def async_streaming( instances=None, vertex_project=None, vertex_location=None, + safety_settings=None, **optional_params, ): """ @@ -1048,6 +1066,7 @@ async def async_streaming( response = await llm_model._generate_content_streaming_async( contents=content, generation_config=optional_params, + safety_settings=safety_settings, tools=tools, ) diff --git a/litellm/llms/watsonx.py b/litellm/llms/watsonx.py new file mode 100644 index 00000000000..ac38a2a8fed --- /dev/null +++ b/litellm/llms/watsonx.py @@ -0,0 +1,609 @@ +from enum import Enum +import json, types, time # noqa: E401 +from contextlib import contextmanager +from typing import Callable, Dict, Optional, Any, Union, List + +import httpx +import requests +import litellm +from litellm.utils import ModelResponse, get_secret, Usage + +from .base import BaseLLM +from .prompt_templates import factory as ptf + + +class WatsonXAIError(Exception): + def __init__(self, status_code, message, url: Optional[str] = None): + self.status_code = status_code + self.message = message + url = url or "https://https://us-south.ml.cloud.ibm.com" + self.request = httpx.Request(method="POST", url=url) + 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 IBMWatsonXAIConfig: + """ + Reference: https://cloud.ibm.com/apidocs/watsonx-ai#text-generation + (See ibm_watsonx_ai.metanames.GenTextParamsMetaNames for a list of all available params) + + Supported params for all available watsonx.ai foundational models. + + - `decoding_method` (str): One of "greedy" or "sample" + + - `temperature` (float): Sets the model temperature for sampling - not available when decoding_method='greedy'. + + - `max_new_tokens` (integer): Maximum length of the generated tokens. + + - `min_new_tokens` (integer): Maximum length of input tokens. Any more than this will be truncated. + + - `length_penalty` (dict): A dictionary with keys "decay_factor" and "start_index". + + - `stop_sequences` (string[]): list of strings to use as stop sequences. + + - `top_k` (integer): top k for sampling - not available when decoding_method='greedy'. + + - `top_p` (integer): top p for sampling - not available when decoding_method='greedy'. + + - `repetition_penalty` (float): token repetition penalty during text generation. + + - `truncate_input_tokens` (integer): Truncate input tokens to this length. + + - `include_stop_sequences` (bool): If True, the stop sequence will be included at the end of the generated text in the case of a match. + + - `return_options` (dict): A dictionary of options to return. Options include "input_text", "generated_tokens", "input_tokens", "token_ranks". Values are boolean. + + - `random_seed` (integer): Random seed for text generation. + + - `moderations` (dict): Dictionary of properties that control the moderations, for usages such as Hate and profanity (HAP) and PII filtering. + + - `stream` (bool): If True, the model will return a stream of responses. + """ + + decoding_method: Optional[str] = "sample" + temperature: Optional[float] = None + max_new_tokens: Optional[int] = None # litellm.max_tokens + min_new_tokens: Optional[int] = None + length_penalty: Optional[dict] = None # e.g {"decay_factor": 2.5, "start_index": 5} + stop_sequences: Optional[List[str]] = None # e.g ["}", ")", "."] + top_k: Optional[int] = None + top_p: Optional[float] = None + repetition_penalty: Optional[float] = None + truncate_input_tokens: Optional[int] = None + include_stop_sequences: Optional[bool] = False + return_options: Optional[Dict[str, bool]] = None + random_seed: Optional[int] = None # e.g 42 + moderations: Optional[dict] = None + stream: Optional[bool] = False + + def __init__( + self, + decoding_method: Optional[str] = None, + temperature: Optional[float] = None, + max_new_tokens: Optional[int] = None, + min_new_tokens: Optional[int] = None, + length_penalty: Optional[dict] = None, + stop_sequences: Optional[List[str]] = None, + top_k: Optional[int] = None, + top_p: Optional[float] = None, + repetition_penalty: Optional[float] = None, + truncate_input_tokens: Optional[int] = None, + include_stop_sequences: Optional[bool] = None, + return_options: Optional[dict] = None, + random_seed: Optional[int] = None, + moderations: Optional[dict] = None, + stream: Optional[bool] = None, + **kwargs, + ) -> None: + locals_ = locals() + for key, value in locals_.items(): + if key != "self" and value is not None: + setattr(self.__class__, key, value) + + @classmethod + def get_config(cls): + return { + k: v + for k, v in cls.__dict__.items() + if not k.startswith("__") + and not isinstance( + v, + ( + types.FunctionType, + types.BuiltinFunctionType, + classmethod, + staticmethod, + ), + ) + and v is not None + } + + def get_supported_openai_params(self): + return [ + "temperature", # equivalent to temperature + "max_tokens", # equivalent to max_new_tokens + "top_p", # equivalent to top_p + "frequency_penalty", # equivalent to repetition_penalty + "stop", # equivalent to stop_sequences + "seed", # equivalent to random_seed + "stream", # equivalent to stream + ] + + def get_mapped_special_auth_params(self) -> dict: + """ + Common auth params across bedrock/vertex_ai/azure/watsonx + """ + return { + "project": "watsonx_project", + "region_name": "watsonx_region_name", + "token": "watsonx_token", + } + + def map_special_auth_params(self, non_default_params: dict, optional_params: dict): + mapped_params = self.get_mapped_special_auth_params() + + for param, value in non_default_params.items(): + if param in mapped_params: + optional_params[mapped_params[param]] = value + return optional_params + + +def convert_messages_to_prompt(model, messages, provider, custom_prompt_dict): + # handle anthropic prompts and amazon titan prompts + if model in custom_prompt_dict: + # check if the model has a registered custom prompt + model_prompt_dict = custom_prompt_dict[model] + prompt = ptf.custom_prompt( + messages=messages, + role_dict=model_prompt_dict.get( + "role_dict", model_prompt_dict.get("roles") + ), + initial_prompt_value=model_prompt_dict.get("initial_prompt_value", ""), + final_prompt_value=model_prompt_dict.get("final_prompt_value", ""), + bos_token=model_prompt_dict.get("bos_token", ""), + eos_token=model_prompt_dict.get("eos_token", ""), + ) + return prompt + elif provider == "ibm": + prompt = ptf.prompt_factory( + model=model, messages=messages, custom_llm_provider="watsonx" + ) + elif provider == "ibm-mistralai": + prompt = ptf.mistral_instruct_pt(messages=messages) + else: + prompt = ptf.prompt_factory( + model=model, messages=messages, custom_llm_provider="watsonx" + ) + return prompt + + +class WatsonXAIEndpoint(str, Enum): + TEXT_GENERATION = "/ml/v1/text/generation" + TEXT_GENERATION_STREAM = "/ml/v1/text/generation_stream" + DEPLOYMENT_TEXT_GENERATION = "/ml/v1/deployments/{deployment_id}/text/generation" + DEPLOYMENT_TEXT_GENERATION_STREAM = ( + "/ml/v1/deployments/{deployment_id}/text/generation_stream" + ) + EMBEDDINGS = "/ml/v1/text/embeddings" + PROMPTS = "/ml/v1/prompts" + + +class IBMWatsonXAI(BaseLLM): + """ + Class to interface with IBM Watsonx.ai API for text generation and embeddings. + + Reference: https://cloud.ibm.com/apidocs/watsonx-ai + """ + + api_version = "2024-03-13" + + def __init__(self) -> None: + super().__init__() + + def _prepare_text_generation_req( + self, + model_id: str, + prompt: str, + stream: bool, + optional_params: dict, + print_verbose: Optional[Callable] = None, + ) -> dict: + """ + Get the request parameters for text generation. + """ + api_params = self._get_api_params(optional_params, print_verbose=print_verbose) + # build auth headers + api_token = api_params.get("token") + + headers = { + "Authorization": f"Bearer {api_token}", + "Content-Type": "application/json", + "Accept": "application/json", + } + extra_body_params = optional_params.pop("extra_body", {}) + optional_params.update(extra_body_params) + # init the payload to the text generation call + payload = { + "input": prompt, + "moderations": optional_params.pop("moderations", {}), + "parameters": optional_params, + } + request_params = dict(version=api_params["api_version"]) + # text generation endpoint deployment or model / stream or not + if model_id.startswith("deployment/"): + # deployment models are passed in as 'deployment/' + if api_params.get("space_id") is None: + raise WatsonXAIError( + status_code=401, + url=api_params["url"], + message="Error: space_id is required for models called using the 'deployment/' endpoint. Pass in the space_id as a parameter or set it in the WX_SPACE_ID environment variable.", + ) + deployment_id = "/".join(model_id.split("/")[1:]) + endpoint = ( + WatsonXAIEndpoint.DEPLOYMENT_TEXT_GENERATION_STREAM.value + if stream + else WatsonXAIEndpoint.DEPLOYMENT_TEXT_GENERATION.value + ) + endpoint = endpoint.format(deployment_id=deployment_id) + else: + payload["model_id"] = model_id + payload["project_id"] = api_params["project_id"] + endpoint = ( + WatsonXAIEndpoint.TEXT_GENERATION_STREAM + if stream + else WatsonXAIEndpoint.TEXT_GENERATION + ) + url = api_params["url"].rstrip("/") + endpoint + return dict( + method="POST", url=url, headers=headers, json=payload, params=request_params + ) + + def _get_api_params( + self, params: dict, print_verbose: Optional[Callable] = None + ) -> dict: + """ + Find watsonx.ai credentials in the params or environment variables and return the headers for authentication. + """ + # Load auth variables from params + url = params.pop("url", params.pop("api_base", params.pop("base_url", None))) + api_key = params.pop("apikey", None) + token = params.pop("token", None) + project_id = params.pop( + "project_id", params.pop("watsonx_project", None) + ) # watsonx.ai project_id - allow 'watsonx_project' to be consistent with how vertex project implementation works -> reduce provider-specific params + space_id = params.pop("space_id", None) # watsonx.ai deployment space_id + region_name = params.pop("region_name", params.pop("region", None)) + if region_name is None: + region_name = params.pop( + "watsonx_region_name", params.pop("watsonx_region", None) + ) # consistent with how vertex ai + aws regions are accepted + wx_credentials = params.pop( + "wx_credentials", + params.pop( + "watsonx_credentials", None + ), # follow {provider}_credentials, same as vertex ai + ) + api_version = params.pop("api_version", IBMWatsonXAI.api_version) + # Load auth variables from environment variables + if url is None: + url = ( + get_secret("WATSONX_API_BASE") # consistent with 'AZURE_API_BASE' + or get_secret("WATSONX_URL") + or get_secret("WX_URL") + or get_secret("WML_URL") + ) + if api_key is None: + api_key = ( + get_secret("WATSONX_APIKEY") + or get_secret("WATSONX_API_KEY") + or get_secret("WX_API_KEY") + ) + if token is None: + token = get_secret("WATSONX_TOKEN") or get_secret("WX_TOKEN") + if project_id is None: + project_id = ( + get_secret("WATSONX_PROJECT_ID") + or get_secret("WX_PROJECT_ID") + or get_secret("PROJECT_ID") + ) + if region_name is None: + region_name = ( + get_secret("WATSONX_REGION") + or get_secret("WX_REGION") + or get_secret("REGION") + ) + if space_id is None: + space_id = ( + get_secret("WATSONX_DEPLOYMENT_SPACE_ID") + or get_secret("WATSONX_SPACE_ID") + or get_secret("WX_SPACE_ID") + or get_secret("SPACE_ID") + ) + + # credentials parsing + if wx_credentials is not None: + url = wx_credentials.get("url", url) + api_key = wx_credentials.get( + "apikey", wx_credentials.get("api_key", api_key) + ) + token = wx_credentials.get( + "token", + wx_credentials.get( + "watsonx_token", token + ), # follow format of {provider}_token, same as azure - e.g. 'azure_ad_token=..' + ) + + # verify that all required credentials are present + if url is None: + raise WatsonXAIError( + status_code=401, + message="Error: Watsonx URL not set. Set WX_URL in environment variables or pass in as a parameter.", + ) + if token is None and api_key is not None: + # generate the auth token + if print_verbose: + print_verbose("Generating IAM token for Watsonx.ai") + token = self.generate_iam_token(api_key) + elif token is None and api_key is None: + raise WatsonXAIError( + status_code=401, + url=url, + message="Error: API key or token not found. Set WX_API_KEY or WX_TOKEN in environment variables or pass in as a parameter.", + ) + if project_id is None: + raise WatsonXAIError( + status_code=401, + url=url, + message="Error: Watsonx project_id not set. Set WX_PROJECT_ID in environment variables or pass in as a parameter.", + ) + + return { + "url": url, + "api_key": api_key, + "token": token, + "project_id": project_id, + "space_id": space_id, + "region_name": region_name, + "api_version": api_version, + } + + def completion( + self, + model: str, + messages: list, + custom_prompt_dict: dict, + model_response: ModelResponse, + print_verbose: Callable, + encoding, + logging_obj, + optional_params: dict, + litellm_params: Optional[dict] = None, + logger_fn=None, + timeout: Optional[float] = None, + ): + """ + Send a text generation request to the IBM Watsonx.ai API. + Reference: https://cloud.ibm.com/apidocs/watsonx-ai#text-generation + """ + stream = optional_params.pop("stream", False) + + # Load default configs + config = IBMWatsonXAIConfig.get_config() + for k, v in config.items(): + if k not in optional_params: + optional_params[k] = v + + # Make prompt to send to model + provider = model.split("/")[0] + # model_name = "/".join(model.split("/")[1:]) + prompt = convert_messages_to_prompt( + model, messages, provider, custom_prompt_dict + ) + + def process_text_request(request_params: dict) -> ModelResponse: + with self._manage_response( + request_params, logging_obj=logging_obj, input=prompt, timeout=timeout + ) as resp: + json_resp = resp.json() + + generated_text = json_resp["results"][0]["generated_text"] + prompt_tokens = json_resp["results"][0]["input_token_count"] + completion_tokens = json_resp["results"][0]["generated_token_count"] + model_response["choices"][0]["message"]["content"] = generated_text + model_response["finish_reason"] = json_resp["results"][0]["stop_reason"] + model_response["created"] = int(time.time()) + model_response["model"] = model + setattr( + model_response, + "usage", + Usage( + prompt_tokens=prompt_tokens, + completion_tokens=completion_tokens, + total_tokens=prompt_tokens + completion_tokens, + ), + ) + return model_response + + def process_stream_request( + request_params: dict, + ) -> litellm.CustomStreamWrapper: + # stream the response - generated chunks will be handled + # by litellm.utils.CustomStreamWrapper.handle_watsonx_stream + with self._manage_response( + request_params, + logging_obj=logging_obj, + stream=True, + input=prompt, + timeout=timeout, + ) as resp: + response = litellm.CustomStreamWrapper( + resp.iter_lines(), + model=model, + custom_llm_provider="watsonx", + logging_obj=logging_obj, + ) + return response + + try: + ## Get the response from the model + req_params = self._prepare_text_generation_req( + model_id=model, + prompt=prompt, + stream=stream, + optional_params=optional_params, + print_verbose=print_verbose, + ) + if stream: + return process_stream_request(req_params) + else: + return process_text_request(req_params) + except WatsonXAIError as e: + raise e + except Exception as e: + raise WatsonXAIError(status_code=500, message=str(e)) + + def embedding( + self, + model: str, + input: Union[list, str], + api_key: Optional[str] = None, + logging_obj=None, + model_response=None, + optional_params=None, + encoding=None, + ): + """ + Send a text embedding request to the IBM Watsonx.ai API. + """ + if optional_params is None: + optional_params = {} + # Load default configs + config = IBMWatsonXAIConfig.get_config() + for k, v in config.items(): + if k not in optional_params: + optional_params[k] = v + + # Load auth variables from environment variables + if isinstance(input, str): + input = [input] + if api_key is not None: + optional_params["api_key"] = api_key + api_params = self._get_api_params(optional_params) + # build auth headers + api_token = api_params.get("token") + headers = { + "Authorization": f"Bearer {api_token}", + "Content-Type": "application/json", + "Accept": "application/json", + } + # init the payload to the text generation call + payload = { + "inputs": input, + "model_id": model, + "project_id": api_params["project_id"], + "parameters": optional_params, + } + request_params = dict(version=api_params["api_version"]) + url = api_params["url"].rstrip("/") + WatsonXAIEndpoint.EMBEDDINGS + # request = httpx.Request( + # "POST", url, headers=headers, json=payload, params=request_params + # ) + req_params = { + "method": "POST", + "url": url, + "headers": headers, + "json": payload, + "params": request_params, + } + with self._manage_response( + req_params, logging_obj=logging_obj, input=input + ) as resp: + json_resp = resp.json() + + results = json_resp.get("results", []) + embedding_response = [] + for idx, result in enumerate(results): + embedding_response.append( + {"object": "embedding", "index": idx, "embedding": result["embedding"]} + ) + model_response["object"] = "list" + model_response["data"] = embedding_response + model_response["model"] = model + input_tokens = json_resp.get("input_token_count", 0) + model_response.usage = Usage( + prompt_tokens=input_tokens, completion_tokens=0, total_tokens=input_tokens + ) + return model_response + + def generate_iam_token(self, api_key=None, **params): + headers = {} + headers["Content-Type"] = "application/x-www-form-urlencoded" + if api_key is None: + api_key = get_secret("WX_API_KEY") or get_secret("WATSONX_API_KEY") + if api_key is None: + raise ValueError("API key is required") + headers["Accept"] = "application/json" + data = { + "grant_type": "urn:ibm:params:oauth:grant-type:apikey", + "apikey": api_key, + } + response = httpx.post( + "https://iam.cloud.ibm.com/identity/token", data=data, headers=headers + ) + response.raise_for_status() + json_data = response.json() + iam_access_token = json_data["access_token"] + self.token = iam_access_token + return iam_access_token + + @contextmanager + def _manage_response( + self, + request_params: dict, + logging_obj: Any, + stream: bool = False, + input: Optional[Any] = None, + timeout: Optional[float] = None, + ): + request_str = ( + f"response = {request_params['method']}(\n" + f"\turl={request_params['url']},\n" + f"\tjson={request_params['json']},\n" + f")" + ) + logging_obj.pre_call( + input=input, + api_key=request_params["headers"].get("Authorization"), + additional_args={ + "complete_input_dict": request_params["json"], + "request_str": request_str, + }, + ) + if timeout: + request_params["timeout"] = timeout + try: + if stream: + resp = requests.request( + **request_params, + stream=True, + ) + resp.raise_for_status() + yield resp + else: + resp = requests.request(**request_params) + resp.raise_for_status() + yield resp + except Exception as e: + raise WatsonXAIError(status_code=500, message=str(e)) + if not stream: + logging_obj.post_call( + input=input, + api_key=request_params["headers"].get("Authorization"), + original_response=json.dumps(resp.json()), + additional_args={ + "status_code": resp.status_code, + "complete_input_dict": request_params["json"], + }, + ) diff --git a/litellm/main.py b/litellm/main.py index 52b2f3089e1..454f7f7169a 100644 --- a/litellm/main.py +++ b/litellm/main.py @@ -62,6 +62,7 @@ from .llms import ( vertex_ai, vertex_ai_anthropic, maritalk, + watsonx, ) from .llms.openai import OpenAIChatCompletion, OpenAITextCompletion from .llms.azure import AzureChatCompletion @@ -1862,6 +1863,43 @@ def completion( ## RESPONSE OBJECT response = response + elif custom_llm_provider == "watsonx": + custom_prompt_dict = custom_prompt_dict or litellm.custom_prompt_dict + response = watsonx.IBMWatsonXAI().completion( + model=model, + messages=messages, + custom_prompt_dict=custom_prompt_dict, + model_response=model_response, + print_verbose=print_verbose, + optional_params=optional_params, + litellm_params=litellm_params, # type: ignore + logger_fn=logger_fn, + encoding=encoding, + logging_obj=logging, + timeout=timeout, + ) + if ( + "stream" in optional_params + and optional_params["stream"] == True + and not isinstance(response, CustomStreamWrapper) + ): + # don't try to access stream object, + response = CustomStreamWrapper( + iter(response), + model, + custom_llm_provider="watsonx", + logging_obj=logging, + ) + + if optional_params.get("stream", False): + ## LOGGING + logging.post_call( + input=messages, + api_key=None, + original_response=response, + ) + ## RESPONSE OBJECT + response = response elif custom_llm_provider == "vllm": custom_prompt_dict = custom_prompt_dict or litellm.custom_prompt_dict model_response = vllm.completion( @@ -2941,6 +2979,15 @@ def embedding( client=client, aembedding=aembedding, ) + elif custom_llm_provider == "watsonx": + response = watsonx.IBMWatsonXAI().embedding( + model=model, + input=input, + encoding=encoding, + logging_obj=logging, + optional_params=optional_params, + model_response=EmbeddingResponse(), + ) else: args = locals() raise ValueError(f"No valid embedding model args passed in - {args}") diff --git a/litellm/proxy/_experimental/out/404.html b/litellm/proxy/_experimental/out/404.html index 310a90e222d..6d3d33c80bf 100644 --- a/litellm/proxy/_experimental/out/404.html +++ b/litellm/proxy/_experimental/out/404.html @@ -1 +1 @@ -404: This page could not be found.LiteLLM Dashboard

404

This page could not be found.

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

404

This page could not be found.

\ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/app/page-508c39694bd40fe9.js b/litellm/proxy/_experimental/out/_next/static/chunks/app/page-508c39694bd40fe9.js new file mode 100644 index 00000000000..290d55662cb --- /dev/null +++ b/litellm/proxy/_experimental/out/_next/static/chunks/app/page-508c39694bd40fe9.js @@ -0,0 +1 @@ +(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[931],{20661:function(e,l,t){Promise.resolve().then(t.bind(t,27125))},27125:function(e,l,t){"use strict";t.r(l),t.d(l,{default:function(){return lf}});var s,a,r=t(3827),n=t(64090),o=t(47907),i=t(8792),c=t(40491),d=t(65270),m=e=>{let{userID:l,userRole:t,userEmail:s,showSSOBanner:a}=e;console.log("User ID:",l),console.log("userEmail:",s),console.log("showSSOBanner:",a);let n=[{key:"1",label:(0,r.jsxs)(r.Fragment,{children:[(0,r.jsxs)("p",{children:["Role: ",t]}),(0,r.jsxs)("p",{children:["ID: ",l]})]})}];return(0,r.jsxs)("nav",{className:"left-0 right-0 top-0 flex justify-between items-center h-12 mb-4",children:[(0,r.jsx)("div",{className:"text-left my-2 absolute top-0 left-0",children:(0,r.jsx)("div",{className:"flex flex-col items-center",children:(0,r.jsx)(i.default,{href:"/",children:(0,r.jsx)("button",{className:"text-gray-800 rounded text-center",children:(0,r.jsx)("img",{src:"/get_image",width:160,height:160,alt:"LiteLLM Brand",className:"mr-2"})})})})}),(0,r.jsxs)("div",{className:"text-right mx-4 my-2 absolute top-0 right-0 flex items-center justify-end space-x-2",children:[a?(0,r.jsx)("div",{style:{padding:"6px",borderRadius:"8px"},children:(0,r.jsx)("a",{href:"https://calendly.com/d/4mp-gd3-k5k/litellm-1-1-onboarding-chat",target:"_blank",style:{fontSize:"14px",textDecoration:"underline"},children:"Request hosted proxy"})}):null,(0,r.jsx)("div",{style:{border:"1px solid #391085",padding:"6px",borderRadius:"8px"},children:(0,r.jsx)(c.Z,{menu:{items:n},children:(0,r.jsx)(d.Z,{children:s})})})]})]})},h=t(80588);let u=async()=>{try{let e=await fetch("https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json"),l=await e.json();return console.log("received data: ".concat(l)),l}catch(e){throw console.error("Failed to get model cost map:",e),e}},x=async(e,l)=>{try{let t=await fetch("/model/new",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...l})});if(!t.ok){let e=await t.text();throw h.ZP.error("Failed to create key: "+e,20),console.error("Error response from the server:",e),Error("Network response was not ok")}let s=await t.json();return console.log("API Response:",s),h.ZP.success("Model created successfully. Wait 60s and refresh on 'All Models' page"),s}catch(e){throw console.error("Failed to create key:",e),e}},p=async(e,l)=>{console.log("model_id in model delete call: ".concat(l));try{let t=await fetch("/model/delete",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({id:l})});if(!t.ok){let e=await t.text();throw h.ZP.error("Failed to create key: "+e,20),console.error("Error response from the server:",e),Error("Network response was not ok")}let s=await t.json();return console.log("API Response:",s),h.ZP.success("Model deleted successfully. Restart server to see this."),s}catch(e){throw console.error("Failed to create key:",e),e}},j=async(e,l,t)=>{try{if(console.log("Form Values in keyCreateCall:",t),t.description&&(t.metadata||(t.metadata={}),t.metadata.description=t.description,delete t.description,t.metadata=JSON.stringify(t.metadata)),t.metadata){console.log("formValues.metadata:",t.metadata);try{t.metadata=JSON.parse(t.metadata)}catch(e){throw h.ZP.error("Failed to parse metadata: "+e,20),Error("Failed to parse metadata: "+e)}}console.log("Form Values after check:",t);let s=await fetch("/key/generate",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({user_id:l,...t})});if(!s.ok){let e=await s.text();throw h.ZP.error("Failed to create key: "+e,20),console.error("Error response from the server:",e),Error("Network response was not ok")}let a=await s.json();return console.log("API Response:",a),a}catch(e){throw console.error("Failed to create key:",e),e}},g=async(e,l,t)=>{try{if(console.log("Form Values in keyCreateCall:",t),t.description&&(t.metadata||(t.metadata={}),t.metadata.description=t.description,delete t.description,t.metadata=JSON.stringify(t.metadata)),t.metadata){console.log("formValues.metadata:",t.metadata);try{t.metadata=JSON.parse(t.metadata)}catch(e){throw h.ZP.error("Failed to parse metadata: "+e,20),Error("Failed to parse metadata: "+e)}}console.log("Form Values after check:",t);let s=await fetch("/user/new",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({user_id:l,...t})});if(!s.ok){let e=await s.text();throw h.ZP.error("Failed to create key: "+e,20),console.error("Error response from the server:",e),Error("Network response was not ok")}let a=await s.json();return console.log("API Response:",a),a}catch(e){throw console.error("Failed to create key:",e),e}},f=async(e,l)=>{try{console.log("in keyDeleteCall:",l);let t=await fetch("/key/delete",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({keys:[l]})});if(!t.ok){let e=await t.text();throw h.ZP.error("Failed to delete key: "+e,20),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to create key:",e),e}},y=async(e,l)=>{try{console.log("in teamDeleteCall:",l);let t=await fetch("/team/delete",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({team_ids:[l]})});if(!t.ok){let e=await t.text();throw h.ZP.error("Failed to delete team: "+e,20),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to delete key:",e),e}},Z=async function(e,l,t){let s=arguments.length>3&&void 0!==arguments[3]&&arguments[3],a=arguments.length>4?arguments[4]:void 0,r=arguments.length>5?arguments[5]:void 0;try{let n="/user/info";"App Owner"==t&&l&&(n="".concat(n,"?user_id=").concat(l)),"App User"==t&&l&&(n="".concat(n,"?user_id=").concat(l)),console.log("in userInfoCall viewAll=",s),s&&r&&null!=a&&void 0!=a&&(n="".concat(n,"?view_all=true&page=").concat(a,"&page_size=").concat(r));let o=await fetch(n,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!o.ok){let e=await o.text();throw h.ZP.error(e,20),Error("Network response was not ok")}let i=await o.json();return console.log("API Response:",i),i}catch(e){throw console.error("Failed to create key:",e),e}},w=async(e,l)=>{try{let t="/team/info";l&&(t="".concat(t,"?team_id=").concat(l)),console.log("in teamInfoCall");let s=await fetch(t,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!s.ok){let e=await s.text();throw h.ZP.error(e,20),Error("Network response was not ok")}let a=await s.json();return console.log("API Response:",a),a}catch(e){throw console.error("Failed to create key:",e),e}},b=async e=>{try{let l=await fetch("/global/spend",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw h.ZP.error(e,20),Error("Network response was not ok")}return await l.json()}catch(e){throw console.error("Failed to create key:",e),e}},_=async(e,l,t)=>{try{let l=await fetch("/v2/model/info",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw h.ZP.error(e,20),Error("Network response was not ok")}let t=await l.json();return console.log("modelInfoCall:",t),t}catch(e){throw console.error("Failed to create key:",e),e}},k=async(e,l,t,s)=>{try{let l="/model/metrics";s&&(l="".concat(l,"?_selected_model_group=").concat(s));let t=await fetch(l,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw h.ZP.error(e,20),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},v=async(e,l,t)=>{try{let l=await fetch("/models",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw h.ZP.error(e,20),Error("Network response was not ok")}return await l.json()}catch(e){throw console.error("Failed to create key:",e),e}},S=async(e,l)=>{try{let t="/global/spend/logs";console.log("in keySpendLogsCall:",t);let s=await fetch("".concat(t,"?api_key=").concat(l),{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!s.ok){let e=await s.text();throw h.ZP.error(e,20),Error("Network response was not ok")}let a=await s.json();return console.log(a),a}catch(e){throw console.error("Failed to create key:",e),e}},A=async e=>{try{let l="/global/spend/teams";console.log("in teamSpendLogsCall:",l);let t=await fetch("".concat(l),{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw h.ZP.error(e,20),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to create key:",e),e}},N=async e=>{try{let l="/global/spend/tags";console.log("in tagsSpendLogsCall:",l);let t=await fetch("".concat(l),{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw h.ZP.error(e,20),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to create key:",e),e}},C=async(e,l,t,s,a,r)=>{try{console.log("user role in spend logs call: ".concat(t));let l="/spend/logs";l="App Owner"==t?"".concat(l,"?user_id=").concat(s,"&start_date=").concat(a,"&end_date=").concat(r):"".concat(l,"?start_date=").concat(a,"&end_date=").concat(r);let n=await fetch(l,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!n.ok){let e=await n.text();throw h.ZP.error(e,20),Error("Network response was not ok")}let o=await n.json();return console.log(o),o}catch(e){throw console.error("Failed to create key:",e),e}},I=async e=>{try{let l=await fetch("/global/spend/logs",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw h.ZP.error(e,20),Error("Network response was not ok")}let t=await l.json();return console.log(t),t}catch(e){throw console.error("Failed to create key:",e),e}},P=async e=>{try{let l=await fetch("/global/spend/keys?limit=5",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw h.ZP.error(e,20),Error("Network response was not ok")}let t=await l.json();return console.log(t),t}catch(e){throw console.error("Failed to create key:",e),e}},T=async(e,l)=>{try{l&&JSON.stringify({api_key:l});let t={method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}};l&&(t.body=JSON.stringify({api_key:l}));let s=await fetch("/global/spend/end_users",t);if(!s.ok){let e=await s.text();throw h.ZP.error(e,20),Error("Network response was not ok")}let a=await s.json();return console.log(a),a}catch(e){throw console.error("Failed to create key:",e),e}},E=async e=>{try{let l=await fetch("/global/spend/models?limit=5",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw h.ZP.error(e,20),Error("Network response was not ok")}let t=await l.json();return console.log(t),t}catch(e){throw console.error("Failed to create key:",e),e}},F=async(e,l)=>{try{let t=await fetch("/v2/key/info",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({keys:l})});if(!t.ok){let e=await t.text();throw h.ZP.error(e,20),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to create key:",e),e}},O=async e=>{try{let l="/user/get_requests";console.log("in userGetRequesedtModelsCall:",l);let t=await fetch(l,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw h.ZP.error("Failed to delete key: "+e,20),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to get requested models:",e),e}},M=async(e,l)=>{try{let t="/user/get_users?role=".concat(l);console.log("in userGetAllUsersCall:",t);let s=await fetch(t,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!s.ok){let e=await s.text();throw h.ZP.error("Failed to delete key: "+e,20),Error("Network response was not ok")}let a=await s.json();return console.log(a),a}catch(e){throw console.error("Failed to get requested models:",e),e}},R=async(e,l)=>{try{console.log("Form Values in teamCreateCall:",l);let t=await fetch("/team/new",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...l})});if(!t.ok){let e=await t.text();throw h.ZP.error("Failed to create key: "+e,20),console.error("Error response from the server:",e),Error("Network response was not ok")}let s=await t.json();return console.log("API Response:",s),s}catch(e){throw console.error("Failed to create key:",e),e}},L=async(e,l)=>{try{console.log("Form Values in keyUpdateCall:",l);let t=await fetch("/key/update",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...l})});if(!t.ok){let e=await t.text();throw h.ZP.error("Failed to update key: "+e,20),console.error("Error response from the server:",e),Error("Network response was not ok")}let s=await t.json();return console.log("Update key Response:",s),s}catch(e){throw console.error("Failed to create key:",e),e}},U=async(e,l)=>{try{console.log("Form Values in teamUpateCall:",l);let t=await fetch("/team/update",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...l})});if(!t.ok){let e=await t.text();throw h.ZP.error("Failed to update team: "+e,20),console.error("Error response from the server:",e),Error("Network response was not ok")}let s=await t.json();return console.log("Update Team Response:",s),s}catch(e){throw console.error("Failed to create key:",e),e}},D=async(e,l)=>{try{console.log("Form Values in modelUpateCall:",l);let t=await fetch("/model/update",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...l})});if(!t.ok){let e=await t.text();throw h.ZP.error("Failed to update model: "+e,20),console.error("Error update from the server:",e),Error("Network response was not ok")}let s=await t.json();return console.log("Update model Response:",s),s}catch(e){throw console.error("Failed to update model:",e),e}},z=async(e,l,t)=>{try{console.log("Form Values in teamMemberAddCall:",t);let s=await fetch("/team/member_add",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({team_id:l,member:t})});if(!s.ok){let e=await s.text();throw h.ZP.error("Failed to create key: "+e,20),console.error("Error response from the server:",e),Error("Network response was not ok")}let a=await s.json();return console.log("API Response:",a),a}catch(e){throw console.error("Failed to create key:",e),e}},B=async(e,l,t)=>{try{console.log("Form Values in userUpdateUserCall:",l);let s={...l};null!==t&&(s.user_role=t),s=JSON.stringify(s);let a=await fetch("/user/update",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:s});if(!a.ok){let e=await a.text();throw h.ZP.error("Failed to create key: "+e,20),console.error("Error response from the server:",e),Error("Network response was not ok")}let r=await a.json();return console.log("API Response:",r),r}catch(e){throw console.error("Failed to create key:",e),e}},q=async(e,l)=>{try{let t=await fetch("/global/predict/spend/logs",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({data:l})});if(!t.ok){let e=await t.text();throw h.ZP.error(e,20),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to create key:",e),e}},K=async(e,l)=>{try{let t="/health/services?service=".concat(l);console.log("Checking Slack Budget Alerts service health");let s=await fetch(t,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!s.ok){let e=await s.text();throw h.ZP.error("Failed ".concat(l," service health check ")+e),Error(e)}let a=await s.json();return h.ZP.success("Test request to ".concat(l," made - check logs/alerts on ").concat(l," to verify")),a}catch(e){throw console.error("Failed to perform health check:",e),e}},V=async(e,l,t)=>{try{let l=await fetch("/get/config/callbacks",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw h.ZP.error(e,20),Error("Network response was not ok")}return await l.json()}catch(e){throw console.error("Failed to get callbacks:",e),e}},G=async(e,l)=>{try{let t=await fetch("/config/update",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...l})});if(!t.ok){let e=await t.text();throw h.ZP.error(e,20),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to set callbacks:",e),e}},W=async e=>{try{let l=await fetch("/health",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw h.ZP.error(e),Error("Network response was not ok")}return await l.json()}catch(e){throw console.error("Failed to call /health:",e),e}};var J=t(10384),Y=t(46453),H=t(2179),$=t(52273),X=t(26780),Q=t(15595),ee=t(6698),el=t(71801),et=t(42440),es=t(42308),ea=t(50670),er=t(81583),en=t(99129),eo=t(44839),ei=t(88707),ec=t(1861);let{Option:ed}=ea.default;var em=e=>{let{userID:l,team:t,userRole:s,accessToken:a,data:o,setData:i}=e,[c]=er.Z.useForm(),[d,m]=(0,n.useState)(!1),[u,x]=(0,n.useState)(null),[p,g]=(0,n.useState)(null),[f,y]=(0,n.useState)([]),[Z,w]=(0,n.useState)([]),b=()=>{m(!1),c.resetFields()},_=()=>{m(!1),x(null),c.resetFields()};(0,n.useEffect)(()=>{(async()=>{try{if(null===l||null===s)return;if(null!==a){let e=(await v(a,l,s)).data.map(e=>e.id);console.log("available_model_names:",e),y(e)}}catch(e){console.error("Error fetching user models:",e)}})()},[a,l,s]);let k=async e=>{try{h.ZP.info("Making API Call"),m(!0);let t=await j(a,l,e);console.log("key create Response:",t),i(e=>e?[...e,t]:[t]),x(t.key),g(t.soft_budget),h.ZP.success("API Key Created"),c.resetFields(),localStorage.removeItem("userData"+l)}catch(e){console.error("Error creating the key:",e)}};return(0,n.useEffect)(()=>{w(t&&t.models.length>0?t.models.includes("all-proxy-models")?f:t.models:f)},[t,f]),(0,r.jsxs)("div",{children:[(0,r.jsx)(H.Z,{className:"mx-auto",onClick:()=>m(!0),children:"+ Create New Key"}),(0,r.jsx)(en.Z,{title:"Create Key",visible:d,width:800,footer:null,onOk:b,onCancel:_,children:(0,r.jsxs)(er.Z,{form:c,onFinish:k,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(er.Z.Item,{label:"Key Name",name:"key_alias",rules:[{required:!0,message:"Please input a key name"}],help:"required",children:(0,r.jsx)($.Z,{placeholder:""})}),(0,r.jsx)(er.Z.Item,{label:"Team ID",name:"team_id",hidden:!0,initialValue:t?t.team_id:null,valuePropName:"team_id",className:"mt-8",children:(0,r.jsx)(eo.Z,{value:t?t.team_alias:"",disabled:!0})}),(0,r.jsx)(er.Z.Item,{label:"Models",name:"models",rules:[{required:!0,message:"Please select a model"}],help:"required",children:(0,r.jsxs)(ea.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},onChange:e=>{e.includes("all-team-models")&&c.setFieldsValue({models:["all-team-models"]})},children:[(0,r.jsx)(ed,{value:"all-team-models",children:"All Team Models"},"all-team-models"),Z.map(e=>(0,r.jsx)(ed,{value:e,children:e},e))]})}),(0,r.jsxs)(X.Z,{className:"mt-20 mb-8",children:[(0,r.jsx)(ee.Z,{children:(0,r.jsx)("b",{children:"Optional Settings"})}),(0,r.jsxs)(Q.Z,{children:[(0,r.jsx)(er.Z.Item,{className:"mt-8",label:"Max Budget (USD)",name:"max_budget",help:"Budget cannot exceed team max budget: $".concat((null==t?void 0:t.max_budget)!==null&&(null==t?void 0:t.max_budget)!==void 0?null==t?void 0:t.max_budget:"unlimited"),rules:[{validator:async(e,l)=>{if(l&&t&&null!==t.max_budget&&l>t.max_budget)throw Error("Budget cannot exceed team max budget: $".concat(t.max_budget))}}],children:(0,r.jsx)(ei.Z,{step:.01,precision:2,width:200})}),(0,r.jsx)(er.Z.Item,{className:"mt-8",label:"Reset Budget",name:"budget_duration",help:"Team Reset Budget: ".concat((null==t?void 0:t.budget_duration)!==null&&(null==t?void 0:t.budget_duration)!==void 0?null==t?void 0:t.budget_duration:"None"),children:(0,r.jsxs)(ea.default,{defaultValue:null,placeholder:"n/a",children:[(0,r.jsx)(ea.default.Option,{value:"24h",children:"daily"}),(0,r.jsx)(ea.default.Option,{value:"30d",children:"monthly"})]})}),(0,r.jsx)(er.Z.Item,{className:"mt-8",label:"Tokens per minute Limit (TPM)",name:"tpm_limit",help:"TPM cannot exceed team TPM limit: ".concat((null==t?void 0:t.tpm_limit)!==null&&(null==t?void 0:t.tpm_limit)!==void 0?null==t?void 0:t.tpm_limit:"unlimited"),rules:[{validator:async(e,l)=>{if(l&&t&&null!==t.tpm_limit&&l>t.tpm_limit)throw Error("TPM limit cannot exceed team TPM limit: ".concat(t.tpm_limit))}}],children:(0,r.jsx)(ei.Z,{step:1,width:400})}),(0,r.jsx)(er.Z.Item,{className:"mt-8",label:"Requests per minute Limit (RPM)",name:"rpm_limit",help:"RPM cannot exceed team RPM limit: ".concat((null==t?void 0:t.rpm_limit)!==null&&(null==t?void 0:t.rpm_limit)!==void 0?null==t?void 0:t.rpm_limit:"unlimited"),rules:[{validator:async(e,l)=>{if(l&&t&&null!==t.rpm_limit&&l>t.rpm_limit)throw Error("RPM limit cannot exceed team RPM limit: ".concat(t.rpm_limit))}}],children:(0,r.jsx)(ei.Z,{step:1,width:400})}),(0,r.jsx)(er.Z.Item,{label:"Expire Key (eg: 30s, 30h, 30d)",name:"duration",className:"mt-8",children:(0,r.jsx)($.Z,{placeholder:""})}),(0,r.jsx)(er.Z.Item,{label:"Metadata",name:"metadata",children:(0,r.jsx)(eo.Z.TextArea,{rows:4,placeholder:"Enter metadata as JSON"})})]})]})]}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ec.ZP,{htmlType:"submit",children:"Create Key"})})]})}),u&&(0,r.jsx)(en.Z,{visible:d,onOk:b,onCancel:_,footer:null,children:(0,r.jsxs)(Y.Z,{numItems:1,className:"gap-2 w-full",children:[(0,r.jsx)(et.Z,{children:"Save your Key"}),(0,r.jsx)(J.Z,{numColSpan:1,children:(0,r.jsxs)("p",{children:["Please save this secret key somewhere safe and accessible. For security reasons, ",(0,r.jsx)("b",{children:"you will not be able to view it again"})," ","through your LiteLLM account. If you lose this secret key, you will need to generate a new one."]})}),(0,r.jsx)(J.Z,{numColSpan:1,children:null!=u?(0,r.jsxs)("div",{children:[(0,r.jsx)(el.Z,{className:"mt-3",children:"API Key:"}),(0,r.jsx)("div",{style:{background:"#f8f8f8",padding:"10px",borderRadius:"5px",marginBottom:"10px"},children:(0,r.jsx)("pre",{style:{wordWrap:"break-word",whiteSpace:"normal"},children:u})}),(0,r.jsx)(es.CopyToClipboard,{text:u,onCopy:()=>{h.ZP.success("API Key copied to clipboard")},children:(0,r.jsx)(H.Z,{className:"mt-3",children:"Copy API Key"})})]}):(0,r.jsx)(el.Z,{children:"Key being created, this might take 30s"})})]})})]})},eh=t(9454),eu=t(98941),ex=t(33393),ep=t(5),ej=t(9853),eg=t(13810),ef=t(39290),ey=t(66952),eZ=t(61244),ew=t(10827),eb=t(3851),e_=t(2044),ek=t(64167),ev=t(74480),eS=t(7178),eA=t(95093),eN=t(27166);let{Option:eC}=ea.default;var eI=e=>{let{userID:l,userRole:t,accessToken:s,selectedTeam:a,data:o,setData:i,teams:c}=e,[d,m]=(0,n.useState)(!1),[u,x]=(0,n.useState)(!1),[p,j]=(0,n.useState)(null),[g,y]=n.useState(null),[Z,w]=(0,n.useState)(null),[b,_]=(0,n.useState)(null),[k,A]=(0,n.useState)(""),[N,C]=(0,n.useState)(!1),[I,P]=(0,n.useState)(null),[T,E]=(0,n.useState)([]),F=new Set,[O,M]=(0,n.useState)(F);(0,n.useEffect)(()=>{(async()=>{try{if(null===l)return;if(null!==s&&null!==t){let e=(await v(s,l,t)).data.map(e=>e.id);console.log("available_model_names:",e),E(e)}}catch(e){console.error("Error fetching user models:",e)}})()},[s,l,t]),(0,n.useEffect)(()=>{if(c){let e=new Set;c.forEach((l,t)=>{let s=l.team_id;e.add(s)}),M(e)}},[c]);let R=e=>{console.log("handleEditClick:",e),null==e.token&&null!==e.token_id&&(e.token=e.token_id),P(e),C(!0)},U=async e=>{if(null==s)return;let l=e.token;e.key=l,console.log("handleEditSubmit:",e);let t=await L(s,e);console.log("handleEditSubmit: newKeyValues",t),o&&i(o.map(e=>e.token===l?t:e)),h.ZP.success("Key updated successfully"),C(!1),P(null)},D=async e=>{try{if(null==s||null==e)return;console.log("accessToken: ".concat(s,"; token: ").concat(e.token));let l=await S(s,e.token);console.log("Response:",l),_(l);try{let e=await q(s,l);console.log("Response2:",e);let t=[...l,...e.response];_(t),A(e.predicted_spend),console.log("Combined Data:",t)}catch(e){console.error("There was an error fetching the predicted data",e)}}catch(e){console.error("There was an error fetching the data",e)}};(0,n.useEffect)(()=>{D(Z)},[Z]);let z=async e=>{console.log("handleDelete:",e),null==e.token&&null!==e.token_id&&(e.token=e.token_id),null!=o&&(j(e.token),localStorage.removeItem("userData"+l),x(!0))},B=async()=>{if(null!=p&&null!=o){try{await f(s,p);let e=o.filter(e=>e.token!==p);i(e)}catch(e){console.error("Error deleting the key:",e)}x(!1),j(null)}};if(null!=o)return console.log("RERENDER TRIGGERED"),(0,r.jsxs)("div",{children:[(0,r.jsxs)(eg.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh] mb-4 mt-2",children:[(0,r.jsxs)(ew.Z,{className:"mt-5 max-h-[300px] min-h-[300px]",children:[(0,r.jsx)(ek.Z,{children:(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(ev.Z,{children:"Key Alias"}),(0,r.jsx)(ev.Z,{children:"Secret Key"}),(0,r.jsx)(ev.Z,{children:"Spend (USD)"}),(0,r.jsx)(ev.Z,{children:"Budget (USD)"}),(0,r.jsx)(ev.Z,{children:"Models"}),(0,r.jsx)(ev.Z,{children:"TPM / RPM Limits"})]})}),(0,r.jsx)(eb.Z,{children:o.map(e=>{if(console.log(e),"litellm-dashboard"===e.team_id)return null;if(a){if(console.log("item team id: ".concat(e.team_id,", knownTeamIDs.has(item.team_id): ").concat(O.has(e.team_id),", selectedTeam id: ").concat(a.team_id)),(null!=a.team_id||null===e.team_id||O.has(e.team_id))&&e.team_id!=a.team_id)return null;console.log("item team id: ".concat(e.team_id,", is returned"))}return(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(e_.Z,{style:{maxWidth:"2px",whiteSpace:"pre-wrap",overflow:"hidden"},children:null!=e.key_alias?(0,r.jsx)(el.Z,{children:e.key_alias}):(0,r.jsx)(el.Z,{children:"Not Set"})}),(0,r.jsx)(e_.Z,{children:(0,r.jsx)(el.Z,{children:e.key_name})}),(0,r.jsx)(e_.Z,{children:(0,r.jsx)(el.Z,{children:(()=>{try{return parseFloat(e.spend).toFixed(4)}catch(l){return e.spend}})()})}),(0,r.jsx)(e_.Z,{children:null!=e.max_budget?(0,r.jsx)(el.Z,{children:e.max_budget}):(0,r.jsx)(el.Z,{children:"Unlimited"})}),(0,r.jsx)(e_.Z,{children:Array.isArray(e.models)?(0,r.jsx)("div",{style:{display:"flex",flexDirection:"column"},children:0===e.models.length?(0,r.jsx)(r.Fragment,{children:a&&a.models&&a.models.length>0?a.models.map((e,l)=>"all-proxy-models"===e?(0,r.jsx)(ep.Z,{size:"xs",className:"mb-1",color:"red",children:(0,r.jsx)(el.Z,{children:"All Proxy Models"})},l):"all-team-models"===e?(0,r.jsx)(ep.Z,{size:"xs",className:"mb-1",color:"red",children:(0,r.jsx)(el.Z,{children:"All Team Models"})},l):(0,r.jsx)(ep.Z,{size:"xs",className:"mb-1",color:"blue",children:(0,r.jsx)(el.Z,{children:e.length>30?"".concat(e.slice(0,30),"..."):e})},l)):(0,r.jsx)(ep.Z,{size:"xs",className:"mb-1",color:"blue",children:(0,r.jsx)(el.Z,{children:"all-proxy-models"})})}):e.models.map((e,l)=>"all-proxy-models"===e?(0,r.jsx)(ep.Z,{size:"xs",className:"mb-1",color:"red",children:(0,r.jsx)(el.Z,{children:"All Proxy Models"})},l):"all-team-models"===e?(0,r.jsx)(ep.Z,{size:"xs",className:"mb-1",color:"red",children:(0,r.jsx)(el.Z,{children:"All Team Models"})},l):(0,r.jsx)(ep.Z,{size:"xs",className:"mb-1",color:"blue",children:(0,r.jsx)(el.Z,{children:e.length>30?"".concat(e.slice(0,30),"..."):e})},l))}):null}),(0,r.jsx)(e_.Z,{children:(0,r.jsxs)(el.Z,{children:["TPM: ",e.tpm_limit?e.tpm_limit:"Unlimited"," ",(0,r.jsx)("br",{})," RPM:"," ",e.rpm_limit?e.rpm_limit:"Unlimited"]})}),(0,r.jsxs)(e_.Z,{children:[(0,r.jsx)(eZ.Z,{onClick:()=>{w(e),y(e.id)},icon:eh.Z,size:"sm"}),(0,r.jsx)(ef.Z,{open:null!==g,onClose:()=>{y(null),w(null)},children:(0,r.jsx)(ey.Z,{children:Z&&(0,r.jsxs)(r.Fragment,{children:[(0,r.jsxs)("div",{className:"grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3",children:[(0,r.jsxs)(eg.Z,{children:[(0,r.jsx)("p",{className:"text-tremor-default font-medium text-tremor-content dark:text-dark-tremor-content",children:"Spend"}),(0,r.jsx)("div",{className:"mt-2 flex items-baseline space-x-2.5",children:(0,r.jsx)("p",{className:"text-tremor font-semibold text-tremor-content-strong dark:text-dark-tremor-content-strong",children:(()=>{try{return parseFloat(Z.spend).toFixed(4)}catch(e){return Z.spend}})()})})]}),(0,r.jsxs)(eg.Z,{children:[(0,r.jsx)("p",{className:"text-tremor-default font-medium text-tremor-content dark:text-dark-tremor-content",children:"Budget"}),(0,r.jsx)("div",{className:"mt-2 flex items-baseline space-x-2.5",children:(0,r.jsx)("p",{className:"text-tremor font-semibold text-tremor-content-strong dark:text-dark-tremor-content-strong",children:null!=Z.max_budget?(0,r.jsx)(r.Fragment,{children:Z.max_budget}):(0,r.jsx)(r.Fragment,{children:"Unlimited"})})})]},e.name),(0,r.jsxs)(eg.Z,{children:[(0,r.jsx)("p",{className:"text-tremor-default font-medium text-tremor-content dark:text-dark-tremor-content",children:"Expires"}),(0,r.jsx)("div",{className:"mt-2 flex items-baseline space-x-2.5",children:(0,r.jsx)("p",{className:"text-tremor-default font-small text-tremor-content-strong dark:text-dark-tremor-content-strong",children:null!=Z.expires?(0,r.jsx)(r.Fragment,{children:new Date(Z.expires).toLocaleString(void 0,{day:"numeric",month:"long",year:"numeric",hour:"numeric",minute:"numeric",second:"numeric"})}):(0,r.jsx)(r.Fragment,{children:"Never"})})})]},e.name)]}),(0,r.jsx)(eg.Z,{className:"mt-6 mb-6",children:b&&(0,r.jsx)(ej.Z,{className:"mt-6",data:b,colors:["blue","amber"],index:"date",categories:["spend","predicted_spend"],yAxisWidth:80})}),(0,r.jsx)(et.Z,{children:"Metadata"}),(0,r.jsx)(el.Z,{children:JSON.stringify(Z.metadata)}),(0,r.jsx)(H.Z,{variant:"light",className:"mx-auto flex items-center",onClick:()=>{y(null),w(null)},children:"Close"})]})})}),(0,r.jsx)(eZ.Z,{icon:eu.Z,size:"sm",onClick:()=>R(e)}),(0,r.jsx)(eZ.Z,{onClick:()=>z(e),icon:ex.Z,size:"sm"})]})]},e.token)})})]}),u&&(0,r.jsx)("div",{className:"fixed z-10 inset-0 overflow-y-auto",children:(0,r.jsxs)("div",{className:"flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0",children:[(0,r.jsx)("div",{className:"fixed inset-0 transition-opacity","aria-hidden":"true",children:(0,r.jsx)("div",{className:"absolute inset-0 bg-gray-500 opacity-75"})}),(0,r.jsx)("span",{className:"hidden sm:inline-block sm:align-middle sm:h-screen","aria-hidden":"true",children:"​"}),(0,r.jsxs)("div",{className:"inline-block align-bottom bg-white rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full",children:[(0,r.jsx)("div",{className:"bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4",children:(0,r.jsx)("div",{className:"sm:flex sm:items-start",children:(0,r.jsxs)("div",{className:"mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left",children:[(0,r.jsx)("h3",{className:"text-lg leading-6 font-medium text-gray-900",children:"Delete Key"}),(0,r.jsx)("div",{className:"mt-2",children:(0,r.jsx)("p",{className:"text-sm text-gray-500",children:"Are you sure you want to delete this key ?"})})]})})}),(0,r.jsxs)("div",{className:"bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse",children:[(0,r.jsx)(H.Z,{onClick:B,color:"red",className:"ml-2",children:"Delete"}),(0,r.jsx)(H.Z,{onClick:()=>{x(!1),j(null)},children:"Cancel"})]})]})]})})]}),I&&(0,r.jsx)(e=>{let{visible:l,onCancel:t,token:s,onSubmit:o}=e,[i]=er.Z.useForm(),[d,m]=(0,n.useState)(a),[h,u]=(0,n.useState)([]),[x,p]=(0,n.useState)(!1);return(0,r.jsx)(en.Z,{title:"Edit Key",visible:l,width:800,footer:null,onOk:()=>{i.validateFields().then(e=>{i.resetFields()}).catch(e=>{console.error("Validation failed:",e)})},onCancel:t,children:(0,r.jsxs)(er.Z,{form:i,onFinish:U,initialValues:s,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(er.Z.Item,{label:"Key Name",name:"key_alias",rules:[{required:!0,message:"Please input a key name"}],help:"required",children:(0,r.jsx)(eo.Z,{})}),(0,r.jsx)(er.Z.Item,{label:"Models",name:"models",rules:[{validator:(e,l)=>{let t=l.filter(e=>!d.models.includes(e)&&"all-team-models"!==e&&"all-proxy-models"!==e&&!d.models.includes("all-proxy-models"));return(console.log("errorModels: ".concat(t)),t.length>0)?Promise.reject("Some models are not part of the new team's models - ".concat(t,"Team models: ").concat(d.models)):Promise.resolve()}}],children:(0,r.jsxs)(ea.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:[(0,r.jsx)(eC,{value:"all-team-models",children:"All Team Models"},"all-team-models"),d&&d.models?d.models.includes("all-proxy-models")?T.filter(e=>"all-proxy-models"!==e).map(e=>(0,r.jsx)(eC,{value:e,children:e},e)):d.models.map(e=>(0,r.jsx)(eC,{value:e,children:e},e)):T.map(e=>(0,r.jsx)(eC,{value:e,children:e},e))]})}),(0,r.jsx)(er.Z.Item,{className:"mt-8",label:"Max Budget (USD)",name:"max_budget",help:"Budget cannot exceed team max budget: ".concat((null==d?void 0:d.max_budget)!==null&&(null==d?void 0:d.max_budget)!==void 0?null==d?void 0:d.max_budget:"unlimited"),rules:[{validator:async(e,l)=>{if(l&&d&&null!==d.max_budget&&l>d.max_budget)throw console.log("keyTeam.max_budget: ".concat(d.max_budget)),Error("Budget cannot exceed team max budget: $".concat(d.max_budget))}}],children:(0,r.jsx)(ei.Z,{step:.01,precision:2,width:200})}),(0,r.jsx)(er.Z.Item,{label:"token",name:"token",hidden:!0}),(0,r.jsx)(er.Z.Item,{label:"Team",name:"team_id",help:"the team this key belongs to",children:(0,r.jsx)(eA.Z,{value:s.team_alias,children:null==c?void 0:c.map((e,l)=>(0,r.jsx)(eN.Z,{value:e.team_id,onClick:()=>m(e),children:e.team_alias},l))})})]}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ec.ZP,{htmlType:"submit",children:"Edit Key"})})]})})},{visible:N,onCancel:()=>{C(!1),P(null)},token:I,onSubmit:U})]})},eP=t(76032),eT=t(35152),eE=e=>{let{userID:l,userRole:t,accessToken:s,userSpend:a,selectedTeam:o}=e;console.log("userSpend: ".concat(a));let[i,c]=(0,n.useState)(null!==a?a:0),[d,m]=(0,n.useState)(0),[h,u]=(0,n.useState)([]);(0,n.useEffect)(()=>{let e=async()=>{if(s&&l&&t&&"Admin"===t&&null==a)try{let e=await b(s);e&&(e.spend?c(e.spend):c(0),e.max_budget?m(e.max_budget):m(0))}catch(e){console.error("Error fetching global spend data:",e)}};(async()=>{try{if(null===l||null===t)return;if(null!==s){let e=(await v(s,l,t)).data.map(e=>e.id);console.log("available_model_names:",e),u(e)}}catch(e){console.error("Error fetching user models:",e)}})(),e()},[t,s,l]),(0,n.useEffect)(()=>{null!==a&&c(a)},[a]);let x=[];o&&o.models&&(x=o.models),x&&x.includes("all-proxy-models")?(console.log("user models:",h),x=h):x&&x.includes("all-team-models")?x=o.models:x&&0===x.length&&(x=h);let p=void 0!==i?i.toFixed(4):null;return console.log("spend in view user spend: ".concat(i)),(0,r.jsxs)("div",{className:"flex items-center",children:[(0,r.jsxs)("div",{children:[(0,r.jsxs)("p",{className:"text-tremor-default text-tremor-content dark:text-dark-tremor-content",children:["Total Spend"," "]}),(0,r.jsxs)("p",{className:"text-2xl text-tremor-content-strong dark:text-dark-tremor-content-strong font-semibold",children:["$",p]})]}),(0,r.jsx)("div",{className:"ml-auto",children:(0,r.jsxs)(X.Z,{children:[(0,r.jsx)(ee.Z,{children:(0,r.jsx)(el.Z,{children:"Team Models"})}),(0,r.jsx)(Q.Z,{className:"absolute right-0 z-10 bg-white p-2 shadow-lg max-w-xs",children:(0,r.jsx)(eP.Z,{children:x.map(e=>(0,r.jsx)(eT.Z,{children:(0,r.jsx)(el.Z,{children:e})},e))})})]})})]})},eF=e=>{let{userID:l,userRole:t,selectedTeam:s,accessToken:a}=e,[o,i]=(0,n.useState)([]);(0,n.useEffect)(()=>{(async()=>{try{if(null===l||null===t)return;if(null!==a){let e=(await v(a,l,t)).data.map(e=>e.id);console.log("available_model_names:",e),i(e)}}catch(e){console.error("Error fetching user models:",e)}})()},[a,l,t]);let c=[];return s&&s.models&&(c=s.models),c&&c.includes("all-proxy-models")&&(console.log("user models:",o),c=o),(0,r.jsx)(r.Fragment,{children:(0,r.jsx)("div",{className:"mb-5",children:(0,r.jsx)("p",{className:"text-3xl text-tremor-content-strong dark:text-dark-tremor-content-strong font-semibold",children:null==s?void 0:s.team_alias})})})},eO=e=>{let l,{teams:t,setSelectedTeam:s,userRole:a}=e,o={models:[],team_id:null,team_alias:"Default Team"},[i,c]=(0,n.useState)(o);return(l="App User"===a?t:t?[...t,o]:[o],"App User"===a)?null:(0,r.jsxs)("div",{className:"mt-5 mb-5",children:[(0,r.jsx)(et.Z,{children:"Select Team"}),(0,r.jsx)(el.Z,{children:"If you belong to multiple teams, this setting controls which team is used by default when creating new API Keys."}),(0,r.jsxs)(el.Z,{className:"mt-3 mb-3",children:[(0,r.jsx)("b",{children:"Default Team:"})," If no team_id is set for a key, it will be grouped under here."]}),l&&l.length>0?(0,r.jsx)(eA.Z,{defaultValue:"0",children:l.map((e,l)=>(0,r.jsx)(eN.Z,{value:String(l),onClick:()=>s(e),children:e.team_alias},l))}):(0,r.jsxs)(el.Z,{children:["No team created. ",(0,r.jsx)("b",{children:"Defaulting to personal account."})]})]})},eM=t(37963),eR=t(36083);console.log("isLocal:",!1);var eL=e=>{let{userID:l,userRole:t,teams:s,keys:a,setUserRole:i,userEmail:c,setUserEmail:d,setTeams:m,setKeys:h}=e,[u,x]=(0,n.useState)(null),p=(0,o.useSearchParams)();p.get("viewSpend"),(0,o.useRouter)();let j=p.get("token"),[g,f]=(0,n.useState)(null),[y,w]=(0,n.useState)(null),[_,k]=(0,n.useState)([]),S={models:[],team_alias:"Default Team",team_id:null},[A,N]=(0,n.useState)(s?s[0]:S);if(window.addEventListener("beforeunload",function(){sessionStorage.clear()}),(0,n.useEffect)(()=>{if(j){let e=(0,eM.o)(j);if(e){if(console.log("Decoded token:",e),console.log("Decoded key:",e.key),f(e.key),e.user_role){let l=function(e){if(!e)return"Undefined Role";switch(console.log("Received user role: ".concat(e)),e.toLowerCase()){case"app_owner":case"demo_app_owner":return"App Owner";case"app_admin":case"proxy_admin":return"Admin";case"proxy_admin_viewer":return"Admin Viewer";case"app_user":return"App User";default:return"Unknown Role"}}(e.user_role);console.log("Decoded user_role:",l),i(l)}else console.log("User role not defined");e.user_email?d(e.user_email):console.log("User Email is not set ".concat(e))}}if(l&&g&&t&&!a&&!u){let e=sessionStorage.getItem("userModels"+l);e?k(JSON.parse(e)):(async()=>{try{let e=await Z(g,l,t,!1,null,null);if(console.log("received teams in user dashboard: ".concat(Object.keys(e),"; team values: ").concat(Object.entries(e.teams))),"Admin"==t){let e=await b(g);x(e),console.log("globalSpend:",e)}else x(e.user_info);h(e.keys),m(e.teams);let s=[...e.teams];s.length>0?(console.log("response['teams']: ".concat(s)),N(s[0])):N(S),sessionStorage.setItem("userData"+l,JSON.stringify(e.keys)),sessionStorage.setItem("userSpendData"+l,JSON.stringify(e.user_info));let a=(await v(g,l,t)).data.map(e=>e.id);console.log("available_model_names:",a),k(a),console.log("userModels:",_),sessionStorage.setItem("userModels"+l,JSON.stringify(a))}catch(e){console.error("There was an error fetching the data",e)}})()}},[l,j,g,a,t]),(0,n.useEffect)(()=>{if(null!==a&&null!=A){let e=0;for(let l of a)A.hasOwnProperty("team_id")&&null!==l.team_id&&l.team_id===A.team_id&&(e+=l.spend);w(e)}else if(null!==a){let e=0;for(let l of a)e+=l.spend;w(e)}},[A]),null==l||null==j){let e="/sso/key/generate";return console.log("Full URL:",e),window.location.href=e,null}if(null==g)return null;if(null==t&&i("App Owner"),t&&"Admin Viewer"==t){let{Title:e,Paragraph:l}=eR.default;return(0,r.jsxs)("div",{children:[(0,r.jsx)(e,{level:1,children:"Access Denied"}),(0,r.jsx)(l,{children:"Ask your proxy admin for access to create keys"})]})}return console.log("inside user dashboard, selected team",A),console.log("teamSpend: ".concat(y)),(0,r.jsx)("div",{className:"w-full mx-4",children:(0,r.jsx)(Y.Z,{numItems:1,className:"gap-2 p-8 h-[75vh] w-full mt-2",children:(0,r.jsxs)(J.Z,{numColSpan:1,children:[(0,r.jsx)(eF,{userID:l,userRole:t,selectedTeam:A||null,accessToken:g}),(0,r.jsx)(eE,{userID:l,userRole:t,accessToken:g,userSpend:y,selectedTeam:A||null}),(0,r.jsx)(eI,{userID:l,userRole:t,accessToken:g,selectedTeam:A||null,data:a,setData:h,teams:s}),(0,r.jsx)(em,{userID:l,team:A||null,userRole:t,accessToken:g,data:a,setData:h},A?A.team_id:null),(0,r.jsx)(eO,{teams:s,setSelectedTeam:N,userRole:t})]})})})},eU=t(92836),eD=t(26734),ez=t(41608),eB=t(32126),eq=t(23682),eK=t(47047),eV=t(76628),eG=t(38302),eW=t(28683),eJ=t(1460),eY=t(78578),eH=t(63954),e$=e=>{let{modelID:l,accessToken:t}=e,[s,a]=(0,n.useState)(!1),o=async()=>{try{h.ZP.info("Making API Call"),a(!0);let e=await p(t,l);console.log("model delete Response:",e),h.ZP.success("Model ".concat(l," deleted successfully")),a(!1)}catch(e){console.error("Error deleting the model:",e)}};return(0,r.jsxs)("div",{children:[(0,r.jsx)(eZ.Z,{onClick:()=>a(!0),icon:ex.Z,size:"sm"}),(0,r.jsx)(en.Z,{open:s,onOk:o,okType:"danger",onCancel:()=>a(!1),children:(0,r.jsxs)(Y.Z,{numItems:1,className:"gap-2 w-full",children:[(0,r.jsx)(et.Z,{children:"Delete Model"}),(0,r.jsx)(J.Z,{numColSpan:1,children:(0,r.jsx)("p",{children:"Are you sure you want to delete this model? This action is irreversible."})}),(0,r.jsx)(J.Z,{numColSpan:1,children:(0,r.jsxs)("p",{children:["Model ID: ",(0,r.jsx)("b",{children:l})]})})]})})]})},eX=t(97766),eQ=t(46495);let{Title:e0,Link:e1}=eR.default;(s=a||(a={})).OpenAI="OpenAI",s.Azure="Azure",s.Anthropic="Anthropic",s.Google_AI_Studio="Gemini (Google AI Studio)",s.Bedrock="Amazon Bedrock",s.OpenAI_Compatible="OpenAI-Compatible Endpoints (Groq, Together AI, Mistral AI, etc.)",s.Vertex_AI="Vertex AI (Anthropic, Gemini, etc.)";let e2={OpenAI:"openai",Azure:"azure",Anthropic:"anthropic",Google_AI_Studio:"gemini",Bedrock:"bedrock",OpenAI_Compatible:"openai",Vertex_AI:"vertex_ai"},e4=async(e,l,t)=>{try{let s=Array.isArray(e.model)?e.model:[e.model];console.log("received deployments: ".concat(s)),console.log("received type of deployments: ".concat(typeof s)),s.forEach(async t=>{console.log("litellm_model: ".concat(t));let s={},a={};s.model=t;let r="";for(let[l,t]of Object.entries(e))if(""!==t){if("model_name"==l)r+=t;else if("custom_llm_provider"==l)continue;else if("model"==l)continue;else if("base_model"===l)a[l]=t;else if("litellm_extra_params"==l){console.log("litellm_extra_params:",t);let e={};if(t&&void 0!=t){try{e=JSON.parse(t)}catch(e){throw h.ZP.error("Failed to parse LiteLLM Extra Params: "+e,20),Error("Failed to parse litellm_extra_params: "+e)}for(let[l,t]of Object.entries(e))s[l]=t}}else s[l]=t}let n={model_name:r,litellm_params:s,model_info:a},o=await x(l,n);console.log("response for model create call: ".concat(o.data))}),t.resetFields()}catch(e){h.ZP.error("Failed to create model: "+e,20)}};var e8=e=>{var l,t,s;let{accessToken:o,token:i,userRole:c,userID:d,modelData:m={data:[]},setModelData:x}=e,[p,j]=(0,n.useState)([]),[g]=er.Z.useForm(),[f,y]=(0,n.useState)(null),[Z,w]=(0,n.useState)(""),[b,k]=(0,n.useState)([]),v=Object.values(a).filter(e=>isNaN(Number(e))),[S,A]=(0,n.useState)("OpenAI"),[N,C]=(0,n.useState)(""),[I,P]=(0,n.useState)(!1),[T,E]=(0,n.useState)(null),[F,M]=(0,n.useState)([]),[R,L]=(0,n.useState)(null),U=e=>{E(e),P(!0)},z=async e=>{if(console.log("handleEditSubmit:",e),null==o)return;let l={},t=null;for(let[s,a]of Object.entries(e))"model_id"!==s?l[s]=a:t=a;let s={litellm_params:l,model_info:{id:t}};console.log("handleEditSubmit payload:",s),await D(o,s),h.ZP.success("Model updated successfully, restart server to see updates"),P(!1),E(null)},B=()=>{w(new Date().toLocaleString())};if((0,n.useEffect)(()=>{if(!o||!i||!c||!d)return;let e=async()=>{try{let e=await _(o,d,c);console.log("Model data response:",e.data),x(e);let l=new Set;for(let t=0;t{let e=await u();console.log("received model cost map data: ".concat(Object.keys(e))),y(e)};null==f&&l(),B()},[o,i,c,d,f,Z]),!m||!o||!i||!c||!d)return(0,r.jsx)("div",{children:"Loading..."});let q=[];for(let e=0;e(console.log("GET PROVIDER CALLED! - ".concat(f)),null!=f&&"object"==typeof f&&e in f)?f[e].litellm_provider:"openai";if(a){let e=a.split("/"),l=e[0];n=1===e.length?h(a):l}else n="openai";r&&(o=null==r?void 0:r.input_cost_per_token,i=null==r?void 0:r.output_cost_per_token,c=null==r?void 0:r.max_tokens),(null==s?void 0:s.litellm_params)&&(d=Object.fromEntries(Object.entries(null==s?void 0:s.litellm_params).filter(e=>{let[l]=e;return"model"!==l&&"api_base"!==l}))),m.data[e].provider=n,m.data[e].input_cost=o,m.data[e].output_cost=i,m.data[e].max_tokens=c,m.data[e].api_base=null==s?void 0:null===(t=s.litellm_params)||void 0===t?void 0:t.api_base,m.data[e].cleanedLitellmParams=d,q.push(s.model_name),console.log(m.data[e])}if(c&&"Admin Viewer"==c){let{Title:e,Paragraph:l}=eR.default;return(0,r.jsxs)("div",{children:[(0,r.jsx)(e,{level:1,children:"Access Denied"}),(0,r.jsx)(l,{children:"Ask your proxy admin for access to view all models"})]})}let K=e=>{console.log("received provider string: ".concat(e));let l=Object.keys(a).find(l=>a[l]===e);if(l){let e=e2[l];console.log("mappingResult: ".concat(e));let t=[];"object"==typeof f&&Object.entries(f).forEach(l=>{let[s,a]=l;null!==a&&"object"==typeof a&&"litellm_provider"in a&&(a.litellm_provider===e||a.litellm_provider.includes(e))&&t.push(s)}),k(t),console.log("providerModels: ".concat(b))}},V=async()=>{try{h.ZP.info("Running health check..."),C("");let e=await W(o);C(e)}catch(e){console.error("Error running health check:",e),C("Error running health check")}};return console.log("selectedProvider: ".concat(S)),console.log("providerModels.length: ".concat(b.length)),(0,r.jsx)("div",{style:{width:"100%",height:"100%"},children:(0,r.jsxs)(eD.Z,{className:"gap-2 p-8 h-[75vh] w-full mt-2",children:[(0,r.jsxs)(ez.Z,{className:"flex justify-between mt-2 w-full items-center",children:[(0,r.jsxs)("div",{className:"flex",children:[(0,r.jsx)(eU.Z,{children:"All Models"}),(0,r.jsx)(eU.Z,{children:"Add Model"}),(0,r.jsx)(eU.Z,{children:(0,r.jsx)("pre",{children:"/health Models"})})]}),(0,r.jsxs)("div",{className:"flex items-center space-x-2",children:[Z&&(0,r.jsxs)(el.Z,{children:["Last Refreshed: ",Z]}),(0,r.jsx)(eZ.Z,{icon:eH.Z,variant:"shadow",size:"xs",className:"self-center",onClick:B})]})]}),(0,r.jsxs)(eq.Z,{children:[(0,r.jsxs)(eB.Z,{children:[(0,r.jsxs)(Y.Z,{children:[(0,r.jsxs)("div",{className:"flex items-center",children:[(0,r.jsx)(el.Z,{children:"Filter by Public Model Name"}),(0,r.jsxs)(eA.Z,{className:"mb-4 mt-2 ml-2 w-50",defaultValue:"all",onValueChange:e=>L("all"===e?"all":e),children:[(0,r.jsx)(eN.Z,{value:"all",children:"All Models"}),F.map((e,l)=>(0,r.jsx)(eN.Z,{value:e,onClick:()=>L(e),children:e},l))]})]}),(0,r.jsx)(eg.Z,{children:(0,r.jsxs)(ew.Z,{className:"mt-5",children:[(0,r.jsx)(ek.Z,{children:(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(ev.Z,{children:"Public Model Name "}),(0,r.jsx)(ev.Z,{children:"Provider"}),"Admin"===c&&(0,r.jsx)(ev.Z,{children:"API Base"}),(0,r.jsx)(ev.Z,{children:"Extra litellm Params"}),(0,r.jsx)(ev.Z,{children:"Input Price per token ($)"}),(0,r.jsx)(ev.Z,{children:"Output Price per token ($)"}),(0,r.jsx)(ev.Z,{children:"Max Tokens"})]})}),(0,r.jsx)(eb.Z,{children:m.data.filter(e=>"all"===R||e.model_name===R||null==R||""===R).map((e,l)=>(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(e_.Z,{children:(0,r.jsx)(el.Z,{children:e.model_name})}),(0,r.jsx)(e_.Z,{children:e.provider}),"Admin"===c&&(0,r.jsx)(e_.Z,{children:e.api_base}),(0,r.jsx)(e_.Z,{children:(0,r.jsxs)(X.Z,{children:[(0,r.jsx)(ee.Z,{children:(0,r.jsx)(el.Z,{children:"Litellm params"})}),(0,r.jsx)(Q.Z,{children:(0,r.jsx)("pre",{children:JSON.stringify(e.cleanedLitellmParams,null,2)})})]})}),(0,r.jsx)(e_.Z,{children:e.input_cost}),(0,r.jsx)(e_.Z,{children:e.output_cost}),(0,r.jsx)(e_.Z,{children:e.max_tokens}),(0,r.jsxs)(e_.Z,{children:[(0,r.jsx)(eZ.Z,{icon:eu.Z,size:"sm",onClick:()=>U(e)}),(0,r.jsx)(e$,{modelID:e.model_info.id,accessToken:o})]})]},l))})]})})]}),(0,r.jsx)(e=>{let{visible:l,onCancel:t,model:s,onSubmit:a}=e,[n]=er.Z.useForm(),o={},i="",c="";if(s){o=s.litellm_params,i=s.model_name;let e=s.model_info;e&&(c=e.id,console.log("model_id: ".concat(c)),o.model_id=c)}return(0,r.jsx)(en.Z,{title:"Edit Model "+i,visible:l,width:800,footer:null,onOk:()=>{n.validateFields().then(e=>{a(e),n.resetFields()}).catch(e=>{console.error("Validation failed:",e)})},onCancel:t,children:(0,r.jsxs)(er.Z,{form:n,onFinish:z,initialValues:o,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(er.Z.Item,{className:"mt-8",label:"api_base",name:"api_base",children:(0,r.jsx)($.Z,{})}),(0,r.jsx)(er.Z.Item,{label:"tpm",name:"tpm",tooltip:"int (optional) - Tokens limit for this deployment: in tokens per minute (tpm). Find this information on your model/providers website",children:(0,r.jsx)(ei.Z,{min:0,step:1})}),(0,r.jsx)(er.Z.Item,{label:"rpm",name:"rpm",tooltip:"int (optional) - Rate limit for this deployment: in requests per minute (rpm). Find this information on your model/providers website",children:(0,r.jsx)(ei.Z,{min:0,step:1})}),(0,r.jsx)(er.Z.Item,{label:"max_retries",name:"max_retries",children:(0,r.jsx)(ei.Z,{min:0,step:1})}),(0,r.jsx)(er.Z.Item,{label:"timeout",name:"timeout",tooltip:"int (optional) - Timeout in seconds for LLM requests (Defaults to 600 seconds)",children:(0,r.jsx)(ei.Z,{min:0,step:1})}),(0,r.jsx)(er.Z.Item,{label:"stream_timeout",name:"stream_timeout",tooltip:"int (optional) - Timeout for stream requests (seconds)",children:(0,r.jsx)(ei.Z,{min:0,step:1})}),(0,r.jsx)(er.Z.Item,{label:"model_id",name:"model_id",hidden:!0})]}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ec.ZP,{htmlType:"submit",children:"Save"})})]})})},{visible:I,onCancel:()=>{P(!1),E(null)},model:T,onSubmit:z})]}),(0,r.jsxs)(eB.Z,{className:"h-full",children:[(0,r.jsx)(e0,{level:2,children:"Add new model"}),(0,r.jsx)(eg.Z,{children:(0,r.jsxs)(er.Z,{form:g,onFinish:()=>{g.validateFields().then(e=>{e4(e,o,g)}).catch(e=>{console.error("Validation failed:",e)})},labelCol:{span:10},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(er.Z.Item,{rules:[{required:!0,message:"Required"}],label:"Provider:",name:"custom_llm_provider",tooltip:"E.g. OpenAI, Azure OpenAI, Anthropic, Bedrock, etc.",labelCol:{span:10},labelAlign:"left",children:(0,r.jsx)(eA.Z,{value:S.toString(),children:v.map((e,l)=>(0,r.jsx)(eN.Z,{value:e,onClick:()=>{K(e),A(e)},children:e},l))})}),(0,r.jsx)(er.Z.Item,{rules:[{required:!0,message:"Required"}],label:"Public Model Name",name:"model_name",tooltip:"Model name your users will pass in. Also used for load-balancing, LiteLLM will load balance between all models with this public name.",className:"mb-0",children:(0,r.jsx)($.Z,{placeholder:"Vertex AI (Anthropic, Gemini, etc.)"===(s=S.toString())?"gemini-pro":"Anthropic"==s?"claude-3-opus":"Amazon Bedrock"==s?"claude-3-opus":"Gemini (Google AI Studio)"==s?"gemini-pro":"gpt-3.5-turbo"})}),(0,r.jsxs)(eG.Z,{children:[(0,r.jsx)(eW.Z,{span:10}),(0,r.jsx)(eW.Z,{span:10,children:(0,r.jsx)(el.Z,{className:"mb-3 mt-1",children:"Model name your users will pass in."})})]}),(0,r.jsx)(er.Z.Item,{rules:[{required:!0,message:"Required"}],label:"LiteLLM Model Name(s)",name:"model",tooltip:"Actual model name used for making litellm.completion() call.",className:"mb-0",children:"Azure"===S?(0,r.jsx)($.Z,{placeholder:"Enter model name"}):b.length>0?(0,r.jsx)(eK.Z,{value:b,children:b.map((e,l)=>(0,r.jsx)(eV.Z,{value:e,children:e},l))}):(0,r.jsx)($.Z,{placeholder:"gpt-3.5-turbo-0125"})}),(0,r.jsxs)(eG.Z,{children:[(0,r.jsx)(eW.Z,{span:10}),(0,r.jsx)(eW.Z,{span:10,children:(0,r.jsxs)(el.Z,{className:"mb-3 mt-1",children:["Actual model name used for making ",(0,r.jsx)(e1,{href:"https://docs.litellm.ai/docs/providers",target:"_blank",children:"litellm.completion() call"}),". We'll ",(0,r.jsx)(e1,{href:"https://docs.litellm.ai/docs/proxy/reliability#step-1---set-deployments-on-config",target:"_blank",children:"loadbalance"})," models with the same 'public name'"]})})]}),"Amazon Bedrock"!=S&&"Vertex AI (Anthropic, Gemini, etc.)"!=S&&(0,r.jsx)(er.Z.Item,{rules:[{required:!0,message:"Required"}],label:"API Key",name:"api_key",children:(0,r.jsx)($.Z,{placeholder:"sk-",type:"password"})}),"OpenAI"==S&&(0,r.jsx)(er.Z.Item,{label:"Organization ID",name:"organization_id",children:(0,r.jsx)($.Z,{placeholder:"[OPTIONAL] my-unique-org"})}),"Vertex AI (Anthropic, Gemini, etc.)"==S&&(0,r.jsx)(er.Z.Item,{rules:[{required:!0,message:"Required"}],label:"Vertex Project",name:"vertex_project",children:(0,r.jsx)($.Z,{placeholder:"adroit-cadet-1234.."})}),"Vertex AI (Anthropic, Gemini, etc.)"==S&&(0,r.jsx)(er.Z.Item,{rules:[{required:!0,message:"Required"}],label:"Vertex Location",name:"vertex_location",children:(0,r.jsx)($.Z,{placeholder:"us-east-1"})}),"Vertex AI (Anthropic, Gemini, etc.)"==S&&(0,r.jsx)(er.Z.Item,{rules:[{required:!0,message:"Required"}],label:"Vertex Credentials",name:"vertex_credentials",className:"mb-0",children:(0,r.jsx)(eQ.Z,{name:"file",accept:".json",beforeUpload:e=>{if("application/json"===e.type){let l=new FileReader;l.onload=e=>{if(e.target){let l=e.target.result;g.setFieldsValue({vertex_credentials:l})}},l.readAsText(e)}return!1},onChange(e){"uploading"!==e.file.status&&console.log(e.file,e.fileList),"done"===e.file.status?h.ZP.success("".concat(e.file.name," file uploaded successfully")):"error"===e.file.status&&h.ZP.error("".concat(e.file.name," file upload failed."))},children:(0,r.jsx)(ec.ZP,{icon:(0,r.jsx)(eX.Z,{}),children:"Click to Upload"})})}),"Vertex AI (Anthropic, Gemini, etc.)"==S&&(0,r.jsxs)(eG.Z,{children:[(0,r.jsx)(eW.Z,{span:10}),(0,r.jsx)(eW.Z,{span:10,children:(0,r.jsx)(el.Z,{className:"mb-3 mt-1",children:"Give litellm a gcp service account(.json file), so it can make the relevant calls"})})]}),("Azure"==S||"OpenAI-Compatible Endpoints (Groq, Together AI, Mistral AI, etc.)"==S)&&(0,r.jsx)(er.Z.Item,{rules:[{required:!0,message:"Required"}],label:"API Base",name:"api_base",children:(0,r.jsx)($.Z,{placeholder:"https://..."})}),"Azure"==S&&(0,r.jsx)(er.Z.Item,{rules:[{required:!0,message:"Required"}],label:"API Version",name:"api_version",children:(0,r.jsx)($.Z,{placeholder:"2023-07-01-preview"})}),"Azure"==S&&(0,r.jsxs)(er.Z.Item,{label:"Base Model",name:"base_model",children:[(0,r.jsx)($.Z,{placeholder:"azure/gpt-3.5-turbo"}),(0,r.jsxs)(el.Z,{children:["The actual model your azure deployment uses. Used for accurate cost tracking. Select name from ",(0,r.jsx)(e1,{href:"https://github.com/BerriAI/litellm/blob/main/model_prices_and_context_window.json",target:"_blank",children:"here"})]})]}),"Amazon Bedrock"==S&&(0,r.jsx)(er.Z.Item,{rules:[{required:!0,message:"Required"}],label:"AWS Access Key ID",name:"aws_access_key_id",tooltip:"You can provide the raw key or the environment variable (e.g. `os.environ/MY_SECRET_KEY`).",children:(0,r.jsx)($.Z,{placeholder:""})}),"Amazon Bedrock"==S&&(0,r.jsx)(er.Z.Item,{rules:[{required:!0,message:"Required"}],label:"AWS Secret Access Key",name:"aws_secret_access_key",tooltip:"You can provide the raw key or the environment variable (e.g. `os.environ/MY_SECRET_KEY`).",children:(0,r.jsx)($.Z,{placeholder:""})}),"Amazon Bedrock"==S&&(0,r.jsx)(er.Z.Item,{rules:[{required:!0,message:"Required"}],label:"AWS Region Name",name:"aws_region_name",tooltip:"You can provide the raw key or the environment variable (e.g. `os.environ/MY_SECRET_KEY`).",children:(0,r.jsx)($.Z,{placeholder:"us-east-1"})}),(0,r.jsx)(er.Z.Item,{label:"LiteLLM Params",name:"litellm_extra_params",tooltip:"Optional litellm params used for making a litellm.completion() call.",className:"mb-0",children:(0,r.jsx)(eY.Z,{rows:4,placeholder:'{ "rpm": 100, "timeout": 0, "stream_timeout": 0 }'})}),(0,r.jsxs)(eG.Z,{children:[(0,r.jsx)(eW.Z,{span:10}),(0,r.jsx)(eW.Z,{span:10,children:(0,r.jsxs)(el.Z,{className:"mb-3 mt-1",children:["Pass JSON of litellm supported params ",(0,r.jsx)(e1,{href:"https://docs.litellm.ai/docs/completion/input",target:"_blank",children:"litellm.completion() call"})]})})]})]}),(0,r.jsx)("div",{style:{textAlign:"center",marginTop:"10px"},children:(0,r.jsx)(ec.ZP,{htmlType:"submit",children:"Add Model"})}),(0,r.jsx)(eJ.Z,{title:"Get help on our github",children:(0,r.jsx)(eR.default.Link,{href:"https://github.com/BerriAI/litellm/issues",children:"Need Help?"})})]})})]}),(0,r.jsx)(eB.Z,{children:(0,r.jsxs)(eg.Z,{children:[(0,r.jsx)(el.Z,{children:"`/health` will run a very small request through your models configured on litellm"}),(0,r.jsx)(H.Z,{onClick:V,children:"Run `/health`"}),N&&(0,r.jsx)("pre",{children:JSON.stringify(N,null,2)})]})})]})]})})};let{Option:e5}=ea.default;var e3=e=>{let{userID:l,accessToken:t,teams:s}=e,[a]=er.Z.useForm(),[o,i]=(0,n.useState)(!1),[c,d]=(0,n.useState)(null),[m,u]=(0,n.useState)([]);(0,n.useEffect)(()=>{(async()=>{try{let e=await v(t,l,"any"),s=[];for(let l=0;l{i(!1),a.resetFields()},p=()=>{i(!1),d(null),a.resetFields()},j=async e=>{try{h.ZP.info("Making API Call"),i(!0),console.log("formValues in create user:",e);let s=await g(t,null,e);console.log("user create Response:",s),d(s.key),h.ZP.success("API user Created"),a.resetFields(),localStorage.removeItem("userData"+l)}catch(e){console.error("Error creating the user:",e)}};return(0,r.jsxs)("div",{children:[(0,r.jsx)(H.Z,{className:"mx-auto",onClick:()=>i(!0),children:"+ Invite User"}),(0,r.jsxs)(en.Z,{title:"Invite User",visible:o,width:800,footer:null,onOk:x,onCancel:p,children:[(0,r.jsx)(el.Z,{className:"mb-1",children:"Invite a user to login to the Admin UI and create Keys"}),(0,r.jsx)(el.Z,{className:"mb-6",children:(0,r.jsx)("b",{children:"Note: SSO Setup Required for this"})}),(0,r.jsxs)(er.Z,{form:a,onFinish:j,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsx)(er.Z.Item,{label:"User Email",name:"user_email",children:(0,r.jsx)($.Z,{placeholder:""})}),(0,r.jsx)(er.Z.Item,{label:"Team ID",name:"team_id",children:(0,r.jsx)(ea.default,{placeholder:"Select Team ID",style:{width:"100%"},children:s?s.map(e=>(0,r.jsx)(e5,{value:e.team_id,children:e.team_alias},e.team_id)):(0,r.jsx)(e5,{value:null,children:"Default Team"},"default")})}),(0,r.jsx)(er.Z.Item,{label:"Metadata",name:"metadata",children:(0,r.jsx)(eo.Z.TextArea,{rows:4,placeholder:"Enter metadata as JSON"})}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ec.ZP,{htmlType:"submit",children:"Create User"})})]})]}),c&&(0,r.jsxs)(en.Z,{title:"User Created Successfully",visible:o,onOk:x,onCancel:p,footer:null,children:[(0,r.jsx)("p",{children:"User has been created to access your proxy. Please Ask them to Log In."}),(0,r.jsx)("br",{}),(0,r.jsx)("p",{children:(0,r.jsx)("b",{children:"Note: This Feature is only supported through SSO on the Admin UI"})})]})]})},e6=e=>{let{accessToken:l,token:t,keys:s,userRole:a,userID:o,teams:i,setKeys:c}=e,[d,m]=(0,n.useState)(null),[h,u]=(0,n.useState)(null),[x,p]=(0,n.useState)(0),[j,g]=n.useState(null),[f,y]=(0,n.useState)(null);if((0,n.useEffect)(()=>{if(!l||!t||!a||!o)return;let e=async()=>{try{let e=await Z(l,null,a,!0,x,25);console.log("user data response:",e),m(e)}catch(e){console.error("There was an error fetching the model data",e)}};l&&t&&a&&o&&e();let s=async()=>{try{let e=await T(l,null);console.log("user data response:",e),u(e)}catch(e){console.error("There was an error fetching the model data",e)}};a&&("Admin"==a||"Admin Viewer"==a)&&!h&&s()},[l,t,a,o,x]),!d||!l||!t||!a||!o)return(0,r.jsx)("div",{children:"Loading..."});let w=async e=>{try{let t=await T(l,e);console.log("user data response:",t),u(t)}catch(e){console.error("There was an error fetching the model data",e)}};return(0,r.jsx)("div",{style:{width:"100%"},children:(0,r.jsxs)(Y.Z,{className:"gap-2 p-2 h-[80vh] w-full mt-8",children:[(0,r.jsx)(e3,{userID:o,accessToken:l,teams:i}),(0,r.jsxs)(eg.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[80vh] mb-4",children:[(0,r.jsxs)("div",{className:"mb-4 mt-1",children:[(0,r.jsxs)(el.Z,{children:[(0,r.jsx)("b",{children:"Key Owners: "})," Users on LiteLLM that created API Keys. Automatically tracked by LiteLLM"]}),(0,r.jsxs)(el.Z,{className:"mt-1",children:[(0,r.jsx)("b",{children:"End Users: "}),"End Users of your LLM API calls. Tracked When a `user` param is passed in your LLM calls"]})]}),(0,r.jsxs)(eD.Z,{children:[(0,r.jsxs)(ez.Z,{variant:"line",defaultValue:"1",children:[(0,r.jsx)(eU.Z,{value:"1",children:"Key Owners"}),(0,r.jsx)(eU.Z,{value:"2",children:"End-Users"})]}),(0,r.jsxs)(eq.Z,{children:[(0,r.jsx)(eB.Z,{children:(0,r.jsxs)(ew.Z,{className:"mt-5",children:[(0,r.jsx)(ek.Z,{children:(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(ev.Z,{children:"User ID"}),(0,r.jsx)(ev.Z,{children:"User Email"}),(0,r.jsx)(ev.Z,{children:"User Models"}),(0,r.jsx)(ev.Z,{children:"User Spend ($ USD)"}),(0,r.jsx)(ev.Z,{children:"User Max Budget ($ USD)"}),(0,r.jsx)(ev.Z,{children:"User API Key Aliases"})]})}),(0,r.jsx)(eb.Z,{children:d.map(e=>(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(e_.Z,{children:e.user_id}),(0,r.jsx)(e_.Z,{children:e.user_email}),(0,r.jsx)(e_.Z,{children:e.models&&e.models.length>0?e.models:"All Models"}),(0,r.jsx)(e_.Z,{children:e.spend?e.spend:0}),(0,r.jsx)(e_.Z,{children:e.max_budget?e.max_budget:"Unlimited"}),(0,r.jsx)(e_.Z,{children:(0,r.jsx)(Y.Z,{numItems:2,children:e&&e.key_aliases&&e.key_aliases.filter(e=>null!==e).length>0?(0,r.jsx)(ep.Z,{size:"xs",color:"indigo",children:e.key_aliases.filter(e=>null!==e).join(", ")}):(0,r.jsx)(ep.Z,{size:"xs",color:"gray",children:"No Keys"})})})]},e.user_id))})]})}),(0,r.jsxs)(eB.Z,{children:[(0,r.jsxs)("div",{className:"flex items-center",children:[(0,r.jsx)("div",{className:"flex-1"}),(0,r.jsxs)("div",{className:"flex-1 flex justify-between items-center",children:[(0,r.jsx)(el.Z,{className:"w-1/4 mr-2 text-right",children:"Key"}),(0,r.jsx)(eA.Z,{defaultValue:"1",className:"w-3/4",children:null==s?void 0:s.map((e,l)=>{if(e&&null!==e.key_alias&&e.key_alias.length>0)return(0,r.jsx)(eN.Z,{value:String(l),onClick:()=>w(e.token),children:e.key_alias},l)})})]})]}),(0,r.jsxs)(ew.Z,{className:"max-h-[70vh] min-h-[500px]",children:[(0,r.jsx)(ek.Z,{children:(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(ev.Z,{children:"End User"}),(0,r.jsx)(ev.Z,{children:"Spend"}),(0,r.jsx)(ev.Z,{children:"Total Events"})]})}),(0,r.jsx)(eb.Z,{children:null==h?void 0:h.map((e,l)=>(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(e_.Z,{children:e.end_user}),(0,r.jsx)(e_.Z,{children:e.total_spend}),(0,r.jsx)(e_.Z,{children:e.total_events})]},l))})]})]})]})]})]}),function(){if(!d)return null;let e=Math.ceil(d.length/25);return(0,r.jsxs)("div",{className:"flex justify-between items-center",children:[(0,r.jsxs)("div",{children:["Showing Page ",x+1," of ",e]}),(0,r.jsxs)("div",{className:"flex",children:[(0,r.jsx)("button",{className:"bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-l focus:outline-none",disabled:0===x,onClick:()=>p(x-1),children:"← Prev"}),(0,r.jsx)("button",{className:"bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-r focus:outline-none",onClick:()=>{p(x+1)},children:"Next →"})]})]})}()]})})},e7=e=>{let{teams:l,searchParams:t,accessToken:s,setTeams:a,userID:o,userRole:i}=e,[c]=er.Z.useForm(),[d]=er.Z.useForm(),{Title:m,Paragraph:u}=eR.default,[x,p]=(0,n.useState)(""),[j,g]=(0,n.useState)(!1),[f,Z]=(0,n.useState)(l?l[0]:null),[b,_]=(0,n.useState)(!1),[k,S]=(0,n.useState)(!1),[A,N]=(0,n.useState)([]),[C,I]=(0,n.useState)(!1),[P,T]=(0,n.useState)(null),[E,F]=(0,n.useState)({}),O=e=>{Z(e),g(!0)},M=async e=>{let t=e.team_id;if(console.log("handleEditSubmit:",e),null==s)return;let r=await U(s,e);l&&a(l.map(e=>e.team_id===t?r.data:e)),h.ZP.success("Team updated successfully"),g(!1),Z(null)},L=async e=>{T(e),I(!0)},D=async()=>{if(null!=P&&null!=l&&null!=s){try{await y(s,P);let e=l.filter(e=>e.team_id!==P);a(e)}catch(e){console.error("Error deleting the team:",e)}I(!1),T(null)}};(0,n.useEffect)(()=>{let e=async()=>{try{if(null===o||null===i||null===s||null===l)return;console.log("fetching team info:");let e={};for(let t=0;t<(null==l?void 0:l.length);t++){let a=l[t].team_id,r=await w(s,a);console.log("teamInfo response:",r),null!==r&&(e={...e,[a]:r})}F(e)}catch(e){console.error("Error fetching team info:",e)}};(async()=>{try{if(null===o||null===i)return;if(null!==s){let e=(await v(s,o,i)).data.map(e=>e.id);console.log("available_model_names:",e),N(e)}}catch(e){console.error("Error fetching user models:",e)}})(),e()},[s,o,i,l]);let B=async e=>{try{if(null!=s){h.ZP.info("Creating Team");let t=await R(s,e);null!==l?a([...l,t]):a([t]),console.log("response for team create call: ".concat(t)),h.ZP.success("Team created"),_(!1)}}catch(e){console.error("Error creating the team:",e),h.ZP.error("Error creating the team: "+e,20)}},q=async e=>{try{if(null!=s&&null!=l){h.ZP.info("Adding Member");let t={role:"user",user_email:e.user_email,user_id:e.user_id},r=await z(s,f.team_id,t);console.log("response for team create call: ".concat(r.data));let n=l.findIndex(e=>(console.log("team.team_id=".concat(e.team_id,"; response.data.team_id=").concat(r.data.team_id)),e.team_id===r.data.team_id));if(console.log("foundIndex: ".concat(n)),-1!==n){let e=[...l];e[n]=r.data,a(e),Z(r.data)}S(!1)}}catch(e){console.error("Error creating the team:",e)}};return console.log("received teams ".concat(l)),(0,r.jsx)("div",{className:"w-full mx-4",children:(0,r.jsxs)(Y.Z,{numItems:1,className:"gap-2 p-8 h-[75vh] w-full mt-2",children:[(0,r.jsxs)(J.Z,{numColSpan:1,children:[(0,r.jsx)(m,{level:4,children:"All Teams"}),(0,r.jsxs)(eg.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:[(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(ek.Z,{children:(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(ev.Z,{children:"Team Name"}),(0,r.jsx)(ev.Z,{children:"Spend (USD)"}),(0,r.jsx)(ev.Z,{children:"Budget (USD)"}),(0,r.jsx)(ev.Z,{children:"Models"}),(0,r.jsx)(ev.Z,{children:"TPM / RPM Limits"}),(0,r.jsx)(ev.Z,{children:"Info"})]})}),(0,r.jsx)(eb.Z,{children:l&&l.length>0?l.map(e=>(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(e_.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:e.team_alias}),(0,r.jsx)(e_.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:e.spend}),(0,r.jsx)(e_.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:e.max_budget?e.max_budget:"No limit"}),(0,r.jsx)(e_.Z,{style:{maxWidth:"8-x",whiteSpace:"pre-wrap",overflow:"hidden"},children:Array.isArray(e.models)?(0,r.jsx)("div",{style:{display:"flex",flexDirection:"column"},children:0===e.models.length?(0,r.jsx)(ep.Z,{size:"xs",className:"mb-1",color:"red",children:(0,r.jsx)(el.Z,{children:"All Proxy Models"})}):e.models.map((e,l)=>"all-proxy-models"===e?(0,r.jsx)(ep.Z,{size:"xs",className:"mb-1",color:"red",children:(0,r.jsx)(el.Z,{children:"All Proxy Models"})},l):(0,r.jsx)(ep.Z,{size:"xs",className:"mb-1",color:"blue",children:(0,r.jsx)(el.Z,{children:e.length>30?"".concat(e.slice(0,30),"..."):e})},l))}):null}),(0,r.jsx)(e_.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,r.jsxs)(el.Z,{children:["TPM:"," ",e.tpm_limit?e.tpm_limit:"Unlimited"," ",(0,r.jsx)("br",{}),"RPM:"," ",e.rpm_limit?e.rpm_limit:"Unlimited"]})}),(0,r.jsxs)(e_.Z,{children:[(0,r.jsxs)(el.Z,{children:[E&&e.team_id&&E[e.team_id]&&E[e.team_id].keys&&E[e.team_id].keys.length," Keys"]}),(0,r.jsxs)(el.Z,{children:[E&&e.team_id&&E[e.team_id]&&E[e.team_id].team_info&&E[e.team_id].team_info.members_with_roles&&E[e.team_id].team_info.members_with_roles.length," Members"]})]}),(0,r.jsxs)(e_.Z,{children:[(0,r.jsx)(eZ.Z,{icon:eu.Z,size:"sm",onClick:()=>O(e)}),(0,r.jsx)(eZ.Z,{onClick:()=>L(e.team_id),icon:ex.Z,size:"sm"})]})]},e.team_id)):null})]}),C&&(0,r.jsx)("div",{className:"fixed z-10 inset-0 overflow-y-auto",children:(0,r.jsxs)("div",{className:"flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0",children:[(0,r.jsx)("div",{className:"fixed inset-0 transition-opacity","aria-hidden":"true",children:(0,r.jsx)("div",{className:"absolute inset-0 bg-gray-500 opacity-75"})}),(0,r.jsx)("span",{className:"hidden sm:inline-block sm:align-middle sm:h-screen","aria-hidden":"true",children:"​"}),(0,r.jsxs)("div",{className:"inline-block align-bottom bg-white rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full",children:[(0,r.jsx)("div",{className:"bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4",children:(0,r.jsx)("div",{className:"sm:flex sm:items-start",children:(0,r.jsxs)("div",{className:"mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left",children:[(0,r.jsx)("h3",{className:"text-lg leading-6 font-medium text-gray-900",children:"Delete Team"}),(0,r.jsx)("div",{className:"mt-2",children:(0,r.jsx)("p",{className:"text-sm text-gray-500",children:"Are you sure you want to delete this team ?"})})]})})}),(0,r.jsxs)("div",{className:"bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse",children:[(0,r.jsx)(H.Z,{onClick:D,color:"red",className:"ml-2",children:"Delete"}),(0,r.jsx)(H.Z,{onClick:()=>{I(!1),T(null)},children:"Cancel"})]})]})]})})]})]}),(0,r.jsxs)(J.Z,{numColSpan:1,children:[(0,r.jsx)(H.Z,{className:"mx-auto",onClick:()=>_(!0),children:"+ Create New Team"}),(0,r.jsx)(en.Z,{title:"Create Team",visible:b,width:800,footer:null,onOk:()=>{_(!1),c.resetFields()},onCancel:()=>{_(!1),c.resetFields()},children:(0,r.jsxs)(er.Z,{form:c,onFinish:B,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(er.Z.Item,{label:"Team Name",name:"team_alias",rules:[{required:!0,message:"Please input a team name"}],children:(0,r.jsx)($.Z,{placeholder:""})}),(0,r.jsx)(er.Z.Item,{label:"Models",name:"models",children:(0,r.jsxs)(ea.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:[(0,r.jsx)(ea.default.Option,{value:"all-proxy-models",children:"All Proxy Models"},"all-proxy-models"),A.map(e=>(0,r.jsx)(ea.default.Option,{value:e,children:e},e))]})}),(0,r.jsx)(er.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,r.jsx)(ei.Z,{step:.01,precision:2,width:200})}),(0,r.jsx)(er.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,r.jsx)(ei.Z,{step:1,width:400})}),(0,r.jsx)(er.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,r.jsx)(ei.Z,{step:1,width:400})})]}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ec.ZP,{htmlType:"submit",children:"Create Team"})})]})})]}),(0,r.jsxs)(J.Z,{numColSpan:1,children:[(0,r.jsx)(m,{level:4,children:"Team Members"}),(0,r.jsx)(u,{children:"If you belong to multiple teams, this setting controls which teams members you see."}),l&&l.length>0?(0,r.jsx)(eA.Z,{defaultValue:"0",children:l.map((e,l)=>(0,r.jsx)(eN.Z,{value:String(l),onClick:()=>{Z(e)},children:e.team_alias},l))}):(0,r.jsxs)(u,{children:["No team created. ",(0,r.jsx)("b",{children:"Defaulting to personal account."})]})]}),(0,r.jsxs)(J.Z,{numColSpan:1,children:[(0,r.jsx)(eg.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(ek.Z,{children:(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(ev.Z,{children:"Member Name"}),(0,r.jsx)(ev.Z,{children:"Role"})]})}),(0,r.jsx)(eb.Z,{children:f?f.members_with_roles.map((e,l)=>(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(e_.Z,{children:e.user_email?e.user_email:e.user_id?e.user_id:null}),(0,r.jsx)(e_.Z,{children:e.role})]},l)):null})]})}),f&&(0,r.jsx)(e=>{let{visible:l,onCancel:t,team:s,onSubmit:a}=e,[n]=er.Z.useForm();return(0,r.jsx)(en.Z,{title:"Edit Team",visible:l,width:800,footer:null,onOk:()=>{n.validateFields().then(e=>{a({...e,team_id:s.team_id}),n.resetFields()}).catch(e=>{console.error("Validation failed:",e)})},onCancel:t,children:(0,r.jsxs)(er.Z,{form:n,onFinish:M,initialValues:s,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(er.Z.Item,{label:"Team Name",name:"team_alias",rules:[{required:!0,message:"Please input a team name"}],children:(0,r.jsx)(eo.Z,{})}),(0,r.jsx)(er.Z.Item,{label:"Models",name:"models",children:(0,r.jsxs)(ea.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:[(0,r.jsx)(ea.default.Option,{value:"all-proxy-models",children:"All Proxy Models"},"all-proxy-models"),A&&A.map(e=>(0,r.jsx)(ea.default.Option,{value:e,children:e},e))]})}),(0,r.jsx)(er.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,r.jsx)(ei.Z,{step:.01,precision:2,width:200})}),(0,r.jsx)(er.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,r.jsx)(ei.Z,{step:1,width:400})}),(0,r.jsx)(er.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,r.jsx)(ei.Z,{step:1,width:400})}),(0,r.jsx)(er.Z.Item,{label:"Requests per minute Limit (RPM)",name:"team_id",hidden:!0})]}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ec.ZP,{htmlType:"submit",children:"Edit Team"})})]})})},{visible:j,onCancel:()=>{g(!1),Z(null)},team:f,onSubmit:M})]}),(0,r.jsxs)(J.Z,{numColSpan:1,children:[(0,r.jsx)(H.Z,{className:"mx-auto mb-5",onClick:()=>S(!0),children:"+ Add member"}),(0,r.jsx)(en.Z,{title:"Add member",visible:k,width:800,footer:null,onOk:()=>{S(!1),d.resetFields()},onCancel:()=>{S(!1),d.resetFields()},children:(0,r.jsxs)(er.Z,{form:c,onFinish:q,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(er.Z.Item,{label:"Email",name:"user_email",className:"mb-4",children:(0,r.jsx)(eo.Z,{name:"user_email",className:"px-3 py-2 border rounded-md w-full"})}),(0,r.jsx)("div",{className:"text-center mb-4",children:"OR"}),(0,r.jsx)(er.Z.Item,{label:"User ID",name:"user_id",className:"mb-4",children:(0,r.jsx)(eo.Z,{name:"user_id",className:"px-3 py-2 border rounded-md w-full"})})]}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ec.ZP,{htmlType:"submit",children:"Add member"})})]})})]})]})})},e9=t(18190),le=e=>{let l,{searchParams:t,accessToken:s,showSSOBanner:a}=e,[o]=er.Z.useForm(),[i]=er.Z.useForm(),{Title:c,Paragraph:d}=eR.default,[m,u]=(0,n.useState)(""),[x,p]=(0,n.useState)(null),[j,g]=(0,n.useState)(!1),[f,y]=(0,n.useState)(!1),[Z,w]=(0,n.useState)(!1),[b,_]=(0,n.useState)(!1),[k,v]=(0,n.useState)(!1);try{l=window.location.origin}catch(e){l=""}l+="/fallback/login";let S=()=>{v(!1)},A=["proxy_admin","proxy_admin_viewer"];(0,n.useEffect)(()=>{(async()=>{if(null!=s){let e=[],l=await M(s,"proxy_admin_viewer");l.forEach(l=>{e.push({user_role:l.user_role,user_id:l.user_id,user_email:l.user_email})}),console.log("proxy viewers: ".concat(l));let t=await M(s,"proxy_admin");t.forEach(l=>{e.push({user_role:l.user_role,user_id:l.user_id,user_email:l.user_email})}),console.log("proxy admins: ".concat(t)),console.log("combinedList: ".concat(e)),p(e)}})()},[s]);let N=()=>{w(!1),i.resetFields()},C=()=>{w(!1),i.resetFields()},I=e=>(0,r.jsxs)(er.Z,{form:o,onFinish:e,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(er.Z.Item,{label:"Email",name:"user_email",className:"mb-4",children:(0,r.jsx)(eo.Z,{name:"user_email",className:"px-3 py-2 border rounded-md w-full"})}),(0,r.jsx)("div",{className:"text-center mb-4",children:"OR"}),(0,r.jsx)(er.Z.Item,{label:"User ID",name:"user_id",className:"mb-4",children:(0,r.jsx)(eo.Z,{name:"user_id",className:"px-3 py-2 border rounded-md w-full"})})]}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ec.ZP,{htmlType:"submit",children:"Add member"})})]}),P=(e,l,t)=>(0,r.jsxs)(er.Z,{form:o,onFinish:e,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(er.Z.Item,{rules:[{required:!0,message:"Required"}],label:"User Role",name:"user_role",labelCol:{span:10},labelAlign:"left",children:(0,r.jsx)(eA.Z,{value:l,children:A.map((e,l)=>(0,r.jsx)(eN.Z,{value:e,children:e},l))})}),(0,r.jsx)(er.Z.Item,{label:"Team ID",name:"user_id",hidden:!0,initialValue:t,valuePropName:"user_id",className:"mt-8",children:(0,r.jsx)(eo.Z,{value:t,disabled:!0})})]}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ec.ZP,{htmlType:"submit",children:"Update role"})})]}),T=async e=>{try{if(null!=s&&null!=x){h.ZP.info("Making API Call");let l=await B(s,e,null);console.log("response for team create call: ".concat(l));let t=x.findIndex(e=>(console.log("user.user_id=".concat(e.user_id,"; response.user_id=").concat(l.user_id)),e.user_id===l.user_id));console.log("foundIndex: ".concat(t)),-1==t&&(console.log("updates admin with new user"),x.push(l),p(x)),h.ZP.success("Refresh tab to see updated user role"),w(!1)}}catch(e){console.error("Error creating the key:",e)}},E=async e=>{try{if(null!=s&&null!=x){h.ZP.info("Making API Call");let l=await B(s,e,"proxy_admin_viewer");console.log("response for team create call: ".concat(l));let t=x.findIndex(e=>(console.log("user.user_id=".concat(e.user_id,"; response.user_id=").concat(l.user_id)),e.user_id===l.user_id));console.log("foundIndex: ".concat(t)),-1==t&&(console.log("updates admin with new user"),x.push(l),p(x)),g(!1)}}catch(e){console.error("Error creating the key:",e)}},F=async e=>{try{if(null!=s&&null!=x){h.ZP.info("Making API Call"),e.user_email,e.user_id;let l=await B(s,e,"proxy_admin");console.log("response for team create call: ".concat(l));let t=x.findIndex(e=>(console.log("user.user_id=".concat(e.user_id,"; response.user_id=").concat(l.user_id)),e.user_id===l.user_id));console.log("foundIndex: ".concat(t)),-1==t&&(console.log("updates admin with new user"),x.push(l),p(x)),y(!1)}}catch(e){console.error("Error creating the key:",e)}},O=async e=>{null!=s&&G(s,{environment_variables:{PROXY_BASE_URL:e.proxy_base_url,GOOGLE_CLIENT_ID:e.google_client_id,GOOGLE_CLIENT_SECRET:e.google_client_secret}})};return console.log("admins: ".concat(null==x?void 0:x.length)),(0,r.jsxs)("div",{className:"w-full m-2 mt-2 p-8",children:[(0,r.jsx)(c,{level:4,children:"Admin Access "}),(0,r.jsxs)(d,{children:[a&&(0,r.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/ui#restrict-ui-access",children:"Requires SSO Setup"}),(0,r.jsx)("br",{}),(0,r.jsx)("b",{children:"Proxy Admin: "})," Can create keys, teams, users, add models, etc. ",(0,r.jsx)("br",{}),(0,r.jsx)("b",{children:"Proxy Admin Viewer: "}),"Can just view spend. They cannot create keys, teams or grant users access to new models."," "]}),(0,r.jsxs)(Y.Z,{numItems:1,className:"gap-2 p-2 w-full",children:[(0,r.jsx)(J.Z,{numColSpan:1,children:(0,r.jsx)(eg.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(ek.Z,{children:(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(ev.Z,{children:"Member Name"}),(0,r.jsx)(ev.Z,{children:"Role"})]})}),(0,r.jsx)(eb.Z,{children:x?x.map((e,l)=>(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(e_.Z,{children:e.user_email?e.user_email:e.user_id?e.user_id:null}),(0,r.jsx)(e_.Z,{children:e.user_role}),(0,r.jsxs)(e_.Z,{children:[(0,r.jsx)(eZ.Z,{icon:eu.Z,size:"sm",onClick:()=>w(!0)}),(0,r.jsx)(en.Z,{title:"Update role",visible:Z,width:800,footer:null,onOk:N,onCancel:C,children:P(T,e.user_role,e.user_id)})]})]},l)):null})]})})}),(0,r.jsx)(J.Z,{numColSpan:1,children:(0,r.jsxs)("div",{className:"flex justify-start",children:[(0,r.jsx)(H.Z,{className:"mr-4 mb-5",onClick:()=>y(!0),children:"+ Add admin"}),(0,r.jsx)(en.Z,{title:"Add admin",visible:f,width:800,footer:null,onOk:()=>{y(!1),i.resetFields()},onCancel:()=>{y(!1),i.resetFields()},children:I(F)}),(0,r.jsx)(H.Z,{className:"mb-5",onClick:()=>g(!0),children:"+ Add viewer"}),(0,r.jsx)(en.Z,{title:"Add viewer",visible:j,width:800,footer:null,onOk:()=>{g(!1),i.resetFields()},onCancel:()=>{g(!1),i.resetFields()},children:I(E)})]})})]}),(0,r.jsxs)(Y.Z,{children:[(0,r.jsx)(c,{level:4,children:"Add SSO"}),(0,r.jsxs)("div",{className:"flex justify-start mb-4",children:[(0,r.jsx)(H.Z,{onClick:()=>_(!0),children:"Add SSO"}),(0,r.jsx)(en.Z,{title:"Add SSO",visible:b,width:800,footer:null,onOk:()=>{_(!1),o.resetFields()},onCancel:()=>{_(!1),o.resetFields()},children:(0,r.jsxs)(er.Z,{form:o,onFinish:e=>{F(e),O(e),_(!1),v(!0)},labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(er.Z.Item,{label:"Admin Email",name:"user_email",rules:[{required:!0,message:"Please enter the email of the proxy admin"}],children:(0,r.jsx)(eo.Z,{})}),(0,r.jsx)(er.Z.Item,{label:"PROXY BASE URL",name:"proxy_base_url",rules:[{required:!0,message:"Please enter the proxy base url"}],children:(0,r.jsx)(eo.Z,{})}),(0,r.jsx)(er.Z.Item,{label:"GOOGLE CLIENT ID",name:"google_client_id",rules:[{required:!0,message:"Please enter the google client id"}],children:(0,r.jsx)(eo.Z.Password,{})}),(0,r.jsx)(er.Z.Item,{label:"GOOGLE CLIENT SECRET",name:"google_client_secret",rules:[{required:!0,message:"Please enter the google client secret"}],children:(0,r.jsx)(eo.Z.Password,{})})]}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ec.ZP,{htmlType:"submit",children:"Save"})})]})}),(0,r.jsxs)(en.Z,{title:"SSO Setup Instructions",visible:k,width:800,footer:null,onOk:S,onCancel:()=>{v(!1)},children:[(0,r.jsx)("p",{children:"Follow these steps to complete the SSO setup:"}),(0,r.jsx)(el.Z,{className:"mt-2",children:"1. DO NOT Exit this TAB"}),(0,r.jsx)(el.Z,{className:"mt-2",children:"2. Open a new tab, visit your proxy base url"}),(0,r.jsx)(el.Z,{className:"mt-2",children:"3. Confirm your SSO is configured correctly and you can login on the new Tab"}),(0,r.jsx)(el.Z,{className:"mt-2",children:"4. If Step 3 is successful, you can close this tab"}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ec.ZP,{onClick:S,children:"Done"})})]})]}),(0,r.jsxs)(e9.Z,{title:"Login without SSO",color:"teal",children:["If you need to login without sso, you can access ",(0,r.jsxs)("a",{href:l,target:"_blank",children:[(0,r.jsx)("b",{children:l})," "]})]})]})]})},ll=t(12224),lt=e=>{let{accessToken:l,userRole:t,userID:s}=e,[a,o]=(0,n.useState)([]),[i,c]=(0,n.useState)([]),[d,m]=(0,n.useState)(!1),[u]=er.Z.useForm(),[x,p]=(0,n.useState)(null),[j,g]=(0,n.useState)([]),[f,y]=(0,n.useState)(""),[Z,w]=(0,n.useState)({}),[b,_]=(0,n.useState)([]),k=e=>{b.includes(e)?_(b.filter(l=>l!==e)):_([...b,e])},v={llm_exceptions:"LLM Exceptions",llm_too_slow:"LLM Responses Too Slow",llm_requests_hanging:"LLM Requests Hanging",budget_alerts:"Budget Alerts (API Keys, Users)"};(0,n.useEffect)(()=>{l&&t&&s&&V(l,s,t).then(e=>{console.log("callbacks",e),o(e.callbacks);let l=e.alerts;if(console.log("alerts_data",l),l&&l.length>0){let e=l[0];console.log("_alert_info",e);let t=e.variables.SLACK_WEBHOOK_URL;console.log("catch_all_webhook",t),_(e.active_alerts),y(t),w(e.alerts_to_webhook)}c(l)})},[l,t,s]);let S=e=>b&&b.includes(e),A=e=>{if(!l)return;let t=Object.fromEntries(Object.entries(e.variables).map(e=>{var l;let[t,s]=e;return[t,(null===(l=document.querySelector('input[name="'.concat(t,'"]')))||void 0===l?void 0:l.value)||s]}));console.log("updatedVariables",t),console.log("updateAlertTypes",j);try{G(l,{environment_variables:t})}catch(e){h.ZP.error("Failed to update callback: "+e,20)}h.ZP.success("Callback updated successfully")},N=()=>{l&&u.validateFields().then(e=>{if(console.log("Form values:",e),"langfuse"===e.callback){G(l,{environment_variables:{LANGFUSE_PUBLIC_KEY:e.langfusePublicKey,LANGFUSE_SECRET_KEY:e.langfusePrivateKey},litellm_settings:{success_callback:[e.callback]}});let t={name:e.callback,variables:{SLACK_WEBHOOK_URL:null,LANGFUSE_HOST:null,LANGFUSE_PUBLIC_KEY:e.langfusePublicKey,LANGFUSE_SECRET_KEY:e.langfusePrivateKey}};o(a?[...a,t]:[t])}else if("slack"===e.callback){console.log("values.slackWebhookUrl: ".concat(e.slackWebhookUrl)),G(l,{general_settings:{alerting:["slack"],alerting_threshold:300},environment_variables:{SLACK_WEBHOOK_URL:e.slackWebhookUrl}}),console.log("values.callback: ".concat(e.callback));let t={name:e.callback,variables:{SLACK_WEBHOOK_URL:e.slackWebhookUrl,LANGFUSE_HOST:null,LANGFUSE_PUBLIC_KEY:null,LANGFUSE_SECRET_KEY:null}};o(a?[...a,t]:[t])}m(!1),u.resetFields(),p(null)})};return l?(console.log("callbacks: ".concat(a)),(0,r.jsxs)("div",{className:"w-full mx-4",children:[(0,r.jsx)(Y.Z,{numItems:1,className:"gap-2 p-8 w-full mt-2",children:(0,r.jsxs)(eD.Z,{children:[(0,r.jsxs)(ez.Z,{variant:"line",defaultValue:"1",children:[(0,r.jsx)(eU.Z,{value:"1",children:"Logging Callbacks"}),(0,r.jsx)(eU.Z,{value:"2",children:"Alerting"})]}),(0,r.jsxs)(eq.Z,{children:[(0,r.jsx)(eB.Z,{children:(0,r.jsxs)(eg.Z,{children:[(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(ek.Z,{children:(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(ev.Z,{children:"Callback"}),(0,r.jsx)(ev.Z,{children:"Callback Env Vars"})]})}),(0,r.jsx)(eb.Z,{children:a.map((e,t)=>{var s;return(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(e_.Z,{children:(0,r.jsx)(ep.Z,{color:"emerald",children:e.name})}),(0,r.jsxs)(e_.Z,{children:[(0,r.jsx)("ul",{children:Object.entries(null!==(s=e.variables)&&void 0!==s?s:{}).filter(e=>{let[l,t]=e;return null!==t}).map(e=>{let[l,t]=e;return(0,r.jsxs)("li",{children:[(0,r.jsx)(el.Z,{className:"mt-2",children:l}),"LANGFUSE_HOST"===l?(0,r.jsx)("p",{children:"default value=https://cloud.langfuse.com"}):(0,r.jsx)("div",{}),(0,r.jsx)($.Z,{name:l,defaultValue:t,type:"password"})]},l)})}),(0,r.jsx)(H.Z,{className:"mt-2",onClick:()=>A(e),children:"Save Changes"}),(0,r.jsx)(H.Z,{onClick:()=>K(l,e.name),className:"mx-2",children:"Test Callback"})]})]},t)})})]}),(0,r.jsx)(H.Z,{size:"xs",className:"mt-2",onClick:()=>{console.log("Add callback clicked"),m(!0)},children:"Add Callback"})]})}),(0,r.jsx)(eB.Z,{children:(0,r.jsxs)(eg.Z,{children:[(0,r.jsxs)(el.Z,{className:"my-2",children:["Alerts are only supported for Slack Webhook URLs. Get your webhook urls from ",(0,r.jsx)("a",{href:"https://api.slack.com/messaging/webhooks",target:"_blank",style:{color:"blue"},children:"here"})]}),(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(ek.Z,{children:(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(ev.Z,{}),(0,r.jsx)(ev.Z,{}),(0,r.jsx)(ev.Z,{children:"Slack Webhook URL"})]})}),(0,r.jsx)(eb.Z,{children:Object.entries(v).map((e,l)=>{let[t,s]=e;return(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(e_.Z,{children:(0,r.jsx)(ll.Z,{id:"switch",name:"switch",checked:S(t),onChange:()=>k(t)})}),(0,r.jsx)(e_.Z,{children:(0,r.jsx)(el.Z,{children:s})}),(0,r.jsx)(e_.Z,{children:(0,r.jsx)($.Z,{name:t,type:"password",defaultValue:Z&&Z[t]?Z[t]:f})})]},l)})})]}),(0,r.jsx)(H.Z,{size:"xs",className:"mt-2",onClick:()=>{if(!l)return;let e={};Object.entries(v).forEach(l=>{let[t,s]=l,a=document.querySelector('input[name="'.concat(t,'"]'));console.log("key",t),console.log("webhookInput",a);let r=(null==a?void 0:a.value)||"";console.log("newWebhookValue",r),e[t]=r}),console.log("updatedAlertToWebhooks",e);let t={general_settings:{alert_to_webhook_url:e,alert_types:b}};console.log("payload",t);try{G(l,t)}catch(e){h.ZP.error("Failed to update alerts: "+e,20)}h.ZP.success("Alerts updated successfully")},children:"Save Changes"}),(0,r.jsx)(H.Z,{onClick:()=>K(l,"slack"),className:"mx-2",children:"Test Alerts"})]})})]})]})}),(0,r.jsx)(en.Z,{title:"Add Callback",visible:d,onOk:N,width:800,onCancel:()=>{m(!1),u.resetFields(),p(null)},footer:null,children:(0,r.jsxs)(er.Z,{form:u,layout:"vertical",onFinish:N,children:[(0,r.jsx)(er.Z.Item,{label:"Callback",name:"callback",rules:[{required:!0,message:"Please select a callback"}],children:(0,r.jsx)(ea.default,{onChange:e=>{p(e)},children:(0,r.jsx)(ea.default.Option,{value:"langfuse",children:"langfuse"})})}),"langfuse"===x&&(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(er.Z.Item,{label:"LANGFUSE_PUBLIC_KEY",name:"langfusePublicKey",rules:[{required:!0,message:"Please enter the public key"}],children:(0,r.jsx)($.Z,{type:"password"})}),(0,r.jsx)(er.Z.Item,{label:"LANGFUSE_PRIVATE_KEY",name:"langfusePrivateKey",rules:[{required:!0,message:"Please enter the private key"}],children:(0,r.jsx)($.Z,{type:"password"})})]}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ec.ZP,{htmlType:"submit",children:"Save"})})]})})]})):null};let{Option:ls}=ea.default;var la=e=>{let{models:l,accessToken:t,routerSettings:s,setRouterSettings:a}=e,[o]=er.Z.useForm(),[i,c]=(0,n.useState)(!1),[d,m]=(0,n.useState)("");return(0,r.jsxs)("div",{children:[(0,r.jsx)(H.Z,{className:"mx-auto",onClick:()=>c(!0),children:"+ Add Fallbacks"}),(0,r.jsx)(en.Z,{title:"Add Fallbacks",visible:i,width:800,footer:null,onOk:()=>{c(!1),o.resetFields()},onCancel:()=>{c(!1),o.resetFields()},children:(0,r.jsxs)(er.Z,{form:o,onFinish:e=>{console.log(e);let{model_name:l,models:r}=e,n=[...s.fallbacks||[],{[l]:r}],i={...s,fallbacks:n};console.log(i);try{G(t,{router_settings:i}),a(i)}catch(e){h.ZP.error("Failed to update router settings: "+e,20)}h.ZP.success("router settings updated successfully"),c(!1),o.resetFields()},labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(er.Z.Item,{label:"Public Model Name",name:"model_name",rules:[{required:!0,message:"Set the model to fallback for"}],help:"required",children:(0,r.jsx)(eA.Z,{defaultValue:d,children:l&&l.map((e,l)=>(0,r.jsx)(eN.Z,{value:e,onClick:()=>m(e),children:e},l))})}),(0,r.jsx)(er.Z.Item,{label:"Fallback Models",name:"models",rules:[{required:!0,message:"Please select a model"}],help:"required",children:(0,r.jsx)(eK.Z,{value:l,children:l&&l.filter(e=>e!=d).map(e=>(0,r.jsx)(eV.Z,{value:e,children:e},e))})})]}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ec.ZP,{htmlType:"submit",children:"Add Fallbacks"})})]})})]})},lr=t(12968);async function ln(e,l){console.log("isLocal:",!1);let t=window.location.origin,s=new lr.ZP.OpenAI({apiKey:l,baseURL:t,dangerouslyAllowBrowser:!0});try{let l=await s.chat.completions.create({model:e,messages:[{role:"user",content:"Hi, this is a test message"}],mock_testing_fallbacks:!0});h.ZP.success((0,r.jsxs)("span",{children:["Test model=",(0,r.jsx)("strong",{children:e}),", received model=",(0,r.jsx)("strong",{children:l.model}),". See ",(0,r.jsx)("a",{href:"#",onClick:()=>window.open("https://docs.litellm.ai/docs/proxy/reliability","_blank"),style:{textDecoration:"underline",color:"blue"},children:"curl"})]}))}catch(e){h.ZP.error("Error occurred while generating model response. Please try again. Error: ".concat(e),20)}}var lo=e=>{let{accessToken:l,userRole:t,userID:s,modelData:a}=e,[o,i]=(0,n.useState)({}),[c,d]=(0,n.useState)(!1),[m]=er.Z.useForm(),[u,x]=(0,n.useState)(null),p={routing_strategy_args:"(dict) Arguments to pass to the routing strategy",routing_strategy:"(string) Routing strategy to use",allowed_fails:"(int) Number of times a deployment can fail before being added to cooldown",cooldown_time:"(int) time in seconds to cooldown a deployment after failure",num_retries:"(int) Number of retries for failed requests. Defaults to 0.",timeout:"(float) Timeout for requests. Defaults to None.",retry_after:"(int) Minimum time to wait before retrying a failed request"};(0,n.useEffect)(()=>{l&&t&&s&&V(l,s,t).then(e=>{console.log("callbacks",e),i(e.router_settings)})},[l,t,s]);let j=async e=>{if(l){console.log("received key: ".concat(e)),console.log("routerSettings['fallbacks']: ".concat(o.fallbacks)),o.fallbacks.map(l=>(e in l&&delete l[e],l));try{await G(l,{router_settings:o}),i({...o}),h.ZP.success("Router settings updated successfully")}catch(e){h.ZP.error("Failed to update router settings: "+e,20)}}},g=e=>{if(!l)return;console.log("router_settings",e);let t=Object.fromEntries(Object.entries(e).map(e=>{let[l,t]=e;if("routing_strategy_args"!==l){var s;return[l,(null===(s=document.querySelector('input[name="'.concat(l,'"]')))||void 0===s?void 0:s.value)||t]}return null}).filter(e=>null!==e));console.log("updatedVariables",t);try{G(l,{router_settings:t})}catch(e){h.ZP.error("Failed to update router settings: "+e,20)}h.ZP.success("router settings updated successfully")};return l?(0,r.jsx)("div",{className:"w-full mx-4",children:(0,r.jsxs)(eD.Z,{className:"gap-2 p-8 h-[75vh] w-full mt-2",children:[(0,r.jsxs)(ez.Z,{variant:"line",defaultValue:"1",children:[(0,r.jsx)(eU.Z,{value:"1",children:"General Settings"}),(0,r.jsx)(eU.Z,{value:"2",children:"Fallbacks"})]}),(0,r.jsxs)(eq.Z,{children:[(0,r.jsx)(eB.Z,{children:(0,r.jsxs)(Y.Z,{numItems:1,className:"gap-2 p-8 w-full mt-2",children:[(0,r.jsx)(et.Z,{children:"Router Settings"}),(0,r.jsx)(eg.Z,{children:(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(ek.Z,{children:(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(ev.Z,{children:"Setting"}),(0,r.jsx)(ev.Z,{children:"Value"})]})}),(0,r.jsx)(eb.Z,{children:Object.entries(o).filter(e=>{let[l,t]=e;return"fallbacks"!=l&&"context_window_fallbacks"!=l}).map(e=>{let[l,t]=e;return(0,r.jsxs)(eS.Z,{children:[(0,r.jsxs)(e_.Z,{children:[(0,r.jsx)(el.Z,{children:l}),(0,r.jsx)("p",{style:{fontSize:"0.65rem",color:"#808080",fontStyle:"italic"},className:"mt-1",children:p[l]})]}),(0,r.jsx)(e_.Z,{children:(0,r.jsx)($.Z,{name:l,defaultValue:"object"==typeof t?JSON.stringify(t,null,2):t.toString()})})]},l)})})]})}),(0,r.jsx)(J.Z,{children:(0,r.jsx)(H.Z,{className:"mt-2",onClick:()=>g(o),children:"Save Changes"})})]})}),(0,r.jsxs)(eB.Z,{children:[(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(ek.Z,{children:(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(ev.Z,{children:"Model Name"}),(0,r.jsx)(ev.Z,{children:"Fallbacks"})]})}),(0,r.jsx)(eb.Z,{children:o.fallbacks&&o.fallbacks.map((e,t)=>Object.entries(e).map(e=>{let[s,a]=e;return(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(e_.Z,{children:s}),(0,r.jsx)(e_.Z,{children:Array.isArray(a)?a.join(", "):a}),(0,r.jsx)(e_.Z,{children:(0,r.jsx)(H.Z,{onClick:()=>ln(s,l),children:"Test Fallback"})}),(0,r.jsx)(e_.Z,{children:(0,r.jsx)(eZ.Z,{icon:ex.Z,size:"sm",onClick:()=>j(s)})})]},t.toString()+s)}))})]}),(0,r.jsx)(la,{models:(null==a?void 0:a.data)?a.data.map(e=>e.model_name):[],accessToken:l,routerSettings:o,setRouterSettings:i})]})]})]})}):null},li=t(67951),lc=e=>{let{}=e;return(0,r.jsx)(r.Fragment,{children:(0,r.jsx)(Y.Z,{className:"gap-2 p-8 h-[80vh] w-full mt-2",children:(0,r.jsxs)("div",{className:"mb-5",children:[(0,r.jsx)("p",{className:"text-2xl text-tremor-content-strong dark:text-dark-tremor-content-strong font-semibold",children:"OpenAI Compatible Proxy: API Reference"}),(0,r.jsx)(el.Z,{className:"mt-2 mb-2",children:"LiteLLM is OpenAI Compatible. This means your API Key works with the OpenAI SDK. Just replace the base_url to point to your litellm proxy. Example Below "}),(0,r.jsxs)(eD.Z,{children:[(0,r.jsxs)(ez.Z,{children:[(0,r.jsx)(eU.Z,{children:"OpenAI Python SDK"}),(0,r.jsx)(eU.Z,{children:"LlamaIndex"}),(0,r.jsx)(eU.Z,{children:"Langchain Py"})]}),(0,r.jsxs)(eq.Z,{children:[(0,r.jsx)(eB.Z,{children:(0,r.jsx)(li.Z,{language:"python",children:'\nimport openai\nclient = openai.OpenAI(\n api_key="your_api_key",\n base_url="http://0.0.0.0:4000" # LiteLLM Proxy is OpenAI compatible, Read More: https://docs.litellm.ai/docs/proxy/user_keys\n)\n\nresponse = client.chat.completions.create(\n model="gpt-3.5-turbo", # model to send to the proxy\n messages = [\n {\n "role": "user",\n "content": "this is a test request, write a short poem"\n }\n ]\n)\n\nprint(response)\n '})}),(0,r.jsx)(eB.Z,{children:(0,r.jsx)(li.Z,{language:"python",children:'\nimport os, dotenv\n\nfrom llama_index.llms import AzureOpenAI\nfrom llama_index.embeddings import AzureOpenAIEmbedding\nfrom llama_index import VectorStoreIndex, SimpleDirectoryReader, ServiceContext\n\nllm = AzureOpenAI(\n engine="azure-gpt-3.5", # model_name on litellm proxy\n temperature=0.0,\n azure_endpoint="http://0.0.0.0:4000", # litellm proxy endpoint\n api_key="sk-1234", # litellm proxy API Key\n api_version="2023-07-01-preview",\n)\n\nembed_model = AzureOpenAIEmbedding(\n deployment_name="azure-embedding-model",\n azure_endpoint="http://0.0.0.0:4000",\n api_key="sk-1234",\n api_version="2023-07-01-preview",\n)\n\n\ndocuments = SimpleDirectoryReader("llama_index_data").load_data()\nservice_context = ServiceContext.from_defaults(llm=llm, embed_model=embed_model)\nindex = VectorStoreIndex.from_documents(documents, service_context=service_context)\n\nquery_engine = index.as_query_engine()\nresponse = query_engine.query("What did the author do growing up?")\nprint(response)\n\n '})}),(0,r.jsx)(eB.Z,{children:(0,r.jsx)(li.Z,{language:"python",children:'\nfrom langchain.chat_models import ChatOpenAI\nfrom langchain.prompts.chat import (\n ChatPromptTemplate,\n HumanMessagePromptTemplate,\n SystemMessagePromptTemplate,\n)\nfrom langchain.schema import HumanMessage, SystemMessage\n\nchat = ChatOpenAI(\n openai_api_base="http://0.0.0.0:4000",\n model = "gpt-3.5-turbo",\n temperature=0.1\n)\n\nmessages = [\n SystemMessage(\n content="You are a helpful assistant that im using to make a test request to."\n ),\n HumanMessage(\n content="test from litellm. tell me why it\'s amazing in 1 sentence"\n ),\n]\nresponse = chat(messages)\n\nprint(response)\n\n '})})]})]})]})})})};async function ld(e,l,t,s){console.log("isLocal:",!1);let a=window.location.origin,r=new lr.ZP.OpenAI({apiKey:s,baseURL:a,dangerouslyAllowBrowser:!0});try{for await(let s of(await r.chat.completions.create({model:t,stream:!0,messages:[{role:"user",content:e}]})))console.log(s),s.choices[0].delta.content&&l(s.choices[0].delta.content)}catch(e){h.ZP.error("Error occurred while generating model response. Please try again. Error: ".concat(e),20)}}var lm=e=>{let{accessToken:l,token:t,userRole:s,userID:a}=e,[o,i]=(0,n.useState)(""),[c,d]=(0,n.useState)(""),[m,h]=(0,n.useState)([]),[u,x]=(0,n.useState)(void 0),[p,j]=(0,n.useState)([]);(0,n.useEffect)(()=>{l&&t&&s&&a&&(async()=>{try{let e=await v(l,a,s);if(console.log("model_info:",e),(null==e?void 0:e.data.length)>0){let l=e.data.map(e=>({value:e.id,label:e.id}));console.log(l),j(l),x(e.data[0].id)}}catch(e){console.error("Error fetching model info:",e)}})()},[l,a,s]);let g=(e,l)=>{h(t=>{let s=t[t.length-1];return s&&s.role===e?[...t.slice(0,t.length-1),{role:e,content:s.content+l}]:[...t,{role:e,content:l}]})},f=async()=>{if(""!==c.trim()&&o&&t&&s&&a){h(e=>[...e,{role:"user",content:c}]);try{u&&await ld(c,e=>g("assistant",e),u,o)}catch(e){console.error("Error fetching model response",e),g("assistant","Error fetching model response")}d("")}};if(s&&"Admin Viewer"==s){let{Title:e,Paragraph:l}=eR.default;return(0,r.jsxs)("div",{children:[(0,r.jsx)(e,{level:1,children:"Access Denied"}),(0,r.jsx)(l,{children:"Ask your proxy admin for access to test models"})]})}return(0,r.jsx)("div",{style:{width:"100%",position:"relative"},children:(0,r.jsx)(Y.Z,{className:"gap-2 p-8 h-[80vh] w-full mt-2",children:(0,r.jsx)(eg.Z,{children:(0,r.jsxs)(eD.Z,{children:[(0,r.jsx)(ez.Z,{children:(0,r.jsx)(eU.Z,{children:"Chat"})}),(0,r.jsx)(eq.Z,{children:(0,r.jsxs)(eB.Z,{children:[(0,r.jsx)("div",{className:"sm:max-w-2xl",children:(0,r.jsxs)(Y.Z,{numItems:2,children:[(0,r.jsxs)(J.Z,{children:[(0,r.jsx)(el.Z,{children:"API Key"}),(0,r.jsx)($.Z,{placeholder:"Type API Key here",type:"password",onValueChange:i,value:o})]}),(0,r.jsxs)(J.Z,{className:"mx-2",children:[(0,r.jsx)(el.Z,{children:"Select Model:"}),(0,r.jsx)(ea.default,{placeholder:"Select a Model",onChange:e=>{console.log("selected ".concat(e)),x(e)},options:p,style:{width:"200px"}})]})]})}),(0,r.jsxs)(ew.Z,{className:"mt-5",style:{display:"block",maxHeight:"60vh",overflowY:"auto"},children:[(0,r.jsx)(ek.Z,{children:(0,r.jsx)(eS.Z,{children:(0,r.jsx)(e_.Z,{})})}),(0,r.jsx)(eb.Z,{children:m.map((e,l)=>(0,r.jsx)(eS.Z,{children:(0,r.jsx)(e_.Z,{children:"".concat(e.role,": ").concat(e.content)})},l))})]}),(0,r.jsx)("div",{className:"mt-3",style:{position:"absolute",bottom:5,width:"95%"},children:(0,r.jsxs)("div",{className:"flex",children:[(0,r.jsx)($.Z,{type:"text",value:c,onChange:e=>d(e.target.value),placeholder:"Type your message..."}),(0,r.jsx)(H.Z,{onClick:f,className:"ml-2",children:"Send"})]})})]})})]})})})})},lh=t(33509),lu=t(95781);let{Sider:lx}=lh.default;var lp=e=>{let{setPage:l,userRole:t,defaultSelectedKey:s}=e;return"Admin Viewer"==t?(0,r.jsx)(lh.default,{style:{minHeight:"100vh",maxWidth:"120px"},children:(0,r.jsx)(lx,{width:120,children:(0,r.jsxs)(lu.Z,{mode:"inline",defaultSelectedKeys:s||["4"],style:{height:"100%",borderRight:0},children:[(0,r.jsx)(lu.Z.Item,{onClick:()=>l("api-keys"),children:"API Keys"},"4"),(0,r.jsx)(lu.Z.Item,{onClick:()=>l("models"),children:"Models"},"2"),(0,r.jsx)(lu.Z.Item,{onClick:()=>l("llm-playground"),children:"Chat UI"},"3"),(0,r.jsx)(lu.Z.Item,{onClick:()=>l("usage"),children:"Usage"},"1")]})})}):(0,r.jsx)(lh.default,{style:{minHeight:"100vh",maxWidth:"145px"},children:(0,r.jsx)(lx,{width:145,children:(0,r.jsxs)(lu.Z,{mode:"inline",defaultSelectedKeys:s||["1"],style:{height:"100%",borderRight:0},children:[(0,r.jsx)(lu.Z.Item,{onClick:()=>l("api-keys"),children:(0,r.jsx)(el.Z,{children:"API Keys"})},"1"),(0,r.jsx)(lu.Z.Item,{onClick:()=>l("llm-playground"),children:(0,r.jsx)(el.Z,{children:"Test Key"})},"3"),"Admin"==t?(0,r.jsx)(lu.Z.Item,{onClick:()=>l("models"),children:(0,r.jsx)(el.Z,{children:"Models"})},"2"):null,"Admin"==t?(0,r.jsx)(lu.Z.Item,{onClick:()=>l("usage"),children:(0,r.jsx)(el.Z,{children:"Usage"})},"4"):null,"Admin"==t?(0,r.jsx)(lu.Z.Item,{onClick:()=>l("teams"),children:(0,r.jsx)(el.Z,{children:"Teams"})},"6"):null,"Admin"==t?(0,r.jsx)(lu.Z.Item,{onClick:()=>l("users"),children:(0,r.jsx)(el.Z,{children:"Users"})},"5"):null,"Admin"==t?(0,r.jsx)(lu.Z.Item,{onClick:()=>l("settings"),children:(0,r.jsx)(el.Z,{children:"Logging & Alerts"})},"8"):null,"Admin"==t?(0,r.jsx)(lu.Z.Item,{onClick:()=>l("general-settings"),children:(0,r.jsx)(el.Z,{children:"Router Settings"})},"9"):null,"Admin"==t?(0,r.jsx)(lu.Z.Item,{onClick:()=>l("admin-panel"),children:(0,r.jsx)(el.Z,{children:"Admin"})},"7"):null,(0,r.jsx)(lu.Z.Item,{onClick:()=>l("api_ref"),children:(0,r.jsx)(el.Z,{children:"API Reference"})},"11")]})})})},lj=t(67989),lg=e=>{let{accessToken:l,token:t,userRole:s,userID:a}=e,o=new Date,[i,c]=(0,n.useState)([]),[d,m]=(0,n.useState)([]),[h,u]=(0,n.useState)([]),[x,p]=(0,n.useState)([]),[j,g]=(0,n.useState)([]),[f,y]=(0,n.useState)([]),[Z,w]=(0,n.useState)([]),[b,v]=(0,n.useState)([]),[S,T]=(0,n.useState)([]),[O,M]=(0,n.useState)([]),[R,L]=(0,n.useState)([]),[U,D]=(0,n.useState)(null),z=new Date(o.getFullYear(),o.getMonth(),1),B=new Date(o.getFullYear(),o.getMonth()+1,0),q=V(z),K=V(B);function V(e){let l=e.getFullYear(),t=e.getMonth()+1,s=e.getDate();return"".concat(l,"-").concat(t<10?"0"+t:t,"-").concat(s<10?"0"+s:s)}console.log("Start date is ".concat(q)),console.log("End date is ".concat(K)),(0,n.useEffect)(()=>{l&&t&&s&&a&&(async()=>{try{if(console.log("user role: ".concat(s)),"Admin"==s||"Admin Viewer"==s){let e=await I(l);c(e);let t=(await P(l)).map(e=>({key:(e.key_name||e.key_alias||e.api_key).substring(0,10),spend:e.total_spend}));m(t);let r=(await E(l)).map(e=>({key:e.model,spend:e.total_spend}));u(r);let n=await A(l);console.log("teamSpend",n),g(n.daily_spend),w(n.teams);let o=n.total_spend_per_team;o=o.map(e=>(e.name=e.team_id||"",e.value=e.total_spend||0,e)),v(o);let i=await N(l);y(i.top_10_tags);let d=(await _(l,a,s)).data;console.log("model groups in model dashboard",d);let h=[];for(let e=0;e{if(console.log("result from spend logs call",e),"daily_spend"in e){let l=e.daily_spend;console.log("daily spend",l),c(l);let t=e.top_api_keys;m(t)}else{let t=(await F(l,function(e){let l=[];e.forEach(e=>{Object.entries(e).forEach(e=>{let[t,s]=e;"spend"!==t&&"startTime"!==t&&"models"!==t&&"users"!==t&&l.push({key:t,spend:s})})}),l.sort((e,l)=>Number(l.spend)-Number(e.spend));let t=l.slice(0,5).map(e=>e.key);return console.log("topKeys: ".concat(Object.keys(t[0]))),t}(e))).info.map(e=>({key:(e.key_name||e.key_alias).substring(0,10),spend:e.spend}));m(t),p(function(e){let l={};e.forEach(e=>{Object.entries(e.users).forEach(e=>{let[t,s]=e;""!==t&&null!=t&&"None"!=t&&(l[t]||(l[t]=0),l[t]+=s)})});let t=Object.entries(l).map(e=>{let[l,t]=e;return{user_id:l,spend:t}});t.sort((e,l)=>l.spend-e.spend);let s=t.slice(0,5);return console.log("topKeys: ".concat(Object.values(s[0]))),s}(e)),c(e)}});let e=await k(l,a,s,null);console.log("Model metrics response:",e);let r=[...e].sort((e,l)=>l.avg_latency_seconds-e.avg_latency_seconds);console.log("Sorted by latency:",r),T(e),M(r)}catch(e){console.error("There was an error fetching the data",e)}})()},[l,t,s,a,q,K]);let G=async e=>{if(console.log("Updating model metrics for group:",e),l&&a&&s){D(e);try{let t=await k(l,a,s,e);console.log("Model metrics response:",t);let r=[...t].sort((e,l)=>l.avg_latency_seconds-e.avg_latency_seconds);console.log("Sorted by latency:",r),T(t),M(r)}catch(e){console.error("Failed to fetch model metrics",e)}}};return(0,r.jsxs)("div",{style:{width:"100%"},className:"p-8",children:[(0,r.jsx)(eE,{userID:a,userRole:s,accessToken:l,userSpend:null,selectedTeam:null}),(0,r.jsxs)(eD.Z,{children:[(0,r.jsxs)(ez.Z,{className:"mt-2",children:[(0,r.jsx)(eU.Z,{children:"All Up"}),(0,r.jsx)(eU.Z,{children:"Team Based Usage"}),(0,r.jsx)(eU.Z,{children:"Tag Based Usage"}),(0,r.jsx)(eU.Z,{children:"Model Based Usage"})]}),(0,r.jsxs)(eq.Z,{children:[(0,r.jsx)(eB.Z,{children:(0,r.jsxs)(Y.Z,{numItems:2,className:"gap-2 h-[75vh] w-full",children:[(0,r.jsx)(J.Z,{numColSpan:2,children:(0,r.jsxs)(eg.Z,{children:[(0,r.jsx)(et.Z,{children:"Monthly Spend"}),(0,r.jsx)(ej.Z,{data:i,index:"date",categories:["spend"],colors:["blue"],valueFormatter:e=>"$ ".concat(new Intl.NumberFormat("us").format(e).toString()),yAxisWidth:100,tickGap:5})]})}),(0,r.jsx)(J.Z,{numColSpan:1,children:(0,r.jsxs)(eg.Z,{children:[(0,r.jsx)(et.Z,{children:"Top API Keys"}),(0,r.jsx)(ej.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,r.jsx)(J.Z,{numColSpan:1,children:(0,r.jsxs)(eg.Z,{children:[(0,r.jsx)(et.Z,{children:"Top Users"}),(0,r.jsx)(ej.Z,{className:"mt-4 h-40",data:x,index:"user_id",categories:["spend"],colors:["blue"],yAxisWidth:200,layout:"vertical",showXAxis:!1,showLegend:!1})]})}),(0,r.jsx)(J.Z,{numColSpan:1,children:(0,r.jsxs)(eg.Z,{children:[(0,r.jsx)(et.Z,{children:"Top Models"}),(0,r.jsx)(ej.Z,{className:"mt-4 h-40",data:h,index:"key",categories:["spend"],colors:["blue"],yAxisWidth:200,layout:"vertical",showXAxis:!1,showLegend:!1})]})})]})}),(0,r.jsx)(eB.Z,{children:(0,r.jsxs)(Y.Z,{numItems:2,className:"gap-2 h-[75vh] w-full",children:[(0,r.jsxs)(J.Z,{numColSpan:2,children:[(0,r.jsxs)(eg.Z,{className:"mb-2",children:[(0,r.jsx)(et.Z,{children:"Total Spend Per Team"}),(0,r.jsx)(lj.Z,{data:b})]}),(0,r.jsxs)(eg.Z,{children:[(0,r.jsx)(et.Z,{children:"Daily Spend Per Team"}),(0,r.jsx)(ej.Z,{className:"h-72",data:j,showLegend:!0,index:"date",categories:Z,yAxisWidth:80,colors:["blue","green","yellow","red","purple"],stack:!0})]})]}),(0,r.jsx)(J.Z,{numColSpan:2})]})}),(0,r.jsx)(eB.Z,{children:(0,r.jsxs)(Y.Z,{numItems:2,className:"gap-2 h-[75vh] w-full mb-4",children:[(0,r.jsx)(J.Z,{numColSpan:2,children:(0,r.jsxs)(eg.Z,{children:[(0,r.jsx)(et.Z,{children:"Spend Per Tag - Last 30 Days"}),(0,r.jsxs)(el.Z,{children:["Get Started Tracking cost per tag ",(0,r.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/enterprise#tracking-spend-for-custom-tags",target:"_blank",children:"here"})]}),(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(ek.Z,{children:(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(ev.Z,{children:"Tag"}),(0,r.jsx)(ev.Z,{children:"Spend"}),(0,r.jsx)(ev.Z,{children:"Requests"})]})}),(0,r.jsx)(eb.Z,{children:f.map(e=>(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(e_.Z,{children:e.name}),(0,r.jsx)(e_.Z,{children:e.value}),(0,r.jsx)(e_.Z,{children:e.log_count})]},e.name))})]})]})}),(0,r.jsx)(J.Z,{numColSpan:2})]})}),(0,r.jsxs)(eB.Z,{children:[(0,r.jsx)(et.Z,{children:"Filter By Model Group"}),(0,r.jsx)("p",{style:{fontSize:"0.85rem",color:"#808080"},children:"View how requests were load balanced within a model group"}),(0,r.jsx)("p",{style:{fontSize:"0.85rem",color:"#808080",fontStyle:"italic"},children:"(Beta feature) only supported for Azure Model Groups"}),(0,r.jsxs)(eA.Z,{className:"mb-4 mt-2",defaultValue:"all",children:[(0,r.jsx)(eN.Z,{value:"all",onClick:()=>G(null),children:"All Model Groups"}),R.map((e,l)=>(0,r.jsx)(eN.Z,{value:e,onClick:()=>G(e),children:e},l))]}),(0,r.jsxs)(eg.Z,{children:[(0,r.jsx)(et.Z,{children:"Number Requests per Model"}),(0,r.jsx)(ej.Z,{data:S,className:"h-[50vh]",index:"model",categories:["num_requests"],colors:["blue"],yAxisWidth:400,layout:"vertical",tickGap:5})]}),(0,r.jsxs)(eg.Z,{className:"mt-4",children:[(0,r.jsx)(et.Z,{children:"Latency Per Model"}),(0,r.jsx)(ej.Z,{data:O,className:"h-[50vh]",index:"model",categories:["avg_latency_seconds"],colors:["red"],yAxisWidth:400,layout:"vertical",tickGap:5})]})]})]})]})]})},lf=()=>{let{Title:e,Paragraph:l}=eR.default,[t,s]=(0,n.useState)(""),[a,i]=(0,n.useState)(null),[c,d]=(0,n.useState)(null),[h,u]=(0,n.useState)(null),[x,p]=(0,n.useState)(!0),j=(0,o.useSearchParams)(),[g,f]=(0,n.useState)({data:[]}),y=j.get("userID"),Z=j.get("token"),[w,b]=(0,n.useState)("api-keys"),[_,k]=(0,n.useState)(null);return(0,n.useEffect)(()=>{if(Z){let e=(0,eM.o)(Z);if(e){if(console.log("Decoded token:",e),console.log("Decoded key:",e.key),k(e.key),e.user_role){let l=function(e){if(!e)return"Undefined Role";switch(console.log("Received user role: ".concat(e.toLowerCase())),console.log("Received user role length: ".concat(e.toLowerCase().length)),e.toLowerCase()){case"app_owner":case"demo_app_owner":return"App Owner";case"app_admin":case"proxy_admin":return"Admin";case"proxy_admin_viewer":return"Admin Viewer";case"app_user":return"App User";default:return"Unknown Role"}}(e.user_role);console.log("Decoded user_role:",l),s(l),"Admin Viewer"==l&&b("usage")}else console.log("User role not defined");e.user_email?i(e.user_email):console.log("User Email is not set ".concat(e)),e.login_method?p("username_password"==e.login_method):console.log("User Email is not set ".concat(e))}}},[Z]),(0,r.jsx)(n.Suspense,{fallback:(0,r.jsx)("div",{children:"Loading..."}),children:(0,r.jsxs)("div",{className:"flex flex-col min-h-screen",children:[(0,r.jsx)(m,{userID:y,userRole:t,userEmail:a,showSSOBanner:x}),(0,r.jsxs)("div",{className:"flex flex-1 overflow-auto",children:[(0,r.jsx)("div",{className:"mt-8",children:(0,r.jsx)(lp,{setPage:b,userRole:t,defaultSelectedKey:null})}),"api-keys"==w?(0,r.jsx)(eL,{userID:y,userRole:t,teams:c,keys:h,setUserRole:s,userEmail:a,setUserEmail:i,setTeams:d,setKeys:u}):"models"==w?(0,r.jsx)(e8,{userID:y,userRole:t,token:Z,accessToken:_,modelData:g,setModelData:f}):"llm-playground"==w?(0,r.jsx)(lm,{userID:y,userRole:t,token:Z,accessToken:_}):"users"==w?(0,r.jsx)(e6,{userID:y,userRole:t,token:Z,keys:h,teams:c,accessToken:_,setKeys:u}):"teams"==w?(0,r.jsx)(e7,{teams:c,setTeams:d,searchParams:j,accessToken:_,userID:y,userRole:t}):"admin-panel"==w?(0,r.jsx)(le,{setTeams:d,searchParams:j,accessToken:_,showSSOBanner:x}):"api_ref"==w?(0,r.jsx)(lc,{}):"settings"==w?(0,r.jsx)(lt,{userID:y,userRole:t,accessToken:_}):"general-settings"==w?(0,r.jsx)(lo,{userID:y,userRole:t,accessToken:_,modelData:g}):(0,r.jsx)(lg,{userID:y,userRole:t,token:Z,accessToken:_})]})]})})}}},function(e){e.O(0,[447,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-781ca5f151d78d1d.js b/litellm/proxy/_experimental/out/_next/static/chunks/app/page-781ca5f151d78d1d.js deleted file mode 100644 index 40715cd067c..00000000000 --- a/litellm/proxy/_experimental/out/_next/static/chunks/app/page-781ca5f151d78d1d.js +++ /dev/null @@ -1 +0,0 @@ -(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[931],{20661:function(e,l,t){Promise.resolve().then(t.bind(t,27125))},27125:function(e,l,t){"use strict";t.r(l),t.d(l,{default:function(){return lf}});var s,a,r=t(3827),n=t(64090),o=t(47907),i=t(8792),c=t(40491),d=t(65270),m=e=>{let{userID:l,userRole:t,userEmail:s,showSSOBanner:a}=e;console.log("User ID:",l),console.log("userEmail:",s),console.log("showSSOBanner:",a);let n=[{key:"1",label:(0,r.jsxs)(r.Fragment,{children:[(0,r.jsxs)("p",{children:["Role: ",t]}),(0,r.jsxs)("p",{children:["ID: ",l]})]})}];return(0,r.jsxs)("nav",{className:"left-0 right-0 top-0 flex justify-between items-center h-12 mb-4",children:[(0,r.jsx)("div",{className:"text-left my-2 absolute top-0 left-0",children:(0,r.jsx)("div",{className:"flex flex-col items-center",children:(0,r.jsx)(i.default,{href:"/",children:(0,r.jsx)("button",{className:"text-gray-800 rounded text-center",children:(0,r.jsx)("img",{src:"/get_image",width:160,height:160,alt:"LiteLLM Brand",className:"mr-2"})})})})}),(0,r.jsxs)("div",{className:"text-right mx-4 my-2 absolute top-0 right-0 flex items-center justify-end space-x-2",children:[a?(0,r.jsx)("div",{style:{padding:"6px",borderRadius:"8px"},children:(0,r.jsx)("a",{href:"https://calendly.com/d/4mp-gd3-k5k/litellm-1-1-onboarding-chat",target:"_blank",style:{fontSize:"14px",textDecoration:"underline"},children:"Request hosted proxy"})}):null,(0,r.jsx)("div",{style:{border:"1px solid #391085",padding:"6px",borderRadius:"8px"},children:(0,r.jsx)(c.Z,{menu:{items:n},children:(0,r.jsx)(d.Z,{children:s})})})]})]})},h=t(80588);let u=async()=>{try{let e=await fetch("https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json"),l=await e.json();return console.log("received data: ".concat(l)),l}catch(e){throw console.error("Failed to get model cost map:",e),e}},x=async(e,l)=>{try{let t=await fetch("/model/new",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...l})});if(!t.ok){let e=await t.text();throw h.ZP.error("Failed to create key: "+e,20),console.error("Error response from the server:",e),Error("Network response was not ok")}let s=await t.json();return console.log("API Response:",s),h.ZP.success("Model created successfully. Wait 60s and refresh on 'All Models' page"),s}catch(e){throw console.error("Failed to create key:",e),e}},p=async(e,l)=>{console.log("model_id in model delete call: ".concat(l));try{let t=await fetch("/model/delete",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({id:l})});if(!t.ok){let e=await t.text();throw h.ZP.error("Failed to create key: "+e,20),console.error("Error response from the server:",e),Error("Network response was not ok")}let s=await t.json();return console.log("API Response:",s),h.ZP.success("Model deleted successfully. Restart server to see this."),s}catch(e){throw console.error("Failed to create key:",e),e}},j=async(e,l,t)=>{try{if(console.log("Form Values in keyCreateCall:",t),t.description&&(t.metadata||(t.metadata={}),t.metadata.description=t.description,delete t.description,t.metadata=JSON.stringify(t.metadata)),t.metadata){console.log("formValues.metadata:",t.metadata);try{t.metadata=JSON.parse(t.metadata)}catch(e){throw h.ZP.error("Failed to parse metadata: "+e,20),Error("Failed to parse metadata: "+e)}}console.log("Form Values after check:",t);let s=await fetch("/key/generate",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({user_id:l,...t})});if(!s.ok){let e=await s.text();throw h.ZP.error("Failed to create key: "+e,20),console.error("Error response from the server:",e),Error("Network response was not ok")}let a=await s.json();return console.log("API Response:",a),a}catch(e){throw console.error("Failed to create key:",e),e}},g=async(e,l,t)=>{try{if(console.log("Form Values in keyCreateCall:",t),t.description&&(t.metadata||(t.metadata={}),t.metadata.description=t.description,delete t.description,t.metadata=JSON.stringify(t.metadata)),t.metadata){console.log("formValues.metadata:",t.metadata);try{t.metadata=JSON.parse(t.metadata)}catch(e){throw h.ZP.error("Failed to parse metadata: "+e,20),Error("Failed to parse metadata: "+e)}}console.log("Form Values after check:",t);let s=await fetch("/user/new",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({user_id:l,...t})});if(!s.ok){let e=await s.text();throw h.ZP.error("Failed to create key: "+e,20),console.error("Error response from the server:",e),Error("Network response was not ok")}let a=await s.json();return console.log("API Response:",a),a}catch(e){throw console.error("Failed to create key:",e),e}},f=async(e,l)=>{try{console.log("in keyDeleteCall:",l);let t=await fetch("/key/delete",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({keys:[l]})});if(!t.ok){let e=await t.text();throw h.ZP.error("Failed to delete key: "+e,20),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to create key:",e),e}},y=async(e,l)=>{try{console.log("in teamDeleteCall:",l);let t=await fetch("/team/delete",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({team_ids:[l]})});if(!t.ok){let e=await t.text();throw h.ZP.error("Failed to delete team: "+e,20),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to delete key:",e),e}},Z=async function(e,l,t){let s=arguments.length>3&&void 0!==arguments[3]&&arguments[3],a=arguments.length>4?arguments[4]:void 0,r=arguments.length>5?arguments[5]:void 0;try{let n="/user/info";"App Owner"==t&&l&&(n="".concat(n,"?user_id=").concat(l)),"App User"==t&&l&&(n="".concat(n,"?user_id=").concat(l)),console.log("in userInfoCall viewAll=",s),s&&r&&null!=a&&void 0!=a&&(n="".concat(n,"?view_all=true&page=").concat(a,"&page_size=").concat(r));let o=await fetch(n,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!o.ok){let e=await o.text();throw h.ZP.error(e,20),Error("Network response was not ok")}let i=await o.json();return console.log("API Response:",i),i}catch(e){throw console.error("Failed to create key:",e),e}},w=async(e,l)=>{try{let t="/team/info";l&&(t="".concat(t,"?team_id=").concat(l)),console.log("in teamInfoCall");let s=await fetch(t,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!s.ok){let e=await s.text();throw h.ZP.error(e,20),Error("Network response was not ok")}let a=await s.json();return console.log("API Response:",a),a}catch(e){throw console.error("Failed to create key:",e),e}},b=async e=>{try{let l=await fetch("/global/spend",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw h.ZP.error(e,20),Error("Network response was not ok")}return await l.json()}catch(e){throw console.error("Failed to create key:",e),e}},_=async(e,l,t)=>{try{let l=await fetch("/v2/model/info",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw h.ZP.error(e,20),Error("Network response was not ok")}let t=await l.json();return console.log("modelInfoCall:",t),t}catch(e){throw console.error("Failed to create key:",e),e}},k=async(e,l,t,s)=>{try{let l="/model/metrics";s&&(l="".concat(l,"?_selected_model_group=").concat(s));let t=await fetch(l,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw h.ZP.error(e,20),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},v=async(e,l,t)=>{try{let l=await fetch("/models",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw h.ZP.error(e,20),Error("Network response was not ok")}return await l.json()}catch(e){throw console.error("Failed to create key:",e),e}},S=async(e,l)=>{try{let t="/global/spend/logs";console.log("in keySpendLogsCall:",t);let s=await fetch("".concat(t,"?api_key=").concat(l),{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!s.ok){let e=await s.text();throw h.ZP.error(e,20),Error("Network response was not ok")}let a=await s.json();return console.log(a),a}catch(e){throw console.error("Failed to create key:",e),e}},A=async e=>{try{let l="/global/spend/teams";console.log("in teamSpendLogsCall:",l);let t=await fetch("".concat(l),{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw h.ZP.error(e,20),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to create key:",e),e}},N=async e=>{try{let l="/global/spend/tags";console.log("in tagsSpendLogsCall:",l);let t=await fetch("".concat(l),{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw h.ZP.error(e,20),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to create key:",e),e}},C=async(e,l,t,s,a,r)=>{try{console.log("user role in spend logs call: ".concat(t));let l="/spend/logs";l="App Owner"==t?"".concat(l,"?user_id=").concat(s,"&start_date=").concat(a,"&end_date=").concat(r):"".concat(l,"?start_date=").concat(a,"&end_date=").concat(r);let n=await fetch(l,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!n.ok){let e=await n.text();throw h.ZP.error(e,20),Error("Network response was not ok")}let o=await n.json();return console.log(o),o}catch(e){throw console.error("Failed to create key:",e),e}},I=async e=>{try{let l=await fetch("/global/spend/logs",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw h.ZP.error(e,20),Error("Network response was not ok")}let t=await l.json();return console.log(t),t}catch(e){throw console.error("Failed to create key:",e),e}},P=async e=>{try{let l=await fetch("/global/spend/keys?limit=5",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw h.ZP.error(e,20),Error("Network response was not ok")}let t=await l.json();return console.log(t),t}catch(e){throw console.error("Failed to create key:",e),e}},T=async(e,l)=>{try{l&&JSON.stringify({api_key:l});let t={method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}};l&&(t.body=JSON.stringify({api_key:l}));let s=await fetch("/global/spend/end_users",t);if(!s.ok){let e=await s.text();throw h.ZP.error(e,20),Error("Network response was not ok")}let a=await s.json();return console.log(a),a}catch(e){throw console.error("Failed to create key:",e),e}},E=async e=>{try{let l=await fetch("/global/spend/models?limit=5",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw h.ZP.error(e,20),Error("Network response was not ok")}let t=await l.json();return console.log(t),t}catch(e){throw console.error("Failed to create key:",e),e}},F=async(e,l)=>{try{let t=await fetch("/v2/key/info",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({keys:l})});if(!t.ok){let e=await t.text();throw h.ZP.error(e,20),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to create key:",e),e}},O=async e=>{try{let l="/user/get_requests";console.log("in userGetRequesedtModelsCall:",l);let t=await fetch(l,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw h.ZP.error("Failed to delete key: "+e,20),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to get requested models:",e),e}},M=async(e,l)=>{try{let t="/user/get_users?role=".concat(l);console.log("in userGetAllUsersCall:",t);let s=await fetch(t,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!s.ok){let e=await s.text();throw h.ZP.error("Failed to delete key: "+e,20),Error("Network response was not ok")}let a=await s.json();return console.log(a),a}catch(e){throw console.error("Failed to get requested models:",e),e}},R=async(e,l)=>{try{console.log("Form Values in teamCreateCall:",l);let t=await fetch("/team/new",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...l})});if(!t.ok){let e=await t.text();throw h.ZP.error("Failed to create key: "+e,20),console.error("Error response from the server:",e),Error("Network response was not ok")}let s=await t.json();return console.log("API Response:",s),s}catch(e){throw console.error("Failed to create key:",e),e}},L=async(e,l)=>{try{console.log("Form Values in keyUpdateCall:",l);let t=await fetch("/key/update",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...l})});if(!t.ok){let e=await t.text();throw h.ZP.error("Failed to update key: "+e,20),console.error("Error response from the server:",e),Error("Network response was not ok")}let s=await t.json();return console.log("Update key Response:",s),s}catch(e){throw console.error("Failed to create key:",e),e}},U=async(e,l)=>{try{console.log("Form Values in teamUpateCall:",l);let t=await fetch("/team/update",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...l})});if(!t.ok){let e=await t.text();throw h.ZP.error("Failed to update team: "+e,20),console.error("Error response from the server:",e),Error("Network response was not ok")}let s=await t.json();return console.log("Update Team Response:",s),s}catch(e){throw console.error("Failed to create key:",e),e}},D=async(e,l)=>{try{console.log("Form Values in modelUpateCall:",l);let t=await fetch("/model/update",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...l})});if(!t.ok){let e=await t.text();throw h.ZP.error("Failed to update model: "+e,20),console.error("Error update from the server:",e),Error("Network response was not ok")}let s=await t.json();return console.log("Update model Response:",s),s}catch(e){throw console.error("Failed to update model:",e),e}},z=async(e,l,t)=>{try{console.log("Form Values in teamMemberAddCall:",t);let s=await fetch("/team/member_add",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({team_id:l,member:t})});if(!s.ok){let e=await s.text();throw h.ZP.error("Failed to create key: "+e,20),console.error("Error response from the server:",e),Error("Network response was not ok")}let a=await s.json();return console.log("API Response:",a),a}catch(e){throw console.error("Failed to create key:",e),e}},B=async(e,l,t)=>{try{console.log("Form Values in userUpdateUserCall:",l);let s={...l};null!==t&&(s.user_role=t),s=JSON.stringify(s);let a=await fetch("/user/update",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:s});if(!a.ok){let e=await a.text();throw h.ZP.error("Failed to create key: "+e,20),console.error("Error response from the server:",e),Error("Network response was not ok")}let r=await a.json();return console.log("API Response:",r),r}catch(e){throw console.error("Failed to create key:",e),e}},q=async(e,l)=>{try{let t=await fetch("/global/predict/spend/logs",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({data:l})});if(!t.ok){let e=await t.text();throw h.ZP.error(e,20),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to create key:",e),e}},K=async(e,l)=>{try{let t="/health/services?service=".concat(l);console.log("Checking Slack Budget Alerts service health");let s=await fetch(t,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!s.ok){let e=await s.text();throw h.ZP.error("Failed ".concat(l," service health check ")+e),Error(e)}let a=await s.json();return h.ZP.success("Test request to ".concat(l," made - check logs/alerts on ").concat(l," to verify")),a}catch(e){throw console.error("Failed to perform health check:",e),e}},V=async(e,l,t)=>{try{let l=await fetch("/get/config/callbacks",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw h.ZP.error(e,20),Error("Network response was not ok")}return await l.json()}catch(e){throw console.error("Failed to get callbacks:",e),e}},G=async(e,l)=>{try{let t=await fetch("/config/update",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...l})});if(!t.ok){let e=await t.text();throw h.ZP.error(e,20),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to set callbacks:",e),e}},W=async e=>{try{let l=await fetch("/health",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw h.ZP.error(e),Error("Network response was not ok")}return await l.json()}catch(e){throw console.error("Failed to call /health:",e),e}};var J=t(10384),Y=t(46453),H=t(2179),$=t(52273),X=t(26780),Q=t(15595),ee=t(6698),el=t(71801),et=t(42440),es=t(42308),ea=t(50670),er=t(81583),en=t(99129),eo=t(44839),ei=t(88707),ec=t(1861);let{Option:ed}=ea.default;var em=e=>{let{userID:l,team:t,userRole:s,accessToken:a,data:o,setData:i}=e,[c]=er.Z.useForm(),[d,m]=(0,n.useState)(!1),[u,x]=(0,n.useState)(null),[p,g]=(0,n.useState)(null),[f,y]=(0,n.useState)([]),Z=()=>{m(!1),c.resetFields()},w=()=>{m(!1),x(null),c.resetFields()};(0,n.useEffect)(()=>{(async()=>{try{if(null===l||null===s)return;if(null!==a){let e=(await v(a,l,s)).data.map(e=>e.id);console.log("available_model_names:",e),y(e)}}catch(e){console.error("Error fetching user models:",e)}})()},[a,l,s]);let b=async e=>{try{h.ZP.info("Making API Call"),m(!0);let t=await j(a,l,e);console.log("key create Response:",t),i(e=>e?[...e,t]:[t]),x(t.key),g(t.soft_budget),h.ZP.success("API Key Created"),c.resetFields(),localStorage.removeItem("userData"+l)}catch(e){console.error("Error creating the key:",e)}};return(0,r.jsxs)("div",{children:[(0,r.jsx)(H.Z,{className:"mx-auto",onClick:()=>m(!0),children:"+ Create New Key"}),(0,r.jsx)(en.Z,{title:"Create Key",visible:d,width:800,footer:null,onOk:Z,onCancel:w,children:(0,r.jsxs)(er.Z,{form:c,onFinish:b,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(er.Z.Item,{label:"Key Name",name:"key_alias",rules:[{required:!0,message:"Please input a key name"}],help:"required",children:(0,r.jsx)($.Z,{placeholder:""})}),(0,r.jsx)(er.Z.Item,{label:"Team ID",name:"team_id",hidden:!0,initialValue:t?t.team_id:null,valuePropName:"team_id",className:"mt-8",children:(0,r.jsx)(eo.Z,{value:t?t.team_alias:"",disabled:!0})}),(0,r.jsx)(er.Z.Item,{label:"Models",name:"models",rules:[{required:!0,message:"Please select a model"}],help:"required",children:(0,r.jsxs)(ea.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},onChange:e=>{e.includes("all-team-models")&&c.setFieldsValue({models:["all-team-models"]})},children:[(0,r.jsx)(ed,{value:"all-team-models",children:"All Team Models"},"all-team-models"),t&&t.models?t.models.includes("all-proxy-models")?f.map(e=>(0,r.jsx)(ed,{value:e,children:e},e)):t.models.map(e=>(0,r.jsx)(ed,{value:e,children:e},e)):f.map(e=>(0,r.jsx)(ed,{value:e,children:e},e))]})}),(0,r.jsxs)(X.Z,{className:"mt-20 mb-8",children:[(0,r.jsx)(ee.Z,{children:(0,r.jsx)("b",{children:"Optional Settings"})}),(0,r.jsxs)(Q.Z,{children:[(0,r.jsx)(er.Z.Item,{className:"mt-8",label:"Max Budget (USD)",name:"max_budget",help:"Budget cannot exceed team max budget: $".concat((null==t?void 0:t.max_budget)!==null&&(null==t?void 0:t.max_budget)!==void 0?null==t?void 0:t.max_budget:"unlimited"),rules:[{validator:async(e,l)=>{if(l&&t&&null!==t.max_budget&&l>t.max_budget)throw Error("Budget cannot exceed team max budget: $".concat(t.max_budget))}}],children:(0,r.jsx)(ei.Z,{step:.01,precision:2,width:200})}),(0,r.jsx)(er.Z.Item,{className:"mt-8",label:"Reset Budget",name:"budget_duration",help:"Team Reset Budget: ".concat((null==t?void 0:t.budget_duration)!==null&&(null==t?void 0:t.budget_duration)!==void 0?null==t?void 0:t.budget_duration:"None"),children:(0,r.jsxs)(ea.default,{defaultValue:null,placeholder:"n/a",children:[(0,r.jsx)(ea.default.Option,{value:"24h",children:"daily"}),(0,r.jsx)(ea.default.Option,{value:"30d",children:"monthly"})]})}),(0,r.jsx)(er.Z.Item,{className:"mt-8",label:"Tokens per minute Limit (TPM)",name:"tpm_limit",help:"TPM cannot exceed team TPM limit: ".concat((null==t?void 0:t.tpm_limit)!==null&&(null==t?void 0:t.tpm_limit)!==void 0?null==t?void 0:t.tpm_limit:"unlimited"),rules:[{validator:async(e,l)=>{if(l&&t&&null!==t.tpm_limit&&l>t.tpm_limit)throw Error("TPM limit cannot exceed team TPM limit: ".concat(t.tpm_limit))}}],children:(0,r.jsx)(ei.Z,{step:1,width:400})}),(0,r.jsx)(er.Z.Item,{className:"mt-8",label:"Requests per minute Limit (RPM)",name:"rpm_limit",help:"RPM cannot exceed team RPM limit: ".concat((null==t?void 0:t.rpm_limit)!==null&&(null==t?void 0:t.rpm_limit)!==void 0?null==t?void 0:t.rpm_limit:"unlimited"),rules:[{validator:async(e,l)=>{if(l&&t&&null!==t.rpm_limit&&l>t.rpm_limit)throw Error("RPM limit cannot exceed team RPM limit: ".concat(t.rpm_limit))}}],children:(0,r.jsx)(ei.Z,{step:1,width:400})}),(0,r.jsx)(er.Z.Item,{label:"Expire Key (eg: 30s, 30h, 30d)",name:"duration",className:"mt-8",children:(0,r.jsx)($.Z,{placeholder:""})}),(0,r.jsx)(er.Z.Item,{label:"Metadata",name:"metadata",children:(0,r.jsx)(eo.Z.TextArea,{rows:4,placeholder:"Enter metadata as JSON"})})]})]})]}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ec.ZP,{htmlType:"submit",children:"Create Key"})})]})}),u&&(0,r.jsx)(en.Z,{visible:d,onOk:Z,onCancel:w,footer:null,children:(0,r.jsxs)(Y.Z,{numItems:1,className:"gap-2 w-full",children:[(0,r.jsx)(et.Z,{children:"Save your Key"}),(0,r.jsx)(J.Z,{numColSpan:1,children:(0,r.jsxs)("p",{children:["Please save this secret key somewhere safe and accessible. For security reasons, ",(0,r.jsx)("b",{children:"you will not be able to view it again"})," ","through your LiteLLM account. If you lose this secret key, you will need to generate a new one."]})}),(0,r.jsx)(J.Z,{numColSpan:1,children:null!=u?(0,r.jsxs)("div",{children:[(0,r.jsx)(el.Z,{className:"mt-3",children:"API Key:"}),(0,r.jsx)("div",{style:{background:"#f8f8f8",padding:"10px",borderRadius:"5px",marginBottom:"10px"},children:(0,r.jsx)("pre",{style:{wordWrap:"break-word",whiteSpace:"normal"},children:u})}),(0,r.jsx)(es.CopyToClipboard,{text:u,onCopy:()=>{h.ZP.success("API Key copied to clipboard")},children:(0,r.jsx)(H.Z,{className:"mt-3",children:"Copy API Key"})})]}):(0,r.jsx)(el.Z,{children:"Key being created, this might take 30s"})})]})})]})},eh=t(9454),eu=t(98941),ex=t(33393),ep=t(5),ej=t(9853),eg=t(13810),ef=t(39290),ey=t(66952),eZ=t(61244),ew=t(10827),eb=t(3851),e_=t(2044),ek=t(64167),ev=t(74480),eS=t(7178),eA=t(95093),eN=t(27166);let{Option:eC}=ea.default;var eI=e=>{let{userID:l,userRole:t,accessToken:s,selectedTeam:a,data:o,setData:i,teams:c}=e,[d,m]=(0,n.useState)(!1),[u,x]=(0,n.useState)(!1),[p,j]=(0,n.useState)(null),[g,y]=n.useState(null),[Z,w]=(0,n.useState)(null),[b,_]=(0,n.useState)(null),[k,A]=(0,n.useState)(""),[N,C]=(0,n.useState)(!1),[I,P]=(0,n.useState)(null),[T,E]=(0,n.useState)([]),F=new Set,[O,M]=(0,n.useState)(F);(0,n.useEffect)(()=>{(async()=>{try{if(null===l)return;if(null!==s&&null!==t){let e=(await v(s,l,t)).data.map(e=>e.id);console.log("available_model_names:",e),E(e)}}catch(e){console.error("Error fetching user models:",e)}})()},[s,l,t]),(0,n.useEffect)(()=>{if(c){let e=new Set;c.forEach((l,t)=>{let s=l.team_id;e.add(s)}),M(e)}},[c]);let R=e=>{console.log("handleEditClick:",e),null==e.token&&null!==e.token_id&&(e.token=e.token_id),P(e),C(!0)},U=async e=>{if(null==s)return;let l=e.token;e.key=l,console.log("handleEditSubmit:",e);let t=await L(s,e);console.log("handleEditSubmit: newKeyValues",t),o&&i(o.map(e=>e.token===l?t:e)),h.ZP.success("Key updated successfully"),C(!1),P(null)},D=async e=>{try{if(null==s||null==e)return;console.log("accessToken: ".concat(s,"; token: ").concat(e.token));let l=await S(s,e.token);console.log("Response:",l),_(l);try{let e=await q(s,l);console.log("Response2:",e);let t=[...l,...e.response];_(t),A(e.predicted_spend),console.log("Combined Data:",t)}catch(e){console.error("There was an error fetching the predicted data",e)}}catch(e){console.error("There was an error fetching the data",e)}};(0,n.useEffect)(()=>{D(Z)},[Z]);let z=async e=>{console.log("handleDelete:",e),null==e.token&&null!==e.token_id&&(e.token=e.token_id),null!=o&&(j(e.token),localStorage.removeItem("userData"+l),x(!0))},B=async()=>{if(null!=p&&null!=o){try{await f(s,p);let e=o.filter(e=>e.token!==p);i(e)}catch(e){console.error("Error deleting the key:",e)}x(!1),j(null)}};if(null!=o)return console.log("RERENDER TRIGGERED"),(0,r.jsxs)("div",{children:[(0,r.jsxs)(eg.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh] mb-4 mt-2",children:[(0,r.jsxs)(ew.Z,{className:"mt-5 max-h-[300px] min-h-[300px]",children:[(0,r.jsx)(ek.Z,{children:(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(ev.Z,{children:"Key Alias"}),(0,r.jsx)(ev.Z,{children:"Secret Key"}),(0,r.jsx)(ev.Z,{children:"Spend (USD)"}),(0,r.jsx)(ev.Z,{children:"Budget (USD)"}),(0,r.jsx)(ev.Z,{children:"Models"}),(0,r.jsx)(ev.Z,{children:"TPM / RPM Limits"})]})}),(0,r.jsx)(eb.Z,{children:o.map(e=>{if(console.log(e),"litellm-dashboard"===e.team_id)return null;if(a){if(console.log("item team id: ".concat(e.team_id,", knownTeamIDs.has(item.team_id): ").concat(O.has(e.team_id),", selectedTeam id: ").concat(a.team_id)),(null!=a.team_id||null===e.team_id||O.has(e.team_id))&&e.team_id!=a.team_id)return null;console.log("item team id: ".concat(e.team_id,", is returned"))}return(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(e_.Z,{style:{maxWidth:"2px",whiteSpace:"pre-wrap",overflow:"hidden"},children:null!=e.key_alias?(0,r.jsx)(el.Z,{children:e.key_alias}):(0,r.jsx)(el.Z,{children:"Not Set"})}),(0,r.jsx)(e_.Z,{children:(0,r.jsx)(el.Z,{children:e.key_name})}),(0,r.jsx)(e_.Z,{children:(0,r.jsx)(el.Z,{children:(()=>{try{return parseFloat(e.spend).toFixed(4)}catch(l){return e.spend}})()})}),(0,r.jsx)(e_.Z,{children:null!=e.max_budget?(0,r.jsx)(el.Z,{children:e.max_budget}):(0,r.jsx)(el.Z,{children:"Unlimited"})}),(0,r.jsx)(e_.Z,{children:Array.isArray(e.models)?(0,r.jsx)("div",{style:{display:"flex",flexDirection:"column"},children:0===e.models.length?(0,r.jsx)(r.Fragment,{children:a&&a.models&&a.models.length>0?a.models.map((e,l)=>"all-proxy-models"===e?(0,r.jsx)(ep.Z,{size:"xs",className:"mb-1",color:"red",children:(0,r.jsx)(el.Z,{children:"All Proxy Models"})},l):"all-team-models"===e?(0,r.jsx)(ep.Z,{size:"xs",className:"mb-1",color:"red",children:(0,r.jsx)(el.Z,{children:"All Team Models"})},l):(0,r.jsx)(ep.Z,{size:"xs",className:"mb-1",color:"blue",children:(0,r.jsx)(el.Z,{children:e.length>30?"".concat(e.slice(0,30),"..."):e})},l)):(0,r.jsx)(ep.Z,{size:"xs",className:"mb-1",color:"blue",children:(0,r.jsx)(el.Z,{children:"all-proxy-models"})})}):e.models.map((e,l)=>"all-proxy-models"===e?(0,r.jsx)(ep.Z,{size:"xs",className:"mb-1",color:"red",children:(0,r.jsx)(el.Z,{children:"All Proxy Models"})},l):"all-team-models"===e?(0,r.jsx)(ep.Z,{size:"xs",className:"mb-1",color:"red",children:(0,r.jsx)(el.Z,{children:"All Team Models"})},l):(0,r.jsx)(ep.Z,{size:"xs",className:"mb-1",color:"blue",children:(0,r.jsx)(el.Z,{children:e.length>30?"".concat(e.slice(0,30),"..."):e})},l))}):null}),(0,r.jsx)(e_.Z,{children:(0,r.jsxs)(el.Z,{children:["TPM: ",e.tpm_limit?e.tpm_limit:"Unlimited"," ",(0,r.jsx)("br",{})," RPM:"," ",e.rpm_limit?e.rpm_limit:"Unlimited"]})}),(0,r.jsxs)(e_.Z,{children:[(0,r.jsx)(eZ.Z,{onClick:()=>{w(e),y(e.id)},icon:eh.Z,size:"sm"}),(0,r.jsx)(ef.Z,{open:null!==g,onClose:()=>{y(null),w(null)},children:(0,r.jsx)(ey.Z,{children:Z&&(0,r.jsxs)(r.Fragment,{children:[(0,r.jsxs)("div",{className:"grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3",children:[(0,r.jsxs)(eg.Z,{children:[(0,r.jsx)("p",{className:"text-tremor-default font-medium text-tremor-content dark:text-dark-tremor-content",children:"Spend"}),(0,r.jsx)("div",{className:"mt-2 flex items-baseline space-x-2.5",children:(0,r.jsx)("p",{className:"text-tremor font-semibold text-tremor-content-strong dark:text-dark-tremor-content-strong",children:(()=>{try{return parseFloat(Z.spend).toFixed(4)}catch(e){return Z.spend}})()})})]}),(0,r.jsxs)(eg.Z,{children:[(0,r.jsx)("p",{className:"text-tremor-default font-medium text-tremor-content dark:text-dark-tremor-content",children:"Budget"}),(0,r.jsx)("div",{className:"mt-2 flex items-baseline space-x-2.5",children:(0,r.jsx)("p",{className:"text-tremor font-semibold text-tremor-content-strong dark:text-dark-tremor-content-strong",children:null!=Z.max_budget?(0,r.jsx)(r.Fragment,{children:Z.max_budget}):(0,r.jsx)(r.Fragment,{children:"Unlimited"})})})]},e.name),(0,r.jsxs)(eg.Z,{children:[(0,r.jsx)("p",{className:"text-tremor-default font-medium text-tremor-content dark:text-dark-tremor-content",children:"Expires"}),(0,r.jsx)("div",{className:"mt-2 flex items-baseline space-x-2.5",children:(0,r.jsx)("p",{className:"text-tremor-default font-small text-tremor-content-strong dark:text-dark-tremor-content-strong",children:null!=Z.expires?(0,r.jsx)(r.Fragment,{children:new Date(Z.expires).toLocaleString(void 0,{day:"numeric",month:"long",year:"numeric",hour:"numeric",minute:"numeric",second:"numeric"})}):(0,r.jsx)(r.Fragment,{children:"Never"})})})]},e.name)]}),(0,r.jsx)(eg.Z,{className:"mt-6 mb-6",children:b&&(0,r.jsx)(ej.Z,{className:"mt-6",data:b,colors:["blue","amber"],index:"date",categories:["spend","predicted_spend"],yAxisWidth:80})}),(0,r.jsx)(et.Z,{children:"Metadata"}),(0,r.jsx)(el.Z,{children:JSON.stringify(Z.metadata)}),(0,r.jsx)(H.Z,{variant:"light",className:"mx-auto flex items-center",onClick:()=>{y(null),w(null)},children:"Close"})]})})}),(0,r.jsx)(eZ.Z,{icon:eu.Z,size:"sm",onClick:()=>R(e)}),(0,r.jsx)(eZ.Z,{onClick:()=>z(e),icon:ex.Z,size:"sm"})]})]},e.token)})})]}),u&&(0,r.jsx)("div",{className:"fixed z-10 inset-0 overflow-y-auto",children:(0,r.jsxs)("div",{className:"flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0",children:[(0,r.jsx)("div",{className:"fixed inset-0 transition-opacity","aria-hidden":"true",children:(0,r.jsx)("div",{className:"absolute inset-0 bg-gray-500 opacity-75"})}),(0,r.jsx)("span",{className:"hidden sm:inline-block sm:align-middle sm:h-screen","aria-hidden":"true",children:"​"}),(0,r.jsxs)("div",{className:"inline-block align-bottom bg-white rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full",children:[(0,r.jsx)("div",{className:"bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4",children:(0,r.jsx)("div",{className:"sm:flex sm:items-start",children:(0,r.jsxs)("div",{className:"mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left",children:[(0,r.jsx)("h3",{className:"text-lg leading-6 font-medium text-gray-900",children:"Delete Key"}),(0,r.jsx)("div",{className:"mt-2",children:(0,r.jsx)("p",{className:"text-sm text-gray-500",children:"Are you sure you want to delete this key ?"})})]})})}),(0,r.jsxs)("div",{className:"bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse",children:[(0,r.jsx)(H.Z,{onClick:B,color:"red",className:"ml-2",children:"Delete"}),(0,r.jsx)(H.Z,{onClick:()=>{x(!1),j(null)},children:"Cancel"})]})]})]})})]}),I&&(0,r.jsx)(e=>{let{visible:l,onCancel:t,token:s,onSubmit:o}=e,[i]=er.Z.useForm(),[d,m]=(0,n.useState)(a),[h,u]=(0,n.useState)([]),[x,p]=(0,n.useState)(!1);return(0,r.jsx)(en.Z,{title:"Edit Key",visible:l,width:800,footer:null,onOk:()=>{i.validateFields().then(e=>{i.resetFields()}).catch(e=>{console.error("Validation failed:",e)})},onCancel:t,children:(0,r.jsxs)(er.Z,{form:i,onFinish:U,initialValues:s,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(er.Z.Item,{label:"Key Name",name:"key_alias",rules:[{required:!0,message:"Please input a key name"}],help:"required",children:(0,r.jsx)(eo.Z,{})}),(0,r.jsx)(er.Z.Item,{label:"Models",name:"models",rules:[{validator:(e,l)=>{let t=l.filter(e=>!d.models.includes(e)&&"all-team-models"!==e&&"all-proxy-models"!==e&&!d.models.includes("all-proxy-models"));return(console.log("errorModels: ".concat(t)),t.length>0)?Promise.reject("Some models are not part of the new team's models - ".concat(t,"Team models: ").concat(d.models)):Promise.resolve()}}],children:(0,r.jsxs)(ea.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:[(0,r.jsx)(eC,{value:"all-team-models",children:"All Team Models"},"all-team-models"),d&&d.models?d.models.includes("all-proxy-models")?T.filter(e=>"all-proxy-models"!==e).map(e=>(0,r.jsx)(eC,{value:e,children:e},e)):d.models.map(e=>(0,r.jsx)(eC,{value:e,children:e},e)):T.map(e=>(0,r.jsx)(eC,{value:e,children:e},e))]})}),(0,r.jsx)(er.Z.Item,{className:"mt-8",label:"Max Budget (USD)",name:"max_budget",help:"Budget cannot exceed team max budget: ".concat((null==d?void 0:d.max_budget)!==null&&(null==d?void 0:d.max_budget)!==void 0?null==d?void 0:d.max_budget:"unlimited"),rules:[{validator:async(e,l)=>{if(l&&d&&null!==d.max_budget&&l>d.max_budget)throw console.log("keyTeam.max_budget: ".concat(d.max_budget)),Error("Budget cannot exceed team max budget: $".concat(d.max_budget))}}],children:(0,r.jsx)(ei.Z,{step:.01,precision:2,width:200})}),(0,r.jsx)(er.Z.Item,{label:"token",name:"token",hidden:!0}),(0,r.jsx)(er.Z.Item,{label:"Team",name:"team_id",help:"the team this key belongs to",children:(0,r.jsx)(eA.Z,{value:s.team_alias,children:null==c?void 0:c.map((e,l)=>(0,r.jsx)(eN.Z,{value:e.team_id,onClick:()=>m(e),children:e.team_alias},l))})})]}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ec.ZP,{htmlType:"submit",children:"Edit Key"})})]})})},{visible:N,onCancel:()=>{C(!1),P(null)},token:I,onSubmit:U})]})},eP=t(76032),eT=t(35152),eE=e=>{let{userID:l,userRole:t,accessToken:s,userSpend:a,selectedTeam:o}=e;console.log("userSpend: ".concat(a));let[i,c]=(0,n.useState)(null!==a?a:0),[d,m]=(0,n.useState)(0),[h,u]=(0,n.useState)([]);(0,n.useEffect)(()=>{let e=async()=>{if(s&&l&&t&&"Admin"===t&&null==a)try{let e=await b(s);e&&(e.spend?c(e.spend):c(0),e.max_budget?m(e.max_budget):m(0))}catch(e){console.error("Error fetching global spend data:",e)}};(async()=>{try{if(null===l||null===t)return;if(null!==s){let e=(await v(s,l,t)).data.map(e=>e.id);console.log("available_model_names:",e),u(e)}}catch(e){console.error("Error fetching user models:",e)}})(),e()},[t,s,l]),(0,n.useEffect)(()=>{null!==a&&c(a)},[a]);let x=[];o&&o.models&&(x=o.models),x&&x.includes("all-proxy-models")?(console.log("user models:",h),x=h):x&&x.includes("all-team-models")?x=o.models:x&&0===x.length&&(x=h);let p=void 0!==i?i.toFixed(4):null;return console.log("spend in view user spend: ".concat(i)),(0,r.jsxs)("div",{className:"flex items-center",children:[(0,r.jsxs)("div",{children:[(0,r.jsxs)("p",{className:"text-tremor-default text-tremor-content dark:text-dark-tremor-content",children:["Total Spend"," "]}),(0,r.jsxs)("p",{className:"text-2xl text-tremor-content-strong dark:text-dark-tremor-content-strong font-semibold",children:["$",p]})]}),(0,r.jsx)("div",{className:"ml-auto",children:(0,r.jsxs)(X.Z,{children:[(0,r.jsx)(ee.Z,{children:(0,r.jsx)(el.Z,{children:"Team Models"})}),(0,r.jsx)(Q.Z,{className:"absolute right-0 z-10 bg-white p-2 shadow-lg max-w-xs",children:(0,r.jsx)(eP.Z,{children:x.map(e=>(0,r.jsx)(eT.Z,{children:(0,r.jsx)(el.Z,{children:e})},e))})})]})})]})},eF=e=>{let{userID:l,userRole:t,selectedTeam:s,accessToken:a}=e,[o,i]=(0,n.useState)([]);(0,n.useEffect)(()=>{(async()=>{try{if(null===l||null===t)return;if(null!==a){let e=(await v(a,l,t)).data.map(e=>e.id);console.log("available_model_names:",e),i(e)}}catch(e){console.error("Error fetching user models:",e)}})()},[a,l,t]);let c=[];return s&&s.models&&(c=s.models),c&&c.includes("all-proxy-models")&&(console.log("user models:",o),c=o),(0,r.jsx)(r.Fragment,{children:(0,r.jsx)("div",{className:"mb-5",children:(0,r.jsx)("p",{className:"text-3xl text-tremor-content-strong dark:text-dark-tremor-content-strong font-semibold",children:null==s?void 0:s.team_alias})})})},eO=e=>{let l,{teams:t,setSelectedTeam:s,userRole:a}=e,o={models:[],team_id:null,team_alias:"Default Team"},[i,c]=(0,n.useState)(o);return(l="App User"===a?t:t?[...t,o]:[o],"App User"===a)?null:(0,r.jsxs)("div",{className:"mt-5 mb-5",children:[(0,r.jsx)(et.Z,{children:"Select Team"}),(0,r.jsx)(el.Z,{children:"If you belong to multiple teams, this setting controls which team is used by default when creating new API Keys."}),(0,r.jsxs)(el.Z,{className:"mt-3 mb-3",children:[(0,r.jsx)("b",{children:"Default Team:"})," If no team_id is set for a key, it will be grouped under here."]}),l&&l.length>0?(0,r.jsx)(eA.Z,{defaultValue:"0",children:l.map((e,l)=>(0,r.jsx)(eN.Z,{value:String(l),onClick:()=>s(e),children:e.team_alias},l))}):(0,r.jsxs)(el.Z,{children:["No team created. ",(0,r.jsx)("b",{children:"Defaulting to personal account."})]})]})},eM=t(37963),eR=t(36083);console.log("isLocal:",!1);var eL=e=>{let{userID:l,userRole:t,teams:s,keys:a,setUserRole:i,userEmail:c,setUserEmail:d,setTeams:m,setKeys:h}=e,[u,x]=(0,n.useState)(null),p=(0,o.useSearchParams)();p.get("viewSpend"),(0,o.useRouter)();let j=p.get("token"),[g,f]=(0,n.useState)(null),[y,w]=(0,n.useState)(null),[_,k]=(0,n.useState)([]),S={models:[],team_alias:"Default Team",team_id:null},[A,N]=(0,n.useState)(s?s[0]:S);if(window.addEventListener("beforeunload",function(){sessionStorage.clear()}),(0,n.useEffect)(()=>{if(j){let e=(0,eM.o)(j);if(e){if(console.log("Decoded token:",e),console.log("Decoded key:",e.key),f(e.key),e.user_role){let l=function(e){if(!e)return"Undefined Role";switch(console.log("Received user role: ".concat(e)),e.toLowerCase()){case"app_owner":case"demo_app_owner":return"App Owner";case"app_admin":case"proxy_admin":return"Admin";case"proxy_admin_viewer":return"Admin Viewer";case"app_user":return"App User";default:return"Unknown Role"}}(e.user_role);console.log("Decoded user_role:",l),i(l)}else console.log("User role not defined");e.user_email?d(e.user_email):console.log("User Email is not set ".concat(e))}}if(l&&g&&t&&!a&&!u){let e=sessionStorage.getItem("userModels"+l);e?k(JSON.parse(e)):(async()=>{try{let e=await Z(g,l,t,!1,null,null);if(console.log("received teams in user dashboard: ".concat(Object.keys(e),"; team values: ").concat(Object.entries(e.teams))),"Admin"==t){let e=await b(g);x(e),console.log("globalSpend:",e)}else x(e.user_info);h(e.keys),m(e.teams);let s=[...e.teams];s.length>0?(console.log("response['teams']: ".concat(s)),N(s[0])):N(S),sessionStorage.setItem("userData"+l,JSON.stringify(e.keys)),sessionStorage.setItem("userSpendData"+l,JSON.stringify(e.user_info));let a=(await v(g,l,t)).data.map(e=>e.id);console.log("available_model_names:",a),k(a),console.log("userModels:",_),sessionStorage.setItem("userModels"+l,JSON.stringify(a))}catch(e){console.error("There was an error fetching the data",e)}})()}},[l,j,g,a,t]),(0,n.useEffect)(()=>{if(null!==a&&null!=A){let e=0;for(let l of a)A.hasOwnProperty("team_id")&&null!==l.team_id&&l.team_id===A.team_id&&(e+=l.spend);w(e)}else if(null!==a){let e=0;for(let l of a)e+=l.spend;w(e)}},[A]),null==l||null==j){let e="/sso/key/generate";return console.log("Full URL:",e),window.location.href=e,null}if(null==g)return null;if(null==t&&i("App Owner"),t&&"Admin Viewer"==t){let{Title:e,Paragraph:l}=eR.default;return(0,r.jsxs)("div",{children:[(0,r.jsx)(e,{level:1,children:"Access Denied"}),(0,r.jsx)(l,{children:"Ask your proxy admin for access to create keys"})]})}return console.log("inside user dashboard, selected team",A),console.log("teamSpend: ".concat(y)),(0,r.jsx)("div",{className:"w-full mx-4",children:(0,r.jsx)(Y.Z,{numItems:1,className:"gap-2 p-8 h-[75vh] w-full mt-2",children:(0,r.jsxs)(J.Z,{numColSpan:1,children:[(0,r.jsx)(eF,{userID:l,userRole:t,selectedTeam:A||null,accessToken:g}),(0,r.jsx)(eE,{userID:l,userRole:t,accessToken:g,userSpend:y,selectedTeam:A||null}),(0,r.jsx)(eI,{userID:l,userRole:t,accessToken:g,selectedTeam:A||null,data:a,setData:h,teams:s}),(0,r.jsx)(em,{userID:l,team:A||null,userRole:t,accessToken:g,data:a,setData:h},A?A.team_id:null),(0,r.jsx)(eO,{teams:s,setSelectedTeam:N,userRole:t})]})})})},eU=t(92836),eD=t(26734),ez=t(41608),eB=t(32126),eq=t(23682),eK=t(47047),eV=t(76628),eG=t(38302),eW=t(28683),eJ=t(1460),eY=t(78578),eH=t(63954),e$=e=>{let{modelID:l,accessToken:t}=e,[s,a]=(0,n.useState)(!1),o=async()=>{try{h.ZP.info("Making API Call"),a(!0);let e=await p(t,l);console.log("model delete Response:",e),h.ZP.success("Model ".concat(l," deleted successfully")),a(!1)}catch(e){console.error("Error deleting the model:",e)}};return(0,r.jsxs)("div",{children:[(0,r.jsx)(eZ.Z,{onClick:()=>a(!0),icon:ex.Z,size:"sm"}),(0,r.jsx)(en.Z,{open:s,onOk:o,okType:"danger",onCancel:()=>a(!1),children:(0,r.jsxs)(Y.Z,{numItems:1,className:"gap-2 w-full",children:[(0,r.jsx)(et.Z,{children:"Delete Model"}),(0,r.jsx)(J.Z,{numColSpan:1,children:(0,r.jsx)("p",{children:"Are you sure you want to delete this model? This action is irreversible."})}),(0,r.jsx)(J.Z,{numColSpan:1,children:(0,r.jsxs)("p",{children:["Model ID: ",(0,r.jsx)("b",{children:l})]})})]})})]})},eX=t(97766),eQ=t(46495);let{Title:e0,Link:e1}=eR.default;(s=a||(a={})).OpenAI="OpenAI",s.Azure="Azure",s.Anthropic="Anthropic",s.Google_AI_Studio="Gemini (Google AI Studio)",s.Bedrock="Amazon Bedrock",s.OpenAI_Compatible="OpenAI-Compatible Endpoints (Groq, Together AI, Mistral AI, etc.)",s.Vertex_AI="Vertex AI (Anthropic, Gemini, etc.)";let e2={OpenAI:"openai",Azure:"azure",Anthropic:"anthropic",Google_AI_Studio:"gemini",Bedrock:"bedrock",OpenAI_Compatible:"openai",Vertex_AI:"vertex_ai"},e4=async(e,l,t)=>{try{let s=Array.isArray(e.model)?e.model:[e.model];console.log("received deployments: ".concat(s)),console.log("received type of deployments: ".concat(typeof s)),s.forEach(async t=>{console.log("litellm_model: ".concat(t));let s={},a={};s.model=t;let r="";for(let[l,t]of Object.entries(e))if(""!==t){if("model_name"==l)r+=t;else if("custom_llm_provider"==l)continue;else if("model"==l)continue;else if("base_model"===l)a[l]=t;else if("litellm_extra_params"==l){console.log("litellm_extra_params:",t);let e={};if(t&&void 0!=t){try{e=JSON.parse(t)}catch(e){throw h.ZP.error("Failed to parse LiteLLM Extra Params: "+e,20),Error("Failed to parse litellm_extra_params: "+e)}for(let[l,t]of Object.entries(e))s[l]=t}}else s[l]=t}let n={model_name:r,litellm_params:s,model_info:a},o=await x(l,n);console.log("response for model create call: ".concat(o.data))}),t.resetFields()}catch(e){h.ZP.error("Failed to create model: "+e,20)}};var e8=e=>{var l,t,s;let{accessToken:o,token:i,userRole:c,userID:d,modelData:m={data:[]},setModelData:x}=e,[p,j]=(0,n.useState)([]),[g]=er.Z.useForm(),[f,y]=(0,n.useState)(null),[Z,w]=(0,n.useState)(""),[b,k]=(0,n.useState)([]),v=Object.values(a).filter(e=>isNaN(Number(e))),[S,A]=(0,n.useState)("OpenAI"),[N,C]=(0,n.useState)(""),[I,P]=(0,n.useState)(!1),[T,E]=(0,n.useState)(null),[F,M]=(0,n.useState)([]),[R,L]=(0,n.useState)(null),U=e=>{E(e),P(!0)},z=async e=>{if(console.log("handleEditSubmit:",e),null==o)return;let l={},t=null;for(let[s,a]of Object.entries(e))"model_id"!==s?l[s]=a:t=a;let s={litellm_params:l,model_info:{id:t}};console.log("handleEditSubmit payload:",s),await D(o,s),h.ZP.success("Model updated successfully, restart server to see updates"),P(!1),E(null)},B=()=>{w(new Date().toLocaleString())};if((0,n.useEffect)(()=>{if(!o||!i||!c||!d)return;let e=async()=>{try{let e=await _(o,d,c);console.log("Model data response:",e.data),x(e);let l=new Set;for(let t=0;t{let e=await u();console.log("received model cost map data: ".concat(Object.keys(e))),y(e)};null==f&&l(),B()},[o,i,c,d,f,Z]),!m||!o||!i||!c||!d)return(0,r.jsx)("div",{children:"Loading..."});let q=[];for(let e=0;e(console.log("GET PROVIDER CALLED! - ".concat(f)),null!=f&&"object"==typeof f&&e in f)?f[e].litellm_provider:"openai";if(a){let e=a.split("/"),l=e[0];n=1===e.length?h(a):l}else n="openai";r&&(o=null==r?void 0:r.input_cost_per_token,i=null==r?void 0:r.output_cost_per_token,c=null==r?void 0:r.max_tokens),(null==s?void 0:s.litellm_params)&&(d=Object.fromEntries(Object.entries(null==s?void 0:s.litellm_params).filter(e=>{let[l]=e;return"model"!==l&&"api_base"!==l}))),m.data[e].provider=n,m.data[e].input_cost=o,m.data[e].output_cost=i,m.data[e].max_tokens=c,m.data[e].api_base=null==s?void 0:null===(t=s.litellm_params)||void 0===t?void 0:t.api_base,m.data[e].cleanedLitellmParams=d,q.push(s.model_name),console.log(m.data[e])}if(c&&"Admin Viewer"==c){let{Title:e,Paragraph:l}=eR.default;return(0,r.jsxs)("div",{children:[(0,r.jsx)(e,{level:1,children:"Access Denied"}),(0,r.jsx)(l,{children:"Ask your proxy admin for access to view all models"})]})}let K=e=>{console.log("received provider string: ".concat(e));let l=Object.keys(a).find(l=>a[l]===e);if(l){let e=e2[l];console.log("mappingResult: ".concat(e));let t=[];"object"==typeof f&&Object.entries(f).forEach(l=>{let[s,a]=l;null!==a&&"object"==typeof a&&"litellm_provider"in a&&(a.litellm_provider===e||a.litellm_provider.includes(e))&&t.push(s)}),k(t),console.log("providerModels: ".concat(b))}},V=async()=>{try{h.ZP.info("Running health check..."),C("");let e=await W(o);C(e)}catch(e){console.error("Error running health check:",e),C("Error running health check")}};return console.log("selectedProvider: ".concat(S)),console.log("providerModels.length: ".concat(b.length)),(0,r.jsx)("div",{style:{width:"100%",height:"100%"},children:(0,r.jsxs)(eD.Z,{className:"gap-2 p-8 h-[75vh] w-full mt-2",children:[(0,r.jsxs)(ez.Z,{className:"flex justify-between mt-2 w-full items-center",children:[(0,r.jsxs)("div",{className:"flex",children:[(0,r.jsx)(eU.Z,{children:"All Models"}),(0,r.jsx)(eU.Z,{children:"Add Model"}),(0,r.jsx)(eU.Z,{children:(0,r.jsx)("pre",{children:"/health Models"})})]}),(0,r.jsxs)("div",{className:"flex items-center space-x-2",children:[Z&&(0,r.jsxs)(el.Z,{children:["Last Refreshed: ",Z]}),(0,r.jsx)(eZ.Z,{icon:eH.Z,variant:"shadow",size:"xs",className:"self-center",onClick:B})]})]}),(0,r.jsxs)(eq.Z,{children:[(0,r.jsxs)(eB.Z,{children:[(0,r.jsxs)(Y.Z,{children:[(0,r.jsxs)("div",{className:"flex items-center",children:[(0,r.jsx)(el.Z,{children:"Filter by Public Model Name"}),(0,r.jsxs)(eA.Z,{className:"mb-4 mt-2 ml-2 w-50",defaultValue:"all",onValueChange:e=>L("all"===e?"all":e),children:[(0,r.jsx)(eN.Z,{value:"all",children:"All Models"}),F.map((e,l)=>(0,r.jsx)(eN.Z,{value:e,onClick:()=>L(e),children:e},l))]})]}),(0,r.jsx)(eg.Z,{children:(0,r.jsxs)(ew.Z,{className:"mt-5",children:[(0,r.jsx)(ek.Z,{children:(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(ev.Z,{children:"Public Model Name "}),(0,r.jsx)(ev.Z,{children:"Provider"}),"Admin"===c&&(0,r.jsx)(ev.Z,{children:"API Base"}),(0,r.jsx)(ev.Z,{children:"Extra litellm Params"}),(0,r.jsx)(ev.Z,{children:"Input Price per token ($)"}),(0,r.jsx)(ev.Z,{children:"Output Price per token ($)"}),(0,r.jsx)(ev.Z,{children:"Max Tokens"})]})}),(0,r.jsx)(eb.Z,{children:m.data.filter(e=>"all"===R||e.model_name===R||null==R||""===R).map((e,l)=>(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(e_.Z,{children:(0,r.jsx)(el.Z,{children:e.model_name})}),(0,r.jsx)(e_.Z,{children:e.provider}),"Admin"===c&&(0,r.jsx)(e_.Z,{children:e.api_base}),(0,r.jsx)(e_.Z,{children:(0,r.jsxs)(X.Z,{children:[(0,r.jsx)(ee.Z,{children:(0,r.jsx)(el.Z,{children:"Litellm params"})}),(0,r.jsx)(Q.Z,{children:(0,r.jsx)("pre",{children:JSON.stringify(e.cleanedLitellmParams,null,2)})})]})}),(0,r.jsx)(e_.Z,{children:e.input_cost}),(0,r.jsx)(e_.Z,{children:e.output_cost}),(0,r.jsx)(e_.Z,{children:e.max_tokens}),(0,r.jsxs)(e_.Z,{children:[(0,r.jsx)(eZ.Z,{icon:eu.Z,size:"sm",onClick:()=>U(e)}),(0,r.jsx)(e$,{modelID:e.model_info.id,accessToken:o})]})]},l))})]})})]}),(0,r.jsx)(e=>{let{visible:l,onCancel:t,model:s,onSubmit:a}=e,[n]=er.Z.useForm(),o={},i="",c="";if(s){o=s.litellm_params,i=s.model_name;let e=s.model_info;e&&(c=e.id,console.log("model_id: ".concat(c)),o.model_id=c)}return(0,r.jsx)(en.Z,{title:"Edit Model "+i,visible:l,width:800,footer:null,onOk:()=>{n.validateFields().then(e=>{a(e),n.resetFields()}).catch(e=>{console.error("Validation failed:",e)})},onCancel:t,children:(0,r.jsxs)(er.Z,{form:n,onFinish:z,initialValues:o,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(er.Z.Item,{className:"mt-8",label:"api_base",name:"api_base",children:(0,r.jsx)($.Z,{})}),(0,r.jsx)(er.Z.Item,{label:"tpm",name:"tpm",tooltip:"int (optional) - Tokens limit for this deployment: in tokens per minute (tpm). Find this information on your model/providers website",children:(0,r.jsx)(ei.Z,{min:0,step:1})}),(0,r.jsx)(er.Z.Item,{label:"rpm",name:"rpm",tooltip:"int (optional) - Rate limit for this deployment: in requests per minute (rpm). Find this information on your model/providers website",children:(0,r.jsx)(ei.Z,{min:0,step:1})}),(0,r.jsx)(er.Z.Item,{label:"max_retries",name:"max_retries",children:(0,r.jsx)(ei.Z,{min:0,step:1})}),(0,r.jsx)(er.Z.Item,{label:"timeout",name:"timeout",tooltip:"int (optional) - Timeout in seconds for LLM requests (Defaults to 600 seconds)",children:(0,r.jsx)(ei.Z,{min:0,step:1})}),(0,r.jsx)(er.Z.Item,{label:"stream_timeout",name:"stream_timeout",tooltip:"int (optional) - Timeout for stream requests (seconds)",children:(0,r.jsx)(ei.Z,{min:0,step:1})}),(0,r.jsx)(er.Z.Item,{label:"model_id",name:"model_id",hidden:!0})]}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ec.ZP,{htmlType:"submit",children:"Save"})})]})})},{visible:I,onCancel:()=>{P(!1),E(null)},model:T,onSubmit:z})]}),(0,r.jsxs)(eB.Z,{className:"h-full",children:[(0,r.jsx)(e0,{level:2,children:"Add new model"}),(0,r.jsx)(eg.Z,{children:(0,r.jsxs)(er.Z,{form:g,onFinish:()=>{g.validateFields().then(e=>{e4(e,o,g)}).catch(e=>{console.error("Validation failed:",e)})},labelCol:{span:10},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(er.Z.Item,{rules:[{required:!0,message:"Required"}],label:"Provider:",name:"custom_llm_provider",tooltip:"E.g. OpenAI, Azure OpenAI, Anthropic, Bedrock, etc.",labelCol:{span:10},labelAlign:"left",children:(0,r.jsx)(eA.Z,{value:S.toString(),children:v.map((e,l)=>(0,r.jsx)(eN.Z,{value:e,onClick:()=>{K(e),A(e)},children:e},l))})}),(0,r.jsx)(er.Z.Item,{rules:[{required:!0,message:"Required"}],label:"Public Model Name",name:"model_name",tooltip:"Model name your users will pass in. Also used for load-balancing, LiteLLM will load balance between all models with this public name.",className:"mb-0",children:(0,r.jsx)($.Z,{placeholder:"Vertex AI (Anthropic, Gemini, etc.)"===(s=S.toString())?"gemini-pro":"Anthropic"==s?"claude-3-opus":"Amazon Bedrock"==s?"claude-3-opus":"Gemini (Google AI Studio)"==s?"gemini-pro":"gpt-3.5-turbo"})}),(0,r.jsxs)(eG.Z,{children:[(0,r.jsx)(eW.Z,{span:10}),(0,r.jsx)(eW.Z,{span:10,children:(0,r.jsx)(el.Z,{className:"mb-3 mt-1",children:"Model name your users will pass in."})})]}),(0,r.jsx)(er.Z.Item,{rules:[{required:!0,message:"Required"}],label:"LiteLLM Model Name(s)",name:"model",tooltip:"Actual model name used for making litellm.completion() call.",className:"mb-0",children:"Azure"===S?(0,r.jsx)($.Z,{placeholder:"Enter model name"}):b.length>0?(0,r.jsx)(eK.Z,{value:b,children:b.map((e,l)=>(0,r.jsx)(eV.Z,{value:e,children:e},l))}):(0,r.jsx)($.Z,{placeholder:"gpt-3.5-turbo-0125"})}),(0,r.jsxs)(eG.Z,{children:[(0,r.jsx)(eW.Z,{span:10}),(0,r.jsx)(eW.Z,{span:10,children:(0,r.jsxs)(el.Z,{className:"mb-3 mt-1",children:["Actual model name used for making ",(0,r.jsx)(e1,{href:"https://docs.litellm.ai/docs/providers",target:"_blank",children:"litellm.completion() call"}),". We'll ",(0,r.jsx)(e1,{href:"https://docs.litellm.ai/docs/proxy/reliability#step-1---set-deployments-on-config",target:"_blank",children:"loadbalance"})," models with the same 'public name'"]})})]}),"Amazon Bedrock"!=S&&"Vertex AI (Anthropic, Gemini, etc.)"!=S&&(0,r.jsx)(er.Z.Item,{rules:[{required:!0,message:"Required"}],label:"API Key",name:"api_key",children:(0,r.jsx)($.Z,{placeholder:"sk-",type:"password"})}),"OpenAI"==S&&(0,r.jsx)(er.Z.Item,{label:"Organization ID",name:"organization_id",children:(0,r.jsx)($.Z,{placeholder:"[OPTIONAL] my-unique-org"})}),"Vertex AI (Anthropic, Gemini, etc.)"==S&&(0,r.jsx)(er.Z.Item,{rules:[{required:!0,message:"Required"}],label:"Vertex Project",name:"vertex_project",children:(0,r.jsx)($.Z,{placeholder:"adroit-cadet-1234.."})}),"Vertex AI (Anthropic, Gemini, etc.)"==S&&(0,r.jsx)(er.Z.Item,{rules:[{required:!0,message:"Required"}],label:"Vertex Location",name:"vertex_location",children:(0,r.jsx)($.Z,{placeholder:"us-east-1"})}),"Vertex AI (Anthropic, Gemini, etc.)"==S&&(0,r.jsx)(er.Z.Item,{rules:[{required:!0,message:"Required"}],label:"Vertex Credentials",name:"vertex_credentials",className:"mb-0",children:(0,r.jsx)(eQ.Z,{name:"file",accept:".json",beforeUpload:e=>{if("application/json"===e.type){let l=new FileReader;l.onload=e=>{if(e.target){let l=e.target.result;g.setFieldsValue({vertex_credentials:l})}},l.readAsText(e)}return!1},onChange(e){"uploading"!==e.file.status&&console.log(e.file,e.fileList),"done"===e.file.status?h.ZP.success("".concat(e.file.name," file uploaded successfully")):"error"===e.file.status&&h.ZP.error("".concat(e.file.name," file upload failed."))},children:(0,r.jsx)(ec.ZP,{icon:(0,r.jsx)(eX.Z,{}),children:"Click to Upload"})})}),"Vertex AI (Anthropic, Gemini, etc.)"==S&&(0,r.jsxs)(eG.Z,{children:[(0,r.jsx)(eW.Z,{span:10}),(0,r.jsx)(eW.Z,{span:10,children:(0,r.jsx)(el.Z,{className:"mb-3 mt-1",children:"Give litellm a gcp service account(.json file), so it can make the relevant calls"})})]}),("Azure"==S||"OpenAI-Compatible Endpoints (Groq, Together AI, Mistral AI, etc.)"==S)&&(0,r.jsx)(er.Z.Item,{rules:[{required:!0,message:"Required"}],label:"API Base",name:"api_base",children:(0,r.jsx)($.Z,{placeholder:"https://..."})}),"Azure"==S&&(0,r.jsx)(er.Z.Item,{rules:[{required:!0,message:"Required"}],label:"API Version",name:"api_version",children:(0,r.jsx)($.Z,{placeholder:"2023-07-01-preview"})}),"Azure"==S&&(0,r.jsxs)(er.Z.Item,{label:"Base Model",name:"base_model",children:[(0,r.jsx)($.Z,{placeholder:"azure/gpt-3.5-turbo"}),(0,r.jsxs)(el.Z,{children:["The actual model your azure deployment uses. Used for accurate cost tracking. Select name from ",(0,r.jsx)(e1,{href:"https://github.com/BerriAI/litellm/blob/main/model_prices_and_context_window.json",target:"_blank",children:"here"})]})]}),"Amazon Bedrock"==S&&(0,r.jsx)(er.Z.Item,{rules:[{required:!0,message:"Required"}],label:"AWS Access Key ID",name:"aws_access_key_id",tooltip:"You can provide the raw key or the environment variable (e.g. `os.environ/MY_SECRET_KEY`).",children:(0,r.jsx)($.Z,{placeholder:""})}),"Amazon Bedrock"==S&&(0,r.jsx)(er.Z.Item,{rules:[{required:!0,message:"Required"}],label:"AWS Secret Access Key",name:"aws_secret_access_key",tooltip:"You can provide the raw key or the environment variable (e.g. `os.environ/MY_SECRET_KEY`).",children:(0,r.jsx)($.Z,{placeholder:""})}),"Amazon Bedrock"==S&&(0,r.jsx)(er.Z.Item,{rules:[{required:!0,message:"Required"}],label:"AWS Region Name",name:"aws_region_name",tooltip:"You can provide the raw key or the environment variable (e.g. `os.environ/MY_SECRET_KEY`).",children:(0,r.jsx)($.Z,{placeholder:"us-east-1"})}),(0,r.jsx)(er.Z.Item,{label:"LiteLLM Params",name:"litellm_extra_params",tooltip:"Optional litellm params used for making a litellm.completion() call.",className:"mb-0",children:(0,r.jsx)(eY.Z,{rows:4,placeholder:'{ "rpm": 100, "timeout": 0, "stream_timeout": 0 }'})}),(0,r.jsxs)(eG.Z,{children:[(0,r.jsx)(eW.Z,{span:10}),(0,r.jsx)(eW.Z,{span:10,children:(0,r.jsxs)(el.Z,{className:"mb-3 mt-1",children:["Pass JSON of litellm supported params ",(0,r.jsx)(e1,{href:"https://docs.litellm.ai/docs/completion/input",target:"_blank",children:"litellm.completion() call"})]})})]})]}),(0,r.jsx)("div",{style:{textAlign:"center",marginTop:"10px"},children:(0,r.jsx)(ec.ZP,{htmlType:"submit",children:"Add Model"})}),(0,r.jsx)(eJ.Z,{title:"Get help on our github",children:(0,r.jsx)(eR.default.Link,{href:"https://github.com/BerriAI/litellm/issues",children:"Need Help?"})})]})})]}),(0,r.jsx)(eB.Z,{children:(0,r.jsxs)(eg.Z,{children:[(0,r.jsx)(el.Z,{children:"`/health` will run a very small request through your models configured on litellm"}),(0,r.jsx)(H.Z,{onClick:V,children:"Run `/health`"}),N&&(0,r.jsx)("pre",{children:JSON.stringify(N,null,2)})]})})]})]})})};let{Option:e5}=ea.default;var e3=e=>{let{userID:l,accessToken:t,teams:s}=e,[a]=er.Z.useForm(),[o,i]=(0,n.useState)(!1),[c,d]=(0,n.useState)(null),[m,u]=(0,n.useState)([]);(0,n.useEffect)(()=>{(async()=>{try{let e=await v(t,l,"any"),s=[];for(let l=0;l{i(!1),a.resetFields()},p=()=>{i(!1),d(null),a.resetFields()},j=async e=>{try{h.ZP.info("Making API Call"),i(!0),console.log("formValues in create user:",e);let s=await g(t,null,e);console.log("user create Response:",s),d(s.key),h.ZP.success("API user Created"),a.resetFields(),localStorage.removeItem("userData"+l)}catch(e){console.error("Error creating the user:",e)}};return(0,r.jsxs)("div",{children:[(0,r.jsx)(H.Z,{className:"mx-auto",onClick:()=>i(!0),children:"+ Invite User"}),(0,r.jsxs)(en.Z,{title:"Invite User",visible:o,width:800,footer:null,onOk:x,onCancel:p,children:[(0,r.jsx)(el.Z,{className:"mb-1",children:"Invite a user to login to the Admin UI and create Keys"}),(0,r.jsx)(el.Z,{className:"mb-6",children:(0,r.jsx)("b",{children:"Note: SSO Setup Required for this"})}),(0,r.jsxs)(er.Z,{form:a,onFinish:j,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsx)(er.Z.Item,{label:"User Email",name:"user_email",children:(0,r.jsx)($.Z,{placeholder:""})}),(0,r.jsx)(er.Z.Item,{label:"Team ID",name:"team_id",children:(0,r.jsx)(ea.default,{placeholder:"Select Team ID",style:{width:"100%"},children:s?s.map(e=>(0,r.jsx)(e5,{value:e.team_id,children:e.team_alias},e.team_id)):(0,r.jsx)(e5,{value:null,children:"Default Team"},"default")})}),(0,r.jsx)(er.Z.Item,{label:"Metadata",name:"metadata",children:(0,r.jsx)(eo.Z.TextArea,{rows:4,placeholder:"Enter metadata as JSON"})}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ec.ZP,{htmlType:"submit",children:"Create User"})})]})]}),c&&(0,r.jsxs)(en.Z,{title:"User Created Successfully",visible:o,onOk:x,onCancel:p,footer:null,children:[(0,r.jsx)("p",{children:"User has been created to access your proxy. Please Ask them to Log In."}),(0,r.jsx)("br",{}),(0,r.jsx)("p",{children:(0,r.jsx)("b",{children:"Note: This Feature is only supported through SSO on the Admin UI"})})]})]})},e6=e=>{let{accessToken:l,token:t,keys:s,userRole:a,userID:o,teams:i,setKeys:c}=e,[d,m]=(0,n.useState)(null),[h,u]=(0,n.useState)(null),[x,p]=(0,n.useState)(0),[j,g]=n.useState(null),[f,y]=(0,n.useState)(null);if((0,n.useEffect)(()=>{if(!l||!t||!a||!o)return;let e=async()=>{try{let e=await Z(l,null,a,!0,x,25);console.log("user data response:",e),m(e)}catch(e){console.error("There was an error fetching the model data",e)}};l&&t&&a&&o&&e();let s=async()=>{try{let e=await T(l,null);console.log("user data response:",e),u(e)}catch(e){console.error("There was an error fetching the model data",e)}};a&&("Admin"==a||"Admin Viewer"==a)&&!h&&s()},[l,t,a,o,x]),!d||!l||!t||!a||!o)return(0,r.jsx)("div",{children:"Loading..."});let w=async e=>{try{let t=await T(l,e);console.log("user data response:",t),u(t)}catch(e){console.error("There was an error fetching the model data",e)}};return(0,r.jsx)("div",{style:{width:"100%"},children:(0,r.jsxs)(Y.Z,{className:"gap-2 p-2 h-[80vh] w-full mt-8",children:[(0,r.jsx)(e3,{userID:o,accessToken:l,teams:i}),(0,r.jsxs)(eg.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[80vh] mb-4",children:[(0,r.jsxs)("div",{className:"mb-4 mt-1",children:[(0,r.jsxs)(el.Z,{children:[(0,r.jsx)("b",{children:"Key Owners: "})," Users on LiteLLM that created API Keys. Automatically tracked by LiteLLM"]}),(0,r.jsxs)(el.Z,{className:"mt-1",children:[(0,r.jsx)("b",{children:"End Users: "}),"End Users of your LLM API calls. Tracked When a `user` param is passed in your LLM calls"]})]}),(0,r.jsxs)(eD.Z,{children:[(0,r.jsxs)(ez.Z,{variant:"line",defaultValue:"1",children:[(0,r.jsx)(eU.Z,{value:"1",children:"Key Owners"}),(0,r.jsx)(eU.Z,{value:"2",children:"End-Users"})]}),(0,r.jsxs)(eq.Z,{children:[(0,r.jsx)(eB.Z,{children:(0,r.jsxs)(ew.Z,{className:"mt-5",children:[(0,r.jsx)(ek.Z,{children:(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(ev.Z,{children:"User ID"}),(0,r.jsx)(ev.Z,{children:"User Email"}),(0,r.jsx)(ev.Z,{children:"User Models"}),(0,r.jsx)(ev.Z,{children:"User Spend ($ USD)"}),(0,r.jsx)(ev.Z,{children:"User Max Budget ($ USD)"}),(0,r.jsx)(ev.Z,{children:"User API Key Aliases"})]})}),(0,r.jsx)(eb.Z,{children:d.map(e=>(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(e_.Z,{children:e.user_id}),(0,r.jsx)(e_.Z,{children:e.user_email}),(0,r.jsx)(e_.Z,{children:e.models&&e.models.length>0?e.models:"All Models"}),(0,r.jsx)(e_.Z,{children:e.spend?e.spend:0}),(0,r.jsx)(e_.Z,{children:e.max_budget?e.max_budget:"Unlimited"}),(0,r.jsx)(e_.Z,{children:(0,r.jsx)(Y.Z,{numItems:2,children:e&&e.key_aliases&&e.key_aliases.filter(e=>null!==e).length>0?(0,r.jsx)(ep.Z,{size:"xs",color:"indigo",children:e.key_aliases.filter(e=>null!==e).join(", ")}):(0,r.jsx)(ep.Z,{size:"xs",color:"gray",children:"No Keys"})})})]},e.user_id))})]})}),(0,r.jsxs)(eB.Z,{children:[(0,r.jsxs)("div",{className:"flex items-center",children:[(0,r.jsx)("div",{className:"flex-1"}),(0,r.jsxs)("div",{className:"flex-1 flex justify-between items-center",children:[(0,r.jsx)(el.Z,{className:"w-1/4 mr-2 text-right",children:"Key"}),(0,r.jsx)(eA.Z,{defaultValue:"1",className:"w-3/4",children:null==s?void 0:s.map((e,l)=>{if(e&&null!==e.key_alias&&e.key_alias.length>0)return(0,r.jsx)(eN.Z,{value:String(l),onClick:()=>w(e.token),children:e.key_alias},l)})})]})]}),(0,r.jsxs)(ew.Z,{className:"max-h-[70vh] min-h-[500px]",children:[(0,r.jsx)(ek.Z,{children:(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(ev.Z,{children:"End User"}),(0,r.jsx)(ev.Z,{children:"Spend"}),(0,r.jsx)(ev.Z,{children:"Total Events"})]})}),(0,r.jsx)(eb.Z,{children:null==h?void 0:h.map((e,l)=>(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(e_.Z,{children:e.end_user}),(0,r.jsx)(e_.Z,{children:e.total_spend}),(0,r.jsx)(e_.Z,{children:e.total_events})]},l))})]})]})]})]})]}),function(){if(!d)return null;let e=Math.ceil(d.length/25);return(0,r.jsxs)("div",{className:"flex justify-between items-center",children:[(0,r.jsxs)("div",{children:["Showing Page ",x+1," of ",e]}),(0,r.jsxs)("div",{className:"flex",children:[(0,r.jsx)("button",{className:"bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-l focus:outline-none",disabled:0===x,onClick:()=>p(x-1),children:"← Prev"}),(0,r.jsx)("button",{className:"bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-r focus:outline-none",onClick:()=>{p(x+1)},children:"Next →"})]})]})}()]})})},e7=e=>{let{teams:l,searchParams:t,accessToken:s,setTeams:a,userID:o,userRole:i}=e,[c]=er.Z.useForm(),[d]=er.Z.useForm(),{Title:m,Paragraph:u}=eR.default,[x,p]=(0,n.useState)(""),[j,g]=(0,n.useState)(!1),[f,Z]=(0,n.useState)(l?l[0]:null),[b,_]=(0,n.useState)(!1),[k,S]=(0,n.useState)(!1),[A,N]=(0,n.useState)([]),[C,I]=(0,n.useState)(!1),[P,T]=(0,n.useState)(null),[E,F]=(0,n.useState)({}),O=e=>{Z(e),g(!0)},M=async e=>{let t=e.team_id;if(console.log("handleEditSubmit:",e),null==s)return;let r=await U(s,e);l&&a(l.map(e=>e.team_id===t?r.data:e)),h.ZP.success("Team updated successfully"),g(!1),Z(null)},L=async e=>{T(e),I(!0)},D=async()=>{if(null!=P&&null!=l&&null!=s){try{await y(s,P);let e=l.filter(e=>e.team_id!==P);a(e)}catch(e){console.error("Error deleting the team:",e)}I(!1),T(null)}};(0,n.useEffect)(()=>{let e=async()=>{try{if(null===o||null===i||null===s||null===l)return;console.log("fetching team info:");let e={};for(let t=0;t<(null==l?void 0:l.length);t++){let a=l[t].team_id,r=await w(s,a);console.log("teamInfo response:",r),null!==r&&(e={...e,[a]:r})}F(e)}catch(e){console.error("Error fetching team info:",e)}};(async()=>{try{if(null===o||null===i)return;if(null!==s){let e=(await v(s,o,i)).data.map(e=>e.id);console.log("available_model_names:",e),N(e)}}catch(e){console.error("Error fetching user models:",e)}})(),e()},[s,o,i,l]);let B=async e=>{try{if(null!=s){h.ZP.info("Creating Team");let t=await R(s,e);null!==l?a([...l,t]):a([t]),console.log("response for team create call: ".concat(t)),h.ZP.success("Team created"),_(!1)}}catch(e){console.error("Error creating the team:",e),h.ZP.error("Error creating the team: "+e,20)}},q=async e=>{try{if(null!=s&&null!=l){h.ZP.info("Adding Member");let t={role:"user",user_email:e.user_email,user_id:e.user_id},r=await z(s,f.team_id,t);console.log("response for team create call: ".concat(r.data));let n=l.findIndex(e=>(console.log("team.team_id=".concat(e.team_id,"; response.data.team_id=").concat(r.data.team_id)),e.team_id===r.data.team_id));if(console.log("foundIndex: ".concat(n)),-1!==n){let e=[...l];e[n]=r.data,a(e),Z(r.data)}S(!1)}}catch(e){console.error("Error creating the team:",e)}};return console.log("received teams ".concat(l)),(0,r.jsx)("div",{className:"w-full mx-4",children:(0,r.jsxs)(Y.Z,{numItems:1,className:"gap-2 p-8 h-[75vh] w-full mt-2",children:[(0,r.jsxs)(J.Z,{numColSpan:1,children:[(0,r.jsx)(m,{level:4,children:"All Teams"}),(0,r.jsxs)(eg.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:[(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(ek.Z,{children:(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(ev.Z,{children:"Team Name"}),(0,r.jsx)(ev.Z,{children:"Spend (USD)"}),(0,r.jsx)(ev.Z,{children:"Budget (USD)"}),(0,r.jsx)(ev.Z,{children:"Models"}),(0,r.jsx)(ev.Z,{children:"TPM / RPM Limits"}),(0,r.jsx)(ev.Z,{children:"Info"})]})}),(0,r.jsx)(eb.Z,{children:l&&l.length>0?l.map(e=>(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(e_.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:e.team_alias}),(0,r.jsx)(e_.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:e.spend}),(0,r.jsx)(e_.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:e.max_budget?e.max_budget:"No limit"}),(0,r.jsx)(e_.Z,{style:{maxWidth:"8-x",whiteSpace:"pre-wrap",overflow:"hidden"},children:Array.isArray(e.models)?(0,r.jsx)("div",{style:{display:"flex",flexDirection:"column"},children:0===e.models.length?(0,r.jsx)(ep.Z,{size:"xs",className:"mb-1",color:"red",children:(0,r.jsx)(el.Z,{children:"All Proxy Models"})}):e.models.map((e,l)=>"all-proxy-models"===e?(0,r.jsx)(ep.Z,{size:"xs",className:"mb-1",color:"red",children:(0,r.jsx)(el.Z,{children:"All Proxy Models"})},l):(0,r.jsx)(ep.Z,{size:"xs",className:"mb-1",color:"blue",children:(0,r.jsx)(el.Z,{children:e.length>30?"".concat(e.slice(0,30),"..."):e})},l))}):null}),(0,r.jsx)(e_.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,r.jsxs)(el.Z,{children:["TPM:"," ",e.tpm_limit?e.tpm_limit:"Unlimited"," ",(0,r.jsx)("br",{}),"RPM:"," ",e.rpm_limit?e.rpm_limit:"Unlimited"]})}),(0,r.jsxs)(e_.Z,{children:[(0,r.jsxs)(el.Z,{children:[E&&e.team_id&&E[e.team_id]&&E[e.team_id].keys&&E[e.team_id].keys.length," Keys"]}),(0,r.jsxs)(el.Z,{children:[E&&e.team_id&&E[e.team_id]&&E[e.team_id].team_info&&E[e.team_id].team_info.members_with_roles&&E[e.team_id].team_info.members_with_roles.length," Members"]})]}),(0,r.jsxs)(e_.Z,{children:[(0,r.jsx)(eZ.Z,{icon:eu.Z,size:"sm",onClick:()=>O(e)}),(0,r.jsx)(eZ.Z,{onClick:()=>L(e.team_id),icon:ex.Z,size:"sm"})]})]},e.team_id)):null})]}),C&&(0,r.jsx)("div",{className:"fixed z-10 inset-0 overflow-y-auto",children:(0,r.jsxs)("div",{className:"flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0",children:[(0,r.jsx)("div",{className:"fixed inset-0 transition-opacity","aria-hidden":"true",children:(0,r.jsx)("div",{className:"absolute inset-0 bg-gray-500 opacity-75"})}),(0,r.jsx)("span",{className:"hidden sm:inline-block sm:align-middle sm:h-screen","aria-hidden":"true",children:"​"}),(0,r.jsxs)("div",{className:"inline-block align-bottom bg-white rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full",children:[(0,r.jsx)("div",{className:"bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4",children:(0,r.jsx)("div",{className:"sm:flex sm:items-start",children:(0,r.jsxs)("div",{className:"mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left",children:[(0,r.jsx)("h3",{className:"text-lg leading-6 font-medium text-gray-900",children:"Delete Team"}),(0,r.jsx)("div",{className:"mt-2",children:(0,r.jsx)("p",{className:"text-sm text-gray-500",children:"Are you sure you want to delete this team ?"})})]})})}),(0,r.jsxs)("div",{className:"bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse",children:[(0,r.jsx)(H.Z,{onClick:D,color:"red",className:"ml-2",children:"Delete"}),(0,r.jsx)(H.Z,{onClick:()=>{I(!1),T(null)},children:"Cancel"})]})]})]})})]})]}),(0,r.jsxs)(J.Z,{numColSpan:1,children:[(0,r.jsx)(H.Z,{className:"mx-auto",onClick:()=>_(!0),children:"+ Create New Team"}),(0,r.jsx)(en.Z,{title:"Create Team",visible:b,width:800,footer:null,onOk:()=>{_(!1),c.resetFields()},onCancel:()=>{_(!1),c.resetFields()},children:(0,r.jsxs)(er.Z,{form:c,onFinish:B,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(er.Z.Item,{label:"Team Name",name:"team_alias",rules:[{required:!0,message:"Please input a team name"}],children:(0,r.jsx)($.Z,{placeholder:""})}),(0,r.jsx)(er.Z.Item,{label:"Models",name:"models",children:(0,r.jsxs)(ea.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:[(0,r.jsx)(ea.default.Option,{value:"all-proxy-models",children:"All Proxy Models"},"all-proxy-models"),A.map(e=>(0,r.jsx)(ea.default.Option,{value:e,children:e},e))]})}),(0,r.jsx)(er.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,r.jsx)(ei.Z,{step:.01,precision:2,width:200})}),(0,r.jsx)(er.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,r.jsx)(ei.Z,{step:1,width:400})}),(0,r.jsx)(er.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,r.jsx)(ei.Z,{step:1,width:400})})]}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ec.ZP,{htmlType:"submit",children:"Create Team"})})]})})]}),(0,r.jsxs)(J.Z,{numColSpan:1,children:[(0,r.jsx)(m,{level:4,children:"Team Members"}),(0,r.jsx)(u,{children:"If you belong to multiple teams, this setting controls which teams members you see."}),l&&l.length>0?(0,r.jsx)(eA.Z,{defaultValue:"0",children:l.map((e,l)=>(0,r.jsx)(eN.Z,{value:String(l),onClick:()=>{Z(e)},children:e.team_alias},l))}):(0,r.jsxs)(u,{children:["No team created. ",(0,r.jsx)("b",{children:"Defaulting to personal account."})]})]}),(0,r.jsxs)(J.Z,{numColSpan:1,children:[(0,r.jsx)(eg.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(ek.Z,{children:(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(ev.Z,{children:"Member Name"}),(0,r.jsx)(ev.Z,{children:"Role"})]})}),(0,r.jsx)(eb.Z,{children:f?f.members_with_roles.map((e,l)=>(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(e_.Z,{children:e.user_email?e.user_email:e.user_id?e.user_id:null}),(0,r.jsx)(e_.Z,{children:e.role})]},l)):null})]})}),f&&(0,r.jsx)(e=>{let{visible:l,onCancel:t,team:s,onSubmit:a}=e,[n]=er.Z.useForm();return(0,r.jsx)(en.Z,{title:"Edit Team",visible:l,width:800,footer:null,onOk:()=>{n.validateFields().then(e=>{a({...e,team_id:s.team_id}),n.resetFields()}).catch(e=>{console.error("Validation failed:",e)})},onCancel:t,children:(0,r.jsxs)(er.Z,{form:n,onFinish:M,initialValues:s,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(er.Z.Item,{label:"Team Name",name:"team_alias",rules:[{required:!0,message:"Please input a team name"}],children:(0,r.jsx)(eo.Z,{})}),(0,r.jsx)(er.Z.Item,{label:"Models",name:"models",children:(0,r.jsxs)(ea.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:[(0,r.jsx)(ea.default.Option,{value:"all-proxy-models",children:"All Proxy Models"},"all-proxy-models"),A&&A.map(e=>(0,r.jsx)(ea.default.Option,{value:e,children:e},e))]})}),(0,r.jsx)(er.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,r.jsx)(ei.Z,{step:.01,precision:2,width:200})}),(0,r.jsx)(er.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,r.jsx)(ei.Z,{step:1,width:400})}),(0,r.jsx)(er.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,r.jsx)(ei.Z,{step:1,width:400})}),(0,r.jsx)(er.Z.Item,{label:"Requests per minute Limit (RPM)",name:"team_id",hidden:!0})]}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ec.ZP,{htmlType:"submit",children:"Edit Team"})})]})})},{visible:j,onCancel:()=>{g(!1),Z(null)},team:f,onSubmit:M})]}),(0,r.jsxs)(J.Z,{numColSpan:1,children:[(0,r.jsx)(H.Z,{className:"mx-auto mb-5",onClick:()=>S(!0),children:"+ Add member"}),(0,r.jsx)(en.Z,{title:"Add member",visible:k,width:800,footer:null,onOk:()=>{S(!1),d.resetFields()},onCancel:()=>{S(!1),d.resetFields()},children:(0,r.jsxs)(er.Z,{form:c,onFinish:q,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(er.Z.Item,{label:"Email",name:"user_email",className:"mb-4",children:(0,r.jsx)(eo.Z,{name:"user_email",className:"px-3 py-2 border rounded-md w-full"})}),(0,r.jsx)("div",{className:"text-center mb-4",children:"OR"}),(0,r.jsx)(er.Z.Item,{label:"User ID",name:"user_id",className:"mb-4",children:(0,r.jsx)(eo.Z,{name:"user_id",className:"px-3 py-2 border rounded-md w-full"})})]}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ec.ZP,{htmlType:"submit",children:"Add member"})})]})})]})]})})},e9=t(18190),le=e=>{let l,{searchParams:t,accessToken:s,showSSOBanner:a}=e,[o]=er.Z.useForm(),[i]=er.Z.useForm(),{Title:c,Paragraph:d}=eR.default,[m,u]=(0,n.useState)(""),[x,p]=(0,n.useState)(null),[j,g]=(0,n.useState)(!1),[f,y]=(0,n.useState)(!1),[Z,w]=(0,n.useState)(!1),[b,_]=(0,n.useState)(!1),[k,v]=(0,n.useState)(!1);try{l=window.location.origin}catch(e){l=""}l+="/fallback/login";let S=()=>{v(!1)},A=["proxy_admin","proxy_admin_viewer"];(0,n.useEffect)(()=>{(async()=>{if(null!=s){let e=[],l=await M(s,"proxy_admin_viewer");l.forEach(l=>{e.push({user_role:l.user_role,user_id:l.user_id,user_email:l.user_email})}),console.log("proxy viewers: ".concat(l));let t=await M(s,"proxy_admin");t.forEach(l=>{e.push({user_role:l.user_role,user_id:l.user_id,user_email:l.user_email})}),console.log("proxy admins: ".concat(t)),console.log("combinedList: ".concat(e)),p(e)}})()},[s]);let N=()=>{w(!1),i.resetFields()},C=()=>{w(!1),i.resetFields()},I=e=>(0,r.jsxs)(er.Z,{form:o,onFinish:e,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(er.Z.Item,{label:"Email",name:"user_email",className:"mb-4",children:(0,r.jsx)(eo.Z,{name:"user_email",className:"px-3 py-2 border rounded-md w-full"})}),(0,r.jsx)("div",{className:"text-center mb-4",children:"OR"}),(0,r.jsx)(er.Z.Item,{label:"User ID",name:"user_id",className:"mb-4",children:(0,r.jsx)(eo.Z,{name:"user_id",className:"px-3 py-2 border rounded-md w-full"})})]}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ec.ZP,{htmlType:"submit",children:"Add member"})})]}),P=(e,l,t)=>(0,r.jsxs)(er.Z,{form:o,onFinish:e,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(er.Z.Item,{rules:[{required:!0,message:"Required"}],label:"User Role",name:"user_role",labelCol:{span:10},labelAlign:"left",children:(0,r.jsx)(eA.Z,{value:l,children:A.map((e,l)=>(0,r.jsx)(eN.Z,{value:e,children:e},l))})}),(0,r.jsx)(er.Z.Item,{label:"Team ID",name:"user_id",hidden:!0,initialValue:t,valuePropName:"user_id",className:"mt-8",children:(0,r.jsx)(eo.Z,{value:t,disabled:!0})})]}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ec.ZP,{htmlType:"submit",children:"Update role"})})]}),T=async e=>{try{if(null!=s&&null!=x){h.ZP.info("Making API Call");let l=await B(s,e,null);console.log("response for team create call: ".concat(l));let t=x.findIndex(e=>(console.log("user.user_id=".concat(e.user_id,"; response.user_id=").concat(l.user_id)),e.user_id===l.user_id));console.log("foundIndex: ".concat(t)),-1==t&&(console.log("updates admin with new user"),x.push(l),p(x)),h.ZP.success("Refresh tab to see updated user role"),w(!1)}}catch(e){console.error("Error creating the key:",e)}},E=async e=>{try{if(null!=s&&null!=x){h.ZP.info("Making API Call");let l=await B(s,e,"proxy_admin_viewer");console.log("response for team create call: ".concat(l));let t=x.findIndex(e=>(console.log("user.user_id=".concat(e.user_id,"; response.user_id=").concat(l.user_id)),e.user_id===l.user_id));console.log("foundIndex: ".concat(t)),-1==t&&(console.log("updates admin with new user"),x.push(l),p(x)),g(!1)}}catch(e){console.error("Error creating the key:",e)}},F=async e=>{try{if(null!=s&&null!=x){h.ZP.info("Making API Call"),e.user_email,e.user_id;let l=await B(s,e,"proxy_admin");console.log("response for team create call: ".concat(l));let t=x.findIndex(e=>(console.log("user.user_id=".concat(e.user_id,"; response.user_id=").concat(l.user_id)),e.user_id===l.user_id));console.log("foundIndex: ".concat(t)),-1==t&&(console.log("updates admin with new user"),x.push(l),p(x)),y(!1)}}catch(e){console.error("Error creating the key:",e)}},O=async e=>{null!=s&&G(s,{environment_variables:{PROXY_BASE_URL:e.proxy_base_url,GOOGLE_CLIENT_ID:e.google_client_id,GOOGLE_CLIENT_SECRET:e.google_client_secret}})};return console.log("admins: ".concat(null==x?void 0:x.length)),(0,r.jsxs)("div",{className:"w-full m-2 mt-2 p-8",children:[(0,r.jsx)(c,{level:4,children:"Admin Access "}),(0,r.jsxs)(d,{children:[a&&(0,r.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/ui#restrict-ui-access",children:"Requires SSO Setup"}),(0,r.jsx)("br",{}),(0,r.jsx)("b",{children:"Proxy Admin: "})," Can create keys, teams, users, add models, etc. ",(0,r.jsx)("br",{}),(0,r.jsx)("b",{children:"Proxy Admin Viewer: "}),"Can just view spend. They cannot create keys, teams or grant users access to new models."," "]}),(0,r.jsxs)(Y.Z,{numItems:1,className:"gap-2 p-2 w-full",children:[(0,r.jsx)(J.Z,{numColSpan:1,children:(0,r.jsx)(eg.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(ek.Z,{children:(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(ev.Z,{children:"Member Name"}),(0,r.jsx)(ev.Z,{children:"Role"})]})}),(0,r.jsx)(eb.Z,{children:x?x.map((e,l)=>(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(e_.Z,{children:e.user_email?e.user_email:e.user_id?e.user_id:null}),(0,r.jsx)(e_.Z,{children:e.user_role}),(0,r.jsxs)(e_.Z,{children:[(0,r.jsx)(eZ.Z,{icon:eu.Z,size:"sm",onClick:()=>w(!0)}),(0,r.jsx)(en.Z,{title:"Update role",visible:Z,width:800,footer:null,onOk:N,onCancel:C,children:P(T,e.user_role,e.user_id)})]})]},l)):null})]})})}),(0,r.jsx)(J.Z,{numColSpan:1,children:(0,r.jsxs)("div",{className:"flex justify-start",children:[(0,r.jsx)(H.Z,{className:"mr-4 mb-5",onClick:()=>y(!0),children:"+ Add admin"}),(0,r.jsx)(en.Z,{title:"Add admin",visible:f,width:800,footer:null,onOk:()=>{y(!1),i.resetFields()},onCancel:()=>{y(!1),i.resetFields()},children:I(F)}),(0,r.jsx)(H.Z,{className:"mb-5",onClick:()=>g(!0),children:"+ Add viewer"}),(0,r.jsx)(en.Z,{title:"Add viewer",visible:j,width:800,footer:null,onOk:()=>{g(!1),i.resetFields()},onCancel:()=>{g(!1),i.resetFields()},children:I(E)})]})})]}),(0,r.jsxs)(Y.Z,{children:[(0,r.jsx)(c,{level:4,children:"Add SSO"}),(0,r.jsxs)("div",{className:"flex justify-start mb-4",children:[(0,r.jsx)(H.Z,{onClick:()=>_(!0),children:"Add SSO"}),(0,r.jsx)(en.Z,{title:"Add SSO",visible:b,width:800,footer:null,onOk:()=>{_(!1),o.resetFields()},onCancel:()=>{_(!1),o.resetFields()},children:(0,r.jsxs)(er.Z,{form:o,onFinish:e=>{F(e),O(e),_(!1),v(!0)},labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(er.Z.Item,{label:"Admin Email",name:"user_email",rules:[{required:!0,message:"Please enter the email of the proxy admin"}],children:(0,r.jsx)(eo.Z,{})}),(0,r.jsx)(er.Z.Item,{label:"PROXY BASE URL",name:"proxy_base_url",rules:[{required:!0,message:"Please enter the proxy base url"}],children:(0,r.jsx)(eo.Z,{})}),(0,r.jsx)(er.Z.Item,{label:"GOOGLE CLIENT ID",name:"google_client_id",rules:[{required:!0,message:"Please enter the google client id"}],children:(0,r.jsx)(eo.Z.Password,{})}),(0,r.jsx)(er.Z.Item,{label:"GOOGLE CLIENT SECRET",name:"google_client_secret",rules:[{required:!0,message:"Please enter the google client secret"}],children:(0,r.jsx)(eo.Z.Password,{})})]}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ec.ZP,{htmlType:"submit",children:"Save"})})]})}),(0,r.jsxs)(en.Z,{title:"SSO Setup Instructions",visible:k,width:800,footer:null,onOk:S,onCancel:()=>{v(!1)},children:[(0,r.jsx)("p",{children:"Follow these steps to complete the SSO setup:"}),(0,r.jsx)(el.Z,{className:"mt-2",children:"1. DO NOT Exit this TAB"}),(0,r.jsx)(el.Z,{className:"mt-2",children:"2. Open a new tab, visit your proxy base url"}),(0,r.jsx)(el.Z,{className:"mt-2",children:"3. Confirm your SSO is configured correctly and you can login on the new Tab"}),(0,r.jsx)(el.Z,{className:"mt-2",children:"4. If Step 3 is successful, you can close this tab"}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ec.ZP,{onClick:S,children:"Done"})})]})]}),(0,r.jsxs)(e9.Z,{title:"Login without SSO",color:"teal",children:["If you need to login without sso, you can access ",(0,r.jsxs)("a",{href:l,target:"_blank",children:[(0,r.jsx)("b",{children:l})," "]})]})]})]})},ll=t(12224),lt=e=>{let{accessToken:l,userRole:t,userID:s}=e,[a,o]=(0,n.useState)([]),[i,c]=(0,n.useState)([]),[d,m]=(0,n.useState)(!1),[u]=er.Z.useForm(),[x,p]=(0,n.useState)(null),[j,g]=(0,n.useState)([]),[f,y]=(0,n.useState)(""),[Z,w]=(0,n.useState)({}),[b,_]=(0,n.useState)([]),k=e=>{b.includes(e)?_(b.filter(l=>l!==e)):_([...b,e])},v={llm_exceptions:"LLM Exceptions",llm_too_slow:"LLM Responses Too Slow",llm_requests_hanging:"LLM Requests Hanging",budget_alerts:"Budget Alerts (API Keys, Users)"};(0,n.useEffect)(()=>{l&&t&&s&&V(l,s,t).then(e=>{console.log("callbacks",e),o(e.callbacks);let l=e.alerts;if(console.log("alerts_data",l),l&&l.length>0){let e=l[0];console.log("_alert_info",e);let t=e.variables.SLACK_WEBHOOK_URL;console.log("catch_all_webhook",t),_(e.active_alerts),y(t),w(e.alerts_to_webhook)}c(l)})},[l,t,s]);let S=e=>b&&b.includes(e),A=e=>{if(!l)return;let t=Object.fromEntries(Object.entries(e.variables).map(e=>{var l;let[t,s]=e;return[t,(null===(l=document.querySelector('input[name="'.concat(t,'"]')))||void 0===l?void 0:l.value)||s]}));console.log("updatedVariables",t),console.log("updateAlertTypes",j);try{G(l,{environment_variables:t})}catch(e){h.ZP.error("Failed to update callback: "+e,20)}h.ZP.success("Callback updated successfully")},N=()=>{l&&u.validateFields().then(e=>{if(console.log("Form values:",e),"langfuse"===e.callback){G(l,{environment_variables:{LANGFUSE_PUBLIC_KEY:e.langfusePublicKey,LANGFUSE_SECRET_KEY:e.langfusePrivateKey},litellm_settings:{success_callback:[e.callback]}});let t={name:e.callback,variables:{SLACK_WEBHOOK_URL:null,LANGFUSE_HOST:null,LANGFUSE_PUBLIC_KEY:e.langfusePublicKey,LANGFUSE_SECRET_KEY:e.langfusePrivateKey}};o(a?[...a,t]:[t])}else if("slack"===e.callback){console.log("values.slackWebhookUrl: ".concat(e.slackWebhookUrl)),G(l,{general_settings:{alerting:["slack"],alerting_threshold:300},environment_variables:{SLACK_WEBHOOK_URL:e.slackWebhookUrl}}),console.log("values.callback: ".concat(e.callback));let t={name:e.callback,variables:{SLACK_WEBHOOK_URL:e.slackWebhookUrl,LANGFUSE_HOST:null,LANGFUSE_PUBLIC_KEY:null,LANGFUSE_SECRET_KEY:null}};o(a?[...a,t]:[t])}m(!1),u.resetFields(),p(null)})};return l?(console.log("callbacks: ".concat(a)),(0,r.jsxs)("div",{className:"w-full mx-4",children:[(0,r.jsx)(Y.Z,{numItems:1,className:"gap-2 p-8 w-full mt-2",children:(0,r.jsxs)(eD.Z,{children:[(0,r.jsxs)(ez.Z,{variant:"line",defaultValue:"1",children:[(0,r.jsx)(eU.Z,{value:"1",children:"Logging Callbacks"}),(0,r.jsx)(eU.Z,{value:"2",children:"Alerting"})]}),(0,r.jsxs)(eq.Z,{children:[(0,r.jsx)(eB.Z,{children:(0,r.jsxs)(eg.Z,{children:[(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(ek.Z,{children:(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(ev.Z,{children:"Callback"}),(0,r.jsx)(ev.Z,{children:"Callback Env Vars"})]})}),(0,r.jsx)(eb.Z,{children:a.map((e,t)=>{var s;return(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(e_.Z,{children:(0,r.jsx)(ep.Z,{color:"emerald",children:e.name})}),(0,r.jsxs)(e_.Z,{children:[(0,r.jsx)("ul",{children:Object.entries(null!==(s=e.variables)&&void 0!==s?s:{}).filter(e=>{let[l,t]=e;return null!==t}).map(e=>{let[l,t]=e;return(0,r.jsxs)("li",{children:[(0,r.jsx)(el.Z,{className:"mt-2",children:l}),"LANGFUSE_HOST"===l?(0,r.jsx)("p",{children:"default value=https://cloud.langfuse.com"}):(0,r.jsx)("div",{}),(0,r.jsx)($.Z,{name:l,defaultValue:t,type:"password"})]},l)})}),(0,r.jsx)(H.Z,{className:"mt-2",onClick:()=>A(e),children:"Save Changes"}),(0,r.jsx)(H.Z,{onClick:()=>K(l,e.name),className:"mx-2",children:"Test Callback"})]})]},t)})})]}),(0,r.jsx)(H.Z,{size:"xs",className:"mt-2",onClick:()=>{console.log("Add callback clicked"),m(!0)},children:"Add Callback"})]})}),(0,r.jsx)(eB.Z,{children:(0,r.jsxs)(eg.Z,{children:[(0,r.jsxs)(el.Z,{className:"my-2",children:["Alerts are only supported for Slack Webhook URLs. Get your webhook urls from ",(0,r.jsx)("a",{href:"https://api.slack.com/messaging/webhooks",target:"_blank",style:{color:"blue"},children:"here"})]}),(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(ek.Z,{children:(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(ev.Z,{}),(0,r.jsx)(ev.Z,{}),(0,r.jsx)(ev.Z,{children:"Slack Webhook URL"})]})}),(0,r.jsx)(eb.Z,{children:Object.entries(v).map((e,l)=>{let[t,s]=e;return(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(e_.Z,{children:(0,r.jsx)(ll.Z,{id:"switch",name:"switch",checked:S(t),onChange:()=>k(t)})}),(0,r.jsx)(e_.Z,{children:(0,r.jsx)(el.Z,{children:s})}),(0,r.jsx)(e_.Z,{children:(0,r.jsx)($.Z,{name:t,type:"password",defaultValue:Z&&Z[t]?Z[t]:f})})]},l)})})]}),(0,r.jsx)(H.Z,{size:"xs",className:"mt-2",onClick:()=>{if(!l)return;let e={};Object.entries(v).forEach(l=>{let[t,s]=l,a=document.querySelector('input[name="'.concat(t,'"]'));console.log("key",t),console.log("webhookInput",a);let r=(null==a?void 0:a.value)||"";console.log("newWebhookValue",r),e[t]=r}),console.log("updatedAlertToWebhooks",e);let t={general_settings:{alert_to_webhook_url:e,alert_types:b}};console.log("payload",t);try{G(l,t)}catch(e){h.ZP.error("Failed to update alerts: "+e,20)}h.ZP.success("Alerts updated successfully")},children:"Save Changes"}),(0,r.jsx)(H.Z,{onClick:()=>K(l,"slack"),className:"mx-2",children:"Test Alerts"})]})})]})]})}),(0,r.jsx)(en.Z,{title:"Add Callback",visible:d,onOk:N,width:800,onCancel:()=>{m(!1),u.resetFields(),p(null)},footer:null,children:(0,r.jsxs)(er.Z,{form:u,layout:"vertical",onFinish:N,children:[(0,r.jsx)(er.Z.Item,{label:"Callback",name:"callback",rules:[{required:!0,message:"Please select a callback"}],children:(0,r.jsx)(ea.default,{onChange:e=>{p(e)},children:(0,r.jsx)(ea.default.Option,{value:"langfuse",children:"langfuse"})})}),"langfuse"===x&&(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(er.Z.Item,{label:"LANGFUSE_PUBLIC_KEY",name:"langfusePublicKey",rules:[{required:!0,message:"Please enter the public key"}],children:(0,r.jsx)($.Z,{type:"password"})}),(0,r.jsx)(er.Z.Item,{label:"LANGFUSE_PRIVATE_KEY",name:"langfusePrivateKey",rules:[{required:!0,message:"Please enter the private key"}],children:(0,r.jsx)($.Z,{type:"password"})})]}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ec.ZP,{htmlType:"submit",children:"Save"})})]})})]})):null};let{Option:ls}=ea.default;var la=e=>{let{models:l,accessToken:t,routerSettings:s,setRouterSettings:a}=e,[o]=er.Z.useForm(),[i,c]=(0,n.useState)(!1),[d,m]=(0,n.useState)("");return(0,r.jsxs)("div",{children:[(0,r.jsx)(H.Z,{className:"mx-auto",onClick:()=>c(!0),children:"+ Add Fallbacks"}),(0,r.jsx)(en.Z,{title:"Add Fallbacks",visible:i,width:800,footer:null,onOk:()=>{c(!1),o.resetFields()},onCancel:()=>{c(!1),o.resetFields()},children:(0,r.jsxs)(er.Z,{form:o,onFinish:e=>{console.log(e);let{model_name:l,models:r}=e,n=[...s.fallbacks||[],{[l]:r}],i={...s,fallbacks:n};console.log(i);try{G(t,{router_settings:i}),a(i)}catch(e){h.ZP.error("Failed to update router settings: "+e,20)}h.ZP.success("router settings updated successfully"),c(!1),o.resetFields()},labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(er.Z.Item,{label:"Public Model Name",name:"model_name",rules:[{required:!0,message:"Set the model to fallback for"}],help:"required",children:(0,r.jsx)(eA.Z,{defaultValue:d,children:l&&l.map((e,l)=>(0,r.jsx)(eN.Z,{value:e,onClick:()=>m(e),children:e},l))})}),(0,r.jsx)(er.Z.Item,{label:"Fallback Models",name:"models",rules:[{required:!0,message:"Please select a model"}],help:"required",children:(0,r.jsx)(eK.Z,{value:l,children:l&&l.filter(e=>e!=d).map(e=>(0,r.jsx)(eV.Z,{value:e,children:e},e))})})]}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ec.ZP,{htmlType:"submit",children:"Add Fallbacks"})})]})})]})},lr=t(12968);async function ln(e,l){console.log("isLocal:",!1);let t=window.location.origin,s=new lr.ZP.OpenAI({apiKey:l,baseURL:t,dangerouslyAllowBrowser:!0});try{let l=await s.chat.completions.create({model:e,messages:[{role:"user",content:"Hi, this is a test message"}],mock_testing_fallbacks:!0});h.ZP.success((0,r.jsxs)("span",{children:["Test model=",(0,r.jsx)("strong",{children:e}),", received model=",(0,r.jsx)("strong",{children:l.model}),". See ",(0,r.jsx)("a",{href:"#",onClick:()=>window.open("https://docs.litellm.ai/docs/proxy/reliability","_blank"),style:{textDecoration:"underline",color:"blue"},children:"curl"})]}))}catch(e){h.ZP.error("Error occurred while generating model response. Please try again. Error: ".concat(e),20)}}var lo=e=>{let{accessToken:l,userRole:t,userID:s,modelData:a}=e,[o,i]=(0,n.useState)({}),[c,d]=(0,n.useState)(!1),[m]=er.Z.useForm(),[u,x]=(0,n.useState)(null),p={routing_strategy_args:"(dict) Arguments to pass to the routing strategy",routing_strategy:"(string) Routing strategy to use",allowed_fails:"(int) Number of times a deployment can fail before being added to cooldown",cooldown_time:"(int) time in seconds to cooldown a deployment after failure",num_retries:"(int) Number of retries for failed requests. Defaults to 0.",timeout:"(float) Timeout for requests. Defaults to None.",retry_after:"(int) Minimum time to wait before retrying a failed request"};(0,n.useEffect)(()=>{l&&t&&s&&V(l,s,t).then(e=>{console.log("callbacks",e),i(e.router_settings)})},[l,t,s]);let j=async e=>{if(l){console.log("received key: ".concat(e)),console.log("routerSettings['fallbacks']: ".concat(o.fallbacks)),o.fallbacks.map(l=>(e in l&&delete l[e],l));try{await G(l,{router_settings:o}),i({...o}),h.ZP.success("Router settings updated successfully")}catch(e){h.ZP.error("Failed to update router settings: "+e,20)}}},g=e=>{if(!l)return;console.log("router_settings",e);let t=Object.fromEntries(Object.entries(e).map(e=>{let[l,t]=e;if("routing_strategy_args"!==l){var s;return[l,(null===(s=document.querySelector('input[name="'.concat(l,'"]')))||void 0===s?void 0:s.value)||t]}return null}).filter(e=>null!==e));console.log("updatedVariables",t);try{G(l,{router_settings:t})}catch(e){h.ZP.error("Failed to update router settings: "+e,20)}h.ZP.success("router settings updated successfully")};return l?(0,r.jsx)("div",{className:"w-full mx-4",children:(0,r.jsxs)(eD.Z,{className:"gap-2 p-8 h-[75vh] w-full mt-2",children:[(0,r.jsxs)(ez.Z,{variant:"line",defaultValue:"1",children:[(0,r.jsx)(eU.Z,{value:"1",children:"General Settings"}),(0,r.jsx)(eU.Z,{value:"2",children:"Fallbacks"})]}),(0,r.jsxs)(eq.Z,{children:[(0,r.jsx)(eB.Z,{children:(0,r.jsxs)(Y.Z,{numItems:1,className:"gap-2 p-8 w-full mt-2",children:[(0,r.jsx)(et.Z,{children:"Router Settings"}),(0,r.jsx)(eg.Z,{children:(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(ek.Z,{children:(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(ev.Z,{children:"Setting"}),(0,r.jsx)(ev.Z,{children:"Value"})]})}),(0,r.jsx)(eb.Z,{children:Object.entries(o).filter(e=>{let[l,t]=e;return"fallbacks"!=l&&"context_window_fallbacks"!=l}).map(e=>{let[l,t]=e;return(0,r.jsxs)(eS.Z,{children:[(0,r.jsxs)(e_.Z,{children:[(0,r.jsx)(el.Z,{children:l}),(0,r.jsx)("p",{style:{fontSize:"0.65rem",color:"#808080",fontStyle:"italic"},className:"mt-1",children:p[l]})]}),(0,r.jsx)(e_.Z,{children:(0,r.jsx)($.Z,{name:l,defaultValue:"object"==typeof t?JSON.stringify(t,null,2):t.toString()})})]},l)})})]})}),(0,r.jsx)(J.Z,{children:(0,r.jsx)(H.Z,{className:"mt-2",onClick:()=>g(o),children:"Save Changes"})})]})}),(0,r.jsxs)(eB.Z,{children:[(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(ek.Z,{children:(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(ev.Z,{children:"Model Name"}),(0,r.jsx)(ev.Z,{children:"Fallbacks"})]})}),(0,r.jsx)(eb.Z,{children:o.fallbacks&&o.fallbacks.map((e,t)=>Object.entries(e).map(e=>{let[s,a]=e;return(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(e_.Z,{children:s}),(0,r.jsx)(e_.Z,{children:Array.isArray(a)?a.join(", "):a}),(0,r.jsx)(e_.Z,{children:(0,r.jsx)(H.Z,{onClick:()=>ln(s,l),children:"Test Fallback"})}),(0,r.jsx)(e_.Z,{children:(0,r.jsx)(eZ.Z,{icon:ex.Z,size:"sm",onClick:()=>j(s)})})]},t.toString()+s)}))})]}),(0,r.jsx)(la,{models:(null==a?void 0:a.data)?a.data.map(e=>e.model_name):[],accessToken:l,routerSettings:o,setRouterSettings:i})]})]})]})}):null},li=t(67951),lc=e=>{let{}=e;return(0,r.jsx)(r.Fragment,{children:(0,r.jsx)(Y.Z,{className:"gap-2 p-8 h-[80vh] w-full mt-2",children:(0,r.jsxs)("div",{className:"mb-5",children:[(0,r.jsx)("p",{className:"text-2xl text-tremor-content-strong dark:text-dark-tremor-content-strong font-semibold",children:"OpenAI Compatible Proxy: API Reference"}),(0,r.jsx)(el.Z,{className:"mt-2 mb-2",children:"LiteLLM is OpenAI Compatible. This means your API Key works with the OpenAI SDK. Just replace the base_url to point to your litellm proxy. Example Below "}),(0,r.jsxs)(eD.Z,{children:[(0,r.jsxs)(ez.Z,{children:[(0,r.jsx)(eU.Z,{children:"OpenAI Python SDK"}),(0,r.jsx)(eU.Z,{children:"LlamaIndex"}),(0,r.jsx)(eU.Z,{children:"Langchain Py"})]}),(0,r.jsxs)(eq.Z,{children:[(0,r.jsx)(eB.Z,{children:(0,r.jsx)(li.Z,{language:"python",children:'\nimport openai\nclient = openai.OpenAI(\n api_key="your_api_key",\n base_url="http://0.0.0.0:4000" # LiteLLM Proxy is OpenAI compatible, Read More: https://docs.litellm.ai/docs/proxy/user_keys\n)\n\nresponse = client.chat.completions.create(\n model="gpt-3.5-turbo", # model to send to the proxy\n messages = [\n {\n "role": "user",\n "content": "this is a test request, write a short poem"\n }\n ]\n)\n\nprint(response)\n '})}),(0,r.jsx)(eB.Z,{children:(0,r.jsx)(li.Z,{language:"python",children:'\nimport os, dotenv\n\nfrom llama_index.llms import AzureOpenAI\nfrom llama_index.embeddings import AzureOpenAIEmbedding\nfrom llama_index import VectorStoreIndex, SimpleDirectoryReader, ServiceContext\n\nllm = AzureOpenAI(\n engine="azure-gpt-3.5", # model_name on litellm proxy\n temperature=0.0,\n azure_endpoint="http://0.0.0.0:4000", # litellm proxy endpoint\n api_key="sk-1234", # litellm proxy API Key\n api_version="2023-07-01-preview",\n)\n\nembed_model = AzureOpenAIEmbedding(\n deployment_name="azure-embedding-model",\n azure_endpoint="http://0.0.0.0:4000",\n api_key="sk-1234",\n api_version="2023-07-01-preview",\n)\n\n\ndocuments = SimpleDirectoryReader("llama_index_data").load_data()\nservice_context = ServiceContext.from_defaults(llm=llm, embed_model=embed_model)\nindex = VectorStoreIndex.from_documents(documents, service_context=service_context)\n\nquery_engine = index.as_query_engine()\nresponse = query_engine.query("What did the author do growing up?")\nprint(response)\n\n '})}),(0,r.jsx)(eB.Z,{children:(0,r.jsx)(li.Z,{language:"python",children:'\nfrom langchain.chat_models import ChatOpenAI\nfrom langchain.prompts.chat import (\n ChatPromptTemplate,\n HumanMessagePromptTemplate,\n SystemMessagePromptTemplate,\n)\nfrom langchain.schema import HumanMessage, SystemMessage\n\nchat = ChatOpenAI(\n openai_api_base="http://0.0.0.0:4000",\n model = "gpt-3.5-turbo",\n temperature=0.1\n)\n\nmessages = [\n SystemMessage(\n content="You are a helpful assistant that im using to make a test request to."\n ),\n HumanMessage(\n content="test from litellm. tell me why it\'s amazing in 1 sentence"\n ),\n]\nresponse = chat(messages)\n\nprint(response)\n\n '})})]})]})]})})})};async function ld(e,l,t,s){console.log("isLocal:",!1);let a=window.location.origin,r=new lr.ZP.OpenAI({apiKey:s,baseURL:a,dangerouslyAllowBrowser:!0});try{for await(let s of(await r.chat.completions.create({model:t,stream:!0,messages:[{role:"user",content:e}]})))console.log(s),s.choices[0].delta.content&&l(s.choices[0].delta.content)}catch(e){h.ZP.error("Error occurred while generating model response. Please try again. Error: ".concat(e),20)}}var lm=e=>{let{accessToken:l,token:t,userRole:s,userID:a}=e,[o,i]=(0,n.useState)(""),[c,d]=(0,n.useState)(""),[m,h]=(0,n.useState)([]),[u,x]=(0,n.useState)(void 0),[p,j]=(0,n.useState)([]);(0,n.useEffect)(()=>{l&&t&&s&&a&&(async()=>{try{let e=await v(l,a,s);if(console.log("model_info:",e),(null==e?void 0:e.data.length)>0){let l=e.data.map(e=>({value:e.id,label:e.id}));console.log(l),j(l),x(e.data[0].id)}}catch(e){console.error("Error fetching model info:",e)}})()},[l,a,s]);let g=(e,l)=>{h(t=>{let s=t[t.length-1];return s&&s.role===e?[...t.slice(0,t.length-1),{role:e,content:s.content+l}]:[...t,{role:e,content:l}]})},f=async()=>{if(""!==c.trim()&&o&&t&&s&&a){h(e=>[...e,{role:"user",content:c}]);try{u&&await ld(c,e=>g("assistant",e),u,o)}catch(e){console.error("Error fetching model response",e),g("assistant","Error fetching model response")}d("")}};if(s&&"Admin Viewer"==s){let{Title:e,Paragraph:l}=eR.default;return(0,r.jsxs)("div",{children:[(0,r.jsx)(e,{level:1,children:"Access Denied"}),(0,r.jsx)(l,{children:"Ask your proxy admin for access to test models"})]})}return(0,r.jsx)("div",{style:{width:"100%",position:"relative"},children:(0,r.jsx)(Y.Z,{className:"gap-2 p-8 h-[80vh] w-full mt-2",children:(0,r.jsx)(eg.Z,{children:(0,r.jsxs)(eD.Z,{children:[(0,r.jsx)(ez.Z,{children:(0,r.jsx)(eU.Z,{children:"Chat"})}),(0,r.jsx)(eq.Z,{children:(0,r.jsxs)(eB.Z,{children:[(0,r.jsx)("div",{className:"sm:max-w-2xl",children:(0,r.jsxs)(Y.Z,{numItems:2,children:[(0,r.jsxs)(J.Z,{children:[(0,r.jsx)(el.Z,{children:"API Key"}),(0,r.jsx)($.Z,{placeholder:"Type API Key here",type:"password",onValueChange:i,value:o})]}),(0,r.jsxs)(J.Z,{className:"mx-2",children:[(0,r.jsx)(el.Z,{children:"Select Model:"}),(0,r.jsx)(ea.default,{placeholder:"Select a Model",onChange:e=>{console.log("selected ".concat(e)),x(e)},options:p,style:{width:"200px"}})]})]})}),(0,r.jsxs)(ew.Z,{className:"mt-5",style:{display:"block",maxHeight:"60vh",overflowY:"auto"},children:[(0,r.jsx)(ek.Z,{children:(0,r.jsx)(eS.Z,{children:(0,r.jsx)(e_.Z,{})})}),(0,r.jsx)(eb.Z,{children:m.map((e,l)=>(0,r.jsx)(eS.Z,{children:(0,r.jsx)(e_.Z,{children:"".concat(e.role,": ").concat(e.content)})},l))})]}),(0,r.jsx)("div",{className:"mt-3",style:{position:"absolute",bottom:5,width:"95%"},children:(0,r.jsxs)("div",{className:"flex",children:[(0,r.jsx)($.Z,{type:"text",value:c,onChange:e=>d(e.target.value),placeholder:"Type your message..."}),(0,r.jsx)(H.Z,{onClick:f,className:"ml-2",children:"Send"})]})})]})})]})})})})},lh=t(33509),lu=t(95781);let{Sider:lx}=lh.default;var lp=e=>{let{setPage:l,userRole:t,defaultSelectedKey:s}=e;return"Admin Viewer"==t?(0,r.jsx)(lh.default,{style:{minHeight:"100vh",maxWidth:"120px"},children:(0,r.jsx)(lx,{width:120,children:(0,r.jsxs)(lu.Z,{mode:"inline",defaultSelectedKeys:s||["4"],style:{height:"100%",borderRight:0},children:[(0,r.jsx)(lu.Z.Item,{onClick:()=>l("api-keys"),children:"API Keys"},"4"),(0,r.jsx)(lu.Z.Item,{onClick:()=>l("models"),children:"Models"},"2"),(0,r.jsx)(lu.Z.Item,{onClick:()=>l("llm-playground"),children:"Chat UI"},"3"),(0,r.jsx)(lu.Z.Item,{onClick:()=>l("usage"),children:"Usage"},"1")]})})}):(0,r.jsx)(lh.default,{style:{minHeight:"100vh",maxWidth:"145px"},children:(0,r.jsx)(lx,{width:145,children:(0,r.jsxs)(lu.Z,{mode:"inline",defaultSelectedKeys:s||["1"],style:{height:"100%",borderRight:0},children:[(0,r.jsx)(lu.Z.Item,{onClick:()=>l("api-keys"),children:(0,r.jsx)(el.Z,{children:"API Keys"})},"1"),(0,r.jsx)(lu.Z.Item,{onClick:()=>l("llm-playground"),children:(0,r.jsx)(el.Z,{children:"Test Key"})},"3"),"Admin"==t?(0,r.jsx)(lu.Z.Item,{onClick:()=>l("models"),children:(0,r.jsx)(el.Z,{children:"Models"})},"2"):null,"Admin"==t?(0,r.jsx)(lu.Z.Item,{onClick:()=>l("usage"),children:(0,r.jsx)(el.Z,{children:"Usage"})},"4"):null,"Admin"==t?(0,r.jsx)(lu.Z.Item,{onClick:()=>l("teams"),children:(0,r.jsx)(el.Z,{children:"Teams"})},"6"):null,"Admin"==t?(0,r.jsx)(lu.Z.Item,{onClick:()=>l("users"),children:(0,r.jsx)(el.Z,{children:"Users"})},"5"):null,"Admin"==t?(0,r.jsx)(lu.Z.Item,{onClick:()=>l("settings"),children:(0,r.jsx)(el.Z,{children:"Logging & Alerts"})},"8"):null,"Admin"==t?(0,r.jsx)(lu.Z.Item,{onClick:()=>l("general-settings"),children:(0,r.jsx)(el.Z,{children:"Router Settings"})},"9"):null,"Admin"==t?(0,r.jsx)(lu.Z.Item,{onClick:()=>l("admin-panel"),children:(0,r.jsx)(el.Z,{children:"Admin"})},"7"):null,(0,r.jsx)(lu.Z.Item,{onClick:()=>l("api_ref"),children:(0,r.jsx)(el.Z,{children:"API Reference"})},"11")]})})})},lj=t(67989),lg=e=>{let{accessToken:l,token:t,userRole:s,userID:a}=e,o=new Date,[i,c]=(0,n.useState)([]),[d,m]=(0,n.useState)([]),[h,u]=(0,n.useState)([]),[x,p]=(0,n.useState)([]),[j,g]=(0,n.useState)([]),[f,y]=(0,n.useState)([]),[Z,w]=(0,n.useState)([]),[b,v]=(0,n.useState)([]),[S,T]=(0,n.useState)([]),[O,M]=(0,n.useState)([]),[R,L]=(0,n.useState)([]),[U,D]=(0,n.useState)(null),z=new Date(o.getFullYear(),o.getMonth(),1),B=new Date(o.getFullYear(),o.getMonth()+1,0),q=V(z),K=V(B);function V(e){let l=e.getFullYear(),t=e.getMonth()+1,s=e.getDate();return"".concat(l,"-").concat(t<10?"0"+t:t,"-").concat(s<10?"0"+s:s)}console.log("Start date is ".concat(q)),console.log("End date is ".concat(K)),(0,n.useEffect)(()=>{l&&t&&s&&a&&(async()=>{try{if(console.log("user role: ".concat(s)),"Admin"==s||"Admin Viewer"==s){let e=await I(l);c(e);let t=(await P(l)).map(e=>({key:(e.key_name||e.key_alias||e.api_key).substring(0,10),spend:e.total_spend}));m(t);let r=(await E(l)).map(e=>({key:e.model,spend:e.total_spend}));u(r);let n=await A(l);console.log("teamSpend",n),g(n.daily_spend),w(n.teams);let o=n.total_spend_per_team;o=o.map(e=>(e.name=e.team_id||"",e.value=e.total_spend||0,e)),v(o);let i=await N(l);y(i.top_10_tags);let d=(await _(l,a,s)).data;console.log("model groups in model dashboard",d);let h=[];for(let e=0;e{if(console.log("result from spend logs call",e),"daily_spend"in e){let l=e.daily_spend;console.log("daily spend",l),c(l);let t=e.top_api_keys;m(t)}else{let t=(await F(l,function(e){let l=[];e.forEach(e=>{Object.entries(e).forEach(e=>{let[t,s]=e;"spend"!==t&&"startTime"!==t&&"models"!==t&&"users"!==t&&l.push({key:t,spend:s})})}),l.sort((e,l)=>Number(l.spend)-Number(e.spend));let t=l.slice(0,5).map(e=>e.key);return console.log("topKeys: ".concat(Object.keys(t[0]))),t}(e))).info.map(e=>({key:(e.key_name||e.key_alias).substring(0,10),spend:e.spend}));m(t),p(function(e){let l={};e.forEach(e=>{Object.entries(e.users).forEach(e=>{let[t,s]=e;""!==t&&null!=t&&"None"!=t&&(l[t]||(l[t]=0),l[t]+=s)})});let t=Object.entries(l).map(e=>{let[l,t]=e;return{user_id:l,spend:t}});t.sort((e,l)=>l.spend-e.spend);let s=t.slice(0,5);return console.log("topKeys: ".concat(Object.values(s[0]))),s}(e)),c(e)}});let e=await k(l,a,s,null);console.log("Model metrics response:",e);let r=[...e].sort((e,l)=>l.avg_latency_seconds-e.avg_latency_seconds);console.log("Sorted by latency:",r),T(e),M(r)}catch(e){console.error("There was an error fetching the data",e)}})()},[l,t,s,a,q,K]);let G=async e=>{if(console.log("Updating model metrics for group:",e),l&&a&&s){D(e);try{let t=await k(l,a,s,e);console.log("Model metrics response:",t);let r=[...t].sort((e,l)=>l.avg_latency_seconds-e.avg_latency_seconds);console.log("Sorted by latency:",r),T(t),M(r)}catch(e){console.error("Failed to fetch model metrics",e)}}};return(0,r.jsxs)("div",{style:{width:"100%"},className:"p-8",children:[(0,r.jsx)(eE,{userID:a,userRole:s,accessToken:l,userSpend:null,selectedTeam:null}),(0,r.jsxs)(eD.Z,{children:[(0,r.jsxs)(ez.Z,{className:"mt-2",children:[(0,r.jsx)(eU.Z,{children:"All Up"}),(0,r.jsx)(eU.Z,{children:"Team Based Usage"}),(0,r.jsx)(eU.Z,{children:"Tag Based Usage"}),(0,r.jsx)(eU.Z,{children:"Model Based Usage"})]}),(0,r.jsxs)(eq.Z,{children:[(0,r.jsx)(eB.Z,{children:(0,r.jsxs)(Y.Z,{numItems:2,className:"gap-2 h-[75vh] w-full",children:[(0,r.jsx)(J.Z,{numColSpan:2,children:(0,r.jsxs)(eg.Z,{children:[(0,r.jsx)(et.Z,{children:"Monthly Spend"}),(0,r.jsx)(ej.Z,{data:i,index:"date",categories:["spend"],colors:["blue"],valueFormatter:e=>"$ ".concat(new Intl.NumberFormat("us").format(e).toString()),yAxisWidth:100,tickGap:5})]})}),(0,r.jsx)(J.Z,{numColSpan:1,children:(0,r.jsxs)(eg.Z,{children:[(0,r.jsx)(et.Z,{children:"Top API Keys"}),(0,r.jsx)(ej.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,r.jsx)(J.Z,{numColSpan:1,children:(0,r.jsxs)(eg.Z,{children:[(0,r.jsx)(et.Z,{children:"Top Users"}),(0,r.jsx)(ej.Z,{className:"mt-4 h-40",data:x,index:"user_id",categories:["spend"],colors:["blue"],yAxisWidth:200,layout:"vertical",showXAxis:!1,showLegend:!1})]})}),(0,r.jsx)(J.Z,{numColSpan:1,children:(0,r.jsxs)(eg.Z,{children:[(0,r.jsx)(et.Z,{children:"Top Models"}),(0,r.jsx)(ej.Z,{className:"mt-4 h-40",data:h,index:"key",categories:["spend"],colors:["blue"],yAxisWidth:200,layout:"vertical",showXAxis:!1,showLegend:!1})]})})]})}),(0,r.jsx)(eB.Z,{children:(0,r.jsxs)(Y.Z,{numItems:2,className:"gap-2 h-[75vh] w-full",children:[(0,r.jsxs)(J.Z,{numColSpan:2,children:[(0,r.jsxs)(eg.Z,{className:"mb-2",children:[(0,r.jsx)(et.Z,{children:"Total Spend Per Team"}),(0,r.jsx)(lj.Z,{data:b})]}),(0,r.jsxs)(eg.Z,{children:[(0,r.jsx)(et.Z,{children:"Daily Spend Per Team"}),(0,r.jsx)(ej.Z,{className:"h-72",data:j,showLegend:!0,index:"date",categories:Z,yAxisWidth:80,colors:["blue","green","yellow","red","purple"],stack:!0})]})]}),(0,r.jsx)(J.Z,{numColSpan:2})]})}),(0,r.jsx)(eB.Z,{children:(0,r.jsxs)(Y.Z,{numItems:2,className:"gap-2 h-[75vh] w-full mb-4",children:[(0,r.jsx)(J.Z,{numColSpan:2,children:(0,r.jsxs)(eg.Z,{children:[(0,r.jsx)(et.Z,{children:"Spend Per Tag - Last 30 Days"}),(0,r.jsxs)(el.Z,{children:["Get Started Tracking cost per tag ",(0,r.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/enterprise#tracking-spend-for-custom-tags",target:"_blank",children:"here"})]}),(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(ek.Z,{children:(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(ev.Z,{children:"Tag"}),(0,r.jsx)(ev.Z,{children:"Spend"}),(0,r.jsx)(ev.Z,{children:"Requests"})]})}),(0,r.jsx)(eb.Z,{children:f.map(e=>(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(e_.Z,{children:e.name}),(0,r.jsx)(e_.Z,{children:e.value}),(0,r.jsx)(e_.Z,{children:e.log_count})]},e.name))})]})]})}),(0,r.jsx)(J.Z,{numColSpan:2})]})}),(0,r.jsxs)(eB.Z,{children:[(0,r.jsx)(et.Z,{children:"Filter By Model Group"}),(0,r.jsx)("p",{style:{fontSize:"0.85rem",color:"#808080"},children:"View how requests were load balanced within a model group"}),(0,r.jsx)("p",{style:{fontSize:"0.85rem",color:"#808080",fontStyle:"italic"},children:"(Beta feature) only supported for Azure Model Groups"}),(0,r.jsxs)(eA.Z,{className:"mb-4 mt-2",defaultValue:"all",children:[(0,r.jsx)(eN.Z,{value:"all",onClick:()=>G(null),children:"All Model Groups"}),R.map((e,l)=>(0,r.jsx)(eN.Z,{value:e,onClick:()=>G(e),children:e},l))]}),(0,r.jsxs)(eg.Z,{children:[(0,r.jsx)(et.Z,{children:"Number Requests per Model"}),(0,r.jsx)(ej.Z,{data:S,className:"h-[50vh]",index:"model",categories:["num_requests"],colors:["blue"],yAxisWidth:400,layout:"vertical",tickGap:5})]}),(0,r.jsxs)(eg.Z,{className:"mt-4",children:[(0,r.jsx)(et.Z,{children:"Latency Per Model"}),(0,r.jsx)(ej.Z,{data:O,className:"h-[50vh]",index:"model",categories:["avg_latency_seconds"],colors:["red"],yAxisWidth:400,layout:"vertical",tickGap:5})]})]})]})]})]})},lf=()=>{let{Title:e,Paragraph:l}=eR.default,[t,s]=(0,n.useState)(""),[a,i]=(0,n.useState)(null),[c,d]=(0,n.useState)(null),[h,u]=(0,n.useState)(null),[x,p]=(0,n.useState)(!0),j=(0,o.useSearchParams)(),[g,f]=(0,n.useState)({data:[]}),y=j.get("userID"),Z=j.get("token"),[w,b]=(0,n.useState)("api-keys"),[_,k]=(0,n.useState)(null);return(0,n.useEffect)(()=>{if(Z){let e=(0,eM.o)(Z);if(e){if(console.log("Decoded token:",e),console.log("Decoded key:",e.key),k(e.key),e.user_role){let l=function(e){if(!e)return"Undefined Role";switch(console.log("Received user role: ".concat(e.toLowerCase())),console.log("Received user role length: ".concat(e.toLowerCase().length)),e.toLowerCase()){case"app_owner":case"demo_app_owner":return"App Owner";case"app_admin":case"proxy_admin":return"Admin";case"proxy_admin_viewer":return"Admin Viewer";case"app_user":return"App User";default:return"Unknown Role"}}(e.user_role);console.log("Decoded user_role:",l),s(l),"Admin Viewer"==l&&b("usage")}else console.log("User role not defined");e.user_email?i(e.user_email):console.log("User Email is not set ".concat(e)),e.login_method?p("username_password"==e.login_method):console.log("User Email is not set ".concat(e))}}},[Z]),(0,r.jsx)(n.Suspense,{fallback:(0,r.jsx)("div",{children:"Loading..."}),children:(0,r.jsxs)("div",{className:"flex flex-col min-h-screen",children:[(0,r.jsx)(m,{userID:y,userRole:t,userEmail:a,showSSOBanner:x}),(0,r.jsxs)("div",{className:"flex flex-1 overflow-auto",children:[(0,r.jsx)("div",{className:"mt-8",children:(0,r.jsx)(lp,{setPage:b,userRole:t,defaultSelectedKey:null})}),"api-keys"==w?(0,r.jsx)(eL,{userID:y,userRole:t,teams:c,keys:h,setUserRole:s,userEmail:a,setUserEmail:i,setTeams:d,setKeys:u}):"models"==w?(0,r.jsx)(e8,{userID:y,userRole:t,token:Z,accessToken:_,modelData:g,setModelData:f}):"llm-playground"==w?(0,r.jsx)(lm,{userID:y,userRole:t,token:Z,accessToken:_}):"users"==w?(0,r.jsx)(e6,{userID:y,userRole:t,token:Z,keys:h,teams:c,accessToken:_,setKeys:u}):"teams"==w?(0,r.jsx)(e7,{teams:c,setTeams:d,searchParams:j,accessToken:_,userID:y,userRole:t}):"admin-panel"==w?(0,r.jsx)(le,{setTeams:d,searchParams:j,accessToken:_,showSSOBanner:x}):"api_ref"==w?(0,r.jsx)(lc,{}):"settings"==w?(0,r.jsx)(lt,{userID:y,userRole:t,accessToken:_}):"general-settings"==w?(0,r.jsx)(lo,{userID:y,userRole:t,accessToken:_,modelData:g}):(0,r.jsx)(lg,{userID:y,userRole:t,token:Z,accessToken:_})]})]})})}}},function(e){e.O(0,[447,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/PtTtxXIYvdjQsvRgdITlk/_buildManifest.js b/litellm/proxy/_experimental/out/_next/static/kbGdRQFfI6W3bEwfzmJDI/_buildManifest.js similarity index 100% rename from litellm/proxy/_experimental/out/_next/static/PtTtxXIYvdjQsvRgdITlk/_buildManifest.js rename to litellm/proxy/_experimental/out/_next/static/kbGdRQFfI6W3bEwfzmJDI/_buildManifest.js diff --git a/litellm/proxy/_experimental/out/_next/static/PtTtxXIYvdjQsvRgdITlk/_ssgManifest.js b/litellm/proxy/_experimental/out/_next/static/kbGdRQFfI6W3bEwfzmJDI/_ssgManifest.js similarity index 100% rename from litellm/proxy/_experimental/out/_next/static/PtTtxXIYvdjQsvRgdITlk/_ssgManifest.js rename to litellm/proxy/_experimental/out/_next/static/kbGdRQFfI6W3bEwfzmJDI/_ssgManifest.js diff --git a/litellm/proxy/_experimental/out/index.html b/litellm/proxy/_experimental/out/index.html index cb197f11e23..0dbd09152f7 100644 --- a/litellm/proxy/_experimental/out/index.html +++ b/litellm/proxy/_experimental/out/index.html @@ -1 +1 @@ -LiteLLM Dashboard \ No newline at end of file +LiteLLM Dashboard \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/index.txt b/litellm/proxy/_experimental/out/index.txt index 267d8e5baf0..70ccce5418b 100644 --- a/litellm/proxy/_experimental/out/index.txt +++ b/litellm/proxy/_experimental/out/index.txt @@ -1,7 +1,7 @@ 2:I[77831,[],""] -3:I[27125,["447","static/chunks/447-9f8d32190ff7d16d.js","931","static/chunks/app/page-781ca5f151d78d1d.js"],""] +3:I[27125,["447","static/chunks/447-9f8d32190ff7d16d.js","931","static/chunks/app/page-508c39694bd40fe9.js"],""] 4:I[5613,[],""] 5:I[31778,[],""] -0:["PtTtxXIYvdjQsvRgdITlk",[[["",{"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/5e699db73bf6f8c2.css","precedence":"next","crossOrigin":""}]],"$L6"]]]] +0:["kbGdRQFfI6W3bEwfzmJDI",[[["",{"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/5e699db73bf6f8c2.css","precedence":"next","crossOrigin":""}]],"$L6"]]]] 6:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"LiteLLM Dashboard"}],["$","meta","3",{"name":"description","content":"LiteLLM Proxy Admin UI"}],["$","link","4",{"rel":"icon","href":"/ui/favicon.ico","type":"image/x-icon","sizes":"16x16"}],["$","meta","5",{"name":"next-size-adjust"}]] 1:null diff --git a/litellm/proxy/_super_secret_config.yaml b/litellm/proxy/_super_secret_config.yaml index 0ea72c85b1a..0e1b4b2e136 100644 --- a/litellm/proxy/_super_secret_config.yaml +++ b/litellm/proxy/_super_secret_config.yaml @@ -1,18 +1,23 @@ model_list: -- model_name: text-embedding-3-small - litellm_params: - model: text-embedding-3-small -- model_name: whisper - litellm_params: - model: azure/azure-whisper - api_version: 2024-02-15-preview - api_base: os.environ/AZURE_EUROPE_API_BASE - api_key: os.environ/AZURE_EUROPE_API_KEY - model_info: - mode: audio_transcription - litellm_params: - model: gpt-4 - model_name: gpt-4 - -# litellm_settings: -# cache: True \ No newline at end of file + api_base: http://0.0.0.0:8080 + api_key: my-fake-key + model: openai/my-fake-model + model_name: fake-openai-endpoint +- litellm_params: + api_base: http://0.0.0.0:8080 + api_key: my-fake-key + model: openai/my-fake-model-2 + model_name: fake-openai-endpoint +- litellm_params: + api_base: http://0.0.0.0:8080 + api_key: my-fake-key + model: openai/my-fake-model-3 + model_name: fake-openai-endpoint +- litellm_params: + api_base: http://0.0.0.0:8080 + api_key: my-fake-key + model: openai/my-fake-model-4 + model_name: fake-openai-endpoint +router_settings: + num_retries: 0 \ No newline at end of file diff --git a/litellm/proxy/auth/auth_checks.py b/litellm/proxy/auth/auth_checks.py index c037190d352..a393ec90a09 100644 --- a/litellm/proxy/auth/auth_checks.py +++ b/litellm/proxy/auth/auth_checks.py @@ -95,7 +95,15 @@ def common_checks( f"'user' param not passed in. 'enforce_user_param'={general_settings['enforce_user_param']}" ) # 7. [OPTIONAL] If 'litellm.max_budget' is set (>0), is proxy under budget - if litellm.max_budget > 0 and global_proxy_spend is not None: + if ( + litellm.max_budget > 0 + and global_proxy_spend is not None + # only run global budget checks for OpenAI routes + # Reason - the Admin UI should continue working if the proxy crosses it's global budget + and route in LiteLLMRoutes.openai_routes.value + and route != "/v1/models" + and route != "/models" + ): if global_proxy_spend > litellm.max_budget: raise Exception( f"ExceededBudget: LiteLLM Proxy has exceeded its budget. Current spend: {global_proxy_spend}; Max Budget: {litellm.max_budget}" diff --git a/litellm/router.py b/litellm/router.py index 371d8e8ebdd..df4c2e046a7 100644 --- a/litellm/router.py +++ b/litellm/router.py @@ -50,7 +50,6 @@ class Router: model_names: List = [] cache_responses: Optional[bool] = False default_cache_time_seconds: int = 1 * 60 * 60 # 1 hour - num_retries: int = 0 tenacity = None leastbusy_logger: Optional[LeastBusyLoggingHandler] = None lowesttpm_logger: Optional[LowestTPMLoggingHandler] = None @@ -70,9 +69,11 @@ class Router: ] = None, # if you want to cache across model groups client_ttl: int = 3600, # ttl for cached clients - will re-initialize after this time in seconds ## RELIABILITY ## - num_retries: int = 0, + num_retries: Optional[int] = None, timeout: Optional[float] = None, - default_litellm_params={}, # default params for Router.chat.completion.create + default_litellm_params: Optional[ + dict + ] = None, # default params for Router.chat.completion.create default_max_parallel_requests: Optional[int] = None, set_verbose: bool = False, debug_level: Literal["DEBUG", "INFO"] = "INFO", @@ -158,6 +159,7 @@ class Router: router = Router(model_list=model_list, fallbacks=[{"azure-gpt-3.5-turbo": "openai-gpt-3.5-turbo"}]) ``` """ + if semaphore: self.semaphore = semaphore self.set_verbose = set_verbose @@ -229,7 +231,14 @@ class Router: self.failed_calls = ( InMemoryCache() ) # cache to track failed call per deployment, if num failed calls within 1 minute > allowed fails, then add it to cooldown - self.num_retries = num_retries or litellm.num_retries or 0 + + if num_retries is not None: + self.num_retries = num_retries + elif litellm.num_retries is not None: + self.num_retries = litellm.num_retries + else: + self.num_retries = openai.DEFAULT_MAX_RETRIES + self.timeout = timeout or litellm.request_timeout self.retry_after = retry_after @@ -255,6 +264,7 @@ class Router: ) # dict to store aliases for router, ex. {"gpt-4": "gpt-3.5-turbo"}, all requests with gpt-4 -> get routed to gpt-3.5-turbo group # make Router.chat.completions.create compatible for openai.chat.completions.create + default_litellm_params = default_litellm_params or {} self.chat = litellm.Chat(params=default_litellm_params, router_obj=self) # default litellm args @@ -428,6 +438,7 @@ class Router: kwargs["messages"] = messages kwargs["original_function"] = self._acompletion kwargs["num_retries"] = kwargs.get("num_retries", self.num_retries) + timeout = kwargs.get("request_timeout", self.timeout) kwargs.setdefault("metadata", {}).update({"model_group": model}) @@ -469,6 +480,7 @@ class Router: ) kwargs["model_info"] = deployment.get("model_info", {}) data = deployment["litellm_params"].copy() + model_name = data["model"] for k, v in self.default_litellm_params.items(): if ( @@ -1415,10 +1427,12 @@ class Router: context_window_fallbacks = kwargs.pop( "context_window_fallbacks", self.context_window_fallbacks ) - verbose_router_logger.debug( - f"async function w/ retries: original_function - {original_function}" - ) + num_retries = kwargs.pop("num_retries") + + verbose_router_logger.debug( + f"async function w/ retries: original_function - {original_function}, num_retries - {num_retries}" + ) try: # if the function call is successful, no exception will be raised and we'll break out of the loop response = await original_function(*args, **kwargs) @@ -1445,6 +1459,7 @@ class Router: await asyncio.sleep(timeout) elif RouterErrors.user_defined_ratelimit_error.value in str(e): raise e # don't wait to retry if deployment hits user-defined rate-limit + elif hasattr(original_exception, "status_code") and litellm._should_retry( status_code=original_exception.status_code ): @@ -1606,6 +1621,28 @@ class Router: raise e raise original_exception + def _router_should_retry( + self, e: Exception, remaining_retries: int, num_retries: int + ): + """ + Calculate back-off, then retry + """ + if hasattr(e, "response") and hasattr(e.response, "headers"): + timeout = litellm._calculate_retry_after( + remaining_retries=remaining_retries, + max_retries=num_retries, + response_headers=e.response.headers, + min_timeout=self.retry_after, + ) + time.sleep(timeout) + else: + timeout = litellm._calculate_retry_after( + remaining_retries=remaining_retries, + max_retries=num_retries, + min_timeout=self.retry_after, + ) + time.sleep(timeout) + def function_with_retries(self, *args, **kwargs): """ Try calling the model 3 times. Shuffle between available deployments. @@ -1625,9 +1662,6 @@ class Router: return response except Exception as e: original_exception = e - verbose_router_logger.debug( - f"num retries in function with retries: {num_retries}" - ) ### CHECK IF RATE LIMIT / CONTEXT WINDOW ERROR if ( isinstance(original_exception, litellm.ContextWindowExceededError) @@ -1641,6 +1675,11 @@ class Router: if num_retries > 0: kwargs = self.log_retry(kwargs=kwargs, e=original_exception) ### RETRY + self._router_should_retry( + e=original_exception, + remaining_retries=num_retries, + num_retries=num_retries, + ) for current_attempt in range(num_retries): verbose_router_logger.debug( f"retrying request. Current attempt - {current_attempt}; retries left: {num_retries}" @@ -1654,34 +1693,11 @@ class Router: ## LOGGING kwargs = self.log_retry(kwargs=kwargs, e=e) remaining_retries = num_retries - current_attempt - if "No models available" in str(e): - timeout = litellm._calculate_retry_after( - remaining_retries=remaining_retries, - max_retries=num_retries, - min_timeout=self.retry_after, - ) - time.sleep(timeout) - elif ( - hasattr(e, "status_code") - and hasattr(e, "response") - and litellm._should_retry(status_code=e.status_code) - ): - if hasattr(e.response, "headers"): - timeout = litellm._calculate_retry_after( - remaining_retries=remaining_retries, - max_retries=num_retries, - response_headers=e.response.headers, - min_timeout=self.retry_after, - ) - else: - timeout = litellm._calculate_retry_after( - remaining_retries=remaining_retries, - max_retries=num_retries, - min_timeout=self.retry_after, - ) - time.sleep(timeout) - else: - raise e + self._router_should_retry( + e=e, + remaining_retries=remaining_retries, + num_retries=num_retries, + ) raise original_exception ### HELPER FUNCTIONS @@ -1929,6 +1945,7 @@ class Router: ) default_api_base = api_base default_api_key = api_key + if ( model_name in litellm.open_ai_chat_completion_models or custom_llm_provider in litellm.openai_compatible_providers @@ -1964,6 +1981,25 @@ class Router: api_base = litellm.get_secret(api_base_env_name) litellm_params["api_base"] = api_base + ## AZURE AI STUDIO MISTRAL CHECK ## + """ + Make sure api base ends in /v1/ + + if not, add it - https://github.com/BerriAI/litellm/issues/2279 + """ + if ( + custom_llm_provider == "openai" + and api_base is not None + and not api_base.endswith("/v1/") + ): + # check if it ends with a trailing slash + if api_base.endswith("/"): + api_base += "v1/" + elif api_base.endswith("/v1"): + api_base += "/" + else: + api_base += "/v1/" + api_version = litellm_params.get("api_version") if api_version and api_version.startswith("os.environ/"): api_version_env_name = api_version.replace("os.environ/", "") @@ -1986,7 +2022,9 @@ class Router: stream_timeout = litellm.get_secret(stream_timeout_env_name) litellm_params["stream_timeout"] = stream_timeout - max_retries = litellm_params.pop("max_retries", 2) + max_retries = litellm_params.pop( + "max_retries", 0 + ) # router handles retry logic if isinstance(max_retries, str) and max_retries.startswith("os.environ/"): max_retries_env_name = max_retries.replace("os.environ/", "") max_retries = litellm.get_secret(max_retries_env_name) @@ -2052,9 +2090,11 @@ class Router: timeout=timeout, max_retries=max_retries, http_client=httpx.AsyncClient( - transport=AsyncCustomHTTPTransport(), - limits=httpx.Limits( - max_connections=1000, max_keepalive_connections=100 + transport=AsyncCustomHTTPTransport( + limits=httpx.Limits( + max_connections=1000, max_keepalive_connections=100 + ), + verify=litellm.ssl_verify, ), mounts=async_proxy_mounts, ), # type: ignore @@ -2074,9 +2114,11 @@ class Router: timeout=timeout, max_retries=max_retries, http_client=httpx.Client( - transport=CustomHTTPTransport(), - limits=httpx.Limits( - max_connections=1000, max_keepalive_connections=100 + transport=CustomHTTPTransport( + limits=httpx.Limits( + max_connections=1000, max_keepalive_connections=100 + ), + verify=litellm.ssl_verify, ), mounts=sync_proxy_mounts, ), # type: ignore @@ -2096,9 +2138,11 @@ class Router: timeout=stream_timeout, max_retries=max_retries, http_client=httpx.AsyncClient( - transport=AsyncCustomHTTPTransport(), - limits=httpx.Limits( - max_connections=1000, max_keepalive_connections=100 + transport=AsyncCustomHTTPTransport( + limits=httpx.Limits( + max_connections=1000, max_keepalive_connections=100 + ), + verify=litellm.ssl_verify, ), mounts=async_proxy_mounts, ), # type: ignore @@ -2118,9 +2162,11 @@ class Router: timeout=stream_timeout, max_retries=max_retries, http_client=httpx.Client( - transport=CustomHTTPTransport(), - limits=httpx.Limits( - max_connections=1000, max_keepalive_connections=100 + transport=CustomHTTPTransport( + limits=httpx.Limits( + max_connections=1000, max_keepalive_connections=100 + ), + verify=litellm.ssl_verify, ), mounts=sync_proxy_mounts, ), # type: ignore @@ -2158,9 +2204,11 @@ class Router: timeout=timeout, max_retries=max_retries, http_client=httpx.AsyncClient( - transport=AsyncCustomHTTPTransport(), - limits=httpx.Limits( - max_connections=1000, max_keepalive_connections=100 + transport=AsyncCustomHTTPTransport( + limits=httpx.Limits( + max_connections=1000, max_keepalive_connections=100 + ), + verify=litellm.ssl_verify, ), mounts=async_proxy_mounts, ), # type: ignore @@ -2178,9 +2226,11 @@ class Router: timeout=timeout, max_retries=max_retries, http_client=httpx.Client( - transport=CustomHTTPTransport(), - limits=httpx.Limits( - max_connections=1000, max_keepalive_connections=100 + transport=CustomHTTPTransport( + verify=litellm.ssl_verify, + limits=httpx.Limits( + max_connections=1000, max_keepalive_connections=100 + ), ), mounts=sync_proxy_mounts, ), # type: ignore @@ -2199,9 +2249,11 @@ class Router: timeout=stream_timeout, max_retries=max_retries, http_client=httpx.AsyncClient( - transport=AsyncCustomHTTPTransport(), - limits=httpx.Limits( - max_connections=1000, max_keepalive_connections=100 + transport=AsyncCustomHTTPTransport( + limits=httpx.Limits( + max_connections=1000, max_keepalive_connections=100 + ), + verify=litellm.ssl_verify, ), mounts=async_proxy_mounts, ), @@ -2219,9 +2271,11 @@ class Router: timeout=stream_timeout, max_retries=max_retries, http_client=httpx.Client( - transport=CustomHTTPTransport(), - limits=httpx.Limits( - max_connections=1000, max_keepalive_connections=100 + transport=CustomHTTPTransport( + limits=httpx.Limits( + max_connections=1000, max_keepalive_connections=100 + ), + verify=litellm.ssl_verify, ), mounts=sync_proxy_mounts, ), @@ -2249,9 +2303,11 @@ class Router: max_retries=max_retries, organization=organization, http_client=httpx.AsyncClient( - transport=AsyncCustomHTTPTransport(), - limits=httpx.Limits( - max_connections=1000, max_keepalive_connections=100 + transport=AsyncCustomHTTPTransport( + limits=httpx.Limits( + max_connections=1000, max_keepalive_connections=100 + ), + verify=litellm.ssl_verify, ), mounts=async_proxy_mounts, ), # type: ignore @@ -2271,9 +2327,11 @@ class Router: max_retries=max_retries, organization=organization, http_client=httpx.Client( - transport=CustomHTTPTransport(), - limits=httpx.Limits( - max_connections=1000, max_keepalive_connections=100 + transport=CustomHTTPTransport( + limits=httpx.Limits( + max_connections=1000, max_keepalive_connections=100 + ), + verify=litellm.ssl_verify, ), mounts=sync_proxy_mounts, ), # type: ignore @@ -2294,9 +2352,11 @@ class Router: max_retries=max_retries, organization=organization, http_client=httpx.AsyncClient( - transport=AsyncCustomHTTPTransport(), - limits=httpx.Limits( - max_connections=1000, max_keepalive_connections=100 + transport=AsyncCustomHTTPTransport( + limits=httpx.Limits( + max_connections=1000, max_keepalive_connections=100 + ), + verify=litellm.ssl_verify, ), mounts=async_proxy_mounts, ), # type: ignore @@ -2317,9 +2377,11 @@ class Router: max_retries=max_retries, organization=organization, http_client=httpx.Client( - transport=CustomHTTPTransport(), - limits=httpx.Limits( - max_connections=1000, max_keepalive_connections=100 + transport=CustomHTTPTransport( + limits=httpx.Limits( + max_connections=1000, max_keepalive_connections=100 + ), + verify=litellm.ssl_verify, ), mounts=sync_proxy_mounts, ), # type: ignore diff --git a/litellm/tests/test_acooldowns_router.py b/litellm/tests/test_acooldowns_router.py index 28573d5be20..7dced31a8f3 100644 --- a/litellm/tests/test_acooldowns_router.py +++ b/litellm/tests/test_acooldowns_router.py @@ -119,7 +119,9 @@ def test_multiple_deployments_parallel(): # test_multiple_deployments_parallel() -def test_cooldown_same_model_name(): +@pytest.mark.parametrize("sync_mode", [True, False]) +@pytest.mark.asyncio +async def test_cooldown_same_model_name(sync_mode): # users could have the same model with different api_base # example # azure/chatgpt, api_base: 1234 @@ -161,22 +163,40 @@ def test_cooldown_same_model_name(): num_retries=3, ) # type: ignore - response = router.completion( - model="gpt-3.5-turbo", - messages=[{"role": "user", "content": "hello this request will pass"}], - ) - print(router.model_list) - model_ids = [] - for model in router.model_list: - model_ids.append(model["model_info"]["id"]) - print("\n litellm model ids ", model_ids) + if sync_mode: + response = router.completion( + model="gpt-3.5-turbo", + messages=[{"role": "user", "content": "hello this request will pass"}], + ) + print(router.model_list) + model_ids = [] + for model in router.model_list: + model_ids.append(model["model_info"]["id"]) + print("\n litellm model ids ", model_ids) - # example litellm_model_names ['azure/chatgpt-v-2-ModelID-64321', 'azure/chatgpt-v-2-ModelID-63960'] - assert ( - model_ids[0] != model_ids[1] - ) # ensure both models have a uuid added, and they have different names + # example litellm_model_names ['azure/chatgpt-v-2-ModelID-64321', 'azure/chatgpt-v-2-ModelID-63960'] + assert ( + model_ids[0] != model_ids[1] + ) # ensure both models have a uuid added, and they have different names - print("\ngot response\n", response) + print("\ngot response\n", response) + else: + response = await router.acompletion( + model="gpt-3.5-turbo", + messages=[{"role": "user", "content": "hello this request will pass"}], + ) + print(router.model_list) + model_ids = [] + for model in router.model_list: + model_ids.append(model["model_info"]["id"]) + print("\n litellm model ids ", model_ids) + + # example litellm_model_names ['azure/chatgpt-v-2-ModelID-64321', 'azure/chatgpt-v-2-ModelID-63960'] + assert ( + model_ids[0] != model_ids[1] + ) # ensure both models have a uuid added, and they have different names + + print("\ngot response\n", response) except Exception as e: pytest.fail(f"Got unexpected exception on router! - {e}") diff --git a/litellm/tests/test_alangfuse.py b/litellm/tests/test_alangfuse.py index c1d8123c7a0..12e5f9587fb 100644 --- a/litellm/tests/test_alangfuse.py +++ b/litellm/tests/test_alangfuse.py @@ -161,40 +161,54 @@ async def make_async_calls(): return total_time -# def test_langfuse_logging_async_text_completion(): -# try: -# pre_langfuse_setup() -# litellm.set_verbose = False -# litellm.success_callback = ["langfuse"] +@pytest.mark.asyncio +@pytest.mark.parametrize("stream", [False, True]) +async def test_langfuse_logging_without_request_response(stream): + try: + import uuid -# async def _test_langfuse(): -# response = await litellm.atext_completion( -# model="gpt-3.5-turbo-instruct", -# prompt="this is a test", -# max_tokens=5, -# temperature=0.7, -# timeout=5, -# user="test_user", -# stream=True -# ) -# async for chunk in response: -# print() -# print(chunk) -# await asyncio.sleep(1) -# return response + _unique_trace_name = f"litellm-test-{str(uuid.uuid4())}" + litellm.set_verbose = True + litellm.turn_off_message_logging = True + litellm.success_callback = ["langfuse"] + response = await litellm.acompletion( + model="gpt-3.5-turbo", + mock_response="It's simple to use and easy to get started", + messages=[{"role": "user", "content": "Hi 👋 - i'm claude"}], + max_tokens=10, + temperature=0.2, + stream=stream, + metadata={"trace_id": _unique_trace_name}, + ) + print(response) + if stream: + async for chunk in response: + print(chunk) -# response = asyncio.run(_test_langfuse()) -# print(f"response: {response}") + await asyncio.sleep(3) -# # # check langfuse.log to see if there was a failed response -# search_logs("langfuse.log") -# except litellm.Timeout as e: -# pass -# except Exception as e: -# pytest.fail(f"An exception occurred - {e}") + import langfuse + langfuse_client = langfuse.Langfuse( + public_key=os.environ["LANGFUSE_PUBLIC_KEY"], + secret_key=os.environ["LANGFUSE_SECRET_KEY"], + ) -# test_langfuse_logging_async_text_completion() + # get trace with _unique_trace_name + trace = langfuse_client.get_generations(trace_id=_unique_trace_name) + + print("trace_from_langfuse", trace) + + _trace_data = trace.data + + assert _trace_data[0].input == {"messages": "redacted-by-litellm"} + assert _trace_data[0].output == { + "role": "assistant", + "content": "redacted-by-litellm", + } + + except Exception as e: + pytest.fail(f"An exception occurred - {e}") @pytest.mark.skip(reason="beta test - checking langfuse output") diff --git a/litellm/tests/test_completion.py b/litellm/tests/test_completion.py index d2c004a0ab1..fe4aa9c1c80 100644 --- a/litellm/tests/test_completion.py +++ b/litellm/tests/test_completion.py @@ -2655,6 +2655,88 @@ def test_completion_palm_stream(): pytest.fail(f"Error occurred: {e}") +def test_completion_watsonx(): + litellm.set_verbose = True + model_name = "watsonx/ibm/granite-13b-chat-v2" + try: + response = completion( + model=model_name, + messages=messages, + stop=["stop"], + max_tokens=20, + ) + # Add any assertions here to check the response + print(response) + except litellm.APIError as e: + pass + except Exception as e: + pytest.fail(f"Error occurred: {e}") + + +@pytest.mark.parametrize( + "provider, model, project, region_name, token", + [ + ("azure", "chatgpt-v-2", None, None, "test-token"), + ("vertex_ai", "anthropic-claude-3", "adroit-crow-1", "us-east1", None), + ("watsonx", "ibm/granite", "96946574", "dallas", "1234"), + ("bedrock", "anthropic.claude-3", None, "us-east-1", None), + ], +) +def test_unified_auth_params(provider, model, project, region_name, token): + """ + Check if params = ["project", "region_name", "token"] + are correctly translated for = ["azure", "vertex_ai", "watsonx", "aws"] + + tests get_optional_params + """ + data = { + "project": project, + "region_name": region_name, + "token": token, + "custom_llm_provider": provider, + "model": model, + } + + translated_optional_params = litellm.utils.get_optional_params(**data) + + if provider == "azure": + special_auth_params = ( + litellm.AzureOpenAIConfig().get_mapped_special_auth_params() + ) + elif provider == "bedrock": + special_auth_params = ( + litellm.AmazonBedrockGlobalConfig().get_mapped_special_auth_params() + ) + elif provider == "vertex_ai": + special_auth_params = litellm.VertexAIConfig().get_mapped_special_auth_params() + elif provider == "watsonx": + special_auth_params = ( + litellm.IBMWatsonXAIConfig().get_mapped_special_auth_params() + ) + + for param, value in special_auth_params.items(): + assert param in data + assert value in translated_optional_params + + +@pytest.mark.asyncio +async def test_acompletion_watsonx(): + litellm.set_verbose = True + model_name = "watsonx/ibm/granite-13b-chat-v2" + print("testing watsonx") + try: + response = await litellm.acompletion( + model=model_name, + messages=messages, + temperature=0.2, + max_tokens=80, + ) + # Add any assertions here to check the response + print(response) + except Exception as e: + pytest.fail(f"Error occurred: {e}") + + # test_completion_palm_stream() # test_completion_deep_infra() diff --git a/litellm/tests/test_embedding.py b/litellm/tests/test_embedding.py index d69e2d708bc..69ddb39ff65 100644 --- a/litellm/tests/test_embedding.py +++ b/litellm/tests/test_embedding.py @@ -484,6 +484,20 @@ def test_mistral_embeddings(): pytest.fail(f"Error occurred: {e}") +@pytest.mark.skip(reason="local test") +def test_watsonx_embeddings(): + try: + litellm.set_verbose = True + response = litellm.embedding( + model="watsonx/ibm/slate-30m-english-rtrvr", + input=["good morning from litellm"], + ) + print(f"response: {response}") + assert isinstance(response.usage, litellm.Usage) + except Exception as e: + pytest.fail(f"Error occurred: {e}") + + # test_mistral_embeddings() diff --git a/litellm/tests/test_least_busy_routing.py b/litellm/tests/test_least_busy_routing.py index 782d5b343a6..cb9d59e7557 100644 --- a/litellm/tests/test_least_busy_routing.py +++ b/litellm/tests/test_least_busy_routing.py @@ -201,6 +201,7 @@ async def test_router_atext_completion_streaming(): @pytest.mark.asyncio async def test_router_completion_streaming(): + litellm.set_verbose = True messages = [ {"role": "user", "content": "Hello, can you generate a 500 words poem?"} ] @@ -219,9 +220,9 @@ async def test_router_completion_streaming(): { "model_name": "azure-model", "litellm_params": { - "model": "azure/gpt-35-turbo", - "api_key": "os.environ/AZURE_EUROPE_API_KEY", - "api_base": "https://my-endpoint-europe-berri-992.openai.azure.com", + "model": "azure/gpt-turbo", + "api_key": "os.environ/AZURE_FRANCE_API_KEY", + "api_base": "https://openai-france-1234.openai.azure.com", "rpm": 6, }, "model_info": {"id": 2}, @@ -229,9 +230,9 @@ async def test_router_completion_streaming(): { "model_name": "azure-model", "litellm_params": { - "model": "azure/gpt-35-turbo", - "api_key": "os.environ/AZURE_CANADA_API_KEY", - "api_base": "https://my-endpoint-canada-berri992.openai.azure.com", + "model": "azure/gpt-turbo", + "api_key": "os.environ/AZURE_FRANCE_API_KEY", + "api_base": "https://openai-france-1234.openai.azure.com", "rpm": 6, }, "model_info": {"id": 3}, @@ -262,4 +263,4 @@ async def test_router_completion_streaming(): ## check if calls equally distributed cache_dict = router.cache.get_cache(key=cache_key) for k, v in cache_dict.items(): - assert v == 1 + assert v == 1, f"Failed. K={k} called v={v} times, cache_dict={cache_dict}" diff --git a/litellm/tests/test_router.py b/litellm/tests/test_router.py index 7beb1d67c7b..7520ac75f15 100644 --- a/litellm/tests/test_router.py +++ b/litellm/tests/test_router.py @@ -1,7 +1,7 @@ #### What this tests #### # This tests litellm router -import sys, os, time +import sys, os, time, openai import traceback, asyncio import pytest @@ -14,10 +14,133 @@ from litellm.router import Deployment, LiteLLM_Params, ModelInfo from concurrent.futures import ThreadPoolExecutor from collections import defaultdict from dotenv import load_dotenv +import os, httpx load_dotenv() +@pytest.mark.parametrize("num_retries", [None, 2]) +@pytest.mark.parametrize("max_retries", [None, 4]) +def test_router_num_retries_init(num_retries, max_retries): + """ + - test when num_retries set v/s not + - test client value when max retries set v/s not + """ + router = Router( + model_list=[ + { + "model_name": "gpt-3.5-turbo", # openai model name + "litellm_params": { # params for litellm completion/embedding call + "model": "azure/chatgpt-v-2", + "api_key": "bad-key", + "api_version": os.getenv("AZURE_API_VERSION"), + "api_base": os.getenv("AZURE_API_BASE"), + "max_retries": max_retries, + }, + "model_info": {"id": 12345}, + }, + ], + num_retries=num_retries, + ) + + if num_retries is not None: + assert router.num_retries == num_retries + else: + assert router.num_retries == openai.DEFAULT_MAX_RETRIES + + model_client = router._get_client( + {"model_info": {"id": 12345}}, client_type="async", kwargs={} + ) + + if max_retries is not None: + assert getattr(model_client, "max_retries") == max_retries + else: + assert getattr(model_client, "max_retries") == 0 + + +@pytest.mark.parametrize( + "timeout", [10, 1.0, httpx.Timeout(timeout=300.0, connect=20.0)] +) +@pytest.mark.parametrize("ssl_verify", [True, False]) +def test_router_timeout_init(timeout, ssl_verify): + """ + Allow user to pass httpx.Timeout + + related issue - https://github.com/BerriAI/litellm/issues/3162 + """ + litellm.ssl_verify = ssl_verify + + router = Router( + model_list=[ + { + "model_name": "test-model", + "litellm_params": { + "model": "azure/chatgpt-v-2", + "api_key": os.getenv("AZURE_API_KEY"), + "api_base": os.getenv("AZURE_API_BASE"), + "api_version": os.getenv("AZURE_API_VERSION"), + "timeout": timeout, + }, + "model_info": {"id": 1234}, + } + ] + ) + + model_client = router._get_client( + deployment={"model_info": {"id": 1234}}, client_type="sync_client", kwargs={} + ) + + assert getattr(model_client, "timeout") == timeout + + print(f"vars model_client: {vars(model_client)}") + http_client = getattr(model_client, "_client") + print(f"http client: {vars(http_client)}, ssl_Verify={ssl_verify}") + if ssl_verify == False: + assert http_client._transport._pool._ssl_context.verify_mode.name == "CERT_NONE" + else: + assert ( + http_client._transport._pool._ssl_context.verify_mode.name + == "CERT_REQUIRED" + ) + + +@pytest.mark.parametrize( + "mistral_api_base", + [ + "os.environ/AZURE_MISTRAL_API_BASE", + "https://Mistral-large-nmefg-serverless.eastus2.inference.ai.azure.com/v1/", + "https://Mistral-large-nmefg-serverless.eastus2.inference.ai.azure.com/v1", + "https://Mistral-large-nmefg-serverless.eastus2.inference.ai.azure.com/", + "https://Mistral-large-nmefg-serverless.eastus2.inference.ai.azure.com", + ], +) +def test_router_azure_ai_studio_init(mistral_api_base): + router = Router( + model_list=[ + { + "model_name": "test-model", + "litellm_params": { + "model": "azure/mistral-large-latest", + "api_key": "os.environ/AZURE_MISTRAL_API_KEY", + "api_base": mistral_api_base, + }, + "model_info": {"id": 1234}, + } + ] + ) + + model_client = router._get_client( + deployment={"model_info": {"id": 1234}}, client_type="sync_client", kwargs={} + ) + url = getattr(model_client, "_base_url") + uri_reference = str(getattr(url, "_uri_reference")) + + print(f"uri_reference: {uri_reference}") + + assert "/v1/" in uri_reference + assert uri_reference.count("v1") == 1 + + def test_exception_raising(): # this tests if the router raises an exception when invalid params are set # in this test both deployments have bad keys - Keep this test. It validates if the router raises the most recent exception diff --git a/litellm/tests/test_router_fallbacks.py b/litellm/tests/test_router_fallbacks.py index 98a2449f06b..364319929ec 100644 --- a/litellm/tests/test_router_fallbacks.py +++ b/litellm/tests/test_router_fallbacks.py @@ -258,6 +258,7 @@ def test_sync_fallbacks_embeddings(): model_list=model_list, fallbacks=[{"bad-azure-embedding-model": ["good-azure-embedding-model"]}], set_verbose=False, + num_retries=0, ) customHandler = MyCustomHandler() litellm.callbacks = [customHandler] @@ -393,7 +394,7 @@ def test_dynamic_fallbacks_sync(): }, ] - router = Router(model_list=model_list, set_verbose=True) + router = Router(model_list=model_list, set_verbose=True, num_retries=0) kwargs = {} kwargs["model"] = "azure/gpt-3.5-turbo" kwargs["messages"] = [{"role": "user", "content": "Hey, how's it going?"}] @@ -830,6 +831,7 @@ def test_usage_based_routing_fallbacks(): routing_strategy="usage-based-routing", redis_host=os.environ["REDIS_HOST"], redis_port=os.environ["REDIS_PORT"], + num_retries=0, ) messages = [ diff --git a/litellm/tests/test_router_init.py b/litellm/tests/test_router_init.py index 862d7e96581..f0f0cc541ca 100644 --- a/litellm/tests/test_router_init.py +++ b/litellm/tests/test_router_init.py @@ -203,7 +203,7 @@ def test_timeouts_router(): }, }, ] - router = Router(model_list=model_list) + router = Router(model_list=model_list, num_retries=0) print("PASSED !") @@ -396,7 +396,9 @@ def test_router_init_gpt_4_vision_enhancements(): pytest.fail(f"Error occurred: {e}") -def test_openai_with_organization(): +@pytest.mark.parametrize("sync_mode", [True, False]) +@pytest.mark.asyncio +async def test_openai_with_organization(sync_mode): try: print("Testing OpenAI with organization") model_list = [ @@ -418,32 +420,65 @@ def test_openai_with_organization(): print(router.model_list) print(router.model_list[0]) - openai_client = router._get_client( - deployment=router.model_list[0], - kwargs={"input": ["hello"], "model": "openai-bad-org"}, - ) - print(vars(openai_client)) - - assert openai_client.organization == "org-ikDc4ex8NB" - - # bad org raises error - - try: - response = router.completion( - model="openai-bad-org", - messages=[{"role": "user", "content": "this is a test"}], + if sync_mode: + openai_client = router._get_client( + deployment=router.model_list[0], + kwargs={"input": ["hello"], "model": "openai-bad-org"}, ) - pytest.fail("Request should have failed - This organization does not exist") - except Exception as e: - print("Got exception: " + str(e)) - assert "No such organization: org-ikDc4ex8NB" in str(e) + print(vars(openai_client)) - # good org works - response = router.completion( - model="openai-good-org", - messages=[{"role": "user", "content": "this is a test"}], - max_tokens=5, - ) + assert openai_client.organization == "org-ikDc4ex8NB" + + # bad org raises error + + try: + response = router.completion( + model="openai-bad-org", + messages=[{"role": "user", "content": "this is a test"}], + ) + pytest.fail( + "Request should have failed - This organization does not exist" + ) + except Exception as e: + print("Got exception: " + str(e)) + assert "No such organization: org-ikDc4ex8NB" in str(e) + + # good org works + response = router.completion( + model="openai-good-org", + messages=[{"role": "user", "content": "this is a test"}], + max_tokens=5, + ) + else: + openai_client = router._get_client( + deployment=router.model_list[0], + kwargs={"input": ["hello"], "model": "openai-bad-org"}, + client_type="async", + ) + print(vars(openai_client)) + + assert openai_client.organization == "org-ikDc4ex8NB" + + # bad org raises error + + try: + response = await router.acompletion( + model="openai-bad-org", + messages=[{"role": "user", "content": "this is a test"}], + ) + pytest.fail( + "Request should have failed - This organization does not exist" + ) + except Exception as e: + print("Got exception: " + str(e)) + assert "No such organization: org-ikDc4ex8NB" in str(e) + + # good org works + response = await router.acompletion( + model="openai-good-org", + messages=[{"role": "user", "content": "this is a test"}], + max_tokens=5, + ) except Exception as e: pytest.fail(f"Error occurred: {e}") diff --git a/litellm/tests/test_router_timeout.py b/litellm/tests/test_router_timeout.py index dff30113be2..1126f6fb8bf 100644 --- a/litellm/tests/test_router_timeout.py +++ b/litellm/tests/test_router_timeout.py @@ -57,6 +57,7 @@ def test_router_timeouts(): redis_password=os.getenv("REDIS_PASSWORD"), redis_port=int(os.getenv("REDIS_PORT")), timeout=10, + num_retries=0, ) print("***** TPM SETTINGS *****") @@ -89,15 +90,15 @@ def test_router_timeouts(): @pytest.mark.asyncio async def test_router_timeouts_bedrock(): - import openai + import openai, uuid # Model list for OpenAI and Anthropic models - model_list = [ + _model_list = [ { "model_name": "bedrock", "litellm_params": { "model": "bedrock/anthropic.claude-instant-v1", - "timeout": 0.001, + "timeout": 0.00001, }, "tpm": 80000, }, @@ -105,17 +106,18 @@ async def test_router_timeouts_bedrock(): # Configure router router = Router( - model_list=model_list, + model_list=_model_list, routing_strategy="usage-based-routing", debug_level="DEBUG", set_verbose=True, + num_retries=0, ) litellm.set_verbose = True try: response = await router.acompletion( model="bedrock", - messages=[{"role": "user", "content": "hello, who are u"}], + messages=[{"role": "user", "content": f"hello, who are u {uuid.uuid4()}"}], ) print(response) pytest.fail("Did not raise error `openai.APITimeoutError`") diff --git a/litellm/tests/test_streaming.py b/litellm/tests/test_streaming.py index df759b0b926..d0d8a720a72 100644 --- a/litellm/tests/test_streaming.py +++ b/litellm/tests/test_streaming.py @@ -1271,6 +1271,32 @@ def test_completion_sagemaker_stream(): pytest.fail(f"Error occurred: {e}") +def test_completion_watsonx_stream(): + litellm.set_verbose = True + try: + response = completion( + model="watsonx/ibm/granite-13b-chat-v2", + messages=messages, + temperature=0.5, + max_tokens=20, + stream=True, + ) + complete_response = "" + has_finish_reason = False + # Add any assertions here to check the response + for idx, chunk in enumerate(response): + chunk, finished = streaming_format_tests(idx, chunk) + has_finish_reason = finished + if finished: + break + complete_response += chunk + if has_finish_reason is False: + raise Exception("finish reason not set for last chunk") + if complete_response.strip() == "": + raise Exception("Empty response received") + except Exception as e: + pytest.fail(f"Error occurred: {e}") + # test_completion_sagemaker_stream() diff --git a/litellm/tests/test_timeout.py b/litellm/tests/test_timeout.py index 8c92607c02c..d38da52e51f 100644 --- a/litellm/tests/test_timeout.py +++ b/litellm/tests/test_timeout.py @@ -78,7 +78,8 @@ def test_hanging_request_azure(): "model_name": "openai-gpt", "litellm_params": {"model": "gpt-3.5-turbo"}, }, - ] + ], + num_retries=0, ) encoded = litellm.utils.encode(model="gpt-3.5-turbo", text="blue")[0] @@ -131,7 +132,8 @@ def test_hanging_request_openai(): "model_name": "openai-gpt", "litellm_params": {"model": "gpt-3.5-turbo"}, }, - ] + ], + num_retries=0, ) encoded = litellm.utils.encode(model="gpt-3.5-turbo", text="blue")[0] @@ -189,6 +191,7 @@ def test_timeout_streaming(): # test_timeout_streaming() +@pytest.mark.skip(reason="local test") def test_timeout_ollama(): # this Will Raise a timeout import litellm diff --git a/litellm/types/router.py b/litellm/types/router.py index c5ec47091a1..09965bb8a9d 100644 --- a/litellm/types/router.py +++ b/litellm/types/router.py @@ -1,5 +1,5 @@ from typing import List, Optional, Union, Dict, Tuple, Literal - +import httpx from pydantic import BaseModel, validator from .completion import CompletionRequest from .embedding import EmbeddingRequest @@ -104,11 +104,13 @@ class LiteLLM_Params(BaseModel): api_key: Optional[str] = None api_base: Optional[str] = None api_version: Optional[str] = None - timeout: Optional[Union[float, str]] = None # if str, pass in as os.environ/ + timeout: Optional[Union[float, str, httpx.Timeout]] = ( + None # if str, pass in as os.environ/ + ) stream_timeout: Optional[Union[float, str]] = ( None # timeout when making stream=True calls, if str, pass in as os.environ/ ) - max_retries: int = 2 # follows openai default of 2 + max_retries: Optional[int] = None organization: Optional[str] = None # for openai orgs ## VERTEX AI ## vertex_project: Optional[str] = None @@ -146,14 +148,13 @@ class LiteLLM_Params(BaseModel): args.pop("self", None) args.pop("params", None) args.pop("__class__", None) - if max_retries is None: - max_retries = 2 - elif isinstance(max_retries, str): + if max_retries is not None and isinstance(max_retries, str): max_retries = int(max_retries) # cast to int super().__init__(max_retries=max_retries, **args, **params) class Config: extra = "allow" + arbitrary_types_allowed = True def __contains__(self, key): # Define custom behavior for the 'in' operator diff --git a/litellm/utils.py b/litellm/utils.py index 8c38633449e..6e62b64c9fc 100644 --- a/litellm/utils.py +++ b/litellm/utils.py @@ -1212,7 +1212,6 @@ class Logging: print_verbose( f"LiteLLM.LoggingError: [Non-Blocking] Exception occurred while logging {traceback.format_exc()}" ) - # Input Integration Logging -> If you want to log the fact that an attempt to call the model was made callbacks = litellm.input_callback + self.dynamic_input_callbacks for callback in callbacks: @@ -1229,29 +1228,17 @@ class Logging: litellm_call_id=self.litellm_params["litellm_call_id"], print_verbose=print_verbose, ) - - elif callback == "lite_debugger": - print_verbose( - f"reaches litedebugger for logging! - model_call_details {self.model_call_details}" - ) - model = self.model_call_details["model"] - messages = self.model_call_details["input"] - print_verbose(f"liteDebuggerClient: {liteDebuggerClient}") - liteDebuggerClient.input_log_event( - model=model, - messages=messages, - end_user=self.model_call_details.get("user", "default"), - litellm_call_id=self.litellm_params["litellm_call_id"], - litellm_params=self.model_call_details["litellm_params"], - optional_params=self.model_call_details["optional_params"], - print_verbose=print_verbose, - call_type=self.call_type, - ) elif callback == "sentry" and add_breadcrumb: - print_verbose("reaches sentry breadcrumbing") + details_to_log = copy.deepcopy(self.model_call_details) + if litellm.turn_off_message_logging: + # make a copy of the _model_Call_details and log it + details_to_log.pop("messages", None) + details_to_log.pop("input", None) + details_to_log.pop("prompt", None) + add_breadcrumb( category="litellm.llm_call", - message=f"Model Call Details pre-call: {self.model_call_details}", + message=f"Model Call Details pre-call: {details_to_log}", level="info", ) elif isinstance(callback, CustomLogger): # custom logger class @@ -1315,7 +1302,7 @@ class Logging: print_verbose( f"LiteLLM.LoggingError: [Non-Blocking] Exception occurred while logging {traceback.format_exc()}" ) - + self.redact_message_input_output_from_logging(result=original_response) # Input Integration Logging -> If you want to log the fact that an attempt to call the model was made callbacks = litellm.input_callback + self.dynamic_input_callbacks @@ -1333,9 +1320,17 @@ class Logging: ) elif callback == "sentry" and add_breadcrumb: print_verbose("reaches sentry breadcrumbing") + + details_to_log = copy.deepcopy(self.model_call_details) + if litellm.turn_off_message_logging: + # make a copy of the _model_Call_details and log it + details_to_log.pop("messages", None) + details_to_log.pop("input", None) + details_to_log.pop("prompt", None) + add_breadcrumb( category="litellm.llm_call", - message=f"Model Call Details post-call: {self.model_call_details}", + message=f"Model Call Details post-call: {details_to_log}", level="info", ) elif isinstance(callback, CustomLogger): # custom logger class @@ -1527,6 +1522,8 @@ class Logging: else: callbacks = litellm.success_callback + self.redact_message_input_output_from_logging(result=result) + for callback in callbacks: try: litellm_params = self.model_call_details.get("litellm_params", {}) @@ -2071,6 +2068,9 @@ class Logging: callbacks.append(callback) else: callbacks = litellm._async_success_callback + + self.redact_message_input_output_from_logging(result=result) + print_verbose(f"Async success callbacks: {callbacks}") for callback in callbacks: # check if callback can run for this request @@ -2232,7 +2232,10 @@ class Logging: start_time=start_time, end_time=end_time, ) + result = None # result sent to all loggers, init this to None incase it's not created + + self.redact_message_input_output_from_logging(result=result) for callback in litellm.failure_callback: try: if callback == "lite_debugger": @@ -2417,6 +2420,33 @@ class Logging: f"LiteLLM.LoggingError: [Non-Blocking] Exception occurred while success logging {traceback.format_exc()}" ) + def redact_message_input_output_from_logging(self, result): + """ + Removes messages, prompts, input, response from logging. This modifies the data in-place + only redacts when litellm.turn_off_message_logging == True + """ + # check if user opted out of logging message/response to callbacks + if litellm.turn_off_message_logging == True: + # remove messages, prompts, input, response from logging + self.model_call_details["messages"] = "redacted-by-litellm" + self.model_call_details["prompt"] = "" + self.model_call_details["input"] = "" + + # response cleaning + # ChatCompletion Responses + if self.stream and "complete_streaming_response" in self.model_call_details: + _streaming_response = self.model_call_details[ + "complete_streaming_response" + ] + for choice in _streaming_response.choices: + choice.message.content = "redacted-by-litellm" + else: + if result is not None: + if isinstance(result, litellm.ModelResponse): + if hasattr(result, "choices"): + for choice in result.choices: + choice.message.content = "redacted-by-litellm" + def exception_logging( additional_args={}, @@ -2598,9 +2628,15 @@ def function_setup( dynamic_success_callbacks = kwargs.pop("success_callback") if add_breadcrumb: + details_to_log = copy.deepcopy(kwargs) + if litellm.turn_off_message_logging: + # make a copy of the _model_Call_details and log it + details_to_log.pop("messages", None) + details_to_log.pop("input", None) + details_to_log.pop("prompt", None) add_breadcrumb( category="litellm.llm_call", - message=f"Positional Args: {args}, Keyword Args: {kwargs}", + message=f"Positional Args: {args}, Keyword Args: {details_to_log}", level="info", ) if "logger_fn" in kwargs: @@ -4619,7 +4655,36 @@ def get_optional_params( k.startswith("vertex_") and custom_llm_provider != "vertex_ai" ): # allow dynamically setting vertex ai init logic continue + passed_params[k] = v + + optional_params = {} + + common_auth_dict = litellm.common_cloud_provider_auth_params + if custom_llm_provider in common_auth_dict["providers"]: + """ + Check if params = ["project", "region_name", "token"] + and correctly translate for = ["azure", "vertex_ai", "watsonx", "aws"] + """ + if custom_llm_provider == "azure": + optional_params = litellm.AzureOpenAIConfig().map_special_auth_params( + non_default_params=passed_params, optional_params=optional_params + ) + elif custom_llm_provider == "bedrock": + optional_params = ( + litellm.AmazonBedrockGlobalConfig().map_special_auth_params( + non_default_params=passed_params, optional_params=optional_params + ) + ) + elif custom_llm_provider == "vertex_ai": + optional_params = litellm.VertexAIConfig().map_special_auth_params( + non_default_params=passed_params, optional_params=optional_params + ) + elif custom_llm_provider == "watsonx": + optional_params = litellm.IBMWatsonXAIConfig().map_special_auth_params( + non_default_params=passed_params, optional_params=optional_params + ) + default_params = { "functions": None, "function_call": None, @@ -4655,7 +4720,7 @@ def get_optional_params( and v != default_params[k] ) } - optional_params = {} + ## raise exception if function calling passed in for a provider that doesn't support it if ( "functions" in non_default_params @@ -5427,6 +5492,49 @@ def get_optional_params( optional_params["extra_body"] = ( extra_body # openai client supports `extra_body` param ) + elif custom_llm_provider == "watsonx": + supported_params = get_supported_openai_params( + model=model, custom_llm_provider=custom_llm_provider + ) + _check_valid_arg(supported_params=supported_params) + if max_tokens is not None: + optional_params["max_new_tokens"] = max_tokens + if stream: + optional_params["stream"] = stream + if temperature is not None: + optional_params["temperature"] = temperature + if top_p is not None: + optional_params["top_p"] = top_p + if frequency_penalty is not None: + optional_params["repetition_penalty"] = frequency_penalty + if seed is not None: + optional_params["random_seed"] = seed + if stop is not None: + optional_params["stop_sequences"] = stop + + # WatsonX-only parameters + extra_body = {} + if "decoding_method" in passed_params: + extra_body["decoding_method"] = passed_params.pop("decoding_method") + if "min_tokens" in passed_params or "min_new_tokens" in passed_params: + extra_body["min_new_tokens"] = passed_params.pop( + "min_tokens", passed_params.pop("min_new_tokens") + ) + if "top_k" in passed_params: + extra_body["top_k"] = passed_params.pop("top_k") + if "truncate_input_tokens" in passed_params: + extra_body["truncate_input_tokens"] = passed_params.pop( + "truncate_input_tokens" + ) + if "length_penalty" in passed_params: + extra_body["length_penalty"] = passed_params.pop("length_penalty") + if "time_limit" in passed_params: + extra_body["time_limit"] = passed_params.pop("time_limit") + if "return_options" in passed_params: + extra_body["return_options"] = passed_params.pop("return_options") + optional_params["extra_body"] = ( + extra_body # openai client supports `extra_body` param + ) else: # assume passing in params for openai/azure openai print_verbose( f"UNMAPPED PROVIDER, ASSUMING IT'S OPENAI/AZURE - model={model}, custom_llm_provider={custom_llm_provider}" @@ -5829,6 +5937,8 @@ def get_supported_openai_params(model: str, custom_llm_provider: str): "frequency_penalty", "presence_penalty", ] + elif custom_llm_provider == "watsonx": + return litellm.IBMWatsonXAIConfig().get_supported_openai_params() def get_formatted_prompt( @@ -6056,6 +6166,8 @@ def get_llm_provider( model in litellm.bedrock_models or model in litellm.bedrock_embedding_models ): custom_llm_provider = "bedrock" + elif model in litellm.watsonx_models: + custom_llm_provider = "watsonx" # openai embeddings elif model in litellm.open_ai_embedding_models: custom_llm_provider = "openai" @@ -6520,7 +6632,7 @@ def validate_environment(model: Optional[str] = None) -> dict: if "VERTEXAI_PROJECT" in os.environ and "VERTEXAI_LOCATION" in os.environ: keys_in_environment = True else: - missing_keys.extend(["VERTEXAI_PROJECT", "VERTEXAI_PROJECT"]) + missing_keys.extend(["VERTEXAI_PROJECT", "VERTEXAI_LOCATION"]) elif custom_llm_provider == "huggingface": if "HUGGINGFACE_API_KEY" in os.environ: keys_in_environment = True @@ -9751,6 +9863,39 @@ class CustomStreamWrapper: "finish_reason": finish_reason, } + def handle_watsonx_stream(self, chunk): + try: + if isinstance(chunk, dict): + parsed_response = chunk + elif isinstance(chunk, (str, bytes)): + if isinstance(chunk, bytes): + chunk = chunk.decode("utf-8") + if "generated_text" in chunk: + response = chunk.replace("data: ", "").strip() + parsed_response = json.loads(response) + else: + return {"text": "", "is_finished": False} + else: + print_verbose(f"chunk: {chunk} (Type: {type(chunk)})") + raise ValueError( + f"Unable to parse response. Original response: {chunk}" + ) + results = parsed_response.get("results", []) + if len(results) > 0: + text = results[0].get("generated_text", "") + finish_reason = results[0].get("stop_reason") + is_finished = finish_reason != "not_finished" + return { + "text": text, + "is_finished": is_finished, + "finish_reason": finish_reason, + "prompt_tokens": results[0].get("input_token_count", None), + "completion_tokens": results[0].get("generated_token_count", None), + } + return {"text": "", "is_finished": False} + except Exception as e: + raise e + def model_response_creator(self): model_response = ModelResponse(stream=True, model=self.model) if self.response_id is not None: @@ -10006,6 +10151,26 @@ class CustomStreamWrapper: print_verbose(f"completion obj content: {completion_obj['content']}") if response_obj["is_finished"]: self.received_finish_reason = response_obj["finish_reason"] + elif self.custom_llm_provider == "watsonx": + response_obj = self.handle_watsonx_stream(chunk) + completion_obj["content"] = response_obj["text"] + print_verbose(f"completion obj content: {completion_obj['content']}") + if response_obj.get("prompt_tokens") is not None: + prompt_token_count = getattr( + model_response.usage, "prompt_tokens", 0 + ) + model_response.usage.prompt_tokens = ( + prompt_token_count + response_obj["prompt_tokens"] + ) + if response_obj.get("completion_tokens") is not None: + model_response.usage.completion_tokens = response_obj[ + "completion_tokens" + ] + model_response.usage.total_tokens = getattr( + model_response.usage, "prompt_tokens", 0 + ) + getattr(model_response.usage, "completion_tokens", 0) + if response_obj["is_finished"]: + self.received_finish_reason = response_obj["finish_reason"] elif self.custom_llm_provider == "text-completion-openai": response_obj = self.handle_openai_text_completion_chunk(chunk) completion_obj["content"] = response_obj["text"] diff --git a/pyproject.toml b/pyproject.toml index 0b8b7359cd3..ae09ad3cbeb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "litellm" -version = "1.35.29" +version = "1.35.31" description = "Library to easily interface with LLM API providers" authors = ["BerriAI"] license = "MIT" @@ -80,7 +80,7 @@ requires = ["poetry-core", "wheel"] build-backend = "poetry.core.masonry.api" [tool.commitizen] -version = "1.35.29" +version = "1.35.31" version_files = [ "pyproject.toml:^version" ] diff --git a/ui/litellm-dashboard/out/404.html b/ui/litellm-dashboard/out/404.html index 310a90e222d..6d3d33c80bf 100644 --- a/ui/litellm-dashboard/out/404.html +++ b/ui/litellm-dashboard/out/404.html @@ -1 +1 @@ -404: This page could not be found.LiteLLM Dashboard

404

This page could not be found.

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

404

This page could not be found.

\ No newline at end of file diff --git a/ui/litellm-dashboard/out/_next/static/chunks/app/page-508c39694bd40fe9.js b/ui/litellm-dashboard/out/_next/static/chunks/app/page-508c39694bd40fe9.js new file mode 100644 index 00000000000..290d55662cb --- /dev/null +++ b/ui/litellm-dashboard/out/_next/static/chunks/app/page-508c39694bd40fe9.js @@ -0,0 +1 @@ +(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[931],{20661:function(e,l,t){Promise.resolve().then(t.bind(t,27125))},27125:function(e,l,t){"use strict";t.r(l),t.d(l,{default:function(){return lf}});var s,a,r=t(3827),n=t(64090),o=t(47907),i=t(8792),c=t(40491),d=t(65270),m=e=>{let{userID:l,userRole:t,userEmail:s,showSSOBanner:a}=e;console.log("User ID:",l),console.log("userEmail:",s),console.log("showSSOBanner:",a);let n=[{key:"1",label:(0,r.jsxs)(r.Fragment,{children:[(0,r.jsxs)("p",{children:["Role: ",t]}),(0,r.jsxs)("p",{children:["ID: ",l]})]})}];return(0,r.jsxs)("nav",{className:"left-0 right-0 top-0 flex justify-between items-center h-12 mb-4",children:[(0,r.jsx)("div",{className:"text-left my-2 absolute top-0 left-0",children:(0,r.jsx)("div",{className:"flex flex-col items-center",children:(0,r.jsx)(i.default,{href:"/",children:(0,r.jsx)("button",{className:"text-gray-800 rounded text-center",children:(0,r.jsx)("img",{src:"/get_image",width:160,height:160,alt:"LiteLLM Brand",className:"mr-2"})})})})}),(0,r.jsxs)("div",{className:"text-right mx-4 my-2 absolute top-0 right-0 flex items-center justify-end space-x-2",children:[a?(0,r.jsx)("div",{style:{padding:"6px",borderRadius:"8px"},children:(0,r.jsx)("a",{href:"https://calendly.com/d/4mp-gd3-k5k/litellm-1-1-onboarding-chat",target:"_blank",style:{fontSize:"14px",textDecoration:"underline"},children:"Request hosted proxy"})}):null,(0,r.jsx)("div",{style:{border:"1px solid #391085",padding:"6px",borderRadius:"8px"},children:(0,r.jsx)(c.Z,{menu:{items:n},children:(0,r.jsx)(d.Z,{children:s})})})]})]})},h=t(80588);let u=async()=>{try{let e=await fetch("https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json"),l=await e.json();return console.log("received data: ".concat(l)),l}catch(e){throw console.error("Failed to get model cost map:",e),e}},x=async(e,l)=>{try{let t=await fetch("/model/new",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...l})});if(!t.ok){let e=await t.text();throw h.ZP.error("Failed to create key: "+e,20),console.error("Error response from the server:",e),Error("Network response was not ok")}let s=await t.json();return console.log("API Response:",s),h.ZP.success("Model created successfully. Wait 60s and refresh on 'All Models' page"),s}catch(e){throw console.error("Failed to create key:",e),e}},p=async(e,l)=>{console.log("model_id in model delete call: ".concat(l));try{let t=await fetch("/model/delete",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({id:l})});if(!t.ok){let e=await t.text();throw h.ZP.error("Failed to create key: "+e,20),console.error("Error response from the server:",e),Error("Network response was not ok")}let s=await t.json();return console.log("API Response:",s),h.ZP.success("Model deleted successfully. Restart server to see this."),s}catch(e){throw console.error("Failed to create key:",e),e}},j=async(e,l,t)=>{try{if(console.log("Form Values in keyCreateCall:",t),t.description&&(t.metadata||(t.metadata={}),t.metadata.description=t.description,delete t.description,t.metadata=JSON.stringify(t.metadata)),t.metadata){console.log("formValues.metadata:",t.metadata);try{t.metadata=JSON.parse(t.metadata)}catch(e){throw h.ZP.error("Failed to parse metadata: "+e,20),Error("Failed to parse metadata: "+e)}}console.log("Form Values after check:",t);let s=await fetch("/key/generate",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({user_id:l,...t})});if(!s.ok){let e=await s.text();throw h.ZP.error("Failed to create key: "+e,20),console.error("Error response from the server:",e),Error("Network response was not ok")}let a=await s.json();return console.log("API Response:",a),a}catch(e){throw console.error("Failed to create key:",e),e}},g=async(e,l,t)=>{try{if(console.log("Form Values in keyCreateCall:",t),t.description&&(t.metadata||(t.metadata={}),t.metadata.description=t.description,delete t.description,t.metadata=JSON.stringify(t.metadata)),t.metadata){console.log("formValues.metadata:",t.metadata);try{t.metadata=JSON.parse(t.metadata)}catch(e){throw h.ZP.error("Failed to parse metadata: "+e,20),Error("Failed to parse metadata: "+e)}}console.log("Form Values after check:",t);let s=await fetch("/user/new",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({user_id:l,...t})});if(!s.ok){let e=await s.text();throw h.ZP.error("Failed to create key: "+e,20),console.error("Error response from the server:",e),Error("Network response was not ok")}let a=await s.json();return console.log("API Response:",a),a}catch(e){throw console.error("Failed to create key:",e),e}},f=async(e,l)=>{try{console.log("in keyDeleteCall:",l);let t=await fetch("/key/delete",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({keys:[l]})});if(!t.ok){let e=await t.text();throw h.ZP.error("Failed to delete key: "+e,20),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to create key:",e),e}},y=async(e,l)=>{try{console.log("in teamDeleteCall:",l);let t=await fetch("/team/delete",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({team_ids:[l]})});if(!t.ok){let e=await t.text();throw h.ZP.error("Failed to delete team: "+e,20),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to delete key:",e),e}},Z=async function(e,l,t){let s=arguments.length>3&&void 0!==arguments[3]&&arguments[3],a=arguments.length>4?arguments[4]:void 0,r=arguments.length>5?arguments[5]:void 0;try{let n="/user/info";"App Owner"==t&&l&&(n="".concat(n,"?user_id=").concat(l)),"App User"==t&&l&&(n="".concat(n,"?user_id=").concat(l)),console.log("in userInfoCall viewAll=",s),s&&r&&null!=a&&void 0!=a&&(n="".concat(n,"?view_all=true&page=").concat(a,"&page_size=").concat(r));let o=await fetch(n,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!o.ok){let e=await o.text();throw h.ZP.error(e,20),Error("Network response was not ok")}let i=await o.json();return console.log("API Response:",i),i}catch(e){throw console.error("Failed to create key:",e),e}},w=async(e,l)=>{try{let t="/team/info";l&&(t="".concat(t,"?team_id=").concat(l)),console.log("in teamInfoCall");let s=await fetch(t,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!s.ok){let e=await s.text();throw h.ZP.error(e,20),Error("Network response was not ok")}let a=await s.json();return console.log("API Response:",a),a}catch(e){throw console.error("Failed to create key:",e),e}},b=async e=>{try{let l=await fetch("/global/spend",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw h.ZP.error(e,20),Error("Network response was not ok")}return await l.json()}catch(e){throw console.error("Failed to create key:",e),e}},_=async(e,l,t)=>{try{let l=await fetch("/v2/model/info",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw h.ZP.error(e,20),Error("Network response was not ok")}let t=await l.json();return console.log("modelInfoCall:",t),t}catch(e){throw console.error("Failed to create key:",e),e}},k=async(e,l,t,s)=>{try{let l="/model/metrics";s&&(l="".concat(l,"?_selected_model_group=").concat(s));let t=await fetch(l,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw h.ZP.error(e,20),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},v=async(e,l,t)=>{try{let l=await fetch("/models",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw h.ZP.error(e,20),Error("Network response was not ok")}return await l.json()}catch(e){throw console.error("Failed to create key:",e),e}},S=async(e,l)=>{try{let t="/global/spend/logs";console.log("in keySpendLogsCall:",t);let s=await fetch("".concat(t,"?api_key=").concat(l),{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!s.ok){let e=await s.text();throw h.ZP.error(e,20),Error("Network response was not ok")}let a=await s.json();return console.log(a),a}catch(e){throw console.error("Failed to create key:",e),e}},A=async e=>{try{let l="/global/spend/teams";console.log("in teamSpendLogsCall:",l);let t=await fetch("".concat(l),{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw h.ZP.error(e,20),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to create key:",e),e}},N=async e=>{try{let l="/global/spend/tags";console.log("in tagsSpendLogsCall:",l);let t=await fetch("".concat(l),{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw h.ZP.error(e,20),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to create key:",e),e}},C=async(e,l,t,s,a,r)=>{try{console.log("user role in spend logs call: ".concat(t));let l="/spend/logs";l="App Owner"==t?"".concat(l,"?user_id=").concat(s,"&start_date=").concat(a,"&end_date=").concat(r):"".concat(l,"?start_date=").concat(a,"&end_date=").concat(r);let n=await fetch(l,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!n.ok){let e=await n.text();throw h.ZP.error(e,20),Error("Network response was not ok")}let o=await n.json();return console.log(o),o}catch(e){throw console.error("Failed to create key:",e),e}},I=async e=>{try{let l=await fetch("/global/spend/logs",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw h.ZP.error(e,20),Error("Network response was not ok")}let t=await l.json();return console.log(t),t}catch(e){throw console.error("Failed to create key:",e),e}},P=async e=>{try{let l=await fetch("/global/spend/keys?limit=5",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw h.ZP.error(e,20),Error("Network response was not ok")}let t=await l.json();return console.log(t),t}catch(e){throw console.error("Failed to create key:",e),e}},T=async(e,l)=>{try{l&&JSON.stringify({api_key:l});let t={method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}};l&&(t.body=JSON.stringify({api_key:l}));let s=await fetch("/global/spend/end_users",t);if(!s.ok){let e=await s.text();throw h.ZP.error(e,20),Error("Network response was not ok")}let a=await s.json();return console.log(a),a}catch(e){throw console.error("Failed to create key:",e),e}},E=async e=>{try{let l=await fetch("/global/spend/models?limit=5",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw h.ZP.error(e,20),Error("Network response was not ok")}let t=await l.json();return console.log(t),t}catch(e){throw console.error("Failed to create key:",e),e}},F=async(e,l)=>{try{let t=await fetch("/v2/key/info",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({keys:l})});if(!t.ok){let e=await t.text();throw h.ZP.error(e,20),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to create key:",e),e}},O=async e=>{try{let l="/user/get_requests";console.log("in userGetRequesedtModelsCall:",l);let t=await fetch(l,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw h.ZP.error("Failed to delete key: "+e,20),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to get requested models:",e),e}},M=async(e,l)=>{try{let t="/user/get_users?role=".concat(l);console.log("in userGetAllUsersCall:",t);let s=await fetch(t,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!s.ok){let e=await s.text();throw h.ZP.error("Failed to delete key: "+e,20),Error("Network response was not ok")}let a=await s.json();return console.log(a),a}catch(e){throw console.error("Failed to get requested models:",e),e}},R=async(e,l)=>{try{console.log("Form Values in teamCreateCall:",l);let t=await fetch("/team/new",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...l})});if(!t.ok){let e=await t.text();throw h.ZP.error("Failed to create key: "+e,20),console.error("Error response from the server:",e),Error("Network response was not ok")}let s=await t.json();return console.log("API Response:",s),s}catch(e){throw console.error("Failed to create key:",e),e}},L=async(e,l)=>{try{console.log("Form Values in keyUpdateCall:",l);let t=await fetch("/key/update",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...l})});if(!t.ok){let e=await t.text();throw h.ZP.error("Failed to update key: "+e,20),console.error("Error response from the server:",e),Error("Network response was not ok")}let s=await t.json();return console.log("Update key Response:",s),s}catch(e){throw console.error("Failed to create key:",e),e}},U=async(e,l)=>{try{console.log("Form Values in teamUpateCall:",l);let t=await fetch("/team/update",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...l})});if(!t.ok){let e=await t.text();throw h.ZP.error("Failed to update team: "+e,20),console.error("Error response from the server:",e),Error("Network response was not ok")}let s=await t.json();return console.log("Update Team Response:",s),s}catch(e){throw console.error("Failed to create key:",e),e}},D=async(e,l)=>{try{console.log("Form Values in modelUpateCall:",l);let t=await fetch("/model/update",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...l})});if(!t.ok){let e=await t.text();throw h.ZP.error("Failed to update model: "+e,20),console.error("Error update from the server:",e),Error("Network response was not ok")}let s=await t.json();return console.log("Update model Response:",s),s}catch(e){throw console.error("Failed to update model:",e),e}},z=async(e,l,t)=>{try{console.log("Form Values in teamMemberAddCall:",t);let s=await fetch("/team/member_add",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({team_id:l,member:t})});if(!s.ok){let e=await s.text();throw h.ZP.error("Failed to create key: "+e,20),console.error("Error response from the server:",e),Error("Network response was not ok")}let a=await s.json();return console.log("API Response:",a),a}catch(e){throw console.error("Failed to create key:",e),e}},B=async(e,l,t)=>{try{console.log("Form Values in userUpdateUserCall:",l);let s={...l};null!==t&&(s.user_role=t),s=JSON.stringify(s);let a=await fetch("/user/update",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:s});if(!a.ok){let e=await a.text();throw h.ZP.error("Failed to create key: "+e,20),console.error("Error response from the server:",e),Error("Network response was not ok")}let r=await a.json();return console.log("API Response:",r),r}catch(e){throw console.error("Failed to create key:",e),e}},q=async(e,l)=>{try{let t=await fetch("/global/predict/spend/logs",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({data:l})});if(!t.ok){let e=await t.text();throw h.ZP.error(e,20),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to create key:",e),e}},K=async(e,l)=>{try{let t="/health/services?service=".concat(l);console.log("Checking Slack Budget Alerts service health");let s=await fetch(t,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!s.ok){let e=await s.text();throw h.ZP.error("Failed ".concat(l," service health check ")+e),Error(e)}let a=await s.json();return h.ZP.success("Test request to ".concat(l," made - check logs/alerts on ").concat(l," to verify")),a}catch(e){throw console.error("Failed to perform health check:",e),e}},V=async(e,l,t)=>{try{let l=await fetch("/get/config/callbacks",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw h.ZP.error(e,20),Error("Network response was not ok")}return await l.json()}catch(e){throw console.error("Failed to get callbacks:",e),e}},G=async(e,l)=>{try{let t=await fetch("/config/update",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...l})});if(!t.ok){let e=await t.text();throw h.ZP.error(e,20),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to set callbacks:",e),e}},W=async e=>{try{let l=await fetch("/health",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw h.ZP.error(e),Error("Network response was not ok")}return await l.json()}catch(e){throw console.error("Failed to call /health:",e),e}};var J=t(10384),Y=t(46453),H=t(2179),$=t(52273),X=t(26780),Q=t(15595),ee=t(6698),el=t(71801),et=t(42440),es=t(42308),ea=t(50670),er=t(81583),en=t(99129),eo=t(44839),ei=t(88707),ec=t(1861);let{Option:ed}=ea.default;var em=e=>{let{userID:l,team:t,userRole:s,accessToken:a,data:o,setData:i}=e,[c]=er.Z.useForm(),[d,m]=(0,n.useState)(!1),[u,x]=(0,n.useState)(null),[p,g]=(0,n.useState)(null),[f,y]=(0,n.useState)([]),[Z,w]=(0,n.useState)([]),b=()=>{m(!1),c.resetFields()},_=()=>{m(!1),x(null),c.resetFields()};(0,n.useEffect)(()=>{(async()=>{try{if(null===l||null===s)return;if(null!==a){let e=(await v(a,l,s)).data.map(e=>e.id);console.log("available_model_names:",e),y(e)}}catch(e){console.error("Error fetching user models:",e)}})()},[a,l,s]);let k=async e=>{try{h.ZP.info("Making API Call"),m(!0);let t=await j(a,l,e);console.log("key create Response:",t),i(e=>e?[...e,t]:[t]),x(t.key),g(t.soft_budget),h.ZP.success("API Key Created"),c.resetFields(),localStorage.removeItem("userData"+l)}catch(e){console.error("Error creating the key:",e)}};return(0,n.useEffect)(()=>{w(t&&t.models.length>0?t.models.includes("all-proxy-models")?f:t.models:f)},[t,f]),(0,r.jsxs)("div",{children:[(0,r.jsx)(H.Z,{className:"mx-auto",onClick:()=>m(!0),children:"+ Create New Key"}),(0,r.jsx)(en.Z,{title:"Create Key",visible:d,width:800,footer:null,onOk:b,onCancel:_,children:(0,r.jsxs)(er.Z,{form:c,onFinish:k,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(er.Z.Item,{label:"Key Name",name:"key_alias",rules:[{required:!0,message:"Please input a key name"}],help:"required",children:(0,r.jsx)($.Z,{placeholder:""})}),(0,r.jsx)(er.Z.Item,{label:"Team ID",name:"team_id",hidden:!0,initialValue:t?t.team_id:null,valuePropName:"team_id",className:"mt-8",children:(0,r.jsx)(eo.Z,{value:t?t.team_alias:"",disabled:!0})}),(0,r.jsx)(er.Z.Item,{label:"Models",name:"models",rules:[{required:!0,message:"Please select a model"}],help:"required",children:(0,r.jsxs)(ea.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},onChange:e=>{e.includes("all-team-models")&&c.setFieldsValue({models:["all-team-models"]})},children:[(0,r.jsx)(ed,{value:"all-team-models",children:"All Team Models"},"all-team-models"),Z.map(e=>(0,r.jsx)(ed,{value:e,children:e},e))]})}),(0,r.jsxs)(X.Z,{className:"mt-20 mb-8",children:[(0,r.jsx)(ee.Z,{children:(0,r.jsx)("b",{children:"Optional Settings"})}),(0,r.jsxs)(Q.Z,{children:[(0,r.jsx)(er.Z.Item,{className:"mt-8",label:"Max Budget (USD)",name:"max_budget",help:"Budget cannot exceed team max budget: $".concat((null==t?void 0:t.max_budget)!==null&&(null==t?void 0:t.max_budget)!==void 0?null==t?void 0:t.max_budget:"unlimited"),rules:[{validator:async(e,l)=>{if(l&&t&&null!==t.max_budget&&l>t.max_budget)throw Error("Budget cannot exceed team max budget: $".concat(t.max_budget))}}],children:(0,r.jsx)(ei.Z,{step:.01,precision:2,width:200})}),(0,r.jsx)(er.Z.Item,{className:"mt-8",label:"Reset Budget",name:"budget_duration",help:"Team Reset Budget: ".concat((null==t?void 0:t.budget_duration)!==null&&(null==t?void 0:t.budget_duration)!==void 0?null==t?void 0:t.budget_duration:"None"),children:(0,r.jsxs)(ea.default,{defaultValue:null,placeholder:"n/a",children:[(0,r.jsx)(ea.default.Option,{value:"24h",children:"daily"}),(0,r.jsx)(ea.default.Option,{value:"30d",children:"monthly"})]})}),(0,r.jsx)(er.Z.Item,{className:"mt-8",label:"Tokens per minute Limit (TPM)",name:"tpm_limit",help:"TPM cannot exceed team TPM limit: ".concat((null==t?void 0:t.tpm_limit)!==null&&(null==t?void 0:t.tpm_limit)!==void 0?null==t?void 0:t.tpm_limit:"unlimited"),rules:[{validator:async(e,l)=>{if(l&&t&&null!==t.tpm_limit&&l>t.tpm_limit)throw Error("TPM limit cannot exceed team TPM limit: ".concat(t.tpm_limit))}}],children:(0,r.jsx)(ei.Z,{step:1,width:400})}),(0,r.jsx)(er.Z.Item,{className:"mt-8",label:"Requests per minute Limit (RPM)",name:"rpm_limit",help:"RPM cannot exceed team RPM limit: ".concat((null==t?void 0:t.rpm_limit)!==null&&(null==t?void 0:t.rpm_limit)!==void 0?null==t?void 0:t.rpm_limit:"unlimited"),rules:[{validator:async(e,l)=>{if(l&&t&&null!==t.rpm_limit&&l>t.rpm_limit)throw Error("RPM limit cannot exceed team RPM limit: ".concat(t.rpm_limit))}}],children:(0,r.jsx)(ei.Z,{step:1,width:400})}),(0,r.jsx)(er.Z.Item,{label:"Expire Key (eg: 30s, 30h, 30d)",name:"duration",className:"mt-8",children:(0,r.jsx)($.Z,{placeholder:""})}),(0,r.jsx)(er.Z.Item,{label:"Metadata",name:"metadata",children:(0,r.jsx)(eo.Z.TextArea,{rows:4,placeholder:"Enter metadata as JSON"})})]})]})]}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ec.ZP,{htmlType:"submit",children:"Create Key"})})]})}),u&&(0,r.jsx)(en.Z,{visible:d,onOk:b,onCancel:_,footer:null,children:(0,r.jsxs)(Y.Z,{numItems:1,className:"gap-2 w-full",children:[(0,r.jsx)(et.Z,{children:"Save your Key"}),(0,r.jsx)(J.Z,{numColSpan:1,children:(0,r.jsxs)("p",{children:["Please save this secret key somewhere safe and accessible. For security reasons, ",(0,r.jsx)("b",{children:"you will not be able to view it again"})," ","through your LiteLLM account. If you lose this secret key, you will need to generate a new one."]})}),(0,r.jsx)(J.Z,{numColSpan:1,children:null!=u?(0,r.jsxs)("div",{children:[(0,r.jsx)(el.Z,{className:"mt-3",children:"API Key:"}),(0,r.jsx)("div",{style:{background:"#f8f8f8",padding:"10px",borderRadius:"5px",marginBottom:"10px"},children:(0,r.jsx)("pre",{style:{wordWrap:"break-word",whiteSpace:"normal"},children:u})}),(0,r.jsx)(es.CopyToClipboard,{text:u,onCopy:()=>{h.ZP.success("API Key copied to clipboard")},children:(0,r.jsx)(H.Z,{className:"mt-3",children:"Copy API Key"})})]}):(0,r.jsx)(el.Z,{children:"Key being created, this might take 30s"})})]})})]})},eh=t(9454),eu=t(98941),ex=t(33393),ep=t(5),ej=t(9853),eg=t(13810),ef=t(39290),ey=t(66952),eZ=t(61244),ew=t(10827),eb=t(3851),e_=t(2044),ek=t(64167),ev=t(74480),eS=t(7178),eA=t(95093),eN=t(27166);let{Option:eC}=ea.default;var eI=e=>{let{userID:l,userRole:t,accessToken:s,selectedTeam:a,data:o,setData:i,teams:c}=e,[d,m]=(0,n.useState)(!1),[u,x]=(0,n.useState)(!1),[p,j]=(0,n.useState)(null),[g,y]=n.useState(null),[Z,w]=(0,n.useState)(null),[b,_]=(0,n.useState)(null),[k,A]=(0,n.useState)(""),[N,C]=(0,n.useState)(!1),[I,P]=(0,n.useState)(null),[T,E]=(0,n.useState)([]),F=new Set,[O,M]=(0,n.useState)(F);(0,n.useEffect)(()=>{(async()=>{try{if(null===l)return;if(null!==s&&null!==t){let e=(await v(s,l,t)).data.map(e=>e.id);console.log("available_model_names:",e),E(e)}}catch(e){console.error("Error fetching user models:",e)}})()},[s,l,t]),(0,n.useEffect)(()=>{if(c){let e=new Set;c.forEach((l,t)=>{let s=l.team_id;e.add(s)}),M(e)}},[c]);let R=e=>{console.log("handleEditClick:",e),null==e.token&&null!==e.token_id&&(e.token=e.token_id),P(e),C(!0)},U=async e=>{if(null==s)return;let l=e.token;e.key=l,console.log("handleEditSubmit:",e);let t=await L(s,e);console.log("handleEditSubmit: newKeyValues",t),o&&i(o.map(e=>e.token===l?t:e)),h.ZP.success("Key updated successfully"),C(!1),P(null)},D=async e=>{try{if(null==s||null==e)return;console.log("accessToken: ".concat(s,"; token: ").concat(e.token));let l=await S(s,e.token);console.log("Response:",l),_(l);try{let e=await q(s,l);console.log("Response2:",e);let t=[...l,...e.response];_(t),A(e.predicted_spend),console.log("Combined Data:",t)}catch(e){console.error("There was an error fetching the predicted data",e)}}catch(e){console.error("There was an error fetching the data",e)}};(0,n.useEffect)(()=>{D(Z)},[Z]);let z=async e=>{console.log("handleDelete:",e),null==e.token&&null!==e.token_id&&(e.token=e.token_id),null!=o&&(j(e.token),localStorage.removeItem("userData"+l),x(!0))},B=async()=>{if(null!=p&&null!=o){try{await f(s,p);let e=o.filter(e=>e.token!==p);i(e)}catch(e){console.error("Error deleting the key:",e)}x(!1),j(null)}};if(null!=o)return console.log("RERENDER TRIGGERED"),(0,r.jsxs)("div",{children:[(0,r.jsxs)(eg.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh] mb-4 mt-2",children:[(0,r.jsxs)(ew.Z,{className:"mt-5 max-h-[300px] min-h-[300px]",children:[(0,r.jsx)(ek.Z,{children:(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(ev.Z,{children:"Key Alias"}),(0,r.jsx)(ev.Z,{children:"Secret Key"}),(0,r.jsx)(ev.Z,{children:"Spend (USD)"}),(0,r.jsx)(ev.Z,{children:"Budget (USD)"}),(0,r.jsx)(ev.Z,{children:"Models"}),(0,r.jsx)(ev.Z,{children:"TPM / RPM Limits"})]})}),(0,r.jsx)(eb.Z,{children:o.map(e=>{if(console.log(e),"litellm-dashboard"===e.team_id)return null;if(a){if(console.log("item team id: ".concat(e.team_id,", knownTeamIDs.has(item.team_id): ").concat(O.has(e.team_id),", selectedTeam id: ").concat(a.team_id)),(null!=a.team_id||null===e.team_id||O.has(e.team_id))&&e.team_id!=a.team_id)return null;console.log("item team id: ".concat(e.team_id,", is returned"))}return(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(e_.Z,{style:{maxWidth:"2px",whiteSpace:"pre-wrap",overflow:"hidden"},children:null!=e.key_alias?(0,r.jsx)(el.Z,{children:e.key_alias}):(0,r.jsx)(el.Z,{children:"Not Set"})}),(0,r.jsx)(e_.Z,{children:(0,r.jsx)(el.Z,{children:e.key_name})}),(0,r.jsx)(e_.Z,{children:(0,r.jsx)(el.Z,{children:(()=>{try{return parseFloat(e.spend).toFixed(4)}catch(l){return e.spend}})()})}),(0,r.jsx)(e_.Z,{children:null!=e.max_budget?(0,r.jsx)(el.Z,{children:e.max_budget}):(0,r.jsx)(el.Z,{children:"Unlimited"})}),(0,r.jsx)(e_.Z,{children:Array.isArray(e.models)?(0,r.jsx)("div",{style:{display:"flex",flexDirection:"column"},children:0===e.models.length?(0,r.jsx)(r.Fragment,{children:a&&a.models&&a.models.length>0?a.models.map((e,l)=>"all-proxy-models"===e?(0,r.jsx)(ep.Z,{size:"xs",className:"mb-1",color:"red",children:(0,r.jsx)(el.Z,{children:"All Proxy Models"})},l):"all-team-models"===e?(0,r.jsx)(ep.Z,{size:"xs",className:"mb-1",color:"red",children:(0,r.jsx)(el.Z,{children:"All Team Models"})},l):(0,r.jsx)(ep.Z,{size:"xs",className:"mb-1",color:"blue",children:(0,r.jsx)(el.Z,{children:e.length>30?"".concat(e.slice(0,30),"..."):e})},l)):(0,r.jsx)(ep.Z,{size:"xs",className:"mb-1",color:"blue",children:(0,r.jsx)(el.Z,{children:"all-proxy-models"})})}):e.models.map((e,l)=>"all-proxy-models"===e?(0,r.jsx)(ep.Z,{size:"xs",className:"mb-1",color:"red",children:(0,r.jsx)(el.Z,{children:"All Proxy Models"})},l):"all-team-models"===e?(0,r.jsx)(ep.Z,{size:"xs",className:"mb-1",color:"red",children:(0,r.jsx)(el.Z,{children:"All Team Models"})},l):(0,r.jsx)(ep.Z,{size:"xs",className:"mb-1",color:"blue",children:(0,r.jsx)(el.Z,{children:e.length>30?"".concat(e.slice(0,30),"..."):e})},l))}):null}),(0,r.jsx)(e_.Z,{children:(0,r.jsxs)(el.Z,{children:["TPM: ",e.tpm_limit?e.tpm_limit:"Unlimited"," ",(0,r.jsx)("br",{})," RPM:"," ",e.rpm_limit?e.rpm_limit:"Unlimited"]})}),(0,r.jsxs)(e_.Z,{children:[(0,r.jsx)(eZ.Z,{onClick:()=>{w(e),y(e.id)},icon:eh.Z,size:"sm"}),(0,r.jsx)(ef.Z,{open:null!==g,onClose:()=>{y(null),w(null)},children:(0,r.jsx)(ey.Z,{children:Z&&(0,r.jsxs)(r.Fragment,{children:[(0,r.jsxs)("div",{className:"grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3",children:[(0,r.jsxs)(eg.Z,{children:[(0,r.jsx)("p",{className:"text-tremor-default font-medium text-tremor-content dark:text-dark-tremor-content",children:"Spend"}),(0,r.jsx)("div",{className:"mt-2 flex items-baseline space-x-2.5",children:(0,r.jsx)("p",{className:"text-tremor font-semibold text-tremor-content-strong dark:text-dark-tremor-content-strong",children:(()=>{try{return parseFloat(Z.spend).toFixed(4)}catch(e){return Z.spend}})()})})]}),(0,r.jsxs)(eg.Z,{children:[(0,r.jsx)("p",{className:"text-tremor-default font-medium text-tremor-content dark:text-dark-tremor-content",children:"Budget"}),(0,r.jsx)("div",{className:"mt-2 flex items-baseline space-x-2.5",children:(0,r.jsx)("p",{className:"text-tremor font-semibold text-tremor-content-strong dark:text-dark-tremor-content-strong",children:null!=Z.max_budget?(0,r.jsx)(r.Fragment,{children:Z.max_budget}):(0,r.jsx)(r.Fragment,{children:"Unlimited"})})})]},e.name),(0,r.jsxs)(eg.Z,{children:[(0,r.jsx)("p",{className:"text-tremor-default font-medium text-tremor-content dark:text-dark-tremor-content",children:"Expires"}),(0,r.jsx)("div",{className:"mt-2 flex items-baseline space-x-2.5",children:(0,r.jsx)("p",{className:"text-tremor-default font-small text-tremor-content-strong dark:text-dark-tremor-content-strong",children:null!=Z.expires?(0,r.jsx)(r.Fragment,{children:new Date(Z.expires).toLocaleString(void 0,{day:"numeric",month:"long",year:"numeric",hour:"numeric",minute:"numeric",second:"numeric"})}):(0,r.jsx)(r.Fragment,{children:"Never"})})})]},e.name)]}),(0,r.jsx)(eg.Z,{className:"mt-6 mb-6",children:b&&(0,r.jsx)(ej.Z,{className:"mt-6",data:b,colors:["blue","amber"],index:"date",categories:["spend","predicted_spend"],yAxisWidth:80})}),(0,r.jsx)(et.Z,{children:"Metadata"}),(0,r.jsx)(el.Z,{children:JSON.stringify(Z.metadata)}),(0,r.jsx)(H.Z,{variant:"light",className:"mx-auto flex items-center",onClick:()=>{y(null),w(null)},children:"Close"})]})})}),(0,r.jsx)(eZ.Z,{icon:eu.Z,size:"sm",onClick:()=>R(e)}),(0,r.jsx)(eZ.Z,{onClick:()=>z(e),icon:ex.Z,size:"sm"})]})]},e.token)})})]}),u&&(0,r.jsx)("div",{className:"fixed z-10 inset-0 overflow-y-auto",children:(0,r.jsxs)("div",{className:"flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0",children:[(0,r.jsx)("div",{className:"fixed inset-0 transition-opacity","aria-hidden":"true",children:(0,r.jsx)("div",{className:"absolute inset-0 bg-gray-500 opacity-75"})}),(0,r.jsx)("span",{className:"hidden sm:inline-block sm:align-middle sm:h-screen","aria-hidden":"true",children:"​"}),(0,r.jsxs)("div",{className:"inline-block align-bottom bg-white rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full",children:[(0,r.jsx)("div",{className:"bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4",children:(0,r.jsx)("div",{className:"sm:flex sm:items-start",children:(0,r.jsxs)("div",{className:"mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left",children:[(0,r.jsx)("h3",{className:"text-lg leading-6 font-medium text-gray-900",children:"Delete Key"}),(0,r.jsx)("div",{className:"mt-2",children:(0,r.jsx)("p",{className:"text-sm text-gray-500",children:"Are you sure you want to delete this key ?"})})]})})}),(0,r.jsxs)("div",{className:"bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse",children:[(0,r.jsx)(H.Z,{onClick:B,color:"red",className:"ml-2",children:"Delete"}),(0,r.jsx)(H.Z,{onClick:()=>{x(!1),j(null)},children:"Cancel"})]})]})]})})]}),I&&(0,r.jsx)(e=>{let{visible:l,onCancel:t,token:s,onSubmit:o}=e,[i]=er.Z.useForm(),[d,m]=(0,n.useState)(a),[h,u]=(0,n.useState)([]),[x,p]=(0,n.useState)(!1);return(0,r.jsx)(en.Z,{title:"Edit Key",visible:l,width:800,footer:null,onOk:()=>{i.validateFields().then(e=>{i.resetFields()}).catch(e=>{console.error("Validation failed:",e)})},onCancel:t,children:(0,r.jsxs)(er.Z,{form:i,onFinish:U,initialValues:s,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(er.Z.Item,{label:"Key Name",name:"key_alias",rules:[{required:!0,message:"Please input a key name"}],help:"required",children:(0,r.jsx)(eo.Z,{})}),(0,r.jsx)(er.Z.Item,{label:"Models",name:"models",rules:[{validator:(e,l)=>{let t=l.filter(e=>!d.models.includes(e)&&"all-team-models"!==e&&"all-proxy-models"!==e&&!d.models.includes("all-proxy-models"));return(console.log("errorModels: ".concat(t)),t.length>0)?Promise.reject("Some models are not part of the new team's models - ".concat(t,"Team models: ").concat(d.models)):Promise.resolve()}}],children:(0,r.jsxs)(ea.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:[(0,r.jsx)(eC,{value:"all-team-models",children:"All Team Models"},"all-team-models"),d&&d.models?d.models.includes("all-proxy-models")?T.filter(e=>"all-proxy-models"!==e).map(e=>(0,r.jsx)(eC,{value:e,children:e},e)):d.models.map(e=>(0,r.jsx)(eC,{value:e,children:e},e)):T.map(e=>(0,r.jsx)(eC,{value:e,children:e},e))]})}),(0,r.jsx)(er.Z.Item,{className:"mt-8",label:"Max Budget (USD)",name:"max_budget",help:"Budget cannot exceed team max budget: ".concat((null==d?void 0:d.max_budget)!==null&&(null==d?void 0:d.max_budget)!==void 0?null==d?void 0:d.max_budget:"unlimited"),rules:[{validator:async(e,l)=>{if(l&&d&&null!==d.max_budget&&l>d.max_budget)throw console.log("keyTeam.max_budget: ".concat(d.max_budget)),Error("Budget cannot exceed team max budget: $".concat(d.max_budget))}}],children:(0,r.jsx)(ei.Z,{step:.01,precision:2,width:200})}),(0,r.jsx)(er.Z.Item,{label:"token",name:"token",hidden:!0}),(0,r.jsx)(er.Z.Item,{label:"Team",name:"team_id",help:"the team this key belongs to",children:(0,r.jsx)(eA.Z,{value:s.team_alias,children:null==c?void 0:c.map((e,l)=>(0,r.jsx)(eN.Z,{value:e.team_id,onClick:()=>m(e),children:e.team_alias},l))})})]}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ec.ZP,{htmlType:"submit",children:"Edit Key"})})]})})},{visible:N,onCancel:()=>{C(!1),P(null)},token:I,onSubmit:U})]})},eP=t(76032),eT=t(35152),eE=e=>{let{userID:l,userRole:t,accessToken:s,userSpend:a,selectedTeam:o}=e;console.log("userSpend: ".concat(a));let[i,c]=(0,n.useState)(null!==a?a:0),[d,m]=(0,n.useState)(0),[h,u]=(0,n.useState)([]);(0,n.useEffect)(()=>{let e=async()=>{if(s&&l&&t&&"Admin"===t&&null==a)try{let e=await b(s);e&&(e.spend?c(e.spend):c(0),e.max_budget?m(e.max_budget):m(0))}catch(e){console.error("Error fetching global spend data:",e)}};(async()=>{try{if(null===l||null===t)return;if(null!==s){let e=(await v(s,l,t)).data.map(e=>e.id);console.log("available_model_names:",e),u(e)}}catch(e){console.error("Error fetching user models:",e)}})(),e()},[t,s,l]),(0,n.useEffect)(()=>{null!==a&&c(a)},[a]);let x=[];o&&o.models&&(x=o.models),x&&x.includes("all-proxy-models")?(console.log("user models:",h),x=h):x&&x.includes("all-team-models")?x=o.models:x&&0===x.length&&(x=h);let p=void 0!==i?i.toFixed(4):null;return console.log("spend in view user spend: ".concat(i)),(0,r.jsxs)("div",{className:"flex items-center",children:[(0,r.jsxs)("div",{children:[(0,r.jsxs)("p",{className:"text-tremor-default text-tremor-content dark:text-dark-tremor-content",children:["Total Spend"," "]}),(0,r.jsxs)("p",{className:"text-2xl text-tremor-content-strong dark:text-dark-tremor-content-strong font-semibold",children:["$",p]})]}),(0,r.jsx)("div",{className:"ml-auto",children:(0,r.jsxs)(X.Z,{children:[(0,r.jsx)(ee.Z,{children:(0,r.jsx)(el.Z,{children:"Team Models"})}),(0,r.jsx)(Q.Z,{className:"absolute right-0 z-10 bg-white p-2 shadow-lg max-w-xs",children:(0,r.jsx)(eP.Z,{children:x.map(e=>(0,r.jsx)(eT.Z,{children:(0,r.jsx)(el.Z,{children:e})},e))})})]})})]})},eF=e=>{let{userID:l,userRole:t,selectedTeam:s,accessToken:a}=e,[o,i]=(0,n.useState)([]);(0,n.useEffect)(()=>{(async()=>{try{if(null===l||null===t)return;if(null!==a){let e=(await v(a,l,t)).data.map(e=>e.id);console.log("available_model_names:",e),i(e)}}catch(e){console.error("Error fetching user models:",e)}})()},[a,l,t]);let c=[];return s&&s.models&&(c=s.models),c&&c.includes("all-proxy-models")&&(console.log("user models:",o),c=o),(0,r.jsx)(r.Fragment,{children:(0,r.jsx)("div",{className:"mb-5",children:(0,r.jsx)("p",{className:"text-3xl text-tremor-content-strong dark:text-dark-tremor-content-strong font-semibold",children:null==s?void 0:s.team_alias})})})},eO=e=>{let l,{teams:t,setSelectedTeam:s,userRole:a}=e,o={models:[],team_id:null,team_alias:"Default Team"},[i,c]=(0,n.useState)(o);return(l="App User"===a?t:t?[...t,o]:[o],"App User"===a)?null:(0,r.jsxs)("div",{className:"mt-5 mb-5",children:[(0,r.jsx)(et.Z,{children:"Select Team"}),(0,r.jsx)(el.Z,{children:"If you belong to multiple teams, this setting controls which team is used by default when creating new API Keys."}),(0,r.jsxs)(el.Z,{className:"mt-3 mb-3",children:[(0,r.jsx)("b",{children:"Default Team:"})," If no team_id is set for a key, it will be grouped under here."]}),l&&l.length>0?(0,r.jsx)(eA.Z,{defaultValue:"0",children:l.map((e,l)=>(0,r.jsx)(eN.Z,{value:String(l),onClick:()=>s(e),children:e.team_alias},l))}):(0,r.jsxs)(el.Z,{children:["No team created. ",(0,r.jsx)("b",{children:"Defaulting to personal account."})]})]})},eM=t(37963),eR=t(36083);console.log("isLocal:",!1);var eL=e=>{let{userID:l,userRole:t,teams:s,keys:a,setUserRole:i,userEmail:c,setUserEmail:d,setTeams:m,setKeys:h}=e,[u,x]=(0,n.useState)(null),p=(0,o.useSearchParams)();p.get("viewSpend"),(0,o.useRouter)();let j=p.get("token"),[g,f]=(0,n.useState)(null),[y,w]=(0,n.useState)(null),[_,k]=(0,n.useState)([]),S={models:[],team_alias:"Default Team",team_id:null},[A,N]=(0,n.useState)(s?s[0]:S);if(window.addEventListener("beforeunload",function(){sessionStorage.clear()}),(0,n.useEffect)(()=>{if(j){let e=(0,eM.o)(j);if(e){if(console.log("Decoded token:",e),console.log("Decoded key:",e.key),f(e.key),e.user_role){let l=function(e){if(!e)return"Undefined Role";switch(console.log("Received user role: ".concat(e)),e.toLowerCase()){case"app_owner":case"demo_app_owner":return"App Owner";case"app_admin":case"proxy_admin":return"Admin";case"proxy_admin_viewer":return"Admin Viewer";case"app_user":return"App User";default:return"Unknown Role"}}(e.user_role);console.log("Decoded user_role:",l),i(l)}else console.log("User role not defined");e.user_email?d(e.user_email):console.log("User Email is not set ".concat(e))}}if(l&&g&&t&&!a&&!u){let e=sessionStorage.getItem("userModels"+l);e?k(JSON.parse(e)):(async()=>{try{let e=await Z(g,l,t,!1,null,null);if(console.log("received teams in user dashboard: ".concat(Object.keys(e),"; team values: ").concat(Object.entries(e.teams))),"Admin"==t){let e=await b(g);x(e),console.log("globalSpend:",e)}else x(e.user_info);h(e.keys),m(e.teams);let s=[...e.teams];s.length>0?(console.log("response['teams']: ".concat(s)),N(s[0])):N(S),sessionStorage.setItem("userData"+l,JSON.stringify(e.keys)),sessionStorage.setItem("userSpendData"+l,JSON.stringify(e.user_info));let a=(await v(g,l,t)).data.map(e=>e.id);console.log("available_model_names:",a),k(a),console.log("userModels:",_),sessionStorage.setItem("userModels"+l,JSON.stringify(a))}catch(e){console.error("There was an error fetching the data",e)}})()}},[l,j,g,a,t]),(0,n.useEffect)(()=>{if(null!==a&&null!=A){let e=0;for(let l of a)A.hasOwnProperty("team_id")&&null!==l.team_id&&l.team_id===A.team_id&&(e+=l.spend);w(e)}else if(null!==a){let e=0;for(let l of a)e+=l.spend;w(e)}},[A]),null==l||null==j){let e="/sso/key/generate";return console.log("Full URL:",e),window.location.href=e,null}if(null==g)return null;if(null==t&&i("App Owner"),t&&"Admin Viewer"==t){let{Title:e,Paragraph:l}=eR.default;return(0,r.jsxs)("div",{children:[(0,r.jsx)(e,{level:1,children:"Access Denied"}),(0,r.jsx)(l,{children:"Ask your proxy admin for access to create keys"})]})}return console.log("inside user dashboard, selected team",A),console.log("teamSpend: ".concat(y)),(0,r.jsx)("div",{className:"w-full mx-4",children:(0,r.jsx)(Y.Z,{numItems:1,className:"gap-2 p-8 h-[75vh] w-full mt-2",children:(0,r.jsxs)(J.Z,{numColSpan:1,children:[(0,r.jsx)(eF,{userID:l,userRole:t,selectedTeam:A||null,accessToken:g}),(0,r.jsx)(eE,{userID:l,userRole:t,accessToken:g,userSpend:y,selectedTeam:A||null}),(0,r.jsx)(eI,{userID:l,userRole:t,accessToken:g,selectedTeam:A||null,data:a,setData:h,teams:s}),(0,r.jsx)(em,{userID:l,team:A||null,userRole:t,accessToken:g,data:a,setData:h},A?A.team_id:null),(0,r.jsx)(eO,{teams:s,setSelectedTeam:N,userRole:t})]})})})},eU=t(92836),eD=t(26734),ez=t(41608),eB=t(32126),eq=t(23682),eK=t(47047),eV=t(76628),eG=t(38302),eW=t(28683),eJ=t(1460),eY=t(78578),eH=t(63954),e$=e=>{let{modelID:l,accessToken:t}=e,[s,a]=(0,n.useState)(!1),o=async()=>{try{h.ZP.info("Making API Call"),a(!0);let e=await p(t,l);console.log("model delete Response:",e),h.ZP.success("Model ".concat(l," deleted successfully")),a(!1)}catch(e){console.error("Error deleting the model:",e)}};return(0,r.jsxs)("div",{children:[(0,r.jsx)(eZ.Z,{onClick:()=>a(!0),icon:ex.Z,size:"sm"}),(0,r.jsx)(en.Z,{open:s,onOk:o,okType:"danger",onCancel:()=>a(!1),children:(0,r.jsxs)(Y.Z,{numItems:1,className:"gap-2 w-full",children:[(0,r.jsx)(et.Z,{children:"Delete Model"}),(0,r.jsx)(J.Z,{numColSpan:1,children:(0,r.jsx)("p",{children:"Are you sure you want to delete this model? This action is irreversible."})}),(0,r.jsx)(J.Z,{numColSpan:1,children:(0,r.jsxs)("p",{children:["Model ID: ",(0,r.jsx)("b",{children:l})]})})]})})]})},eX=t(97766),eQ=t(46495);let{Title:e0,Link:e1}=eR.default;(s=a||(a={})).OpenAI="OpenAI",s.Azure="Azure",s.Anthropic="Anthropic",s.Google_AI_Studio="Gemini (Google AI Studio)",s.Bedrock="Amazon Bedrock",s.OpenAI_Compatible="OpenAI-Compatible Endpoints (Groq, Together AI, Mistral AI, etc.)",s.Vertex_AI="Vertex AI (Anthropic, Gemini, etc.)";let e2={OpenAI:"openai",Azure:"azure",Anthropic:"anthropic",Google_AI_Studio:"gemini",Bedrock:"bedrock",OpenAI_Compatible:"openai",Vertex_AI:"vertex_ai"},e4=async(e,l,t)=>{try{let s=Array.isArray(e.model)?e.model:[e.model];console.log("received deployments: ".concat(s)),console.log("received type of deployments: ".concat(typeof s)),s.forEach(async t=>{console.log("litellm_model: ".concat(t));let s={},a={};s.model=t;let r="";for(let[l,t]of Object.entries(e))if(""!==t){if("model_name"==l)r+=t;else if("custom_llm_provider"==l)continue;else if("model"==l)continue;else if("base_model"===l)a[l]=t;else if("litellm_extra_params"==l){console.log("litellm_extra_params:",t);let e={};if(t&&void 0!=t){try{e=JSON.parse(t)}catch(e){throw h.ZP.error("Failed to parse LiteLLM Extra Params: "+e,20),Error("Failed to parse litellm_extra_params: "+e)}for(let[l,t]of Object.entries(e))s[l]=t}}else s[l]=t}let n={model_name:r,litellm_params:s,model_info:a},o=await x(l,n);console.log("response for model create call: ".concat(o.data))}),t.resetFields()}catch(e){h.ZP.error("Failed to create model: "+e,20)}};var e8=e=>{var l,t,s;let{accessToken:o,token:i,userRole:c,userID:d,modelData:m={data:[]},setModelData:x}=e,[p,j]=(0,n.useState)([]),[g]=er.Z.useForm(),[f,y]=(0,n.useState)(null),[Z,w]=(0,n.useState)(""),[b,k]=(0,n.useState)([]),v=Object.values(a).filter(e=>isNaN(Number(e))),[S,A]=(0,n.useState)("OpenAI"),[N,C]=(0,n.useState)(""),[I,P]=(0,n.useState)(!1),[T,E]=(0,n.useState)(null),[F,M]=(0,n.useState)([]),[R,L]=(0,n.useState)(null),U=e=>{E(e),P(!0)},z=async e=>{if(console.log("handleEditSubmit:",e),null==o)return;let l={},t=null;for(let[s,a]of Object.entries(e))"model_id"!==s?l[s]=a:t=a;let s={litellm_params:l,model_info:{id:t}};console.log("handleEditSubmit payload:",s),await D(o,s),h.ZP.success("Model updated successfully, restart server to see updates"),P(!1),E(null)},B=()=>{w(new Date().toLocaleString())};if((0,n.useEffect)(()=>{if(!o||!i||!c||!d)return;let e=async()=>{try{let e=await _(o,d,c);console.log("Model data response:",e.data),x(e);let l=new Set;for(let t=0;t{let e=await u();console.log("received model cost map data: ".concat(Object.keys(e))),y(e)};null==f&&l(),B()},[o,i,c,d,f,Z]),!m||!o||!i||!c||!d)return(0,r.jsx)("div",{children:"Loading..."});let q=[];for(let e=0;e(console.log("GET PROVIDER CALLED! - ".concat(f)),null!=f&&"object"==typeof f&&e in f)?f[e].litellm_provider:"openai";if(a){let e=a.split("/"),l=e[0];n=1===e.length?h(a):l}else n="openai";r&&(o=null==r?void 0:r.input_cost_per_token,i=null==r?void 0:r.output_cost_per_token,c=null==r?void 0:r.max_tokens),(null==s?void 0:s.litellm_params)&&(d=Object.fromEntries(Object.entries(null==s?void 0:s.litellm_params).filter(e=>{let[l]=e;return"model"!==l&&"api_base"!==l}))),m.data[e].provider=n,m.data[e].input_cost=o,m.data[e].output_cost=i,m.data[e].max_tokens=c,m.data[e].api_base=null==s?void 0:null===(t=s.litellm_params)||void 0===t?void 0:t.api_base,m.data[e].cleanedLitellmParams=d,q.push(s.model_name),console.log(m.data[e])}if(c&&"Admin Viewer"==c){let{Title:e,Paragraph:l}=eR.default;return(0,r.jsxs)("div",{children:[(0,r.jsx)(e,{level:1,children:"Access Denied"}),(0,r.jsx)(l,{children:"Ask your proxy admin for access to view all models"})]})}let K=e=>{console.log("received provider string: ".concat(e));let l=Object.keys(a).find(l=>a[l]===e);if(l){let e=e2[l];console.log("mappingResult: ".concat(e));let t=[];"object"==typeof f&&Object.entries(f).forEach(l=>{let[s,a]=l;null!==a&&"object"==typeof a&&"litellm_provider"in a&&(a.litellm_provider===e||a.litellm_provider.includes(e))&&t.push(s)}),k(t),console.log("providerModels: ".concat(b))}},V=async()=>{try{h.ZP.info("Running health check..."),C("");let e=await W(o);C(e)}catch(e){console.error("Error running health check:",e),C("Error running health check")}};return console.log("selectedProvider: ".concat(S)),console.log("providerModels.length: ".concat(b.length)),(0,r.jsx)("div",{style:{width:"100%",height:"100%"},children:(0,r.jsxs)(eD.Z,{className:"gap-2 p-8 h-[75vh] w-full mt-2",children:[(0,r.jsxs)(ez.Z,{className:"flex justify-between mt-2 w-full items-center",children:[(0,r.jsxs)("div",{className:"flex",children:[(0,r.jsx)(eU.Z,{children:"All Models"}),(0,r.jsx)(eU.Z,{children:"Add Model"}),(0,r.jsx)(eU.Z,{children:(0,r.jsx)("pre",{children:"/health Models"})})]}),(0,r.jsxs)("div",{className:"flex items-center space-x-2",children:[Z&&(0,r.jsxs)(el.Z,{children:["Last Refreshed: ",Z]}),(0,r.jsx)(eZ.Z,{icon:eH.Z,variant:"shadow",size:"xs",className:"self-center",onClick:B})]})]}),(0,r.jsxs)(eq.Z,{children:[(0,r.jsxs)(eB.Z,{children:[(0,r.jsxs)(Y.Z,{children:[(0,r.jsxs)("div",{className:"flex items-center",children:[(0,r.jsx)(el.Z,{children:"Filter by Public Model Name"}),(0,r.jsxs)(eA.Z,{className:"mb-4 mt-2 ml-2 w-50",defaultValue:"all",onValueChange:e=>L("all"===e?"all":e),children:[(0,r.jsx)(eN.Z,{value:"all",children:"All Models"}),F.map((e,l)=>(0,r.jsx)(eN.Z,{value:e,onClick:()=>L(e),children:e},l))]})]}),(0,r.jsx)(eg.Z,{children:(0,r.jsxs)(ew.Z,{className:"mt-5",children:[(0,r.jsx)(ek.Z,{children:(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(ev.Z,{children:"Public Model Name "}),(0,r.jsx)(ev.Z,{children:"Provider"}),"Admin"===c&&(0,r.jsx)(ev.Z,{children:"API Base"}),(0,r.jsx)(ev.Z,{children:"Extra litellm Params"}),(0,r.jsx)(ev.Z,{children:"Input Price per token ($)"}),(0,r.jsx)(ev.Z,{children:"Output Price per token ($)"}),(0,r.jsx)(ev.Z,{children:"Max Tokens"})]})}),(0,r.jsx)(eb.Z,{children:m.data.filter(e=>"all"===R||e.model_name===R||null==R||""===R).map((e,l)=>(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(e_.Z,{children:(0,r.jsx)(el.Z,{children:e.model_name})}),(0,r.jsx)(e_.Z,{children:e.provider}),"Admin"===c&&(0,r.jsx)(e_.Z,{children:e.api_base}),(0,r.jsx)(e_.Z,{children:(0,r.jsxs)(X.Z,{children:[(0,r.jsx)(ee.Z,{children:(0,r.jsx)(el.Z,{children:"Litellm params"})}),(0,r.jsx)(Q.Z,{children:(0,r.jsx)("pre",{children:JSON.stringify(e.cleanedLitellmParams,null,2)})})]})}),(0,r.jsx)(e_.Z,{children:e.input_cost}),(0,r.jsx)(e_.Z,{children:e.output_cost}),(0,r.jsx)(e_.Z,{children:e.max_tokens}),(0,r.jsxs)(e_.Z,{children:[(0,r.jsx)(eZ.Z,{icon:eu.Z,size:"sm",onClick:()=>U(e)}),(0,r.jsx)(e$,{modelID:e.model_info.id,accessToken:o})]})]},l))})]})})]}),(0,r.jsx)(e=>{let{visible:l,onCancel:t,model:s,onSubmit:a}=e,[n]=er.Z.useForm(),o={},i="",c="";if(s){o=s.litellm_params,i=s.model_name;let e=s.model_info;e&&(c=e.id,console.log("model_id: ".concat(c)),o.model_id=c)}return(0,r.jsx)(en.Z,{title:"Edit Model "+i,visible:l,width:800,footer:null,onOk:()=>{n.validateFields().then(e=>{a(e),n.resetFields()}).catch(e=>{console.error("Validation failed:",e)})},onCancel:t,children:(0,r.jsxs)(er.Z,{form:n,onFinish:z,initialValues:o,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(er.Z.Item,{className:"mt-8",label:"api_base",name:"api_base",children:(0,r.jsx)($.Z,{})}),(0,r.jsx)(er.Z.Item,{label:"tpm",name:"tpm",tooltip:"int (optional) - Tokens limit for this deployment: in tokens per minute (tpm). Find this information on your model/providers website",children:(0,r.jsx)(ei.Z,{min:0,step:1})}),(0,r.jsx)(er.Z.Item,{label:"rpm",name:"rpm",tooltip:"int (optional) - Rate limit for this deployment: in requests per minute (rpm). Find this information on your model/providers website",children:(0,r.jsx)(ei.Z,{min:0,step:1})}),(0,r.jsx)(er.Z.Item,{label:"max_retries",name:"max_retries",children:(0,r.jsx)(ei.Z,{min:0,step:1})}),(0,r.jsx)(er.Z.Item,{label:"timeout",name:"timeout",tooltip:"int (optional) - Timeout in seconds for LLM requests (Defaults to 600 seconds)",children:(0,r.jsx)(ei.Z,{min:0,step:1})}),(0,r.jsx)(er.Z.Item,{label:"stream_timeout",name:"stream_timeout",tooltip:"int (optional) - Timeout for stream requests (seconds)",children:(0,r.jsx)(ei.Z,{min:0,step:1})}),(0,r.jsx)(er.Z.Item,{label:"model_id",name:"model_id",hidden:!0})]}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ec.ZP,{htmlType:"submit",children:"Save"})})]})})},{visible:I,onCancel:()=>{P(!1),E(null)},model:T,onSubmit:z})]}),(0,r.jsxs)(eB.Z,{className:"h-full",children:[(0,r.jsx)(e0,{level:2,children:"Add new model"}),(0,r.jsx)(eg.Z,{children:(0,r.jsxs)(er.Z,{form:g,onFinish:()=>{g.validateFields().then(e=>{e4(e,o,g)}).catch(e=>{console.error("Validation failed:",e)})},labelCol:{span:10},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(er.Z.Item,{rules:[{required:!0,message:"Required"}],label:"Provider:",name:"custom_llm_provider",tooltip:"E.g. OpenAI, Azure OpenAI, Anthropic, Bedrock, etc.",labelCol:{span:10},labelAlign:"left",children:(0,r.jsx)(eA.Z,{value:S.toString(),children:v.map((e,l)=>(0,r.jsx)(eN.Z,{value:e,onClick:()=>{K(e),A(e)},children:e},l))})}),(0,r.jsx)(er.Z.Item,{rules:[{required:!0,message:"Required"}],label:"Public Model Name",name:"model_name",tooltip:"Model name your users will pass in. Also used for load-balancing, LiteLLM will load balance between all models with this public name.",className:"mb-0",children:(0,r.jsx)($.Z,{placeholder:"Vertex AI (Anthropic, Gemini, etc.)"===(s=S.toString())?"gemini-pro":"Anthropic"==s?"claude-3-opus":"Amazon Bedrock"==s?"claude-3-opus":"Gemini (Google AI Studio)"==s?"gemini-pro":"gpt-3.5-turbo"})}),(0,r.jsxs)(eG.Z,{children:[(0,r.jsx)(eW.Z,{span:10}),(0,r.jsx)(eW.Z,{span:10,children:(0,r.jsx)(el.Z,{className:"mb-3 mt-1",children:"Model name your users will pass in."})})]}),(0,r.jsx)(er.Z.Item,{rules:[{required:!0,message:"Required"}],label:"LiteLLM Model Name(s)",name:"model",tooltip:"Actual model name used for making litellm.completion() call.",className:"mb-0",children:"Azure"===S?(0,r.jsx)($.Z,{placeholder:"Enter model name"}):b.length>0?(0,r.jsx)(eK.Z,{value:b,children:b.map((e,l)=>(0,r.jsx)(eV.Z,{value:e,children:e},l))}):(0,r.jsx)($.Z,{placeholder:"gpt-3.5-turbo-0125"})}),(0,r.jsxs)(eG.Z,{children:[(0,r.jsx)(eW.Z,{span:10}),(0,r.jsx)(eW.Z,{span:10,children:(0,r.jsxs)(el.Z,{className:"mb-3 mt-1",children:["Actual model name used for making ",(0,r.jsx)(e1,{href:"https://docs.litellm.ai/docs/providers",target:"_blank",children:"litellm.completion() call"}),". We'll ",(0,r.jsx)(e1,{href:"https://docs.litellm.ai/docs/proxy/reliability#step-1---set-deployments-on-config",target:"_blank",children:"loadbalance"})," models with the same 'public name'"]})})]}),"Amazon Bedrock"!=S&&"Vertex AI (Anthropic, Gemini, etc.)"!=S&&(0,r.jsx)(er.Z.Item,{rules:[{required:!0,message:"Required"}],label:"API Key",name:"api_key",children:(0,r.jsx)($.Z,{placeholder:"sk-",type:"password"})}),"OpenAI"==S&&(0,r.jsx)(er.Z.Item,{label:"Organization ID",name:"organization_id",children:(0,r.jsx)($.Z,{placeholder:"[OPTIONAL] my-unique-org"})}),"Vertex AI (Anthropic, Gemini, etc.)"==S&&(0,r.jsx)(er.Z.Item,{rules:[{required:!0,message:"Required"}],label:"Vertex Project",name:"vertex_project",children:(0,r.jsx)($.Z,{placeholder:"adroit-cadet-1234.."})}),"Vertex AI (Anthropic, Gemini, etc.)"==S&&(0,r.jsx)(er.Z.Item,{rules:[{required:!0,message:"Required"}],label:"Vertex Location",name:"vertex_location",children:(0,r.jsx)($.Z,{placeholder:"us-east-1"})}),"Vertex AI (Anthropic, Gemini, etc.)"==S&&(0,r.jsx)(er.Z.Item,{rules:[{required:!0,message:"Required"}],label:"Vertex Credentials",name:"vertex_credentials",className:"mb-0",children:(0,r.jsx)(eQ.Z,{name:"file",accept:".json",beforeUpload:e=>{if("application/json"===e.type){let l=new FileReader;l.onload=e=>{if(e.target){let l=e.target.result;g.setFieldsValue({vertex_credentials:l})}},l.readAsText(e)}return!1},onChange(e){"uploading"!==e.file.status&&console.log(e.file,e.fileList),"done"===e.file.status?h.ZP.success("".concat(e.file.name," file uploaded successfully")):"error"===e.file.status&&h.ZP.error("".concat(e.file.name," file upload failed."))},children:(0,r.jsx)(ec.ZP,{icon:(0,r.jsx)(eX.Z,{}),children:"Click to Upload"})})}),"Vertex AI (Anthropic, Gemini, etc.)"==S&&(0,r.jsxs)(eG.Z,{children:[(0,r.jsx)(eW.Z,{span:10}),(0,r.jsx)(eW.Z,{span:10,children:(0,r.jsx)(el.Z,{className:"mb-3 mt-1",children:"Give litellm a gcp service account(.json file), so it can make the relevant calls"})})]}),("Azure"==S||"OpenAI-Compatible Endpoints (Groq, Together AI, Mistral AI, etc.)"==S)&&(0,r.jsx)(er.Z.Item,{rules:[{required:!0,message:"Required"}],label:"API Base",name:"api_base",children:(0,r.jsx)($.Z,{placeholder:"https://..."})}),"Azure"==S&&(0,r.jsx)(er.Z.Item,{rules:[{required:!0,message:"Required"}],label:"API Version",name:"api_version",children:(0,r.jsx)($.Z,{placeholder:"2023-07-01-preview"})}),"Azure"==S&&(0,r.jsxs)(er.Z.Item,{label:"Base Model",name:"base_model",children:[(0,r.jsx)($.Z,{placeholder:"azure/gpt-3.5-turbo"}),(0,r.jsxs)(el.Z,{children:["The actual model your azure deployment uses. Used for accurate cost tracking. Select name from ",(0,r.jsx)(e1,{href:"https://github.com/BerriAI/litellm/blob/main/model_prices_and_context_window.json",target:"_blank",children:"here"})]})]}),"Amazon Bedrock"==S&&(0,r.jsx)(er.Z.Item,{rules:[{required:!0,message:"Required"}],label:"AWS Access Key ID",name:"aws_access_key_id",tooltip:"You can provide the raw key or the environment variable (e.g. `os.environ/MY_SECRET_KEY`).",children:(0,r.jsx)($.Z,{placeholder:""})}),"Amazon Bedrock"==S&&(0,r.jsx)(er.Z.Item,{rules:[{required:!0,message:"Required"}],label:"AWS Secret Access Key",name:"aws_secret_access_key",tooltip:"You can provide the raw key or the environment variable (e.g. `os.environ/MY_SECRET_KEY`).",children:(0,r.jsx)($.Z,{placeholder:""})}),"Amazon Bedrock"==S&&(0,r.jsx)(er.Z.Item,{rules:[{required:!0,message:"Required"}],label:"AWS Region Name",name:"aws_region_name",tooltip:"You can provide the raw key or the environment variable (e.g. `os.environ/MY_SECRET_KEY`).",children:(0,r.jsx)($.Z,{placeholder:"us-east-1"})}),(0,r.jsx)(er.Z.Item,{label:"LiteLLM Params",name:"litellm_extra_params",tooltip:"Optional litellm params used for making a litellm.completion() call.",className:"mb-0",children:(0,r.jsx)(eY.Z,{rows:4,placeholder:'{ "rpm": 100, "timeout": 0, "stream_timeout": 0 }'})}),(0,r.jsxs)(eG.Z,{children:[(0,r.jsx)(eW.Z,{span:10}),(0,r.jsx)(eW.Z,{span:10,children:(0,r.jsxs)(el.Z,{className:"mb-3 mt-1",children:["Pass JSON of litellm supported params ",(0,r.jsx)(e1,{href:"https://docs.litellm.ai/docs/completion/input",target:"_blank",children:"litellm.completion() call"})]})})]})]}),(0,r.jsx)("div",{style:{textAlign:"center",marginTop:"10px"},children:(0,r.jsx)(ec.ZP,{htmlType:"submit",children:"Add Model"})}),(0,r.jsx)(eJ.Z,{title:"Get help on our github",children:(0,r.jsx)(eR.default.Link,{href:"https://github.com/BerriAI/litellm/issues",children:"Need Help?"})})]})})]}),(0,r.jsx)(eB.Z,{children:(0,r.jsxs)(eg.Z,{children:[(0,r.jsx)(el.Z,{children:"`/health` will run a very small request through your models configured on litellm"}),(0,r.jsx)(H.Z,{onClick:V,children:"Run `/health`"}),N&&(0,r.jsx)("pre",{children:JSON.stringify(N,null,2)})]})})]})]})})};let{Option:e5}=ea.default;var e3=e=>{let{userID:l,accessToken:t,teams:s}=e,[a]=er.Z.useForm(),[o,i]=(0,n.useState)(!1),[c,d]=(0,n.useState)(null),[m,u]=(0,n.useState)([]);(0,n.useEffect)(()=>{(async()=>{try{let e=await v(t,l,"any"),s=[];for(let l=0;l{i(!1),a.resetFields()},p=()=>{i(!1),d(null),a.resetFields()},j=async e=>{try{h.ZP.info("Making API Call"),i(!0),console.log("formValues in create user:",e);let s=await g(t,null,e);console.log("user create Response:",s),d(s.key),h.ZP.success("API user Created"),a.resetFields(),localStorage.removeItem("userData"+l)}catch(e){console.error("Error creating the user:",e)}};return(0,r.jsxs)("div",{children:[(0,r.jsx)(H.Z,{className:"mx-auto",onClick:()=>i(!0),children:"+ Invite User"}),(0,r.jsxs)(en.Z,{title:"Invite User",visible:o,width:800,footer:null,onOk:x,onCancel:p,children:[(0,r.jsx)(el.Z,{className:"mb-1",children:"Invite a user to login to the Admin UI and create Keys"}),(0,r.jsx)(el.Z,{className:"mb-6",children:(0,r.jsx)("b",{children:"Note: SSO Setup Required for this"})}),(0,r.jsxs)(er.Z,{form:a,onFinish:j,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsx)(er.Z.Item,{label:"User Email",name:"user_email",children:(0,r.jsx)($.Z,{placeholder:""})}),(0,r.jsx)(er.Z.Item,{label:"Team ID",name:"team_id",children:(0,r.jsx)(ea.default,{placeholder:"Select Team ID",style:{width:"100%"},children:s?s.map(e=>(0,r.jsx)(e5,{value:e.team_id,children:e.team_alias},e.team_id)):(0,r.jsx)(e5,{value:null,children:"Default Team"},"default")})}),(0,r.jsx)(er.Z.Item,{label:"Metadata",name:"metadata",children:(0,r.jsx)(eo.Z.TextArea,{rows:4,placeholder:"Enter metadata as JSON"})}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ec.ZP,{htmlType:"submit",children:"Create User"})})]})]}),c&&(0,r.jsxs)(en.Z,{title:"User Created Successfully",visible:o,onOk:x,onCancel:p,footer:null,children:[(0,r.jsx)("p",{children:"User has been created to access your proxy. Please Ask them to Log In."}),(0,r.jsx)("br",{}),(0,r.jsx)("p",{children:(0,r.jsx)("b",{children:"Note: This Feature is only supported through SSO on the Admin UI"})})]})]})},e6=e=>{let{accessToken:l,token:t,keys:s,userRole:a,userID:o,teams:i,setKeys:c}=e,[d,m]=(0,n.useState)(null),[h,u]=(0,n.useState)(null),[x,p]=(0,n.useState)(0),[j,g]=n.useState(null),[f,y]=(0,n.useState)(null);if((0,n.useEffect)(()=>{if(!l||!t||!a||!o)return;let e=async()=>{try{let e=await Z(l,null,a,!0,x,25);console.log("user data response:",e),m(e)}catch(e){console.error("There was an error fetching the model data",e)}};l&&t&&a&&o&&e();let s=async()=>{try{let e=await T(l,null);console.log("user data response:",e),u(e)}catch(e){console.error("There was an error fetching the model data",e)}};a&&("Admin"==a||"Admin Viewer"==a)&&!h&&s()},[l,t,a,o,x]),!d||!l||!t||!a||!o)return(0,r.jsx)("div",{children:"Loading..."});let w=async e=>{try{let t=await T(l,e);console.log("user data response:",t),u(t)}catch(e){console.error("There was an error fetching the model data",e)}};return(0,r.jsx)("div",{style:{width:"100%"},children:(0,r.jsxs)(Y.Z,{className:"gap-2 p-2 h-[80vh] w-full mt-8",children:[(0,r.jsx)(e3,{userID:o,accessToken:l,teams:i}),(0,r.jsxs)(eg.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[80vh] mb-4",children:[(0,r.jsxs)("div",{className:"mb-4 mt-1",children:[(0,r.jsxs)(el.Z,{children:[(0,r.jsx)("b",{children:"Key Owners: "})," Users on LiteLLM that created API Keys. Automatically tracked by LiteLLM"]}),(0,r.jsxs)(el.Z,{className:"mt-1",children:[(0,r.jsx)("b",{children:"End Users: "}),"End Users of your LLM API calls. Tracked When a `user` param is passed in your LLM calls"]})]}),(0,r.jsxs)(eD.Z,{children:[(0,r.jsxs)(ez.Z,{variant:"line",defaultValue:"1",children:[(0,r.jsx)(eU.Z,{value:"1",children:"Key Owners"}),(0,r.jsx)(eU.Z,{value:"2",children:"End-Users"})]}),(0,r.jsxs)(eq.Z,{children:[(0,r.jsx)(eB.Z,{children:(0,r.jsxs)(ew.Z,{className:"mt-5",children:[(0,r.jsx)(ek.Z,{children:(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(ev.Z,{children:"User ID"}),(0,r.jsx)(ev.Z,{children:"User Email"}),(0,r.jsx)(ev.Z,{children:"User Models"}),(0,r.jsx)(ev.Z,{children:"User Spend ($ USD)"}),(0,r.jsx)(ev.Z,{children:"User Max Budget ($ USD)"}),(0,r.jsx)(ev.Z,{children:"User API Key Aliases"})]})}),(0,r.jsx)(eb.Z,{children:d.map(e=>(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(e_.Z,{children:e.user_id}),(0,r.jsx)(e_.Z,{children:e.user_email}),(0,r.jsx)(e_.Z,{children:e.models&&e.models.length>0?e.models:"All Models"}),(0,r.jsx)(e_.Z,{children:e.spend?e.spend:0}),(0,r.jsx)(e_.Z,{children:e.max_budget?e.max_budget:"Unlimited"}),(0,r.jsx)(e_.Z,{children:(0,r.jsx)(Y.Z,{numItems:2,children:e&&e.key_aliases&&e.key_aliases.filter(e=>null!==e).length>0?(0,r.jsx)(ep.Z,{size:"xs",color:"indigo",children:e.key_aliases.filter(e=>null!==e).join(", ")}):(0,r.jsx)(ep.Z,{size:"xs",color:"gray",children:"No Keys"})})})]},e.user_id))})]})}),(0,r.jsxs)(eB.Z,{children:[(0,r.jsxs)("div",{className:"flex items-center",children:[(0,r.jsx)("div",{className:"flex-1"}),(0,r.jsxs)("div",{className:"flex-1 flex justify-between items-center",children:[(0,r.jsx)(el.Z,{className:"w-1/4 mr-2 text-right",children:"Key"}),(0,r.jsx)(eA.Z,{defaultValue:"1",className:"w-3/4",children:null==s?void 0:s.map((e,l)=>{if(e&&null!==e.key_alias&&e.key_alias.length>0)return(0,r.jsx)(eN.Z,{value:String(l),onClick:()=>w(e.token),children:e.key_alias},l)})})]})]}),(0,r.jsxs)(ew.Z,{className:"max-h-[70vh] min-h-[500px]",children:[(0,r.jsx)(ek.Z,{children:(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(ev.Z,{children:"End User"}),(0,r.jsx)(ev.Z,{children:"Spend"}),(0,r.jsx)(ev.Z,{children:"Total Events"})]})}),(0,r.jsx)(eb.Z,{children:null==h?void 0:h.map((e,l)=>(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(e_.Z,{children:e.end_user}),(0,r.jsx)(e_.Z,{children:e.total_spend}),(0,r.jsx)(e_.Z,{children:e.total_events})]},l))})]})]})]})]})]}),function(){if(!d)return null;let e=Math.ceil(d.length/25);return(0,r.jsxs)("div",{className:"flex justify-between items-center",children:[(0,r.jsxs)("div",{children:["Showing Page ",x+1," of ",e]}),(0,r.jsxs)("div",{className:"flex",children:[(0,r.jsx)("button",{className:"bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-l focus:outline-none",disabled:0===x,onClick:()=>p(x-1),children:"← Prev"}),(0,r.jsx)("button",{className:"bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-r focus:outline-none",onClick:()=>{p(x+1)},children:"Next →"})]})]})}()]})})},e7=e=>{let{teams:l,searchParams:t,accessToken:s,setTeams:a,userID:o,userRole:i}=e,[c]=er.Z.useForm(),[d]=er.Z.useForm(),{Title:m,Paragraph:u}=eR.default,[x,p]=(0,n.useState)(""),[j,g]=(0,n.useState)(!1),[f,Z]=(0,n.useState)(l?l[0]:null),[b,_]=(0,n.useState)(!1),[k,S]=(0,n.useState)(!1),[A,N]=(0,n.useState)([]),[C,I]=(0,n.useState)(!1),[P,T]=(0,n.useState)(null),[E,F]=(0,n.useState)({}),O=e=>{Z(e),g(!0)},M=async e=>{let t=e.team_id;if(console.log("handleEditSubmit:",e),null==s)return;let r=await U(s,e);l&&a(l.map(e=>e.team_id===t?r.data:e)),h.ZP.success("Team updated successfully"),g(!1),Z(null)},L=async e=>{T(e),I(!0)},D=async()=>{if(null!=P&&null!=l&&null!=s){try{await y(s,P);let e=l.filter(e=>e.team_id!==P);a(e)}catch(e){console.error("Error deleting the team:",e)}I(!1),T(null)}};(0,n.useEffect)(()=>{let e=async()=>{try{if(null===o||null===i||null===s||null===l)return;console.log("fetching team info:");let e={};for(let t=0;t<(null==l?void 0:l.length);t++){let a=l[t].team_id,r=await w(s,a);console.log("teamInfo response:",r),null!==r&&(e={...e,[a]:r})}F(e)}catch(e){console.error("Error fetching team info:",e)}};(async()=>{try{if(null===o||null===i)return;if(null!==s){let e=(await v(s,o,i)).data.map(e=>e.id);console.log("available_model_names:",e),N(e)}}catch(e){console.error("Error fetching user models:",e)}})(),e()},[s,o,i,l]);let B=async e=>{try{if(null!=s){h.ZP.info("Creating Team");let t=await R(s,e);null!==l?a([...l,t]):a([t]),console.log("response for team create call: ".concat(t)),h.ZP.success("Team created"),_(!1)}}catch(e){console.error("Error creating the team:",e),h.ZP.error("Error creating the team: "+e,20)}},q=async e=>{try{if(null!=s&&null!=l){h.ZP.info("Adding Member");let t={role:"user",user_email:e.user_email,user_id:e.user_id},r=await z(s,f.team_id,t);console.log("response for team create call: ".concat(r.data));let n=l.findIndex(e=>(console.log("team.team_id=".concat(e.team_id,"; response.data.team_id=").concat(r.data.team_id)),e.team_id===r.data.team_id));if(console.log("foundIndex: ".concat(n)),-1!==n){let e=[...l];e[n]=r.data,a(e),Z(r.data)}S(!1)}}catch(e){console.error("Error creating the team:",e)}};return console.log("received teams ".concat(l)),(0,r.jsx)("div",{className:"w-full mx-4",children:(0,r.jsxs)(Y.Z,{numItems:1,className:"gap-2 p-8 h-[75vh] w-full mt-2",children:[(0,r.jsxs)(J.Z,{numColSpan:1,children:[(0,r.jsx)(m,{level:4,children:"All Teams"}),(0,r.jsxs)(eg.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:[(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(ek.Z,{children:(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(ev.Z,{children:"Team Name"}),(0,r.jsx)(ev.Z,{children:"Spend (USD)"}),(0,r.jsx)(ev.Z,{children:"Budget (USD)"}),(0,r.jsx)(ev.Z,{children:"Models"}),(0,r.jsx)(ev.Z,{children:"TPM / RPM Limits"}),(0,r.jsx)(ev.Z,{children:"Info"})]})}),(0,r.jsx)(eb.Z,{children:l&&l.length>0?l.map(e=>(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(e_.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:e.team_alias}),(0,r.jsx)(e_.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:e.spend}),(0,r.jsx)(e_.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:e.max_budget?e.max_budget:"No limit"}),(0,r.jsx)(e_.Z,{style:{maxWidth:"8-x",whiteSpace:"pre-wrap",overflow:"hidden"},children:Array.isArray(e.models)?(0,r.jsx)("div",{style:{display:"flex",flexDirection:"column"},children:0===e.models.length?(0,r.jsx)(ep.Z,{size:"xs",className:"mb-1",color:"red",children:(0,r.jsx)(el.Z,{children:"All Proxy Models"})}):e.models.map((e,l)=>"all-proxy-models"===e?(0,r.jsx)(ep.Z,{size:"xs",className:"mb-1",color:"red",children:(0,r.jsx)(el.Z,{children:"All Proxy Models"})},l):(0,r.jsx)(ep.Z,{size:"xs",className:"mb-1",color:"blue",children:(0,r.jsx)(el.Z,{children:e.length>30?"".concat(e.slice(0,30),"..."):e})},l))}):null}),(0,r.jsx)(e_.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,r.jsxs)(el.Z,{children:["TPM:"," ",e.tpm_limit?e.tpm_limit:"Unlimited"," ",(0,r.jsx)("br",{}),"RPM:"," ",e.rpm_limit?e.rpm_limit:"Unlimited"]})}),(0,r.jsxs)(e_.Z,{children:[(0,r.jsxs)(el.Z,{children:[E&&e.team_id&&E[e.team_id]&&E[e.team_id].keys&&E[e.team_id].keys.length," Keys"]}),(0,r.jsxs)(el.Z,{children:[E&&e.team_id&&E[e.team_id]&&E[e.team_id].team_info&&E[e.team_id].team_info.members_with_roles&&E[e.team_id].team_info.members_with_roles.length," Members"]})]}),(0,r.jsxs)(e_.Z,{children:[(0,r.jsx)(eZ.Z,{icon:eu.Z,size:"sm",onClick:()=>O(e)}),(0,r.jsx)(eZ.Z,{onClick:()=>L(e.team_id),icon:ex.Z,size:"sm"})]})]},e.team_id)):null})]}),C&&(0,r.jsx)("div",{className:"fixed z-10 inset-0 overflow-y-auto",children:(0,r.jsxs)("div",{className:"flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0",children:[(0,r.jsx)("div",{className:"fixed inset-0 transition-opacity","aria-hidden":"true",children:(0,r.jsx)("div",{className:"absolute inset-0 bg-gray-500 opacity-75"})}),(0,r.jsx)("span",{className:"hidden sm:inline-block sm:align-middle sm:h-screen","aria-hidden":"true",children:"​"}),(0,r.jsxs)("div",{className:"inline-block align-bottom bg-white rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full",children:[(0,r.jsx)("div",{className:"bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4",children:(0,r.jsx)("div",{className:"sm:flex sm:items-start",children:(0,r.jsxs)("div",{className:"mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left",children:[(0,r.jsx)("h3",{className:"text-lg leading-6 font-medium text-gray-900",children:"Delete Team"}),(0,r.jsx)("div",{className:"mt-2",children:(0,r.jsx)("p",{className:"text-sm text-gray-500",children:"Are you sure you want to delete this team ?"})})]})})}),(0,r.jsxs)("div",{className:"bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse",children:[(0,r.jsx)(H.Z,{onClick:D,color:"red",className:"ml-2",children:"Delete"}),(0,r.jsx)(H.Z,{onClick:()=>{I(!1),T(null)},children:"Cancel"})]})]})]})})]})]}),(0,r.jsxs)(J.Z,{numColSpan:1,children:[(0,r.jsx)(H.Z,{className:"mx-auto",onClick:()=>_(!0),children:"+ Create New Team"}),(0,r.jsx)(en.Z,{title:"Create Team",visible:b,width:800,footer:null,onOk:()=>{_(!1),c.resetFields()},onCancel:()=>{_(!1),c.resetFields()},children:(0,r.jsxs)(er.Z,{form:c,onFinish:B,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(er.Z.Item,{label:"Team Name",name:"team_alias",rules:[{required:!0,message:"Please input a team name"}],children:(0,r.jsx)($.Z,{placeholder:""})}),(0,r.jsx)(er.Z.Item,{label:"Models",name:"models",children:(0,r.jsxs)(ea.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:[(0,r.jsx)(ea.default.Option,{value:"all-proxy-models",children:"All Proxy Models"},"all-proxy-models"),A.map(e=>(0,r.jsx)(ea.default.Option,{value:e,children:e},e))]})}),(0,r.jsx)(er.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,r.jsx)(ei.Z,{step:.01,precision:2,width:200})}),(0,r.jsx)(er.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,r.jsx)(ei.Z,{step:1,width:400})}),(0,r.jsx)(er.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,r.jsx)(ei.Z,{step:1,width:400})})]}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ec.ZP,{htmlType:"submit",children:"Create Team"})})]})})]}),(0,r.jsxs)(J.Z,{numColSpan:1,children:[(0,r.jsx)(m,{level:4,children:"Team Members"}),(0,r.jsx)(u,{children:"If you belong to multiple teams, this setting controls which teams members you see."}),l&&l.length>0?(0,r.jsx)(eA.Z,{defaultValue:"0",children:l.map((e,l)=>(0,r.jsx)(eN.Z,{value:String(l),onClick:()=>{Z(e)},children:e.team_alias},l))}):(0,r.jsxs)(u,{children:["No team created. ",(0,r.jsx)("b",{children:"Defaulting to personal account."})]})]}),(0,r.jsxs)(J.Z,{numColSpan:1,children:[(0,r.jsx)(eg.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(ek.Z,{children:(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(ev.Z,{children:"Member Name"}),(0,r.jsx)(ev.Z,{children:"Role"})]})}),(0,r.jsx)(eb.Z,{children:f?f.members_with_roles.map((e,l)=>(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(e_.Z,{children:e.user_email?e.user_email:e.user_id?e.user_id:null}),(0,r.jsx)(e_.Z,{children:e.role})]},l)):null})]})}),f&&(0,r.jsx)(e=>{let{visible:l,onCancel:t,team:s,onSubmit:a}=e,[n]=er.Z.useForm();return(0,r.jsx)(en.Z,{title:"Edit Team",visible:l,width:800,footer:null,onOk:()=>{n.validateFields().then(e=>{a({...e,team_id:s.team_id}),n.resetFields()}).catch(e=>{console.error("Validation failed:",e)})},onCancel:t,children:(0,r.jsxs)(er.Z,{form:n,onFinish:M,initialValues:s,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(er.Z.Item,{label:"Team Name",name:"team_alias",rules:[{required:!0,message:"Please input a team name"}],children:(0,r.jsx)(eo.Z,{})}),(0,r.jsx)(er.Z.Item,{label:"Models",name:"models",children:(0,r.jsxs)(ea.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:[(0,r.jsx)(ea.default.Option,{value:"all-proxy-models",children:"All Proxy Models"},"all-proxy-models"),A&&A.map(e=>(0,r.jsx)(ea.default.Option,{value:e,children:e},e))]})}),(0,r.jsx)(er.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,r.jsx)(ei.Z,{step:.01,precision:2,width:200})}),(0,r.jsx)(er.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,r.jsx)(ei.Z,{step:1,width:400})}),(0,r.jsx)(er.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,r.jsx)(ei.Z,{step:1,width:400})}),(0,r.jsx)(er.Z.Item,{label:"Requests per minute Limit (RPM)",name:"team_id",hidden:!0})]}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ec.ZP,{htmlType:"submit",children:"Edit Team"})})]})})},{visible:j,onCancel:()=>{g(!1),Z(null)},team:f,onSubmit:M})]}),(0,r.jsxs)(J.Z,{numColSpan:1,children:[(0,r.jsx)(H.Z,{className:"mx-auto mb-5",onClick:()=>S(!0),children:"+ Add member"}),(0,r.jsx)(en.Z,{title:"Add member",visible:k,width:800,footer:null,onOk:()=>{S(!1),d.resetFields()},onCancel:()=>{S(!1),d.resetFields()},children:(0,r.jsxs)(er.Z,{form:c,onFinish:q,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(er.Z.Item,{label:"Email",name:"user_email",className:"mb-4",children:(0,r.jsx)(eo.Z,{name:"user_email",className:"px-3 py-2 border rounded-md w-full"})}),(0,r.jsx)("div",{className:"text-center mb-4",children:"OR"}),(0,r.jsx)(er.Z.Item,{label:"User ID",name:"user_id",className:"mb-4",children:(0,r.jsx)(eo.Z,{name:"user_id",className:"px-3 py-2 border rounded-md w-full"})})]}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ec.ZP,{htmlType:"submit",children:"Add member"})})]})})]})]})})},e9=t(18190),le=e=>{let l,{searchParams:t,accessToken:s,showSSOBanner:a}=e,[o]=er.Z.useForm(),[i]=er.Z.useForm(),{Title:c,Paragraph:d}=eR.default,[m,u]=(0,n.useState)(""),[x,p]=(0,n.useState)(null),[j,g]=(0,n.useState)(!1),[f,y]=(0,n.useState)(!1),[Z,w]=(0,n.useState)(!1),[b,_]=(0,n.useState)(!1),[k,v]=(0,n.useState)(!1);try{l=window.location.origin}catch(e){l=""}l+="/fallback/login";let S=()=>{v(!1)},A=["proxy_admin","proxy_admin_viewer"];(0,n.useEffect)(()=>{(async()=>{if(null!=s){let e=[],l=await M(s,"proxy_admin_viewer");l.forEach(l=>{e.push({user_role:l.user_role,user_id:l.user_id,user_email:l.user_email})}),console.log("proxy viewers: ".concat(l));let t=await M(s,"proxy_admin");t.forEach(l=>{e.push({user_role:l.user_role,user_id:l.user_id,user_email:l.user_email})}),console.log("proxy admins: ".concat(t)),console.log("combinedList: ".concat(e)),p(e)}})()},[s]);let N=()=>{w(!1),i.resetFields()},C=()=>{w(!1),i.resetFields()},I=e=>(0,r.jsxs)(er.Z,{form:o,onFinish:e,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(er.Z.Item,{label:"Email",name:"user_email",className:"mb-4",children:(0,r.jsx)(eo.Z,{name:"user_email",className:"px-3 py-2 border rounded-md w-full"})}),(0,r.jsx)("div",{className:"text-center mb-4",children:"OR"}),(0,r.jsx)(er.Z.Item,{label:"User ID",name:"user_id",className:"mb-4",children:(0,r.jsx)(eo.Z,{name:"user_id",className:"px-3 py-2 border rounded-md w-full"})})]}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ec.ZP,{htmlType:"submit",children:"Add member"})})]}),P=(e,l,t)=>(0,r.jsxs)(er.Z,{form:o,onFinish:e,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(er.Z.Item,{rules:[{required:!0,message:"Required"}],label:"User Role",name:"user_role",labelCol:{span:10},labelAlign:"left",children:(0,r.jsx)(eA.Z,{value:l,children:A.map((e,l)=>(0,r.jsx)(eN.Z,{value:e,children:e},l))})}),(0,r.jsx)(er.Z.Item,{label:"Team ID",name:"user_id",hidden:!0,initialValue:t,valuePropName:"user_id",className:"mt-8",children:(0,r.jsx)(eo.Z,{value:t,disabled:!0})})]}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ec.ZP,{htmlType:"submit",children:"Update role"})})]}),T=async e=>{try{if(null!=s&&null!=x){h.ZP.info("Making API Call");let l=await B(s,e,null);console.log("response for team create call: ".concat(l));let t=x.findIndex(e=>(console.log("user.user_id=".concat(e.user_id,"; response.user_id=").concat(l.user_id)),e.user_id===l.user_id));console.log("foundIndex: ".concat(t)),-1==t&&(console.log("updates admin with new user"),x.push(l),p(x)),h.ZP.success("Refresh tab to see updated user role"),w(!1)}}catch(e){console.error("Error creating the key:",e)}},E=async e=>{try{if(null!=s&&null!=x){h.ZP.info("Making API Call");let l=await B(s,e,"proxy_admin_viewer");console.log("response for team create call: ".concat(l));let t=x.findIndex(e=>(console.log("user.user_id=".concat(e.user_id,"; response.user_id=").concat(l.user_id)),e.user_id===l.user_id));console.log("foundIndex: ".concat(t)),-1==t&&(console.log("updates admin with new user"),x.push(l),p(x)),g(!1)}}catch(e){console.error("Error creating the key:",e)}},F=async e=>{try{if(null!=s&&null!=x){h.ZP.info("Making API Call"),e.user_email,e.user_id;let l=await B(s,e,"proxy_admin");console.log("response for team create call: ".concat(l));let t=x.findIndex(e=>(console.log("user.user_id=".concat(e.user_id,"; response.user_id=").concat(l.user_id)),e.user_id===l.user_id));console.log("foundIndex: ".concat(t)),-1==t&&(console.log("updates admin with new user"),x.push(l),p(x)),y(!1)}}catch(e){console.error("Error creating the key:",e)}},O=async e=>{null!=s&&G(s,{environment_variables:{PROXY_BASE_URL:e.proxy_base_url,GOOGLE_CLIENT_ID:e.google_client_id,GOOGLE_CLIENT_SECRET:e.google_client_secret}})};return console.log("admins: ".concat(null==x?void 0:x.length)),(0,r.jsxs)("div",{className:"w-full m-2 mt-2 p-8",children:[(0,r.jsx)(c,{level:4,children:"Admin Access "}),(0,r.jsxs)(d,{children:[a&&(0,r.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/ui#restrict-ui-access",children:"Requires SSO Setup"}),(0,r.jsx)("br",{}),(0,r.jsx)("b",{children:"Proxy Admin: "})," Can create keys, teams, users, add models, etc. ",(0,r.jsx)("br",{}),(0,r.jsx)("b",{children:"Proxy Admin Viewer: "}),"Can just view spend. They cannot create keys, teams or grant users access to new models."," "]}),(0,r.jsxs)(Y.Z,{numItems:1,className:"gap-2 p-2 w-full",children:[(0,r.jsx)(J.Z,{numColSpan:1,children:(0,r.jsx)(eg.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(ek.Z,{children:(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(ev.Z,{children:"Member Name"}),(0,r.jsx)(ev.Z,{children:"Role"})]})}),(0,r.jsx)(eb.Z,{children:x?x.map((e,l)=>(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(e_.Z,{children:e.user_email?e.user_email:e.user_id?e.user_id:null}),(0,r.jsx)(e_.Z,{children:e.user_role}),(0,r.jsxs)(e_.Z,{children:[(0,r.jsx)(eZ.Z,{icon:eu.Z,size:"sm",onClick:()=>w(!0)}),(0,r.jsx)(en.Z,{title:"Update role",visible:Z,width:800,footer:null,onOk:N,onCancel:C,children:P(T,e.user_role,e.user_id)})]})]},l)):null})]})})}),(0,r.jsx)(J.Z,{numColSpan:1,children:(0,r.jsxs)("div",{className:"flex justify-start",children:[(0,r.jsx)(H.Z,{className:"mr-4 mb-5",onClick:()=>y(!0),children:"+ Add admin"}),(0,r.jsx)(en.Z,{title:"Add admin",visible:f,width:800,footer:null,onOk:()=>{y(!1),i.resetFields()},onCancel:()=>{y(!1),i.resetFields()},children:I(F)}),(0,r.jsx)(H.Z,{className:"mb-5",onClick:()=>g(!0),children:"+ Add viewer"}),(0,r.jsx)(en.Z,{title:"Add viewer",visible:j,width:800,footer:null,onOk:()=>{g(!1),i.resetFields()},onCancel:()=>{g(!1),i.resetFields()},children:I(E)})]})})]}),(0,r.jsxs)(Y.Z,{children:[(0,r.jsx)(c,{level:4,children:"Add SSO"}),(0,r.jsxs)("div",{className:"flex justify-start mb-4",children:[(0,r.jsx)(H.Z,{onClick:()=>_(!0),children:"Add SSO"}),(0,r.jsx)(en.Z,{title:"Add SSO",visible:b,width:800,footer:null,onOk:()=>{_(!1),o.resetFields()},onCancel:()=>{_(!1),o.resetFields()},children:(0,r.jsxs)(er.Z,{form:o,onFinish:e=>{F(e),O(e),_(!1),v(!0)},labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(er.Z.Item,{label:"Admin Email",name:"user_email",rules:[{required:!0,message:"Please enter the email of the proxy admin"}],children:(0,r.jsx)(eo.Z,{})}),(0,r.jsx)(er.Z.Item,{label:"PROXY BASE URL",name:"proxy_base_url",rules:[{required:!0,message:"Please enter the proxy base url"}],children:(0,r.jsx)(eo.Z,{})}),(0,r.jsx)(er.Z.Item,{label:"GOOGLE CLIENT ID",name:"google_client_id",rules:[{required:!0,message:"Please enter the google client id"}],children:(0,r.jsx)(eo.Z.Password,{})}),(0,r.jsx)(er.Z.Item,{label:"GOOGLE CLIENT SECRET",name:"google_client_secret",rules:[{required:!0,message:"Please enter the google client secret"}],children:(0,r.jsx)(eo.Z.Password,{})})]}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ec.ZP,{htmlType:"submit",children:"Save"})})]})}),(0,r.jsxs)(en.Z,{title:"SSO Setup Instructions",visible:k,width:800,footer:null,onOk:S,onCancel:()=>{v(!1)},children:[(0,r.jsx)("p",{children:"Follow these steps to complete the SSO setup:"}),(0,r.jsx)(el.Z,{className:"mt-2",children:"1. DO NOT Exit this TAB"}),(0,r.jsx)(el.Z,{className:"mt-2",children:"2. Open a new tab, visit your proxy base url"}),(0,r.jsx)(el.Z,{className:"mt-2",children:"3. Confirm your SSO is configured correctly and you can login on the new Tab"}),(0,r.jsx)(el.Z,{className:"mt-2",children:"4. If Step 3 is successful, you can close this tab"}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ec.ZP,{onClick:S,children:"Done"})})]})]}),(0,r.jsxs)(e9.Z,{title:"Login without SSO",color:"teal",children:["If you need to login without sso, you can access ",(0,r.jsxs)("a",{href:l,target:"_blank",children:[(0,r.jsx)("b",{children:l})," "]})]})]})]})},ll=t(12224),lt=e=>{let{accessToken:l,userRole:t,userID:s}=e,[a,o]=(0,n.useState)([]),[i,c]=(0,n.useState)([]),[d,m]=(0,n.useState)(!1),[u]=er.Z.useForm(),[x,p]=(0,n.useState)(null),[j,g]=(0,n.useState)([]),[f,y]=(0,n.useState)(""),[Z,w]=(0,n.useState)({}),[b,_]=(0,n.useState)([]),k=e=>{b.includes(e)?_(b.filter(l=>l!==e)):_([...b,e])},v={llm_exceptions:"LLM Exceptions",llm_too_slow:"LLM Responses Too Slow",llm_requests_hanging:"LLM Requests Hanging",budget_alerts:"Budget Alerts (API Keys, Users)"};(0,n.useEffect)(()=>{l&&t&&s&&V(l,s,t).then(e=>{console.log("callbacks",e),o(e.callbacks);let l=e.alerts;if(console.log("alerts_data",l),l&&l.length>0){let e=l[0];console.log("_alert_info",e);let t=e.variables.SLACK_WEBHOOK_URL;console.log("catch_all_webhook",t),_(e.active_alerts),y(t),w(e.alerts_to_webhook)}c(l)})},[l,t,s]);let S=e=>b&&b.includes(e),A=e=>{if(!l)return;let t=Object.fromEntries(Object.entries(e.variables).map(e=>{var l;let[t,s]=e;return[t,(null===(l=document.querySelector('input[name="'.concat(t,'"]')))||void 0===l?void 0:l.value)||s]}));console.log("updatedVariables",t),console.log("updateAlertTypes",j);try{G(l,{environment_variables:t})}catch(e){h.ZP.error("Failed to update callback: "+e,20)}h.ZP.success("Callback updated successfully")},N=()=>{l&&u.validateFields().then(e=>{if(console.log("Form values:",e),"langfuse"===e.callback){G(l,{environment_variables:{LANGFUSE_PUBLIC_KEY:e.langfusePublicKey,LANGFUSE_SECRET_KEY:e.langfusePrivateKey},litellm_settings:{success_callback:[e.callback]}});let t={name:e.callback,variables:{SLACK_WEBHOOK_URL:null,LANGFUSE_HOST:null,LANGFUSE_PUBLIC_KEY:e.langfusePublicKey,LANGFUSE_SECRET_KEY:e.langfusePrivateKey}};o(a?[...a,t]:[t])}else if("slack"===e.callback){console.log("values.slackWebhookUrl: ".concat(e.slackWebhookUrl)),G(l,{general_settings:{alerting:["slack"],alerting_threshold:300},environment_variables:{SLACK_WEBHOOK_URL:e.slackWebhookUrl}}),console.log("values.callback: ".concat(e.callback));let t={name:e.callback,variables:{SLACK_WEBHOOK_URL:e.slackWebhookUrl,LANGFUSE_HOST:null,LANGFUSE_PUBLIC_KEY:null,LANGFUSE_SECRET_KEY:null}};o(a?[...a,t]:[t])}m(!1),u.resetFields(),p(null)})};return l?(console.log("callbacks: ".concat(a)),(0,r.jsxs)("div",{className:"w-full mx-4",children:[(0,r.jsx)(Y.Z,{numItems:1,className:"gap-2 p-8 w-full mt-2",children:(0,r.jsxs)(eD.Z,{children:[(0,r.jsxs)(ez.Z,{variant:"line",defaultValue:"1",children:[(0,r.jsx)(eU.Z,{value:"1",children:"Logging Callbacks"}),(0,r.jsx)(eU.Z,{value:"2",children:"Alerting"})]}),(0,r.jsxs)(eq.Z,{children:[(0,r.jsx)(eB.Z,{children:(0,r.jsxs)(eg.Z,{children:[(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(ek.Z,{children:(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(ev.Z,{children:"Callback"}),(0,r.jsx)(ev.Z,{children:"Callback Env Vars"})]})}),(0,r.jsx)(eb.Z,{children:a.map((e,t)=>{var s;return(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(e_.Z,{children:(0,r.jsx)(ep.Z,{color:"emerald",children:e.name})}),(0,r.jsxs)(e_.Z,{children:[(0,r.jsx)("ul",{children:Object.entries(null!==(s=e.variables)&&void 0!==s?s:{}).filter(e=>{let[l,t]=e;return null!==t}).map(e=>{let[l,t]=e;return(0,r.jsxs)("li",{children:[(0,r.jsx)(el.Z,{className:"mt-2",children:l}),"LANGFUSE_HOST"===l?(0,r.jsx)("p",{children:"default value=https://cloud.langfuse.com"}):(0,r.jsx)("div",{}),(0,r.jsx)($.Z,{name:l,defaultValue:t,type:"password"})]},l)})}),(0,r.jsx)(H.Z,{className:"mt-2",onClick:()=>A(e),children:"Save Changes"}),(0,r.jsx)(H.Z,{onClick:()=>K(l,e.name),className:"mx-2",children:"Test Callback"})]})]},t)})})]}),(0,r.jsx)(H.Z,{size:"xs",className:"mt-2",onClick:()=>{console.log("Add callback clicked"),m(!0)},children:"Add Callback"})]})}),(0,r.jsx)(eB.Z,{children:(0,r.jsxs)(eg.Z,{children:[(0,r.jsxs)(el.Z,{className:"my-2",children:["Alerts are only supported for Slack Webhook URLs. Get your webhook urls from ",(0,r.jsx)("a",{href:"https://api.slack.com/messaging/webhooks",target:"_blank",style:{color:"blue"},children:"here"})]}),(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(ek.Z,{children:(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(ev.Z,{}),(0,r.jsx)(ev.Z,{}),(0,r.jsx)(ev.Z,{children:"Slack Webhook URL"})]})}),(0,r.jsx)(eb.Z,{children:Object.entries(v).map((e,l)=>{let[t,s]=e;return(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(e_.Z,{children:(0,r.jsx)(ll.Z,{id:"switch",name:"switch",checked:S(t),onChange:()=>k(t)})}),(0,r.jsx)(e_.Z,{children:(0,r.jsx)(el.Z,{children:s})}),(0,r.jsx)(e_.Z,{children:(0,r.jsx)($.Z,{name:t,type:"password",defaultValue:Z&&Z[t]?Z[t]:f})})]},l)})})]}),(0,r.jsx)(H.Z,{size:"xs",className:"mt-2",onClick:()=>{if(!l)return;let e={};Object.entries(v).forEach(l=>{let[t,s]=l,a=document.querySelector('input[name="'.concat(t,'"]'));console.log("key",t),console.log("webhookInput",a);let r=(null==a?void 0:a.value)||"";console.log("newWebhookValue",r),e[t]=r}),console.log("updatedAlertToWebhooks",e);let t={general_settings:{alert_to_webhook_url:e,alert_types:b}};console.log("payload",t);try{G(l,t)}catch(e){h.ZP.error("Failed to update alerts: "+e,20)}h.ZP.success("Alerts updated successfully")},children:"Save Changes"}),(0,r.jsx)(H.Z,{onClick:()=>K(l,"slack"),className:"mx-2",children:"Test Alerts"})]})})]})]})}),(0,r.jsx)(en.Z,{title:"Add Callback",visible:d,onOk:N,width:800,onCancel:()=>{m(!1),u.resetFields(),p(null)},footer:null,children:(0,r.jsxs)(er.Z,{form:u,layout:"vertical",onFinish:N,children:[(0,r.jsx)(er.Z.Item,{label:"Callback",name:"callback",rules:[{required:!0,message:"Please select a callback"}],children:(0,r.jsx)(ea.default,{onChange:e=>{p(e)},children:(0,r.jsx)(ea.default.Option,{value:"langfuse",children:"langfuse"})})}),"langfuse"===x&&(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(er.Z.Item,{label:"LANGFUSE_PUBLIC_KEY",name:"langfusePublicKey",rules:[{required:!0,message:"Please enter the public key"}],children:(0,r.jsx)($.Z,{type:"password"})}),(0,r.jsx)(er.Z.Item,{label:"LANGFUSE_PRIVATE_KEY",name:"langfusePrivateKey",rules:[{required:!0,message:"Please enter the private key"}],children:(0,r.jsx)($.Z,{type:"password"})})]}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ec.ZP,{htmlType:"submit",children:"Save"})})]})})]})):null};let{Option:ls}=ea.default;var la=e=>{let{models:l,accessToken:t,routerSettings:s,setRouterSettings:a}=e,[o]=er.Z.useForm(),[i,c]=(0,n.useState)(!1),[d,m]=(0,n.useState)("");return(0,r.jsxs)("div",{children:[(0,r.jsx)(H.Z,{className:"mx-auto",onClick:()=>c(!0),children:"+ Add Fallbacks"}),(0,r.jsx)(en.Z,{title:"Add Fallbacks",visible:i,width:800,footer:null,onOk:()=>{c(!1),o.resetFields()},onCancel:()=>{c(!1),o.resetFields()},children:(0,r.jsxs)(er.Z,{form:o,onFinish:e=>{console.log(e);let{model_name:l,models:r}=e,n=[...s.fallbacks||[],{[l]:r}],i={...s,fallbacks:n};console.log(i);try{G(t,{router_settings:i}),a(i)}catch(e){h.ZP.error("Failed to update router settings: "+e,20)}h.ZP.success("router settings updated successfully"),c(!1),o.resetFields()},labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(er.Z.Item,{label:"Public Model Name",name:"model_name",rules:[{required:!0,message:"Set the model to fallback for"}],help:"required",children:(0,r.jsx)(eA.Z,{defaultValue:d,children:l&&l.map((e,l)=>(0,r.jsx)(eN.Z,{value:e,onClick:()=>m(e),children:e},l))})}),(0,r.jsx)(er.Z.Item,{label:"Fallback Models",name:"models",rules:[{required:!0,message:"Please select a model"}],help:"required",children:(0,r.jsx)(eK.Z,{value:l,children:l&&l.filter(e=>e!=d).map(e=>(0,r.jsx)(eV.Z,{value:e,children:e},e))})})]}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ec.ZP,{htmlType:"submit",children:"Add Fallbacks"})})]})})]})},lr=t(12968);async function ln(e,l){console.log("isLocal:",!1);let t=window.location.origin,s=new lr.ZP.OpenAI({apiKey:l,baseURL:t,dangerouslyAllowBrowser:!0});try{let l=await s.chat.completions.create({model:e,messages:[{role:"user",content:"Hi, this is a test message"}],mock_testing_fallbacks:!0});h.ZP.success((0,r.jsxs)("span",{children:["Test model=",(0,r.jsx)("strong",{children:e}),", received model=",(0,r.jsx)("strong",{children:l.model}),". See ",(0,r.jsx)("a",{href:"#",onClick:()=>window.open("https://docs.litellm.ai/docs/proxy/reliability","_blank"),style:{textDecoration:"underline",color:"blue"},children:"curl"})]}))}catch(e){h.ZP.error("Error occurred while generating model response. Please try again. Error: ".concat(e),20)}}var lo=e=>{let{accessToken:l,userRole:t,userID:s,modelData:a}=e,[o,i]=(0,n.useState)({}),[c,d]=(0,n.useState)(!1),[m]=er.Z.useForm(),[u,x]=(0,n.useState)(null),p={routing_strategy_args:"(dict) Arguments to pass to the routing strategy",routing_strategy:"(string) Routing strategy to use",allowed_fails:"(int) Number of times a deployment can fail before being added to cooldown",cooldown_time:"(int) time in seconds to cooldown a deployment after failure",num_retries:"(int) Number of retries for failed requests. Defaults to 0.",timeout:"(float) Timeout for requests. Defaults to None.",retry_after:"(int) Minimum time to wait before retrying a failed request"};(0,n.useEffect)(()=>{l&&t&&s&&V(l,s,t).then(e=>{console.log("callbacks",e),i(e.router_settings)})},[l,t,s]);let j=async e=>{if(l){console.log("received key: ".concat(e)),console.log("routerSettings['fallbacks']: ".concat(o.fallbacks)),o.fallbacks.map(l=>(e in l&&delete l[e],l));try{await G(l,{router_settings:o}),i({...o}),h.ZP.success("Router settings updated successfully")}catch(e){h.ZP.error("Failed to update router settings: "+e,20)}}},g=e=>{if(!l)return;console.log("router_settings",e);let t=Object.fromEntries(Object.entries(e).map(e=>{let[l,t]=e;if("routing_strategy_args"!==l){var s;return[l,(null===(s=document.querySelector('input[name="'.concat(l,'"]')))||void 0===s?void 0:s.value)||t]}return null}).filter(e=>null!==e));console.log("updatedVariables",t);try{G(l,{router_settings:t})}catch(e){h.ZP.error("Failed to update router settings: "+e,20)}h.ZP.success("router settings updated successfully")};return l?(0,r.jsx)("div",{className:"w-full mx-4",children:(0,r.jsxs)(eD.Z,{className:"gap-2 p-8 h-[75vh] w-full mt-2",children:[(0,r.jsxs)(ez.Z,{variant:"line",defaultValue:"1",children:[(0,r.jsx)(eU.Z,{value:"1",children:"General Settings"}),(0,r.jsx)(eU.Z,{value:"2",children:"Fallbacks"})]}),(0,r.jsxs)(eq.Z,{children:[(0,r.jsx)(eB.Z,{children:(0,r.jsxs)(Y.Z,{numItems:1,className:"gap-2 p-8 w-full mt-2",children:[(0,r.jsx)(et.Z,{children:"Router Settings"}),(0,r.jsx)(eg.Z,{children:(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(ek.Z,{children:(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(ev.Z,{children:"Setting"}),(0,r.jsx)(ev.Z,{children:"Value"})]})}),(0,r.jsx)(eb.Z,{children:Object.entries(o).filter(e=>{let[l,t]=e;return"fallbacks"!=l&&"context_window_fallbacks"!=l}).map(e=>{let[l,t]=e;return(0,r.jsxs)(eS.Z,{children:[(0,r.jsxs)(e_.Z,{children:[(0,r.jsx)(el.Z,{children:l}),(0,r.jsx)("p",{style:{fontSize:"0.65rem",color:"#808080",fontStyle:"italic"},className:"mt-1",children:p[l]})]}),(0,r.jsx)(e_.Z,{children:(0,r.jsx)($.Z,{name:l,defaultValue:"object"==typeof t?JSON.stringify(t,null,2):t.toString()})})]},l)})})]})}),(0,r.jsx)(J.Z,{children:(0,r.jsx)(H.Z,{className:"mt-2",onClick:()=>g(o),children:"Save Changes"})})]})}),(0,r.jsxs)(eB.Z,{children:[(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(ek.Z,{children:(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(ev.Z,{children:"Model Name"}),(0,r.jsx)(ev.Z,{children:"Fallbacks"})]})}),(0,r.jsx)(eb.Z,{children:o.fallbacks&&o.fallbacks.map((e,t)=>Object.entries(e).map(e=>{let[s,a]=e;return(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(e_.Z,{children:s}),(0,r.jsx)(e_.Z,{children:Array.isArray(a)?a.join(", "):a}),(0,r.jsx)(e_.Z,{children:(0,r.jsx)(H.Z,{onClick:()=>ln(s,l),children:"Test Fallback"})}),(0,r.jsx)(e_.Z,{children:(0,r.jsx)(eZ.Z,{icon:ex.Z,size:"sm",onClick:()=>j(s)})})]},t.toString()+s)}))})]}),(0,r.jsx)(la,{models:(null==a?void 0:a.data)?a.data.map(e=>e.model_name):[],accessToken:l,routerSettings:o,setRouterSettings:i})]})]})]})}):null},li=t(67951),lc=e=>{let{}=e;return(0,r.jsx)(r.Fragment,{children:(0,r.jsx)(Y.Z,{className:"gap-2 p-8 h-[80vh] w-full mt-2",children:(0,r.jsxs)("div",{className:"mb-5",children:[(0,r.jsx)("p",{className:"text-2xl text-tremor-content-strong dark:text-dark-tremor-content-strong font-semibold",children:"OpenAI Compatible Proxy: API Reference"}),(0,r.jsx)(el.Z,{className:"mt-2 mb-2",children:"LiteLLM is OpenAI Compatible. This means your API Key works with the OpenAI SDK. Just replace the base_url to point to your litellm proxy. Example Below "}),(0,r.jsxs)(eD.Z,{children:[(0,r.jsxs)(ez.Z,{children:[(0,r.jsx)(eU.Z,{children:"OpenAI Python SDK"}),(0,r.jsx)(eU.Z,{children:"LlamaIndex"}),(0,r.jsx)(eU.Z,{children:"Langchain Py"})]}),(0,r.jsxs)(eq.Z,{children:[(0,r.jsx)(eB.Z,{children:(0,r.jsx)(li.Z,{language:"python",children:'\nimport openai\nclient = openai.OpenAI(\n api_key="your_api_key",\n base_url="http://0.0.0.0:4000" # LiteLLM Proxy is OpenAI compatible, Read More: https://docs.litellm.ai/docs/proxy/user_keys\n)\n\nresponse = client.chat.completions.create(\n model="gpt-3.5-turbo", # model to send to the proxy\n messages = [\n {\n "role": "user",\n "content": "this is a test request, write a short poem"\n }\n ]\n)\n\nprint(response)\n '})}),(0,r.jsx)(eB.Z,{children:(0,r.jsx)(li.Z,{language:"python",children:'\nimport os, dotenv\n\nfrom llama_index.llms import AzureOpenAI\nfrom llama_index.embeddings import AzureOpenAIEmbedding\nfrom llama_index import VectorStoreIndex, SimpleDirectoryReader, ServiceContext\n\nllm = AzureOpenAI(\n engine="azure-gpt-3.5", # model_name on litellm proxy\n temperature=0.0,\n azure_endpoint="http://0.0.0.0:4000", # litellm proxy endpoint\n api_key="sk-1234", # litellm proxy API Key\n api_version="2023-07-01-preview",\n)\n\nembed_model = AzureOpenAIEmbedding(\n deployment_name="azure-embedding-model",\n azure_endpoint="http://0.0.0.0:4000",\n api_key="sk-1234",\n api_version="2023-07-01-preview",\n)\n\n\ndocuments = SimpleDirectoryReader("llama_index_data").load_data()\nservice_context = ServiceContext.from_defaults(llm=llm, embed_model=embed_model)\nindex = VectorStoreIndex.from_documents(documents, service_context=service_context)\n\nquery_engine = index.as_query_engine()\nresponse = query_engine.query("What did the author do growing up?")\nprint(response)\n\n '})}),(0,r.jsx)(eB.Z,{children:(0,r.jsx)(li.Z,{language:"python",children:'\nfrom langchain.chat_models import ChatOpenAI\nfrom langchain.prompts.chat import (\n ChatPromptTemplate,\n HumanMessagePromptTemplate,\n SystemMessagePromptTemplate,\n)\nfrom langchain.schema import HumanMessage, SystemMessage\n\nchat = ChatOpenAI(\n openai_api_base="http://0.0.0.0:4000",\n model = "gpt-3.5-turbo",\n temperature=0.1\n)\n\nmessages = [\n SystemMessage(\n content="You are a helpful assistant that im using to make a test request to."\n ),\n HumanMessage(\n content="test from litellm. tell me why it\'s amazing in 1 sentence"\n ),\n]\nresponse = chat(messages)\n\nprint(response)\n\n '})})]})]})]})})})};async function ld(e,l,t,s){console.log("isLocal:",!1);let a=window.location.origin,r=new lr.ZP.OpenAI({apiKey:s,baseURL:a,dangerouslyAllowBrowser:!0});try{for await(let s of(await r.chat.completions.create({model:t,stream:!0,messages:[{role:"user",content:e}]})))console.log(s),s.choices[0].delta.content&&l(s.choices[0].delta.content)}catch(e){h.ZP.error("Error occurred while generating model response. Please try again. Error: ".concat(e),20)}}var lm=e=>{let{accessToken:l,token:t,userRole:s,userID:a}=e,[o,i]=(0,n.useState)(""),[c,d]=(0,n.useState)(""),[m,h]=(0,n.useState)([]),[u,x]=(0,n.useState)(void 0),[p,j]=(0,n.useState)([]);(0,n.useEffect)(()=>{l&&t&&s&&a&&(async()=>{try{let e=await v(l,a,s);if(console.log("model_info:",e),(null==e?void 0:e.data.length)>0){let l=e.data.map(e=>({value:e.id,label:e.id}));console.log(l),j(l),x(e.data[0].id)}}catch(e){console.error("Error fetching model info:",e)}})()},[l,a,s]);let g=(e,l)=>{h(t=>{let s=t[t.length-1];return s&&s.role===e?[...t.slice(0,t.length-1),{role:e,content:s.content+l}]:[...t,{role:e,content:l}]})},f=async()=>{if(""!==c.trim()&&o&&t&&s&&a){h(e=>[...e,{role:"user",content:c}]);try{u&&await ld(c,e=>g("assistant",e),u,o)}catch(e){console.error("Error fetching model response",e),g("assistant","Error fetching model response")}d("")}};if(s&&"Admin Viewer"==s){let{Title:e,Paragraph:l}=eR.default;return(0,r.jsxs)("div",{children:[(0,r.jsx)(e,{level:1,children:"Access Denied"}),(0,r.jsx)(l,{children:"Ask your proxy admin for access to test models"})]})}return(0,r.jsx)("div",{style:{width:"100%",position:"relative"},children:(0,r.jsx)(Y.Z,{className:"gap-2 p-8 h-[80vh] w-full mt-2",children:(0,r.jsx)(eg.Z,{children:(0,r.jsxs)(eD.Z,{children:[(0,r.jsx)(ez.Z,{children:(0,r.jsx)(eU.Z,{children:"Chat"})}),(0,r.jsx)(eq.Z,{children:(0,r.jsxs)(eB.Z,{children:[(0,r.jsx)("div",{className:"sm:max-w-2xl",children:(0,r.jsxs)(Y.Z,{numItems:2,children:[(0,r.jsxs)(J.Z,{children:[(0,r.jsx)(el.Z,{children:"API Key"}),(0,r.jsx)($.Z,{placeholder:"Type API Key here",type:"password",onValueChange:i,value:o})]}),(0,r.jsxs)(J.Z,{className:"mx-2",children:[(0,r.jsx)(el.Z,{children:"Select Model:"}),(0,r.jsx)(ea.default,{placeholder:"Select a Model",onChange:e=>{console.log("selected ".concat(e)),x(e)},options:p,style:{width:"200px"}})]})]})}),(0,r.jsxs)(ew.Z,{className:"mt-5",style:{display:"block",maxHeight:"60vh",overflowY:"auto"},children:[(0,r.jsx)(ek.Z,{children:(0,r.jsx)(eS.Z,{children:(0,r.jsx)(e_.Z,{})})}),(0,r.jsx)(eb.Z,{children:m.map((e,l)=>(0,r.jsx)(eS.Z,{children:(0,r.jsx)(e_.Z,{children:"".concat(e.role,": ").concat(e.content)})},l))})]}),(0,r.jsx)("div",{className:"mt-3",style:{position:"absolute",bottom:5,width:"95%"},children:(0,r.jsxs)("div",{className:"flex",children:[(0,r.jsx)($.Z,{type:"text",value:c,onChange:e=>d(e.target.value),placeholder:"Type your message..."}),(0,r.jsx)(H.Z,{onClick:f,className:"ml-2",children:"Send"})]})})]})})]})})})})},lh=t(33509),lu=t(95781);let{Sider:lx}=lh.default;var lp=e=>{let{setPage:l,userRole:t,defaultSelectedKey:s}=e;return"Admin Viewer"==t?(0,r.jsx)(lh.default,{style:{minHeight:"100vh",maxWidth:"120px"},children:(0,r.jsx)(lx,{width:120,children:(0,r.jsxs)(lu.Z,{mode:"inline",defaultSelectedKeys:s||["4"],style:{height:"100%",borderRight:0},children:[(0,r.jsx)(lu.Z.Item,{onClick:()=>l("api-keys"),children:"API Keys"},"4"),(0,r.jsx)(lu.Z.Item,{onClick:()=>l("models"),children:"Models"},"2"),(0,r.jsx)(lu.Z.Item,{onClick:()=>l("llm-playground"),children:"Chat UI"},"3"),(0,r.jsx)(lu.Z.Item,{onClick:()=>l("usage"),children:"Usage"},"1")]})})}):(0,r.jsx)(lh.default,{style:{minHeight:"100vh",maxWidth:"145px"},children:(0,r.jsx)(lx,{width:145,children:(0,r.jsxs)(lu.Z,{mode:"inline",defaultSelectedKeys:s||["1"],style:{height:"100%",borderRight:0},children:[(0,r.jsx)(lu.Z.Item,{onClick:()=>l("api-keys"),children:(0,r.jsx)(el.Z,{children:"API Keys"})},"1"),(0,r.jsx)(lu.Z.Item,{onClick:()=>l("llm-playground"),children:(0,r.jsx)(el.Z,{children:"Test Key"})},"3"),"Admin"==t?(0,r.jsx)(lu.Z.Item,{onClick:()=>l("models"),children:(0,r.jsx)(el.Z,{children:"Models"})},"2"):null,"Admin"==t?(0,r.jsx)(lu.Z.Item,{onClick:()=>l("usage"),children:(0,r.jsx)(el.Z,{children:"Usage"})},"4"):null,"Admin"==t?(0,r.jsx)(lu.Z.Item,{onClick:()=>l("teams"),children:(0,r.jsx)(el.Z,{children:"Teams"})},"6"):null,"Admin"==t?(0,r.jsx)(lu.Z.Item,{onClick:()=>l("users"),children:(0,r.jsx)(el.Z,{children:"Users"})},"5"):null,"Admin"==t?(0,r.jsx)(lu.Z.Item,{onClick:()=>l("settings"),children:(0,r.jsx)(el.Z,{children:"Logging & Alerts"})},"8"):null,"Admin"==t?(0,r.jsx)(lu.Z.Item,{onClick:()=>l("general-settings"),children:(0,r.jsx)(el.Z,{children:"Router Settings"})},"9"):null,"Admin"==t?(0,r.jsx)(lu.Z.Item,{onClick:()=>l("admin-panel"),children:(0,r.jsx)(el.Z,{children:"Admin"})},"7"):null,(0,r.jsx)(lu.Z.Item,{onClick:()=>l("api_ref"),children:(0,r.jsx)(el.Z,{children:"API Reference"})},"11")]})})})},lj=t(67989),lg=e=>{let{accessToken:l,token:t,userRole:s,userID:a}=e,o=new Date,[i,c]=(0,n.useState)([]),[d,m]=(0,n.useState)([]),[h,u]=(0,n.useState)([]),[x,p]=(0,n.useState)([]),[j,g]=(0,n.useState)([]),[f,y]=(0,n.useState)([]),[Z,w]=(0,n.useState)([]),[b,v]=(0,n.useState)([]),[S,T]=(0,n.useState)([]),[O,M]=(0,n.useState)([]),[R,L]=(0,n.useState)([]),[U,D]=(0,n.useState)(null),z=new Date(o.getFullYear(),o.getMonth(),1),B=new Date(o.getFullYear(),o.getMonth()+1,0),q=V(z),K=V(B);function V(e){let l=e.getFullYear(),t=e.getMonth()+1,s=e.getDate();return"".concat(l,"-").concat(t<10?"0"+t:t,"-").concat(s<10?"0"+s:s)}console.log("Start date is ".concat(q)),console.log("End date is ".concat(K)),(0,n.useEffect)(()=>{l&&t&&s&&a&&(async()=>{try{if(console.log("user role: ".concat(s)),"Admin"==s||"Admin Viewer"==s){let e=await I(l);c(e);let t=(await P(l)).map(e=>({key:(e.key_name||e.key_alias||e.api_key).substring(0,10),spend:e.total_spend}));m(t);let r=(await E(l)).map(e=>({key:e.model,spend:e.total_spend}));u(r);let n=await A(l);console.log("teamSpend",n),g(n.daily_spend),w(n.teams);let o=n.total_spend_per_team;o=o.map(e=>(e.name=e.team_id||"",e.value=e.total_spend||0,e)),v(o);let i=await N(l);y(i.top_10_tags);let d=(await _(l,a,s)).data;console.log("model groups in model dashboard",d);let h=[];for(let e=0;e{if(console.log("result from spend logs call",e),"daily_spend"in e){let l=e.daily_spend;console.log("daily spend",l),c(l);let t=e.top_api_keys;m(t)}else{let t=(await F(l,function(e){let l=[];e.forEach(e=>{Object.entries(e).forEach(e=>{let[t,s]=e;"spend"!==t&&"startTime"!==t&&"models"!==t&&"users"!==t&&l.push({key:t,spend:s})})}),l.sort((e,l)=>Number(l.spend)-Number(e.spend));let t=l.slice(0,5).map(e=>e.key);return console.log("topKeys: ".concat(Object.keys(t[0]))),t}(e))).info.map(e=>({key:(e.key_name||e.key_alias).substring(0,10),spend:e.spend}));m(t),p(function(e){let l={};e.forEach(e=>{Object.entries(e.users).forEach(e=>{let[t,s]=e;""!==t&&null!=t&&"None"!=t&&(l[t]||(l[t]=0),l[t]+=s)})});let t=Object.entries(l).map(e=>{let[l,t]=e;return{user_id:l,spend:t}});t.sort((e,l)=>l.spend-e.spend);let s=t.slice(0,5);return console.log("topKeys: ".concat(Object.values(s[0]))),s}(e)),c(e)}});let e=await k(l,a,s,null);console.log("Model metrics response:",e);let r=[...e].sort((e,l)=>l.avg_latency_seconds-e.avg_latency_seconds);console.log("Sorted by latency:",r),T(e),M(r)}catch(e){console.error("There was an error fetching the data",e)}})()},[l,t,s,a,q,K]);let G=async e=>{if(console.log("Updating model metrics for group:",e),l&&a&&s){D(e);try{let t=await k(l,a,s,e);console.log("Model metrics response:",t);let r=[...t].sort((e,l)=>l.avg_latency_seconds-e.avg_latency_seconds);console.log("Sorted by latency:",r),T(t),M(r)}catch(e){console.error("Failed to fetch model metrics",e)}}};return(0,r.jsxs)("div",{style:{width:"100%"},className:"p-8",children:[(0,r.jsx)(eE,{userID:a,userRole:s,accessToken:l,userSpend:null,selectedTeam:null}),(0,r.jsxs)(eD.Z,{children:[(0,r.jsxs)(ez.Z,{className:"mt-2",children:[(0,r.jsx)(eU.Z,{children:"All Up"}),(0,r.jsx)(eU.Z,{children:"Team Based Usage"}),(0,r.jsx)(eU.Z,{children:"Tag Based Usage"}),(0,r.jsx)(eU.Z,{children:"Model Based Usage"})]}),(0,r.jsxs)(eq.Z,{children:[(0,r.jsx)(eB.Z,{children:(0,r.jsxs)(Y.Z,{numItems:2,className:"gap-2 h-[75vh] w-full",children:[(0,r.jsx)(J.Z,{numColSpan:2,children:(0,r.jsxs)(eg.Z,{children:[(0,r.jsx)(et.Z,{children:"Monthly Spend"}),(0,r.jsx)(ej.Z,{data:i,index:"date",categories:["spend"],colors:["blue"],valueFormatter:e=>"$ ".concat(new Intl.NumberFormat("us").format(e).toString()),yAxisWidth:100,tickGap:5})]})}),(0,r.jsx)(J.Z,{numColSpan:1,children:(0,r.jsxs)(eg.Z,{children:[(0,r.jsx)(et.Z,{children:"Top API Keys"}),(0,r.jsx)(ej.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,r.jsx)(J.Z,{numColSpan:1,children:(0,r.jsxs)(eg.Z,{children:[(0,r.jsx)(et.Z,{children:"Top Users"}),(0,r.jsx)(ej.Z,{className:"mt-4 h-40",data:x,index:"user_id",categories:["spend"],colors:["blue"],yAxisWidth:200,layout:"vertical",showXAxis:!1,showLegend:!1})]})}),(0,r.jsx)(J.Z,{numColSpan:1,children:(0,r.jsxs)(eg.Z,{children:[(0,r.jsx)(et.Z,{children:"Top Models"}),(0,r.jsx)(ej.Z,{className:"mt-4 h-40",data:h,index:"key",categories:["spend"],colors:["blue"],yAxisWidth:200,layout:"vertical",showXAxis:!1,showLegend:!1})]})})]})}),(0,r.jsx)(eB.Z,{children:(0,r.jsxs)(Y.Z,{numItems:2,className:"gap-2 h-[75vh] w-full",children:[(0,r.jsxs)(J.Z,{numColSpan:2,children:[(0,r.jsxs)(eg.Z,{className:"mb-2",children:[(0,r.jsx)(et.Z,{children:"Total Spend Per Team"}),(0,r.jsx)(lj.Z,{data:b})]}),(0,r.jsxs)(eg.Z,{children:[(0,r.jsx)(et.Z,{children:"Daily Spend Per Team"}),(0,r.jsx)(ej.Z,{className:"h-72",data:j,showLegend:!0,index:"date",categories:Z,yAxisWidth:80,colors:["blue","green","yellow","red","purple"],stack:!0})]})]}),(0,r.jsx)(J.Z,{numColSpan:2})]})}),(0,r.jsx)(eB.Z,{children:(0,r.jsxs)(Y.Z,{numItems:2,className:"gap-2 h-[75vh] w-full mb-4",children:[(0,r.jsx)(J.Z,{numColSpan:2,children:(0,r.jsxs)(eg.Z,{children:[(0,r.jsx)(et.Z,{children:"Spend Per Tag - Last 30 Days"}),(0,r.jsxs)(el.Z,{children:["Get Started Tracking cost per tag ",(0,r.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/enterprise#tracking-spend-for-custom-tags",target:"_blank",children:"here"})]}),(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(ek.Z,{children:(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(ev.Z,{children:"Tag"}),(0,r.jsx)(ev.Z,{children:"Spend"}),(0,r.jsx)(ev.Z,{children:"Requests"})]})}),(0,r.jsx)(eb.Z,{children:f.map(e=>(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(e_.Z,{children:e.name}),(0,r.jsx)(e_.Z,{children:e.value}),(0,r.jsx)(e_.Z,{children:e.log_count})]},e.name))})]})]})}),(0,r.jsx)(J.Z,{numColSpan:2})]})}),(0,r.jsxs)(eB.Z,{children:[(0,r.jsx)(et.Z,{children:"Filter By Model Group"}),(0,r.jsx)("p",{style:{fontSize:"0.85rem",color:"#808080"},children:"View how requests were load balanced within a model group"}),(0,r.jsx)("p",{style:{fontSize:"0.85rem",color:"#808080",fontStyle:"italic"},children:"(Beta feature) only supported for Azure Model Groups"}),(0,r.jsxs)(eA.Z,{className:"mb-4 mt-2",defaultValue:"all",children:[(0,r.jsx)(eN.Z,{value:"all",onClick:()=>G(null),children:"All Model Groups"}),R.map((e,l)=>(0,r.jsx)(eN.Z,{value:e,onClick:()=>G(e),children:e},l))]}),(0,r.jsxs)(eg.Z,{children:[(0,r.jsx)(et.Z,{children:"Number Requests per Model"}),(0,r.jsx)(ej.Z,{data:S,className:"h-[50vh]",index:"model",categories:["num_requests"],colors:["blue"],yAxisWidth:400,layout:"vertical",tickGap:5})]}),(0,r.jsxs)(eg.Z,{className:"mt-4",children:[(0,r.jsx)(et.Z,{children:"Latency Per Model"}),(0,r.jsx)(ej.Z,{data:O,className:"h-[50vh]",index:"model",categories:["avg_latency_seconds"],colors:["red"],yAxisWidth:400,layout:"vertical",tickGap:5})]})]})]})]})]})},lf=()=>{let{Title:e,Paragraph:l}=eR.default,[t,s]=(0,n.useState)(""),[a,i]=(0,n.useState)(null),[c,d]=(0,n.useState)(null),[h,u]=(0,n.useState)(null),[x,p]=(0,n.useState)(!0),j=(0,o.useSearchParams)(),[g,f]=(0,n.useState)({data:[]}),y=j.get("userID"),Z=j.get("token"),[w,b]=(0,n.useState)("api-keys"),[_,k]=(0,n.useState)(null);return(0,n.useEffect)(()=>{if(Z){let e=(0,eM.o)(Z);if(e){if(console.log("Decoded token:",e),console.log("Decoded key:",e.key),k(e.key),e.user_role){let l=function(e){if(!e)return"Undefined Role";switch(console.log("Received user role: ".concat(e.toLowerCase())),console.log("Received user role length: ".concat(e.toLowerCase().length)),e.toLowerCase()){case"app_owner":case"demo_app_owner":return"App Owner";case"app_admin":case"proxy_admin":return"Admin";case"proxy_admin_viewer":return"Admin Viewer";case"app_user":return"App User";default:return"Unknown Role"}}(e.user_role);console.log("Decoded user_role:",l),s(l),"Admin Viewer"==l&&b("usage")}else console.log("User role not defined");e.user_email?i(e.user_email):console.log("User Email is not set ".concat(e)),e.login_method?p("username_password"==e.login_method):console.log("User Email is not set ".concat(e))}}},[Z]),(0,r.jsx)(n.Suspense,{fallback:(0,r.jsx)("div",{children:"Loading..."}),children:(0,r.jsxs)("div",{className:"flex flex-col min-h-screen",children:[(0,r.jsx)(m,{userID:y,userRole:t,userEmail:a,showSSOBanner:x}),(0,r.jsxs)("div",{className:"flex flex-1 overflow-auto",children:[(0,r.jsx)("div",{className:"mt-8",children:(0,r.jsx)(lp,{setPage:b,userRole:t,defaultSelectedKey:null})}),"api-keys"==w?(0,r.jsx)(eL,{userID:y,userRole:t,teams:c,keys:h,setUserRole:s,userEmail:a,setUserEmail:i,setTeams:d,setKeys:u}):"models"==w?(0,r.jsx)(e8,{userID:y,userRole:t,token:Z,accessToken:_,modelData:g,setModelData:f}):"llm-playground"==w?(0,r.jsx)(lm,{userID:y,userRole:t,token:Z,accessToken:_}):"users"==w?(0,r.jsx)(e6,{userID:y,userRole:t,token:Z,keys:h,teams:c,accessToken:_,setKeys:u}):"teams"==w?(0,r.jsx)(e7,{teams:c,setTeams:d,searchParams:j,accessToken:_,userID:y,userRole:t}):"admin-panel"==w?(0,r.jsx)(le,{setTeams:d,searchParams:j,accessToken:_,showSSOBanner:x}):"api_ref"==w?(0,r.jsx)(lc,{}):"settings"==w?(0,r.jsx)(lt,{userID:y,userRole:t,accessToken:_}):"general-settings"==w?(0,r.jsx)(lo,{userID:y,userRole:t,accessToken:_,modelData:g}):(0,r.jsx)(lg,{userID:y,userRole:t,token:Z,accessToken:_})]})]})})}}},function(e){e.O(0,[447,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-781ca5f151d78d1d.js b/ui/litellm-dashboard/out/_next/static/chunks/app/page-781ca5f151d78d1d.js deleted file mode 100644 index 40715cd067c..00000000000 --- a/ui/litellm-dashboard/out/_next/static/chunks/app/page-781ca5f151d78d1d.js +++ /dev/null @@ -1 +0,0 @@ -(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[931],{20661:function(e,l,t){Promise.resolve().then(t.bind(t,27125))},27125:function(e,l,t){"use strict";t.r(l),t.d(l,{default:function(){return lf}});var s,a,r=t(3827),n=t(64090),o=t(47907),i=t(8792),c=t(40491),d=t(65270),m=e=>{let{userID:l,userRole:t,userEmail:s,showSSOBanner:a}=e;console.log("User ID:",l),console.log("userEmail:",s),console.log("showSSOBanner:",a);let n=[{key:"1",label:(0,r.jsxs)(r.Fragment,{children:[(0,r.jsxs)("p",{children:["Role: ",t]}),(0,r.jsxs)("p",{children:["ID: ",l]})]})}];return(0,r.jsxs)("nav",{className:"left-0 right-0 top-0 flex justify-between items-center h-12 mb-4",children:[(0,r.jsx)("div",{className:"text-left my-2 absolute top-0 left-0",children:(0,r.jsx)("div",{className:"flex flex-col items-center",children:(0,r.jsx)(i.default,{href:"/",children:(0,r.jsx)("button",{className:"text-gray-800 rounded text-center",children:(0,r.jsx)("img",{src:"/get_image",width:160,height:160,alt:"LiteLLM Brand",className:"mr-2"})})})})}),(0,r.jsxs)("div",{className:"text-right mx-4 my-2 absolute top-0 right-0 flex items-center justify-end space-x-2",children:[a?(0,r.jsx)("div",{style:{padding:"6px",borderRadius:"8px"},children:(0,r.jsx)("a",{href:"https://calendly.com/d/4mp-gd3-k5k/litellm-1-1-onboarding-chat",target:"_blank",style:{fontSize:"14px",textDecoration:"underline"},children:"Request hosted proxy"})}):null,(0,r.jsx)("div",{style:{border:"1px solid #391085",padding:"6px",borderRadius:"8px"},children:(0,r.jsx)(c.Z,{menu:{items:n},children:(0,r.jsx)(d.Z,{children:s})})})]})]})},h=t(80588);let u=async()=>{try{let e=await fetch("https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json"),l=await e.json();return console.log("received data: ".concat(l)),l}catch(e){throw console.error("Failed to get model cost map:",e),e}},x=async(e,l)=>{try{let t=await fetch("/model/new",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...l})});if(!t.ok){let e=await t.text();throw h.ZP.error("Failed to create key: "+e,20),console.error("Error response from the server:",e),Error("Network response was not ok")}let s=await t.json();return console.log("API Response:",s),h.ZP.success("Model created successfully. Wait 60s and refresh on 'All Models' page"),s}catch(e){throw console.error("Failed to create key:",e),e}},p=async(e,l)=>{console.log("model_id in model delete call: ".concat(l));try{let t=await fetch("/model/delete",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({id:l})});if(!t.ok){let e=await t.text();throw h.ZP.error("Failed to create key: "+e,20),console.error("Error response from the server:",e),Error("Network response was not ok")}let s=await t.json();return console.log("API Response:",s),h.ZP.success("Model deleted successfully. Restart server to see this."),s}catch(e){throw console.error("Failed to create key:",e),e}},j=async(e,l,t)=>{try{if(console.log("Form Values in keyCreateCall:",t),t.description&&(t.metadata||(t.metadata={}),t.metadata.description=t.description,delete t.description,t.metadata=JSON.stringify(t.metadata)),t.metadata){console.log("formValues.metadata:",t.metadata);try{t.metadata=JSON.parse(t.metadata)}catch(e){throw h.ZP.error("Failed to parse metadata: "+e,20),Error("Failed to parse metadata: "+e)}}console.log("Form Values after check:",t);let s=await fetch("/key/generate",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({user_id:l,...t})});if(!s.ok){let e=await s.text();throw h.ZP.error("Failed to create key: "+e,20),console.error("Error response from the server:",e),Error("Network response was not ok")}let a=await s.json();return console.log("API Response:",a),a}catch(e){throw console.error("Failed to create key:",e),e}},g=async(e,l,t)=>{try{if(console.log("Form Values in keyCreateCall:",t),t.description&&(t.metadata||(t.metadata={}),t.metadata.description=t.description,delete t.description,t.metadata=JSON.stringify(t.metadata)),t.metadata){console.log("formValues.metadata:",t.metadata);try{t.metadata=JSON.parse(t.metadata)}catch(e){throw h.ZP.error("Failed to parse metadata: "+e,20),Error("Failed to parse metadata: "+e)}}console.log("Form Values after check:",t);let s=await fetch("/user/new",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({user_id:l,...t})});if(!s.ok){let e=await s.text();throw h.ZP.error("Failed to create key: "+e,20),console.error("Error response from the server:",e),Error("Network response was not ok")}let a=await s.json();return console.log("API Response:",a),a}catch(e){throw console.error("Failed to create key:",e),e}},f=async(e,l)=>{try{console.log("in keyDeleteCall:",l);let t=await fetch("/key/delete",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({keys:[l]})});if(!t.ok){let e=await t.text();throw h.ZP.error("Failed to delete key: "+e,20),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to create key:",e),e}},y=async(e,l)=>{try{console.log("in teamDeleteCall:",l);let t=await fetch("/team/delete",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({team_ids:[l]})});if(!t.ok){let e=await t.text();throw h.ZP.error("Failed to delete team: "+e,20),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to delete key:",e),e}},Z=async function(e,l,t){let s=arguments.length>3&&void 0!==arguments[3]&&arguments[3],a=arguments.length>4?arguments[4]:void 0,r=arguments.length>5?arguments[5]:void 0;try{let n="/user/info";"App Owner"==t&&l&&(n="".concat(n,"?user_id=").concat(l)),"App User"==t&&l&&(n="".concat(n,"?user_id=").concat(l)),console.log("in userInfoCall viewAll=",s),s&&r&&null!=a&&void 0!=a&&(n="".concat(n,"?view_all=true&page=").concat(a,"&page_size=").concat(r));let o=await fetch(n,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!o.ok){let e=await o.text();throw h.ZP.error(e,20),Error("Network response was not ok")}let i=await o.json();return console.log("API Response:",i),i}catch(e){throw console.error("Failed to create key:",e),e}},w=async(e,l)=>{try{let t="/team/info";l&&(t="".concat(t,"?team_id=").concat(l)),console.log("in teamInfoCall");let s=await fetch(t,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!s.ok){let e=await s.text();throw h.ZP.error(e,20),Error("Network response was not ok")}let a=await s.json();return console.log("API Response:",a),a}catch(e){throw console.error("Failed to create key:",e),e}},b=async e=>{try{let l=await fetch("/global/spend",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw h.ZP.error(e,20),Error("Network response was not ok")}return await l.json()}catch(e){throw console.error("Failed to create key:",e),e}},_=async(e,l,t)=>{try{let l=await fetch("/v2/model/info",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw h.ZP.error(e,20),Error("Network response was not ok")}let t=await l.json();return console.log("modelInfoCall:",t),t}catch(e){throw console.error("Failed to create key:",e),e}},k=async(e,l,t,s)=>{try{let l="/model/metrics";s&&(l="".concat(l,"?_selected_model_group=").concat(s));let t=await fetch(l,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw h.ZP.error(e,20),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},v=async(e,l,t)=>{try{let l=await fetch("/models",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw h.ZP.error(e,20),Error("Network response was not ok")}return await l.json()}catch(e){throw console.error("Failed to create key:",e),e}},S=async(e,l)=>{try{let t="/global/spend/logs";console.log("in keySpendLogsCall:",t);let s=await fetch("".concat(t,"?api_key=").concat(l),{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!s.ok){let e=await s.text();throw h.ZP.error(e,20),Error("Network response was not ok")}let a=await s.json();return console.log(a),a}catch(e){throw console.error("Failed to create key:",e),e}},A=async e=>{try{let l="/global/spend/teams";console.log("in teamSpendLogsCall:",l);let t=await fetch("".concat(l),{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw h.ZP.error(e,20),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to create key:",e),e}},N=async e=>{try{let l="/global/spend/tags";console.log("in tagsSpendLogsCall:",l);let t=await fetch("".concat(l),{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw h.ZP.error(e,20),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to create key:",e),e}},C=async(e,l,t,s,a,r)=>{try{console.log("user role in spend logs call: ".concat(t));let l="/spend/logs";l="App Owner"==t?"".concat(l,"?user_id=").concat(s,"&start_date=").concat(a,"&end_date=").concat(r):"".concat(l,"?start_date=").concat(a,"&end_date=").concat(r);let n=await fetch(l,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!n.ok){let e=await n.text();throw h.ZP.error(e,20),Error("Network response was not ok")}let o=await n.json();return console.log(o),o}catch(e){throw console.error("Failed to create key:",e),e}},I=async e=>{try{let l=await fetch("/global/spend/logs",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw h.ZP.error(e,20),Error("Network response was not ok")}let t=await l.json();return console.log(t),t}catch(e){throw console.error("Failed to create key:",e),e}},P=async e=>{try{let l=await fetch("/global/spend/keys?limit=5",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw h.ZP.error(e,20),Error("Network response was not ok")}let t=await l.json();return console.log(t),t}catch(e){throw console.error("Failed to create key:",e),e}},T=async(e,l)=>{try{l&&JSON.stringify({api_key:l});let t={method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}};l&&(t.body=JSON.stringify({api_key:l}));let s=await fetch("/global/spend/end_users",t);if(!s.ok){let e=await s.text();throw h.ZP.error(e,20),Error("Network response was not ok")}let a=await s.json();return console.log(a),a}catch(e){throw console.error("Failed to create key:",e),e}},E=async e=>{try{let l=await fetch("/global/spend/models?limit=5",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw h.ZP.error(e,20),Error("Network response was not ok")}let t=await l.json();return console.log(t),t}catch(e){throw console.error("Failed to create key:",e),e}},F=async(e,l)=>{try{let t=await fetch("/v2/key/info",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({keys:l})});if(!t.ok){let e=await t.text();throw h.ZP.error(e,20),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to create key:",e),e}},O=async e=>{try{let l="/user/get_requests";console.log("in userGetRequesedtModelsCall:",l);let t=await fetch(l,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw h.ZP.error("Failed to delete key: "+e,20),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to get requested models:",e),e}},M=async(e,l)=>{try{let t="/user/get_users?role=".concat(l);console.log("in userGetAllUsersCall:",t);let s=await fetch(t,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!s.ok){let e=await s.text();throw h.ZP.error("Failed to delete key: "+e,20),Error("Network response was not ok")}let a=await s.json();return console.log(a),a}catch(e){throw console.error("Failed to get requested models:",e),e}},R=async(e,l)=>{try{console.log("Form Values in teamCreateCall:",l);let t=await fetch("/team/new",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...l})});if(!t.ok){let e=await t.text();throw h.ZP.error("Failed to create key: "+e,20),console.error("Error response from the server:",e),Error("Network response was not ok")}let s=await t.json();return console.log("API Response:",s),s}catch(e){throw console.error("Failed to create key:",e),e}},L=async(e,l)=>{try{console.log("Form Values in keyUpdateCall:",l);let t=await fetch("/key/update",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...l})});if(!t.ok){let e=await t.text();throw h.ZP.error("Failed to update key: "+e,20),console.error("Error response from the server:",e),Error("Network response was not ok")}let s=await t.json();return console.log("Update key Response:",s),s}catch(e){throw console.error("Failed to create key:",e),e}},U=async(e,l)=>{try{console.log("Form Values in teamUpateCall:",l);let t=await fetch("/team/update",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...l})});if(!t.ok){let e=await t.text();throw h.ZP.error("Failed to update team: "+e,20),console.error("Error response from the server:",e),Error("Network response was not ok")}let s=await t.json();return console.log("Update Team Response:",s),s}catch(e){throw console.error("Failed to create key:",e),e}},D=async(e,l)=>{try{console.log("Form Values in modelUpateCall:",l);let t=await fetch("/model/update",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...l})});if(!t.ok){let e=await t.text();throw h.ZP.error("Failed to update model: "+e,20),console.error("Error update from the server:",e),Error("Network response was not ok")}let s=await t.json();return console.log("Update model Response:",s),s}catch(e){throw console.error("Failed to update model:",e),e}},z=async(e,l,t)=>{try{console.log("Form Values in teamMemberAddCall:",t);let s=await fetch("/team/member_add",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({team_id:l,member:t})});if(!s.ok){let e=await s.text();throw h.ZP.error("Failed to create key: "+e,20),console.error("Error response from the server:",e),Error("Network response was not ok")}let a=await s.json();return console.log("API Response:",a),a}catch(e){throw console.error("Failed to create key:",e),e}},B=async(e,l,t)=>{try{console.log("Form Values in userUpdateUserCall:",l);let s={...l};null!==t&&(s.user_role=t),s=JSON.stringify(s);let a=await fetch("/user/update",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:s});if(!a.ok){let e=await a.text();throw h.ZP.error("Failed to create key: "+e,20),console.error("Error response from the server:",e),Error("Network response was not ok")}let r=await a.json();return console.log("API Response:",r),r}catch(e){throw console.error("Failed to create key:",e),e}},q=async(e,l)=>{try{let t=await fetch("/global/predict/spend/logs",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({data:l})});if(!t.ok){let e=await t.text();throw h.ZP.error(e,20),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to create key:",e),e}},K=async(e,l)=>{try{let t="/health/services?service=".concat(l);console.log("Checking Slack Budget Alerts service health");let s=await fetch(t,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!s.ok){let e=await s.text();throw h.ZP.error("Failed ".concat(l," service health check ")+e),Error(e)}let a=await s.json();return h.ZP.success("Test request to ".concat(l," made - check logs/alerts on ").concat(l," to verify")),a}catch(e){throw console.error("Failed to perform health check:",e),e}},V=async(e,l,t)=>{try{let l=await fetch("/get/config/callbacks",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw h.ZP.error(e,20),Error("Network response was not ok")}return await l.json()}catch(e){throw console.error("Failed to get callbacks:",e),e}},G=async(e,l)=>{try{let t=await fetch("/config/update",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...l})});if(!t.ok){let e=await t.text();throw h.ZP.error(e,20),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to set callbacks:",e),e}},W=async e=>{try{let l=await fetch("/health",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw h.ZP.error(e),Error("Network response was not ok")}return await l.json()}catch(e){throw console.error("Failed to call /health:",e),e}};var J=t(10384),Y=t(46453),H=t(2179),$=t(52273),X=t(26780),Q=t(15595),ee=t(6698),el=t(71801),et=t(42440),es=t(42308),ea=t(50670),er=t(81583),en=t(99129),eo=t(44839),ei=t(88707),ec=t(1861);let{Option:ed}=ea.default;var em=e=>{let{userID:l,team:t,userRole:s,accessToken:a,data:o,setData:i}=e,[c]=er.Z.useForm(),[d,m]=(0,n.useState)(!1),[u,x]=(0,n.useState)(null),[p,g]=(0,n.useState)(null),[f,y]=(0,n.useState)([]),Z=()=>{m(!1),c.resetFields()},w=()=>{m(!1),x(null),c.resetFields()};(0,n.useEffect)(()=>{(async()=>{try{if(null===l||null===s)return;if(null!==a){let e=(await v(a,l,s)).data.map(e=>e.id);console.log("available_model_names:",e),y(e)}}catch(e){console.error("Error fetching user models:",e)}})()},[a,l,s]);let b=async e=>{try{h.ZP.info("Making API Call"),m(!0);let t=await j(a,l,e);console.log("key create Response:",t),i(e=>e?[...e,t]:[t]),x(t.key),g(t.soft_budget),h.ZP.success("API Key Created"),c.resetFields(),localStorage.removeItem("userData"+l)}catch(e){console.error("Error creating the key:",e)}};return(0,r.jsxs)("div",{children:[(0,r.jsx)(H.Z,{className:"mx-auto",onClick:()=>m(!0),children:"+ Create New Key"}),(0,r.jsx)(en.Z,{title:"Create Key",visible:d,width:800,footer:null,onOk:Z,onCancel:w,children:(0,r.jsxs)(er.Z,{form:c,onFinish:b,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(er.Z.Item,{label:"Key Name",name:"key_alias",rules:[{required:!0,message:"Please input a key name"}],help:"required",children:(0,r.jsx)($.Z,{placeholder:""})}),(0,r.jsx)(er.Z.Item,{label:"Team ID",name:"team_id",hidden:!0,initialValue:t?t.team_id:null,valuePropName:"team_id",className:"mt-8",children:(0,r.jsx)(eo.Z,{value:t?t.team_alias:"",disabled:!0})}),(0,r.jsx)(er.Z.Item,{label:"Models",name:"models",rules:[{required:!0,message:"Please select a model"}],help:"required",children:(0,r.jsxs)(ea.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},onChange:e=>{e.includes("all-team-models")&&c.setFieldsValue({models:["all-team-models"]})},children:[(0,r.jsx)(ed,{value:"all-team-models",children:"All Team Models"},"all-team-models"),t&&t.models?t.models.includes("all-proxy-models")?f.map(e=>(0,r.jsx)(ed,{value:e,children:e},e)):t.models.map(e=>(0,r.jsx)(ed,{value:e,children:e},e)):f.map(e=>(0,r.jsx)(ed,{value:e,children:e},e))]})}),(0,r.jsxs)(X.Z,{className:"mt-20 mb-8",children:[(0,r.jsx)(ee.Z,{children:(0,r.jsx)("b",{children:"Optional Settings"})}),(0,r.jsxs)(Q.Z,{children:[(0,r.jsx)(er.Z.Item,{className:"mt-8",label:"Max Budget (USD)",name:"max_budget",help:"Budget cannot exceed team max budget: $".concat((null==t?void 0:t.max_budget)!==null&&(null==t?void 0:t.max_budget)!==void 0?null==t?void 0:t.max_budget:"unlimited"),rules:[{validator:async(e,l)=>{if(l&&t&&null!==t.max_budget&&l>t.max_budget)throw Error("Budget cannot exceed team max budget: $".concat(t.max_budget))}}],children:(0,r.jsx)(ei.Z,{step:.01,precision:2,width:200})}),(0,r.jsx)(er.Z.Item,{className:"mt-8",label:"Reset Budget",name:"budget_duration",help:"Team Reset Budget: ".concat((null==t?void 0:t.budget_duration)!==null&&(null==t?void 0:t.budget_duration)!==void 0?null==t?void 0:t.budget_duration:"None"),children:(0,r.jsxs)(ea.default,{defaultValue:null,placeholder:"n/a",children:[(0,r.jsx)(ea.default.Option,{value:"24h",children:"daily"}),(0,r.jsx)(ea.default.Option,{value:"30d",children:"monthly"})]})}),(0,r.jsx)(er.Z.Item,{className:"mt-8",label:"Tokens per minute Limit (TPM)",name:"tpm_limit",help:"TPM cannot exceed team TPM limit: ".concat((null==t?void 0:t.tpm_limit)!==null&&(null==t?void 0:t.tpm_limit)!==void 0?null==t?void 0:t.tpm_limit:"unlimited"),rules:[{validator:async(e,l)=>{if(l&&t&&null!==t.tpm_limit&&l>t.tpm_limit)throw Error("TPM limit cannot exceed team TPM limit: ".concat(t.tpm_limit))}}],children:(0,r.jsx)(ei.Z,{step:1,width:400})}),(0,r.jsx)(er.Z.Item,{className:"mt-8",label:"Requests per minute Limit (RPM)",name:"rpm_limit",help:"RPM cannot exceed team RPM limit: ".concat((null==t?void 0:t.rpm_limit)!==null&&(null==t?void 0:t.rpm_limit)!==void 0?null==t?void 0:t.rpm_limit:"unlimited"),rules:[{validator:async(e,l)=>{if(l&&t&&null!==t.rpm_limit&&l>t.rpm_limit)throw Error("RPM limit cannot exceed team RPM limit: ".concat(t.rpm_limit))}}],children:(0,r.jsx)(ei.Z,{step:1,width:400})}),(0,r.jsx)(er.Z.Item,{label:"Expire Key (eg: 30s, 30h, 30d)",name:"duration",className:"mt-8",children:(0,r.jsx)($.Z,{placeholder:""})}),(0,r.jsx)(er.Z.Item,{label:"Metadata",name:"metadata",children:(0,r.jsx)(eo.Z.TextArea,{rows:4,placeholder:"Enter metadata as JSON"})})]})]})]}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ec.ZP,{htmlType:"submit",children:"Create Key"})})]})}),u&&(0,r.jsx)(en.Z,{visible:d,onOk:Z,onCancel:w,footer:null,children:(0,r.jsxs)(Y.Z,{numItems:1,className:"gap-2 w-full",children:[(0,r.jsx)(et.Z,{children:"Save your Key"}),(0,r.jsx)(J.Z,{numColSpan:1,children:(0,r.jsxs)("p",{children:["Please save this secret key somewhere safe and accessible. For security reasons, ",(0,r.jsx)("b",{children:"you will not be able to view it again"})," ","through your LiteLLM account. If you lose this secret key, you will need to generate a new one."]})}),(0,r.jsx)(J.Z,{numColSpan:1,children:null!=u?(0,r.jsxs)("div",{children:[(0,r.jsx)(el.Z,{className:"mt-3",children:"API Key:"}),(0,r.jsx)("div",{style:{background:"#f8f8f8",padding:"10px",borderRadius:"5px",marginBottom:"10px"},children:(0,r.jsx)("pre",{style:{wordWrap:"break-word",whiteSpace:"normal"},children:u})}),(0,r.jsx)(es.CopyToClipboard,{text:u,onCopy:()=>{h.ZP.success("API Key copied to clipboard")},children:(0,r.jsx)(H.Z,{className:"mt-3",children:"Copy API Key"})})]}):(0,r.jsx)(el.Z,{children:"Key being created, this might take 30s"})})]})})]})},eh=t(9454),eu=t(98941),ex=t(33393),ep=t(5),ej=t(9853),eg=t(13810),ef=t(39290),ey=t(66952),eZ=t(61244),ew=t(10827),eb=t(3851),e_=t(2044),ek=t(64167),ev=t(74480),eS=t(7178),eA=t(95093),eN=t(27166);let{Option:eC}=ea.default;var eI=e=>{let{userID:l,userRole:t,accessToken:s,selectedTeam:a,data:o,setData:i,teams:c}=e,[d,m]=(0,n.useState)(!1),[u,x]=(0,n.useState)(!1),[p,j]=(0,n.useState)(null),[g,y]=n.useState(null),[Z,w]=(0,n.useState)(null),[b,_]=(0,n.useState)(null),[k,A]=(0,n.useState)(""),[N,C]=(0,n.useState)(!1),[I,P]=(0,n.useState)(null),[T,E]=(0,n.useState)([]),F=new Set,[O,M]=(0,n.useState)(F);(0,n.useEffect)(()=>{(async()=>{try{if(null===l)return;if(null!==s&&null!==t){let e=(await v(s,l,t)).data.map(e=>e.id);console.log("available_model_names:",e),E(e)}}catch(e){console.error("Error fetching user models:",e)}})()},[s,l,t]),(0,n.useEffect)(()=>{if(c){let e=new Set;c.forEach((l,t)=>{let s=l.team_id;e.add(s)}),M(e)}},[c]);let R=e=>{console.log("handleEditClick:",e),null==e.token&&null!==e.token_id&&(e.token=e.token_id),P(e),C(!0)},U=async e=>{if(null==s)return;let l=e.token;e.key=l,console.log("handleEditSubmit:",e);let t=await L(s,e);console.log("handleEditSubmit: newKeyValues",t),o&&i(o.map(e=>e.token===l?t:e)),h.ZP.success("Key updated successfully"),C(!1),P(null)},D=async e=>{try{if(null==s||null==e)return;console.log("accessToken: ".concat(s,"; token: ").concat(e.token));let l=await S(s,e.token);console.log("Response:",l),_(l);try{let e=await q(s,l);console.log("Response2:",e);let t=[...l,...e.response];_(t),A(e.predicted_spend),console.log("Combined Data:",t)}catch(e){console.error("There was an error fetching the predicted data",e)}}catch(e){console.error("There was an error fetching the data",e)}};(0,n.useEffect)(()=>{D(Z)},[Z]);let z=async e=>{console.log("handleDelete:",e),null==e.token&&null!==e.token_id&&(e.token=e.token_id),null!=o&&(j(e.token),localStorage.removeItem("userData"+l),x(!0))},B=async()=>{if(null!=p&&null!=o){try{await f(s,p);let e=o.filter(e=>e.token!==p);i(e)}catch(e){console.error("Error deleting the key:",e)}x(!1),j(null)}};if(null!=o)return console.log("RERENDER TRIGGERED"),(0,r.jsxs)("div",{children:[(0,r.jsxs)(eg.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh] mb-4 mt-2",children:[(0,r.jsxs)(ew.Z,{className:"mt-5 max-h-[300px] min-h-[300px]",children:[(0,r.jsx)(ek.Z,{children:(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(ev.Z,{children:"Key Alias"}),(0,r.jsx)(ev.Z,{children:"Secret Key"}),(0,r.jsx)(ev.Z,{children:"Spend (USD)"}),(0,r.jsx)(ev.Z,{children:"Budget (USD)"}),(0,r.jsx)(ev.Z,{children:"Models"}),(0,r.jsx)(ev.Z,{children:"TPM / RPM Limits"})]})}),(0,r.jsx)(eb.Z,{children:o.map(e=>{if(console.log(e),"litellm-dashboard"===e.team_id)return null;if(a){if(console.log("item team id: ".concat(e.team_id,", knownTeamIDs.has(item.team_id): ").concat(O.has(e.team_id),", selectedTeam id: ").concat(a.team_id)),(null!=a.team_id||null===e.team_id||O.has(e.team_id))&&e.team_id!=a.team_id)return null;console.log("item team id: ".concat(e.team_id,", is returned"))}return(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(e_.Z,{style:{maxWidth:"2px",whiteSpace:"pre-wrap",overflow:"hidden"},children:null!=e.key_alias?(0,r.jsx)(el.Z,{children:e.key_alias}):(0,r.jsx)(el.Z,{children:"Not Set"})}),(0,r.jsx)(e_.Z,{children:(0,r.jsx)(el.Z,{children:e.key_name})}),(0,r.jsx)(e_.Z,{children:(0,r.jsx)(el.Z,{children:(()=>{try{return parseFloat(e.spend).toFixed(4)}catch(l){return e.spend}})()})}),(0,r.jsx)(e_.Z,{children:null!=e.max_budget?(0,r.jsx)(el.Z,{children:e.max_budget}):(0,r.jsx)(el.Z,{children:"Unlimited"})}),(0,r.jsx)(e_.Z,{children:Array.isArray(e.models)?(0,r.jsx)("div",{style:{display:"flex",flexDirection:"column"},children:0===e.models.length?(0,r.jsx)(r.Fragment,{children:a&&a.models&&a.models.length>0?a.models.map((e,l)=>"all-proxy-models"===e?(0,r.jsx)(ep.Z,{size:"xs",className:"mb-1",color:"red",children:(0,r.jsx)(el.Z,{children:"All Proxy Models"})},l):"all-team-models"===e?(0,r.jsx)(ep.Z,{size:"xs",className:"mb-1",color:"red",children:(0,r.jsx)(el.Z,{children:"All Team Models"})},l):(0,r.jsx)(ep.Z,{size:"xs",className:"mb-1",color:"blue",children:(0,r.jsx)(el.Z,{children:e.length>30?"".concat(e.slice(0,30),"..."):e})},l)):(0,r.jsx)(ep.Z,{size:"xs",className:"mb-1",color:"blue",children:(0,r.jsx)(el.Z,{children:"all-proxy-models"})})}):e.models.map((e,l)=>"all-proxy-models"===e?(0,r.jsx)(ep.Z,{size:"xs",className:"mb-1",color:"red",children:(0,r.jsx)(el.Z,{children:"All Proxy Models"})},l):"all-team-models"===e?(0,r.jsx)(ep.Z,{size:"xs",className:"mb-1",color:"red",children:(0,r.jsx)(el.Z,{children:"All Team Models"})},l):(0,r.jsx)(ep.Z,{size:"xs",className:"mb-1",color:"blue",children:(0,r.jsx)(el.Z,{children:e.length>30?"".concat(e.slice(0,30),"..."):e})},l))}):null}),(0,r.jsx)(e_.Z,{children:(0,r.jsxs)(el.Z,{children:["TPM: ",e.tpm_limit?e.tpm_limit:"Unlimited"," ",(0,r.jsx)("br",{})," RPM:"," ",e.rpm_limit?e.rpm_limit:"Unlimited"]})}),(0,r.jsxs)(e_.Z,{children:[(0,r.jsx)(eZ.Z,{onClick:()=>{w(e),y(e.id)},icon:eh.Z,size:"sm"}),(0,r.jsx)(ef.Z,{open:null!==g,onClose:()=>{y(null),w(null)},children:(0,r.jsx)(ey.Z,{children:Z&&(0,r.jsxs)(r.Fragment,{children:[(0,r.jsxs)("div",{className:"grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3",children:[(0,r.jsxs)(eg.Z,{children:[(0,r.jsx)("p",{className:"text-tremor-default font-medium text-tremor-content dark:text-dark-tremor-content",children:"Spend"}),(0,r.jsx)("div",{className:"mt-2 flex items-baseline space-x-2.5",children:(0,r.jsx)("p",{className:"text-tremor font-semibold text-tremor-content-strong dark:text-dark-tremor-content-strong",children:(()=>{try{return parseFloat(Z.spend).toFixed(4)}catch(e){return Z.spend}})()})})]}),(0,r.jsxs)(eg.Z,{children:[(0,r.jsx)("p",{className:"text-tremor-default font-medium text-tremor-content dark:text-dark-tremor-content",children:"Budget"}),(0,r.jsx)("div",{className:"mt-2 flex items-baseline space-x-2.5",children:(0,r.jsx)("p",{className:"text-tremor font-semibold text-tremor-content-strong dark:text-dark-tremor-content-strong",children:null!=Z.max_budget?(0,r.jsx)(r.Fragment,{children:Z.max_budget}):(0,r.jsx)(r.Fragment,{children:"Unlimited"})})})]},e.name),(0,r.jsxs)(eg.Z,{children:[(0,r.jsx)("p",{className:"text-tremor-default font-medium text-tremor-content dark:text-dark-tremor-content",children:"Expires"}),(0,r.jsx)("div",{className:"mt-2 flex items-baseline space-x-2.5",children:(0,r.jsx)("p",{className:"text-tremor-default font-small text-tremor-content-strong dark:text-dark-tremor-content-strong",children:null!=Z.expires?(0,r.jsx)(r.Fragment,{children:new Date(Z.expires).toLocaleString(void 0,{day:"numeric",month:"long",year:"numeric",hour:"numeric",minute:"numeric",second:"numeric"})}):(0,r.jsx)(r.Fragment,{children:"Never"})})})]},e.name)]}),(0,r.jsx)(eg.Z,{className:"mt-6 mb-6",children:b&&(0,r.jsx)(ej.Z,{className:"mt-6",data:b,colors:["blue","amber"],index:"date",categories:["spend","predicted_spend"],yAxisWidth:80})}),(0,r.jsx)(et.Z,{children:"Metadata"}),(0,r.jsx)(el.Z,{children:JSON.stringify(Z.metadata)}),(0,r.jsx)(H.Z,{variant:"light",className:"mx-auto flex items-center",onClick:()=>{y(null),w(null)},children:"Close"})]})})}),(0,r.jsx)(eZ.Z,{icon:eu.Z,size:"sm",onClick:()=>R(e)}),(0,r.jsx)(eZ.Z,{onClick:()=>z(e),icon:ex.Z,size:"sm"})]})]},e.token)})})]}),u&&(0,r.jsx)("div",{className:"fixed z-10 inset-0 overflow-y-auto",children:(0,r.jsxs)("div",{className:"flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0",children:[(0,r.jsx)("div",{className:"fixed inset-0 transition-opacity","aria-hidden":"true",children:(0,r.jsx)("div",{className:"absolute inset-0 bg-gray-500 opacity-75"})}),(0,r.jsx)("span",{className:"hidden sm:inline-block sm:align-middle sm:h-screen","aria-hidden":"true",children:"​"}),(0,r.jsxs)("div",{className:"inline-block align-bottom bg-white rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full",children:[(0,r.jsx)("div",{className:"bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4",children:(0,r.jsx)("div",{className:"sm:flex sm:items-start",children:(0,r.jsxs)("div",{className:"mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left",children:[(0,r.jsx)("h3",{className:"text-lg leading-6 font-medium text-gray-900",children:"Delete Key"}),(0,r.jsx)("div",{className:"mt-2",children:(0,r.jsx)("p",{className:"text-sm text-gray-500",children:"Are you sure you want to delete this key ?"})})]})})}),(0,r.jsxs)("div",{className:"bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse",children:[(0,r.jsx)(H.Z,{onClick:B,color:"red",className:"ml-2",children:"Delete"}),(0,r.jsx)(H.Z,{onClick:()=>{x(!1),j(null)},children:"Cancel"})]})]})]})})]}),I&&(0,r.jsx)(e=>{let{visible:l,onCancel:t,token:s,onSubmit:o}=e,[i]=er.Z.useForm(),[d,m]=(0,n.useState)(a),[h,u]=(0,n.useState)([]),[x,p]=(0,n.useState)(!1);return(0,r.jsx)(en.Z,{title:"Edit Key",visible:l,width:800,footer:null,onOk:()=>{i.validateFields().then(e=>{i.resetFields()}).catch(e=>{console.error("Validation failed:",e)})},onCancel:t,children:(0,r.jsxs)(er.Z,{form:i,onFinish:U,initialValues:s,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(er.Z.Item,{label:"Key Name",name:"key_alias",rules:[{required:!0,message:"Please input a key name"}],help:"required",children:(0,r.jsx)(eo.Z,{})}),(0,r.jsx)(er.Z.Item,{label:"Models",name:"models",rules:[{validator:(e,l)=>{let t=l.filter(e=>!d.models.includes(e)&&"all-team-models"!==e&&"all-proxy-models"!==e&&!d.models.includes("all-proxy-models"));return(console.log("errorModels: ".concat(t)),t.length>0)?Promise.reject("Some models are not part of the new team's models - ".concat(t,"Team models: ").concat(d.models)):Promise.resolve()}}],children:(0,r.jsxs)(ea.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:[(0,r.jsx)(eC,{value:"all-team-models",children:"All Team Models"},"all-team-models"),d&&d.models?d.models.includes("all-proxy-models")?T.filter(e=>"all-proxy-models"!==e).map(e=>(0,r.jsx)(eC,{value:e,children:e},e)):d.models.map(e=>(0,r.jsx)(eC,{value:e,children:e},e)):T.map(e=>(0,r.jsx)(eC,{value:e,children:e},e))]})}),(0,r.jsx)(er.Z.Item,{className:"mt-8",label:"Max Budget (USD)",name:"max_budget",help:"Budget cannot exceed team max budget: ".concat((null==d?void 0:d.max_budget)!==null&&(null==d?void 0:d.max_budget)!==void 0?null==d?void 0:d.max_budget:"unlimited"),rules:[{validator:async(e,l)=>{if(l&&d&&null!==d.max_budget&&l>d.max_budget)throw console.log("keyTeam.max_budget: ".concat(d.max_budget)),Error("Budget cannot exceed team max budget: $".concat(d.max_budget))}}],children:(0,r.jsx)(ei.Z,{step:.01,precision:2,width:200})}),(0,r.jsx)(er.Z.Item,{label:"token",name:"token",hidden:!0}),(0,r.jsx)(er.Z.Item,{label:"Team",name:"team_id",help:"the team this key belongs to",children:(0,r.jsx)(eA.Z,{value:s.team_alias,children:null==c?void 0:c.map((e,l)=>(0,r.jsx)(eN.Z,{value:e.team_id,onClick:()=>m(e),children:e.team_alias},l))})})]}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ec.ZP,{htmlType:"submit",children:"Edit Key"})})]})})},{visible:N,onCancel:()=>{C(!1),P(null)},token:I,onSubmit:U})]})},eP=t(76032),eT=t(35152),eE=e=>{let{userID:l,userRole:t,accessToken:s,userSpend:a,selectedTeam:o}=e;console.log("userSpend: ".concat(a));let[i,c]=(0,n.useState)(null!==a?a:0),[d,m]=(0,n.useState)(0),[h,u]=(0,n.useState)([]);(0,n.useEffect)(()=>{let e=async()=>{if(s&&l&&t&&"Admin"===t&&null==a)try{let e=await b(s);e&&(e.spend?c(e.spend):c(0),e.max_budget?m(e.max_budget):m(0))}catch(e){console.error("Error fetching global spend data:",e)}};(async()=>{try{if(null===l||null===t)return;if(null!==s){let e=(await v(s,l,t)).data.map(e=>e.id);console.log("available_model_names:",e),u(e)}}catch(e){console.error("Error fetching user models:",e)}})(),e()},[t,s,l]),(0,n.useEffect)(()=>{null!==a&&c(a)},[a]);let x=[];o&&o.models&&(x=o.models),x&&x.includes("all-proxy-models")?(console.log("user models:",h),x=h):x&&x.includes("all-team-models")?x=o.models:x&&0===x.length&&(x=h);let p=void 0!==i?i.toFixed(4):null;return console.log("spend in view user spend: ".concat(i)),(0,r.jsxs)("div",{className:"flex items-center",children:[(0,r.jsxs)("div",{children:[(0,r.jsxs)("p",{className:"text-tremor-default text-tremor-content dark:text-dark-tremor-content",children:["Total Spend"," "]}),(0,r.jsxs)("p",{className:"text-2xl text-tremor-content-strong dark:text-dark-tremor-content-strong font-semibold",children:["$",p]})]}),(0,r.jsx)("div",{className:"ml-auto",children:(0,r.jsxs)(X.Z,{children:[(0,r.jsx)(ee.Z,{children:(0,r.jsx)(el.Z,{children:"Team Models"})}),(0,r.jsx)(Q.Z,{className:"absolute right-0 z-10 bg-white p-2 shadow-lg max-w-xs",children:(0,r.jsx)(eP.Z,{children:x.map(e=>(0,r.jsx)(eT.Z,{children:(0,r.jsx)(el.Z,{children:e})},e))})})]})})]})},eF=e=>{let{userID:l,userRole:t,selectedTeam:s,accessToken:a}=e,[o,i]=(0,n.useState)([]);(0,n.useEffect)(()=>{(async()=>{try{if(null===l||null===t)return;if(null!==a){let e=(await v(a,l,t)).data.map(e=>e.id);console.log("available_model_names:",e),i(e)}}catch(e){console.error("Error fetching user models:",e)}})()},[a,l,t]);let c=[];return s&&s.models&&(c=s.models),c&&c.includes("all-proxy-models")&&(console.log("user models:",o),c=o),(0,r.jsx)(r.Fragment,{children:(0,r.jsx)("div",{className:"mb-5",children:(0,r.jsx)("p",{className:"text-3xl text-tremor-content-strong dark:text-dark-tremor-content-strong font-semibold",children:null==s?void 0:s.team_alias})})})},eO=e=>{let l,{teams:t,setSelectedTeam:s,userRole:a}=e,o={models:[],team_id:null,team_alias:"Default Team"},[i,c]=(0,n.useState)(o);return(l="App User"===a?t:t?[...t,o]:[o],"App User"===a)?null:(0,r.jsxs)("div",{className:"mt-5 mb-5",children:[(0,r.jsx)(et.Z,{children:"Select Team"}),(0,r.jsx)(el.Z,{children:"If you belong to multiple teams, this setting controls which team is used by default when creating new API Keys."}),(0,r.jsxs)(el.Z,{className:"mt-3 mb-3",children:[(0,r.jsx)("b",{children:"Default Team:"})," If no team_id is set for a key, it will be grouped under here."]}),l&&l.length>0?(0,r.jsx)(eA.Z,{defaultValue:"0",children:l.map((e,l)=>(0,r.jsx)(eN.Z,{value:String(l),onClick:()=>s(e),children:e.team_alias},l))}):(0,r.jsxs)(el.Z,{children:["No team created. ",(0,r.jsx)("b",{children:"Defaulting to personal account."})]})]})},eM=t(37963),eR=t(36083);console.log("isLocal:",!1);var eL=e=>{let{userID:l,userRole:t,teams:s,keys:a,setUserRole:i,userEmail:c,setUserEmail:d,setTeams:m,setKeys:h}=e,[u,x]=(0,n.useState)(null),p=(0,o.useSearchParams)();p.get("viewSpend"),(0,o.useRouter)();let j=p.get("token"),[g,f]=(0,n.useState)(null),[y,w]=(0,n.useState)(null),[_,k]=(0,n.useState)([]),S={models:[],team_alias:"Default Team",team_id:null},[A,N]=(0,n.useState)(s?s[0]:S);if(window.addEventListener("beforeunload",function(){sessionStorage.clear()}),(0,n.useEffect)(()=>{if(j){let e=(0,eM.o)(j);if(e){if(console.log("Decoded token:",e),console.log("Decoded key:",e.key),f(e.key),e.user_role){let l=function(e){if(!e)return"Undefined Role";switch(console.log("Received user role: ".concat(e)),e.toLowerCase()){case"app_owner":case"demo_app_owner":return"App Owner";case"app_admin":case"proxy_admin":return"Admin";case"proxy_admin_viewer":return"Admin Viewer";case"app_user":return"App User";default:return"Unknown Role"}}(e.user_role);console.log("Decoded user_role:",l),i(l)}else console.log("User role not defined");e.user_email?d(e.user_email):console.log("User Email is not set ".concat(e))}}if(l&&g&&t&&!a&&!u){let e=sessionStorage.getItem("userModels"+l);e?k(JSON.parse(e)):(async()=>{try{let e=await Z(g,l,t,!1,null,null);if(console.log("received teams in user dashboard: ".concat(Object.keys(e),"; team values: ").concat(Object.entries(e.teams))),"Admin"==t){let e=await b(g);x(e),console.log("globalSpend:",e)}else x(e.user_info);h(e.keys),m(e.teams);let s=[...e.teams];s.length>0?(console.log("response['teams']: ".concat(s)),N(s[0])):N(S),sessionStorage.setItem("userData"+l,JSON.stringify(e.keys)),sessionStorage.setItem("userSpendData"+l,JSON.stringify(e.user_info));let a=(await v(g,l,t)).data.map(e=>e.id);console.log("available_model_names:",a),k(a),console.log("userModels:",_),sessionStorage.setItem("userModels"+l,JSON.stringify(a))}catch(e){console.error("There was an error fetching the data",e)}})()}},[l,j,g,a,t]),(0,n.useEffect)(()=>{if(null!==a&&null!=A){let e=0;for(let l of a)A.hasOwnProperty("team_id")&&null!==l.team_id&&l.team_id===A.team_id&&(e+=l.spend);w(e)}else if(null!==a){let e=0;for(let l of a)e+=l.spend;w(e)}},[A]),null==l||null==j){let e="/sso/key/generate";return console.log("Full URL:",e),window.location.href=e,null}if(null==g)return null;if(null==t&&i("App Owner"),t&&"Admin Viewer"==t){let{Title:e,Paragraph:l}=eR.default;return(0,r.jsxs)("div",{children:[(0,r.jsx)(e,{level:1,children:"Access Denied"}),(0,r.jsx)(l,{children:"Ask your proxy admin for access to create keys"})]})}return console.log("inside user dashboard, selected team",A),console.log("teamSpend: ".concat(y)),(0,r.jsx)("div",{className:"w-full mx-4",children:(0,r.jsx)(Y.Z,{numItems:1,className:"gap-2 p-8 h-[75vh] w-full mt-2",children:(0,r.jsxs)(J.Z,{numColSpan:1,children:[(0,r.jsx)(eF,{userID:l,userRole:t,selectedTeam:A||null,accessToken:g}),(0,r.jsx)(eE,{userID:l,userRole:t,accessToken:g,userSpend:y,selectedTeam:A||null}),(0,r.jsx)(eI,{userID:l,userRole:t,accessToken:g,selectedTeam:A||null,data:a,setData:h,teams:s}),(0,r.jsx)(em,{userID:l,team:A||null,userRole:t,accessToken:g,data:a,setData:h},A?A.team_id:null),(0,r.jsx)(eO,{teams:s,setSelectedTeam:N,userRole:t})]})})})},eU=t(92836),eD=t(26734),ez=t(41608),eB=t(32126),eq=t(23682),eK=t(47047),eV=t(76628),eG=t(38302),eW=t(28683),eJ=t(1460),eY=t(78578),eH=t(63954),e$=e=>{let{modelID:l,accessToken:t}=e,[s,a]=(0,n.useState)(!1),o=async()=>{try{h.ZP.info("Making API Call"),a(!0);let e=await p(t,l);console.log("model delete Response:",e),h.ZP.success("Model ".concat(l," deleted successfully")),a(!1)}catch(e){console.error("Error deleting the model:",e)}};return(0,r.jsxs)("div",{children:[(0,r.jsx)(eZ.Z,{onClick:()=>a(!0),icon:ex.Z,size:"sm"}),(0,r.jsx)(en.Z,{open:s,onOk:o,okType:"danger",onCancel:()=>a(!1),children:(0,r.jsxs)(Y.Z,{numItems:1,className:"gap-2 w-full",children:[(0,r.jsx)(et.Z,{children:"Delete Model"}),(0,r.jsx)(J.Z,{numColSpan:1,children:(0,r.jsx)("p",{children:"Are you sure you want to delete this model? This action is irreversible."})}),(0,r.jsx)(J.Z,{numColSpan:1,children:(0,r.jsxs)("p",{children:["Model ID: ",(0,r.jsx)("b",{children:l})]})})]})})]})},eX=t(97766),eQ=t(46495);let{Title:e0,Link:e1}=eR.default;(s=a||(a={})).OpenAI="OpenAI",s.Azure="Azure",s.Anthropic="Anthropic",s.Google_AI_Studio="Gemini (Google AI Studio)",s.Bedrock="Amazon Bedrock",s.OpenAI_Compatible="OpenAI-Compatible Endpoints (Groq, Together AI, Mistral AI, etc.)",s.Vertex_AI="Vertex AI (Anthropic, Gemini, etc.)";let e2={OpenAI:"openai",Azure:"azure",Anthropic:"anthropic",Google_AI_Studio:"gemini",Bedrock:"bedrock",OpenAI_Compatible:"openai",Vertex_AI:"vertex_ai"},e4=async(e,l,t)=>{try{let s=Array.isArray(e.model)?e.model:[e.model];console.log("received deployments: ".concat(s)),console.log("received type of deployments: ".concat(typeof s)),s.forEach(async t=>{console.log("litellm_model: ".concat(t));let s={},a={};s.model=t;let r="";for(let[l,t]of Object.entries(e))if(""!==t){if("model_name"==l)r+=t;else if("custom_llm_provider"==l)continue;else if("model"==l)continue;else if("base_model"===l)a[l]=t;else if("litellm_extra_params"==l){console.log("litellm_extra_params:",t);let e={};if(t&&void 0!=t){try{e=JSON.parse(t)}catch(e){throw h.ZP.error("Failed to parse LiteLLM Extra Params: "+e,20),Error("Failed to parse litellm_extra_params: "+e)}for(let[l,t]of Object.entries(e))s[l]=t}}else s[l]=t}let n={model_name:r,litellm_params:s,model_info:a},o=await x(l,n);console.log("response for model create call: ".concat(o.data))}),t.resetFields()}catch(e){h.ZP.error("Failed to create model: "+e,20)}};var e8=e=>{var l,t,s;let{accessToken:o,token:i,userRole:c,userID:d,modelData:m={data:[]},setModelData:x}=e,[p,j]=(0,n.useState)([]),[g]=er.Z.useForm(),[f,y]=(0,n.useState)(null),[Z,w]=(0,n.useState)(""),[b,k]=(0,n.useState)([]),v=Object.values(a).filter(e=>isNaN(Number(e))),[S,A]=(0,n.useState)("OpenAI"),[N,C]=(0,n.useState)(""),[I,P]=(0,n.useState)(!1),[T,E]=(0,n.useState)(null),[F,M]=(0,n.useState)([]),[R,L]=(0,n.useState)(null),U=e=>{E(e),P(!0)},z=async e=>{if(console.log("handleEditSubmit:",e),null==o)return;let l={},t=null;for(let[s,a]of Object.entries(e))"model_id"!==s?l[s]=a:t=a;let s={litellm_params:l,model_info:{id:t}};console.log("handleEditSubmit payload:",s),await D(o,s),h.ZP.success("Model updated successfully, restart server to see updates"),P(!1),E(null)},B=()=>{w(new Date().toLocaleString())};if((0,n.useEffect)(()=>{if(!o||!i||!c||!d)return;let e=async()=>{try{let e=await _(o,d,c);console.log("Model data response:",e.data),x(e);let l=new Set;for(let t=0;t{let e=await u();console.log("received model cost map data: ".concat(Object.keys(e))),y(e)};null==f&&l(),B()},[o,i,c,d,f,Z]),!m||!o||!i||!c||!d)return(0,r.jsx)("div",{children:"Loading..."});let q=[];for(let e=0;e(console.log("GET PROVIDER CALLED! - ".concat(f)),null!=f&&"object"==typeof f&&e in f)?f[e].litellm_provider:"openai";if(a){let e=a.split("/"),l=e[0];n=1===e.length?h(a):l}else n="openai";r&&(o=null==r?void 0:r.input_cost_per_token,i=null==r?void 0:r.output_cost_per_token,c=null==r?void 0:r.max_tokens),(null==s?void 0:s.litellm_params)&&(d=Object.fromEntries(Object.entries(null==s?void 0:s.litellm_params).filter(e=>{let[l]=e;return"model"!==l&&"api_base"!==l}))),m.data[e].provider=n,m.data[e].input_cost=o,m.data[e].output_cost=i,m.data[e].max_tokens=c,m.data[e].api_base=null==s?void 0:null===(t=s.litellm_params)||void 0===t?void 0:t.api_base,m.data[e].cleanedLitellmParams=d,q.push(s.model_name),console.log(m.data[e])}if(c&&"Admin Viewer"==c){let{Title:e,Paragraph:l}=eR.default;return(0,r.jsxs)("div",{children:[(0,r.jsx)(e,{level:1,children:"Access Denied"}),(0,r.jsx)(l,{children:"Ask your proxy admin for access to view all models"})]})}let K=e=>{console.log("received provider string: ".concat(e));let l=Object.keys(a).find(l=>a[l]===e);if(l){let e=e2[l];console.log("mappingResult: ".concat(e));let t=[];"object"==typeof f&&Object.entries(f).forEach(l=>{let[s,a]=l;null!==a&&"object"==typeof a&&"litellm_provider"in a&&(a.litellm_provider===e||a.litellm_provider.includes(e))&&t.push(s)}),k(t),console.log("providerModels: ".concat(b))}},V=async()=>{try{h.ZP.info("Running health check..."),C("");let e=await W(o);C(e)}catch(e){console.error("Error running health check:",e),C("Error running health check")}};return console.log("selectedProvider: ".concat(S)),console.log("providerModels.length: ".concat(b.length)),(0,r.jsx)("div",{style:{width:"100%",height:"100%"},children:(0,r.jsxs)(eD.Z,{className:"gap-2 p-8 h-[75vh] w-full mt-2",children:[(0,r.jsxs)(ez.Z,{className:"flex justify-between mt-2 w-full items-center",children:[(0,r.jsxs)("div",{className:"flex",children:[(0,r.jsx)(eU.Z,{children:"All Models"}),(0,r.jsx)(eU.Z,{children:"Add Model"}),(0,r.jsx)(eU.Z,{children:(0,r.jsx)("pre",{children:"/health Models"})})]}),(0,r.jsxs)("div",{className:"flex items-center space-x-2",children:[Z&&(0,r.jsxs)(el.Z,{children:["Last Refreshed: ",Z]}),(0,r.jsx)(eZ.Z,{icon:eH.Z,variant:"shadow",size:"xs",className:"self-center",onClick:B})]})]}),(0,r.jsxs)(eq.Z,{children:[(0,r.jsxs)(eB.Z,{children:[(0,r.jsxs)(Y.Z,{children:[(0,r.jsxs)("div",{className:"flex items-center",children:[(0,r.jsx)(el.Z,{children:"Filter by Public Model Name"}),(0,r.jsxs)(eA.Z,{className:"mb-4 mt-2 ml-2 w-50",defaultValue:"all",onValueChange:e=>L("all"===e?"all":e),children:[(0,r.jsx)(eN.Z,{value:"all",children:"All Models"}),F.map((e,l)=>(0,r.jsx)(eN.Z,{value:e,onClick:()=>L(e),children:e},l))]})]}),(0,r.jsx)(eg.Z,{children:(0,r.jsxs)(ew.Z,{className:"mt-5",children:[(0,r.jsx)(ek.Z,{children:(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(ev.Z,{children:"Public Model Name "}),(0,r.jsx)(ev.Z,{children:"Provider"}),"Admin"===c&&(0,r.jsx)(ev.Z,{children:"API Base"}),(0,r.jsx)(ev.Z,{children:"Extra litellm Params"}),(0,r.jsx)(ev.Z,{children:"Input Price per token ($)"}),(0,r.jsx)(ev.Z,{children:"Output Price per token ($)"}),(0,r.jsx)(ev.Z,{children:"Max Tokens"})]})}),(0,r.jsx)(eb.Z,{children:m.data.filter(e=>"all"===R||e.model_name===R||null==R||""===R).map((e,l)=>(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(e_.Z,{children:(0,r.jsx)(el.Z,{children:e.model_name})}),(0,r.jsx)(e_.Z,{children:e.provider}),"Admin"===c&&(0,r.jsx)(e_.Z,{children:e.api_base}),(0,r.jsx)(e_.Z,{children:(0,r.jsxs)(X.Z,{children:[(0,r.jsx)(ee.Z,{children:(0,r.jsx)(el.Z,{children:"Litellm params"})}),(0,r.jsx)(Q.Z,{children:(0,r.jsx)("pre",{children:JSON.stringify(e.cleanedLitellmParams,null,2)})})]})}),(0,r.jsx)(e_.Z,{children:e.input_cost}),(0,r.jsx)(e_.Z,{children:e.output_cost}),(0,r.jsx)(e_.Z,{children:e.max_tokens}),(0,r.jsxs)(e_.Z,{children:[(0,r.jsx)(eZ.Z,{icon:eu.Z,size:"sm",onClick:()=>U(e)}),(0,r.jsx)(e$,{modelID:e.model_info.id,accessToken:o})]})]},l))})]})})]}),(0,r.jsx)(e=>{let{visible:l,onCancel:t,model:s,onSubmit:a}=e,[n]=er.Z.useForm(),o={},i="",c="";if(s){o=s.litellm_params,i=s.model_name;let e=s.model_info;e&&(c=e.id,console.log("model_id: ".concat(c)),o.model_id=c)}return(0,r.jsx)(en.Z,{title:"Edit Model "+i,visible:l,width:800,footer:null,onOk:()=>{n.validateFields().then(e=>{a(e),n.resetFields()}).catch(e=>{console.error("Validation failed:",e)})},onCancel:t,children:(0,r.jsxs)(er.Z,{form:n,onFinish:z,initialValues:o,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(er.Z.Item,{className:"mt-8",label:"api_base",name:"api_base",children:(0,r.jsx)($.Z,{})}),(0,r.jsx)(er.Z.Item,{label:"tpm",name:"tpm",tooltip:"int (optional) - Tokens limit for this deployment: in tokens per minute (tpm). Find this information on your model/providers website",children:(0,r.jsx)(ei.Z,{min:0,step:1})}),(0,r.jsx)(er.Z.Item,{label:"rpm",name:"rpm",tooltip:"int (optional) - Rate limit for this deployment: in requests per minute (rpm). Find this information on your model/providers website",children:(0,r.jsx)(ei.Z,{min:0,step:1})}),(0,r.jsx)(er.Z.Item,{label:"max_retries",name:"max_retries",children:(0,r.jsx)(ei.Z,{min:0,step:1})}),(0,r.jsx)(er.Z.Item,{label:"timeout",name:"timeout",tooltip:"int (optional) - Timeout in seconds for LLM requests (Defaults to 600 seconds)",children:(0,r.jsx)(ei.Z,{min:0,step:1})}),(0,r.jsx)(er.Z.Item,{label:"stream_timeout",name:"stream_timeout",tooltip:"int (optional) - Timeout for stream requests (seconds)",children:(0,r.jsx)(ei.Z,{min:0,step:1})}),(0,r.jsx)(er.Z.Item,{label:"model_id",name:"model_id",hidden:!0})]}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ec.ZP,{htmlType:"submit",children:"Save"})})]})})},{visible:I,onCancel:()=>{P(!1),E(null)},model:T,onSubmit:z})]}),(0,r.jsxs)(eB.Z,{className:"h-full",children:[(0,r.jsx)(e0,{level:2,children:"Add new model"}),(0,r.jsx)(eg.Z,{children:(0,r.jsxs)(er.Z,{form:g,onFinish:()=>{g.validateFields().then(e=>{e4(e,o,g)}).catch(e=>{console.error("Validation failed:",e)})},labelCol:{span:10},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(er.Z.Item,{rules:[{required:!0,message:"Required"}],label:"Provider:",name:"custom_llm_provider",tooltip:"E.g. OpenAI, Azure OpenAI, Anthropic, Bedrock, etc.",labelCol:{span:10},labelAlign:"left",children:(0,r.jsx)(eA.Z,{value:S.toString(),children:v.map((e,l)=>(0,r.jsx)(eN.Z,{value:e,onClick:()=>{K(e),A(e)},children:e},l))})}),(0,r.jsx)(er.Z.Item,{rules:[{required:!0,message:"Required"}],label:"Public Model Name",name:"model_name",tooltip:"Model name your users will pass in. Also used for load-balancing, LiteLLM will load balance between all models with this public name.",className:"mb-0",children:(0,r.jsx)($.Z,{placeholder:"Vertex AI (Anthropic, Gemini, etc.)"===(s=S.toString())?"gemini-pro":"Anthropic"==s?"claude-3-opus":"Amazon Bedrock"==s?"claude-3-opus":"Gemini (Google AI Studio)"==s?"gemini-pro":"gpt-3.5-turbo"})}),(0,r.jsxs)(eG.Z,{children:[(0,r.jsx)(eW.Z,{span:10}),(0,r.jsx)(eW.Z,{span:10,children:(0,r.jsx)(el.Z,{className:"mb-3 mt-1",children:"Model name your users will pass in."})})]}),(0,r.jsx)(er.Z.Item,{rules:[{required:!0,message:"Required"}],label:"LiteLLM Model Name(s)",name:"model",tooltip:"Actual model name used for making litellm.completion() call.",className:"mb-0",children:"Azure"===S?(0,r.jsx)($.Z,{placeholder:"Enter model name"}):b.length>0?(0,r.jsx)(eK.Z,{value:b,children:b.map((e,l)=>(0,r.jsx)(eV.Z,{value:e,children:e},l))}):(0,r.jsx)($.Z,{placeholder:"gpt-3.5-turbo-0125"})}),(0,r.jsxs)(eG.Z,{children:[(0,r.jsx)(eW.Z,{span:10}),(0,r.jsx)(eW.Z,{span:10,children:(0,r.jsxs)(el.Z,{className:"mb-3 mt-1",children:["Actual model name used for making ",(0,r.jsx)(e1,{href:"https://docs.litellm.ai/docs/providers",target:"_blank",children:"litellm.completion() call"}),". We'll ",(0,r.jsx)(e1,{href:"https://docs.litellm.ai/docs/proxy/reliability#step-1---set-deployments-on-config",target:"_blank",children:"loadbalance"})," models with the same 'public name'"]})})]}),"Amazon Bedrock"!=S&&"Vertex AI (Anthropic, Gemini, etc.)"!=S&&(0,r.jsx)(er.Z.Item,{rules:[{required:!0,message:"Required"}],label:"API Key",name:"api_key",children:(0,r.jsx)($.Z,{placeholder:"sk-",type:"password"})}),"OpenAI"==S&&(0,r.jsx)(er.Z.Item,{label:"Organization ID",name:"organization_id",children:(0,r.jsx)($.Z,{placeholder:"[OPTIONAL] my-unique-org"})}),"Vertex AI (Anthropic, Gemini, etc.)"==S&&(0,r.jsx)(er.Z.Item,{rules:[{required:!0,message:"Required"}],label:"Vertex Project",name:"vertex_project",children:(0,r.jsx)($.Z,{placeholder:"adroit-cadet-1234.."})}),"Vertex AI (Anthropic, Gemini, etc.)"==S&&(0,r.jsx)(er.Z.Item,{rules:[{required:!0,message:"Required"}],label:"Vertex Location",name:"vertex_location",children:(0,r.jsx)($.Z,{placeholder:"us-east-1"})}),"Vertex AI (Anthropic, Gemini, etc.)"==S&&(0,r.jsx)(er.Z.Item,{rules:[{required:!0,message:"Required"}],label:"Vertex Credentials",name:"vertex_credentials",className:"mb-0",children:(0,r.jsx)(eQ.Z,{name:"file",accept:".json",beforeUpload:e=>{if("application/json"===e.type){let l=new FileReader;l.onload=e=>{if(e.target){let l=e.target.result;g.setFieldsValue({vertex_credentials:l})}},l.readAsText(e)}return!1},onChange(e){"uploading"!==e.file.status&&console.log(e.file,e.fileList),"done"===e.file.status?h.ZP.success("".concat(e.file.name," file uploaded successfully")):"error"===e.file.status&&h.ZP.error("".concat(e.file.name," file upload failed."))},children:(0,r.jsx)(ec.ZP,{icon:(0,r.jsx)(eX.Z,{}),children:"Click to Upload"})})}),"Vertex AI (Anthropic, Gemini, etc.)"==S&&(0,r.jsxs)(eG.Z,{children:[(0,r.jsx)(eW.Z,{span:10}),(0,r.jsx)(eW.Z,{span:10,children:(0,r.jsx)(el.Z,{className:"mb-3 mt-1",children:"Give litellm a gcp service account(.json file), so it can make the relevant calls"})})]}),("Azure"==S||"OpenAI-Compatible Endpoints (Groq, Together AI, Mistral AI, etc.)"==S)&&(0,r.jsx)(er.Z.Item,{rules:[{required:!0,message:"Required"}],label:"API Base",name:"api_base",children:(0,r.jsx)($.Z,{placeholder:"https://..."})}),"Azure"==S&&(0,r.jsx)(er.Z.Item,{rules:[{required:!0,message:"Required"}],label:"API Version",name:"api_version",children:(0,r.jsx)($.Z,{placeholder:"2023-07-01-preview"})}),"Azure"==S&&(0,r.jsxs)(er.Z.Item,{label:"Base Model",name:"base_model",children:[(0,r.jsx)($.Z,{placeholder:"azure/gpt-3.5-turbo"}),(0,r.jsxs)(el.Z,{children:["The actual model your azure deployment uses. Used for accurate cost tracking. Select name from ",(0,r.jsx)(e1,{href:"https://github.com/BerriAI/litellm/blob/main/model_prices_and_context_window.json",target:"_blank",children:"here"})]})]}),"Amazon Bedrock"==S&&(0,r.jsx)(er.Z.Item,{rules:[{required:!0,message:"Required"}],label:"AWS Access Key ID",name:"aws_access_key_id",tooltip:"You can provide the raw key or the environment variable (e.g. `os.environ/MY_SECRET_KEY`).",children:(0,r.jsx)($.Z,{placeholder:""})}),"Amazon Bedrock"==S&&(0,r.jsx)(er.Z.Item,{rules:[{required:!0,message:"Required"}],label:"AWS Secret Access Key",name:"aws_secret_access_key",tooltip:"You can provide the raw key or the environment variable (e.g. `os.environ/MY_SECRET_KEY`).",children:(0,r.jsx)($.Z,{placeholder:""})}),"Amazon Bedrock"==S&&(0,r.jsx)(er.Z.Item,{rules:[{required:!0,message:"Required"}],label:"AWS Region Name",name:"aws_region_name",tooltip:"You can provide the raw key or the environment variable (e.g. `os.environ/MY_SECRET_KEY`).",children:(0,r.jsx)($.Z,{placeholder:"us-east-1"})}),(0,r.jsx)(er.Z.Item,{label:"LiteLLM Params",name:"litellm_extra_params",tooltip:"Optional litellm params used for making a litellm.completion() call.",className:"mb-0",children:(0,r.jsx)(eY.Z,{rows:4,placeholder:'{ "rpm": 100, "timeout": 0, "stream_timeout": 0 }'})}),(0,r.jsxs)(eG.Z,{children:[(0,r.jsx)(eW.Z,{span:10}),(0,r.jsx)(eW.Z,{span:10,children:(0,r.jsxs)(el.Z,{className:"mb-3 mt-1",children:["Pass JSON of litellm supported params ",(0,r.jsx)(e1,{href:"https://docs.litellm.ai/docs/completion/input",target:"_blank",children:"litellm.completion() call"})]})})]})]}),(0,r.jsx)("div",{style:{textAlign:"center",marginTop:"10px"},children:(0,r.jsx)(ec.ZP,{htmlType:"submit",children:"Add Model"})}),(0,r.jsx)(eJ.Z,{title:"Get help on our github",children:(0,r.jsx)(eR.default.Link,{href:"https://github.com/BerriAI/litellm/issues",children:"Need Help?"})})]})})]}),(0,r.jsx)(eB.Z,{children:(0,r.jsxs)(eg.Z,{children:[(0,r.jsx)(el.Z,{children:"`/health` will run a very small request through your models configured on litellm"}),(0,r.jsx)(H.Z,{onClick:V,children:"Run `/health`"}),N&&(0,r.jsx)("pre",{children:JSON.stringify(N,null,2)})]})})]})]})})};let{Option:e5}=ea.default;var e3=e=>{let{userID:l,accessToken:t,teams:s}=e,[a]=er.Z.useForm(),[o,i]=(0,n.useState)(!1),[c,d]=(0,n.useState)(null),[m,u]=(0,n.useState)([]);(0,n.useEffect)(()=>{(async()=>{try{let e=await v(t,l,"any"),s=[];for(let l=0;l{i(!1),a.resetFields()},p=()=>{i(!1),d(null),a.resetFields()},j=async e=>{try{h.ZP.info("Making API Call"),i(!0),console.log("formValues in create user:",e);let s=await g(t,null,e);console.log("user create Response:",s),d(s.key),h.ZP.success("API user Created"),a.resetFields(),localStorage.removeItem("userData"+l)}catch(e){console.error("Error creating the user:",e)}};return(0,r.jsxs)("div",{children:[(0,r.jsx)(H.Z,{className:"mx-auto",onClick:()=>i(!0),children:"+ Invite User"}),(0,r.jsxs)(en.Z,{title:"Invite User",visible:o,width:800,footer:null,onOk:x,onCancel:p,children:[(0,r.jsx)(el.Z,{className:"mb-1",children:"Invite a user to login to the Admin UI and create Keys"}),(0,r.jsx)(el.Z,{className:"mb-6",children:(0,r.jsx)("b",{children:"Note: SSO Setup Required for this"})}),(0,r.jsxs)(er.Z,{form:a,onFinish:j,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsx)(er.Z.Item,{label:"User Email",name:"user_email",children:(0,r.jsx)($.Z,{placeholder:""})}),(0,r.jsx)(er.Z.Item,{label:"Team ID",name:"team_id",children:(0,r.jsx)(ea.default,{placeholder:"Select Team ID",style:{width:"100%"},children:s?s.map(e=>(0,r.jsx)(e5,{value:e.team_id,children:e.team_alias},e.team_id)):(0,r.jsx)(e5,{value:null,children:"Default Team"},"default")})}),(0,r.jsx)(er.Z.Item,{label:"Metadata",name:"metadata",children:(0,r.jsx)(eo.Z.TextArea,{rows:4,placeholder:"Enter metadata as JSON"})}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ec.ZP,{htmlType:"submit",children:"Create User"})})]})]}),c&&(0,r.jsxs)(en.Z,{title:"User Created Successfully",visible:o,onOk:x,onCancel:p,footer:null,children:[(0,r.jsx)("p",{children:"User has been created to access your proxy. Please Ask them to Log In."}),(0,r.jsx)("br",{}),(0,r.jsx)("p",{children:(0,r.jsx)("b",{children:"Note: This Feature is only supported through SSO on the Admin UI"})})]})]})},e6=e=>{let{accessToken:l,token:t,keys:s,userRole:a,userID:o,teams:i,setKeys:c}=e,[d,m]=(0,n.useState)(null),[h,u]=(0,n.useState)(null),[x,p]=(0,n.useState)(0),[j,g]=n.useState(null),[f,y]=(0,n.useState)(null);if((0,n.useEffect)(()=>{if(!l||!t||!a||!o)return;let e=async()=>{try{let e=await Z(l,null,a,!0,x,25);console.log("user data response:",e),m(e)}catch(e){console.error("There was an error fetching the model data",e)}};l&&t&&a&&o&&e();let s=async()=>{try{let e=await T(l,null);console.log("user data response:",e),u(e)}catch(e){console.error("There was an error fetching the model data",e)}};a&&("Admin"==a||"Admin Viewer"==a)&&!h&&s()},[l,t,a,o,x]),!d||!l||!t||!a||!o)return(0,r.jsx)("div",{children:"Loading..."});let w=async e=>{try{let t=await T(l,e);console.log("user data response:",t),u(t)}catch(e){console.error("There was an error fetching the model data",e)}};return(0,r.jsx)("div",{style:{width:"100%"},children:(0,r.jsxs)(Y.Z,{className:"gap-2 p-2 h-[80vh] w-full mt-8",children:[(0,r.jsx)(e3,{userID:o,accessToken:l,teams:i}),(0,r.jsxs)(eg.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[80vh] mb-4",children:[(0,r.jsxs)("div",{className:"mb-4 mt-1",children:[(0,r.jsxs)(el.Z,{children:[(0,r.jsx)("b",{children:"Key Owners: "})," Users on LiteLLM that created API Keys. Automatically tracked by LiteLLM"]}),(0,r.jsxs)(el.Z,{className:"mt-1",children:[(0,r.jsx)("b",{children:"End Users: "}),"End Users of your LLM API calls. Tracked When a `user` param is passed in your LLM calls"]})]}),(0,r.jsxs)(eD.Z,{children:[(0,r.jsxs)(ez.Z,{variant:"line",defaultValue:"1",children:[(0,r.jsx)(eU.Z,{value:"1",children:"Key Owners"}),(0,r.jsx)(eU.Z,{value:"2",children:"End-Users"})]}),(0,r.jsxs)(eq.Z,{children:[(0,r.jsx)(eB.Z,{children:(0,r.jsxs)(ew.Z,{className:"mt-5",children:[(0,r.jsx)(ek.Z,{children:(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(ev.Z,{children:"User ID"}),(0,r.jsx)(ev.Z,{children:"User Email"}),(0,r.jsx)(ev.Z,{children:"User Models"}),(0,r.jsx)(ev.Z,{children:"User Spend ($ USD)"}),(0,r.jsx)(ev.Z,{children:"User Max Budget ($ USD)"}),(0,r.jsx)(ev.Z,{children:"User API Key Aliases"})]})}),(0,r.jsx)(eb.Z,{children:d.map(e=>(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(e_.Z,{children:e.user_id}),(0,r.jsx)(e_.Z,{children:e.user_email}),(0,r.jsx)(e_.Z,{children:e.models&&e.models.length>0?e.models:"All Models"}),(0,r.jsx)(e_.Z,{children:e.spend?e.spend:0}),(0,r.jsx)(e_.Z,{children:e.max_budget?e.max_budget:"Unlimited"}),(0,r.jsx)(e_.Z,{children:(0,r.jsx)(Y.Z,{numItems:2,children:e&&e.key_aliases&&e.key_aliases.filter(e=>null!==e).length>0?(0,r.jsx)(ep.Z,{size:"xs",color:"indigo",children:e.key_aliases.filter(e=>null!==e).join(", ")}):(0,r.jsx)(ep.Z,{size:"xs",color:"gray",children:"No Keys"})})})]},e.user_id))})]})}),(0,r.jsxs)(eB.Z,{children:[(0,r.jsxs)("div",{className:"flex items-center",children:[(0,r.jsx)("div",{className:"flex-1"}),(0,r.jsxs)("div",{className:"flex-1 flex justify-between items-center",children:[(0,r.jsx)(el.Z,{className:"w-1/4 mr-2 text-right",children:"Key"}),(0,r.jsx)(eA.Z,{defaultValue:"1",className:"w-3/4",children:null==s?void 0:s.map((e,l)=>{if(e&&null!==e.key_alias&&e.key_alias.length>0)return(0,r.jsx)(eN.Z,{value:String(l),onClick:()=>w(e.token),children:e.key_alias},l)})})]})]}),(0,r.jsxs)(ew.Z,{className:"max-h-[70vh] min-h-[500px]",children:[(0,r.jsx)(ek.Z,{children:(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(ev.Z,{children:"End User"}),(0,r.jsx)(ev.Z,{children:"Spend"}),(0,r.jsx)(ev.Z,{children:"Total Events"})]})}),(0,r.jsx)(eb.Z,{children:null==h?void 0:h.map((e,l)=>(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(e_.Z,{children:e.end_user}),(0,r.jsx)(e_.Z,{children:e.total_spend}),(0,r.jsx)(e_.Z,{children:e.total_events})]},l))})]})]})]})]})]}),function(){if(!d)return null;let e=Math.ceil(d.length/25);return(0,r.jsxs)("div",{className:"flex justify-between items-center",children:[(0,r.jsxs)("div",{children:["Showing Page ",x+1," of ",e]}),(0,r.jsxs)("div",{className:"flex",children:[(0,r.jsx)("button",{className:"bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-l focus:outline-none",disabled:0===x,onClick:()=>p(x-1),children:"← Prev"}),(0,r.jsx)("button",{className:"bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-r focus:outline-none",onClick:()=>{p(x+1)},children:"Next →"})]})]})}()]})})},e7=e=>{let{teams:l,searchParams:t,accessToken:s,setTeams:a,userID:o,userRole:i}=e,[c]=er.Z.useForm(),[d]=er.Z.useForm(),{Title:m,Paragraph:u}=eR.default,[x,p]=(0,n.useState)(""),[j,g]=(0,n.useState)(!1),[f,Z]=(0,n.useState)(l?l[0]:null),[b,_]=(0,n.useState)(!1),[k,S]=(0,n.useState)(!1),[A,N]=(0,n.useState)([]),[C,I]=(0,n.useState)(!1),[P,T]=(0,n.useState)(null),[E,F]=(0,n.useState)({}),O=e=>{Z(e),g(!0)},M=async e=>{let t=e.team_id;if(console.log("handleEditSubmit:",e),null==s)return;let r=await U(s,e);l&&a(l.map(e=>e.team_id===t?r.data:e)),h.ZP.success("Team updated successfully"),g(!1),Z(null)},L=async e=>{T(e),I(!0)},D=async()=>{if(null!=P&&null!=l&&null!=s){try{await y(s,P);let e=l.filter(e=>e.team_id!==P);a(e)}catch(e){console.error("Error deleting the team:",e)}I(!1),T(null)}};(0,n.useEffect)(()=>{let e=async()=>{try{if(null===o||null===i||null===s||null===l)return;console.log("fetching team info:");let e={};for(let t=0;t<(null==l?void 0:l.length);t++){let a=l[t].team_id,r=await w(s,a);console.log("teamInfo response:",r),null!==r&&(e={...e,[a]:r})}F(e)}catch(e){console.error("Error fetching team info:",e)}};(async()=>{try{if(null===o||null===i)return;if(null!==s){let e=(await v(s,o,i)).data.map(e=>e.id);console.log("available_model_names:",e),N(e)}}catch(e){console.error("Error fetching user models:",e)}})(),e()},[s,o,i,l]);let B=async e=>{try{if(null!=s){h.ZP.info("Creating Team");let t=await R(s,e);null!==l?a([...l,t]):a([t]),console.log("response for team create call: ".concat(t)),h.ZP.success("Team created"),_(!1)}}catch(e){console.error("Error creating the team:",e),h.ZP.error("Error creating the team: "+e,20)}},q=async e=>{try{if(null!=s&&null!=l){h.ZP.info("Adding Member");let t={role:"user",user_email:e.user_email,user_id:e.user_id},r=await z(s,f.team_id,t);console.log("response for team create call: ".concat(r.data));let n=l.findIndex(e=>(console.log("team.team_id=".concat(e.team_id,"; response.data.team_id=").concat(r.data.team_id)),e.team_id===r.data.team_id));if(console.log("foundIndex: ".concat(n)),-1!==n){let e=[...l];e[n]=r.data,a(e),Z(r.data)}S(!1)}}catch(e){console.error("Error creating the team:",e)}};return console.log("received teams ".concat(l)),(0,r.jsx)("div",{className:"w-full mx-4",children:(0,r.jsxs)(Y.Z,{numItems:1,className:"gap-2 p-8 h-[75vh] w-full mt-2",children:[(0,r.jsxs)(J.Z,{numColSpan:1,children:[(0,r.jsx)(m,{level:4,children:"All Teams"}),(0,r.jsxs)(eg.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:[(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(ek.Z,{children:(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(ev.Z,{children:"Team Name"}),(0,r.jsx)(ev.Z,{children:"Spend (USD)"}),(0,r.jsx)(ev.Z,{children:"Budget (USD)"}),(0,r.jsx)(ev.Z,{children:"Models"}),(0,r.jsx)(ev.Z,{children:"TPM / RPM Limits"}),(0,r.jsx)(ev.Z,{children:"Info"})]})}),(0,r.jsx)(eb.Z,{children:l&&l.length>0?l.map(e=>(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(e_.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:e.team_alias}),(0,r.jsx)(e_.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:e.spend}),(0,r.jsx)(e_.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:e.max_budget?e.max_budget:"No limit"}),(0,r.jsx)(e_.Z,{style:{maxWidth:"8-x",whiteSpace:"pre-wrap",overflow:"hidden"},children:Array.isArray(e.models)?(0,r.jsx)("div",{style:{display:"flex",flexDirection:"column"},children:0===e.models.length?(0,r.jsx)(ep.Z,{size:"xs",className:"mb-1",color:"red",children:(0,r.jsx)(el.Z,{children:"All Proxy Models"})}):e.models.map((e,l)=>"all-proxy-models"===e?(0,r.jsx)(ep.Z,{size:"xs",className:"mb-1",color:"red",children:(0,r.jsx)(el.Z,{children:"All Proxy Models"})},l):(0,r.jsx)(ep.Z,{size:"xs",className:"mb-1",color:"blue",children:(0,r.jsx)(el.Z,{children:e.length>30?"".concat(e.slice(0,30),"..."):e})},l))}):null}),(0,r.jsx)(e_.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,r.jsxs)(el.Z,{children:["TPM:"," ",e.tpm_limit?e.tpm_limit:"Unlimited"," ",(0,r.jsx)("br",{}),"RPM:"," ",e.rpm_limit?e.rpm_limit:"Unlimited"]})}),(0,r.jsxs)(e_.Z,{children:[(0,r.jsxs)(el.Z,{children:[E&&e.team_id&&E[e.team_id]&&E[e.team_id].keys&&E[e.team_id].keys.length," Keys"]}),(0,r.jsxs)(el.Z,{children:[E&&e.team_id&&E[e.team_id]&&E[e.team_id].team_info&&E[e.team_id].team_info.members_with_roles&&E[e.team_id].team_info.members_with_roles.length," Members"]})]}),(0,r.jsxs)(e_.Z,{children:[(0,r.jsx)(eZ.Z,{icon:eu.Z,size:"sm",onClick:()=>O(e)}),(0,r.jsx)(eZ.Z,{onClick:()=>L(e.team_id),icon:ex.Z,size:"sm"})]})]},e.team_id)):null})]}),C&&(0,r.jsx)("div",{className:"fixed z-10 inset-0 overflow-y-auto",children:(0,r.jsxs)("div",{className:"flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0",children:[(0,r.jsx)("div",{className:"fixed inset-0 transition-opacity","aria-hidden":"true",children:(0,r.jsx)("div",{className:"absolute inset-0 bg-gray-500 opacity-75"})}),(0,r.jsx)("span",{className:"hidden sm:inline-block sm:align-middle sm:h-screen","aria-hidden":"true",children:"​"}),(0,r.jsxs)("div",{className:"inline-block align-bottom bg-white rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full",children:[(0,r.jsx)("div",{className:"bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4",children:(0,r.jsx)("div",{className:"sm:flex sm:items-start",children:(0,r.jsxs)("div",{className:"mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left",children:[(0,r.jsx)("h3",{className:"text-lg leading-6 font-medium text-gray-900",children:"Delete Team"}),(0,r.jsx)("div",{className:"mt-2",children:(0,r.jsx)("p",{className:"text-sm text-gray-500",children:"Are you sure you want to delete this team ?"})})]})})}),(0,r.jsxs)("div",{className:"bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse",children:[(0,r.jsx)(H.Z,{onClick:D,color:"red",className:"ml-2",children:"Delete"}),(0,r.jsx)(H.Z,{onClick:()=>{I(!1),T(null)},children:"Cancel"})]})]})]})})]})]}),(0,r.jsxs)(J.Z,{numColSpan:1,children:[(0,r.jsx)(H.Z,{className:"mx-auto",onClick:()=>_(!0),children:"+ Create New Team"}),(0,r.jsx)(en.Z,{title:"Create Team",visible:b,width:800,footer:null,onOk:()=>{_(!1),c.resetFields()},onCancel:()=>{_(!1),c.resetFields()},children:(0,r.jsxs)(er.Z,{form:c,onFinish:B,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(er.Z.Item,{label:"Team Name",name:"team_alias",rules:[{required:!0,message:"Please input a team name"}],children:(0,r.jsx)($.Z,{placeholder:""})}),(0,r.jsx)(er.Z.Item,{label:"Models",name:"models",children:(0,r.jsxs)(ea.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:[(0,r.jsx)(ea.default.Option,{value:"all-proxy-models",children:"All Proxy Models"},"all-proxy-models"),A.map(e=>(0,r.jsx)(ea.default.Option,{value:e,children:e},e))]})}),(0,r.jsx)(er.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,r.jsx)(ei.Z,{step:.01,precision:2,width:200})}),(0,r.jsx)(er.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,r.jsx)(ei.Z,{step:1,width:400})}),(0,r.jsx)(er.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,r.jsx)(ei.Z,{step:1,width:400})})]}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ec.ZP,{htmlType:"submit",children:"Create Team"})})]})})]}),(0,r.jsxs)(J.Z,{numColSpan:1,children:[(0,r.jsx)(m,{level:4,children:"Team Members"}),(0,r.jsx)(u,{children:"If you belong to multiple teams, this setting controls which teams members you see."}),l&&l.length>0?(0,r.jsx)(eA.Z,{defaultValue:"0",children:l.map((e,l)=>(0,r.jsx)(eN.Z,{value:String(l),onClick:()=>{Z(e)},children:e.team_alias},l))}):(0,r.jsxs)(u,{children:["No team created. ",(0,r.jsx)("b",{children:"Defaulting to personal account."})]})]}),(0,r.jsxs)(J.Z,{numColSpan:1,children:[(0,r.jsx)(eg.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(ek.Z,{children:(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(ev.Z,{children:"Member Name"}),(0,r.jsx)(ev.Z,{children:"Role"})]})}),(0,r.jsx)(eb.Z,{children:f?f.members_with_roles.map((e,l)=>(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(e_.Z,{children:e.user_email?e.user_email:e.user_id?e.user_id:null}),(0,r.jsx)(e_.Z,{children:e.role})]},l)):null})]})}),f&&(0,r.jsx)(e=>{let{visible:l,onCancel:t,team:s,onSubmit:a}=e,[n]=er.Z.useForm();return(0,r.jsx)(en.Z,{title:"Edit Team",visible:l,width:800,footer:null,onOk:()=>{n.validateFields().then(e=>{a({...e,team_id:s.team_id}),n.resetFields()}).catch(e=>{console.error("Validation failed:",e)})},onCancel:t,children:(0,r.jsxs)(er.Z,{form:n,onFinish:M,initialValues:s,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(er.Z.Item,{label:"Team Name",name:"team_alias",rules:[{required:!0,message:"Please input a team name"}],children:(0,r.jsx)(eo.Z,{})}),(0,r.jsx)(er.Z.Item,{label:"Models",name:"models",children:(0,r.jsxs)(ea.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:[(0,r.jsx)(ea.default.Option,{value:"all-proxy-models",children:"All Proxy Models"},"all-proxy-models"),A&&A.map(e=>(0,r.jsx)(ea.default.Option,{value:e,children:e},e))]})}),(0,r.jsx)(er.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,r.jsx)(ei.Z,{step:.01,precision:2,width:200})}),(0,r.jsx)(er.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,r.jsx)(ei.Z,{step:1,width:400})}),(0,r.jsx)(er.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,r.jsx)(ei.Z,{step:1,width:400})}),(0,r.jsx)(er.Z.Item,{label:"Requests per minute Limit (RPM)",name:"team_id",hidden:!0})]}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ec.ZP,{htmlType:"submit",children:"Edit Team"})})]})})},{visible:j,onCancel:()=>{g(!1),Z(null)},team:f,onSubmit:M})]}),(0,r.jsxs)(J.Z,{numColSpan:1,children:[(0,r.jsx)(H.Z,{className:"mx-auto mb-5",onClick:()=>S(!0),children:"+ Add member"}),(0,r.jsx)(en.Z,{title:"Add member",visible:k,width:800,footer:null,onOk:()=>{S(!1),d.resetFields()},onCancel:()=>{S(!1),d.resetFields()},children:(0,r.jsxs)(er.Z,{form:c,onFinish:q,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(er.Z.Item,{label:"Email",name:"user_email",className:"mb-4",children:(0,r.jsx)(eo.Z,{name:"user_email",className:"px-3 py-2 border rounded-md w-full"})}),(0,r.jsx)("div",{className:"text-center mb-4",children:"OR"}),(0,r.jsx)(er.Z.Item,{label:"User ID",name:"user_id",className:"mb-4",children:(0,r.jsx)(eo.Z,{name:"user_id",className:"px-3 py-2 border rounded-md w-full"})})]}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ec.ZP,{htmlType:"submit",children:"Add member"})})]})})]})]})})},e9=t(18190),le=e=>{let l,{searchParams:t,accessToken:s,showSSOBanner:a}=e,[o]=er.Z.useForm(),[i]=er.Z.useForm(),{Title:c,Paragraph:d}=eR.default,[m,u]=(0,n.useState)(""),[x,p]=(0,n.useState)(null),[j,g]=(0,n.useState)(!1),[f,y]=(0,n.useState)(!1),[Z,w]=(0,n.useState)(!1),[b,_]=(0,n.useState)(!1),[k,v]=(0,n.useState)(!1);try{l=window.location.origin}catch(e){l=""}l+="/fallback/login";let S=()=>{v(!1)},A=["proxy_admin","proxy_admin_viewer"];(0,n.useEffect)(()=>{(async()=>{if(null!=s){let e=[],l=await M(s,"proxy_admin_viewer");l.forEach(l=>{e.push({user_role:l.user_role,user_id:l.user_id,user_email:l.user_email})}),console.log("proxy viewers: ".concat(l));let t=await M(s,"proxy_admin");t.forEach(l=>{e.push({user_role:l.user_role,user_id:l.user_id,user_email:l.user_email})}),console.log("proxy admins: ".concat(t)),console.log("combinedList: ".concat(e)),p(e)}})()},[s]);let N=()=>{w(!1),i.resetFields()},C=()=>{w(!1),i.resetFields()},I=e=>(0,r.jsxs)(er.Z,{form:o,onFinish:e,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(er.Z.Item,{label:"Email",name:"user_email",className:"mb-4",children:(0,r.jsx)(eo.Z,{name:"user_email",className:"px-3 py-2 border rounded-md w-full"})}),(0,r.jsx)("div",{className:"text-center mb-4",children:"OR"}),(0,r.jsx)(er.Z.Item,{label:"User ID",name:"user_id",className:"mb-4",children:(0,r.jsx)(eo.Z,{name:"user_id",className:"px-3 py-2 border rounded-md w-full"})})]}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ec.ZP,{htmlType:"submit",children:"Add member"})})]}),P=(e,l,t)=>(0,r.jsxs)(er.Z,{form:o,onFinish:e,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(er.Z.Item,{rules:[{required:!0,message:"Required"}],label:"User Role",name:"user_role",labelCol:{span:10},labelAlign:"left",children:(0,r.jsx)(eA.Z,{value:l,children:A.map((e,l)=>(0,r.jsx)(eN.Z,{value:e,children:e},l))})}),(0,r.jsx)(er.Z.Item,{label:"Team ID",name:"user_id",hidden:!0,initialValue:t,valuePropName:"user_id",className:"mt-8",children:(0,r.jsx)(eo.Z,{value:t,disabled:!0})})]}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ec.ZP,{htmlType:"submit",children:"Update role"})})]}),T=async e=>{try{if(null!=s&&null!=x){h.ZP.info("Making API Call");let l=await B(s,e,null);console.log("response for team create call: ".concat(l));let t=x.findIndex(e=>(console.log("user.user_id=".concat(e.user_id,"; response.user_id=").concat(l.user_id)),e.user_id===l.user_id));console.log("foundIndex: ".concat(t)),-1==t&&(console.log("updates admin with new user"),x.push(l),p(x)),h.ZP.success("Refresh tab to see updated user role"),w(!1)}}catch(e){console.error("Error creating the key:",e)}},E=async e=>{try{if(null!=s&&null!=x){h.ZP.info("Making API Call");let l=await B(s,e,"proxy_admin_viewer");console.log("response for team create call: ".concat(l));let t=x.findIndex(e=>(console.log("user.user_id=".concat(e.user_id,"; response.user_id=").concat(l.user_id)),e.user_id===l.user_id));console.log("foundIndex: ".concat(t)),-1==t&&(console.log("updates admin with new user"),x.push(l),p(x)),g(!1)}}catch(e){console.error("Error creating the key:",e)}},F=async e=>{try{if(null!=s&&null!=x){h.ZP.info("Making API Call"),e.user_email,e.user_id;let l=await B(s,e,"proxy_admin");console.log("response for team create call: ".concat(l));let t=x.findIndex(e=>(console.log("user.user_id=".concat(e.user_id,"; response.user_id=").concat(l.user_id)),e.user_id===l.user_id));console.log("foundIndex: ".concat(t)),-1==t&&(console.log("updates admin with new user"),x.push(l),p(x)),y(!1)}}catch(e){console.error("Error creating the key:",e)}},O=async e=>{null!=s&&G(s,{environment_variables:{PROXY_BASE_URL:e.proxy_base_url,GOOGLE_CLIENT_ID:e.google_client_id,GOOGLE_CLIENT_SECRET:e.google_client_secret}})};return console.log("admins: ".concat(null==x?void 0:x.length)),(0,r.jsxs)("div",{className:"w-full m-2 mt-2 p-8",children:[(0,r.jsx)(c,{level:4,children:"Admin Access "}),(0,r.jsxs)(d,{children:[a&&(0,r.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/ui#restrict-ui-access",children:"Requires SSO Setup"}),(0,r.jsx)("br",{}),(0,r.jsx)("b",{children:"Proxy Admin: "})," Can create keys, teams, users, add models, etc. ",(0,r.jsx)("br",{}),(0,r.jsx)("b",{children:"Proxy Admin Viewer: "}),"Can just view spend. They cannot create keys, teams or grant users access to new models."," "]}),(0,r.jsxs)(Y.Z,{numItems:1,className:"gap-2 p-2 w-full",children:[(0,r.jsx)(J.Z,{numColSpan:1,children:(0,r.jsx)(eg.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(ek.Z,{children:(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(ev.Z,{children:"Member Name"}),(0,r.jsx)(ev.Z,{children:"Role"})]})}),(0,r.jsx)(eb.Z,{children:x?x.map((e,l)=>(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(e_.Z,{children:e.user_email?e.user_email:e.user_id?e.user_id:null}),(0,r.jsx)(e_.Z,{children:e.user_role}),(0,r.jsxs)(e_.Z,{children:[(0,r.jsx)(eZ.Z,{icon:eu.Z,size:"sm",onClick:()=>w(!0)}),(0,r.jsx)(en.Z,{title:"Update role",visible:Z,width:800,footer:null,onOk:N,onCancel:C,children:P(T,e.user_role,e.user_id)})]})]},l)):null})]})})}),(0,r.jsx)(J.Z,{numColSpan:1,children:(0,r.jsxs)("div",{className:"flex justify-start",children:[(0,r.jsx)(H.Z,{className:"mr-4 mb-5",onClick:()=>y(!0),children:"+ Add admin"}),(0,r.jsx)(en.Z,{title:"Add admin",visible:f,width:800,footer:null,onOk:()=>{y(!1),i.resetFields()},onCancel:()=>{y(!1),i.resetFields()},children:I(F)}),(0,r.jsx)(H.Z,{className:"mb-5",onClick:()=>g(!0),children:"+ Add viewer"}),(0,r.jsx)(en.Z,{title:"Add viewer",visible:j,width:800,footer:null,onOk:()=>{g(!1),i.resetFields()},onCancel:()=>{g(!1),i.resetFields()},children:I(E)})]})})]}),(0,r.jsxs)(Y.Z,{children:[(0,r.jsx)(c,{level:4,children:"Add SSO"}),(0,r.jsxs)("div",{className:"flex justify-start mb-4",children:[(0,r.jsx)(H.Z,{onClick:()=>_(!0),children:"Add SSO"}),(0,r.jsx)(en.Z,{title:"Add SSO",visible:b,width:800,footer:null,onOk:()=>{_(!1),o.resetFields()},onCancel:()=>{_(!1),o.resetFields()},children:(0,r.jsxs)(er.Z,{form:o,onFinish:e=>{F(e),O(e),_(!1),v(!0)},labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(er.Z.Item,{label:"Admin Email",name:"user_email",rules:[{required:!0,message:"Please enter the email of the proxy admin"}],children:(0,r.jsx)(eo.Z,{})}),(0,r.jsx)(er.Z.Item,{label:"PROXY BASE URL",name:"proxy_base_url",rules:[{required:!0,message:"Please enter the proxy base url"}],children:(0,r.jsx)(eo.Z,{})}),(0,r.jsx)(er.Z.Item,{label:"GOOGLE CLIENT ID",name:"google_client_id",rules:[{required:!0,message:"Please enter the google client id"}],children:(0,r.jsx)(eo.Z.Password,{})}),(0,r.jsx)(er.Z.Item,{label:"GOOGLE CLIENT SECRET",name:"google_client_secret",rules:[{required:!0,message:"Please enter the google client secret"}],children:(0,r.jsx)(eo.Z.Password,{})})]}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ec.ZP,{htmlType:"submit",children:"Save"})})]})}),(0,r.jsxs)(en.Z,{title:"SSO Setup Instructions",visible:k,width:800,footer:null,onOk:S,onCancel:()=>{v(!1)},children:[(0,r.jsx)("p",{children:"Follow these steps to complete the SSO setup:"}),(0,r.jsx)(el.Z,{className:"mt-2",children:"1. DO NOT Exit this TAB"}),(0,r.jsx)(el.Z,{className:"mt-2",children:"2. Open a new tab, visit your proxy base url"}),(0,r.jsx)(el.Z,{className:"mt-2",children:"3. Confirm your SSO is configured correctly and you can login on the new Tab"}),(0,r.jsx)(el.Z,{className:"mt-2",children:"4. If Step 3 is successful, you can close this tab"}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ec.ZP,{onClick:S,children:"Done"})})]})]}),(0,r.jsxs)(e9.Z,{title:"Login without SSO",color:"teal",children:["If you need to login without sso, you can access ",(0,r.jsxs)("a",{href:l,target:"_blank",children:[(0,r.jsx)("b",{children:l})," "]})]})]})]})},ll=t(12224),lt=e=>{let{accessToken:l,userRole:t,userID:s}=e,[a,o]=(0,n.useState)([]),[i,c]=(0,n.useState)([]),[d,m]=(0,n.useState)(!1),[u]=er.Z.useForm(),[x,p]=(0,n.useState)(null),[j,g]=(0,n.useState)([]),[f,y]=(0,n.useState)(""),[Z,w]=(0,n.useState)({}),[b,_]=(0,n.useState)([]),k=e=>{b.includes(e)?_(b.filter(l=>l!==e)):_([...b,e])},v={llm_exceptions:"LLM Exceptions",llm_too_slow:"LLM Responses Too Slow",llm_requests_hanging:"LLM Requests Hanging",budget_alerts:"Budget Alerts (API Keys, Users)"};(0,n.useEffect)(()=>{l&&t&&s&&V(l,s,t).then(e=>{console.log("callbacks",e),o(e.callbacks);let l=e.alerts;if(console.log("alerts_data",l),l&&l.length>0){let e=l[0];console.log("_alert_info",e);let t=e.variables.SLACK_WEBHOOK_URL;console.log("catch_all_webhook",t),_(e.active_alerts),y(t),w(e.alerts_to_webhook)}c(l)})},[l,t,s]);let S=e=>b&&b.includes(e),A=e=>{if(!l)return;let t=Object.fromEntries(Object.entries(e.variables).map(e=>{var l;let[t,s]=e;return[t,(null===(l=document.querySelector('input[name="'.concat(t,'"]')))||void 0===l?void 0:l.value)||s]}));console.log("updatedVariables",t),console.log("updateAlertTypes",j);try{G(l,{environment_variables:t})}catch(e){h.ZP.error("Failed to update callback: "+e,20)}h.ZP.success("Callback updated successfully")},N=()=>{l&&u.validateFields().then(e=>{if(console.log("Form values:",e),"langfuse"===e.callback){G(l,{environment_variables:{LANGFUSE_PUBLIC_KEY:e.langfusePublicKey,LANGFUSE_SECRET_KEY:e.langfusePrivateKey},litellm_settings:{success_callback:[e.callback]}});let t={name:e.callback,variables:{SLACK_WEBHOOK_URL:null,LANGFUSE_HOST:null,LANGFUSE_PUBLIC_KEY:e.langfusePublicKey,LANGFUSE_SECRET_KEY:e.langfusePrivateKey}};o(a?[...a,t]:[t])}else if("slack"===e.callback){console.log("values.slackWebhookUrl: ".concat(e.slackWebhookUrl)),G(l,{general_settings:{alerting:["slack"],alerting_threshold:300},environment_variables:{SLACK_WEBHOOK_URL:e.slackWebhookUrl}}),console.log("values.callback: ".concat(e.callback));let t={name:e.callback,variables:{SLACK_WEBHOOK_URL:e.slackWebhookUrl,LANGFUSE_HOST:null,LANGFUSE_PUBLIC_KEY:null,LANGFUSE_SECRET_KEY:null}};o(a?[...a,t]:[t])}m(!1),u.resetFields(),p(null)})};return l?(console.log("callbacks: ".concat(a)),(0,r.jsxs)("div",{className:"w-full mx-4",children:[(0,r.jsx)(Y.Z,{numItems:1,className:"gap-2 p-8 w-full mt-2",children:(0,r.jsxs)(eD.Z,{children:[(0,r.jsxs)(ez.Z,{variant:"line",defaultValue:"1",children:[(0,r.jsx)(eU.Z,{value:"1",children:"Logging Callbacks"}),(0,r.jsx)(eU.Z,{value:"2",children:"Alerting"})]}),(0,r.jsxs)(eq.Z,{children:[(0,r.jsx)(eB.Z,{children:(0,r.jsxs)(eg.Z,{children:[(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(ek.Z,{children:(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(ev.Z,{children:"Callback"}),(0,r.jsx)(ev.Z,{children:"Callback Env Vars"})]})}),(0,r.jsx)(eb.Z,{children:a.map((e,t)=>{var s;return(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(e_.Z,{children:(0,r.jsx)(ep.Z,{color:"emerald",children:e.name})}),(0,r.jsxs)(e_.Z,{children:[(0,r.jsx)("ul",{children:Object.entries(null!==(s=e.variables)&&void 0!==s?s:{}).filter(e=>{let[l,t]=e;return null!==t}).map(e=>{let[l,t]=e;return(0,r.jsxs)("li",{children:[(0,r.jsx)(el.Z,{className:"mt-2",children:l}),"LANGFUSE_HOST"===l?(0,r.jsx)("p",{children:"default value=https://cloud.langfuse.com"}):(0,r.jsx)("div",{}),(0,r.jsx)($.Z,{name:l,defaultValue:t,type:"password"})]},l)})}),(0,r.jsx)(H.Z,{className:"mt-2",onClick:()=>A(e),children:"Save Changes"}),(0,r.jsx)(H.Z,{onClick:()=>K(l,e.name),className:"mx-2",children:"Test Callback"})]})]},t)})})]}),(0,r.jsx)(H.Z,{size:"xs",className:"mt-2",onClick:()=>{console.log("Add callback clicked"),m(!0)},children:"Add Callback"})]})}),(0,r.jsx)(eB.Z,{children:(0,r.jsxs)(eg.Z,{children:[(0,r.jsxs)(el.Z,{className:"my-2",children:["Alerts are only supported for Slack Webhook URLs. Get your webhook urls from ",(0,r.jsx)("a",{href:"https://api.slack.com/messaging/webhooks",target:"_blank",style:{color:"blue"},children:"here"})]}),(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(ek.Z,{children:(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(ev.Z,{}),(0,r.jsx)(ev.Z,{}),(0,r.jsx)(ev.Z,{children:"Slack Webhook URL"})]})}),(0,r.jsx)(eb.Z,{children:Object.entries(v).map((e,l)=>{let[t,s]=e;return(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(e_.Z,{children:(0,r.jsx)(ll.Z,{id:"switch",name:"switch",checked:S(t),onChange:()=>k(t)})}),(0,r.jsx)(e_.Z,{children:(0,r.jsx)(el.Z,{children:s})}),(0,r.jsx)(e_.Z,{children:(0,r.jsx)($.Z,{name:t,type:"password",defaultValue:Z&&Z[t]?Z[t]:f})})]},l)})})]}),(0,r.jsx)(H.Z,{size:"xs",className:"mt-2",onClick:()=>{if(!l)return;let e={};Object.entries(v).forEach(l=>{let[t,s]=l,a=document.querySelector('input[name="'.concat(t,'"]'));console.log("key",t),console.log("webhookInput",a);let r=(null==a?void 0:a.value)||"";console.log("newWebhookValue",r),e[t]=r}),console.log("updatedAlertToWebhooks",e);let t={general_settings:{alert_to_webhook_url:e,alert_types:b}};console.log("payload",t);try{G(l,t)}catch(e){h.ZP.error("Failed to update alerts: "+e,20)}h.ZP.success("Alerts updated successfully")},children:"Save Changes"}),(0,r.jsx)(H.Z,{onClick:()=>K(l,"slack"),className:"mx-2",children:"Test Alerts"})]})})]})]})}),(0,r.jsx)(en.Z,{title:"Add Callback",visible:d,onOk:N,width:800,onCancel:()=>{m(!1),u.resetFields(),p(null)},footer:null,children:(0,r.jsxs)(er.Z,{form:u,layout:"vertical",onFinish:N,children:[(0,r.jsx)(er.Z.Item,{label:"Callback",name:"callback",rules:[{required:!0,message:"Please select a callback"}],children:(0,r.jsx)(ea.default,{onChange:e=>{p(e)},children:(0,r.jsx)(ea.default.Option,{value:"langfuse",children:"langfuse"})})}),"langfuse"===x&&(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(er.Z.Item,{label:"LANGFUSE_PUBLIC_KEY",name:"langfusePublicKey",rules:[{required:!0,message:"Please enter the public key"}],children:(0,r.jsx)($.Z,{type:"password"})}),(0,r.jsx)(er.Z.Item,{label:"LANGFUSE_PRIVATE_KEY",name:"langfusePrivateKey",rules:[{required:!0,message:"Please enter the private key"}],children:(0,r.jsx)($.Z,{type:"password"})})]}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ec.ZP,{htmlType:"submit",children:"Save"})})]})})]})):null};let{Option:ls}=ea.default;var la=e=>{let{models:l,accessToken:t,routerSettings:s,setRouterSettings:a}=e,[o]=er.Z.useForm(),[i,c]=(0,n.useState)(!1),[d,m]=(0,n.useState)("");return(0,r.jsxs)("div",{children:[(0,r.jsx)(H.Z,{className:"mx-auto",onClick:()=>c(!0),children:"+ Add Fallbacks"}),(0,r.jsx)(en.Z,{title:"Add Fallbacks",visible:i,width:800,footer:null,onOk:()=>{c(!1),o.resetFields()},onCancel:()=>{c(!1),o.resetFields()},children:(0,r.jsxs)(er.Z,{form:o,onFinish:e=>{console.log(e);let{model_name:l,models:r}=e,n=[...s.fallbacks||[],{[l]:r}],i={...s,fallbacks:n};console.log(i);try{G(t,{router_settings:i}),a(i)}catch(e){h.ZP.error("Failed to update router settings: "+e,20)}h.ZP.success("router settings updated successfully"),c(!1),o.resetFields()},labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(er.Z.Item,{label:"Public Model Name",name:"model_name",rules:[{required:!0,message:"Set the model to fallback for"}],help:"required",children:(0,r.jsx)(eA.Z,{defaultValue:d,children:l&&l.map((e,l)=>(0,r.jsx)(eN.Z,{value:e,onClick:()=>m(e),children:e},l))})}),(0,r.jsx)(er.Z.Item,{label:"Fallback Models",name:"models",rules:[{required:!0,message:"Please select a model"}],help:"required",children:(0,r.jsx)(eK.Z,{value:l,children:l&&l.filter(e=>e!=d).map(e=>(0,r.jsx)(eV.Z,{value:e,children:e},e))})})]}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ec.ZP,{htmlType:"submit",children:"Add Fallbacks"})})]})})]})},lr=t(12968);async function ln(e,l){console.log("isLocal:",!1);let t=window.location.origin,s=new lr.ZP.OpenAI({apiKey:l,baseURL:t,dangerouslyAllowBrowser:!0});try{let l=await s.chat.completions.create({model:e,messages:[{role:"user",content:"Hi, this is a test message"}],mock_testing_fallbacks:!0});h.ZP.success((0,r.jsxs)("span",{children:["Test model=",(0,r.jsx)("strong",{children:e}),", received model=",(0,r.jsx)("strong",{children:l.model}),". See ",(0,r.jsx)("a",{href:"#",onClick:()=>window.open("https://docs.litellm.ai/docs/proxy/reliability","_blank"),style:{textDecoration:"underline",color:"blue"},children:"curl"})]}))}catch(e){h.ZP.error("Error occurred while generating model response. Please try again. Error: ".concat(e),20)}}var lo=e=>{let{accessToken:l,userRole:t,userID:s,modelData:a}=e,[o,i]=(0,n.useState)({}),[c,d]=(0,n.useState)(!1),[m]=er.Z.useForm(),[u,x]=(0,n.useState)(null),p={routing_strategy_args:"(dict) Arguments to pass to the routing strategy",routing_strategy:"(string) Routing strategy to use",allowed_fails:"(int) Number of times a deployment can fail before being added to cooldown",cooldown_time:"(int) time in seconds to cooldown a deployment after failure",num_retries:"(int) Number of retries for failed requests. Defaults to 0.",timeout:"(float) Timeout for requests. Defaults to None.",retry_after:"(int) Minimum time to wait before retrying a failed request"};(0,n.useEffect)(()=>{l&&t&&s&&V(l,s,t).then(e=>{console.log("callbacks",e),i(e.router_settings)})},[l,t,s]);let j=async e=>{if(l){console.log("received key: ".concat(e)),console.log("routerSettings['fallbacks']: ".concat(o.fallbacks)),o.fallbacks.map(l=>(e in l&&delete l[e],l));try{await G(l,{router_settings:o}),i({...o}),h.ZP.success("Router settings updated successfully")}catch(e){h.ZP.error("Failed to update router settings: "+e,20)}}},g=e=>{if(!l)return;console.log("router_settings",e);let t=Object.fromEntries(Object.entries(e).map(e=>{let[l,t]=e;if("routing_strategy_args"!==l){var s;return[l,(null===(s=document.querySelector('input[name="'.concat(l,'"]')))||void 0===s?void 0:s.value)||t]}return null}).filter(e=>null!==e));console.log("updatedVariables",t);try{G(l,{router_settings:t})}catch(e){h.ZP.error("Failed to update router settings: "+e,20)}h.ZP.success("router settings updated successfully")};return l?(0,r.jsx)("div",{className:"w-full mx-4",children:(0,r.jsxs)(eD.Z,{className:"gap-2 p-8 h-[75vh] w-full mt-2",children:[(0,r.jsxs)(ez.Z,{variant:"line",defaultValue:"1",children:[(0,r.jsx)(eU.Z,{value:"1",children:"General Settings"}),(0,r.jsx)(eU.Z,{value:"2",children:"Fallbacks"})]}),(0,r.jsxs)(eq.Z,{children:[(0,r.jsx)(eB.Z,{children:(0,r.jsxs)(Y.Z,{numItems:1,className:"gap-2 p-8 w-full mt-2",children:[(0,r.jsx)(et.Z,{children:"Router Settings"}),(0,r.jsx)(eg.Z,{children:(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(ek.Z,{children:(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(ev.Z,{children:"Setting"}),(0,r.jsx)(ev.Z,{children:"Value"})]})}),(0,r.jsx)(eb.Z,{children:Object.entries(o).filter(e=>{let[l,t]=e;return"fallbacks"!=l&&"context_window_fallbacks"!=l}).map(e=>{let[l,t]=e;return(0,r.jsxs)(eS.Z,{children:[(0,r.jsxs)(e_.Z,{children:[(0,r.jsx)(el.Z,{children:l}),(0,r.jsx)("p",{style:{fontSize:"0.65rem",color:"#808080",fontStyle:"italic"},className:"mt-1",children:p[l]})]}),(0,r.jsx)(e_.Z,{children:(0,r.jsx)($.Z,{name:l,defaultValue:"object"==typeof t?JSON.stringify(t,null,2):t.toString()})})]},l)})})]})}),(0,r.jsx)(J.Z,{children:(0,r.jsx)(H.Z,{className:"mt-2",onClick:()=>g(o),children:"Save Changes"})})]})}),(0,r.jsxs)(eB.Z,{children:[(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(ek.Z,{children:(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(ev.Z,{children:"Model Name"}),(0,r.jsx)(ev.Z,{children:"Fallbacks"})]})}),(0,r.jsx)(eb.Z,{children:o.fallbacks&&o.fallbacks.map((e,t)=>Object.entries(e).map(e=>{let[s,a]=e;return(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(e_.Z,{children:s}),(0,r.jsx)(e_.Z,{children:Array.isArray(a)?a.join(", "):a}),(0,r.jsx)(e_.Z,{children:(0,r.jsx)(H.Z,{onClick:()=>ln(s,l),children:"Test Fallback"})}),(0,r.jsx)(e_.Z,{children:(0,r.jsx)(eZ.Z,{icon:ex.Z,size:"sm",onClick:()=>j(s)})})]},t.toString()+s)}))})]}),(0,r.jsx)(la,{models:(null==a?void 0:a.data)?a.data.map(e=>e.model_name):[],accessToken:l,routerSettings:o,setRouterSettings:i})]})]})]})}):null},li=t(67951),lc=e=>{let{}=e;return(0,r.jsx)(r.Fragment,{children:(0,r.jsx)(Y.Z,{className:"gap-2 p-8 h-[80vh] w-full mt-2",children:(0,r.jsxs)("div",{className:"mb-5",children:[(0,r.jsx)("p",{className:"text-2xl text-tremor-content-strong dark:text-dark-tremor-content-strong font-semibold",children:"OpenAI Compatible Proxy: API Reference"}),(0,r.jsx)(el.Z,{className:"mt-2 mb-2",children:"LiteLLM is OpenAI Compatible. This means your API Key works with the OpenAI SDK. Just replace the base_url to point to your litellm proxy. Example Below "}),(0,r.jsxs)(eD.Z,{children:[(0,r.jsxs)(ez.Z,{children:[(0,r.jsx)(eU.Z,{children:"OpenAI Python SDK"}),(0,r.jsx)(eU.Z,{children:"LlamaIndex"}),(0,r.jsx)(eU.Z,{children:"Langchain Py"})]}),(0,r.jsxs)(eq.Z,{children:[(0,r.jsx)(eB.Z,{children:(0,r.jsx)(li.Z,{language:"python",children:'\nimport openai\nclient = openai.OpenAI(\n api_key="your_api_key",\n base_url="http://0.0.0.0:4000" # LiteLLM Proxy is OpenAI compatible, Read More: https://docs.litellm.ai/docs/proxy/user_keys\n)\n\nresponse = client.chat.completions.create(\n model="gpt-3.5-turbo", # model to send to the proxy\n messages = [\n {\n "role": "user",\n "content": "this is a test request, write a short poem"\n }\n ]\n)\n\nprint(response)\n '})}),(0,r.jsx)(eB.Z,{children:(0,r.jsx)(li.Z,{language:"python",children:'\nimport os, dotenv\n\nfrom llama_index.llms import AzureOpenAI\nfrom llama_index.embeddings import AzureOpenAIEmbedding\nfrom llama_index import VectorStoreIndex, SimpleDirectoryReader, ServiceContext\n\nllm = AzureOpenAI(\n engine="azure-gpt-3.5", # model_name on litellm proxy\n temperature=0.0,\n azure_endpoint="http://0.0.0.0:4000", # litellm proxy endpoint\n api_key="sk-1234", # litellm proxy API Key\n api_version="2023-07-01-preview",\n)\n\nembed_model = AzureOpenAIEmbedding(\n deployment_name="azure-embedding-model",\n azure_endpoint="http://0.0.0.0:4000",\n api_key="sk-1234",\n api_version="2023-07-01-preview",\n)\n\n\ndocuments = SimpleDirectoryReader("llama_index_data").load_data()\nservice_context = ServiceContext.from_defaults(llm=llm, embed_model=embed_model)\nindex = VectorStoreIndex.from_documents(documents, service_context=service_context)\n\nquery_engine = index.as_query_engine()\nresponse = query_engine.query("What did the author do growing up?")\nprint(response)\n\n '})}),(0,r.jsx)(eB.Z,{children:(0,r.jsx)(li.Z,{language:"python",children:'\nfrom langchain.chat_models import ChatOpenAI\nfrom langchain.prompts.chat import (\n ChatPromptTemplate,\n HumanMessagePromptTemplate,\n SystemMessagePromptTemplate,\n)\nfrom langchain.schema import HumanMessage, SystemMessage\n\nchat = ChatOpenAI(\n openai_api_base="http://0.0.0.0:4000",\n model = "gpt-3.5-turbo",\n temperature=0.1\n)\n\nmessages = [\n SystemMessage(\n content="You are a helpful assistant that im using to make a test request to."\n ),\n HumanMessage(\n content="test from litellm. tell me why it\'s amazing in 1 sentence"\n ),\n]\nresponse = chat(messages)\n\nprint(response)\n\n '})})]})]})]})})})};async function ld(e,l,t,s){console.log("isLocal:",!1);let a=window.location.origin,r=new lr.ZP.OpenAI({apiKey:s,baseURL:a,dangerouslyAllowBrowser:!0});try{for await(let s of(await r.chat.completions.create({model:t,stream:!0,messages:[{role:"user",content:e}]})))console.log(s),s.choices[0].delta.content&&l(s.choices[0].delta.content)}catch(e){h.ZP.error("Error occurred while generating model response. Please try again. Error: ".concat(e),20)}}var lm=e=>{let{accessToken:l,token:t,userRole:s,userID:a}=e,[o,i]=(0,n.useState)(""),[c,d]=(0,n.useState)(""),[m,h]=(0,n.useState)([]),[u,x]=(0,n.useState)(void 0),[p,j]=(0,n.useState)([]);(0,n.useEffect)(()=>{l&&t&&s&&a&&(async()=>{try{let e=await v(l,a,s);if(console.log("model_info:",e),(null==e?void 0:e.data.length)>0){let l=e.data.map(e=>({value:e.id,label:e.id}));console.log(l),j(l),x(e.data[0].id)}}catch(e){console.error("Error fetching model info:",e)}})()},[l,a,s]);let g=(e,l)=>{h(t=>{let s=t[t.length-1];return s&&s.role===e?[...t.slice(0,t.length-1),{role:e,content:s.content+l}]:[...t,{role:e,content:l}]})},f=async()=>{if(""!==c.trim()&&o&&t&&s&&a){h(e=>[...e,{role:"user",content:c}]);try{u&&await ld(c,e=>g("assistant",e),u,o)}catch(e){console.error("Error fetching model response",e),g("assistant","Error fetching model response")}d("")}};if(s&&"Admin Viewer"==s){let{Title:e,Paragraph:l}=eR.default;return(0,r.jsxs)("div",{children:[(0,r.jsx)(e,{level:1,children:"Access Denied"}),(0,r.jsx)(l,{children:"Ask your proxy admin for access to test models"})]})}return(0,r.jsx)("div",{style:{width:"100%",position:"relative"},children:(0,r.jsx)(Y.Z,{className:"gap-2 p-8 h-[80vh] w-full mt-2",children:(0,r.jsx)(eg.Z,{children:(0,r.jsxs)(eD.Z,{children:[(0,r.jsx)(ez.Z,{children:(0,r.jsx)(eU.Z,{children:"Chat"})}),(0,r.jsx)(eq.Z,{children:(0,r.jsxs)(eB.Z,{children:[(0,r.jsx)("div",{className:"sm:max-w-2xl",children:(0,r.jsxs)(Y.Z,{numItems:2,children:[(0,r.jsxs)(J.Z,{children:[(0,r.jsx)(el.Z,{children:"API Key"}),(0,r.jsx)($.Z,{placeholder:"Type API Key here",type:"password",onValueChange:i,value:o})]}),(0,r.jsxs)(J.Z,{className:"mx-2",children:[(0,r.jsx)(el.Z,{children:"Select Model:"}),(0,r.jsx)(ea.default,{placeholder:"Select a Model",onChange:e=>{console.log("selected ".concat(e)),x(e)},options:p,style:{width:"200px"}})]})]})}),(0,r.jsxs)(ew.Z,{className:"mt-5",style:{display:"block",maxHeight:"60vh",overflowY:"auto"},children:[(0,r.jsx)(ek.Z,{children:(0,r.jsx)(eS.Z,{children:(0,r.jsx)(e_.Z,{})})}),(0,r.jsx)(eb.Z,{children:m.map((e,l)=>(0,r.jsx)(eS.Z,{children:(0,r.jsx)(e_.Z,{children:"".concat(e.role,": ").concat(e.content)})},l))})]}),(0,r.jsx)("div",{className:"mt-3",style:{position:"absolute",bottom:5,width:"95%"},children:(0,r.jsxs)("div",{className:"flex",children:[(0,r.jsx)($.Z,{type:"text",value:c,onChange:e=>d(e.target.value),placeholder:"Type your message..."}),(0,r.jsx)(H.Z,{onClick:f,className:"ml-2",children:"Send"})]})})]})})]})})})})},lh=t(33509),lu=t(95781);let{Sider:lx}=lh.default;var lp=e=>{let{setPage:l,userRole:t,defaultSelectedKey:s}=e;return"Admin Viewer"==t?(0,r.jsx)(lh.default,{style:{minHeight:"100vh",maxWidth:"120px"},children:(0,r.jsx)(lx,{width:120,children:(0,r.jsxs)(lu.Z,{mode:"inline",defaultSelectedKeys:s||["4"],style:{height:"100%",borderRight:0},children:[(0,r.jsx)(lu.Z.Item,{onClick:()=>l("api-keys"),children:"API Keys"},"4"),(0,r.jsx)(lu.Z.Item,{onClick:()=>l("models"),children:"Models"},"2"),(0,r.jsx)(lu.Z.Item,{onClick:()=>l("llm-playground"),children:"Chat UI"},"3"),(0,r.jsx)(lu.Z.Item,{onClick:()=>l("usage"),children:"Usage"},"1")]})})}):(0,r.jsx)(lh.default,{style:{minHeight:"100vh",maxWidth:"145px"},children:(0,r.jsx)(lx,{width:145,children:(0,r.jsxs)(lu.Z,{mode:"inline",defaultSelectedKeys:s||["1"],style:{height:"100%",borderRight:0},children:[(0,r.jsx)(lu.Z.Item,{onClick:()=>l("api-keys"),children:(0,r.jsx)(el.Z,{children:"API Keys"})},"1"),(0,r.jsx)(lu.Z.Item,{onClick:()=>l("llm-playground"),children:(0,r.jsx)(el.Z,{children:"Test Key"})},"3"),"Admin"==t?(0,r.jsx)(lu.Z.Item,{onClick:()=>l("models"),children:(0,r.jsx)(el.Z,{children:"Models"})},"2"):null,"Admin"==t?(0,r.jsx)(lu.Z.Item,{onClick:()=>l("usage"),children:(0,r.jsx)(el.Z,{children:"Usage"})},"4"):null,"Admin"==t?(0,r.jsx)(lu.Z.Item,{onClick:()=>l("teams"),children:(0,r.jsx)(el.Z,{children:"Teams"})},"6"):null,"Admin"==t?(0,r.jsx)(lu.Z.Item,{onClick:()=>l("users"),children:(0,r.jsx)(el.Z,{children:"Users"})},"5"):null,"Admin"==t?(0,r.jsx)(lu.Z.Item,{onClick:()=>l("settings"),children:(0,r.jsx)(el.Z,{children:"Logging & Alerts"})},"8"):null,"Admin"==t?(0,r.jsx)(lu.Z.Item,{onClick:()=>l("general-settings"),children:(0,r.jsx)(el.Z,{children:"Router Settings"})},"9"):null,"Admin"==t?(0,r.jsx)(lu.Z.Item,{onClick:()=>l("admin-panel"),children:(0,r.jsx)(el.Z,{children:"Admin"})},"7"):null,(0,r.jsx)(lu.Z.Item,{onClick:()=>l("api_ref"),children:(0,r.jsx)(el.Z,{children:"API Reference"})},"11")]})})})},lj=t(67989),lg=e=>{let{accessToken:l,token:t,userRole:s,userID:a}=e,o=new Date,[i,c]=(0,n.useState)([]),[d,m]=(0,n.useState)([]),[h,u]=(0,n.useState)([]),[x,p]=(0,n.useState)([]),[j,g]=(0,n.useState)([]),[f,y]=(0,n.useState)([]),[Z,w]=(0,n.useState)([]),[b,v]=(0,n.useState)([]),[S,T]=(0,n.useState)([]),[O,M]=(0,n.useState)([]),[R,L]=(0,n.useState)([]),[U,D]=(0,n.useState)(null),z=new Date(o.getFullYear(),o.getMonth(),1),B=new Date(o.getFullYear(),o.getMonth()+1,0),q=V(z),K=V(B);function V(e){let l=e.getFullYear(),t=e.getMonth()+1,s=e.getDate();return"".concat(l,"-").concat(t<10?"0"+t:t,"-").concat(s<10?"0"+s:s)}console.log("Start date is ".concat(q)),console.log("End date is ".concat(K)),(0,n.useEffect)(()=>{l&&t&&s&&a&&(async()=>{try{if(console.log("user role: ".concat(s)),"Admin"==s||"Admin Viewer"==s){let e=await I(l);c(e);let t=(await P(l)).map(e=>({key:(e.key_name||e.key_alias||e.api_key).substring(0,10),spend:e.total_spend}));m(t);let r=(await E(l)).map(e=>({key:e.model,spend:e.total_spend}));u(r);let n=await A(l);console.log("teamSpend",n),g(n.daily_spend),w(n.teams);let o=n.total_spend_per_team;o=o.map(e=>(e.name=e.team_id||"",e.value=e.total_spend||0,e)),v(o);let i=await N(l);y(i.top_10_tags);let d=(await _(l,a,s)).data;console.log("model groups in model dashboard",d);let h=[];for(let e=0;e{if(console.log("result from spend logs call",e),"daily_spend"in e){let l=e.daily_spend;console.log("daily spend",l),c(l);let t=e.top_api_keys;m(t)}else{let t=(await F(l,function(e){let l=[];e.forEach(e=>{Object.entries(e).forEach(e=>{let[t,s]=e;"spend"!==t&&"startTime"!==t&&"models"!==t&&"users"!==t&&l.push({key:t,spend:s})})}),l.sort((e,l)=>Number(l.spend)-Number(e.spend));let t=l.slice(0,5).map(e=>e.key);return console.log("topKeys: ".concat(Object.keys(t[0]))),t}(e))).info.map(e=>({key:(e.key_name||e.key_alias).substring(0,10),spend:e.spend}));m(t),p(function(e){let l={};e.forEach(e=>{Object.entries(e.users).forEach(e=>{let[t,s]=e;""!==t&&null!=t&&"None"!=t&&(l[t]||(l[t]=0),l[t]+=s)})});let t=Object.entries(l).map(e=>{let[l,t]=e;return{user_id:l,spend:t}});t.sort((e,l)=>l.spend-e.spend);let s=t.slice(0,5);return console.log("topKeys: ".concat(Object.values(s[0]))),s}(e)),c(e)}});let e=await k(l,a,s,null);console.log("Model metrics response:",e);let r=[...e].sort((e,l)=>l.avg_latency_seconds-e.avg_latency_seconds);console.log("Sorted by latency:",r),T(e),M(r)}catch(e){console.error("There was an error fetching the data",e)}})()},[l,t,s,a,q,K]);let G=async e=>{if(console.log("Updating model metrics for group:",e),l&&a&&s){D(e);try{let t=await k(l,a,s,e);console.log("Model metrics response:",t);let r=[...t].sort((e,l)=>l.avg_latency_seconds-e.avg_latency_seconds);console.log("Sorted by latency:",r),T(t),M(r)}catch(e){console.error("Failed to fetch model metrics",e)}}};return(0,r.jsxs)("div",{style:{width:"100%"},className:"p-8",children:[(0,r.jsx)(eE,{userID:a,userRole:s,accessToken:l,userSpend:null,selectedTeam:null}),(0,r.jsxs)(eD.Z,{children:[(0,r.jsxs)(ez.Z,{className:"mt-2",children:[(0,r.jsx)(eU.Z,{children:"All Up"}),(0,r.jsx)(eU.Z,{children:"Team Based Usage"}),(0,r.jsx)(eU.Z,{children:"Tag Based Usage"}),(0,r.jsx)(eU.Z,{children:"Model Based Usage"})]}),(0,r.jsxs)(eq.Z,{children:[(0,r.jsx)(eB.Z,{children:(0,r.jsxs)(Y.Z,{numItems:2,className:"gap-2 h-[75vh] w-full",children:[(0,r.jsx)(J.Z,{numColSpan:2,children:(0,r.jsxs)(eg.Z,{children:[(0,r.jsx)(et.Z,{children:"Monthly Spend"}),(0,r.jsx)(ej.Z,{data:i,index:"date",categories:["spend"],colors:["blue"],valueFormatter:e=>"$ ".concat(new Intl.NumberFormat("us").format(e).toString()),yAxisWidth:100,tickGap:5})]})}),(0,r.jsx)(J.Z,{numColSpan:1,children:(0,r.jsxs)(eg.Z,{children:[(0,r.jsx)(et.Z,{children:"Top API Keys"}),(0,r.jsx)(ej.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,r.jsx)(J.Z,{numColSpan:1,children:(0,r.jsxs)(eg.Z,{children:[(0,r.jsx)(et.Z,{children:"Top Users"}),(0,r.jsx)(ej.Z,{className:"mt-4 h-40",data:x,index:"user_id",categories:["spend"],colors:["blue"],yAxisWidth:200,layout:"vertical",showXAxis:!1,showLegend:!1})]})}),(0,r.jsx)(J.Z,{numColSpan:1,children:(0,r.jsxs)(eg.Z,{children:[(0,r.jsx)(et.Z,{children:"Top Models"}),(0,r.jsx)(ej.Z,{className:"mt-4 h-40",data:h,index:"key",categories:["spend"],colors:["blue"],yAxisWidth:200,layout:"vertical",showXAxis:!1,showLegend:!1})]})})]})}),(0,r.jsx)(eB.Z,{children:(0,r.jsxs)(Y.Z,{numItems:2,className:"gap-2 h-[75vh] w-full",children:[(0,r.jsxs)(J.Z,{numColSpan:2,children:[(0,r.jsxs)(eg.Z,{className:"mb-2",children:[(0,r.jsx)(et.Z,{children:"Total Spend Per Team"}),(0,r.jsx)(lj.Z,{data:b})]}),(0,r.jsxs)(eg.Z,{children:[(0,r.jsx)(et.Z,{children:"Daily Spend Per Team"}),(0,r.jsx)(ej.Z,{className:"h-72",data:j,showLegend:!0,index:"date",categories:Z,yAxisWidth:80,colors:["blue","green","yellow","red","purple"],stack:!0})]})]}),(0,r.jsx)(J.Z,{numColSpan:2})]})}),(0,r.jsx)(eB.Z,{children:(0,r.jsxs)(Y.Z,{numItems:2,className:"gap-2 h-[75vh] w-full mb-4",children:[(0,r.jsx)(J.Z,{numColSpan:2,children:(0,r.jsxs)(eg.Z,{children:[(0,r.jsx)(et.Z,{children:"Spend Per Tag - Last 30 Days"}),(0,r.jsxs)(el.Z,{children:["Get Started Tracking cost per tag ",(0,r.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/enterprise#tracking-spend-for-custom-tags",target:"_blank",children:"here"})]}),(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(ek.Z,{children:(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(ev.Z,{children:"Tag"}),(0,r.jsx)(ev.Z,{children:"Spend"}),(0,r.jsx)(ev.Z,{children:"Requests"})]})}),(0,r.jsx)(eb.Z,{children:f.map(e=>(0,r.jsxs)(eS.Z,{children:[(0,r.jsx)(e_.Z,{children:e.name}),(0,r.jsx)(e_.Z,{children:e.value}),(0,r.jsx)(e_.Z,{children:e.log_count})]},e.name))})]})]})}),(0,r.jsx)(J.Z,{numColSpan:2})]})}),(0,r.jsxs)(eB.Z,{children:[(0,r.jsx)(et.Z,{children:"Filter By Model Group"}),(0,r.jsx)("p",{style:{fontSize:"0.85rem",color:"#808080"},children:"View how requests were load balanced within a model group"}),(0,r.jsx)("p",{style:{fontSize:"0.85rem",color:"#808080",fontStyle:"italic"},children:"(Beta feature) only supported for Azure Model Groups"}),(0,r.jsxs)(eA.Z,{className:"mb-4 mt-2",defaultValue:"all",children:[(0,r.jsx)(eN.Z,{value:"all",onClick:()=>G(null),children:"All Model Groups"}),R.map((e,l)=>(0,r.jsx)(eN.Z,{value:e,onClick:()=>G(e),children:e},l))]}),(0,r.jsxs)(eg.Z,{children:[(0,r.jsx)(et.Z,{children:"Number Requests per Model"}),(0,r.jsx)(ej.Z,{data:S,className:"h-[50vh]",index:"model",categories:["num_requests"],colors:["blue"],yAxisWidth:400,layout:"vertical",tickGap:5})]}),(0,r.jsxs)(eg.Z,{className:"mt-4",children:[(0,r.jsx)(et.Z,{children:"Latency Per Model"}),(0,r.jsx)(ej.Z,{data:O,className:"h-[50vh]",index:"model",categories:["avg_latency_seconds"],colors:["red"],yAxisWidth:400,layout:"vertical",tickGap:5})]})]})]})]})]})},lf=()=>{let{Title:e,Paragraph:l}=eR.default,[t,s]=(0,n.useState)(""),[a,i]=(0,n.useState)(null),[c,d]=(0,n.useState)(null),[h,u]=(0,n.useState)(null),[x,p]=(0,n.useState)(!0),j=(0,o.useSearchParams)(),[g,f]=(0,n.useState)({data:[]}),y=j.get("userID"),Z=j.get("token"),[w,b]=(0,n.useState)("api-keys"),[_,k]=(0,n.useState)(null);return(0,n.useEffect)(()=>{if(Z){let e=(0,eM.o)(Z);if(e){if(console.log("Decoded token:",e),console.log("Decoded key:",e.key),k(e.key),e.user_role){let l=function(e){if(!e)return"Undefined Role";switch(console.log("Received user role: ".concat(e.toLowerCase())),console.log("Received user role length: ".concat(e.toLowerCase().length)),e.toLowerCase()){case"app_owner":case"demo_app_owner":return"App Owner";case"app_admin":case"proxy_admin":return"Admin";case"proxy_admin_viewer":return"Admin Viewer";case"app_user":return"App User";default:return"Unknown Role"}}(e.user_role);console.log("Decoded user_role:",l),s(l),"Admin Viewer"==l&&b("usage")}else console.log("User role not defined");e.user_email?i(e.user_email):console.log("User Email is not set ".concat(e)),e.login_method?p("username_password"==e.login_method):console.log("User Email is not set ".concat(e))}}},[Z]),(0,r.jsx)(n.Suspense,{fallback:(0,r.jsx)("div",{children:"Loading..."}),children:(0,r.jsxs)("div",{className:"flex flex-col min-h-screen",children:[(0,r.jsx)(m,{userID:y,userRole:t,userEmail:a,showSSOBanner:x}),(0,r.jsxs)("div",{className:"flex flex-1 overflow-auto",children:[(0,r.jsx)("div",{className:"mt-8",children:(0,r.jsx)(lp,{setPage:b,userRole:t,defaultSelectedKey:null})}),"api-keys"==w?(0,r.jsx)(eL,{userID:y,userRole:t,teams:c,keys:h,setUserRole:s,userEmail:a,setUserEmail:i,setTeams:d,setKeys:u}):"models"==w?(0,r.jsx)(e8,{userID:y,userRole:t,token:Z,accessToken:_,modelData:g,setModelData:f}):"llm-playground"==w?(0,r.jsx)(lm,{userID:y,userRole:t,token:Z,accessToken:_}):"users"==w?(0,r.jsx)(e6,{userID:y,userRole:t,token:Z,keys:h,teams:c,accessToken:_,setKeys:u}):"teams"==w?(0,r.jsx)(e7,{teams:c,setTeams:d,searchParams:j,accessToken:_,userID:y,userRole:t}):"admin-panel"==w?(0,r.jsx)(le,{setTeams:d,searchParams:j,accessToken:_,showSSOBanner:x}):"api_ref"==w?(0,r.jsx)(lc,{}):"settings"==w?(0,r.jsx)(lt,{userID:y,userRole:t,accessToken:_}):"general-settings"==w?(0,r.jsx)(lo,{userID:y,userRole:t,accessToken:_,modelData:g}):(0,r.jsx)(lg,{userID:y,userRole:t,token:Z,accessToken:_})]})]})})}}},function(e){e.O(0,[447,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/PtTtxXIYvdjQsvRgdITlk/_buildManifest.js b/ui/litellm-dashboard/out/_next/static/kbGdRQFfI6W3bEwfzmJDI/_buildManifest.js similarity index 100% rename from ui/litellm-dashboard/out/_next/static/PtTtxXIYvdjQsvRgdITlk/_buildManifest.js rename to ui/litellm-dashboard/out/_next/static/kbGdRQFfI6W3bEwfzmJDI/_buildManifest.js diff --git a/ui/litellm-dashboard/out/_next/static/PtTtxXIYvdjQsvRgdITlk/_ssgManifest.js b/ui/litellm-dashboard/out/_next/static/kbGdRQFfI6W3bEwfzmJDI/_ssgManifest.js similarity index 100% rename from ui/litellm-dashboard/out/_next/static/PtTtxXIYvdjQsvRgdITlk/_ssgManifest.js rename to ui/litellm-dashboard/out/_next/static/kbGdRQFfI6W3bEwfzmJDI/_ssgManifest.js diff --git a/ui/litellm-dashboard/out/index.html b/ui/litellm-dashboard/out/index.html index cb197f11e23..0dbd09152f7 100644 --- a/ui/litellm-dashboard/out/index.html +++ b/ui/litellm-dashboard/out/index.html @@ -1 +1 @@ -LiteLLM Dashboard \ No newline at end of file +LiteLLM Dashboard \ No newline at end of file diff --git a/ui/litellm-dashboard/out/index.txt b/ui/litellm-dashboard/out/index.txt index 267d8e5baf0..70ccce5418b 100644 --- a/ui/litellm-dashboard/out/index.txt +++ b/ui/litellm-dashboard/out/index.txt @@ -1,7 +1,7 @@ 2:I[77831,[],""] -3:I[27125,["447","static/chunks/447-9f8d32190ff7d16d.js","931","static/chunks/app/page-781ca5f151d78d1d.js"],""] +3:I[27125,["447","static/chunks/447-9f8d32190ff7d16d.js","931","static/chunks/app/page-508c39694bd40fe9.js"],""] 4:I[5613,[],""] 5:I[31778,[],""] -0:["PtTtxXIYvdjQsvRgdITlk",[[["",{"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/5e699db73bf6f8c2.css","precedence":"next","crossOrigin":""}]],"$L6"]]]] +0:["kbGdRQFfI6W3bEwfzmJDI",[[["",{"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/5e699db73bf6f8c2.css","precedence":"next","crossOrigin":""}]],"$L6"]]]] 6:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"LiteLLM Dashboard"}],["$","meta","3",{"name":"description","content":"LiteLLM Proxy Admin UI"}],["$","link","4",{"rel":"icon","href":"/ui/favicon.ico","type":"image/x-icon","sizes":"16x16"}],["$","meta","5",{"name":"next-size-adjust"}]] 1:null diff --git a/ui/litellm-dashboard/src/components/create_key_button.tsx b/ui/litellm-dashboard/src/components/create_key_button.tsx index 976ac2ccfdc..648eee9cadf 100644 --- a/ui/litellm-dashboard/src/components/create_key_button.tsx +++ b/ui/litellm-dashboard/src/components/create_key_button.tsx @@ -39,6 +39,7 @@ const CreateKey: React.FC = ({ const [apiKey, setApiKey] = useState(null); const [softBudget, setSoftBudget] = useState(null); const [userModels, setUserModels] = useState([]); + const [modelsToPick, setModelsToPick] = useState([]); const handleOk = () => { setIsModalVisible(false); form.resetFields(); @@ -94,6 +95,30 @@ const CreateKey: React.FC = ({ const handleCopy = () => { message.success('API Key copied to clipboard'); }; + + useEffect(() => { + let tempModelsToPick = []; + + if (team) { + if (team.models.length > 0) { + if (team.models.includes("all-proxy-models")) { + // if the team has all-proxy-models show all available models + tempModelsToPick = userModels; + } else { + // show team models + tempModelsToPick = team.models; + } + } else { + // show all available models if the team has no models set + tempModelsToPick = userModels; + } + } else { + // no team set, show all available models + tempModelsToPick = userModels; + } + + setModelsToPick(tempModelsToPick); + }, [team, userModels]); return ( @@ -161,30 +186,15 @@ const CreateKey: React.FC = ({ - {team && team.models ? ( - team.models.includes("all-proxy-models") ? ( - userModels.map((model: string) => ( + { + modelsToPick.map((model: string) => ( ( ) )) - ) : ( - team.models.map((model: string) => ( - - )) - ) - ) : ( - userModels.map((model: string) => ( - - )) - )} - + }